|   | 
| /* | 
| * Licensed to the Apache Software Foundation (ASF) under one | 
| * or more contributor license agreements.  See the NOTICE file | 
| * distributed with this work for additional information | 
| * regarding copyright ownership.  The ASF licenses this file | 
| * to you under the Apache License, Version 2.0 (the | 
| * "License"); you may not use this file except in compliance | 
| * with the License.  You may obtain a copy of the License at | 
| * | 
| *   http://www.apache.org/licenses/LICENSE-2.0 | 
| * | 
| * Unless required by applicable law or agreed to in writing, | 
| * software distributed under the License is distributed on an | 
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
| * KIND, either express or implied.  See the License for the | 
| * specific language governing permissions and limitations | 
| * under the License. | 
| */ | 
|   | 
|   | 
| /** | 
|  * AUTO-GENERATED FILE. DO NOT MODIFY. | 
|  */ | 
|   | 
| /* | 
| * Licensed to the Apache Software Foundation (ASF) under one | 
| * or more contributor license agreements.  See the NOTICE file | 
| * distributed with this work for additional information | 
| * regarding copyright ownership.  The ASF licenses this file | 
| * to you under the Apache License, Version 2.0 (the | 
| * "License"); you may not use this file except in compliance | 
| * with the License.  You may obtain a copy of the License at | 
| * | 
| *   http://www.apache.org/licenses/LICENSE-2.0 | 
| * | 
| * Unless required by applicable law or agreed to in writing, | 
| * software distributed under the License is distributed on an | 
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
| * KIND, either express or implied.  See the License for the | 
| * specific language governing permissions and limitations | 
| * under the License. | 
| */ | 
| import { __extends } from "tslib"; | 
| import { curry, each, map, bind, merge, clone, defaults, assert } from 'zrender/lib/core/util.js'; | 
| import Eventful from 'zrender/lib/core/Eventful.js'; | 
| import * as graphic from '../../util/graphic.js'; | 
| import * as interactionMutex from './interactionMutex.js'; | 
| import DataDiffer from '../../data/DataDiffer.js'; | 
| var BRUSH_PANEL_GLOBAL = true; | 
| var mathMin = Math.min; | 
| var mathMax = Math.max; | 
| var mathPow = Math.pow; | 
| var COVER_Z = 10000; | 
| var UNSELECT_THRESHOLD = 6; | 
| var MIN_RESIZE_LINE_WIDTH = 6; | 
| var MUTEX_RESOURCE_KEY = 'globalPan'; | 
| var DIRECTION_MAP = { | 
|   w: [0, 0], | 
|   e: [0, 1], | 
|   n: [1, 0], | 
|   s: [1, 1] | 
| }; | 
| var CURSOR_MAP = { | 
|   w: 'ew', | 
|   e: 'ew', | 
|   n: 'ns', | 
|   s: 'ns', | 
|   ne: 'nesw', | 
|   sw: 'nesw', | 
|   nw: 'nwse', | 
|   se: 'nwse' | 
| }; | 
| var DEFAULT_BRUSH_OPT = { | 
|   brushStyle: { | 
|     lineWidth: 2, | 
|     stroke: 'rgba(210,219,238,0.3)', | 
|     fill: '#D2DBEE' | 
|   }, | 
|   transformable: true, | 
|   brushMode: 'single', | 
|   removeOnClick: false | 
| }; | 
| var baseUID = 0; | 
| /** | 
|  * params: | 
|  *     areas: Array.<Array>, coord relates to container group, | 
|  *                             If no container specified, to global. | 
|  *     opt { | 
|  *         isEnd: boolean, | 
|  *         removeOnClick: boolean | 
|  *     } | 
|  */ | 
| var BrushController = /** @class */function (_super) { | 
|   __extends(BrushController, _super); | 
|   function BrushController(zr) { | 
|     var _this = _super.call(this) || this; | 
|     /** | 
|      * @internal | 
|      */ | 
|     _this._track = []; | 
|     /** | 
|      * @internal | 
|      */ | 
|     _this._covers = []; | 
|     _this._handlers = {}; | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assert(zr); | 
|     } | 
|     _this._zr = zr; | 
|     _this.group = new graphic.Group(); | 
|     _this._uid = 'brushController_' + baseUID++; | 
|     each(pointerHandlers, function (handler, eventName) { | 
|       this._handlers[eventName] = bind(handler, this); | 
|     }, _this); | 
|     return _this; | 
|   } | 
|   /** | 
|    * If set to `false`, select disabled. | 
|    */ | 
|   BrushController.prototype.enableBrush = function (brushOption) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assert(this._mounted); | 
|     } | 
|     this._brushType && this._doDisableBrush(); | 
|     brushOption.brushType && this._doEnableBrush(brushOption); | 
|     return this; | 
|   }; | 
|   BrushController.prototype._doEnableBrush = function (brushOption) { | 
|     var zr = this._zr; | 
|     // Consider roam, which takes globalPan too. | 
|     if (!this._enableGlobalPan) { | 
|       interactionMutex.take(zr, MUTEX_RESOURCE_KEY, this._uid); | 
|     } | 
|     each(this._handlers, function (handler, eventName) { | 
|       zr.on(eventName, handler); | 
|     }); | 
|     this._brushType = brushOption.brushType; | 
|     this._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true); | 
|   }; | 
|   BrushController.prototype._doDisableBrush = function () { | 
|     var zr = this._zr; | 
|     interactionMutex.release(zr, MUTEX_RESOURCE_KEY, this._uid); | 
|     each(this._handlers, function (handler, eventName) { | 
|       zr.off(eventName, handler); | 
|     }); | 
|     this._brushType = this._brushOption = null; | 
|   }; | 
|   /** | 
|    * @param panelOpts If not pass, it is global brush. | 
|    */ | 
|   BrushController.prototype.setPanels = function (panelOpts) { | 
|     if (panelOpts && panelOpts.length) { | 
|       var panels_1 = this._panels = {}; | 
|       each(panelOpts, function (panelOpts) { | 
|         panels_1[panelOpts.panelId] = clone(panelOpts); | 
|       }); | 
|     } else { | 
|       this._panels = null; | 
|     } | 
|     return this; | 
|   }; | 
|   BrushController.prototype.mount = function (opt) { | 
|     opt = opt || {}; | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       this._mounted = true; // should be at first. | 
|     } | 
|     this._enableGlobalPan = opt.enableGlobalPan; | 
|     var thisGroup = this.group; | 
|     this._zr.add(thisGroup); | 
|     thisGroup.attr({ | 
|       x: opt.x || 0, | 
|       y: opt.y || 0, | 
|       rotation: opt.rotation || 0, | 
|       scaleX: opt.scaleX || 1, | 
|       scaleY: opt.scaleY || 1 | 
|     }); | 
|     this._transform = thisGroup.getLocalTransform(); | 
|     return this; | 
|   }; | 
|   // eachCover(cb, context): void { | 
|   //     each(this._covers, cb, context); | 
|   // } | 
|   /** | 
|    * Update covers. | 
|    * @param coverConfigList | 
|    *        If coverConfigList is null/undefined, all covers removed. | 
|    */ | 
|   BrushController.prototype.updateCovers = function (coverConfigList) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assert(this._mounted); | 
|     } | 
|     coverConfigList = map(coverConfigList, function (coverConfig) { | 
|       return merge(clone(DEFAULT_BRUSH_OPT), coverConfig, true); | 
|     }); | 
|     var tmpIdPrefix = '\0-brush-index-'; | 
|     var oldCovers = this._covers; | 
|     var newCovers = this._covers = []; | 
|     var controller = this; | 
|     var creatingCover = this._creatingCover; | 
|     new DataDiffer(oldCovers, coverConfigList, oldGetKey, getKey).add(addOrUpdate).update(addOrUpdate).remove(remove).execute(); | 
|     return this; | 
|     function getKey(brushOption, index) { | 
|       return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + '-' + brushOption.brushType; | 
|     } | 
|     function oldGetKey(cover, index) { | 
|       return getKey(cover.__brushOption, index); | 
|     } | 
|     function addOrUpdate(newIndex, oldIndex) { | 
|       var newBrushInternal = coverConfigList[newIndex]; | 
|       // Consider setOption in event listener of brushSelect, | 
|       // where updating cover when creating should be forbidden. | 
|       if (oldIndex != null && oldCovers[oldIndex] === creatingCover) { | 
|         newCovers[newIndex] = oldCovers[oldIndex]; | 
|       } else { | 
|         var cover = newCovers[newIndex] = oldIndex != null ? (oldCovers[oldIndex].__brushOption = newBrushInternal, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushInternal)); | 
|         updateCoverAfterCreation(controller, cover); | 
|       } | 
|     } | 
|     function remove(oldIndex) { | 
|       if (oldCovers[oldIndex] !== creatingCover) { | 
|         controller.group.remove(oldCovers[oldIndex]); | 
|       } | 
|     } | 
|   }; | 
|   BrushController.prototype.unmount = function () { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       if (!this._mounted) { | 
|         return; | 
|       } | 
|     } | 
|     this.enableBrush(false); | 
|     // container may 'removeAll' outside. | 
|     clearCovers(this); | 
|     this._zr.remove(this.group); | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       this._mounted = false; // should be at last. | 
|     } | 
|     return this; | 
|   }; | 
|   BrushController.prototype.dispose = function () { | 
|     this.unmount(); | 
|     this.off(); | 
|   }; | 
|   return BrushController; | 
| }(Eventful); | 
| function createCover(controller, brushOption) { | 
|   var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption); | 
|   cover.__brushOption = brushOption; | 
|   updateZ(cover, brushOption); | 
|   controller.group.add(cover); | 
|   return cover; | 
| } | 
| function endCreating(controller, creatingCover) { | 
|   var coverRenderer = getCoverRenderer(creatingCover); | 
|   if (coverRenderer.endCreating) { | 
|     coverRenderer.endCreating(controller, creatingCover); | 
|     updateZ(creatingCover, creatingCover.__brushOption); | 
|   } | 
|   return creatingCover; | 
| } | 
| function updateCoverShape(controller, cover) { | 
|   var brushOption = cover.__brushOption; | 
|   getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption); | 
| } | 
| function updateZ(cover, brushOption) { | 
|   var z = brushOption.z; | 
|   z == null && (z = COVER_Z); | 
|   cover.traverse(function (el) { | 
|     el.z = z; | 
|     el.z2 = z; // Consider in given container. | 
|   }); | 
| } | 
| function updateCoverAfterCreation(controller, cover) { | 
|   getCoverRenderer(cover).updateCommon(controller, cover); | 
|   updateCoverShape(controller, cover); | 
| } | 
| function getCoverRenderer(cover) { | 
|   return coverRenderers[cover.__brushOption.brushType]; | 
| } | 
| // return target panel or `true` (means global panel) | 
| function getPanelByPoint(controller, e, localCursorPoint) { | 
|   var panels = controller._panels; | 
|   if (!panels) { | 
|     return BRUSH_PANEL_GLOBAL; // Global panel | 
|   } | 
|   var panel; | 
|   var transform = controller._transform; | 
|   each(panels, function (pn) { | 
|     pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn); | 
|   }); | 
|   return panel; | 
| } | 
| // Return a panel or true | 
| function getPanelByCover(controller, cover) { | 
|   var panels = controller._panels; | 
|   if (!panels) { | 
|     return BRUSH_PANEL_GLOBAL; // Global panel | 
|   } | 
|   var panelId = cover.__brushOption.panelId; | 
|   // User may give cover without coord sys info, | 
|   // which is then treated as global panel. | 
|   return panelId != null ? panels[panelId] : BRUSH_PANEL_GLOBAL; | 
| } | 
| function clearCovers(controller) { | 
|   var covers = controller._covers; | 
|   var originalLength = covers.length; | 
|   each(covers, function (cover) { | 
|     controller.group.remove(cover); | 
|   }, controller); | 
|   covers.length = 0; | 
|   return !!originalLength; | 
| } | 
| function trigger(controller, opt) { | 
|   var areas = map(controller._covers, function (cover) { | 
|     var brushOption = cover.__brushOption; | 
|     var range = clone(brushOption.range); | 
|     return { | 
|       brushType: brushOption.brushType, | 
|       panelId: brushOption.panelId, | 
|       range: range | 
|     }; | 
|   }); | 
|   controller.trigger('brush', { | 
|     areas: areas, | 
|     isEnd: !!opt.isEnd, | 
|     removeOnClick: !!opt.removeOnClick | 
|   }); | 
| } | 
| function shouldShowCover(controller) { | 
|   var track = controller._track; | 
|   if (!track.length) { | 
|     return false; | 
|   } | 
|   var p2 = track[track.length - 1]; | 
|   var p1 = track[0]; | 
|   var dx = p2[0] - p1[0]; | 
|   var dy = p2[1] - p1[1]; | 
|   var dist = mathPow(dx * dx + dy * dy, 0.5); | 
|   return dist > UNSELECT_THRESHOLD; | 
| } | 
| function getTrackEnds(track) { | 
|   var tail = track.length - 1; | 
|   tail < 0 && (tail = 0); | 
|   return [track[0], track[tail]]; | 
| } | 
| ; | 
| function createBaseRectCover(rectRangeConverter, controller, brushOption, edgeNameSequences) { | 
|   var cover = new graphic.Group(); | 
|   cover.add(new graphic.Rect({ | 
|     name: 'main', | 
|     style: makeStyle(brushOption), | 
|     silent: true, | 
|     draggable: true, | 
|     cursor: 'move', | 
|     drift: curry(driftRect, rectRangeConverter, controller, cover, ['n', 's', 'w', 'e']), | 
|     ondragend: curry(trigger, controller, { | 
|       isEnd: true | 
|     }) | 
|   })); | 
|   each(edgeNameSequences, function (nameSequence) { | 
|     cover.add(new graphic.Rect({ | 
|       name: nameSequence.join(''), | 
|       style: { | 
|         opacity: 0 | 
|       }, | 
|       draggable: true, | 
|       silent: true, | 
|       invisible: true, | 
|       drift: curry(driftRect, rectRangeConverter, controller, cover, nameSequence), | 
|       ondragend: curry(trigger, controller, { | 
|         isEnd: true | 
|       }) | 
|     })); | 
|   }); | 
|   return cover; | 
| } | 
| function updateBaseRect(controller, cover, localRange, brushOption) { | 
|   var lineWidth = brushOption.brushStyle.lineWidth || 0; | 
|   var handleSize = mathMax(lineWidth, MIN_RESIZE_LINE_WIDTH); | 
|   var x = localRange[0][0]; | 
|   var y = localRange[1][0]; | 
|   var xa = x - lineWidth / 2; | 
|   var ya = y - lineWidth / 2; | 
|   var x2 = localRange[0][1]; | 
|   var y2 = localRange[1][1]; | 
|   var x2a = x2 - handleSize + lineWidth / 2; | 
|   var y2a = y2 - handleSize + lineWidth / 2; | 
|   var width = x2 - x; | 
|   var height = y2 - y; | 
|   var widtha = width + lineWidth; | 
|   var heighta = height + lineWidth; | 
|   updateRectShape(controller, cover, 'main', x, y, width, height); | 
|   if (brushOption.transformable) { | 
|     updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta); | 
|     updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta); | 
|     updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize); | 
|     updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize); | 
|     updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize); | 
|     updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize); | 
|     updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize); | 
|     updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize); | 
|   } | 
| } | 
| function updateCommon(controller, cover) { | 
|   var brushOption = cover.__brushOption; | 
|   var transformable = brushOption.transformable; | 
|   var mainEl = cover.childAt(0); | 
|   mainEl.useStyle(makeStyle(brushOption)); | 
|   mainEl.attr({ | 
|     silent: !transformable, | 
|     cursor: transformable ? 'move' : 'default' | 
|   }); | 
|   each([['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']], function (nameSequence) { | 
|     var el = cover.childOfName(nameSequence.join('')); | 
|     var globalDir = nameSequence.length === 1 ? getGlobalDirection1(controller, nameSequence[0]) : getGlobalDirection2(controller, nameSequence); | 
|     el && el.attr({ | 
|       silent: !transformable, | 
|       invisible: !transformable, | 
|       cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null | 
|     }); | 
|   }); | 
| } | 
| function updateRectShape(controller, cover, name, x, y, w, h) { | 
|   var el = cover.childOfName(name); | 
|   el && el.setShape(pointsToRect(clipByPanel(controller, cover, [[x, y], [x + w, y + h]]))); | 
| } | 
| function makeStyle(brushOption) { | 
|   return defaults({ | 
|     strokeNoScale: true | 
|   }, brushOption.brushStyle); | 
| } | 
| function formatRectRange(x, y, x2, y2) { | 
|   var min = [mathMin(x, x2), mathMin(y, y2)]; | 
|   var max = [mathMax(x, x2), mathMax(y, y2)]; | 
|   return [[min[0], max[0]], [min[1], max[1]] // y range | 
|   ]; | 
| } | 
| function getTransform(controller) { | 
|   return graphic.getTransform(controller.group); | 
| } | 
| function getGlobalDirection1(controller, localDirName) { | 
|   var map = { | 
|     w: 'left', | 
|     e: 'right', | 
|     n: 'top', | 
|     s: 'bottom' | 
|   }; | 
|   var inverseMap = { | 
|     left: 'w', | 
|     right: 'e', | 
|     top: 'n', | 
|     bottom: 's' | 
|   }; | 
|   var dir = graphic.transformDirection(map[localDirName], getTransform(controller)); | 
|   return inverseMap[dir]; | 
| } | 
| function getGlobalDirection2(controller, localDirNameSeq) { | 
|   var globalDir = [getGlobalDirection1(controller, localDirNameSeq[0]), getGlobalDirection1(controller, localDirNameSeq[1])]; | 
|   (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse(); | 
|   return globalDir.join(''); | 
| } | 
| function driftRect(rectRangeConverter, controller, cover, dirNameSequence, dx, dy) { | 
|   var brushOption = cover.__brushOption; | 
|   var rectRange = rectRangeConverter.toRectRange(brushOption.range); | 
|   var localDelta = toLocalDelta(controller, dx, dy); | 
|   each(dirNameSequence, function (dirName) { | 
|     var ind = DIRECTION_MAP[dirName]; | 
|     rectRange[ind[0]][ind[1]] += localDelta[ind[0]]; | 
|   }); | 
|   brushOption.range = rectRangeConverter.fromRectRange(formatRectRange(rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1])); | 
|   updateCoverAfterCreation(controller, cover); | 
|   trigger(controller, { | 
|     isEnd: false | 
|   }); | 
| } | 
| function driftPolygon(controller, cover, dx, dy) { | 
|   var range = cover.__brushOption.range; | 
|   var localDelta = toLocalDelta(controller, dx, dy); | 
|   each(range, function (point) { | 
|     point[0] += localDelta[0]; | 
|     point[1] += localDelta[1]; | 
|   }); | 
|   updateCoverAfterCreation(controller, cover); | 
|   trigger(controller, { | 
|     isEnd: false | 
|   }); | 
| } | 
| function toLocalDelta(controller, dx, dy) { | 
|   var thisGroup = controller.group; | 
|   var localD = thisGroup.transformCoordToLocal(dx, dy); | 
|   var localZero = thisGroup.transformCoordToLocal(0, 0); | 
|   return [localD[0] - localZero[0], localD[1] - localZero[1]]; | 
| } | 
| function clipByPanel(controller, cover, data) { | 
|   var panel = getPanelByCover(controller, cover); | 
|   return panel && panel !== BRUSH_PANEL_GLOBAL ? panel.clipPath(data, controller._transform) : clone(data); | 
| } | 
| function pointsToRect(points) { | 
|   var xmin = mathMin(points[0][0], points[1][0]); | 
|   var ymin = mathMin(points[0][1], points[1][1]); | 
|   var xmax = mathMax(points[0][0], points[1][0]); | 
|   var ymax = mathMax(points[0][1], points[1][1]); | 
|   return { | 
|     x: xmin, | 
|     y: ymin, | 
|     width: xmax - xmin, | 
|     height: ymax - ymin | 
|   }; | 
| } | 
| function resetCursor(controller, e, localCursorPoint) { | 
|   if ( | 
|   // Check active | 
|   !controller._brushType | 
|   // resetCursor should be always called when mouse is in zr area, | 
|   // but not called when mouse is out of zr area to avoid bad influence | 
|   // if `mousemove`, `mouseup` are triggered from `document` event. | 
|   || isOutsideZrArea(controller, e.offsetX, e.offsetY)) { | 
|     return; | 
|   } | 
|   var zr = controller._zr; | 
|   var covers = controller._covers; | 
|   var currPanel = getPanelByPoint(controller, e, localCursorPoint); | 
|   // Check whether in covers. | 
|   if (!controller._dragging) { | 
|     for (var i = 0; i < covers.length; i++) { | 
|       var brushOption = covers[i].__brushOption; | 
|       if (currPanel && (currPanel === BRUSH_PANEL_GLOBAL || brushOption.panelId === currPanel.panelId) && coverRenderers[brushOption.brushType].contain(covers[i], localCursorPoint[0], localCursorPoint[1])) { | 
|         // Use cursor style set on cover. | 
|         return; | 
|       } | 
|     } | 
|   } | 
|   currPanel && zr.setCursorStyle('crosshair'); | 
| } | 
| function preventDefault(e) { | 
|   var rawE = e.event; | 
|   rawE.preventDefault && rawE.preventDefault(); | 
| } | 
| function mainShapeContain(cover, x, y) { | 
|   return cover.childOfName('main').contain(x, y); | 
| } | 
| function updateCoverByMouse(controller, e, localCursorPoint, isEnd) { | 
|   var creatingCover = controller._creatingCover; | 
|   var panel = controller._creatingPanel; | 
|   var thisBrushOption = controller._brushOption; | 
|   var eventParams; | 
|   controller._track.push(localCursorPoint.slice()); | 
|   if (shouldShowCover(controller) || creatingCover) { | 
|     if (panel && !creatingCover) { | 
|       thisBrushOption.brushMode === 'single' && clearCovers(controller); | 
|       var brushOption = clone(thisBrushOption); | 
|       brushOption.brushType = determineBrushType(brushOption.brushType, panel); | 
|       brushOption.panelId = panel === BRUSH_PANEL_GLOBAL ? null : panel.panelId; | 
|       creatingCover = controller._creatingCover = createCover(controller, brushOption); | 
|       controller._covers.push(creatingCover); | 
|     } | 
|     if (creatingCover) { | 
|       var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)]; | 
|       var coverBrushOption = creatingCover.__brushOption; | 
|       coverBrushOption.range = coverRenderer.getCreatingRange(clipByPanel(controller, creatingCover, controller._track)); | 
|       if (isEnd) { | 
|         endCreating(controller, creatingCover); | 
|         coverRenderer.updateCommon(controller, creatingCover); | 
|       } | 
|       updateCoverShape(controller, creatingCover); | 
|       eventParams = { | 
|         isEnd: isEnd | 
|       }; | 
|     } | 
|   } else if (isEnd && thisBrushOption.brushMode === 'single' && thisBrushOption.removeOnClick) { | 
|     // Help user to remove covers easily, only by a tiny drag, in 'single' mode. | 
|     // But a single click do not clear covers, because user may have casual | 
|     // clicks (for example, click on other component and do not expect covers | 
|     // disappear). | 
|     // Only some cover removed, trigger action, but not every click trigger action. | 
|     if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) { | 
|       eventParams = { | 
|         isEnd: isEnd, | 
|         removeOnClick: true | 
|       }; | 
|     } | 
|   } | 
|   return eventParams; | 
| } | 
| function determineBrushType(brushType, panel) { | 
|   if (brushType === 'auto') { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assert(panel && panel.defaultBrushType, 'MUST have defaultBrushType when brushType is "atuo"'); | 
|     } | 
|     return panel.defaultBrushType; | 
|   } | 
|   return brushType; | 
| } | 
| var pointerHandlers = { | 
|   mousedown: function (e) { | 
|     if (this._dragging) { | 
|       // In case some browser do not support globalOut, | 
|       // and release mouse out side the browser. | 
|       handleDragEnd(this, e); | 
|     } else if (!e.target || !e.target.draggable) { | 
|       preventDefault(e); | 
|       var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY); | 
|       this._creatingCover = null; | 
|       var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint); | 
|       if (panel) { | 
|         this._dragging = true; | 
|         this._track = [localCursorPoint.slice()]; | 
|       } | 
|     } | 
|   }, | 
|   mousemove: function (e) { | 
|     var x = e.offsetX; | 
|     var y = e.offsetY; | 
|     var localCursorPoint = this.group.transformCoordToLocal(x, y); | 
|     resetCursor(this, e, localCursorPoint); | 
|     if (this._dragging) { | 
|       preventDefault(e); | 
|       var eventParams = updateCoverByMouse(this, e, localCursorPoint, false); | 
|       eventParams && trigger(this, eventParams); | 
|     } | 
|   }, | 
|   mouseup: function (e) { | 
|     handleDragEnd(this, e); | 
|   } | 
| }; | 
| function handleDragEnd(controller, e) { | 
|   if (controller._dragging) { | 
|     preventDefault(e); | 
|     var x = e.offsetX; | 
|     var y = e.offsetY; | 
|     var localCursorPoint = controller.group.transformCoordToLocal(x, y); | 
|     var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true); | 
|     controller._dragging = false; | 
|     controller._track = []; | 
|     controller._creatingCover = null; | 
|     // trigger event should be at final, after procedure will be nested. | 
|     eventParams && trigger(controller, eventParams); | 
|   } | 
| } | 
| function isOutsideZrArea(controller, x, y) { | 
|   var zr = controller._zr; | 
|   return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight(); | 
| } | 
| /** | 
|  * key: brushType | 
|  */ | 
| var coverRenderers = { | 
|   lineX: getLineRenderer(0), | 
|   lineY: getLineRenderer(1), | 
|   rect: { | 
|     createCover: function (controller, brushOption) { | 
|       function returnInput(range) { | 
|         return range; | 
|       } | 
|       return createBaseRectCover({ | 
|         toRectRange: returnInput, | 
|         fromRectRange: returnInput | 
|       }, controller, brushOption, [['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']]); | 
|     }, | 
|     getCreatingRange: function (localTrack) { | 
|       var ends = getTrackEnds(localTrack); | 
|       return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]); | 
|     }, | 
|     updateCoverShape: function (controller, cover, localRange, brushOption) { | 
|       updateBaseRect(controller, cover, localRange, brushOption); | 
|     }, | 
|     updateCommon: updateCommon, | 
|     contain: mainShapeContain | 
|   }, | 
|   polygon: { | 
|     createCover: function (controller, brushOption) { | 
|       var cover = new graphic.Group(); | 
|       // Do not use graphic.Polygon because graphic.Polyline do not close the | 
|       // border of the shape when drawing, which is a better experience for user. | 
|       cover.add(new graphic.Polyline({ | 
|         name: 'main', | 
|         style: makeStyle(brushOption), | 
|         silent: true | 
|       })); | 
|       return cover; | 
|     }, | 
|     getCreatingRange: function (localTrack) { | 
|       return localTrack; | 
|     }, | 
|     endCreating: function (controller, cover) { | 
|       cover.remove(cover.childAt(0)); | 
|       // Use graphic.Polygon close the shape. | 
|       cover.add(new graphic.Polygon({ | 
|         name: 'main', | 
|         draggable: true, | 
|         drift: curry(driftPolygon, controller, cover), | 
|         ondragend: curry(trigger, controller, { | 
|           isEnd: true | 
|         }) | 
|       })); | 
|     }, | 
|     updateCoverShape: function (controller, cover, localRange, brushOption) { | 
|       cover.childAt(0).setShape({ | 
|         points: clipByPanel(controller, cover, localRange) | 
|       }); | 
|     }, | 
|     updateCommon: updateCommon, | 
|     contain: mainShapeContain | 
|   } | 
| }; | 
| function getLineRenderer(xyIndex) { | 
|   return { | 
|     createCover: function (controller, brushOption) { | 
|       return createBaseRectCover({ | 
|         toRectRange: function (range) { | 
|           var rectRange = [range, [0, 100]]; | 
|           xyIndex && rectRange.reverse(); | 
|           return rectRange; | 
|         }, | 
|         fromRectRange: function (rectRange) { | 
|           return rectRange[xyIndex]; | 
|         } | 
|       }, controller, brushOption, [[['w'], ['e']], [['n'], ['s']]][xyIndex]); | 
|     }, | 
|     getCreatingRange: function (localTrack) { | 
|       var ends = getTrackEnds(localTrack); | 
|       var min = mathMin(ends[0][xyIndex], ends[1][xyIndex]); | 
|       var max = mathMax(ends[0][xyIndex], ends[1][xyIndex]); | 
|       return [min, max]; | 
|     }, | 
|     updateCoverShape: function (controller, cover, localRange, brushOption) { | 
|       var otherExtent; | 
|       // If brushWidth not specified, fit the panel. | 
|       var panel = getPanelByCover(controller, cover); | 
|       if (panel !== BRUSH_PANEL_GLOBAL && panel.getLinearBrushOtherExtent) { | 
|         otherExtent = panel.getLinearBrushOtherExtent(xyIndex); | 
|       } else { | 
|         var zr = controller._zr; | 
|         otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]]; | 
|       } | 
|       var rectRange = [localRange, otherExtent]; | 
|       xyIndex && rectRange.reverse(); | 
|       updateBaseRect(controller, cover, rectRange, brushOption); | 
|     }, | 
|     updateCommon: updateCommon, | 
|     contain: mainShapeContain | 
|   }; | 
| } | 
| export default BrushController; |