| import Displayable, { DisplayableProps, | 
|     CommonStyleProps, | 
|     DEFAULT_COMMON_STYLE, | 
|     DisplayableStatePropNames, | 
|     DEFAULT_COMMON_ANIMATION_PROPS | 
| } from './Displayable'; | 
| import Element, { ElementAnimateConfig } from '../Element'; | 
| import PathProxy from '../core/PathProxy'; | 
| import * as pathContain from '../contain/path'; | 
| import { PatternObject } from './Pattern'; | 
| import { Dictionary, PropType, MapToType } from '../core/types'; | 
| import BoundingRect from '../core/BoundingRect'; | 
| import { LinearGradientObject } from './LinearGradient'; | 
| import { RadialGradientObject } from './RadialGradient'; | 
| import { defaults, keys, extend, clone, isString, createObject } from '../core/util'; | 
| import Animator from '../animation/Animator'; | 
| import { lum } from '../tool/color'; | 
| import { DARK_LABEL_COLOR, LIGHT_LABEL_COLOR, DARK_MODE_THRESHOLD, LIGHTER_LABEL_COLOR } from '../config'; | 
| import { REDRAW_BIT, SHAPE_CHANGED_BIT, STYLE_CHANGED_BIT } from './constants'; | 
| import { TRANSFORMABLE_PROPS } from '../core/Transformable'; | 
|   | 
|   | 
| export interface PathStyleProps extends CommonStyleProps { | 
|     fill?: string | PatternObject | LinearGradientObject | RadialGradientObject | 
|     stroke?: string | PatternObject | LinearGradientObject | RadialGradientObject | 
|     decal?: PatternObject | 
|   | 
|     /** | 
|      * Still experimental, not works weel on arc with edge cases(large angle). | 
|      */ | 
|     strokePercent?: number | 
|     strokeNoScale?: boolean | 
|     fillOpacity?: number | 
|     strokeOpacity?: number | 
|   | 
|     /** | 
|      * `true` is not supported. | 
|      * `false`/`null`/`undefined` are the same. | 
|      * `false` is used to remove lineDash in some | 
|      * case that `null`/`undefined` can not be set. | 
|      * (e.g., emphasis.lineStyle in echarts) | 
|      */ | 
|     lineDash?: false | number[] | 'solid' | 'dashed' | 'dotted' | 
|     lineDashOffset?: number | 
|   | 
|     lineWidth?: number | 
|     lineCap?: CanvasLineCap | 
|     lineJoin?: CanvasLineJoin | 
|   | 
|     miterLimit?: number | 
|     /** | 
|      * Paint order, if do stroke first. Similar to SVG paint-order | 
|      * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/paint-order | 
|      */ | 
|     strokeFirst?: boolean | 
| } | 
|   | 
| export const DEFAULT_PATH_STYLE: PathStyleProps = defaults({ | 
|     fill: '#000', | 
|     stroke: null, | 
|     strokePercent: 1, | 
|     fillOpacity: 1, | 
|     strokeOpacity: 1, | 
|   | 
|     lineDashOffset: 0, | 
|     lineWidth: 1, | 
|     lineCap: 'butt', | 
|     miterLimit: 10, | 
|   | 
|     strokeNoScale: false, | 
|     strokeFirst: false | 
| } as PathStyleProps, DEFAULT_COMMON_STYLE); | 
|   | 
|   | 
| export const DEFAULT_PATH_ANIMATION_PROPS: MapToType<PathProps, boolean> = { | 
|     style: defaults<MapToType<PathStyleProps, boolean>, MapToType<PathStyleProps, boolean>>({ | 
|         fill: true, | 
|         stroke: true, | 
|         strokePercent: true, | 
|         fillOpacity: true, | 
|         strokeOpacity: true, | 
|         lineDashOffset: true, | 
|         lineWidth: true, | 
|         miterLimit: true | 
|     } as MapToType<PathStyleProps, boolean>, DEFAULT_COMMON_ANIMATION_PROPS.style) | 
|  }; | 
|   | 
| export interface PathProps extends DisplayableProps { | 
|     strokeContainThreshold?: number | 
|     segmentIgnoreThreshold?: number | 
|     subPixelOptimize?: boolean | 
|   | 
|     style?: PathStyleProps | 
|     shape?: Dictionary<any> | 
|   | 
|     autoBatch?: boolean | 
|   | 
|     __value?: (string | number)[] | (string | number) | 
|   | 
|     buildPath?: ( | 
|         ctx: PathProxy | CanvasRenderingContext2D, | 
|         shapeCfg: Dictionary<any>, | 
|         inBatch?: boolean | 
|     ) => void | 
| } | 
|   | 
|   | 
| type PathKey = keyof PathProps | 
| type PathPropertyType = PropType<PathProps, PathKey> | 
|   | 
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | 
| interface Path<Props extends PathProps = PathProps> { | 
|     animate(key?: '', loop?: boolean): Animator<this> | 
|     animate(key: 'style', loop?: boolean): Animator<this['style']> | 
|     animate(key: 'shape', loop?: boolean): Animator<this['shape']> | 
|   | 
|     getState(stateName: string): PathState | 
|     ensureState(stateName: string): PathState | 
|   | 
|     states: Dictionary<PathState> | 
|     stateProxy: (stateName: string) => PathState | 
| } | 
|   | 
| export type PathStatePropNames = DisplayableStatePropNames | 'shape'; | 
| export type PathState = Pick<PathProps, PathStatePropNames> & { | 
|     hoverLayer?: boolean | 
| } | 
|   | 
| const pathCopyParams = (TRANSFORMABLE_PROPS as readonly string[]).concat(['invisible', | 
|     'culling', 'z', 'z2', 'zlevel', 'parent' | 
| ]) as (keyof Path)[]; | 
|   | 
| class Path<Props extends PathProps = PathProps> extends Displayable<Props> { | 
|   | 
|     path: PathProxy | 
|   | 
|     strokeContainThreshold: number | 
|   | 
|     // This item default to be false. But in map series in echarts, | 
|     // in order to improve performance, it should be set to true, | 
|     // so the shorty segment won't draw. | 
|     segmentIgnoreThreshold: number | 
|   | 
|     subPixelOptimize: boolean | 
|   | 
|     style: PathStyleProps | 
|     /** | 
|      * If element can be batched automatically | 
|      */ | 
|     autoBatch: boolean | 
|   | 
|     private _rectStroke: BoundingRect | 
|   | 
|     protected _normalState: PathState | 
|   | 
|     protected _decalEl: Path | 
|   | 
|     // Must have an initial value on shape. | 
|     // It will be assigned by default value. | 
|     shape: Dictionary<any> | 
|   | 
|     constructor(opts?: Props) { | 
|         super(opts); | 
|     } | 
|   | 
|     update() { | 
|         super.update(); | 
|   | 
|         const style = this.style; | 
|         if (style.decal) { | 
|             const decalEl: Path = this._decalEl = this._decalEl || new Path(); | 
|             if (decalEl.buildPath === Path.prototype.buildPath) { | 
|                 decalEl.buildPath = ctx => { | 
|                     this.buildPath(ctx, this.shape); | 
|                 }; | 
|             } | 
|   | 
|             decalEl.silent = true; | 
|   | 
|             const decalElStyle = decalEl.style; | 
|   | 
|             for (let key in style) { | 
|                 if ((decalElStyle as any)[key] !== (style as any)[key]) { | 
|                     (decalElStyle as any)[key] = (style as any)[key]; | 
|                 } | 
|             } | 
|             decalElStyle.fill = style.fill ? style.decal : null; | 
|             decalElStyle.decal = null; | 
|             decalElStyle.shadowColor = null; | 
|             style.strokeFirst && (decalElStyle.stroke = null); | 
|   | 
|             for (let i = 0; i < pathCopyParams.length; ++i) { | 
|                 (decalEl as any)[pathCopyParams[i]] = this[pathCopyParams[i]]; | 
|             } | 
|   | 
|             decalEl.__dirty |= REDRAW_BIT; | 
|         } | 
|         else if (this._decalEl) { | 
|             this._decalEl = null; | 
|         } | 
|     } | 
|   | 
|     getDecalElement() { | 
|         return this._decalEl; | 
|     } | 
|   | 
|     protected _init(props?: Props) { | 
|         // Init default properties | 
|         const keysArr = keys(props); | 
|   | 
|         this.shape = this.getDefaultShape(); | 
|         const defaultStyle = this.getDefaultStyle(); | 
|         if (defaultStyle) { | 
|             this.useStyle(defaultStyle); | 
|         } | 
|   | 
|         for (let i = 0; i < keysArr.length; i++) { | 
|             const key = keysArr[i]; | 
|             const value = props[key]; | 
|             if (key === 'style') { | 
|                 if (!this.style) { | 
|                     // PENDING Reuse style object if possible? | 
|                     this.useStyle(value as Props['style']); | 
|                 } | 
|                 else { | 
|                     extend(this.style, value as Props['style']); | 
|                 } | 
|             } | 
|             else if (key === 'shape') { | 
|                 // this.shape = value; | 
|                 extend(this.shape, value as Props['shape']); | 
|             } | 
|             else { | 
|                 super.attrKV(key as any, value); | 
|             } | 
|         } | 
|   | 
|         // Create an empty one if no style object exists. | 
|         if (!this.style) { | 
|             this.useStyle({}); | 
|         } | 
|         // const defaultShape = this.getDefaultShape(); | 
|         // if (!this.shape) { | 
|         //     this.shape = defaultShape; | 
|         // } | 
|         // else { | 
|         //     defaults(this.shape, defaultShape); | 
|         // } | 
|     } | 
|   | 
|     protected getDefaultStyle(): Props['style'] { | 
|         return null; | 
|     } | 
|   | 
|     // Needs to override | 
|     protected getDefaultShape() { | 
|         return {}; | 
|     } | 
|   | 
|     protected canBeInsideText() { | 
|         return this.hasFill(); | 
|     } | 
|   | 
|     protected getInsideTextFill() { | 
|         const pathFill = this.style.fill; | 
|         if (pathFill !== 'none') { | 
|             if (isString(pathFill)) { | 
|                 const fillLum = lum(pathFill, 0); | 
|                 // Determin text color based on the lum of path fill. | 
|                 // TODO use (1 - DARK_MODE_THRESHOLD)? | 
|                 if (fillLum > 0.5) {   // TODO Consider background lum? | 
|                     return DARK_LABEL_COLOR; | 
|                 } | 
|                 else if (fillLum > 0.2) { | 
|                     return LIGHTER_LABEL_COLOR; | 
|                 } | 
|                 return LIGHT_LABEL_COLOR; | 
|             } | 
|             else if (pathFill) { | 
|                 return LIGHT_LABEL_COLOR; | 
|             } | 
|   | 
|         } | 
|         return DARK_LABEL_COLOR; | 
|     } | 
|   | 
|     protected getInsideTextStroke(textFill?: string) { | 
|         const pathFill = this.style.fill; | 
|         // Not stroke on none fill object or gradient object | 
|         if (isString(pathFill)) { | 
|             const zr = this.__zr; | 
|             const isDarkMode = !!(zr && zr.isDarkMode()); | 
|             const isDarkLabel = lum(textFill, 0) < DARK_MODE_THRESHOLD; | 
|             // All dark or all light. | 
|             if (isDarkMode === isDarkLabel) { | 
|                 return pathFill; | 
|             } | 
|         } | 
|     } | 
|   | 
|     // When bundling path, some shape may decide if use moveTo to begin a new subpath or closePath | 
|     // Like in circle | 
|     buildPath( | 
|         ctx: PathProxy | CanvasRenderingContext2D, | 
|         shapeCfg: Dictionary<any>, | 
|         inBatch?: boolean | 
|     ) {} | 
|   | 
|     pathUpdated() { | 
|         this.__dirty &= ~SHAPE_CHANGED_BIT; | 
|     } | 
|   | 
|     getUpdatedPathProxy(inBatch?: boolean) { | 
|         // Update path proxy data to latest. | 
|         !this.path && this.createPathProxy(); | 
|         this.path.beginPath(); | 
|         this.buildPath(this.path, this.shape, inBatch); | 
|         return this.path; | 
|     } | 
|   | 
|     createPathProxy() { | 
|         this.path = new PathProxy(false); | 
|     } | 
|   | 
|     hasStroke() { | 
|         const style = this.style; | 
|         const stroke = style.stroke; | 
|         return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0)); | 
|     } | 
|   | 
|     hasFill() { | 
|         const style = this.style; | 
|         const fill = style.fill; | 
|         return fill != null && fill !== 'none'; | 
|     } | 
|   | 
|     getBoundingRect(): BoundingRect { | 
|         let rect = this._rect; | 
|         const style = this.style; | 
|         const needsUpdateRect = !rect; | 
|         if (needsUpdateRect) { | 
|             let firstInvoke = false; | 
|             if (!this.path) { | 
|                 firstInvoke = true; | 
|                 // Create path on demand. | 
|                 this.createPathProxy(); | 
|             } | 
|             let path = this.path; | 
|             if (firstInvoke || (this.__dirty & SHAPE_CHANGED_BIT)) { | 
|                 path.beginPath(); | 
|                 this.buildPath(path, this.shape, false); | 
|                 this.pathUpdated(); | 
|             } | 
|             rect = path.getBoundingRect(); | 
|         } | 
|         this._rect = rect; | 
|   | 
|         if (this.hasStroke() && this.path && this.path.len() > 0) { | 
|             // Needs update rect with stroke lineWidth when | 
|             // 1. Element changes scale or lineWidth | 
|             // 2. Shape is changed | 
|             const rectStroke = this._rectStroke || (this._rectStroke = rect.clone()); | 
|             if (this.__dirty || needsUpdateRect) { | 
|                 rectStroke.copy(rect); | 
|                 // PENDING, Min line width is needed when line is horizontal or vertical | 
|                 const lineScale = style.strokeNoScale ? this.getLineScale() : 1; | 
|                 // FIXME Must after updateTransform | 
|                 let w = style.lineWidth; | 
|   | 
|                 // Only add extra hover lineWidth when there are no fill | 
|                 if (!this.hasFill()) { | 
|                     const strokeContainThreshold = this.strokeContainThreshold; | 
|                     w = Math.max(w, strokeContainThreshold == null ? 4 : strokeContainThreshold); | 
|                 } | 
|                 // Consider line width | 
|                 // Line scale can't be 0; | 
|                 if (lineScale > 1e-10) { | 
|                     rectStroke.width += w / lineScale; | 
|                     rectStroke.height += w / lineScale; | 
|                     rectStroke.x -= w / lineScale / 2; | 
|                     rectStroke.y -= w / lineScale / 2; | 
|                 } | 
|             } | 
|   | 
|             // Return rect with stroke | 
|             return rectStroke; | 
|         } | 
|   | 
|         return rect; | 
|     } | 
|   | 
|     contain(x: number, y: number): boolean { | 
|         const localPos = this.transformCoordToLocal(x, y); | 
|         const rect = this.getBoundingRect(); | 
|         const style = this.style; | 
|         x = localPos[0]; | 
|         y = localPos[1]; | 
|   | 
|         if (rect.contain(x, y)) { | 
|             const pathProxy = this.path; | 
|             if (this.hasStroke()) { | 
|                 let lineWidth = style.lineWidth; | 
|                 let lineScale = style.strokeNoScale ? this.getLineScale() : 1; | 
|                 // Line scale can't be 0; | 
|                 if (lineScale > 1e-10) { | 
|                     // Only add extra hover lineWidth when there are no fill | 
|                     if (!this.hasFill()) { | 
|                         lineWidth = Math.max(lineWidth, this.strokeContainThreshold); | 
|                     } | 
|                     if (pathContain.containStroke( | 
|                         pathProxy, lineWidth / lineScale, x, y | 
|                     )) { | 
|                         return true; | 
|                     } | 
|                 } | 
|             } | 
|             if (this.hasFill()) { | 
|                 return pathContain.contain(pathProxy, x, y); | 
|             } | 
|         } | 
|         return false; | 
|     } | 
|   | 
|     /** | 
|      * Shape changed | 
|      */ | 
|     dirtyShape() { | 
|         this.__dirty |= SHAPE_CHANGED_BIT; | 
|         if (this._rect) { | 
|             this._rect = null; | 
|         } | 
|         if (this._decalEl) { | 
|             this._decalEl.dirtyShape(); | 
|         } | 
|         this.markRedraw(); | 
|     } | 
|   | 
|     dirty() { | 
|         this.dirtyStyle(); | 
|         this.dirtyShape(); | 
|     } | 
|   | 
|     /** | 
|      * Alias for animate('shape') | 
|      * @param {boolean} loop | 
|      */ | 
|     animateShape(loop: boolean) { | 
|         return this.animate('shape', loop); | 
|     } | 
|   | 
|     // Override updateDuringAnimation | 
|     updateDuringAnimation(targetKey: string) { | 
|         if (targetKey === 'style') { | 
|             this.dirtyStyle(); | 
|         } | 
|         else if (targetKey === 'shape') { | 
|             this.dirtyShape(); | 
|         } | 
|         else { | 
|             this.markRedraw(); | 
|         } | 
|     } | 
|   | 
|     // Overwrite attrKV | 
|     attrKV(key: PathKey, value: PathPropertyType) { | 
|         // FIXME | 
|         if (key === 'shape') { | 
|             this.setShape(value as Props['shape']); | 
|         } | 
|         else { | 
|             super.attrKV(key as keyof DisplayableProps, value); | 
|         } | 
|     } | 
|   | 
|     setShape(obj: Props['shape']): this | 
|     setShape<T extends keyof Props['shape']>(obj: T, value: Props['shape'][T]): this | 
|     setShape(keyOrObj: keyof Props['shape'] | Props['shape'], value?: unknown): this { | 
|         let shape = this.shape; | 
|         if (!shape) { | 
|             shape = this.shape = {}; | 
|         } | 
|         // Path from string may not have shape | 
|         if (typeof keyOrObj === 'string') { | 
|             shape[keyOrObj] = value; | 
|         } | 
|         else { | 
|             extend(shape, keyOrObj as Props['shape']); | 
|         } | 
|         this.dirtyShape(); | 
|   | 
|         return this; | 
|     } | 
|   | 
|     /** | 
|      * If shape changed. used with dirtyShape | 
|      */ | 
|     shapeChanged() { | 
|         return !!(this.__dirty & SHAPE_CHANGED_BIT); | 
|     } | 
|   | 
|     /** | 
|      * Create a path style object with default values in it's prototype. | 
|      * @override | 
|      */ | 
|     createStyle(obj?: Props['style']) { | 
|         return createObject(DEFAULT_PATH_STYLE, obj); | 
|     } | 
|   | 
|     protected _innerSaveToNormal(toState: PathState) { | 
|         super._innerSaveToNormal(toState); | 
|   | 
|         const normalState = this._normalState; | 
|         // Clone a new one. DON'T share object reference between states and current using. | 
|         // TODO: Clone array in shape?. | 
|         // TODO: Only save changed shape. | 
|         if (toState.shape && !normalState.shape) { | 
|             normalState.shape = extend({}, this.shape); | 
|         } | 
|     } | 
|   | 
|     protected _applyStateObj( | 
|         stateName: string, | 
|         state: PathState, | 
|         normalState: PathState, | 
|         keepCurrentStates: boolean, | 
|         transition: boolean, | 
|         animationCfg: ElementAnimateConfig | 
|     ) { | 
|         super._applyStateObj(stateName, state, normalState, keepCurrentStates, transition, animationCfg); | 
|         const needsRestoreToNormal = !(state && keepCurrentStates); | 
|         let targetShape: Props['shape']; | 
|         if (state && state.shape) { | 
|             // Only animate changed properties. | 
|             if (transition) { | 
|                 if (keepCurrentStates) { | 
|                     targetShape = state.shape; | 
|                 } | 
|                 else { | 
|                     // Inherits from normal state. | 
|                     targetShape = extend({}, normalState.shape); | 
|                     extend(targetShape, state.shape); | 
|                 } | 
|             } | 
|             else { | 
|                 // Because the shape will be replaced. So inherits from current shape. | 
|                 targetShape = extend({}, keepCurrentStates ? this.shape : normalState.shape); | 
|                 extend(targetShape, state.shape); | 
|             } | 
|         } | 
|         else if (needsRestoreToNormal) { | 
|             targetShape = normalState.shape; | 
|         } | 
|   | 
|         if (targetShape) { | 
|             if (transition) { | 
|                 // Clone a new shape. | 
|                 this.shape = extend({}, this.shape); | 
|                 // Only supports transition on primary props. Because shape is not deep cloned. | 
|                 const targetShapePrimaryProps: Props['shape'] = {}; | 
|                 const shapeKeys = keys(targetShape); | 
|                 for (let i = 0; i < shapeKeys.length; i++) { | 
|                     const key = shapeKeys[i]; | 
|                     if (typeof targetShape[key] === 'object') { | 
|                         (this.shape as Props['shape'])[key] = targetShape[key]; | 
|                     } | 
|                     else { | 
|                         targetShapePrimaryProps[key] = targetShape[key]; | 
|                     } | 
|                 } | 
|                 this._transitionState(stateName, { | 
|                     shape: targetShapePrimaryProps | 
|                 } as Props, animationCfg); | 
|             } | 
|             else { | 
|                 this.shape = targetShape; | 
|                 this.dirtyShape(); | 
|             } | 
|         } | 
|     } | 
|   | 
|     protected _mergeStates(states: PathState[]) { | 
|         const mergedState = super._mergeStates(states) as PathState; | 
|         let mergedShape: Props['shape']; | 
|         for (let i = 0; i < states.length; i++) { | 
|             const state = states[i]; | 
|             if (state.shape) { | 
|                 mergedShape = mergedShape || {}; | 
|                 this._mergeStyle(mergedShape, state.shape); | 
|             } | 
|         } | 
|         if (mergedShape) { | 
|             mergedState.shape = mergedShape; | 
|         } | 
|         return mergedState; | 
|     } | 
|   | 
|     getAnimationStyleProps() { | 
|         return DEFAULT_PATH_ANIMATION_PROPS; | 
|     } | 
|     /** | 
|      * If path shape is zero area | 
|      */ | 
|     isZeroArea(): boolean { | 
|         return false; | 
|     } | 
|     /** | 
|      * 扩展一个 Path element, 比如星形,圆等。 | 
|      * Extend a path element | 
|      * @DEPRECATED Use class extends | 
|      * @param props | 
|      * @param props.type Path type | 
|      * @param props.init Initialize | 
|      * @param props.buildPath Overwrite buildPath method | 
|      * @param props.style Extended default style config | 
|      * @param props.shape Extended default shape config | 
|      */ | 
|     static extend<Shape extends Dictionary<any>>(defaultProps: { | 
|         type?: string | 
|         shape?: Shape | 
|         style?: PathStyleProps | 
|         beforeBrush?: Displayable['beforeBrush'] | 
|         afterBrush?: Displayable['afterBrush'] | 
|         getBoundingRect?: Displayable['getBoundingRect'] | 
|   | 
|         calculateTextPosition?: Element['calculateTextPosition'] | 
|         buildPath(this: Path, ctx: CanvasRenderingContext2D | PathProxy, shape: Shape, inBatch?: boolean): void | 
|         init?(this: Path, opts: PathProps): void // TODO Should be SubPathOption | 
|     }): { | 
|         new(opts?: PathProps & {shape: Shape}): Path | 
|     } { | 
|         interface SubPathOption extends PathProps { | 
|             shape: Shape | 
|         } | 
|   | 
|         class Sub extends Path { | 
|   | 
|             shape: Shape | 
|   | 
|             getDefaultStyle() { | 
|                 return clone(defaultProps.style); | 
|             } | 
|   | 
|             getDefaultShape() { | 
|                 return clone(defaultProps.shape); | 
|             } | 
|   | 
|             constructor(opts?: SubPathOption) { | 
|                 super(opts); | 
|                 defaultProps.init && defaultProps.init.call(this as any, opts); | 
|             } | 
|         } | 
|   | 
|         // TODO Legacy usage. Extend functions | 
|         for (let key in defaultProps) { | 
|             if (typeof (defaultProps as any)[key] === 'function') { | 
|                 (Sub.prototype as any)[key] = (defaultProps as any)[key]; | 
|             } | 
|         } | 
|         // Sub.prototype.buildPath = defaultProps.buildPath; | 
|         // Sub.prototype.beforeBrush = defaultProps.beforeBrush; | 
|         // Sub.prototype.afterBrush = defaultProps.afterBrush; | 
|   | 
|         return Sub as any; | 
|     } | 
|   | 
|     protected static initDefaultProps = (function () { | 
|         const pathProto = Path.prototype; | 
|         pathProto.type = 'path'; | 
|         pathProto.strokeContainThreshold = 5; | 
|         pathProto.segmentIgnoreThreshold = 0; | 
|         pathProto.subPixelOptimize = false; | 
|         pathProto.autoBatch = false; | 
|         pathProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT | SHAPE_CHANGED_BIT; | 
|     })() | 
| } | 
|   | 
| export default Path; |