76b98260dbcec264eeb8405275baa2be.json 108 KB
{"ast":null,"code":"/**\r\n * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>\r\n * @fileoverview Graphics module\r\n */\nimport snippet from 'tui-code-snippet';\nimport fabric from 'fabric';\nimport ImageLoader from './component/imageLoader';\nimport Cropper from './component/cropper';\nimport Flip from './component/flip';\nimport Rotation from './component/rotation';\nimport FreeDrawing from './component/freeDrawing';\nimport Line from './component/line';\nimport Text from './component/text';\nimport Icon from './component/icon';\nimport Filter from './component/filter';\nimport Shape from './component/shape';\nimport CropperDrawingMode from './drawingMode/cropper';\nimport FreeDrawingMode from './drawingMode/freeDrawing';\nimport LineDrawingMode from './drawingMode/lineDrawing';\nimport ShapeDrawingMode from './drawingMode/shape';\nimport TextDrawingMode from './drawingMode/text';\nimport IconDrawingMode from './drawingMode/icon';\nimport { getProperties, includes, isShape, Promise } from './util';\nimport { componentNames as components, eventNames as events, drawingModes, fObjectOptions } from './consts';\nimport { makeSelectionUndoData, makeSelectionUndoDatum, setCachedUndoDataForDimension } from './helper/selectionModifyHelper';\nconst {\n  extend,\n  stamp,\n  isArray,\n  isString,\n  forEachArray,\n  forEachOwnProperties,\n  CustomEvents\n} = snippet;\nconst DEFAULT_CSS_MAX_WIDTH = 1000;\nconst DEFAULT_CSS_MAX_HEIGHT = 800;\nconst EXTRA_PX_FOR_PASTE = 10;\nconst cssOnly = {\n  cssOnly: true\n};\nconst backstoreOnly = {\n  backstoreOnly: true\n};\n/**\r\n * Graphics class\r\n * @class\r\n * @param {string|HTMLElement} wrapper - Wrapper's element or selector\r\n * @param {Object} [option] - Canvas max width & height of css\r\n *  @param {number} option.cssMaxWidth - Canvas css-max-width\r\n *  @param {number} option.cssMaxHeight - Canvas css-max-height\r\n * @ignore\r\n */\n\nclass Graphics {\n  constructor(element, {\n    cssMaxWidth,\n    cssMaxHeight\n  } = {}) {\n    /**\r\n     * Fabric image instance\r\n     * @type {fabric.Image}\r\n     */\n    this.canvasImage = null;\n    /**\r\n     * Max width of canvas elements\r\n     * @type {number}\r\n     */\n\n    this.cssMaxWidth = cssMaxWidth || DEFAULT_CSS_MAX_WIDTH;\n    /**\r\n     * Max height of canvas elements\r\n     * @type {number}\r\n     */\n\n    this.cssMaxHeight = cssMaxHeight || DEFAULT_CSS_MAX_HEIGHT;\n    /**\r\n     * cropper Selection Style\r\n     * @type {Object}\r\n     */\n\n    this.cropSelectionStyle = {};\n    /**\r\n     * target fabric object for copy paste feature\r\n     * @type {fabric.Object}\r\n     * @private\r\n     */\n\n    this.targetObjectForCopyPaste = null;\n    /**\r\n     * Image name\r\n     * @type {string}\r\n     */\n\n    this.imageName = '';\n    /**\r\n     * Object Map\r\n     * @type {Object}\r\n     * @private\r\n     */\n\n    this._objects = {};\n    /**\r\n     * Fabric-Canvas instance\r\n     * @type {fabric.Canvas}\r\n     * @private\r\n     */\n\n    this._canvas = null;\n    /**\r\n     * Drawing mode\r\n     * @type {string}\r\n     * @private\r\n     */\n\n    this._drawingMode = drawingModes.NORMAL;\n    /**\r\n     * DrawingMode map\r\n     * @type {Object.<string, DrawingMode>}\r\n     * @private\r\n     */\n\n    this._drawingModeMap = {};\n    /**\r\n     * Component map\r\n     * @type {Object.<string, Component>}\r\n     * @private\r\n     */\n\n    this._componentMap = {};\n    /**\r\n     * fabric event handlers\r\n     * @type {Object.<string, function>}\r\n     * @private\r\n     */\n\n    this._handler = {\n      onMouseDown: this._onMouseDown.bind(this),\n      onObjectAdded: this._onObjectAdded.bind(this),\n      onObjectRemoved: this._onObjectRemoved.bind(this),\n      onObjectMoved: this._onObjectMoved.bind(this),\n      onObjectScaled: this._onObjectScaled.bind(this),\n      onObjectModified: this._onObjectModified.bind(this),\n      onObjectRotated: this._onObjectRotated.bind(this),\n      onObjectSelected: this._onObjectSelected.bind(this),\n      onPathCreated: this._onPathCreated.bind(this),\n      onSelectionCleared: this._onSelectionCleared.bind(this),\n      onSelectionCreated: this._onSelectionCreated.bind(this)\n    };\n\n    this._setObjectCachingToFalse();\n\n    this._setCanvasElement(element);\n\n    this._createDrawingModeInstances();\n\n    this._createComponents();\n\n    this._attachCanvasEvents();\n  }\n  /**\r\n   * Destroy canvas element\r\n   */\n\n\n  destroy() {\n    const {\n      wrapperEl\n    } = this._canvas;\n\n    this._canvas.clear();\n\n    wrapperEl.parentNode.removeChild(wrapperEl);\n  }\n  /**\r\n   * Deactivates all objects on canvas\r\n   * @returns {Graphics} this\r\n   */\n\n\n  deactivateAll() {\n    this._canvas.discardActiveObject();\n\n    return this;\n  }\n  /**\r\n   * Renders all objects on canvas\r\n   * @returns {Graphics} this\r\n   */\n\n\n  renderAll() {\n    this._canvas.renderAll();\n\n    return this;\n  }\n  /**\r\n   * Adds objects on canvas\r\n   * @param {Object|Array} objects - objects\r\n   */\n\n\n  add(objects) {\n    let theArgs = [];\n\n    if (isArray(objects)) {\n      theArgs = objects;\n    } else {\n      theArgs.push(objects);\n    }\n\n    this._canvas.add(...theArgs);\n  }\n  /**\r\n   * Removes the object or group\r\n   * @param {Object} target - graphics object or group\r\n   * @returns {boolean} true if contains or false\r\n   */\n\n\n  contains(target) {\n    return this._canvas.contains(target);\n  }\n  /**\r\n   * Gets all objects or group\r\n   * @returns {Array} all objects, shallow copy\r\n   */\n\n\n  getObjects() {\n    return this._canvas.getObjects().slice();\n  }\n  /**\r\n   * Get an object by id\r\n   * @param {number} id - object id\r\n   * @returns {fabric.Object} object corresponding id\r\n   */\n\n\n  getObject(id) {\n    return this._objects[id];\n  }\n  /**\r\n   * Removes the object or group\r\n   * @param {Object} target - graphics object or group\r\n   */\n\n\n  remove(target) {\n    this._canvas.remove(target);\n  }\n  /**\r\n   * Removes all object or group\r\n   * @param {boolean} includesBackground - remove the background image or not\r\n   * @returns {Array} all objects array which is removed\r\n   */\n\n\n  removeAll(includesBackground) {\n    const canvas = this._canvas;\n    const objects = canvas.getObjects().slice();\n    canvas.remove(...this._canvas.getObjects());\n\n    if (includesBackground) {\n      canvas.clear();\n    }\n\n    return objects;\n  }\n  /**\r\n   * Removes an object or group by id\r\n   * @param {number} id - object id\r\n   * @returns {Array} removed objects\r\n   */\n\n\n  removeObjectById(id) {\n    const objects = [];\n    const canvas = this._canvas;\n    const target = this.getObject(id);\n    const isValidGroup = target && target.isType('group') && !target.isEmpty();\n\n    if (isValidGroup) {\n      canvas.discardActiveObject(); // restore states for each objects\n\n      target.forEachObject(obj => {\n        objects.push(obj);\n        canvas.remove(obj);\n      });\n    } else if (canvas.contains(target)) {\n      objects.push(target);\n      canvas.remove(target);\n    }\n\n    return objects;\n  }\n  /**\r\n   * Get an id by object instance\r\n   * @param {fabric.Object} object object\r\n   * @returns {number} object id if it exists or null\r\n   */\n\n\n  getObjectId(object) {\n    let key = null;\n\n    for (key in this._objects) {\n      if (this._objects.hasOwnProperty(key)) {\n        if (object === this._objects[key]) {\n          return key;\n        }\n      }\n    }\n\n    return null;\n  }\n  /**\r\n   * Gets an active object or group\r\n   * @returns {Object} active object or group instance\r\n   */\n\n\n  getActiveObject() {\n    return this._canvas._activeObject;\n  }\n  /**\r\n   * Returns the object ID to delete the object.\r\n   * @returns {number} object id for remove\r\n   */\n\n\n  getActiveObjectIdForRemove() {\n    const activeObject = this.getActiveObject();\n    const {\n      type,\n      left,\n      top\n    } = activeObject;\n    const isSelection = type === 'activeSelection';\n\n    if (isSelection) {\n      const group = new fabric.Group([...activeObject.getObjects()], {\n        left,\n        top\n      });\n      return this._addFabricObject(group);\n    }\n\n    return this.getObjectId(activeObject);\n  }\n  /**\r\n   * Verify that you are ready to erase the object.\r\n   * @returns {boolean} ready for object remove\r\n   */\n\n\n  isReadyRemoveObject() {\n    const activeObject = this.getActiveObject();\n    return activeObject && !activeObject.isEditing;\n  }\n  /**\r\n   * Gets an active group object\r\n   * @returns {Object} active group object instance\r\n   */\n\n\n  getActiveObjects() {\n    const activeObject = this._canvas._activeObject;\n    return activeObject && activeObject.type === 'activeSelection' ? activeObject : null;\n  }\n  /**\r\n   * Get Active object Selection from object ids\r\n   * @param {Array.<Object>} objects - fabric objects\r\n   * @returns {Object} target - target object group\r\n   */\n\n\n  getActiveSelectionFromObjects(objects) {\n    const canvas = this.getCanvas();\n    return new fabric.ActiveSelection(objects, {\n      canvas\n    });\n  }\n  /**\r\n   * Activates an object or group\r\n   * @param {Object} target - target object or group\r\n   */\n\n\n  setActiveObject(target) {\n    this._canvas.setActiveObject(target);\n  }\n  /**\r\n   * Set Crop selection style\r\n   * @param {Object} style - Selection styles\r\n   */\n\n\n  setCropSelectionStyle(style) {\n    this.cropSelectionStyle = style;\n  }\n  /**\r\n   * Get component\r\n   * @param {string} name - Component name\r\n   * @returns {Component}\r\n   */\n\n\n  getComponent(name) {\n    return this._componentMap[name];\n  }\n  /**\r\n   * Get current drawing mode\r\n   * @returns {string}\r\n   */\n\n\n  getDrawingMode() {\n    return this._drawingMode;\n  }\n  /**\r\n   * Start a drawing mode. If the current mode is not 'NORMAL', 'stopDrawingMode()' will be called first.\r\n   * @param {String} mode Can be one of <I>'CROPPER', 'FREE_DRAWING', 'LINE', 'TEXT', 'SHAPE'</I>\r\n   * @param {Object} [option] parameters of drawing mode, it's available with 'FREE_DRAWING', 'LINE_DRAWING'\r\n   *  @param {Number} [option.width] brush width\r\n   *  @param {String} [option.color] brush color\r\n   * @returns {boolean} true if success or false\r\n   */\n\n\n  startDrawingMode(mode, option) {\n    if (this._isSameDrawingMode(mode)) {\n      return true;\n    } // If the current mode is not 'NORMAL', 'stopDrawingMode()' will be called first.\n\n\n    this.stopDrawingMode();\n\n    const drawingModeInstance = this._getDrawingModeInstance(mode);\n\n    if (drawingModeInstance && drawingModeInstance.start) {\n      drawingModeInstance.start(this, option);\n      this._drawingMode = mode;\n    }\n\n    return !!drawingModeInstance;\n  }\n  /**\r\n   * Stop the current drawing mode and back to the 'NORMAL' mode\r\n   */\n\n\n  stopDrawingMode() {\n    if (this._isSameDrawingMode(drawingModes.NORMAL)) {\n      return;\n    }\n\n    const drawingModeInstance = this._getDrawingModeInstance(this.getDrawingMode());\n\n    if (drawingModeInstance && drawingModeInstance.end) {\n      drawingModeInstance.end(this);\n    }\n\n    this._drawingMode = drawingModes.NORMAL;\n  }\n  /**\r\n   * To data url from canvas\r\n   * @param {Object} options - options for toDataURL\r\n   *   @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\r\n   *   @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\r\n   *   @param {Number} [options.multiplier=1] Multiplier to scale by\r\n   *   @param {Number} [options.left] Cropping left offset. Introduced in fabric v1.2.14\r\n   *   @param {Number} [options.top] Cropping top offset. Introduced in fabric v1.2.14\r\n   *   @param {Number} [options.width] Cropping width. Introduced in fabric v1.2.14\r\n   *   @param {Number} [options.height] Cropping height. Introduced in fabric v1.2.14\r\n   * @returns {string} A DOMString containing the requested data URI.\r\n   */\n\n\n  toDataURL(options) {\n    const cropper = this.getComponent(components.CROPPER);\n    cropper.changeVisibility(false);\n\n    const dataUrl = this._canvas && this._canvas.toDataURL(options);\n\n    cropper.changeVisibility(true);\n    return dataUrl;\n  }\n  /**\r\n   * Save image(background) of canvas\r\n   * @param {string} name - Name of image\r\n   * @param {?fabric.Image} canvasImage - Fabric image instance\r\n   */\n\n\n  setCanvasImage(name, canvasImage) {\n    if (canvasImage) {\n      stamp(canvasImage);\n    }\n\n    this.imageName = name;\n    this.canvasImage = canvasImage;\n  }\n  /**\r\n   * Set css max dimension\r\n   * @param {{width: number, height: number}} maxDimension - Max width & Max height\r\n   */\n\n\n  setCssMaxDimension(maxDimension) {\n    this.cssMaxWidth = maxDimension.width || this.cssMaxWidth;\n    this.cssMaxHeight = maxDimension.height || this.cssMaxHeight;\n  }\n  /**\r\n   * Adjust canvas dimension with scaling image\r\n   */\n\n\n  adjustCanvasDimension() {\n    const canvasImage = this.canvasImage.scale(1);\n    const {\n      width,\n      height\n    } = canvasImage.getBoundingRect();\n\n    const maxDimension = this._calcMaxDimension(width, height);\n\n    this.setCanvasCssDimension({\n      width: '100%',\n      height: '100%',\n      // Set height '' for IE9\n      'max-width': `${maxDimension.width}px`,\n      'max-height': `${maxDimension.height}px`\n    });\n    this.setCanvasBackstoreDimension({\n      width,\n      height\n    });\n\n    this._canvas.centerObject(canvasImage);\n  }\n  /**\r\n   * Set canvas dimension - css only\r\n   *  {@link http://fabricjs.com/docs/fabric.Canvas.html#setDimensions}\r\n   * @param {Object} dimension - Canvas css dimension\r\n   */\n\n\n  setCanvasCssDimension(dimension) {\n    this._canvas.setDimensions(dimension, cssOnly);\n  }\n  /**\r\n   * Set canvas dimension - backstore only\r\n   *  {@link http://fabricjs.com/docs/fabric.Canvas.html#setDimensions}\r\n   * @param {Object} dimension - Canvas backstore dimension\r\n   */\n\n\n  setCanvasBackstoreDimension(dimension) {\n    this._canvas.setDimensions(dimension, backstoreOnly);\n  }\n  /**\r\n   * Set image properties\r\n   * {@link http://fabricjs.com/docs/fabric.Image.html#set}\r\n   * @param {Object} setting - Image properties\r\n   * @param {boolean} [withRendering] - If true, The changed image will be reflected in the canvas\r\n   */\n\n\n  setImageProperties(setting, withRendering) {\n    const {\n      canvasImage\n    } = this;\n\n    if (!canvasImage) {\n      return;\n    }\n\n    canvasImage.set(setting).setCoords();\n\n    if (withRendering) {\n      this._canvas.renderAll();\n    }\n  }\n  /**\r\n   * Returns canvas element of fabric.Canvas[[lower-canvas]]\r\n   * @returns {HTMLCanvasElement}\r\n   */\n\n\n  getCanvasElement() {\n    return this._canvas.getElement();\n  }\n  /**\r\n   * Get fabric.Canvas instance\r\n   * @returns {fabric.Canvas}\r\n   * @private\r\n   */\n\n\n  getCanvas() {\n    return this._canvas;\n  }\n  /**\r\n   * Get canvasImage (fabric.Image instance)\r\n   * @returns {fabric.Image}\r\n   */\n\n\n  getCanvasImage() {\n    return this.canvasImage;\n  }\n  /**\r\n   * Get image name\r\n   * @returns {string}\r\n   */\n\n\n  getImageName() {\n    return this.imageName;\n  }\n  /**\r\n   * Add image object on canvas\r\n   * @param {string} imgUrl - Image url to make object\r\n   * @returns {Promise}\r\n   */\n\n\n  addImageObject(imgUrl) {\n    const callback = this._callbackAfterLoadingImageObject.bind(this);\n\n    return new Promise(resolve => {\n      fabric.Image.fromURL(imgUrl, image => {\n        callback(image);\n        resolve(this.createObjectProperties(image));\n      }, {\n        crossOrigin: 'Anonymous'\n      });\n    });\n  }\n  /**\r\n   * Get center position of canvas\r\n   * @returns {Object} {left, top}\r\n   */\n\n\n  getCenter() {\n    return this._canvas.getCenter();\n  }\n  /**\r\n   * Get cropped rect\r\n   * @returns {Object} rect\r\n   */\n\n\n  getCropzoneRect() {\n    return this.getComponent(components.CROPPER).getCropzoneRect();\n  }\n  /**\r\n   * Get cropped rect\r\n   * @param {number} [mode] cropzone rect mode\r\n   */\n\n\n  setCropzoneRect(mode) {\n    this.getComponent(components.CROPPER).setCropzoneRect(mode);\n  }\n  /**\r\n   * Get cropped image data\r\n   * @param {Object} cropRect cropzone rect\r\n   *  @param {Number} cropRect.left left position\r\n   *  @param {Number} cropRect.top top position\r\n   *  @param {Number} cropRect.width width\r\n   *  @param {Number} cropRect.height height\r\n   * @returns {?{imageName: string, url: string}} cropped Image data\r\n   */\n\n\n  getCroppedImageData(cropRect) {\n    return this.getComponent(components.CROPPER).getCroppedImageData(cropRect);\n  }\n  /**\r\n   * Set brush option\r\n   * @param {Object} option brush option\r\n   *  @param {Number} option.width width\r\n   *  @param {String} option.color color like 'FFFFFF', 'rgba(0, 0, 0, 0.5)'\r\n   */\n\n\n  setBrush(option) {\n    const drawingMode = this._drawingMode;\n    let compName = components.FREE_DRAWING;\n\n    if (drawingMode === drawingModes.LINE_DRAWING) {\n      compName = components.LINE;\n    }\n\n    this.getComponent(compName).setBrush(option);\n  }\n  /**\r\n   * Set states of current drawing shape\r\n   * @param {string} type - Shape type (ex: 'rect', 'circle', 'triangle')\r\n   * @param {Object} [options] - Shape options\r\n   *      @param {(ShapeFillOption | string)} [options.fill] - {@link ShapeFillOption} or\r\n   *        Shape foreground color (ex: '#fff', 'transparent')\r\n   *      @param {string} [options.stoke] - Shape outline color\r\n   *      @param {number} [options.strokeWidth] - Shape outline width\r\n   *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not\r\n   */\n\n\n  setDrawingShape(type, options) {\n    this.getComponent(components.SHAPE).setStates(type, options);\n  }\n  /**\r\n   * Set style of current drawing icon\r\n   * @param {string} type - icon type (ex: 'icon-arrow', 'icon-star')\r\n   * @param {Object} [iconColor] - Icon color\r\n   */\n\n\n  setIconStyle(type, iconColor) {\n    this.getComponent(components.ICON).setStates(type, iconColor);\n  }\n  /**\r\n   * Register icon paths\r\n   * @param {Object} pathInfos - Path infos\r\n   *  @param {string} pathInfos.key - key\r\n   *  @param {string} pathInfos.value - value\r\n   */\n\n\n  registerPaths(pathInfos) {\n    this.getComponent(components.ICON).registerPaths(pathInfos);\n  }\n  /**\r\n   * Change cursor style\r\n   * @param {string} cursorType - cursor type\r\n   */\n\n\n  changeCursor(cursorType) {\n    const canvas = this.getCanvas();\n    canvas.defaultCursor = cursorType;\n    canvas.renderAll();\n  }\n  /**\r\n   * Whether it has the filter or not\r\n   * @param {string} type - Filter type\r\n   * @returns {boolean} true if it has the filter\r\n   */\n\n\n  hasFilter(type) {\n    return this.getComponent(components.FILTER).hasFilter(type);\n  }\n  /**\r\n   * Set selection style of fabric object by init option\r\n   * @param {Object} styles - Selection styles\r\n   */\n\n\n  setSelectionStyle(styles) {\n    extend(fObjectOptions.SELECTION_STYLE, styles);\n  }\n  /**\r\n   * Set object properties\r\n   * @param {number} id - object id\r\n   * @param {Object} props - props\r\n   *     @param {string} [props.fill] Color\r\n   *     @param {string} [props.fontFamily] Font type for text\r\n   *     @param {number} [props.fontSize] Size\r\n   *     @param {string} [props.fontStyle] Type of inclination (normal / italic)\r\n   *     @param {string} [props.fontWeight] Type of thicker or thinner looking (normal / bold)\r\n   *     @param {string} [props.textAlign] Type of text align (left / center / right)\r\n   *     @param {string} [props.textDecoration] Type of line (underline / line-through / overline)\r\n   * @returns {Object} applied properties\r\n   */\n\n\n  setObjectProperties(id, props) {\n    const object = this.getObject(id);\n    const clone = extend({}, props);\n    object.set(clone);\n    object.setCoords();\n    this.getCanvas().renderAll();\n    return clone;\n  }\n  /**\r\n   * Get object properties corresponding key\r\n   * @param {number} id - object id\r\n   * @param {Array<string>|ObjectProps|string} keys - property's key\r\n   * @returns {Object} properties\r\n   */\n\n\n  getObjectProperties(id, keys) {\n    const object = this.getObject(id);\n    const props = {};\n\n    if (isString(keys)) {\n      props[keys] = object[keys];\n    } else if (isArray(keys)) {\n      forEachArray(keys, value => {\n        props[value] = object[value];\n      });\n    } else {\n      forEachOwnProperties(keys, (value, key) => {\n        props[key] = object[key];\n      });\n    }\n\n    return props;\n  }\n  /**\r\n   * Get object position by originX, originY\r\n   * @param {number} id - object id\r\n   * @param {string} originX - can be 'left', 'center', 'right'\r\n   * @param {string} originY - can be 'top', 'center', 'bottom'\r\n   * @returns {Object} {{x:number, y: number}} position by origin if id is valid, or null\r\n   */\n\n\n  getObjectPosition(id, originX, originY) {\n    const targetObj = this.getObject(id);\n\n    if (!targetObj) {\n      return null;\n    }\n\n    return targetObj.getPointByOrigin(originX, originY);\n  }\n  /**\r\n   * Set object position  by originX, originY\r\n   * @param {number} id - object id\r\n   * @param {Object} posInfo - position object\r\n   *  @param {number} posInfo.x - x position\r\n   *  @param {number} posInfo.y - y position\r\n   *  @param {string} posInfo.originX - can be 'left', 'center', 'right'\r\n   *  @param {string} posInfo.originY - can be 'top', 'center', 'bottom'\r\n   * @returns {boolean} true if target id is valid or false\r\n   */\n\n\n  setObjectPosition(id, posInfo) {\n    const targetObj = this.getObject(id);\n    const {\n      x,\n      y,\n      originX,\n      originY\n    } = posInfo;\n\n    if (!targetObj) {\n      return false;\n    }\n\n    const targetOrigin = targetObj.getPointByOrigin(originX, originY);\n    const centerOrigin = targetObj.getPointByOrigin('center', 'center');\n    const diffX = centerOrigin.x - targetOrigin.x;\n    const diffY = centerOrigin.y - targetOrigin.y;\n    targetObj.set({\n      left: x + diffX,\n      top: y + diffY\n    });\n    targetObj.setCoords();\n    return true;\n  }\n  /**\r\n   * Get the canvas size\r\n   * @returns {Object} {{width: number, height: number}} image size\r\n   */\n\n\n  getCanvasSize() {\n    const image = this.getCanvasImage();\n    return {\n      width: image ? image.width : 0,\n      height: image ? image.height : 0\n    };\n  }\n  /**\r\n   * Create fabric static canvas\r\n   * @returns {Object} {{width: number, height: number}} image size\r\n   */\n\n\n  createStaticCanvas() {\n    const staticCanvas = new fabric.StaticCanvas();\n    staticCanvas.set({\n      enableRetinaScaling: false\n    });\n    return staticCanvas;\n  }\n  /**\r\n   * Get a DrawingMode instance\r\n   * @param {string} modeName - DrawingMode Class Name\r\n   * @returns {DrawingMode} DrawingMode instance\r\n   * @private\r\n   */\n\n\n  _getDrawingModeInstance(modeName) {\n    return this._drawingModeMap[modeName];\n  }\n  /**\r\n   * Set object caching to false. This brought many bugs when draw Shape & cropzone\r\n   * @see http://fabricjs.com/fabric-object-caching\r\n   * @private\r\n   */\n\n\n  _setObjectCachingToFalse() {\n    fabric.Object.prototype.objectCaching = false;\n  }\n  /**\r\n   * Set canvas element to fabric.Canvas\r\n   * @param {Element|string} element - Wrapper or canvas element or selector\r\n   * @private\r\n   */\n\n\n  _setCanvasElement(element) {\n    let selectedElement;\n    let canvasElement;\n\n    if (element.nodeType) {\n      selectedElement = element;\n    } else {\n      selectedElement = document.querySelector(element);\n    }\n\n    if (selectedElement.nodeName.toUpperCase() !== 'CANVAS') {\n      canvasElement = document.createElement('canvas');\n      selectedElement.appendChild(canvasElement);\n    }\n\n    this._canvas = new fabric.Canvas(canvasElement, {\n      containerClass: 'tui-image-editor-canvas-container',\n      enableRetinaScaling: false\n    });\n  }\n  /**\r\n   * Creates DrawingMode instances\r\n   * @private\r\n   */\n\n\n  _createDrawingModeInstances() {\n    this._register(this._drawingModeMap, new CropperDrawingMode());\n\n    this._register(this._drawingModeMap, new FreeDrawingMode());\n\n    this._register(this._drawingModeMap, new LineDrawingMode());\n\n    this._register(this._drawingModeMap, new ShapeDrawingMode());\n\n    this._register(this._drawingModeMap, new TextDrawingMode());\n\n    this._register(this._drawingModeMap, new IconDrawingMode());\n  }\n  /**\r\n   * Create components\r\n   * @private\r\n   */\n\n\n  _createComponents() {\n    this._register(this._componentMap, new ImageLoader(this));\n\n    this._register(this._componentMap, new Cropper(this));\n\n    this._register(this._componentMap, new Flip(this));\n\n    this._register(this._componentMap, new Rotation(this));\n\n    this._register(this._componentMap, new FreeDrawing(this));\n\n    this._register(this._componentMap, new Line(this));\n\n    this._register(this._componentMap, new Text(this));\n\n    this._register(this._componentMap, new Icon(this));\n\n    this._register(this._componentMap, new Filter(this));\n\n    this._register(this._componentMap, new Shape(this));\n  }\n  /**\r\n   * Register component\r\n   * @param {Object} map - map object\r\n   * @param {Object} module - module which has getName method\r\n   * @private\r\n   */\n\n\n  _register(map, module) {\n    map[module.getName()] = module;\n  }\n  /**\r\n   * Get the current drawing mode is same with given mode\r\n   * @param {string} mode drawing mode\r\n   * @returns {boolean} true if same or false\r\n   */\n\n\n  _isSameDrawingMode(mode) {\n    return this.getDrawingMode() === mode;\n  }\n  /**\r\n   * Calculate max dimension of canvas\r\n   * The css-max dimension is dynamically decided with maintaining image ratio\r\n   * The css-max dimension is lower than canvas dimension (attribute of canvas, not css)\r\n   * @param {number} width - Canvas width\r\n   * @param {number} height - Canvas height\r\n   * @returns {{width: number, height: number}} - Max width & Max height\r\n   * @private\r\n   */\n\n\n  _calcMaxDimension(width, height) {\n    const wScaleFactor = this.cssMaxWidth / width;\n    const hScaleFactor = this.cssMaxHeight / height;\n    let cssMaxWidth = Math.min(width, this.cssMaxWidth);\n    let cssMaxHeight = Math.min(height, this.cssMaxHeight);\n\n    if (wScaleFactor < 1 && wScaleFactor < hScaleFactor) {\n      cssMaxWidth = width * wScaleFactor;\n      cssMaxHeight = height * wScaleFactor;\n    } else if (hScaleFactor < 1 && hScaleFactor < wScaleFactor) {\n      cssMaxWidth = width * hScaleFactor;\n      cssMaxHeight = height * hScaleFactor;\n    }\n\n    return {\n      width: Math.floor(cssMaxWidth),\n      height: Math.floor(cssMaxHeight)\n    };\n  }\n  /**\r\n   * Callback function after loading image\r\n   * @param {fabric.Image} obj - Fabric image object\r\n   * @private\r\n   */\n\n\n  _callbackAfterLoadingImageObject(obj) {\n    const centerPos = this.getCanvasImage().getCenterPoint();\n    obj.set(fObjectOptions.SELECTION_STYLE);\n    obj.set({\n      left: centerPos.x,\n      top: centerPos.y,\n      crossOrigin: 'Anonymous'\n    });\n    this.getCanvas().add(obj).setActiveObject(obj);\n  }\n  /**\r\n   * Attach canvas's events\r\n   */\n\n\n  _attachCanvasEvents() {\n    const canvas = this._canvas;\n    const handler = this._handler;\n    canvas.on({\n      'mouse:down': handler.onMouseDown,\n      'object:added': handler.onObjectAdded,\n      'object:removed': handler.onObjectRemoved,\n      'object:moving': handler.onObjectMoved,\n      'object:scaling': handler.onObjectScaled,\n      'object:modified': handler.onObjectModified,\n      'object:rotating': handler.onObjectRotated,\n      'path:created': handler.onPathCreated,\n      'selection:cleared': handler.onSelectionCleared,\n      'selection:created': handler.onSelectionCreated,\n      'selection:updated': handler.onObjectSelected\n    });\n  }\n  /**\r\n   * \"mouse:down\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\n\n\n  _onMouseDown(fEvent) {\n    const {\n      e: event,\n      target\n    } = fEvent;\n\n    const originPointer = this._canvas.getPointer(event);\n\n    if (target) {\n      const {\n        type\n      } = target;\n      const undoData = makeSelectionUndoData(target, item => makeSelectionUndoDatum(this.getObjectId(item), item, type === 'activeSelection'));\n      setCachedUndoDataForDimension(undoData);\n    }\n\n    this.fire(events.MOUSE_DOWN, event, originPointer);\n  }\n  /**\r\n   * \"object:added\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\n\n\n  _onObjectAdded(fEvent) {\n    const obj = fEvent.target;\n\n    if (obj.isType('cropzone')) {\n      return;\n    }\n\n    this._addFabricObject(obj);\n  }\n  /**\r\n   * \"object:removed\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\n\n\n  _onObjectRemoved(fEvent) {\n    const obj = fEvent.target;\n\n    this._removeFabricObject(stamp(obj));\n  }\n  /**\r\n   * \"object:moving\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\n\n\n  _onObjectMoved(fEvent) {\n    this._lazyFire(events.OBJECT_MOVED, object => this.createObjectProperties(object), fEvent.target);\n  }\n  /**\r\n   * \"object:scaling\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\n\n\n  _onObjectScaled(fEvent) {\n    this._lazyFire(events.OBJECT_SCALED, object => this.createObjectProperties(object), fEvent.target);\n  }\n  /**\r\n   * \"object:modified\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\n\n\n  _onObjectModified(fEvent) {\n    const {\n      target\n    } = fEvent;\n\n    if (target.type === 'activeSelection') {\n      const items = target.getObjects();\n      items.forEach(item => item.fire('modifiedInGroup', target));\n    }\n\n    this.fire(events.OBJECT_MODIFIED, target, this.getObjectId(target));\n  }\n  /**\r\n   * \"object:rotating\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\n\n\n  _onObjectRotated(fEvent) {\n    this._lazyFire(events.OBJECT_ROTATED, object => this.createObjectProperties(object), fEvent.target);\n  }\n  /**\r\n   * Lazy event emitter\r\n   * @param {string} eventName - event name\r\n   * @param {Function} paramsMaker - make param function\r\n   * @param {Object} [target] - Object of the event owner.\r\n   * @private\r\n   */\n\n\n  _lazyFire(eventName, paramsMaker, target) {\n    const existEventDelegation = target && target.canvasEventDelegation;\n    const delegationState = existEventDelegation ? target.canvasEventDelegation(eventName) : 'none';\n\n    if (delegationState === 'unregisted') {\n      target.canvasEventRegister(eventName, object => {\n        this.fire(eventName, paramsMaker(object));\n      });\n    }\n\n    if (delegationState === 'none') {\n      this.fire(eventName, paramsMaker(target));\n    }\n  }\n  /**\r\n   * \"object:selected\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\n\n\n  _onObjectSelected(fEvent) {\n    const {\n      target\n    } = fEvent;\n    const params = this.createObjectProperties(target);\n    this.fire(events.OBJECT_ACTIVATED, params);\n  }\n  /**\r\n   * \"path:created\" canvas event handler\r\n   * @param {{path: fabric.Path}} obj - Path object\r\n   * @private\r\n   */\n\n\n  _onPathCreated(obj) {\n    const {\n      x: left,\n      y: top\n    } = obj.path.getCenterPoint();\n    obj.path.set(extend({\n      left,\n      top\n    }, fObjectOptions.SELECTION_STYLE));\n    const params = this.createObjectProperties(obj.path);\n    this.fire(events.ADD_OBJECT, params);\n  }\n  /**\r\n   * \"selction:cleared\" canvas event handler\r\n   * @private\r\n   */\n\n\n  _onSelectionCleared() {\n    this.fire(events.SELECTION_CLEARED);\n  }\n  /**\r\n   * \"selction:created\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\n\n\n  _onSelectionCreated(fEvent) {\n    const {\n      target\n    } = fEvent;\n    const params = this.createObjectProperties(target);\n    this.fire(events.OBJECT_ACTIVATED, params);\n    this.fire(events.SELECTION_CREATED, fEvent.target);\n  }\n  /**\r\n   * Canvas discard selection all\r\n   */\n\n\n  discardSelection() {\n    this._canvas.discardActiveObject();\n\n    this._canvas.renderAll();\n  }\n  /**\r\n   * Canvas Selectable status change\r\n   * @param {boolean} selectable - expect status\r\n   */\n\n\n  changeSelectableAll(selectable) {\n    this._canvas.forEachObject(obj => {\n      obj.selectable = selectable;\n      obj.hoverCursor = selectable ? 'move' : 'crosshair';\n    });\n  }\n  /**\r\n   * Return object's properties\r\n   * @param {fabric.Object} obj - fabric object\r\n   * @returns {Object} properties object\r\n   */\n\n\n  createObjectProperties(obj) {\n    const predefinedKeys = ['left', 'top', 'width', 'height', 'fill', 'stroke', 'strokeWidth', 'opacity', 'angle'];\n    const props = {\n      id: stamp(obj),\n      type: obj.type\n    };\n    extend(props, getProperties(obj, predefinedKeys));\n\n    if (includes(['i-text', 'text'], obj.type)) {\n      extend(props, this._createTextProperties(obj, props));\n    } else if (includes(['rect', 'triangle', 'circle'], obj.type)) {\n      const shapeComp = this.getComponent(components.SHAPE);\n      extend(props, {\n        fill: shapeComp.makeFillPropertyForUserEvent(obj)\n      });\n    }\n\n    return props;\n  }\n  /**\r\n   * Get text object's properties\r\n   * @param {fabric.Object} obj - fabric text object\r\n   * @param {Object} props - properties\r\n   * @returns {Object} properties object\r\n   */\n\n\n  _createTextProperties(obj) {\n    const predefinedKeys = ['text', 'fontFamily', 'fontSize', 'fontStyle', 'textAlign', 'textDecoration', 'fontWeight'];\n    const props = {};\n    extend(props, getProperties(obj, predefinedKeys));\n    return props;\n  }\n  /**\r\n   * Add object array by id\r\n   * @param {fabric.Object} obj - fabric object\r\n   * @returns {number} object id\r\n   */\n\n\n  _addFabricObject(obj) {\n    const id = stamp(obj);\n    this._objects[id] = obj;\n    return id;\n  }\n  /**\r\n   * Remove an object in array yb id\r\n   * @param {number} id - object id\r\n   */\n\n\n  _removeFabricObject(id) {\n    delete this._objects[id];\n  }\n  /**\r\n   * Reset targetObjectForCopyPaste value from activeObject\r\n   */\n\n\n  resetTargetObjectForCopyPaste() {\n    const activeObject = this.getActiveObject();\n\n    if (activeObject) {\n      this.targetObjectForCopyPaste = activeObject;\n    }\n  }\n  /**\r\n   * Paste fabric object\r\n   * @returns {Promise}\r\n   */\n\n\n  pasteObject() {\n    if (!this.targetObjectForCopyPaste) {\n      return Promise.resolve([]);\n    }\n\n    const targetObject = this.targetObjectForCopyPaste;\n    const isGroupSelect = targetObject.type === 'activeSelection';\n    const targetObjects = isGroupSelect ? targetObject.getObjects() : [targetObject];\n    let newTargetObject = null;\n    this.discardSelection();\n    return this._cloneObject(targetObjects).then(addedObjects => {\n      if (addedObjects.length > 1) {\n        newTargetObject = this.getActiveSelectionFromObjects(addedObjects);\n      } else {\n        [newTargetObject] = addedObjects;\n      }\n\n      this.targetObjectForCopyPaste = newTargetObject;\n      this.setActiveObject(newTargetObject);\n    });\n  }\n  /**\r\n   * Clone object\r\n   * @param {fabric.Object} targetObjects - fabric object\r\n   * @returns {Promise}\r\n   * @private\r\n   */\n\n\n  _cloneObject(targetObjects) {\n    const addedObjects = snippet.map(targetObjects, targetObject => this._cloneObjectItem(targetObject));\n    return Promise.all(addedObjects);\n  }\n  /**\r\n   * Clone object one item\r\n   * @param {fabric.Object} targetObject - fabric object\r\n   * @returns {Promise}\r\n   * @private\r\n   */\n\n\n  _cloneObjectItem(targetObject) {\n    return this._copyFabricObjectForPaste(targetObject).then(clonedObject => {\n      const objectProperties = this.createObjectProperties(clonedObject);\n      this.add(clonedObject);\n      this.fire(events.ADD_OBJECT, objectProperties);\n      return clonedObject;\n    });\n  }\n  /**\r\n   * Copy fabric object with Changed position for copy and paste\r\n   * @param {fabric.Object} targetObject - fabric object\r\n   * @returns {Promise}\r\n   * @private\r\n   */\n\n\n  _copyFabricObjectForPaste(targetObject) {\n    const addExtraPx = (value, isReverse) => isReverse ? value - EXTRA_PX_FOR_PASTE : value + EXTRA_PX_FOR_PASTE;\n\n    return this._copyFabricObject(targetObject).then(clonedObject => {\n      const {\n        left,\n        top,\n        width,\n        height\n      } = clonedObject;\n      const {\n        width: canvasWidth,\n        height: canvasHeight\n      } = this.getCanvasSize();\n      const rightEdge = left + width / 2;\n      const bottomEdge = top + height / 2;\n      clonedObject.set(snippet.extend({\n        left: addExtraPx(left, rightEdge + EXTRA_PX_FOR_PASTE > canvasWidth),\n        top: addExtraPx(top, bottomEdge + EXTRA_PX_FOR_PASTE > canvasHeight)\n      }, fObjectOptions.SELECTION_STYLE));\n      return clonedObject;\n    });\n  }\n  /**\r\n   * Copy fabric object\r\n   * @param {fabric.Object} targetObject - fabric object\r\n   * @returns {Promise}\r\n   * @private\r\n   */\n\n\n  _copyFabricObject(targetObject) {\n    return new Promise(resolve => {\n      targetObject.clone(cloned => {\n        const shapeComp = this.getComponent(components.SHAPE);\n\n        if (isShape(cloned)) {\n          shapeComp.processForCopiedObject(cloned, targetObject);\n        }\n\n        resolve(cloned);\n      });\n    });\n  }\n\n}\n\nCustomEvents.mixin(Graphics);\nexport default Graphics;","map":{"version":3,"sources":["C:/Users/kkwan_000/Desktop/git/2017110269/minsung/src/js/graphics.js"],"names":["snippet","fabric","ImageLoader","Cropper","Flip","Rotation","FreeDrawing","Line","Text","Icon","Filter","Shape","CropperDrawingMode","FreeDrawingMode","LineDrawingMode","ShapeDrawingMode","TextDrawingMode","IconDrawingMode","getProperties","includes","isShape","Promise","componentNames","components","eventNames","events","drawingModes","fObjectOptions","makeSelectionUndoData","makeSelectionUndoDatum","setCachedUndoDataForDimension","extend","stamp","isArray","isString","forEachArray","forEachOwnProperties","CustomEvents","DEFAULT_CSS_MAX_WIDTH","DEFAULT_CSS_MAX_HEIGHT","EXTRA_PX_FOR_PASTE","cssOnly","backstoreOnly","Graphics","constructor","element","cssMaxWidth","cssMaxHeight","canvasImage","cropSelectionStyle","targetObjectForCopyPaste","imageName","_objects","_canvas","_drawingMode","NORMAL","_drawingModeMap","_componentMap","_handler","onMouseDown","_onMouseDown","bind","onObjectAdded","_onObjectAdded","onObjectRemoved","_onObjectRemoved","onObjectMoved","_onObjectMoved","onObjectScaled","_onObjectScaled","onObjectModified","_onObjectModified","onObjectRotated","_onObjectRotated","onObjectSelected","_onObjectSelected","onPathCreated","_onPathCreated","onSelectionCleared","_onSelectionCleared","onSelectionCreated","_onSelectionCreated","_setObjectCachingToFalse","_setCanvasElement","_createDrawingModeInstances","_createComponents","_attachCanvasEvents","destroy","wrapperEl","clear","parentNode","removeChild","deactivateAll","discardActiveObject","renderAll","add","objects","theArgs","push","contains","target","getObjects","slice","getObject","id","remove","removeAll","includesBackground","canvas","removeObjectById","isValidGroup","isType","isEmpty","forEachObject","obj","getObjectId","object","key","hasOwnProperty","getActiveObject","_activeObject","getActiveObjectIdForRemove","activeObject","type","left","top","isSelection","group","Group","_addFabricObject","isReadyRemoveObject","isEditing","getActiveObjects","getActiveSelectionFromObjects","getCanvas","ActiveSelection","setActiveObject","setCropSelectionStyle","style","getComponent","name","getDrawingMode","startDrawingMode","mode","option","_isSameDrawingMode","stopDrawingMode","drawingModeInstance","_getDrawingModeInstance","start","end","toDataURL","options","cropper","CROPPER","changeVisibility","dataUrl","setCanvasImage","setCssMaxDimension","maxDimension","width","height","adjustCanvasDimension","scale","getBoundingRect","_calcMaxDimension","setCanvasCssDimension","setCanvasBackstoreDimension","centerObject","dimension","setDimensions","setImageProperties","setting","withRendering","set","setCoords","getCanvasElement","getElement","getCanvasImage","getImageName","addImageObject","imgUrl","callback","_callbackAfterLoadingImageObject","resolve","Image","fromURL","image","createObjectProperties","crossOrigin","getCenter","getCropzoneRect","setCropzoneRect","getCroppedImageData","cropRect","setBrush","drawingMode","compName","FREE_DRAWING","LINE_DRAWING","LINE","setDrawingShape","SHAPE","setStates","setIconStyle","iconColor","ICON","registerPaths","pathInfos","changeCursor","cursorType","defaultCursor","hasFilter","FILTER","setSelectionStyle","styles","SELECTION_STYLE","setObjectProperties","props","clone","getObjectProperties","keys","value","getObjectPosition","originX","originY","targetObj","getPointByOrigin","setObjectPosition","posInfo","x","y","targetOrigin","centerOrigin","diffX","diffY","getCanvasSize","createStaticCanvas","staticCanvas","StaticCanvas","enableRetinaScaling","modeName","Object","prototype","objectCaching","selectedElement","canvasElement","nodeType","document","querySelector","nodeName","toUpperCase","createElement","appendChild","Canvas","containerClass","_register","map","module","getName","wScaleFactor","hScaleFactor","Math","min","floor","centerPos","getCenterPoint","handler","on","fEvent","e","event","originPointer","getPointer","undoData","item","fire","MOUSE_DOWN","_removeFabricObject","_lazyFire","OBJECT_MOVED","OBJECT_SCALED","items","forEach","OBJECT_MODIFIED","OBJECT_ROTATED","eventName","paramsMaker","existEventDelegation","canvasEventDelegation","delegationState","canvasEventRegister","params","OBJECT_ACTIVATED","path","ADD_OBJECT","SELECTION_CLEARED","SELECTION_CREATED","discardSelection","changeSelectableAll","selectable","hoverCursor","predefinedKeys","_createTextProperties","shapeComp","fill","makeFillPropertyForUserEvent","resetTargetObjectForCopyPaste","pasteObject","targetObject","isGroupSelect","targetObjects","newTargetObject","_cloneObject","then","addedObjects","length","_cloneObjectItem","all","_copyFabricObjectForPaste","clonedObject","objectProperties","addExtraPx","isReverse","_copyFabricObject","canvasWidth","canvasHeight","rightEdge","bottomEdge","cloned","processForCopiedObject","mixin"],"mappings":"AAAA;AACA;AACA;AACA;AACA,OAAOA,OAAP,MAAoB,kBAApB;AACA,OAAOC,MAAP,MAAmB,QAAnB;AACA,OAAOC,WAAP,MAAwB,yBAAxB;AACA,OAAOC,OAAP,MAAoB,qBAApB;AACA,OAAOC,IAAP,MAAiB,kBAAjB;AACA,OAAOC,QAAP,MAAqB,sBAArB;AACA,OAAOC,WAAP,MAAwB,yBAAxB;AACA,OAAOC,IAAP,MAAiB,kBAAjB;AACA,OAAOC,IAAP,MAAiB,kBAAjB;AACA,OAAOC,IAAP,MAAiB,kBAAjB;AACA,OAAOC,MAAP,MAAmB,oBAAnB;AACA,OAAOC,KAAP,MAAkB,mBAAlB;AACA,OAAOC,kBAAP,MAA+B,uBAA/B;AACA,OAAOC,eAAP,MAA4B,2BAA5B;AACA,OAAOC,eAAP,MAA4B,2BAA5B;AACA,OAAOC,gBAAP,MAA6B,qBAA7B;AACA,OAAOC,eAAP,MAA4B,oBAA5B;AACA,OAAOC,eAAP,MAA4B,oBAA5B;AACA,SAASC,aAAT,EAAwBC,QAAxB,EAAkCC,OAAlC,EAA2CC,OAA3C,QAA0D,QAA1D;AACA,SACEC,cAAc,IAAIC,UADpB,EAEEC,UAAU,IAAIC,MAFhB,EAGEC,YAHF,EAIEC,cAJF,QAKO,UALP;AAMA,SACEC,qBADF,EAEEC,sBAFF,EAGEC,6BAHF,QAIO,gCAJP;AAMA,MAAM;AACJC,EAAAA,MADI;AAEJC,EAAAA,KAFI;AAGJC,EAAAA,OAHI;AAIJC,EAAAA,QAJI;AAKJC,EAAAA,YALI;AAMJC,EAAAA,oBANI;AAOJC,EAAAA;AAPI,IAQFrC,OARJ;AASA,MAAMsC,qBAAqB,GAAG,IAA9B;AACA,MAAMC,sBAAsB,GAAG,GAA/B;AACA,MAAMC,kBAAkB,GAAG,EAA3B;AAEA,MAAMC,OAAO,GAAG;AACdA,EAAAA,OAAO,EAAE;AADK,CAAhB;AAGA,MAAMC,aAAa,GAAG;AACpBA,EAAAA,aAAa,EAAE;AADK,CAAtB;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,MAAMC,QAAN,CAAe;AACbC,EAAAA,WAAW,CAACC,OAAD,EAAU;AAAEC,IAAAA,WAAF;AAAeC,IAAAA;AAAf,MAAgC,EAA1C,EAA8C;AACvD;AACJ;AACA;AACA;AACI,SAAKC,WAAL,GAAmB,IAAnB;AAEA;AACJ;AACA;AACA;;AACI,SAAKF,WAAL,GAAmBA,WAAW,IAAIR,qBAAlC;AAEA;AACJ;AACA;AACA;;AACI,SAAKS,YAAL,GAAoBA,YAAY,IAAIR,sBAApC;AAEA;AACJ;AACA;AACA;;AACI,SAAKU,kBAAL,GAA0B,EAA1B;AAEA;AACJ;AACA;AACA;AACA;;AACI,SAAKC,wBAAL,GAAgC,IAAhC;AAEA;AACJ;AACA;AACA;;AACI,SAAKC,SAAL,GAAiB,EAAjB;AAEA;AACJ;AACA;AACA;AACA;;AACI,SAAKC,QAAL,GAAgB,EAAhB;AAEA;AACJ;AACA;AACA;AACA;;AACI,SAAKC,OAAL,GAAe,IAAf;AAEA;AACJ;AACA;AACA;AACA;;AACI,SAAKC,YAAL,GAAoB5B,YAAY,CAAC6B,MAAjC;AAEA;AACJ;AACA;AACA;AACA;;AACI,SAAKC,eAAL,GAAuB,EAAvB;AAEA;AACJ;AACA;AACA;AACA;;AACI,SAAKC,aAAL,GAAqB,EAArB;AAEA;AACJ;AACA;AACA;AACA;;AACI,SAAKC,QAAL,GAAgB;AACdC,MAAAA,WAAW,EAAE,KAAKC,YAAL,CAAkBC,IAAlB,CAAuB,IAAvB,CADC;AAEdC,MAAAA,aAAa,EAAE,KAAKC,cAAL,CAAoBF,IAApB,CAAyB,IAAzB,CAFD;AAGdG,MAAAA,eAAe,EAAE,KAAKC,gBAAL,CAAsBJ,IAAtB,CAA2B,IAA3B,CAHH;AAIdK,MAAAA,aAAa,EAAE,KAAKC,cAAL,CAAoBN,IAApB,CAAyB,IAAzB,CAJD;AAKdO,MAAAA,cAAc,EAAE,KAAKC,eAAL,CAAqBR,IAArB,CAA0B,IAA1B,CALF;AAMdS,MAAAA,gBAAgB,EAAE,KAAKC,iBAAL,CAAuBV,IAAvB,CAA4B,IAA5B,CANJ;AAOdW,MAAAA,eAAe,EAAE,KAAKC,gBAAL,CAAsBZ,IAAtB,CAA2B,IAA3B,CAPH;AAQda,MAAAA,gBAAgB,EAAE,KAAKC,iBAAL,CAAuBd,IAAvB,CAA4B,IAA5B,CARJ;AASde,MAAAA,aAAa,EAAE,KAAKC,cAAL,CAAoBhB,IAApB,CAAyB,IAAzB,CATD;AAUdiB,MAAAA,kBAAkB,EAAE,KAAKC,mBAAL,CAAyBlB,IAAzB,CAA8B,IAA9B,CAVN;AAWdmB,MAAAA,kBAAkB,EAAE,KAAKC,mBAAL,CAAyBpB,IAAzB,CAA8B,IAA9B;AAXN,KAAhB;;AAcA,SAAKqB,wBAAL;;AACA,SAAKC,iBAAL,CAAuBtC,OAAvB;;AACA,SAAKuC,2BAAL;;AACA,SAAKC,iBAAL;;AACA,SAAKC,mBAAL;AACD;AAED;AACF;AACA;;;AACEC,EAAAA,OAAO,GAAG;AACR,UAAM;AAAEC,MAAAA;AAAF,QAAgB,KAAKnC,OAA3B;;AAEA,SAAKA,OAAL,CAAaoC,KAAb;;AAEAD,IAAAA,SAAS,CAACE,UAAV,CAAqBC,WAArB,CAAiCH,SAAjC;AACD;AAED;AACF;AACA;AACA;;;AACEI,EAAAA,aAAa,GAAG;AACd,SAAKvC,OAAL,CAAawC,mBAAb;;AAEA,WAAO,IAAP;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,SAAS,GAAG;AACV,SAAKzC,OAAL,CAAayC,SAAb;;AAEA,WAAO,IAAP;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,GAAG,CAACC,OAAD,EAAU;AACX,QAAIC,OAAO,GAAG,EAAd;;AACA,QAAIhE,OAAO,CAAC+D,OAAD,CAAX,EAAsB;AACpBC,MAAAA,OAAO,GAAGD,OAAV;AACD,KAFD,MAEO;AACLC,MAAAA,OAAO,CAACC,IAAR,CAAaF,OAAb;AACD;;AAED,SAAK3C,OAAL,CAAa0C,GAAb,CAAiB,GAAGE,OAApB;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEE,EAAAA,QAAQ,CAACC,MAAD,EAAS;AACf,WAAO,KAAK/C,OAAL,CAAa8C,QAAb,CAAsBC,MAAtB,CAAP;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,UAAU,GAAG;AACX,WAAO,KAAKhD,OAAL,CAAagD,UAAb,GAA0BC,KAA1B,EAAP;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEC,EAAAA,SAAS,CAACC,EAAD,EAAK;AACZ,WAAO,KAAKpD,QAAL,CAAcoD,EAAd,CAAP;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,MAAM,CAACL,MAAD,EAAS;AACb,SAAK/C,OAAL,CAAaoD,MAAb,CAAoBL,MAApB;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEM,EAAAA,SAAS,CAACC,kBAAD,EAAqB;AAC5B,UAAMC,MAAM,GAAG,KAAKvD,OAApB;AACA,UAAM2C,OAAO,GAAGY,MAAM,CAACP,UAAP,GAAoBC,KAApB,EAAhB;AACAM,IAAAA,MAAM,CAACH,MAAP,CAAc,GAAG,KAAKpD,OAAL,CAAagD,UAAb,EAAjB;;AAEA,QAAIM,kBAAJ,EAAwB;AACtBC,MAAAA,MAAM,CAACnB,KAAP;AACD;;AAED,WAAOO,OAAP;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEa,EAAAA,gBAAgB,CAACL,EAAD,EAAK;AACnB,UAAMR,OAAO,GAAG,EAAhB;AACA,UAAMY,MAAM,GAAG,KAAKvD,OAApB;AACA,UAAM+C,MAAM,GAAG,KAAKG,SAAL,CAAeC,EAAf,CAAf;AACA,UAAMM,YAAY,GAAGV,MAAM,IAAIA,MAAM,CAACW,MAAP,CAAc,OAAd,CAAV,IAAoC,CAACX,MAAM,CAACY,OAAP,EAA1D;;AAEA,QAAIF,YAAJ,EAAkB;AAChBF,MAAAA,MAAM,CAACf,mBAAP,GADgB,CACc;;AAC9BO,MAAAA,MAAM,CAACa,aAAP,CAAsBC,GAAD,IAAS;AAC5BlB,QAAAA,OAAO,CAACE,IAAR,CAAagB,GAAb;AACAN,QAAAA,MAAM,CAACH,MAAP,CAAcS,GAAd;AACD,OAHD;AAID,KAND,MAMO,IAAIN,MAAM,CAACT,QAAP,CAAgBC,MAAhB,CAAJ,EAA6B;AAClCJ,MAAAA,OAAO,CAACE,IAAR,CAAaE,MAAb;AACAQ,MAAAA,MAAM,CAACH,MAAP,CAAcL,MAAd;AACD;;AAED,WAAOJ,OAAP;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEmB,EAAAA,WAAW,CAACC,MAAD,EAAS;AAClB,QAAIC,GAAG,GAAG,IAAV;;AACA,SAAKA,GAAL,IAAY,KAAKjE,QAAjB,EAA2B;AACzB,UAAI,KAAKA,QAAL,CAAckE,cAAd,CAA6BD,GAA7B,CAAJ,EAAuC;AACrC,YAAID,MAAM,KAAK,KAAKhE,QAAL,CAAciE,GAAd,CAAf,EAAmC;AACjC,iBAAOA,GAAP;AACD;AACF;AACF;;AAED,WAAO,IAAP;AACD;AAED;AACF;AACA;AACA;;;AACEE,EAAAA,eAAe,GAAG;AAChB,WAAO,KAAKlE,OAAL,CAAamE,aAApB;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,0BAA0B,GAAG;AAC3B,UAAMC,YAAY,GAAG,KAAKH,eAAL,EAArB;AACA,UAAM;AAAEI,MAAAA,IAAF;AAAQC,MAAAA,IAAR;AAAcC,MAAAA;AAAd,QAAsBH,YAA5B;AACA,UAAMI,WAAW,GAAGH,IAAI,KAAK,iBAA7B;;AAEA,QAAIG,WAAJ,EAAiB;AACf,YAAMC,KAAK,GAAG,IAAI9H,MAAM,CAAC+H,KAAX,CAAiB,CAAC,GAAGN,YAAY,CAACrB,UAAb,EAAJ,CAAjB,EAAiD;AAC7DuB,QAAAA,IAD6D;AAE7DC,QAAAA;AAF6D,OAAjD,CAAd;AAKA,aAAO,KAAKI,gBAAL,CAAsBF,KAAtB,CAAP;AACD;;AAED,WAAO,KAAKZ,WAAL,CAAiBO,YAAjB,CAAP;AACD;AAED;AACF;AACA;AACA;;;AACEQ,EAAAA,mBAAmB,GAAG;AACpB,UAAMR,YAAY,GAAG,KAAKH,eAAL,EAArB;AAEA,WAAOG,YAAY,IAAI,CAACA,YAAY,CAACS,SAArC;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,gBAAgB,GAAG;AACjB,UAAMV,YAAY,GAAG,KAAKrE,OAAL,CAAamE,aAAlC;AAEA,WAAOE,YAAY,IAAIA,YAAY,CAACC,IAAb,KAAsB,iBAAtC,GAA0DD,YAA1D,GAAyE,IAAhF;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEW,EAAAA,6BAA6B,CAACrC,OAAD,EAAU;AACrC,UAAMY,MAAM,GAAG,KAAK0B,SAAL,EAAf;AAEA,WAAO,IAAIrI,MAAM,CAACsI,eAAX,CAA2BvC,OAA3B,EAAoC;AAAEY,MAAAA;AAAF,KAApC,CAAP;AACD;AAED;AACF;AACA;AACA;;;AACE4B,EAAAA,eAAe,CAACpC,MAAD,EAAS;AACtB,SAAK/C,OAAL,CAAamF,eAAb,CAA6BpC,MAA7B;AACD;AAED;AACF;AACA;AACA;;;AACEqC,EAAAA,qBAAqB,CAACC,KAAD,EAAQ;AAC3B,SAAKzF,kBAAL,GAA0ByF,KAA1B;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEC,EAAAA,YAAY,CAACC,IAAD,EAAO;AACjB,WAAO,KAAKnF,aAAL,CAAmBmF,IAAnB,CAAP;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,cAAc,GAAG;AACf,WAAO,KAAKvF,YAAZ;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEwF,EAAAA,gBAAgB,CAACC,IAAD,EAAOC,MAAP,EAAe;AAC7B,QAAI,KAAKC,kBAAL,CAAwBF,IAAxB,CAAJ,EAAmC;AACjC,aAAO,IAAP;AACD,KAH4B,CAK7B;;;AACA,SAAKG,eAAL;;AAEA,UAAMC,mBAAmB,GAAG,KAAKC,uBAAL,CAA6BL,IAA7B,CAA5B;;AACA,QAAII,mBAAmB,IAAIA,mBAAmB,CAACE,KAA/C,EAAsD;AACpDF,MAAAA,mBAAmB,CAACE,KAApB,CAA0B,IAA1B,EAAgCL,MAAhC;AAEA,WAAK1F,YAAL,GAAoByF,IAApB;AACD;;AAED,WAAO,CAAC,CAACI,mBAAT;AACD;AAED;AACF;AACA;;;AACED,EAAAA,eAAe,GAAG;AAChB,QAAI,KAAKD,kBAAL,CAAwBvH,YAAY,CAAC6B,MAArC,CAAJ,EAAkD;AAChD;AACD;;AAED,UAAM4F,mBAAmB,GAAG,KAAKC,uBAAL,CAA6B,KAAKP,cAAL,EAA7B,CAA5B;;AACA,QAAIM,mBAAmB,IAAIA,mBAAmB,CAACG,GAA/C,EAAoD;AAClDH,MAAAA,mBAAmB,CAACG,GAApB,CAAwB,IAAxB;AACD;;AACD,SAAKhG,YAAL,GAAoB5B,YAAY,CAAC6B,MAAjC;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEgG,EAAAA,SAAS,CAACC,OAAD,EAAU;AACjB,UAAMC,OAAO,GAAG,KAAKd,YAAL,CAAkBpH,UAAU,CAACmI,OAA7B,CAAhB;AACAD,IAAAA,OAAO,CAACE,gBAAR,CAAyB,KAAzB;;AAEA,UAAMC,OAAO,GAAG,KAAKvG,OAAL,IAAgB,KAAKA,OAAL,CAAakG,SAAb,CAAuBC,OAAvB,CAAhC;;AACAC,IAAAA,OAAO,CAACE,gBAAR,CAAyB,IAAzB;AAEA,WAAOC,OAAP;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEC,EAAAA,cAAc,CAACjB,IAAD,EAAO5F,WAAP,EAAoB;AAChC,QAAIA,WAAJ,EAAiB;AACfhB,MAAAA,KAAK,CAACgB,WAAD,CAAL;AACD;;AACD,SAAKG,SAAL,GAAiByF,IAAjB;AACA,SAAK5F,WAAL,GAAmBA,WAAnB;AACD;AAED;AACF;AACA;AACA;;;AACE8G,EAAAA,kBAAkB,CAACC,YAAD,EAAe;AAC/B,SAAKjH,WAAL,GAAmBiH,YAAY,CAACC,KAAb,IAAsB,KAAKlH,WAA9C;AACA,SAAKC,YAAL,GAAoBgH,YAAY,CAACE,MAAb,IAAuB,KAAKlH,YAAhD;AACD;AAED;AACF;AACA;;;AACEmH,EAAAA,qBAAqB,GAAG;AACtB,UAAMlH,WAAW,GAAG,KAAKA,WAAL,CAAiBmH,KAAjB,CAAuB,CAAvB,CAApB;AACA,UAAM;AAAEH,MAAAA,KAAF;AAASC,MAAAA;AAAT,QAAoBjH,WAAW,CAACoH,eAAZ,EAA1B;;AACA,UAAML,YAAY,GAAG,KAAKM,iBAAL,CAAuBL,KAAvB,EAA8BC,MAA9B,CAArB;;AAEA,SAAKK,qBAAL,CAA2B;AACzBN,MAAAA,KAAK,EAAE,MADkB;AAEzBC,MAAAA,MAAM,EAAE,MAFiB;AAET;AAChB,mBAAc,GAAEF,YAAY,CAACC,KAAM,IAHV;AAIzB,oBAAe,GAAED,YAAY,CAACE,MAAO;AAJZ,KAA3B;AAOA,SAAKM,2BAAL,CAAiC;AAC/BP,MAAAA,KAD+B;AAE/BC,MAAAA;AAF+B,KAAjC;;AAIA,SAAK5G,OAAL,CAAamH,YAAb,CAA0BxH,WAA1B;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEsH,EAAAA,qBAAqB,CAACG,SAAD,EAAY;AAC/B,SAAKpH,OAAL,CAAaqH,aAAb,CAA2BD,SAA3B,EAAsChI,OAAtC;AACD;AAED;AACF;AACA;AACA;AACA;;;AACE8H,EAAAA,2BAA2B,CAACE,SAAD,EAAY;AACrC,SAAKpH,OAAL,CAAaqH,aAAb,CAA2BD,SAA3B,EAAsC/H,aAAtC;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEiI,EAAAA,kBAAkB,CAACC,OAAD,EAAUC,aAAV,EAAyB;AACzC,UAAM;AAAE7H,MAAAA;AAAF,QAAkB,IAAxB;;AAEA,QAAI,CAACA,WAAL,EAAkB;AAChB;AACD;;AAEDA,IAAAA,WAAW,CAAC8H,GAAZ,CAAgBF,OAAhB,EAAyBG,SAAzB;;AACA,QAAIF,aAAJ,EAAmB;AACjB,WAAKxH,OAAL,CAAayC,SAAb;AACD;AACF;AAED;AACF;AACA;AACA;;;AACEkF,EAAAA,gBAAgB,GAAG;AACjB,WAAO,KAAK3H,OAAL,CAAa4H,UAAb,EAAP;AACD;AAED;AACF;AACA;AACA;AACA;;;AACE3C,EAAAA,SAAS,GAAG;AACV,WAAO,KAAKjF,OAAZ;AACD;AAED;AACF;AACA;AACA;;;AACE6H,EAAAA,cAAc,GAAG;AACf,WAAO,KAAKlI,WAAZ;AACD;AAED;AACF;AACA;AACA;;;AACEmI,EAAAA,YAAY,GAAG;AACb,WAAO,KAAKhI,SAAZ;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEiI,EAAAA,cAAc,CAACC,MAAD,EAAS;AACrB,UAAMC,QAAQ,GAAG,KAAKC,gCAAL,CAAsC1H,IAAtC,CAA2C,IAA3C,CAAjB;;AAEA,WAAO,IAAIxC,OAAJ,CAAamK,OAAD,IAAa;AAC9BvL,MAAAA,MAAM,CAACwL,KAAP,CAAaC,OAAb,CACEL,MADF,EAEGM,KAAD,IAAW;AACTL,QAAAA,QAAQ,CAACK,KAAD,CAAR;AACAH,QAAAA,OAAO,CAAC,KAAKI,sBAAL,CAA4BD,KAA5B,CAAD,CAAP;AACD,OALH,EAME;AACEE,QAAAA,WAAW,EAAE;AADf,OANF;AAUD,KAXM,CAAP;AAYD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,SAAS,GAAG;AACV,WAAO,KAAKzI,OAAL,CAAayI,SAAb,EAAP;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,eAAe,GAAG;AAChB,WAAO,KAAKpD,YAAL,CAAkBpH,UAAU,CAACmI,OAA7B,EAAsCqC,eAAtC,EAAP;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,eAAe,CAACjD,IAAD,EAAO;AACpB,SAAKJ,YAAL,CAAkBpH,UAAU,CAACmI,OAA7B,EAAsCsC,eAAtC,CAAsDjD,IAAtD;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEkD,EAAAA,mBAAmB,CAACC,QAAD,EAAW;AAC5B,WAAO,KAAKvD,YAAL,CAAkBpH,UAAU,CAACmI,OAA7B,EAAsCuC,mBAAtC,CAA0DC,QAA1D,CAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEC,EAAAA,QAAQ,CAACnD,MAAD,EAAS;AACf,UAAMoD,WAAW,GAAG,KAAK9I,YAAzB;AACA,QAAI+I,QAAQ,GAAG9K,UAAU,CAAC+K,YAA1B;;AAEA,QAAIF,WAAW,KAAK1K,YAAY,CAAC6K,YAAjC,EAA+C;AAC7CF,MAAAA,QAAQ,GAAG9K,UAAU,CAACiL,IAAtB;AACD;;AAED,SAAK7D,YAAL,CAAkB0D,QAAlB,EAA4BF,QAA5B,CAAqCnD,MAArC;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEyD,EAAAA,eAAe,CAAC9E,IAAD,EAAO6B,OAAP,EAAgB;AAC7B,SAAKb,YAAL,CAAkBpH,UAAU,CAACmL,KAA7B,EAAoCC,SAApC,CAA8ChF,IAA9C,EAAoD6B,OAApD;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEoD,EAAAA,YAAY,CAACjF,IAAD,EAAOkF,SAAP,EAAkB;AAC5B,SAAKlE,YAAL,CAAkBpH,UAAU,CAACuL,IAA7B,EAAmCH,SAAnC,CAA6ChF,IAA7C,EAAmDkF,SAAnD;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEE,EAAAA,aAAa,CAACC,SAAD,EAAY;AACvB,SAAKrE,YAAL,CAAkBpH,UAAU,CAACuL,IAA7B,EAAmCC,aAAnC,CAAiDC,SAAjD;AACD;AAED;AACF;AACA;AACA;;;AACEC,EAAAA,YAAY,CAACC,UAAD,EAAa;AACvB,UAAMtG,MAAM,GAAG,KAAK0B,SAAL,EAAf;AACA1B,IAAAA,MAAM,CAACuG,aAAP,GAAuBD,UAAvB;AACAtG,IAAAA,MAAM,CAACd,SAAP;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEsH,EAAAA,SAAS,CAACzF,IAAD,EAAO;AACd,WAAO,KAAKgB,YAAL,CAAkBpH,UAAU,CAAC8L,MAA7B,EAAqCD,SAArC,CAA+CzF,IAA/C,CAAP;AACD;AAED;AACF;AACA;AACA;;;AACE2F,EAAAA,iBAAiB,CAACC,MAAD,EAAS;AACxBxL,IAAAA,MAAM,CAACJ,cAAc,CAAC6L,eAAhB,EAAiCD,MAAjC,CAAN;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEE,EAAAA,mBAAmB,CAACjH,EAAD,EAAKkH,KAAL,EAAY;AAC7B,UAAMtG,MAAM,GAAG,KAAKb,SAAL,CAAeC,EAAf,CAAf;AACA,UAAMmH,KAAK,GAAG5L,MAAM,CAAC,EAAD,EAAK2L,KAAL,CAApB;AAEAtG,IAAAA,MAAM,CAAC0D,GAAP,CAAW6C,KAAX;AAEAvG,IAAAA,MAAM,CAAC2D,SAAP;AAEA,SAAKzC,SAAL,GAAiBxC,SAAjB;AAEA,WAAO6H,KAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEC,EAAAA,mBAAmB,CAACpH,EAAD,EAAKqH,IAAL,EAAW;AAC5B,UAAMzG,MAAM,GAAG,KAAKb,SAAL,CAAeC,EAAf,CAAf;AACA,UAAMkH,KAAK,GAAG,EAAd;;AAEA,QAAIxL,QAAQ,CAAC2L,IAAD,CAAZ,EAAoB;AAClBH,MAAAA,KAAK,CAACG,IAAD,CAAL,GAAczG,MAAM,CAACyG,IAAD,CAApB;AACD,KAFD,MAEO,IAAI5L,OAAO,CAAC4L,IAAD,CAAX,EAAmB;AACxB1L,MAAAA,YAAY,CAAC0L,IAAD,EAAQC,KAAD,IAAW;AAC5BJ,QAAAA,KAAK,CAACI,KAAD,CAAL,GAAe1G,MAAM,CAAC0G,KAAD,CAArB;AACD,OAFW,CAAZ;AAGD,KAJM,MAIA;AACL1L,MAAAA,oBAAoB,CAACyL,IAAD,EAAO,CAACC,KAAD,EAAQzG,GAAR,KAAgB;AACzCqG,QAAAA,KAAK,CAACrG,GAAD,CAAL,GAAaD,MAAM,CAACC,GAAD,CAAnB;AACD,OAFmB,CAApB;AAGD;;AAED,WAAOqG,KAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACEK,EAAAA,iBAAiB,CAACvH,EAAD,EAAKwH,OAAL,EAAcC,OAAd,EAAuB;AACtC,UAAMC,SAAS,GAAG,KAAK3H,SAAL,CAAeC,EAAf,CAAlB;;AACA,QAAI,CAAC0H,SAAL,EAAgB;AACd,aAAO,IAAP;AACD;;AAED,WAAOA,SAAS,CAACC,gBAAV,CAA2BH,OAA3B,EAAoCC,OAApC,CAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEG,EAAAA,iBAAiB,CAAC5H,EAAD,EAAK6H,OAAL,EAAc;AAC7B,UAAMH,SAAS,GAAG,KAAK3H,SAAL,CAAeC,EAAf,CAAlB;AACA,UAAM;AAAE8H,MAAAA,CAAF;AAAKC,MAAAA,CAAL;AAAQP,MAAAA,OAAR;AAAiBC,MAAAA;AAAjB,QAA6BI,OAAnC;;AACA,QAAI,CAACH,SAAL,EAAgB;AACd,aAAO,KAAP;AACD;;AAED,UAAMM,YAAY,GAAGN,SAAS,CAACC,gBAAV,CAA2BH,OAA3B,EAAoCC,OAApC,CAArB;AACA,UAAMQ,YAAY,GAAGP,SAAS,CAACC,gBAAV,CAA2B,QAA3B,EAAqC,QAArC,CAArB;AACA,UAAMO,KAAK,GAAGD,YAAY,CAACH,CAAb,GAAiBE,YAAY,CAACF,CAA5C;AACA,UAAMK,KAAK,GAAGF,YAAY,CAACF,CAAb,GAAiBC,YAAY,CAACD,CAA5C;AAEAL,IAAAA,SAAS,CAACpD,GAAV,CAAc;AACZlD,MAAAA,IAAI,EAAE0G,CAAC,GAAGI,KADE;AAEZ7G,MAAAA,GAAG,EAAE0G,CAAC,GAAGI;AAFG,KAAd;AAKAT,IAAAA,SAAS,CAACnD,SAAV;AAEA,WAAO,IAAP;AACD;AAED;AACF;AACA;AACA;;;AACE6D,EAAAA,aAAa,GAAG;AACd,UAAMjD,KAAK,GAAG,KAAKT,cAAL,EAAd;AAEA,WAAO;AACLlB,MAAAA,KAAK,EAAE2B,KAAK,GAAGA,KAAK,CAAC3B,KAAT,GAAiB,CADxB;AAELC,MAAAA,MAAM,EAAE0B,KAAK,GAAGA,KAAK,CAAC1B,MAAT,GAAkB;AAF1B,KAAP;AAID;AAED;AACF;AACA;AACA;;;AACE4E,EAAAA,kBAAkB,GAAG;AACnB,UAAMC,YAAY,GAAG,IAAI7O,MAAM,CAAC8O,YAAX,EAArB;AAEAD,IAAAA,YAAY,CAAChE,GAAb,CAAiB;AACfkE,MAAAA,mBAAmB,EAAE;AADN,KAAjB;AAIA,WAAOF,YAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACE1F,EAAAA,uBAAuB,CAAC6F,QAAD,EAAW;AAChC,WAAO,KAAKzL,eAAL,CAAqByL,QAArB,CAAP;AACD;AAED;AACF;AACA;AACA;AACA;;;AACE/J,EAAAA,wBAAwB,GAAG;AACzBjF,IAAAA,MAAM,CAACiP,MAAP,CAAcC,SAAd,CAAwBC,aAAxB,GAAwC,KAAxC;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEjK,EAAAA,iBAAiB,CAACtC,OAAD,EAAU;AACzB,QAAIwM,eAAJ;AACA,QAAIC,aAAJ;;AAEA,QAAIzM,OAAO,CAAC0M,QAAZ,EAAsB;AACpBF,MAAAA,eAAe,GAAGxM,OAAlB;AACD,KAFD,MAEO;AACLwM,MAAAA,eAAe,GAAGG,QAAQ,CAACC,aAAT,CAAuB5M,OAAvB,CAAlB;AACD;;AAED,QAAIwM,eAAe,CAACK,QAAhB,CAAyBC,WAAzB,OAA2C,QAA/C,EAAyD;AACvDL,MAAAA,aAAa,GAAGE,QAAQ,CAACI,aAAT,CAAuB,QAAvB,CAAhB;AACAP,MAAAA,eAAe,CAACQ,WAAhB,CAA4BP,aAA5B;AACD;;AAED,SAAKjM,OAAL,GAAe,IAAIpD,MAAM,CAAC6P,MAAX,CAAkBR,aAAlB,EAAiC;AAC9CS,MAAAA,cAAc,EAAE,mCAD8B;AAE9Cf,MAAAA,mBAAmB,EAAE;AAFyB,KAAjC,CAAf;AAID;AAED;AACF;AACA;AACA;;;AACE5J,EAAAA,2BAA2B,GAAG;AAC5B,SAAK4K,SAAL,CAAe,KAAKxM,eAApB,EAAqC,IAAI5C,kBAAJ,EAArC;;AACA,SAAKoP,SAAL,CAAe,KAAKxM,eAApB,EAAqC,IAAI3C,eAAJ,EAArC;;AACA,SAAKmP,SAAL,CAAe,KAAKxM,eAApB,EAAqC,IAAI1C,eAAJ,EAArC;;AACA,SAAKkP,SAAL,CAAe,KAAKxM,eAApB,EAAqC,IAAIzC,gBAAJ,EAArC;;AACA,SAAKiP,SAAL,CAAe,KAAKxM,eAApB,EAAqC,IAAIxC,eAAJ,EAArC;;AACA,SAAKgP,SAAL,CAAe,KAAKxM,eAApB,EAAqC,IAAIvC,eAAJ,EAArC;AACD;AAED;AACF;AACA;AACA;;;AACEoE,EAAAA,iBAAiB,GAAG;AAClB,SAAK2K,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAIvD,WAAJ,CAAgB,IAAhB,CAAnC;;AACA,SAAK8P,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAItD,OAAJ,CAAY,IAAZ,CAAnC;;AACA,SAAK6P,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAIrD,IAAJ,CAAS,IAAT,CAAnC;;AACA,SAAK4P,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAIpD,QAAJ,CAAa,IAAb,CAAnC;;AACA,SAAK2P,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAInD,WAAJ,CAAgB,IAAhB,CAAnC;;AACA,SAAK0P,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAIlD,IAAJ,CAAS,IAAT,CAAnC;;AACA,SAAKyP,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAIjD,IAAJ,CAAS,IAAT,CAAnC;;AACA,SAAKwP,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAIhD,IAAJ,CAAS,IAAT,CAAnC;;AACA,SAAKuP,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAI/C,MAAJ,CAAW,IAAX,CAAnC;;AACA,SAAKsP,SAAL,CAAe,KAAKvM,aAApB,EAAmC,IAAI9C,KAAJ,CAAU,IAAV,CAAnC;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEqP,EAAAA,SAAS,CAACC,GAAD,EAAMC,MAAN,EAAc;AACrBD,IAAAA,GAAG,CAACC,MAAM,CAACC,OAAP,EAAD,CAAH,GAAwBD,MAAxB;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEjH,EAAAA,kBAAkB,CAACF,IAAD,EAAO;AACvB,WAAO,KAAKF,cAAL,OAA0BE,IAAjC;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEsB,EAAAA,iBAAiB,CAACL,KAAD,EAAQC,MAAR,EAAgB;AAC/B,UAAMmG,YAAY,GAAG,KAAKtN,WAAL,GAAmBkH,KAAxC;AACA,UAAMqG,YAAY,GAAG,KAAKtN,YAAL,GAAoBkH,MAAzC;AACA,QAAInH,WAAW,GAAGwN,IAAI,CAACC,GAAL,CAASvG,KAAT,EAAgB,KAAKlH,WAArB,CAAlB;AACA,QAAIC,YAAY,GAAGuN,IAAI,CAACC,GAAL,CAAStG,MAAT,EAAiB,KAAKlH,YAAtB,CAAnB;;AAEA,QAAIqN,YAAY,GAAG,CAAf,IAAoBA,YAAY,GAAGC,YAAvC,EAAqD;AACnDvN,MAAAA,WAAW,GAAGkH,KAAK,GAAGoG,YAAtB;AACArN,MAAAA,YAAY,GAAGkH,MAAM,GAAGmG,YAAxB;AACD,KAHD,MAGO,IAAIC,YAAY,GAAG,CAAf,IAAoBA,YAAY,GAAGD,YAAvC,EAAqD;AAC1DtN,MAAAA,WAAW,GAAGkH,KAAK,GAAGqG,YAAtB;AACAtN,MAAAA,YAAY,GAAGkH,MAAM,GAAGoG,YAAxB;AACD;;AAED,WAAO;AACLrG,MAAAA,KAAK,EAAEsG,IAAI,CAACE,KAAL,CAAW1N,WAAX,CADF;AAELmH,MAAAA,MAAM,EAAEqG,IAAI,CAACE,KAAL,CAAWzN,YAAX;AAFH,KAAP;AAID;AAED;AACF;AACA;AACA;AACA;;;AACEwI,EAAAA,gCAAgC,CAACrE,GAAD,EAAM;AACpC,UAAMuJ,SAAS,GAAG,KAAKvF,cAAL,GAAsBwF,cAAtB,EAAlB;AAEAxJ,IAAAA,GAAG,CAAC4D,GAAJ,CAAQnJ,cAAc,CAAC6L,eAAvB;AACAtG,IAAAA,GAAG,CAAC4D,GAAJ,CAAQ;AACNlD,MAAAA,IAAI,EAAE6I,SAAS,CAACnC,CADV;AAENzG,MAAAA,GAAG,EAAE4I,SAAS,CAAClC,CAFT;AAGN1C,MAAAA,WAAW,EAAE;AAHP,KAAR;AAMA,SAAKvD,SAAL,GAAiBvC,GAAjB,CAAqBmB,GAArB,EAA0BsB,eAA1B,CAA0CtB,GAA1C;AACD;AAED;AACF;AACA;;;AACE5B,EAAAA,mBAAmB,GAAG;AACpB,UAAMsB,MAAM,GAAG,KAAKvD,OAApB;AACA,UAAMsN,OAAO,GAAG,KAAKjN,QAArB;AACAkD,IAAAA,MAAM,CAACgK,EAAP,CAAU;AACR,oBAAcD,OAAO,CAAChN,WADd;AAER,sBAAgBgN,OAAO,CAAC7M,aAFhB;AAGR,wBAAkB6M,OAAO,CAAC3M,eAHlB;AAIR,uBAAiB2M,OAAO,CAACzM,aAJjB;AAKR,wBAAkByM,OAAO,CAACvM,cALlB;AAMR,yBAAmBuM,OAAO,CAACrM,gBANnB;AAOR,yBAAmBqM,OAAO,CAACnM,eAPnB;AAQR,sBAAgBmM,OAAO,CAAC/L,aARhB;AASR,2BAAqB+L,OAAO,CAAC7L,kBATrB;AAUR,2BAAqB6L,OAAO,CAAC3L,kBAVrB;AAWR,2BAAqB2L,OAAO,CAACjM;AAXrB,KAAV;AAaD;AAED;AACF;AACA;AACA;AACA;;;AACEd,EAAAA,YAAY,CAACiN,MAAD,EAAS;AACnB,UAAM;AAAEC,MAAAA,CAAC,EAAEC,KAAL;AAAY3K,MAAAA;AAAZ,QAAuByK,MAA7B;;AACA,UAAMG,aAAa,GAAG,KAAK3N,OAAL,CAAa4N,UAAb,CAAwBF,KAAxB,CAAtB;;AAEA,QAAI3K,MAAJ,EAAY;AACV,YAAM;AAAEuB,QAAAA;AAAF,UAAWvB,MAAjB;AACA,YAAM8K,QAAQ,GAAGtP,qBAAqB,CAACwE,MAAD,EAAU+K,IAAD,IAC7CtP,sBAAsB,CAAC,KAAKsF,WAAL,CAAiBgK,IAAjB,CAAD,EAAyBA,IAAzB,EAA+BxJ,IAAI,KAAK,iBAAxC,CADc,CAAtC;AAIA7F,MAAAA,6BAA6B,CAACoP,QAAD,CAA7B;AACD;;AAED,SAAKE,IAAL,CAAU3P,MAAM,CAAC4P,UAAjB,EAA6BN,KAA7B,EAAoCC,aAApC;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEjN,EAAAA,cAAc,CAAC8M,MAAD,EAAS;AACrB,UAAM3J,GAAG,GAAG2J,MAAM,CAACzK,MAAnB;;AACA,QAAIc,GAAG,CAACH,MAAJ,CAAW,UAAX,CAAJ,EAA4B;AAC1B;AACD;;AAED,SAAKkB,gBAAL,CAAsBf,GAAtB;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEjD,EAAAA,gBAAgB,CAAC4M,MAAD,EAAS;AACvB,UAAM3J,GAAG,GAAG2J,MAAM,CAACzK,MAAnB;;AAEA,SAAKkL,mBAAL,CAAyBtP,KAAK,CAACkF,GAAD,CAA9B;AACD;AAED;AACF;AACA;AACA;AACA;;;AACE/C,EAAAA,cAAc,CAAC0M,MAAD,EAAS;AACrB,SAAKU,SAAL,CACE9P,MAAM,CAAC+P,YADT,EAEGpK,MAAD,IAAY,KAAKwE,sBAAL,CAA4BxE,MAA5B,CAFd,EAGEyJ,MAAM,CAACzK,MAHT;AAKD;AAED;AACF;AACA;AACA;AACA;;;AACE/B,EAAAA,eAAe,CAACwM,MAAD,EAAS;AACtB,SAAKU,SAAL,CACE9P,MAAM,CAACgQ,aADT,EAEGrK,MAAD,IAAY,KAAKwE,sBAAL,CAA4BxE,MAA5B,CAFd,EAGEyJ,MAAM,CAACzK,MAHT;AAKD;AAED;AACF;AACA;AACA;AACA;;;AACE7B,EAAAA,iBAAiB,CAACsM,MAAD,EAAS;AACxB,UAAM;AAAEzK,MAAAA;AAAF,QAAayK,MAAnB;;AACA,QAAIzK,MAAM,CAACuB,IAAP,KAAgB,iBAApB,EAAuC;AACrC,YAAM+J,KAAK,GAAGtL,MAAM,CAACC,UAAP,EAAd;AAEAqL,MAAAA,KAAK,CAACC,OAAN,CAAeR,IAAD,IAAUA,IAAI,CAACC,IAAL,CAAU,iBAAV,EAA6BhL,MAA7B,CAAxB;AACD;;AAED,SAAKgL,IAAL,CAAU3P,MAAM,CAACmQ,eAAjB,EAAkCxL,MAAlC,EAA0C,KAAKe,WAAL,CAAiBf,MAAjB,CAA1C;AACD;AAED;AACF;AACA;AACA;AACA;;;AACE3B,EAAAA,gBAAgB,CAACoM,MAAD,EAAS;AACvB,SAAKU,SAAL,CACE9P,MAAM,CAACoQ,cADT,EAEGzK,MAAD,IAAY,KAAKwE,sBAAL,CAA4BxE,MAA5B,CAFd,EAGEyJ,MAAM,CAACzK,MAHT;AAKD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACEmL,EAAAA,SAAS,CAACO,SAAD,EAAYC,WAAZ,EAAyB3L,MAAzB,EAAiC;AACxC,UAAM4L,oBAAoB,GAAG5L,MAAM,IAAIA,MAAM,CAAC6L,qBAA9C;AACA,UAAMC,eAAe,GAAGF,oBAAoB,GAAG5L,MAAM,CAAC6L,qBAAP,CAA6BH,SAA7B,CAAH,GAA6C,MAAzF;;AAEA,QAAII,eAAe,KAAK,YAAxB,EAAsC;AACpC9L,MAAAA,MAAM,CAAC+L,mBAAP,CAA2BL,SAA3B,EAAuC1K,MAAD,IAAY;AAChD,aAAKgK,IAAL,CAAUU,SAAV,EAAqBC,WAAW,CAAC3K,MAAD,CAAhC;AACD,OAFD;AAGD;;AAED,QAAI8K,eAAe,KAAK,MAAxB,EAAgC;AAC9B,WAAKd,IAAL,CAAUU,SAAV,EAAqBC,WAAW,CAAC3L,MAAD,CAAhC;AACD;AACF;AAED;AACF;AACA;AACA;AACA;;;AACEzB,EAAAA,iBAAiB,CAACkM,MAAD,EAAS;AACxB,UAAM;AAAEzK,MAAAA;AAAF,QAAayK,MAAnB;AACA,UAAMuB,MAAM,GAAG,KAAKxG,sBAAL,CAA4BxF,MAA5B,CAAf;AAEA,SAAKgL,IAAL,CAAU3P,MAAM,CAAC4Q,gBAAjB,EAAmCD,MAAnC;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEvN,EAAAA,cAAc,CAACqC,GAAD,EAAM;AAClB,UAAM;AAAEoH,MAAAA,CAAC,EAAE1G,IAAL;AAAW2G,MAAAA,CAAC,EAAE1G;AAAd,QAAsBX,GAAG,CAACoL,IAAJ,CAAS5B,cAAT,EAA5B;AACAxJ,IAAAA,GAAG,CAACoL,IAAJ,CAASxH,GAAT,CACE/I,MAAM,CACJ;AACE6F,MAAAA,IADF;AAEEC,MAAAA;AAFF,KADI,EAKJlG,cAAc,CAAC6L,eALX,CADR;AAUA,UAAM4E,MAAM,GAAG,KAAKxG,sBAAL,CAA4B1E,GAAG,CAACoL,IAAhC,CAAf;AAEA,SAAKlB,IAAL,CAAU3P,MAAM,CAAC8Q,UAAjB,EAA6BH,MAA7B;AACD;AAED;AACF;AACA;AACA;;;AACErN,EAAAA,mBAAmB,GAAG;AACpB,SAAKqM,IAAL,CAAU3P,MAAM,CAAC+Q,iBAAjB;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEvN,EAAAA,mBAAmB,CAAC4L,MAAD,EAAS;AAC1B,UAAM;AAAEzK,MAAAA;AAAF,QAAayK,MAAnB;AACA,UAAMuB,MAAM,GAAG,KAAKxG,sBAAL,CAA4BxF,MAA5B,CAAf;AAEA,SAAKgL,IAAL,CAAU3P,MAAM,CAAC4Q,gBAAjB,EAAmCD,MAAnC;AACA,SAAKhB,IAAL,CAAU3P,MAAM,CAACgR,iBAAjB,EAAoC5B,MAAM,CAACzK,MAA3C;AACD;AAED;AACF;AACA;;;AACEsM,EAAAA,gBAAgB,GAAG;AACjB,SAAKrP,OAAL,CAAawC,mBAAb;;AACA,SAAKxC,OAAL,CAAayC,SAAb;AACD;AAED;AACF;AACA;AACA;;;AACE6M,EAAAA,mBAAmB,CAACC,UAAD,EAAa;AAC9B,SAAKvP,OAAL,CAAa4D,aAAb,CAA4BC,GAAD,IAAS;AAClCA,MAAAA,GAAG,CAAC0L,UAAJ,GAAiBA,UAAjB;AACA1L,MAAAA,GAAG,CAAC2L,WAAJ,GAAkBD,UAAU,GAAG,MAAH,GAAY,WAAxC;AACD,KAHD;AAID;AAED;AACF;AACA;AACA;AACA;;;AACEhH,EAAAA,sBAAsB,CAAC1E,GAAD,EAAM;AAC1B,UAAM4L,cAAc,GAAG,CACrB,MADqB,EAErB,KAFqB,EAGrB,OAHqB,EAIrB,QAJqB,EAKrB,MALqB,EAMrB,QANqB,EAOrB,aAPqB,EAQrB,SARqB,EASrB,OATqB,CAAvB;AAWA,UAAMpF,KAAK,GAAG;AACZlH,MAAAA,EAAE,EAAExE,KAAK,CAACkF,GAAD,CADG;AAEZS,MAAAA,IAAI,EAAET,GAAG,CAACS;AAFE,KAAd;AAKA5F,IAAAA,MAAM,CAAC2L,KAAD,EAAQxM,aAAa,CAACgG,GAAD,EAAM4L,cAAN,CAArB,CAAN;;AAEA,QAAI3R,QAAQ,CAAC,CAAC,QAAD,EAAW,MAAX,CAAD,EAAqB+F,GAAG,CAACS,IAAzB,CAAZ,EAA4C;AAC1C5F,MAAAA,MAAM,CAAC2L,KAAD,EAAQ,KAAKqF,qBAAL,CAA2B7L,GAA3B,EAAgCwG,KAAhC,CAAR,CAAN;AACD,KAFD,MAEO,IAAIvM,QAAQ,CAAC,CAAC,MAAD,EAAS,UAAT,EAAqB,QAArB,CAAD,EAAiC+F,GAAG,CAACS,IAArC,CAAZ,EAAwD;AAC7D,YAAMqL,SAAS,GAAG,KAAKrK,YAAL,CAAkBpH,UAAU,CAACmL,KAA7B,CAAlB;AACA3K,MAAAA,MAAM,CAAC2L,KAAD,EAAQ;AACZuF,QAAAA,IAAI,EAAED,SAAS,CAACE,4BAAV,CAAuChM,GAAvC;AADM,OAAR,CAAN;AAGD;;AAED,WAAOwG,KAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEqF,EAAAA,qBAAqB,CAAC7L,GAAD,EAAM;AACzB,UAAM4L,cAAc,GAAG,CACrB,MADqB,EAErB,YAFqB,EAGrB,UAHqB,EAIrB,WAJqB,EAKrB,WALqB,EAMrB,gBANqB,EAOrB,YAPqB,CAAvB;AASA,UAAMpF,KAAK,GAAG,EAAd;AACA3L,IAAAA,MAAM,CAAC2L,KAAD,EAAQxM,aAAa,CAACgG,GAAD,EAAM4L,cAAN,CAArB,CAAN;AAEA,WAAOpF,KAAP;AACD;AAED;AACF;AACA;AACA;AACA;;;AACEzF,EAAAA,gBAAgB,CAACf,GAAD,EAAM;AACpB,UAAMV,EAAE,GAAGxE,KAAK,CAACkF,GAAD,CAAhB;AACA,SAAK9D,QAAL,CAAcoD,EAAd,IAAoBU,GAApB;AAEA,WAAOV,EAAP;AACD;AAED;AACF;AACA;AACA;;;AACE8K,EAAAA,mBAAmB,CAAC9K,EAAD,EAAK;AACtB,WAAO,KAAKpD,QAAL,CAAcoD,EAAd,CAAP;AACD;AAED;AACF;AACA;;;AACE2M,EAAAA,6BAA6B,GAAG;AAC9B,UAAMzL,YAAY,GAAG,KAAKH,eAAL,EAArB;;AAEA,QAAIG,YAAJ,EAAkB;AAChB,WAAKxE,wBAAL,GAAgCwE,YAAhC;AACD;AACF;AAED;AACF;AACA;AACA;;;AACE0L,EAAAA,WAAW,GAAG;AACZ,QAAI,CAAC,KAAKlQ,wBAAV,EAAoC;AAClC,aAAO7B,OAAO,CAACmK,OAAR,CAAgB,EAAhB,CAAP;AACD;;AAED,UAAM6H,YAAY,GAAG,KAAKnQ,wBAA1B;AACA,UAAMoQ,aAAa,GAAGD,YAAY,CAAC1L,IAAb,KAAsB,iBAA5C;AACA,UAAM4L,aAAa,GAAGD,aAAa,GAAGD,YAAY,CAAChN,UAAb,EAAH,GAA+B,CAACgN,YAAD,CAAlE;AACA,QAAIG,eAAe,GAAG,IAAtB;AAEA,SAAKd,gBAAL;AAEA,WAAO,KAAKe,YAAL,CAAkBF,aAAlB,EAAiCG,IAAjC,CAAuCC,YAAD,IAAkB;AAC7D,UAAIA,YAAY,CAACC,MAAb,GAAsB,CAA1B,EAA6B;AAC3BJ,QAAAA,eAAe,GAAG,KAAKnL,6BAAL,CAAmCsL,YAAnC,CAAlB;AACD,OAFD,MAEO;AACL,SAACH,eAAD,IAAoBG,YAApB;AACD;;AACD,WAAKzQ,wBAAL,GAAgCsQ,eAAhC;AACA,WAAKhL,eAAL,CAAqBgL,eAArB;AACD,KARM,CAAP;AASD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEC,EAAAA,YAAY,CAACF,aAAD,EAAgB;AAC1B,UAAMI,YAAY,GAAG3T,OAAO,CAACiQ,GAAR,CAAYsD,aAAZ,EAA4BF,YAAD,IAC9C,KAAKQ,gBAAL,CAAsBR,YAAtB,CADmB,CAArB;AAIA,WAAOhS,OAAO,CAACyS,GAAR,CAAYH,YAAZ,CAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEE,EAAAA,gBAAgB,CAACR,YAAD,EAAe;AAC7B,WAAO,KAAKU,yBAAL,CAA+BV,YAA/B,EAA6CK,IAA7C,CAAmDM,YAAD,IAAkB;AACzE,YAAMC,gBAAgB,GAAG,KAAKrI,sBAAL,CAA4BoI,YAA5B,CAAzB;AACA,WAAKjO,GAAL,CAASiO,YAAT;AAEA,WAAK5C,IAAL,CAAU3P,MAAM,CAAC8Q,UAAjB,EAA6B0B,gBAA7B;AAEA,aAAOD,YAAP;AACD,KAPM,CAAP;AAQD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACED,EAAAA,yBAAyB,CAACV,YAAD,EAAe;AACtC,UAAMa,UAAU,GAAG,CAACpG,KAAD,EAAQqG,SAAR,KACjBA,SAAS,GAAGrG,KAAK,GAAGtL,kBAAX,GAAgCsL,KAAK,GAAGtL,kBADnD;;AAGA,WAAO,KAAK4R,iBAAL,CAAuBf,YAAvB,EAAqCK,IAArC,CAA2CM,YAAD,IAAkB;AACjE,YAAM;AAAEpM,QAAAA,IAAF;AAAQC,QAAAA,GAAR;AAAamC,QAAAA,KAAb;AAAoBC,QAAAA;AAApB,UAA+B+J,YAArC;AACA,YAAM;AAAEhK,QAAAA,KAAK,EAAEqK,WAAT;AAAsBpK,QAAAA,MAAM,EAAEqK;AAA9B,UAA+C,KAAK1F,aAAL,EAArD;AACA,YAAM2F,SAAS,GAAG3M,IAAI,GAAGoC,KAAK,GAAG,CAAjC;AACA,YAAMwK,UAAU,GAAG3M,GAAG,GAAGoC,MAAM,GAAG,CAAlC;AAEA+J,MAAAA,YAAY,CAAClJ,GAAb,CACE9K,OAAO,CAAC+B,MAAR,CACE;AACE6F,QAAAA,IAAI,EAAEsM,UAAU,CAACtM,IAAD,EAAO2M,SAAS,GAAG/R,kBAAZ,GAAiC6R,WAAxC,CADlB;AAEExM,QAAAA,GAAG,EAAEqM,UAAU,CAACrM,GAAD,EAAM2M,UAAU,GAAGhS,kBAAb,GAAkC8R,YAAxC;AAFjB,OADF,EAKE3S,cAAc,CAAC6L,eALjB,CADF;AAUA,aAAOwG,YAAP;AACD,KAjBM,CAAP;AAkBD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACEI,EAAAA,iBAAiB,CAACf,YAAD,EAAe;AAC9B,WAAO,IAAIhS,OAAJ,CAAamK,OAAD,IAAa;AAC9B6H,MAAAA,YAAY,CAAC1F,KAAb,CAAoB8G,MAAD,IAAY;AAC7B,cAAMzB,SAAS,GAAG,KAAKrK,YAAL,CAAkBpH,UAAU,CAACmL,KAA7B,CAAlB;;AACA,YAAItL,OAAO,CAACqT,MAAD,CAAX,EAAqB;AACnBzB,UAAAA,SAAS,CAAC0B,sBAAV,CAAiCD,MAAjC,EAAyCpB,YAAzC;AACD;;AAED7H,QAAAA,OAAO,CAACiJ,MAAD,CAAP;AACD,OAPD;AAQD,KATM,CAAP;AAUD;;AAjzCY;;AAozCfpS,YAAY,CAACsS,KAAb,CAAmBhS,QAAnB;AAEA,eAAeA,QAAf","sourcesContent":["/**\r\n * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>\r\n * @fileoverview Graphics module\r\n */\r\nimport snippet from 'tui-code-snippet';\r\nimport fabric from 'fabric';\r\nimport ImageLoader from './component/imageLoader';\r\nimport Cropper from './component/cropper';\r\nimport Flip from './component/flip';\r\nimport Rotation from './component/rotation';\r\nimport FreeDrawing from './component/freeDrawing';\r\nimport Line from './component/line';\r\nimport Text from './component/text';\r\nimport Icon from './component/icon';\r\nimport Filter from './component/filter';\r\nimport Shape from './component/shape';\r\nimport CropperDrawingMode from './drawingMode/cropper';\r\nimport FreeDrawingMode from './drawingMode/freeDrawing';\r\nimport LineDrawingMode from './drawingMode/lineDrawing';\r\nimport ShapeDrawingMode from './drawingMode/shape';\r\nimport TextDrawingMode from './drawingMode/text';\r\nimport IconDrawingMode from './drawingMode/icon';\r\nimport { getProperties, includes, isShape, Promise } from './util';\r\nimport {\r\n  componentNames as components,\r\n  eventNames as events,\r\n  drawingModes,\r\n  fObjectOptions,\r\n} from './consts';\r\nimport {\r\n  makeSelectionUndoData,\r\n  makeSelectionUndoDatum,\r\n  setCachedUndoDataForDimension,\r\n} from './helper/selectionModifyHelper';\r\n\r\nconst {\r\n  extend,\r\n  stamp,\r\n  isArray,\r\n  isString,\r\n  forEachArray,\r\n  forEachOwnProperties,\r\n  CustomEvents,\r\n} = snippet;\r\nconst DEFAULT_CSS_MAX_WIDTH = 1000;\r\nconst DEFAULT_CSS_MAX_HEIGHT = 800;\r\nconst EXTRA_PX_FOR_PASTE = 10;\r\n\r\nconst cssOnly = {\r\n  cssOnly: true,\r\n};\r\nconst backstoreOnly = {\r\n  backstoreOnly: true,\r\n};\r\n\r\n/**\r\n * Graphics class\r\n * @class\r\n * @param {string|HTMLElement} wrapper - Wrapper's element or selector\r\n * @param {Object} [option] - Canvas max width & height of css\r\n *  @param {number} option.cssMaxWidth - Canvas css-max-width\r\n *  @param {number} option.cssMaxHeight - Canvas css-max-height\r\n * @ignore\r\n */\r\nclass Graphics {\r\n  constructor(element, { cssMaxWidth, cssMaxHeight } = {}) {\r\n    /**\r\n     * Fabric image instance\r\n     * @type {fabric.Image}\r\n     */\r\n    this.canvasImage = null;\r\n\r\n    /**\r\n     * Max width of canvas elements\r\n     * @type {number}\r\n     */\r\n    this.cssMaxWidth = cssMaxWidth || DEFAULT_CSS_MAX_WIDTH;\r\n\r\n    /**\r\n     * Max height of canvas elements\r\n     * @type {number}\r\n     */\r\n    this.cssMaxHeight = cssMaxHeight || DEFAULT_CSS_MAX_HEIGHT;\r\n\r\n    /**\r\n     * cropper Selection Style\r\n     * @type {Object}\r\n     */\r\n    this.cropSelectionStyle = {};\r\n\r\n    /**\r\n     * target fabric object for copy paste feature\r\n     * @type {fabric.Object}\r\n     * @private\r\n     */\r\n    this.targetObjectForCopyPaste = null;\r\n\r\n    /**\r\n     * Image name\r\n     * @type {string}\r\n     */\r\n    this.imageName = '';\r\n\r\n    /**\r\n     * Object Map\r\n     * @type {Object}\r\n     * @private\r\n     */\r\n    this._objects = {};\r\n\r\n    /**\r\n     * Fabric-Canvas instance\r\n     * @type {fabric.Canvas}\r\n     * @private\r\n     */\r\n    this._canvas = null;\r\n\r\n    /**\r\n     * Drawing mode\r\n     * @type {string}\r\n     * @private\r\n     */\r\n    this._drawingMode = drawingModes.NORMAL;\r\n\r\n    /**\r\n     * DrawingMode map\r\n     * @type {Object.<string, DrawingMode>}\r\n     * @private\r\n     */\r\n    this._drawingModeMap = {};\r\n\r\n    /**\r\n     * Component map\r\n     * @type {Object.<string, Component>}\r\n     * @private\r\n     */\r\n    this._componentMap = {};\r\n\r\n    /**\r\n     * fabric event handlers\r\n     * @type {Object.<string, function>}\r\n     * @private\r\n     */\r\n    this._handler = {\r\n      onMouseDown: this._onMouseDown.bind(this),\r\n      onObjectAdded: this._onObjectAdded.bind(this),\r\n      onObjectRemoved: this._onObjectRemoved.bind(this),\r\n      onObjectMoved: this._onObjectMoved.bind(this),\r\n      onObjectScaled: this._onObjectScaled.bind(this),\r\n      onObjectModified: this._onObjectModified.bind(this),\r\n      onObjectRotated: this._onObjectRotated.bind(this),\r\n      onObjectSelected: this._onObjectSelected.bind(this),\r\n      onPathCreated: this._onPathCreated.bind(this),\r\n      onSelectionCleared: this._onSelectionCleared.bind(this),\r\n      onSelectionCreated: this._onSelectionCreated.bind(this),\r\n    };\r\n\r\n    this._setObjectCachingToFalse();\r\n    this._setCanvasElement(element);\r\n    this._createDrawingModeInstances();\r\n    this._createComponents();\r\n    this._attachCanvasEvents();\r\n  }\r\n\r\n  /**\r\n   * Destroy canvas element\r\n   */\r\n  destroy() {\r\n    const { wrapperEl } = this._canvas;\r\n\r\n    this._canvas.clear();\r\n\r\n    wrapperEl.parentNode.removeChild(wrapperEl);\r\n  }\r\n\r\n  /**\r\n   * Deactivates all objects on canvas\r\n   * @returns {Graphics} this\r\n   */\r\n  deactivateAll() {\r\n    this._canvas.discardActiveObject();\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Renders all objects on canvas\r\n   * @returns {Graphics} this\r\n   */\r\n  renderAll() {\r\n    this._canvas.renderAll();\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Adds objects on canvas\r\n   * @param {Object|Array} objects - objects\r\n   */\r\n  add(objects) {\r\n    let theArgs = [];\r\n    if (isArray(objects)) {\r\n      theArgs = objects;\r\n    } else {\r\n      theArgs.push(objects);\r\n    }\r\n\r\n    this._canvas.add(...theArgs);\r\n  }\r\n\r\n  /**\r\n   * Removes the object or group\r\n   * @param {Object} target - graphics object or group\r\n   * @returns {boolean} true if contains or false\r\n   */\r\n  contains(target) {\r\n    return this._canvas.contains(target);\r\n  }\r\n\r\n  /**\r\n   * Gets all objects or group\r\n   * @returns {Array} all objects, shallow copy\r\n   */\r\n  getObjects() {\r\n    return this._canvas.getObjects().slice();\r\n  }\r\n\r\n  /**\r\n   * Get an object by id\r\n   * @param {number} id - object id\r\n   * @returns {fabric.Object} object corresponding id\r\n   */\r\n  getObject(id) {\r\n    return this._objects[id];\r\n  }\r\n\r\n  /**\r\n   * Removes the object or group\r\n   * @param {Object} target - graphics object or group\r\n   */\r\n  remove(target) {\r\n    this._canvas.remove(target);\r\n  }\r\n\r\n  /**\r\n   * Removes all object or group\r\n   * @param {boolean} includesBackground - remove the background image or not\r\n   * @returns {Array} all objects array which is removed\r\n   */\r\n  removeAll(includesBackground) {\r\n    const canvas = this._canvas;\r\n    const objects = canvas.getObjects().slice();\r\n    canvas.remove(...this._canvas.getObjects());\r\n\r\n    if (includesBackground) {\r\n      canvas.clear();\r\n    }\r\n\r\n    return objects;\r\n  }\r\n\r\n  /**\r\n   * Removes an object or group by id\r\n   * @param {number} id - object id\r\n   * @returns {Array} removed objects\r\n   */\r\n  removeObjectById(id) {\r\n    const objects = [];\r\n    const canvas = this._canvas;\r\n    const target = this.getObject(id);\r\n    const isValidGroup = target && target.isType('group') && !target.isEmpty();\r\n\r\n    if (isValidGroup) {\r\n      canvas.discardActiveObject(); // restore states for each objects\r\n      target.forEachObject((obj) => {\r\n        objects.push(obj);\r\n        canvas.remove(obj);\r\n      });\r\n    } else if (canvas.contains(target)) {\r\n      objects.push(target);\r\n      canvas.remove(target);\r\n    }\r\n\r\n    return objects;\r\n  }\r\n\r\n  /**\r\n   * Get an id by object instance\r\n   * @param {fabric.Object} object object\r\n   * @returns {number} object id if it exists or null\r\n   */\r\n  getObjectId(object) {\r\n    let key = null;\r\n    for (key in this._objects) {\r\n      if (this._objects.hasOwnProperty(key)) {\r\n        if (object === this._objects[key]) {\r\n          return key;\r\n        }\r\n      }\r\n    }\r\n\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * Gets an active object or group\r\n   * @returns {Object} active object or group instance\r\n   */\r\n  getActiveObject() {\r\n    return this._canvas._activeObject;\r\n  }\r\n\r\n  /**\r\n   * Returns the object ID to delete the object.\r\n   * @returns {number} object id for remove\r\n   */\r\n  getActiveObjectIdForRemove() {\r\n    const activeObject = this.getActiveObject();\r\n    const { type, left, top } = activeObject;\r\n    const isSelection = type === 'activeSelection';\r\n\r\n    if (isSelection) {\r\n      const group = new fabric.Group([...activeObject.getObjects()], {\r\n        left,\r\n        top,\r\n      });\r\n\r\n      return this._addFabricObject(group);\r\n    }\r\n\r\n    return this.getObjectId(activeObject);\r\n  }\r\n\r\n  /**\r\n   * Verify that you are ready to erase the object.\r\n   * @returns {boolean} ready for object remove\r\n   */\r\n  isReadyRemoveObject() {\r\n    const activeObject = this.getActiveObject();\r\n\r\n    return activeObject && !activeObject.isEditing;\r\n  }\r\n\r\n  /**\r\n   * Gets an active group object\r\n   * @returns {Object} active group object instance\r\n   */\r\n  getActiveObjects() {\r\n    const activeObject = this._canvas._activeObject;\r\n\r\n    return activeObject && activeObject.type === 'activeSelection' ? activeObject : null;\r\n  }\r\n\r\n  /**\r\n   * Get Active object Selection from object ids\r\n   * @param {Array.<Object>} objects - fabric objects\r\n   * @returns {Object} target - target object group\r\n   */\r\n  getActiveSelectionFromObjects(objects) {\r\n    const canvas = this.getCanvas();\r\n\r\n    return new fabric.ActiveSelection(objects, { canvas });\r\n  }\r\n\r\n  /**\r\n   * Activates an object or group\r\n   * @param {Object} target - target object or group\r\n   */\r\n  setActiveObject(target) {\r\n    this._canvas.setActiveObject(target);\r\n  }\r\n\r\n  /**\r\n   * Set Crop selection style\r\n   * @param {Object} style - Selection styles\r\n   */\r\n  setCropSelectionStyle(style) {\r\n    this.cropSelectionStyle = style;\r\n  }\r\n\r\n  /**\r\n   * Get component\r\n   * @param {string} name - Component name\r\n   * @returns {Component}\r\n   */\r\n  getComponent(name) {\r\n    return this._componentMap[name];\r\n  }\r\n\r\n  /**\r\n   * Get current drawing mode\r\n   * @returns {string}\r\n   */\r\n  getDrawingMode() {\r\n    return this._drawingMode;\r\n  }\r\n\r\n  /**\r\n   * Start a drawing mode. If the current mode is not 'NORMAL', 'stopDrawingMode()' will be called first.\r\n   * @param {String} mode Can be one of <I>'CROPPER', 'FREE_DRAWING', 'LINE', 'TEXT', 'SHAPE'</I>\r\n   * @param {Object} [option] parameters of drawing mode, it's available with 'FREE_DRAWING', 'LINE_DRAWING'\r\n   *  @param {Number} [option.width] brush width\r\n   *  @param {String} [option.color] brush color\r\n   * @returns {boolean} true if success or false\r\n   */\r\n  startDrawingMode(mode, option) {\r\n    if (this._isSameDrawingMode(mode)) {\r\n      return true;\r\n    }\r\n\r\n    // If the current mode is not 'NORMAL', 'stopDrawingMode()' will be called first.\r\n    this.stopDrawingMode();\r\n\r\n    const drawingModeInstance = this._getDrawingModeInstance(mode);\r\n    if (drawingModeInstance && drawingModeInstance.start) {\r\n      drawingModeInstance.start(this, option);\r\n\r\n      this._drawingMode = mode;\r\n    }\r\n\r\n    return !!drawingModeInstance;\r\n  }\r\n\r\n  /**\r\n   * Stop the current drawing mode and back to the 'NORMAL' mode\r\n   */\r\n  stopDrawingMode() {\r\n    if (this._isSameDrawingMode(drawingModes.NORMAL)) {\r\n      return;\r\n    }\r\n\r\n    const drawingModeInstance = this._getDrawingModeInstance(this.getDrawingMode());\r\n    if (drawingModeInstance && drawingModeInstance.end) {\r\n      drawingModeInstance.end(this);\r\n    }\r\n    this._drawingMode = drawingModes.NORMAL;\r\n  }\r\n\r\n  /**\r\n   * To data url from canvas\r\n   * @param {Object} options - options for toDataURL\r\n   *   @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\r\n   *   @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\r\n   *   @param {Number} [options.multiplier=1] Multiplier to scale by\r\n   *   @param {Number} [options.left] Cropping left offset. Introduced in fabric v1.2.14\r\n   *   @param {Number} [options.top] Cropping top offset. Introduced in fabric v1.2.14\r\n   *   @param {Number} [options.width] Cropping width. Introduced in fabric v1.2.14\r\n   *   @param {Number} [options.height] Cropping height. Introduced in fabric v1.2.14\r\n   * @returns {string} A DOMString containing the requested data URI.\r\n   */\r\n  toDataURL(options) {\r\n    const cropper = this.getComponent(components.CROPPER);\r\n    cropper.changeVisibility(false);\r\n\r\n    const dataUrl = this._canvas && this._canvas.toDataURL(options);\r\n    cropper.changeVisibility(true);\r\n\r\n    return dataUrl;\r\n  }\r\n\r\n  /**\r\n   * Save image(background) of canvas\r\n   * @param {string} name - Name of image\r\n   * @param {?fabric.Image} canvasImage - Fabric image instance\r\n   */\r\n  setCanvasImage(name, canvasImage) {\r\n    if (canvasImage) {\r\n      stamp(canvasImage);\r\n    }\r\n    this.imageName = name;\r\n    this.canvasImage = canvasImage;\r\n  }\r\n\r\n  /**\r\n   * Set css max dimension\r\n   * @param {{width: number, height: number}} maxDimension - Max width & Max height\r\n   */\r\n  setCssMaxDimension(maxDimension) {\r\n    this.cssMaxWidth = maxDimension.width || this.cssMaxWidth;\r\n    this.cssMaxHeight = maxDimension.height || this.cssMaxHeight;\r\n  }\r\n\r\n  /**\r\n   * Adjust canvas dimension with scaling image\r\n   */\r\n  adjustCanvasDimension() {\r\n    const canvasImage = this.canvasImage.scale(1);\r\n    const { width, height } = canvasImage.getBoundingRect();\r\n    const maxDimension = this._calcMaxDimension(width, height);\r\n\r\n    this.setCanvasCssDimension({\r\n      width: '100%',\r\n      height: '100%', // Set height '' for IE9\r\n      'max-width': `${maxDimension.width}px`,\r\n      'max-height': `${maxDimension.height}px`,\r\n    });\r\n\r\n    this.setCanvasBackstoreDimension({\r\n      width,\r\n      height,\r\n    });\r\n    this._canvas.centerObject(canvasImage);\r\n  }\r\n\r\n  /**\r\n   * Set canvas dimension - css only\r\n   *  {@link http://fabricjs.com/docs/fabric.Canvas.html#setDimensions}\r\n   * @param {Object} dimension - Canvas css dimension\r\n   */\r\n  setCanvasCssDimension(dimension) {\r\n    this._canvas.setDimensions(dimension, cssOnly);\r\n  }\r\n\r\n  /**\r\n   * Set canvas dimension - backstore only\r\n   *  {@link http://fabricjs.com/docs/fabric.Canvas.html#setDimensions}\r\n   * @param {Object} dimension - Canvas backstore dimension\r\n   */\r\n  setCanvasBackstoreDimension(dimension) {\r\n    this._canvas.setDimensions(dimension, backstoreOnly);\r\n  }\r\n\r\n  /**\r\n   * Set image properties\r\n   * {@link http://fabricjs.com/docs/fabric.Image.html#set}\r\n   * @param {Object} setting - Image properties\r\n   * @param {boolean} [withRendering] - If true, The changed image will be reflected in the canvas\r\n   */\r\n  setImageProperties(setting, withRendering) {\r\n    const { canvasImage } = this;\r\n\r\n    if (!canvasImage) {\r\n      return;\r\n    }\r\n\r\n    canvasImage.set(setting).setCoords();\r\n    if (withRendering) {\r\n      this._canvas.renderAll();\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns canvas element of fabric.Canvas[[lower-canvas]]\r\n   * @returns {HTMLCanvasElement}\r\n   */\r\n  getCanvasElement() {\r\n    return this._canvas.getElement();\r\n  }\r\n\r\n  /**\r\n   * Get fabric.Canvas instance\r\n   * @returns {fabric.Canvas}\r\n   * @private\r\n   */\r\n  getCanvas() {\r\n    return this._canvas;\r\n  }\r\n\r\n  /**\r\n   * Get canvasImage (fabric.Image instance)\r\n   * @returns {fabric.Image}\r\n   */\r\n  getCanvasImage() {\r\n    return this.canvasImage;\r\n  }\r\n\r\n  /**\r\n   * Get image name\r\n   * @returns {string}\r\n   */\r\n  getImageName() {\r\n    return this.imageName;\r\n  }\r\n\r\n  /**\r\n   * Add image object on canvas\r\n   * @param {string} imgUrl - Image url to make object\r\n   * @returns {Promise}\r\n   */\r\n  addImageObject(imgUrl) {\r\n    const callback = this._callbackAfterLoadingImageObject.bind(this);\r\n\r\n    return new Promise((resolve) => {\r\n      fabric.Image.fromURL(\r\n        imgUrl,\r\n        (image) => {\r\n          callback(image);\r\n          resolve(this.createObjectProperties(image));\r\n        },\r\n        {\r\n          crossOrigin: 'Anonymous',\r\n        }\r\n      );\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Get center position of canvas\r\n   * @returns {Object} {left, top}\r\n   */\r\n  getCenter() {\r\n    return this._canvas.getCenter();\r\n  }\r\n\r\n  /**\r\n   * Get cropped rect\r\n   * @returns {Object} rect\r\n   */\r\n  getCropzoneRect() {\r\n    return this.getComponent(components.CROPPER).getCropzoneRect();\r\n  }\r\n\r\n  /**\r\n   * Get cropped rect\r\n   * @param {number} [mode] cropzone rect mode\r\n   */\r\n  setCropzoneRect(mode) {\r\n    this.getComponent(components.CROPPER).setCropzoneRect(mode);\r\n  }\r\n\r\n  /**\r\n   * Get cropped image data\r\n   * @param {Object} cropRect cropzone rect\r\n   *  @param {Number} cropRect.left left position\r\n   *  @param {Number} cropRect.top top position\r\n   *  @param {Number} cropRect.width width\r\n   *  @param {Number} cropRect.height height\r\n   * @returns {?{imageName: string, url: string}} cropped Image data\r\n   */\r\n  getCroppedImageData(cropRect) {\r\n    return this.getComponent(components.CROPPER).getCroppedImageData(cropRect);\r\n  }\r\n\r\n  /**\r\n   * Set brush option\r\n   * @param {Object} option brush option\r\n   *  @param {Number} option.width width\r\n   *  @param {String} option.color color like 'FFFFFF', 'rgba(0, 0, 0, 0.5)'\r\n   */\r\n  setBrush(option) {\r\n    const drawingMode = this._drawingMode;\r\n    let compName = components.FREE_DRAWING;\r\n\r\n    if (drawingMode === drawingModes.LINE_DRAWING) {\r\n      compName = components.LINE;\r\n    }\r\n\r\n    this.getComponent(compName).setBrush(option);\r\n  }\r\n\r\n  /**\r\n   * Set states of current drawing shape\r\n   * @param {string} type - Shape type (ex: 'rect', 'circle', 'triangle')\r\n   * @param {Object} [options] - Shape options\r\n   *      @param {(ShapeFillOption | string)} [options.fill] - {@link ShapeFillOption} or\r\n   *        Shape foreground color (ex: '#fff', 'transparent')\r\n   *      @param {string} [options.stoke] - Shape outline color\r\n   *      @param {number} [options.strokeWidth] - Shape outline width\r\n   *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not\r\n   */\r\n  setDrawingShape(type, options) {\r\n    this.getComponent(components.SHAPE).setStates(type, options);\r\n  }\r\n\r\n  /**\r\n   * Set style of current drawing icon\r\n   * @param {string} type - icon type (ex: 'icon-arrow', 'icon-star')\r\n   * @param {Object} [iconColor] - Icon color\r\n   */\r\n  setIconStyle(type, iconColor) {\r\n    this.getComponent(components.ICON).setStates(type, iconColor);\r\n  }\r\n\r\n  /**\r\n   * Register icon paths\r\n   * @param {Object} pathInfos - Path infos\r\n   *  @param {string} pathInfos.key - key\r\n   *  @param {string} pathInfos.value - value\r\n   */\r\n  registerPaths(pathInfos) {\r\n    this.getComponent(components.ICON).registerPaths(pathInfos);\r\n  }\r\n\r\n  /**\r\n   * Change cursor style\r\n   * @param {string} cursorType - cursor type\r\n   */\r\n  changeCursor(cursorType) {\r\n    const canvas = this.getCanvas();\r\n    canvas.defaultCursor = cursorType;\r\n    canvas.renderAll();\r\n  }\r\n\r\n  /**\r\n   * Whether it has the filter or not\r\n   * @param {string} type - Filter type\r\n   * @returns {boolean} true if it has the filter\r\n   */\r\n  hasFilter(type) {\r\n    return this.getComponent(components.FILTER).hasFilter(type);\r\n  }\r\n\r\n  /**\r\n   * Set selection style of fabric object by init option\r\n   * @param {Object} styles - Selection styles\r\n   */\r\n  setSelectionStyle(styles) {\r\n    extend(fObjectOptions.SELECTION_STYLE, styles);\r\n  }\r\n\r\n  /**\r\n   * Set object properties\r\n   * @param {number} id - object id\r\n   * @param {Object} props - props\r\n   *     @param {string} [props.fill] Color\r\n   *     @param {string} [props.fontFamily] Font type for text\r\n   *     @param {number} [props.fontSize] Size\r\n   *     @param {string} [props.fontStyle] Type of inclination (normal / italic)\r\n   *     @param {string} [props.fontWeight] Type of thicker or thinner looking (normal / bold)\r\n   *     @param {string} [props.textAlign] Type of text align (left / center / right)\r\n   *     @param {string} [props.textDecoration] Type of line (underline / line-through / overline)\r\n   * @returns {Object} applied properties\r\n   */\r\n  setObjectProperties(id, props) {\r\n    const object = this.getObject(id);\r\n    const clone = extend({}, props);\r\n\r\n    object.set(clone);\r\n\r\n    object.setCoords();\r\n\r\n    this.getCanvas().renderAll();\r\n\r\n    return clone;\r\n  }\r\n\r\n  /**\r\n   * Get object properties corresponding key\r\n   * @param {number} id - object id\r\n   * @param {Array<string>|ObjectProps|string} keys - property's key\r\n   * @returns {Object} properties\r\n   */\r\n  getObjectProperties(id, keys) {\r\n    const object = this.getObject(id);\r\n    const props = {};\r\n\r\n    if (isString(keys)) {\r\n      props[keys] = object[keys];\r\n    } else if (isArray(keys)) {\r\n      forEachArray(keys, (value) => {\r\n        props[value] = object[value];\r\n      });\r\n    } else {\r\n      forEachOwnProperties(keys, (value, key) => {\r\n        props[key] = object[key];\r\n      });\r\n    }\r\n\r\n    return props;\r\n  }\r\n\r\n  /**\r\n   * Get object position by originX, originY\r\n   * @param {number} id - object id\r\n   * @param {string} originX - can be 'left', 'center', 'right'\r\n   * @param {string} originY - can be 'top', 'center', 'bottom'\r\n   * @returns {Object} {{x:number, y: number}} position by origin if id is valid, or null\r\n   */\r\n  getObjectPosition(id, originX, originY) {\r\n    const targetObj = this.getObject(id);\r\n    if (!targetObj) {\r\n      return null;\r\n    }\r\n\r\n    return targetObj.getPointByOrigin(originX, originY);\r\n  }\r\n\r\n  /**\r\n   * Set object position  by originX, originY\r\n   * @param {number} id - object id\r\n   * @param {Object} posInfo - position object\r\n   *  @param {number} posInfo.x - x position\r\n   *  @param {number} posInfo.y - y position\r\n   *  @param {string} posInfo.originX - can be 'left', 'center', 'right'\r\n   *  @param {string} posInfo.originY - can be 'top', 'center', 'bottom'\r\n   * @returns {boolean} true if target id is valid or false\r\n   */\r\n  setObjectPosition(id, posInfo) {\r\n    const targetObj = this.getObject(id);\r\n    const { x, y, originX, originY } = posInfo;\r\n    if (!targetObj) {\r\n      return false;\r\n    }\r\n\r\n    const targetOrigin = targetObj.getPointByOrigin(originX, originY);\r\n    const centerOrigin = targetObj.getPointByOrigin('center', 'center');\r\n    const diffX = centerOrigin.x - targetOrigin.x;\r\n    const diffY = centerOrigin.y - targetOrigin.y;\r\n\r\n    targetObj.set({\r\n      left: x + diffX,\r\n      top: y + diffY,\r\n    });\r\n\r\n    targetObj.setCoords();\r\n\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Get the canvas size\r\n   * @returns {Object} {{width: number, height: number}} image size\r\n   */\r\n  getCanvasSize() {\r\n    const image = this.getCanvasImage();\r\n\r\n    return {\r\n      width: image ? image.width : 0,\r\n      height: image ? image.height : 0,\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Create fabric static canvas\r\n   * @returns {Object} {{width: number, height: number}} image size\r\n   */\r\n  createStaticCanvas() {\r\n    const staticCanvas = new fabric.StaticCanvas();\r\n\r\n    staticCanvas.set({\r\n      enableRetinaScaling: false,\r\n    });\r\n\r\n    return staticCanvas;\r\n  }\r\n\r\n  /**\r\n   * Get a DrawingMode instance\r\n   * @param {string} modeName - DrawingMode Class Name\r\n   * @returns {DrawingMode} DrawingMode instance\r\n   * @private\r\n   */\r\n  _getDrawingModeInstance(modeName) {\r\n    return this._drawingModeMap[modeName];\r\n  }\r\n\r\n  /**\r\n   * Set object caching to false. This brought many bugs when draw Shape & cropzone\r\n   * @see http://fabricjs.com/fabric-object-caching\r\n   * @private\r\n   */\r\n  _setObjectCachingToFalse() {\r\n    fabric.Object.prototype.objectCaching = false;\r\n  }\r\n\r\n  /**\r\n   * Set canvas element to fabric.Canvas\r\n   * @param {Element|string} element - Wrapper or canvas element or selector\r\n   * @private\r\n   */\r\n  _setCanvasElement(element) {\r\n    let selectedElement;\r\n    let canvasElement;\r\n\r\n    if (element.nodeType) {\r\n      selectedElement = element;\r\n    } else {\r\n      selectedElement = document.querySelector(element);\r\n    }\r\n\r\n    if (selectedElement.nodeName.toUpperCase() !== 'CANVAS') {\r\n      canvasElement = document.createElement('canvas');\r\n      selectedElement.appendChild(canvasElement);\r\n    }\r\n\r\n    this._canvas = new fabric.Canvas(canvasElement, {\r\n      containerClass: 'tui-image-editor-canvas-container',\r\n      enableRetinaScaling: false,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Creates DrawingMode instances\r\n   * @private\r\n   */\r\n  _createDrawingModeInstances() {\r\n    this._register(this._drawingModeMap, new CropperDrawingMode());\r\n    this._register(this._drawingModeMap, new FreeDrawingMode());\r\n    this._register(this._drawingModeMap, new LineDrawingMode());\r\n    this._register(this._drawingModeMap, new ShapeDrawingMode());\r\n    this._register(this._drawingModeMap, new TextDrawingMode());\r\n    this._register(this._drawingModeMap, new IconDrawingMode());\r\n  }\r\n\r\n  /**\r\n   * Create components\r\n   * @private\r\n   */\r\n  _createComponents() {\r\n    this._register(this._componentMap, new ImageLoader(this));\r\n    this._register(this._componentMap, new Cropper(this));\r\n    this._register(this._componentMap, new Flip(this));\r\n    this._register(this._componentMap, new Rotation(this));\r\n    this._register(this._componentMap, new FreeDrawing(this));\r\n    this._register(this._componentMap, new Line(this));\r\n    this._register(this._componentMap, new Text(this));\r\n    this._register(this._componentMap, new Icon(this));\r\n    this._register(this._componentMap, new Filter(this));\r\n    this._register(this._componentMap, new Shape(this));\r\n  }\r\n\r\n  /**\r\n   * Register component\r\n   * @param {Object} map - map object\r\n   * @param {Object} module - module which has getName method\r\n   * @private\r\n   */\r\n  _register(map, module) {\r\n    map[module.getName()] = module;\r\n  }\r\n\r\n  /**\r\n   * Get the current drawing mode is same with given mode\r\n   * @param {string} mode drawing mode\r\n   * @returns {boolean} true if same or false\r\n   */\r\n  _isSameDrawingMode(mode) {\r\n    return this.getDrawingMode() === mode;\r\n  }\r\n\r\n  /**\r\n   * Calculate max dimension of canvas\r\n   * The css-max dimension is dynamically decided with maintaining image ratio\r\n   * The css-max dimension is lower than canvas dimension (attribute of canvas, not css)\r\n   * @param {number} width - Canvas width\r\n   * @param {number} height - Canvas height\r\n   * @returns {{width: number, height: number}} - Max width & Max height\r\n   * @private\r\n   */\r\n  _calcMaxDimension(width, height) {\r\n    const wScaleFactor = this.cssMaxWidth / width;\r\n    const hScaleFactor = this.cssMaxHeight / height;\r\n    let cssMaxWidth = Math.min(width, this.cssMaxWidth);\r\n    let cssMaxHeight = Math.min(height, this.cssMaxHeight);\r\n\r\n    if (wScaleFactor < 1 && wScaleFactor < hScaleFactor) {\r\n      cssMaxWidth = width * wScaleFactor;\r\n      cssMaxHeight = height * wScaleFactor;\r\n    } else if (hScaleFactor < 1 && hScaleFactor < wScaleFactor) {\r\n      cssMaxWidth = width * hScaleFactor;\r\n      cssMaxHeight = height * hScaleFactor;\r\n    }\r\n\r\n    return {\r\n      width: Math.floor(cssMaxWidth),\r\n      height: Math.floor(cssMaxHeight),\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Callback function after loading image\r\n   * @param {fabric.Image} obj - Fabric image object\r\n   * @private\r\n   */\r\n  _callbackAfterLoadingImageObject(obj) {\r\n    const centerPos = this.getCanvasImage().getCenterPoint();\r\n\r\n    obj.set(fObjectOptions.SELECTION_STYLE);\r\n    obj.set({\r\n      left: centerPos.x,\r\n      top: centerPos.y,\r\n      crossOrigin: 'Anonymous',\r\n    });\r\n\r\n    this.getCanvas().add(obj).setActiveObject(obj);\r\n  }\r\n\r\n  /**\r\n   * Attach canvas's events\r\n   */\r\n  _attachCanvasEvents() {\r\n    const canvas = this._canvas;\r\n    const handler = this._handler;\r\n    canvas.on({\r\n      'mouse:down': handler.onMouseDown,\r\n      'object:added': handler.onObjectAdded,\r\n      'object:removed': handler.onObjectRemoved,\r\n      'object:moving': handler.onObjectMoved,\r\n      'object:scaling': handler.onObjectScaled,\r\n      'object:modified': handler.onObjectModified,\r\n      'object:rotating': handler.onObjectRotated,\r\n      'path:created': handler.onPathCreated,\r\n      'selection:cleared': handler.onSelectionCleared,\r\n      'selection:created': handler.onSelectionCreated,\r\n      'selection:updated': handler.onObjectSelected,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * \"mouse:down\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\r\n  _onMouseDown(fEvent) {\r\n    const { e: event, target } = fEvent;\r\n    const originPointer = this._canvas.getPointer(event);\r\n\r\n    if (target) {\r\n      const { type } = target;\r\n      const undoData = makeSelectionUndoData(target, (item) =>\r\n        makeSelectionUndoDatum(this.getObjectId(item), item, type === 'activeSelection')\r\n      );\r\n\r\n      setCachedUndoDataForDimension(undoData);\r\n    }\r\n\r\n    this.fire(events.MOUSE_DOWN, event, originPointer);\r\n  }\r\n\r\n  /**\r\n   * \"object:added\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\r\n  _onObjectAdded(fEvent) {\r\n    const obj = fEvent.target;\r\n    if (obj.isType('cropzone')) {\r\n      return;\r\n    }\r\n\r\n    this._addFabricObject(obj);\r\n  }\r\n\r\n  /**\r\n   * \"object:removed\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\r\n  _onObjectRemoved(fEvent) {\r\n    const obj = fEvent.target;\r\n\r\n    this._removeFabricObject(stamp(obj));\r\n  }\r\n\r\n  /**\r\n   * \"object:moving\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\r\n  _onObjectMoved(fEvent) {\r\n    this._lazyFire(\r\n      events.OBJECT_MOVED,\r\n      (object) => this.createObjectProperties(object),\r\n      fEvent.target\r\n    );\r\n  }\r\n\r\n  /**\r\n   * \"object:scaling\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\r\n  _onObjectScaled(fEvent) {\r\n    this._lazyFire(\r\n      events.OBJECT_SCALED,\r\n      (object) => this.createObjectProperties(object),\r\n      fEvent.target\r\n    );\r\n  }\r\n\r\n  /**\r\n   * \"object:modified\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\r\n  _onObjectModified(fEvent) {\r\n    const { target } = fEvent;\r\n    if (target.type === 'activeSelection') {\r\n      const items = target.getObjects();\r\n\r\n      items.forEach((item) => item.fire('modifiedInGroup', target));\r\n    }\r\n\r\n    this.fire(events.OBJECT_MODIFIED, target, this.getObjectId(target));\r\n  }\r\n\r\n  /**\r\n   * \"object:rotating\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\r\n  _onObjectRotated(fEvent) {\r\n    this._lazyFire(\r\n      events.OBJECT_ROTATED,\r\n      (object) => this.createObjectProperties(object),\r\n      fEvent.target\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Lazy event emitter\r\n   * @param {string} eventName - event name\r\n   * @param {Function} paramsMaker - make param function\r\n   * @param {Object} [target] - Object of the event owner.\r\n   * @private\r\n   */\r\n  _lazyFire(eventName, paramsMaker, target) {\r\n    const existEventDelegation = target && target.canvasEventDelegation;\r\n    const delegationState = existEventDelegation ? target.canvasEventDelegation(eventName) : 'none';\r\n\r\n    if (delegationState === 'unregisted') {\r\n      target.canvasEventRegister(eventName, (object) => {\r\n        this.fire(eventName, paramsMaker(object));\r\n      });\r\n    }\r\n\r\n    if (delegationState === 'none') {\r\n      this.fire(eventName, paramsMaker(target));\r\n    }\r\n  }\r\n\r\n  /**\r\n   * \"object:selected\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\r\n  _onObjectSelected(fEvent) {\r\n    const { target } = fEvent;\r\n    const params = this.createObjectProperties(target);\r\n\r\n    this.fire(events.OBJECT_ACTIVATED, params);\r\n  }\r\n\r\n  /**\r\n   * \"path:created\" canvas event handler\r\n   * @param {{path: fabric.Path}} obj - Path object\r\n   * @private\r\n   */\r\n  _onPathCreated(obj) {\r\n    const { x: left, y: top } = obj.path.getCenterPoint();\r\n    obj.path.set(\r\n      extend(\r\n        {\r\n          left,\r\n          top,\r\n        },\r\n        fObjectOptions.SELECTION_STYLE\r\n      )\r\n    );\r\n\r\n    const params = this.createObjectProperties(obj.path);\r\n\r\n    this.fire(events.ADD_OBJECT, params);\r\n  }\r\n\r\n  /**\r\n   * \"selction:cleared\" canvas event handler\r\n   * @private\r\n   */\r\n  _onSelectionCleared() {\r\n    this.fire(events.SELECTION_CLEARED);\r\n  }\r\n\r\n  /**\r\n   * \"selction:created\" canvas event handler\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event\r\n   * @private\r\n   */\r\n  _onSelectionCreated(fEvent) {\r\n    const { target } = fEvent;\r\n    const params = this.createObjectProperties(target);\r\n\r\n    this.fire(events.OBJECT_ACTIVATED, params);\r\n    this.fire(events.SELECTION_CREATED, fEvent.target);\r\n  }\r\n\r\n  /**\r\n   * Canvas discard selection all\r\n   */\r\n  discardSelection() {\r\n    this._canvas.discardActiveObject();\r\n    this._canvas.renderAll();\r\n  }\r\n\r\n  /**\r\n   * Canvas Selectable status change\r\n   * @param {boolean} selectable - expect status\r\n   */\r\n  changeSelectableAll(selectable) {\r\n    this._canvas.forEachObject((obj) => {\r\n      obj.selectable = selectable;\r\n      obj.hoverCursor = selectable ? 'move' : 'crosshair';\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Return object's properties\r\n   * @param {fabric.Object} obj - fabric object\r\n   * @returns {Object} properties object\r\n   */\r\n  createObjectProperties(obj) {\r\n    const predefinedKeys = [\r\n      'left',\r\n      'top',\r\n      'width',\r\n      'height',\r\n      'fill',\r\n      'stroke',\r\n      'strokeWidth',\r\n      'opacity',\r\n      'angle',\r\n    ];\r\n    const props = {\r\n      id: stamp(obj),\r\n      type: obj.type,\r\n    };\r\n\r\n    extend(props, getProperties(obj, predefinedKeys));\r\n\r\n    if (includes(['i-text', 'text'], obj.type)) {\r\n      extend(props, this._createTextProperties(obj, props));\r\n    } else if (includes(['rect', 'triangle', 'circle'], obj.type)) {\r\n      const shapeComp = this.getComponent(components.SHAPE);\r\n      extend(props, {\r\n        fill: shapeComp.makeFillPropertyForUserEvent(obj),\r\n      });\r\n    }\r\n\r\n    return props;\r\n  }\r\n\r\n  /**\r\n   * Get text object's properties\r\n   * @param {fabric.Object} obj - fabric text object\r\n   * @param {Object} props - properties\r\n   * @returns {Object} properties object\r\n   */\r\n  _createTextProperties(obj) {\r\n    const predefinedKeys = [\r\n      'text',\r\n      'fontFamily',\r\n      'fontSize',\r\n      'fontStyle',\r\n      'textAlign',\r\n      'textDecoration',\r\n      'fontWeight',\r\n    ];\r\n    const props = {};\r\n    extend(props, getProperties(obj, predefinedKeys));\r\n\r\n    return props;\r\n  }\r\n\r\n  /**\r\n   * Add object array by id\r\n   * @param {fabric.Object} obj - fabric object\r\n   * @returns {number} object id\r\n   */\r\n  _addFabricObject(obj) {\r\n    const id = stamp(obj);\r\n    this._objects[id] = obj;\r\n\r\n    return id;\r\n  }\r\n\r\n  /**\r\n   * Remove an object in array yb id\r\n   * @param {number} id - object id\r\n   */\r\n  _removeFabricObject(id) {\r\n    delete this._objects[id];\r\n  }\r\n\r\n  /**\r\n   * Reset targetObjectForCopyPaste value from activeObject\r\n   */\r\n  resetTargetObjectForCopyPaste() {\r\n    const activeObject = this.getActiveObject();\r\n\r\n    if (activeObject) {\r\n      this.targetObjectForCopyPaste = activeObject;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Paste fabric object\r\n   * @returns {Promise}\r\n   */\r\n  pasteObject() {\r\n    if (!this.targetObjectForCopyPaste) {\r\n      return Promise.resolve([]);\r\n    }\r\n\r\n    const targetObject = this.targetObjectForCopyPaste;\r\n    const isGroupSelect = targetObject.type === 'activeSelection';\r\n    const targetObjects = isGroupSelect ? targetObject.getObjects() : [targetObject];\r\n    let newTargetObject = null;\r\n\r\n    this.discardSelection();\r\n\r\n    return this._cloneObject(targetObjects).then((addedObjects) => {\r\n      if (addedObjects.length > 1) {\r\n        newTargetObject = this.getActiveSelectionFromObjects(addedObjects);\r\n      } else {\r\n        [newTargetObject] = addedObjects;\r\n      }\r\n      this.targetObjectForCopyPaste = newTargetObject;\r\n      this.setActiveObject(newTargetObject);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Clone object\r\n   * @param {fabric.Object} targetObjects - fabric object\r\n   * @returns {Promise}\r\n   * @private\r\n   */\r\n  _cloneObject(targetObjects) {\r\n    const addedObjects = snippet.map(targetObjects, (targetObject) =>\r\n      this._cloneObjectItem(targetObject)\r\n    );\r\n\r\n    return Promise.all(addedObjects);\r\n  }\r\n\r\n  /**\r\n   * Clone object one item\r\n   * @param {fabric.Object} targetObject - fabric object\r\n   * @returns {Promise}\r\n   * @private\r\n   */\r\n  _cloneObjectItem(targetObject) {\r\n    return this._copyFabricObjectForPaste(targetObject).then((clonedObject) => {\r\n      const objectProperties = this.createObjectProperties(clonedObject);\r\n      this.add(clonedObject);\r\n\r\n      this.fire(events.ADD_OBJECT, objectProperties);\r\n\r\n      return clonedObject;\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Copy fabric object with Changed position for copy and paste\r\n   * @param {fabric.Object} targetObject - fabric object\r\n   * @returns {Promise}\r\n   * @private\r\n   */\r\n  _copyFabricObjectForPaste(targetObject) {\r\n    const addExtraPx = (value, isReverse) =>\r\n      isReverse ? value - EXTRA_PX_FOR_PASTE : value + EXTRA_PX_FOR_PASTE;\r\n\r\n    return this._copyFabricObject(targetObject).then((clonedObject) => {\r\n      const { left, top, width, height } = clonedObject;\r\n      const { width: canvasWidth, height: canvasHeight } = this.getCanvasSize();\r\n      const rightEdge = left + width / 2;\r\n      const bottomEdge = top + height / 2;\r\n\r\n      clonedObject.set(\r\n        snippet.extend(\r\n          {\r\n            left: addExtraPx(left, rightEdge + EXTRA_PX_FOR_PASTE > canvasWidth),\r\n            top: addExtraPx(top, bottomEdge + EXTRA_PX_FOR_PASTE > canvasHeight),\r\n          },\r\n          fObjectOptions.SELECTION_STYLE\r\n        )\r\n      );\r\n\r\n      return clonedObject;\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Copy fabric object\r\n   * @param {fabric.Object} targetObject - fabric object\r\n   * @returns {Promise}\r\n   * @private\r\n   */\r\n  _copyFabricObject(targetObject) {\r\n    return new Promise((resolve) => {\r\n      targetObject.clone((cloned) => {\r\n        const shapeComp = this.getComponent(components.SHAPE);\r\n        if (isShape(cloned)) {\r\n          shapeComp.processForCopiedObject(cloned, targetObject);\r\n        }\r\n\r\n        resolve(cloned);\r\n      });\r\n    });\r\n  }\r\n}\r\n\r\nCustomEvents.mixin(Graphics);\r\n\r\nexport default Graphics;\r\n"]},"metadata":{},"sourceType":"module"}