69ad1ef956c8e1960cd6f35a0750ee9e.json
47.9 KB
{"ast":null,"code":"/**\r\n * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>\r\n * @fileoverview Cropzone extending fabric.Rect\r\n */\nimport snippet from 'tui-code-snippet';\nimport fabric from 'fabric';\nimport { clamp } from '../util';\nimport { eventNames as events } from '../consts';\nconst CORNER_TYPE_TOP_LEFT = 'tl';\nconst CORNER_TYPE_TOP_RIGHT = 'tr';\nconst CORNER_TYPE_MIDDLE_TOP = 'mt';\nconst CORNER_TYPE_MIDDLE_LEFT = 'ml';\nconst CORNER_TYPE_MIDDLE_RIGHT = 'mr';\nconst CORNER_TYPE_MIDDLE_BOTTOM = 'mb';\nconst CORNER_TYPE_BOTTOM_LEFT = 'bl';\nconst CORNER_TYPE_BOTTOM_RIGHT = 'br';\nconst CORNER_TYPE_LIST = [CORNER_TYPE_TOP_LEFT, CORNER_TYPE_TOP_RIGHT, CORNER_TYPE_MIDDLE_TOP, CORNER_TYPE_MIDDLE_LEFT, CORNER_TYPE_MIDDLE_RIGHT, CORNER_TYPE_MIDDLE_BOTTOM, CORNER_TYPE_BOTTOM_LEFT, CORNER_TYPE_BOTTOM_RIGHT];\n\nconst NOOP_FUNCTION = () => {};\n/**\r\n * Align with cropzone ratio\r\n * @param {string} selectedCorner - selected corner type\r\n * @returns {{width: number, height: number}}\r\n * @private\r\n */\n\n\n_c = NOOP_FUNCTION;\n\nfunction cornerTypeValid(selectedCorner) {\n return CORNER_TYPE_LIST.indexOf(selectedCorner) >= 0;\n}\n/**\r\n * return scale basis type\r\n * @param {number} diffX - X distance of the cursor and corner.\r\n * @param {number} diffY - Y distance of the cursor and corner.\r\n * @returns {string}\r\n * @private\r\n */\n\n\nfunction getScaleBasis(diffX, diffY) {\n return diffX > diffY ? 'width' : 'height';\n}\n/**\r\n * Cropzone object\r\n * Issue: IE7, 8(with excanvas)\r\n * - Cropzone is a black zone without transparency.\r\n * @class Cropzone\r\n * @extends {fabric.Rect}\r\n * @ignore\r\n */\n\n\nconst Cropzone = fabric.util.createClass(fabric.Rect,\n/** @lends Cropzone.prototype */\n{\n /**\r\n * Constructor\r\n * @param {Object} canvas canvas\r\n * @param {Object} options Options object\r\n * @param {Object} extendsOptions object for extends \"options\"\r\n * @override\r\n */\n initialize(canvas, options, extendsOptions) {\n options = snippet.extend(options, extendsOptions);\n options.type = 'cropzone';\n this.callSuper('initialize', options);\n\n this._addEventHandler();\n\n this.canvas = canvas;\n this.options = options;\n },\n\n canvasEventDelegation(eventName) {\n let delegationState = 'unregisted';\n const isRegisted = this.canvasEventTrigger[eventName] !== NOOP_FUNCTION;\n\n if (isRegisted) {\n delegationState = 'registed';\n } else if ([events.OBJECT_MOVED, events.OBJECT_SCALED].indexOf(eventName) < 0) {\n delegationState = 'none';\n }\n\n return delegationState;\n },\n\n canvasEventRegister(eventName, eventTrigger) {\n this.canvasEventTrigger[eventName] = eventTrigger;\n },\n\n _addEventHandler() {\n this.canvasEventTrigger = {\n [events.OBJECT_MOVED]: NOOP_FUNCTION,\n [events.OBJECT_SCALED]: NOOP_FUNCTION\n };\n this.on({\n moving: this._onMoving.bind(this),\n scaling: this._onScaling.bind(this)\n });\n },\n\n _renderCropzone(ctx) {\n const cropzoneDashLineWidth = 7;\n const cropzoneDashLineOffset = 7; // Calc original scale\n\n const originalFlipX = this.flipX ? -1 : 1;\n const originalFlipY = this.flipY ? -1 : 1;\n const originalScaleX = originalFlipX / this.scaleX;\n const originalScaleY = originalFlipY / this.scaleY; // Set original scale\n\n ctx.scale(originalScaleX, originalScaleY); // Render outer rect\n\n this._fillOuterRect(ctx, 'rgba(0, 0, 0, 0.5)');\n\n if (this.options.lineWidth) {\n this._fillInnerRect(ctx);\n\n this._strokeBorder(ctx, 'rgb(255, 255, 255)', {\n lineWidth: this.options.lineWidth\n });\n } else {\n // Black dash line\n this._strokeBorder(ctx, 'rgb(0, 0, 0)', {\n lineDashWidth: cropzoneDashLineWidth\n }); // White dash line\n\n\n this._strokeBorder(ctx, 'rgb(255, 255, 255)', {\n lineDashWidth: cropzoneDashLineWidth,\n lineDashOffset: cropzoneDashLineOffset\n });\n } // Reset scale\n\n\n ctx.scale(1 / originalScaleX, 1 / originalScaleY);\n },\n\n /**\r\n * Render Crop-zone\r\n * @private\r\n * @override\r\n */\n _render(ctx) {\n this.callSuper('_render', ctx);\n\n this._renderCropzone(ctx);\n },\n\n /**\r\n * Cropzone-coordinates with outer rectangle\r\n *\r\n * x0 x1 x2 x3\r\n * y0 +--------------------------+\r\n * |///////|//////////|///////| // <--- \"Outer-rectangle\"\r\n * |///////|//////////|///////|\r\n * y1 +-------+----------+-------+\r\n * |///////| Cropzone |///////| Cropzone is the \"Inner-rectangle\"\r\n * |///////| (0, 0) |///////| Center point (0, 0)\r\n * y2 +-------+----------+-------+\r\n * |///////|//////////|///////|\r\n * |///////|//////////|///////|\r\n * y3 +--------------------------+\r\n *\r\n * @typedef {{x: Array<number>, y: Array<number>}} cropzoneCoordinates\r\n * @ignore\r\n */\n\n /**\r\n * Fill outer rectangle\r\n * @param {CanvasRenderingContext2D} ctx - Context\r\n * @param {string|CanvasGradient|CanvasPattern} fillStyle - Fill-style\r\n * @private\r\n */\n _fillOuterRect(ctx, fillStyle) {\n const {\n x,\n y\n } = this._getCoordinates();\n\n ctx.save();\n ctx.fillStyle = fillStyle;\n ctx.beginPath(); // Outer rectangle\n // Numbers are +/-1 so that overlay edges don't get blurry.\n\n ctx.moveTo(x[0] - 1, y[0] - 1);\n ctx.lineTo(x[3] + 1, y[0] - 1);\n ctx.lineTo(x[3] + 1, y[3] + 1);\n ctx.lineTo(x[0] - 1, y[3] + 1);\n ctx.lineTo(x[0] - 1, y[0] - 1);\n ctx.closePath(); // Inner rectangle\n\n ctx.moveTo(x[1], y[1]);\n ctx.lineTo(x[1], y[2]);\n ctx.lineTo(x[2], y[2]);\n ctx.lineTo(x[2], y[1]);\n ctx.lineTo(x[1], y[1]);\n ctx.closePath();\n ctx.fill();\n ctx.restore();\n },\n\n /**\r\n * Draw Inner grid line\r\n * @param {CanvasRenderingContext2D} ctx - Context\r\n * @private\r\n */\n _fillInnerRect(ctx) {\n const {\n x: outerX,\n y: outerY\n } = this._getCoordinates();\n\n const x = this._caculateInnerPosition(outerX, (outerX[2] - outerX[1]) / 3);\n\n const y = this._caculateInnerPosition(outerY, (outerY[2] - outerY[1]) / 3);\n\n ctx.save();\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';\n ctx.lineWidth = this.options.lineWidth;\n ctx.beginPath();\n ctx.moveTo(x[0], y[1]);\n ctx.lineTo(x[3], y[1]);\n ctx.moveTo(x[0], y[2]);\n ctx.lineTo(x[3], y[2]);\n ctx.moveTo(x[1], y[0]);\n ctx.lineTo(x[1], y[3]);\n ctx.moveTo(x[2], y[0]);\n ctx.lineTo(x[2], y[3]);\n ctx.stroke();\n ctx.closePath();\n ctx.restore();\n },\n\n /**\r\n * Calculate Inner Position\r\n * @param {Array} outer - outer position\r\n * @param {number} size - interval for calculate\r\n * @returns {Array} - inner position\r\n * @private\r\n */\n _caculateInnerPosition(outer, size) {\n const position = [];\n position[0] = outer[1];\n position[1] = outer[1] + size;\n position[2] = outer[1] + size * 2;\n position[3] = outer[2];\n return position;\n },\n\n /**\r\n * Get coordinates\r\n * @returns {cropzoneCoordinates} - {@link cropzoneCoordinates}\r\n * @private\r\n */\n _getCoordinates() {\n const {\n canvas,\n width,\n height,\n left,\n top\n } = this;\n const halfWidth = width / 2;\n const halfHeight = height / 2;\n const canvasHeight = canvas.getHeight(); // fabric object\n\n const canvasWidth = canvas.getWidth(); // fabric object\n\n return {\n x: snippet.map([-(halfWidth + left), // x0\n -halfWidth, // x1\n halfWidth, // x2\n halfWidth + (canvasWidth - left - width) // x3\n ], Math.ceil),\n y: snippet.map([-(halfHeight + top), // y0\n -halfHeight, // y1\n halfHeight, // y2\n halfHeight + (canvasHeight - top - height) // y3\n ], Math.ceil)\n };\n },\n\n /**\r\n * Stroke border\r\n * @param {CanvasRenderingContext2D} ctx - Context\r\n * @param {string|CanvasGradient|CanvasPattern} strokeStyle - Stroke-style\r\n * @param {number} lineDashWidth - Dash width\r\n * @param {number} [lineDashOffset] - Dash offset\r\n * @param {number} [lineWidth] - line width\r\n * @private\r\n */\n _strokeBorder(ctx, strokeStyle, {\n lineDashWidth,\n lineDashOffset,\n lineWidth\n }) {\n const halfWidth = this.width / 2;\n const halfHeight = this.height / 2;\n ctx.save();\n ctx.strokeStyle = strokeStyle;\n\n if (ctx.setLineDash) {\n ctx.setLineDash([lineDashWidth, lineDashWidth]);\n }\n\n if (lineDashOffset) {\n ctx.lineDashOffset = lineDashOffset;\n }\n\n if (lineWidth) {\n ctx.lineWidth = lineWidth;\n }\n\n ctx.beginPath();\n ctx.moveTo(-halfWidth, -halfHeight);\n ctx.lineTo(halfWidth, -halfHeight);\n ctx.lineTo(halfWidth, halfHeight);\n ctx.lineTo(-halfWidth, halfHeight);\n ctx.lineTo(-halfWidth, -halfHeight);\n ctx.stroke();\n ctx.restore();\n },\n\n /**\r\n * onMoving event listener\r\n * @private\r\n */\n _onMoving() {\n const {\n height,\n width,\n left,\n top\n } = this;\n const maxLeft = this.canvas.getWidth() - width;\n const maxTop = this.canvas.getHeight() - height;\n this.left = clamp(left, 0, maxLeft);\n this.top = clamp(top, 0, maxTop);\n this.canvasEventTrigger[events.OBJECT_MOVED](this);\n },\n\n /**\r\n * onScaling event listener\r\n * @param {{e: MouseEvent}} fEvent - Fabric event\r\n * @private\r\n */\n _onScaling(fEvent) {\n const selectedCorner = fEvent.transform.corner;\n const pointer = this.canvas.getPointer(fEvent.e);\n\n const settings = this._calcScalingSizeFromPointer(pointer, selectedCorner); // On scaling cropzone,\n // change real width and height and fix scaleFactor to 1\n\n\n this.scale(1).set(settings);\n this.canvasEventTrigger[events.OBJECT_SCALED](this);\n },\n\n /**\r\n * Calc scaled size from mouse pointer with selected corner\r\n * @param {{x: number, y: number}} pointer - Mouse position\r\n * @param {string} selectedCorner - selected corner type\r\n * @returns {Object} Having left or(and) top or(and) width or(and) height.\r\n * @private\r\n */\n _calcScalingSizeFromPointer(pointer, selectedCorner) {\n const isCornerTypeValid = cornerTypeValid(selectedCorner);\n return isCornerTypeValid && this._resizeCropZone(pointer, selectedCorner);\n },\n\n /**\r\n * Align with cropzone ratio\r\n * @param {number} width - cropzone width\r\n * @param {number} height - cropzone height\r\n * @param {number} maxWidth - limit max width\r\n * @param {number} maxHeight - limit max height\r\n * @param {number} scaleTo - cropzone ratio\r\n * @returns {{width: number, height: number}}\r\n * @private\r\n */\n adjustRatioCropzoneSize({\n width,\n height,\n leftMaker,\n topMaker,\n maxWidth,\n maxHeight,\n scaleTo\n }) {\n width = maxWidth ? clamp(width, 1, maxWidth) : width;\n height = maxHeight ? clamp(height, 1, maxHeight) : height;\n\n if (!this.presetRatio) {\n return {\n width,\n height,\n left: leftMaker(width),\n top: topMaker(height)\n };\n }\n\n if (scaleTo === 'width') {\n height = width / this.presetRatio;\n } else {\n width = height * this.presetRatio;\n }\n\n const maxScaleFactor = Math.min(maxWidth / width, maxHeight / height);\n\n if (maxScaleFactor <= 1) {\n [width, height] = [width, height].map(v => v * maxScaleFactor);\n }\n\n return {\n width,\n height,\n left: leftMaker(width),\n top: topMaker(height)\n };\n },\n\n /**\r\n * Get dimension last state cropzone\r\n * @returns {{rectTop: number, rectLeft: number, rectWidth: number, rectHeight: number}}\r\n * @private\r\n */\n _getCropzoneRectInfo() {\n const {\n width: canvasWidth,\n height: canvasHeight\n } = this.canvas;\n const {\n top: rectTop,\n left: rectLeft,\n width: rectWidth,\n height: rectHeight\n } = this.getBoundingRect(false, true);\n return {\n rectTop,\n rectLeft,\n rectWidth,\n rectHeight,\n rectRight: rectLeft + rectWidth,\n rectBottom: rectTop + rectHeight,\n canvasWidth,\n canvasHeight\n };\n },\n\n /**\r\n * Calc scaling dimension\r\n * @param {Object} position - Mouse position\r\n * @param {string} corner - corner type\r\n * @returns {{left: number, top: number, width: number, height: number}}\r\n * @private\r\n */\n _resizeCropZone({\n x,\n y\n }, corner) {\n const {\n rectWidth,\n rectHeight,\n rectTop,\n rectLeft,\n rectBottom,\n rectRight,\n canvasWidth,\n canvasHeight\n } = this._getCropzoneRectInfo();\n\n const resizeInfoMap = {\n tl: {\n width: rectRight - x,\n height: rectBottom - y,\n leftMaker: newWidth => rectRight - newWidth,\n topMaker: newHeight => rectBottom - newHeight,\n maxWidth: rectRight,\n maxHeight: rectBottom,\n scaleTo: getScaleBasis(rectLeft - x, rectTop - y)\n },\n tr: {\n width: x - rectLeft,\n height: rectBottom - y,\n leftMaker: () => rectLeft,\n topMaker: newHeight => rectBottom - newHeight,\n maxWidth: canvasWidth - rectLeft,\n maxHeight: rectBottom,\n scaleTo: getScaleBasis(x - rectRight, rectTop - y)\n },\n mt: {\n width: rectWidth,\n height: rectBottom - y,\n leftMaker: () => rectLeft,\n topMaker: newHeight => rectBottom - newHeight,\n maxWidth: canvasWidth - rectLeft,\n maxHeight: rectBottom,\n scaleTo: 'height'\n },\n ml: {\n width: rectRight - x,\n height: rectHeight,\n leftMaker: newWidth => rectRight - newWidth,\n topMaker: () => rectTop,\n maxWidth: rectRight,\n maxHeight: canvasHeight - rectTop,\n scaleTo: 'width'\n },\n mr: {\n width: x - rectLeft,\n height: rectHeight,\n leftMaker: () => rectLeft,\n topMaker: () => rectTop,\n maxWidth: canvasWidth - rectLeft,\n maxHeight: canvasHeight - rectTop,\n scaleTo: 'width'\n },\n mb: {\n width: rectWidth,\n height: y - rectTop,\n leftMaker: () => rectLeft,\n topMaker: () => rectTop,\n maxWidth: canvasWidth - rectLeft,\n maxHeight: canvasHeight - rectTop,\n scaleTo: 'height'\n },\n bl: {\n width: rectRight - x,\n height: y - rectTop,\n leftMaker: newWidth => rectRight - newWidth,\n topMaker: () => rectTop,\n maxWidth: rectRight,\n maxHeight: canvasHeight - rectTop,\n scaleTo: getScaleBasis(rectLeft - x, y - rectBottom)\n },\n br: {\n width: x - rectLeft,\n height: y - rectTop,\n leftMaker: () => rectLeft,\n topMaker: () => rectTop,\n maxWidth: canvasWidth - rectLeft,\n maxHeight: canvasHeight - rectTop,\n scaleTo: getScaleBasis(x - rectRight, y - rectBottom)\n }\n };\n return this.adjustRatioCropzoneSize(resizeInfoMap[corner]);\n },\n\n /**\r\n * Return the whether this cropzone is valid\r\n * @returns {boolean}\r\n */\n isValid() {\n return this.left >= 0 && this.top >= 0 && this.width > 0 && this.height > 0;\n }\n\n});\nexport default Cropzone;\n\nvar _c;\n\n$RefreshReg$(_c, \"NOOP_FUNCTION\");","map":{"version":3,"sources":["C:/Users/kkwan_000/Desktop/git/2017110269/minsung/src/js/extension/cropzone.js"],"names":["snippet","fabric","clamp","eventNames","events","CORNER_TYPE_TOP_LEFT","CORNER_TYPE_TOP_RIGHT","CORNER_TYPE_MIDDLE_TOP","CORNER_TYPE_MIDDLE_LEFT","CORNER_TYPE_MIDDLE_RIGHT","CORNER_TYPE_MIDDLE_BOTTOM","CORNER_TYPE_BOTTOM_LEFT","CORNER_TYPE_BOTTOM_RIGHT","CORNER_TYPE_LIST","NOOP_FUNCTION","cornerTypeValid","selectedCorner","indexOf","getScaleBasis","diffX","diffY","Cropzone","util","createClass","Rect","initialize","canvas","options","extendsOptions","extend","type","callSuper","_addEventHandler","canvasEventDelegation","eventName","delegationState","isRegisted","canvasEventTrigger","OBJECT_MOVED","OBJECT_SCALED","canvasEventRegister","eventTrigger","on","moving","_onMoving","bind","scaling","_onScaling","_renderCropzone","ctx","cropzoneDashLineWidth","cropzoneDashLineOffset","originalFlipX","flipX","originalFlipY","flipY","originalScaleX","scaleX","originalScaleY","scaleY","scale","_fillOuterRect","lineWidth","_fillInnerRect","_strokeBorder","lineDashWidth","lineDashOffset","_render","fillStyle","x","y","_getCoordinates","save","beginPath","moveTo","lineTo","closePath","fill","restore","outerX","outerY","_caculateInnerPosition","strokeStyle","stroke","outer","size","position","width","height","left","top","halfWidth","halfHeight","canvasHeight","getHeight","canvasWidth","getWidth","map","Math","ceil","setLineDash","maxLeft","maxTop","fEvent","transform","corner","pointer","getPointer","e","settings","_calcScalingSizeFromPointer","set","isCornerTypeValid","_resizeCropZone","adjustRatioCropzoneSize","leftMaker","topMaker","maxWidth","maxHeight","scaleTo","presetRatio","maxScaleFactor","min","v","_getCropzoneRectInfo","rectTop","rectLeft","rectWidth","rectHeight","getBoundingRect","rectRight","rectBottom","resizeInfoMap","tl","newWidth","newHeight","tr","mt","ml","mr","mb","bl","br","isValid"],"mappings":"AAAA;AACA;AACA;AACA;AACA,OAAOA,OAAP,MAAoB,kBAApB;AACA,OAAOC,MAAP,MAAmB,QAAnB;AACA,SAASC,KAAT,QAAsB,SAAtB;AACA,SAASC,UAAU,IAAIC,MAAvB,QAAqC,WAArC;AAEA,MAAMC,oBAAoB,GAAG,IAA7B;AACA,MAAMC,qBAAqB,GAAG,IAA9B;AACA,MAAMC,sBAAsB,GAAG,IAA/B;AACA,MAAMC,uBAAuB,GAAG,IAAhC;AACA,MAAMC,wBAAwB,GAAG,IAAjC;AACA,MAAMC,yBAAyB,GAAG,IAAlC;AACA,MAAMC,uBAAuB,GAAG,IAAhC;AACA,MAAMC,wBAAwB,GAAG,IAAjC;AACA,MAAMC,gBAAgB,GAAG,CACvBR,oBADuB,EAEvBC,qBAFuB,EAGvBC,sBAHuB,EAIvBC,uBAJuB,EAKvBC,wBALuB,EAMvBC,yBANuB,EAOvBC,uBAPuB,EAQvBC,wBARuB,CAAzB;;AAUA,MAAME,aAAa,GAAG,MAAM,CAAE,CAA9B;AAEA;AACA;AACA;AACA;AACA;AACA;;;KAPMA,a;;AAQN,SAASC,eAAT,CAAyBC,cAAzB,EAAyC;AACvC,SAAOH,gBAAgB,CAACI,OAAjB,CAAyBD,cAAzB,KAA4C,CAAnD;AACD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,SAASE,aAAT,CAAuBC,KAAvB,EAA8BC,KAA9B,EAAqC;AACnC,SAAOD,KAAK,GAAGC,KAAR,GAAgB,OAAhB,GAA0B,QAAjC;AACD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,MAAMC,QAAQ,GAAGpB,MAAM,CAACqB,IAAP,CAAYC,WAAZ,CACftB,MAAM,CAACuB,IADQ;AAEf;AAAiC;AAC/B;AACJ;AACA;AACA;AACA;AACA;AACA;AACIC,EAAAA,UAAU,CAACC,MAAD,EAASC,OAAT,EAAkBC,cAAlB,EAAkC;AAC1CD,IAAAA,OAAO,GAAG3B,OAAO,CAAC6B,MAAR,CAAeF,OAAf,EAAwBC,cAAxB,CAAV;AACAD,IAAAA,OAAO,CAACG,IAAR,GAAe,UAAf;AAEA,SAAKC,SAAL,CAAe,YAAf,EAA6BJ,OAA7B;;AACA,SAAKK,gBAAL;;AAEA,SAAKN,MAAL,GAAcA,MAAd;AACA,SAAKC,OAAL,GAAeA,OAAf;AACD,GAjB8B;;AAkB/BM,EAAAA,qBAAqB,CAACC,SAAD,EAAY;AAC/B,QAAIC,eAAe,GAAG,YAAtB;AACA,UAAMC,UAAU,GAAG,KAAKC,kBAAL,CAAwBH,SAAxB,MAAuCpB,aAA1D;;AACA,QAAIsB,UAAJ,EAAgB;AACdD,MAAAA,eAAe,GAAG,UAAlB;AACD,KAFD,MAEO,IAAI,CAAC/B,MAAM,CAACkC,YAAR,EAAsBlC,MAAM,CAACmC,aAA7B,EAA4CtB,OAA5C,CAAoDiB,SAApD,IAAiE,CAArE,EAAwE;AAC7EC,MAAAA,eAAe,GAAG,MAAlB;AACD;;AAED,WAAOA,eAAP;AACD,GA5B8B;;AA6B/BK,EAAAA,mBAAmB,CAACN,SAAD,EAAYO,YAAZ,EAA0B;AAC3C,SAAKJ,kBAAL,CAAwBH,SAAxB,IAAqCO,YAArC;AACD,GA/B8B;;AAgC/BT,EAAAA,gBAAgB,GAAG;AACjB,SAAKK,kBAAL,GAA0B;AACxB,OAACjC,MAAM,CAACkC,YAAR,GAAuBxB,aADC;AAExB,OAACV,MAAM,CAACmC,aAAR,GAAwBzB;AAFA,KAA1B;AAIA,SAAK4B,EAAL,CAAQ;AACNC,MAAAA,MAAM,EAAE,KAAKC,SAAL,CAAeC,IAAf,CAAoB,IAApB,CADF;AAENC,MAAAA,OAAO,EAAE,KAAKC,UAAL,CAAgBF,IAAhB,CAAqB,IAArB;AAFH,KAAR;AAID,GAzC8B;;AA0C/BG,EAAAA,eAAe,CAACC,GAAD,EAAM;AACnB,UAAMC,qBAAqB,GAAG,CAA9B;AACA,UAAMC,sBAAsB,GAAG,CAA/B,CAFmB,CAInB;;AACA,UAAMC,aAAa,GAAG,KAAKC,KAAL,GAAa,CAAC,CAAd,GAAkB,CAAxC;AACA,UAAMC,aAAa,GAAG,KAAKC,KAAL,GAAa,CAAC,CAAd,GAAkB,CAAxC;AACA,UAAMC,cAAc,GAAGJ,aAAa,GAAG,KAAKK,MAA5C;AACA,UAAMC,cAAc,GAAGJ,aAAa,GAAG,KAAKK,MAA5C,CARmB,CAUnB;;AACAV,IAAAA,GAAG,CAACW,KAAJ,CAAUJ,cAAV,EAA0BE,cAA1B,EAXmB,CAanB;;AACA,SAAKG,cAAL,CAAoBZ,GAApB,EAAyB,oBAAzB;;AAEA,QAAI,KAAKtB,OAAL,CAAamC,SAAjB,EAA4B;AAC1B,WAAKC,cAAL,CAAoBd,GAApB;;AACA,WAAKe,aAAL,CAAmBf,GAAnB,EAAwB,oBAAxB,EAA8C;AAC5Ca,QAAAA,SAAS,EAAE,KAAKnC,OAAL,CAAamC;AADoB,OAA9C;AAGD,KALD,MAKO;AACL;AACA,WAAKE,aAAL,CAAmBf,GAAnB,EAAwB,cAAxB,EAAwC;AACtCgB,QAAAA,aAAa,EAAEf;AADuB,OAAxC,EAFK,CAML;;;AACA,WAAKc,aAAL,CAAmBf,GAAnB,EAAwB,oBAAxB,EAA8C;AAC5CgB,QAAAA,aAAa,EAAEf,qBAD6B;AAE5CgB,QAAAA,cAAc,EAAEf;AAF4B,OAA9C;AAID,KAhCkB,CAkCnB;;;AACAF,IAAAA,GAAG,CAACW,KAAJ,CAAU,IAAIJ,cAAd,EAA8B,IAAIE,cAAlC;AACD,GA9E8B;;AAgF/B;AACJ;AACA;AACA;AACA;AACIS,EAAAA,OAAO,CAAClB,GAAD,EAAM;AACX,SAAKlB,SAAL,CAAe,SAAf,EAA0BkB,GAA1B;;AAEA,SAAKD,eAAL,CAAqBC,GAArB;AACD,GAzF8B;;AA2F/B;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEI;AACJ;AACA;AACA;AACA;AACA;AACIY,EAAAA,cAAc,CAACZ,GAAD,EAAMmB,SAAN,EAAiB;AAC7B,UAAM;AAAEC,MAAAA,CAAF;AAAKC,MAAAA;AAAL,QAAW,KAAKC,eAAL,EAAjB;;AAEAtB,IAAAA,GAAG,CAACuB,IAAJ;AACAvB,IAAAA,GAAG,CAACmB,SAAJ,GAAgBA,SAAhB;AACAnB,IAAAA,GAAG,CAACwB,SAAJ,GAL6B,CAO7B;AACA;;AACAxB,IAAAA,GAAG,CAACyB,MAAJ,CAAWL,CAAC,CAAC,CAAD,CAAD,GAAO,CAAlB,EAAqBC,CAAC,CAAC,CAAD,CAAD,GAAO,CAA5B;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAD,GAAO,CAAlB,EAAqBC,CAAC,CAAC,CAAD,CAAD,GAAO,CAA5B;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAD,GAAO,CAAlB,EAAqBC,CAAC,CAAC,CAAD,CAAD,GAAO,CAA5B;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAD,GAAO,CAAlB,EAAqBC,CAAC,CAAC,CAAD,CAAD,GAAO,CAA5B;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAD,GAAO,CAAlB,EAAqBC,CAAC,CAAC,CAAD,CAAD,GAAO,CAA5B;AACArB,IAAAA,GAAG,CAAC2B,SAAJ,GAd6B,CAgB7B;;AACA3B,IAAAA,GAAG,CAACyB,MAAJ,CAAWL,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAAC2B,SAAJ;AAEA3B,IAAAA,GAAG,CAAC4B,IAAJ;AACA5B,IAAAA,GAAG,CAAC6B,OAAJ;AACD,GA9I8B;;AAgJ/B;AACJ;AACA;AACA;AACA;AACIf,EAAAA,cAAc,CAACd,GAAD,EAAM;AAClB,UAAM;AAAEoB,MAAAA,CAAC,EAAEU,MAAL;AAAaT,MAAAA,CAAC,EAAEU;AAAhB,QAA2B,KAAKT,eAAL,EAAjC;;AACA,UAAMF,CAAC,GAAG,KAAKY,sBAAL,CAA4BF,MAA5B,EAAoC,CAACA,MAAM,CAAC,CAAD,CAAN,GAAYA,MAAM,CAAC,CAAD,CAAnB,IAA0B,CAA9D,CAAV;;AACA,UAAMT,CAAC,GAAG,KAAKW,sBAAL,CAA4BD,MAA5B,EAAoC,CAACA,MAAM,CAAC,CAAD,CAAN,GAAYA,MAAM,CAAC,CAAD,CAAnB,IAA0B,CAA9D,CAAV;;AAEA/B,IAAAA,GAAG,CAACuB,IAAJ;AACAvB,IAAAA,GAAG,CAACiC,WAAJ,GAAkB,0BAAlB;AACAjC,IAAAA,GAAG,CAACa,SAAJ,GAAgB,KAAKnC,OAAL,CAAamC,SAA7B;AACAb,IAAAA,GAAG,CAACwB,SAAJ;AAEAxB,IAAAA,GAAG,CAACyB,MAAJ,CAAWL,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AAEArB,IAAAA,GAAG,CAACyB,MAAJ,CAAWL,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AAEArB,IAAAA,GAAG,CAACyB,MAAJ,CAAWL,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AAEArB,IAAAA,GAAG,CAACyB,MAAJ,CAAWL,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAAC0B,MAAJ,CAAWN,CAAC,CAAC,CAAD,CAAZ,EAAiBC,CAAC,CAAC,CAAD,CAAlB;AACArB,IAAAA,GAAG,CAACkC,MAAJ;AACAlC,IAAAA,GAAG,CAAC2B,SAAJ;AAEA3B,IAAAA,GAAG,CAAC6B,OAAJ;AACD,GA9K8B;;AAgL/B;AACJ;AACA;AACA;AACA;AACA;AACA;AACIG,EAAAA,sBAAsB,CAACG,KAAD,EAAQC,IAAR,EAAc;AAClC,UAAMC,QAAQ,GAAG,EAAjB;AACAA,IAAAA,QAAQ,CAAC,CAAD,CAAR,GAAcF,KAAK,CAAC,CAAD,CAAnB;AACAE,IAAAA,QAAQ,CAAC,CAAD,CAAR,GAAcF,KAAK,CAAC,CAAD,CAAL,GAAWC,IAAzB;AACAC,IAAAA,QAAQ,CAAC,CAAD,CAAR,GAAcF,KAAK,CAAC,CAAD,CAAL,GAAWC,IAAI,GAAG,CAAhC;AACAC,IAAAA,QAAQ,CAAC,CAAD,CAAR,GAAcF,KAAK,CAAC,CAAD,CAAnB;AAEA,WAAOE,QAAP;AACD,GA/L8B;;AAiM/B;AACJ;AACA;AACA;AACA;AACIf,EAAAA,eAAe,GAAG;AAChB,UAAM;AAAE7C,MAAAA,MAAF;AAAU6D,MAAAA,KAAV;AAAiBC,MAAAA,MAAjB;AAAyBC,MAAAA,IAAzB;AAA+BC,MAAAA;AAA/B,QAAuC,IAA7C;AACA,UAAMC,SAAS,GAAGJ,KAAK,GAAG,CAA1B;AACA,UAAMK,UAAU,GAAGJ,MAAM,GAAG,CAA5B;AACA,UAAMK,YAAY,GAAGnE,MAAM,CAACoE,SAAP,EAArB,CAJgB,CAIyB;;AACzC,UAAMC,WAAW,GAAGrE,MAAM,CAACsE,QAAP,EAApB,CALgB,CAKuB;;AAEvC,WAAO;AACL3B,MAAAA,CAAC,EAAErE,OAAO,CAACiG,GAAR,CACD,CACE,EAAEN,SAAS,GAAGF,IAAd,CADF,EACuB;AACrB,OAACE,SAFH,EAEc;AACZA,MAAAA,SAHF,EAGa;AACXA,MAAAA,SAAS,IAAII,WAAW,GAAGN,IAAd,GAAqBF,KAAzB,CAJX,CAI4C;AAJ5C,OADC,EAODW,IAAI,CAACC,IAPJ,CADE;AAUL7B,MAAAA,CAAC,EAAEtE,OAAO,CAACiG,GAAR,CACD,CACE,EAAEL,UAAU,GAAGF,GAAf,CADF,EACuB;AACrB,OAACE,UAFH,EAEe;AACbA,MAAAA,UAHF,EAGc;AACZA,MAAAA,UAAU,IAAIC,YAAY,GAAGH,GAAf,GAAqBF,MAAzB,CAJZ,CAI8C;AAJ9C,OADC,EAODU,IAAI,CAACC,IAPJ;AAVE,KAAP;AAoBD,GAjO8B;;AAmO/B;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACInC,EAAAA,aAAa,CAACf,GAAD,EAAMiC,WAAN,EAAmB;AAAEjB,IAAAA,aAAF;AAAiBC,IAAAA,cAAjB;AAAiCJ,IAAAA;AAAjC,GAAnB,EAAiE;AAC5E,UAAM6B,SAAS,GAAG,KAAKJ,KAAL,GAAa,CAA/B;AACA,UAAMK,UAAU,GAAG,KAAKJ,MAAL,GAAc,CAAjC;AAEAvC,IAAAA,GAAG,CAACuB,IAAJ;AACAvB,IAAAA,GAAG,CAACiC,WAAJ,GAAkBA,WAAlB;;AAEA,QAAIjC,GAAG,CAACmD,WAAR,EAAqB;AACnBnD,MAAAA,GAAG,CAACmD,WAAJ,CAAgB,CAACnC,aAAD,EAAgBA,aAAhB,CAAhB;AACD;;AACD,QAAIC,cAAJ,EAAoB;AAClBjB,MAAAA,GAAG,CAACiB,cAAJ,GAAqBA,cAArB;AACD;;AACD,QAAIJ,SAAJ,EAAe;AACbb,MAAAA,GAAG,CAACa,SAAJ,GAAgBA,SAAhB;AACD;;AAEDb,IAAAA,GAAG,CAACwB,SAAJ;AACAxB,IAAAA,GAAG,CAACyB,MAAJ,CAAW,CAACiB,SAAZ,EAAuB,CAACC,UAAxB;AACA3C,IAAAA,GAAG,CAAC0B,MAAJ,CAAWgB,SAAX,EAAsB,CAACC,UAAvB;AACA3C,IAAAA,GAAG,CAAC0B,MAAJ,CAAWgB,SAAX,EAAsBC,UAAtB;AACA3C,IAAAA,GAAG,CAAC0B,MAAJ,CAAW,CAACgB,SAAZ,EAAuBC,UAAvB;AACA3C,IAAAA,GAAG,CAAC0B,MAAJ,CAAW,CAACgB,SAAZ,EAAuB,CAACC,UAAxB;AACA3C,IAAAA,GAAG,CAACkC,MAAJ;AAEAlC,IAAAA,GAAG,CAAC6B,OAAJ;AACD,GAtQ8B;;AAwQ/B;AACJ;AACA;AACA;AACIlC,EAAAA,SAAS,GAAG;AACV,UAAM;AAAE4C,MAAAA,MAAF;AAAUD,MAAAA,KAAV;AAAiBE,MAAAA,IAAjB;AAAuBC,MAAAA;AAAvB,QAA+B,IAArC;AACA,UAAMW,OAAO,GAAG,KAAK3E,MAAL,CAAYsE,QAAZ,KAAyBT,KAAzC;AACA,UAAMe,MAAM,GAAG,KAAK5E,MAAL,CAAYoE,SAAZ,KAA0BN,MAAzC;AAEA,SAAKC,IAAL,GAAYvF,KAAK,CAACuF,IAAD,EAAO,CAAP,EAAUY,OAAV,CAAjB;AACA,SAAKX,GAAL,GAAWxF,KAAK,CAACwF,GAAD,EAAM,CAAN,EAASY,MAAT,CAAhB;AAEA,SAAKjE,kBAAL,CAAwBjC,MAAM,CAACkC,YAA/B,EAA6C,IAA7C;AACD,GArR8B;;AAuR/B;AACJ;AACA;AACA;AACA;AACIS,EAAAA,UAAU,CAACwD,MAAD,EAAS;AACjB,UAAMvF,cAAc,GAAGuF,MAAM,CAACC,SAAP,CAAiBC,MAAxC;AACA,UAAMC,OAAO,GAAG,KAAKhF,MAAL,CAAYiF,UAAZ,CAAuBJ,MAAM,CAACK,CAA9B,CAAhB;;AACA,UAAMC,QAAQ,GAAG,KAAKC,2BAAL,CAAiCJ,OAAjC,EAA0C1F,cAA1C,CAAjB,CAHiB,CAKjB;AACA;;;AACA,SAAK4C,KAAL,CAAW,CAAX,EAAcmD,GAAd,CAAkBF,QAAlB;AAEA,SAAKxE,kBAAL,CAAwBjC,MAAM,CAACmC,aAA/B,EAA8C,IAA9C;AACD,GAtS8B;;AAwS/B;AACJ;AACA;AACA;AACA;AACA;AACA;AACIuE,EAAAA,2BAA2B,CAACJ,OAAD,EAAU1F,cAAV,EAA0B;AACnD,UAAMgG,iBAAiB,GAAGjG,eAAe,CAACC,cAAD,CAAzC;AAEA,WAAOgG,iBAAiB,IAAI,KAAKC,eAAL,CAAqBP,OAArB,EAA8B1F,cAA9B,CAA5B;AACD,GAnT8B;;AAqT/B;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACIkG,EAAAA,uBAAuB,CAAC;AAAE3B,IAAAA,KAAF;AAASC,IAAAA,MAAT;AAAiB2B,IAAAA,SAAjB;AAA4BC,IAAAA,QAA5B;AAAsCC,IAAAA,QAAtC;AAAgDC,IAAAA,SAAhD;AAA2DC,IAAAA;AAA3D,GAAD,EAAuE;AAC5FhC,IAAAA,KAAK,GAAG8B,QAAQ,GAAGnH,KAAK,CAACqF,KAAD,EAAQ,CAAR,EAAW8B,QAAX,CAAR,GAA+B9B,KAA/C;AACAC,IAAAA,MAAM,GAAG8B,SAAS,GAAGpH,KAAK,CAACsF,MAAD,EAAS,CAAT,EAAY8B,SAAZ,CAAR,GAAiC9B,MAAnD;;AAEA,QAAI,CAAC,KAAKgC,WAAV,EAAuB;AACrB,aAAO;AACLjC,QAAAA,KADK;AAELC,QAAAA,MAFK;AAGLC,QAAAA,IAAI,EAAE0B,SAAS,CAAC5B,KAAD,CAHV;AAILG,QAAAA,GAAG,EAAE0B,QAAQ,CAAC5B,MAAD;AAJR,OAAP;AAMD;;AAED,QAAI+B,OAAO,KAAK,OAAhB,EAAyB;AACvB/B,MAAAA,MAAM,GAAGD,KAAK,GAAG,KAAKiC,WAAtB;AACD,KAFD,MAEO;AACLjC,MAAAA,KAAK,GAAGC,MAAM,GAAG,KAAKgC,WAAtB;AACD;;AAED,UAAMC,cAAc,GAAGvB,IAAI,CAACwB,GAAL,CAASL,QAAQ,GAAG9B,KAApB,EAA2B+B,SAAS,GAAG9B,MAAvC,CAAvB;;AACA,QAAIiC,cAAc,IAAI,CAAtB,EAAyB;AACvB,OAAClC,KAAD,EAAQC,MAAR,IAAkB,CAACD,KAAD,EAAQC,MAAR,EAAgBS,GAAhB,CAAqB0B,CAAD,IAAOA,CAAC,GAAGF,cAA/B,CAAlB;AACD;;AAED,WAAO;AACLlC,MAAAA,KADK;AAELC,MAAAA,MAFK;AAGLC,MAAAA,IAAI,EAAE0B,SAAS,CAAC5B,KAAD,CAHV;AAILG,MAAAA,GAAG,EAAE0B,QAAQ,CAAC5B,MAAD;AAJR,KAAP;AAMD,GA7V8B;;AA+V/B;AACJ;AACA;AACA;AACA;AACIoC,EAAAA,oBAAoB,GAAG;AACrB,UAAM;AAAErC,MAAAA,KAAK,EAAEQ,WAAT;AAAsBP,MAAAA,MAAM,EAAEK;AAA9B,QAA+C,KAAKnE,MAA1D;AACA,UAAM;AACJgE,MAAAA,GAAG,EAAEmC,OADD;AAEJpC,MAAAA,IAAI,EAAEqC,QAFF;AAGJvC,MAAAA,KAAK,EAAEwC,SAHH;AAIJvC,MAAAA,MAAM,EAAEwC;AAJJ,QAKF,KAAKC,eAAL,CAAqB,KAArB,EAA4B,IAA5B,CALJ;AAOA,WAAO;AACLJ,MAAAA,OADK;AAELC,MAAAA,QAFK;AAGLC,MAAAA,SAHK;AAILC,MAAAA,UAJK;AAKLE,MAAAA,SAAS,EAAEJ,QAAQ,GAAGC,SALjB;AAMLI,MAAAA,UAAU,EAAEN,OAAO,GAAGG,UANjB;AAOLjC,MAAAA,WAPK;AAQLF,MAAAA;AARK,KAAP;AAUD,GAvX8B;;AAyX/B;AACJ;AACA;AACA;AACA;AACA;AACA;AACIoB,EAAAA,eAAe,CAAC;AAAE5C,IAAAA,CAAF;AAAKC,IAAAA;AAAL,GAAD,EAAWmC,MAAX,EAAmB;AAChC,UAAM;AACJsB,MAAAA,SADI;AAEJC,MAAAA,UAFI;AAGJH,MAAAA,OAHI;AAIJC,MAAAA,QAJI;AAKJK,MAAAA,UALI;AAMJD,MAAAA,SANI;AAOJnC,MAAAA,WAPI;AAQJF,MAAAA;AARI,QASF,KAAK+B,oBAAL,EATJ;;AAWA,UAAMQ,aAAa,GAAG;AACpBC,MAAAA,EAAE,EAAE;AACF9C,QAAAA,KAAK,EAAE2C,SAAS,GAAG7D,CADjB;AAEFmB,QAAAA,MAAM,EAAE2C,UAAU,GAAG7D,CAFnB;AAGF6C,QAAAA,SAAS,EAAGmB,QAAD,IAAcJ,SAAS,GAAGI,QAHnC;AAIFlB,QAAAA,QAAQ,EAAGmB,SAAD,IAAeJ,UAAU,GAAGI,SAJpC;AAKFlB,QAAAA,QAAQ,EAAEa,SALR;AAMFZ,QAAAA,SAAS,EAAEa,UANT;AAOFZ,QAAAA,OAAO,EAAErG,aAAa,CAAC4G,QAAQ,GAAGzD,CAAZ,EAAewD,OAAO,GAAGvD,CAAzB;AAPpB,OADgB;AAUpBkE,MAAAA,EAAE,EAAE;AACFjD,QAAAA,KAAK,EAAElB,CAAC,GAAGyD,QADT;AAEFtC,QAAAA,MAAM,EAAE2C,UAAU,GAAG7D,CAFnB;AAGF6C,QAAAA,SAAS,EAAE,MAAMW,QAHf;AAIFV,QAAAA,QAAQ,EAAGmB,SAAD,IAAeJ,UAAU,GAAGI,SAJpC;AAKFlB,QAAAA,QAAQ,EAAEtB,WAAW,GAAG+B,QALtB;AAMFR,QAAAA,SAAS,EAAEa,UANT;AAOFZ,QAAAA,OAAO,EAAErG,aAAa,CAACmD,CAAC,GAAG6D,SAAL,EAAgBL,OAAO,GAAGvD,CAA1B;AAPpB,OAVgB;AAmBpBmE,MAAAA,EAAE,EAAE;AACFlD,QAAAA,KAAK,EAAEwC,SADL;AAEFvC,QAAAA,MAAM,EAAE2C,UAAU,GAAG7D,CAFnB;AAGF6C,QAAAA,SAAS,EAAE,MAAMW,QAHf;AAIFV,QAAAA,QAAQ,EAAGmB,SAAD,IAAeJ,UAAU,GAAGI,SAJpC;AAKFlB,QAAAA,QAAQ,EAAEtB,WAAW,GAAG+B,QALtB;AAMFR,QAAAA,SAAS,EAAEa,UANT;AAOFZ,QAAAA,OAAO,EAAE;AAPP,OAnBgB;AA4BpBmB,MAAAA,EAAE,EAAE;AACFnD,QAAAA,KAAK,EAAE2C,SAAS,GAAG7D,CADjB;AAEFmB,QAAAA,MAAM,EAAEwC,UAFN;AAGFb,QAAAA,SAAS,EAAGmB,QAAD,IAAcJ,SAAS,GAAGI,QAHnC;AAIFlB,QAAAA,QAAQ,EAAE,MAAMS,OAJd;AAKFR,QAAAA,QAAQ,EAAEa,SALR;AAMFZ,QAAAA,SAAS,EAAEzB,YAAY,GAAGgC,OANxB;AAOFN,QAAAA,OAAO,EAAE;AAPP,OA5BgB;AAqCpBoB,MAAAA,EAAE,EAAE;AACFpD,QAAAA,KAAK,EAAElB,CAAC,GAAGyD,QADT;AAEFtC,QAAAA,MAAM,EAAEwC,UAFN;AAGFb,QAAAA,SAAS,EAAE,MAAMW,QAHf;AAIFV,QAAAA,QAAQ,EAAE,MAAMS,OAJd;AAKFR,QAAAA,QAAQ,EAAEtB,WAAW,GAAG+B,QALtB;AAMFR,QAAAA,SAAS,EAAEzB,YAAY,GAAGgC,OANxB;AAOFN,QAAAA,OAAO,EAAE;AAPP,OArCgB;AA8CpBqB,MAAAA,EAAE,EAAE;AACFrD,QAAAA,KAAK,EAAEwC,SADL;AAEFvC,QAAAA,MAAM,EAAElB,CAAC,GAAGuD,OAFV;AAGFV,QAAAA,SAAS,EAAE,MAAMW,QAHf;AAIFV,QAAAA,QAAQ,EAAE,MAAMS,OAJd;AAKFR,QAAAA,QAAQ,EAAEtB,WAAW,GAAG+B,QALtB;AAMFR,QAAAA,SAAS,EAAEzB,YAAY,GAAGgC,OANxB;AAOFN,QAAAA,OAAO,EAAE;AAPP,OA9CgB;AAuDpBsB,MAAAA,EAAE,EAAE;AACFtD,QAAAA,KAAK,EAAE2C,SAAS,GAAG7D,CADjB;AAEFmB,QAAAA,MAAM,EAAElB,CAAC,GAAGuD,OAFV;AAGFV,QAAAA,SAAS,EAAGmB,QAAD,IAAcJ,SAAS,GAAGI,QAHnC;AAIFlB,QAAAA,QAAQ,EAAE,MAAMS,OAJd;AAKFR,QAAAA,QAAQ,EAAEa,SALR;AAMFZ,QAAAA,SAAS,EAAEzB,YAAY,GAAGgC,OANxB;AAOFN,QAAAA,OAAO,EAAErG,aAAa,CAAC4G,QAAQ,GAAGzD,CAAZ,EAAeC,CAAC,GAAG6D,UAAnB;AAPpB,OAvDgB;AAgEpBW,MAAAA,EAAE,EAAE;AACFvD,QAAAA,KAAK,EAAElB,CAAC,GAAGyD,QADT;AAEFtC,QAAAA,MAAM,EAAElB,CAAC,GAAGuD,OAFV;AAGFV,QAAAA,SAAS,EAAE,MAAMW,QAHf;AAIFV,QAAAA,QAAQ,EAAE,MAAMS,OAJd;AAKFR,QAAAA,QAAQ,EAAEtB,WAAW,GAAG+B,QALtB;AAMFR,QAAAA,SAAS,EAAEzB,YAAY,GAAGgC,OANxB;AAOFN,QAAAA,OAAO,EAAErG,aAAa,CAACmD,CAAC,GAAG6D,SAAL,EAAgB5D,CAAC,GAAG6D,UAApB;AAPpB;AAhEgB,KAAtB;AA2EA,WAAO,KAAKjB,uBAAL,CAA6BkB,aAAa,CAAC3B,MAAD,CAA1C,CAAP;AACD,GAxd8B;;AA0d/B;AACJ;AACA;AACA;AACIsC,EAAAA,OAAO,GAAG;AACR,WAAO,KAAKtD,IAAL,IAAa,CAAb,IAAkB,KAAKC,GAAL,IAAY,CAA9B,IAAmC,KAAKH,KAAL,GAAa,CAAhD,IAAqD,KAAKC,MAAL,GAAc,CAA1E;AACD;;AAhe8B,CAFlB,CAAjB;AAseA,eAAenE,QAAf","sourcesContent":["/**\r\n * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>\r\n * @fileoverview Cropzone extending fabric.Rect\r\n */\r\nimport snippet from 'tui-code-snippet';\r\nimport fabric from 'fabric';\r\nimport { clamp } from '../util';\r\nimport { eventNames as events } from '../consts';\r\n\r\nconst CORNER_TYPE_TOP_LEFT = 'tl';\r\nconst CORNER_TYPE_TOP_RIGHT = 'tr';\r\nconst CORNER_TYPE_MIDDLE_TOP = 'mt';\r\nconst CORNER_TYPE_MIDDLE_LEFT = 'ml';\r\nconst CORNER_TYPE_MIDDLE_RIGHT = 'mr';\r\nconst CORNER_TYPE_MIDDLE_BOTTOM = 'mb';\r\nconst CORNER_TYPE_BOTTOM_LEFT = 'bl';\r\nconst CORNER_TYPE_BOTTOM_RIGHT = 'br';\r\nconst CORNER_TYPE_LIST = [\r\n CORNER_TYPE_TOP_LEFT,\r\n CORNER_TYPE_TOP_RIGHT,\r\n CORNER_TYPE_MIDDLE_TOP,\r\n CORNER_TYPE_MIDDLE_LEFT,\r\n CORNER_TYPE_MIDDLE_RIGHT,\r\n CORNER_TYPE_MIDDLE_BOTTOM,\r\n CORNER_TYPE_BOTTOM_LEFT,\r\n CORNER_TYPE_BOTTOM_RIGHT,\r\n];\r\nconst NOOP_FUNCTION = () => {};\r\n\r\n/**\r\n * Align with cropzone ratio\r\n * @param {string} selectedCorner - selected corner type\r\n * @returns {{width: number, height: number}}\r\n * @private\r\n */\r\nfunction cornerTypeValid(selectedCorner) {\r\n return CORNER_TYPE_LIST.indexOf(selectedCorner) >= 0;\r\n}\r\n\r\n/**\r\n * return scale basis type\r\n * @param {number} diffX - X distance of the cursor and corner.\r\n * @param {number} diffY - Y distance of the cursor and corner.\r\n * @returns {string}\r\n * @private\r\n */\r\nfunction getScaleBasis(diffX, diffY) {\r\n return diffX > diffY ? 'width' : 'height';\r\n}\r\n\r\n/**\r\n * Cropzone object\r\n * Issue: IE7, 8(with excanvas)\r\n * - Cropzone is a black zone without transparency.\r\n * @class Cropzone\r\n * @extends {fabric.Rect}\r\n * @ignore\r\n */\r\nconst Cropzone = fabric.util.createClass(\r\n fabric.Rect,\r\n /** @lends Cropzone.prototype */ {\r\n /**\r\n * Constructor\r\n * @param {Object} canvas canvas\r\n * @param {Object} options Options object\r\n * @param {Object} extendsOptions object for extends \"options\"\r\n * @override\r\n */\r\n initialize(canvas, options, extendsOptions) {\r\n options = snippet.extend(options, extendsOptions);\r\n options.type = 'cropzone';\r\n\r\n this.callSuper('initialize', options);\r\n this._addEventHandler();\r\n\r\n this.canvas = canvas;\r\n this.options = options;\r\n },\r\n canvasEventDelegation(eventName) {\r\n let delegationState = 'unregisted';\r\n const isRegisted = this.canvasEventTrigger[eventName] !== NOOP_FUNCTION;\r\n if (isRegisted) {\r\n delegationState = 'registed';\r\n } else if ([events.OBJECT_MOVED, events.OBJECT_SCALED].indexOf(eventName) < 0) {\r\n delegationState = 'none';\r\n }\r\n\r\n return delegationState;\r\n },\r\n canvasEventRegister(eventName, eventTrigger) {\r\n this.canvasEventTrigger[eventName] = eventTrigger;\r\n },\r\n _addEventHandler() {\r\n this.canvasEventTrigger = {\r\n [events.OBJECT_MOVED]: NOOP_FUNCTION,\r\n [events.OBJECT_SCALED]: NOOP_FUNCTION,\r\n };\r\n this.on({\r\n moving: this._onMoving.bind(this),\r\n scaling: this._onScaling.bind(this),\r\n });\r\n },\r\n _renderCropzone(ctx) {\r\n const cropzoneDashLineWidth = 7;\r\n const cropzoneDashLineOffset = 7;\r\n\r\n // Calc original scale\r\n const originalFlipX = this.flipX ? -1 : 1;\r\n const originalFlipY = this.flipY ? -1 : 1;\r\n const originalScaleX = originalFlipX / this.scaleX;\r\n const originalScaleY = originalFlipY / this.scaleY;\r\n\r\n // Set original scale\r\n ctx.scale(originalScaleX, originalScaleY);\r\n\r\n // Render outer rect\r\n this._fillOuterRect(ctx, 'rgba(0, 0, 0, 0.5)');\r\n\r\n if (this.options.lineWidth) {\r\n this._fillInnerRect(ctx);\r\n this._strokeBorder(ctx, 'rgb(255, 255, 255)', {\r\n lineWidth: this.options.lineWidth,\r\n });\r\n } else {\r\n // Black dash line\r\n this._strokeBorder(ctx, 'rgb(0, 0, 0)', {\r\n lineDashWidth: cropzoneDashLineWidth,\r\n });\r\n\r\n // White dash line\r\n this._strokeBorder(ctx, 'rgb(255, 255, 255)', {\r\n lineDashWidth: cropzoneDashLineWidth,\r\n lineDashOffset: cropzoneDashLineOffset,\r\n });\r\n }\r\n\r\n // Reset scale\r\n ctx.scale(1 / originalScaleX, 1 / originalScaleY);\r\n },\r\n\r\n /**\r\n * Render Crop-zone\r\n * @private\r\n * @override\r\n */\r\n _render(ctx) {\r\n this.callSuper('_render', ctx);\r\n\r\n this._renderCropzone(ctx);\r\n },\r\n\r\n /**\r\n * Cropzone-coordinates with outer rectangle\r\n *\r\n * x0 x1 x2 x3\r\n * y0 +--------------------------+\r\n * |///////|//////////|///////| // <--- \"Outer-rectangle\"\r\n * |///////|//////////|///////|\r\n * y1 +-------+----------+-------+\r\n * |///////| Cropzone |///////| Cropzone is the \"Inner-rectangle\"\r\n * |///////| (0, 0) |///////| Center point (0, 0)\r\n * y2 +-------+----------+-------+\r\n * |///////|//////////|///////|\r\n * |///////|//////////|///////|\r\n * y3 +--------------------------+\r\n *\r\n * @typedef {{x: Array<number>, y: Array<number>}} cropzoneCoordinates\r\n * @ignore\r\n */\r\n\r\n /**\r\n * Fill outer rectangle\r\n * @param {CanvasRenderingContext2D} ctx - Context\r\n * @param {string|CanvasGradient|CanvasPattern} fillStyle - Fill-style\r\n * @private\r\n */\r\n _fillOuterRect(ctx, fillStyle) {\r\n const { x, y } = this._getCoordinates();\r\n\r\n ctx.save();\r\n ctx.fillStyle = fillStyle;\r\n ctx.beginPath();\r\n\r\n // Outer rectangle\r\n // Numbers are +/-1 so that overlay edges don't get blurry.\r\n ctx.moveTo(x[0] - 1, y[0] - 1);\r\n ctx.lineTo(x[3] + 1, y[0] - 1);\r\n ctx.lineTo(x[3] + 1, y[3] + 1);\r\n ctx.lineTo(x[0] - 1, y[3] + 1);\r\n ctx.lineTo(x[0] - 1, y[0] - 1);\r\n ctx.closePath();\r\n\r\n // Inner rectangle\r\n ctx.moveTo(x[1], y[1]);\r\n ctx.lineTo(x[1], y[2]);\r\n ctx.lineTo(x[2], y[2]);\r\n ctx.lineTo(x[2], y[1]);\r\n ctx.lineTo(x[1], y[1]);\r\n ctx.closePath();\r\n\r\n ctx.fill();\r\n ctx.restore();\r\n },\r\n\r\n /**\r\n * Draw Inner grid line\r\n * @param {CanvasRenderingContext2D} ctx - Context\r\n * @private\r\n */\r\n _fillInnerRect(ctx) {\r\n const { x: outerX, y: outerY } = this._getCoordinates();\r\n const x = this._caculateInnerPosition(outerX, (outerX[2] - outerX[1]) / 3);\r\n const y = this._caculateInnerPosition(outerY, (outerY[2] - outerY[1]) / 3);\r\n\r\n ctx.save();\r\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';\r\n ctx.lineWidth = this.options.lineWidth;\r\n ctx.beginPath();\r\n\r\n ctx.moveTo(x[0], y[1]);\r\n ctx.lineTo(x[3], y[1]);\r\n\r\n ctx.moveTo(x[0], y[2]);\r\n ctx.lineTo(x[3], y[2]);\r\n\r\n ctx.moveTo(x[1], y[0]);\r\n ctx.lineTo(x[1], y[3]);\r\n\r\n ctx.moveTo(x[2], y[0]);\r\n ctx.lineTo(x[2], y[3]);\r\n ctx.stroke();\r\n ctx.closePath();\r\n\r\n ctx.restore();\r\n },\r\n\r\n /**\r\n * Calculate Inner Position\r\n * @param {Array} outer - outer position\r\n * @param {number} size - interval for calculate\r\n * @returns {Array} - inner position\r\n * @private\r\n */\r\n _caculateInnerPosition(outer, size) {\r\n const position = [];\r\n position[0] = outer[1];\r\n position[1] = outer[1] + size;\r\n position[2] = outer[1] + size * 2;\r\n position[3] = outer[2];\r\n\r\n return position;\r\n },\r\n\r\n /**\r\n * Get coordinates\r\n * @returns {cropzoneCoordinates} - {@link cropzoneCoordinates}\r\n * @private\r\n */\r\n _getCoordinates() {\r\n const { canvas, width, height, left, top } = this;\r\n const halfWidth = width / 2;\r\n const halfHeight = height / 2;\r\n const canvasHeight = canvas.getHeight(); // fabric object\r\n const canvasWidth = canvas.getWidth(); // fabric object\r\n\r\n return {\r\n x: snippet.map(\r\n [\r\n -(halfWidth + left), // x0\r\n -halfWidth, // x1\r\n halfWidth, // x2\r\n halfWidth + (canvasWidth - left - width), // x3\r\n ],\r\n Math.ceil\r\n ),\r\n y: snippet.map(\r\n [\r\n -(halfHeight + top), // y0\r\n -halfHeight, // y1\r\n halfHeight, // y2\r\n halfHeight + (canvasHeight - top - height), // y3\r\n ],\r\n Math.ceil\r\n ),\r\n };\r\n },\r\n\r\n /**\r\n * Stroke border\r\n * @param {CanvasRenderingContext2D} ctx - Context\r\n * @param {string|CanvasGradient|CanvasPattern} strokeStyle - Stroke-style\r\n * @param {number} lineDashWidth - Dash width\r\n * @param {number} [lineDashOffset] - Dash offset\r\n * @param {number} [lineWidth] - line width\r\n * @private\r\n */\r\n _strokeBorder(ctx, strokeStyle, { lineDashWidth, lineDashOffset, lineWidth }) {\r\n const halfWidth = this.width / 2;\r\n const halfHeight = this.height / 2;\r\n\r\n ctx.save();\r\n ctx.strokeStyle = strokeStyle;\r\n\r\n if (ctx.setLineDash) {\r\n ctx.setLineDash([lineDashWidth, lineDashWidth]);\r\n }\r\n if (lineDashOffset) {\r\n ctx.lineDashOffset = lineDashOffset;\r\n }\r\n if (lineWidth) {\r\n ctx.lineWidth = lineWidth;\r\n }\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(-halfWidth, -halfHeight);\r\n ctx.lineTo(halfWidth, -halfHeight);\r\n ctx.lineTo(halfWidth, halfHeight);\r\n ctx.lineTo(-halfWidth, halfHeight);\r\n ctx.lineTo(-halfWidth, -halfHeight);\r\n ctx.stroke();\r\n\r\n ctx.restore();\r\n },\r\n\r\n /**\r\n * onMoving event listener\r\n * @private\r\n */\r\n _onMoving() {\r\n const { height, width, left, top } = this;\r\n const maxLeft = this.canvas.getWidth() - width;\r\n const maxTop = this.canvas.getHeight() - height;\r\n\r\n this.left = clamp(left, 0, maxLeft);\r\n this.top = clamp(top, 0, maxTop);\r\n\r\n this.canvasEventTrigger[events.OBJECT_MOVED](this);\r\n },\r\n\r\n /**\r\n * onScaling event listener\r\n * @param {{e: MouseEvent}} fEvent - Fabric event\r\n * @private\r\n */\r\n _onScaling(fEvent) {\r\n const selectedCorner = fEvent.transform.corner;\r\n const pointer = this.canvas.getPointer(fEvent.e);\r\n const settings = this._calcScalingSizeFromPointer(pointer, selectedCorner);\r\n\r\n // On scaling cropzone,\r\n // change real width and height and fix scaleFactor to 1\r\n this.scale(1).set(settings);\r\n\r\n this.canvasEventTrigger[events.OBJECT_SCALED](this);\r\n },\r\n\r\n /**\r\n * Calc scaled size from mouse pointer with selected corner\r\n * @param {{x: number, y: number}} pointer - Mouse position\r\n * @param {string} selectedCorner - selected corner type\r\n * @returns {Object} Having left or(and) top or(and) width or(and) height.\r\n * @private\r\n */\r\n _calcScalingSizeFromPointer(pointer, selectedCorner) {\r\n const isCornerTypeValid = cornerTypeValid(selectedCorner);\r\n\r\n return isCornerTypeValid && this._resizeCropZone(pointer, selectedCorner);\r\n },\r\n\r\n /**\r\n * Align with cropzone ratio\r\n * @param {number} width - cropzone width\r\n * @param {number} height - cropzone height\r\n * @param {number} maxWidth - limit max width\r\n * @param {number} maxHeight - limit max height\r\n * @param {number} scaleTo - cropzone ratio\r\n * @returns {{width: number, height: number}}\r\n * @private\r\n */\r\n adjustRatioCropzoneSize({ width, height, leftMaker, topMaker, maxWidth, maxHeight, scaleTo }) {\r\n width = maxWidth ? clamp(width, 1, maxWidth) : width;\r\n height = maxHeight ? clamp(height, 1, maxHeight) : height;\r\n\r\n if (!this.presetRatio) {\r\n return {\r\n width,\r\n height,\r\n left: leftMaker(width),\r\n top: topMaker(height),\r\n };\r\n }\r\n\r\n if (scaleTo === 'width') {\r\n height = width / this.presetRatio;\r\n } else {\r\n width = height * this.presetRatio;\r\n }\r\n\r\n const maxScaleFactor = Math.min(maxWidth / width, maxHeight / height);\r\n if (maxScaleFactor <= 1) {\r\n [width, height] = [width, height].map((v) => v * maxScaleFactor);\r\n }\r\n\r\n return {\r\n width,\r\n height,\r\n left: leftMaker(width),\r\n top: topMaker(height),\r\n };\r\n },\r\n\r\n /**\r\n * Get dimension last state cropzone\r\n * @returns {{rectTop: number, rectLeft: number, rectWidth: number, rectHeight: number}}\r\n * @private\r\n */\r\n _getCropzoneRectInfo() {\r\n const { width: canvasWidth, height: canvasHeight } = this.canvas;\r\n const {\r\n top: rectTop,\r\n left: rectLeft,\r\n width: rectWidth,\r\n height: rectHeight,\r\n } = this.getBoundingRect(false, true);\r\n\r\n return {\r\n rectTop,\r\n rectLeft,\r\n rectWidth,\r\n rectHeight,\r\n rectRight: rectLeft + rectWidth,\r\n rectBottom: rectTop + rectHeight,\r\n canvasWidth,\r\n canvasHeight,\r\n };\r\n },\r\n\r\n /**\r\n * Calc scaling dimension\r\n * @param {Object} position - Mouse position\r\n * @param {string} corner - corner type\r\n * @returns {{left: number, top: number, width: number, height: number}}\r\n * @private\r\n */\r\n _resizeCropZone({ x, y }, corner) {\r\n const {\r\n rectWidth,\r\n rectHeight,\r\n rectTop,\r\n rectLeft,\r\n rectBottom,\r\n rectRight,\r\n canvasWidth,\r\n canvasHeight,\r\n } = this._getCropzoneRectInfo();\r\n\r\n const resizeInfoMap = {\r\n tl: {\r\n width: rectRight - x,\r\n height: rectBottom - y,\r\n leftMaker: (newWidth) => rectRight - newWidth,\r\n topMaker: (newHeight) => rectBottom - newHeight,\r\n maxWidth: rectRight,\r\n maxHeight: rectBottom,\r\n scaleTo: getScaleBasis(rectLeft - x, rectTop - y),\r\n },\r\n tr: {\r\n width: x - rectLeft,\r\n height: rectBottom - y,\r\n leftMaker: () => rectLeft,\r\n topMaker: (newHeight) => rectBottom - newHeight,\r\n maxWidth: canvasWidth - rectLeft,\r\n maxHeight: rectBottom,\r\n scaleTo: getScaleBasis(x - rectRight, rectTop - y),\r\n },\r\n mt: {\r\n width: rectWidth,\r\n height: rectBottom - y,\r\n leftMaker: () => rectLeft,\r\n topMaker: (newHeight) => rectBottom - newHeight,\r\n maxWidth: canvasWidth - rectLeft,\r\n maxHeight: rectBottom,\r\n scaleTo: 'height',\r\n },\r\n ml: {\r\n width: rectRight - x,\r\n height: rectHeight,\r\n leftMaker: (newWidth) => rectRight - newWidth,\r\n topMaker: () => rectTop,\r\n maxWidth: rectRight,\r\n maxHeight: canvasHeight - rectTop,\r\n scaleTo: 'width',\r\n },\r\n mr: {\r\n width: x - rectLeft,\r\n height: rectHeight,\r\n leftMaker: () => rectLeft,\r\n topMaker: () => rectTop,\r\n maxWidth: canvasWidth - rectLeft,\r\n maxHeight: canvasHeight - rectTop,\r\n scaleTo: 'width',\r\n },\r\n mb: {\r\n width: rectWidth,\r\n height: y - rectTop,\r\n leftMaker: () => rectLeft,\r\n topMaker: () => rectTop,\r\n maxWidth: canvasWidth - rectLeft,\r\n maxHeight: canvasHeight - rectTop,\r\n scaleTo: 'height',\r\n },\r\n bl: {\r\n width: rectRight - x,\r\n height: y - rectTop,\r\n leftMaker: (newWidth) => rectRight - newWidth,\r\n topMaker: () => rectTop,\r\n maxWidth: rectRight,\r\n maxHeight: canvasHeight - rectTop,\r\n scaleTo: getScaleBasis(rectLeft - x, y - rectBottom),\r\n },\r\n br: {\r\n width: x - rectLeft,\r\n height: y - rectTop,\r\n leftMaker: () => rectLeft,\r\n topMaker: () => rectTop,\r\n maxWidth: canvasWidth - rectLeft,\r\n maxHeight: canvasHeight - rectTop,\r\n scaleTo: getScaleBasis(x - rectRight, y - rectBottom),\r\n },\r\n };\r\n\r\n return this.adjustRatioCropzoneSize(resizeInfoMap[corner]);\r\n },\r\n\r\n /**\r\n * Return the whether this cropzone is valid\r\n * @returns {boolean}\r\n */\r\n isValid() {\r\n return this.left >= 0 && this.top >= 0 && this.width > 0 && this.height > 0;\r\n },\r\n }\r\n);\r\n\r\nexport default Cropzone;\r\n"]},"metadata":{},"sourceType":"module"}