{"version":3,"sources":["webpack:///webpack/universalModuleDefinition?5ca6*****","webpack:///tools.js","webpack:///./src/web/tools.js","webpack:///./src/ui/tool/index.js","webpack:///./src/ui/tool/select.js","webpack:///./src/ui/tool/select-transform.js","webpack:///./src/ui/tool/select-handles.js","webpack:///./src/ui/tool/drag-selector.js","webpack:///./src/ui/tool/clip.js","webpack:///./src/ui/tool/power-clip.js","webpack:///./src/ui/tool/add-figure.js","webpack:///./src/ui/tool/draw.js","webpack:///./src/ui/tool/free-draw.js","webpack:///./src/ui/tool/edit-text.js","webpack:///./src/ui/tool/chars-transform.js","webpack:///./src/ui/tool/node-edit.js","webpack:///./src/ui/tool/render-info.js","webpack:///./src/ui/tool/select-brush.js"],"names":["root","factory","exports","module","define","amd","this","webpackJsonpGrafika","0","__webpack_require__","151","_interopRequireWildcard","obj","__esModule","newObj","key","Object","prototype","hasOwnProperty","call","default","_lodash","_tool","Tool","_window","window","Cx","assign","152","defineProperty","value","_select","keys","forEach","enumerable","get","_zoom","_pan","_clip","_powerClip","_addFigure","_draw","_freeDraw","_editText","_charsTransform","_nodeEdit","_renderInfo","_selectBrush","153","SelectTool","SelectBaseTool","undefined","_config","_gear","_cdl","_view","_selectTransform","_dragSelector","extend","type","toolbarName","allowKeyShortcuts","isCommitable","Properties","selectAndDragEnabled","def","resume","callParent","handles","update","setIddleToolhelp","initTool","view","config","_this","OptimizedFiguresHandles","tool","editingItems","selectedFigures","onItemsDrag","event","figures","fireEvent","onItemsDrop","_ref","onDrop","cancelMove","absoluteTranslate","Point","notRemovedFigures","doc","figure","document","push","length","_transparentMode","th","toolhelp","link","on","rendercomplete","on_rendercomplete","create","unlink","un","dispose","on_dblclick","_ref2","docPoint","canEditContent","editContent","editingContent","commitContent$","onSelectionChanged","redraw","draw","context","transformModel","docIslands","filter","metadata","is3D","model","docIsland","modelIsland","modelIslandFor","strokeStyle","lineWidth","customDraw","c","stroke","setLineDash","useAggregateMode","_ref3","shiftKey","cmdKey","Config","ctrlAggregation","useContentEditMode","_ref4","try_pointerdown","_ref5","isHandle","isHandleEnabledAt","down","stopPropagation","_possibleClicking","time","now","on_pointerdown","_ref6","_this2","which","pointers","_editionMode","_possibleDrag","helper","_endMode","leftClick","clearSelection","render$","figureHit","possibleDrag","tight","_figureClicked","movable","is","on_mousemove","mousemove","on_pointermove","_ref7","DragSelectorHelper","_dragEnd","bind","move","on_pointerup","_ref8","viewPoint","up","pc","t","pc_event","pcViewPoint","Math","abs","x","y","_ref9","bounds","width","height","activeSelectableFigures","updateArray$","then","selection","fb","bounds_","lx","ly","hx","hy","reverse","add","activeDocument","includes","remove","set","somethingToDraw","visible","needsToDrawFor","frame","Frame","areOverlapping","frame_","typeName","canUndo","undo","canRedo","redo","supportsClipboard","Select","154","computeScale","pin","dir","mousePos","initialMousePos","zoomScale","initialDiff","substract","currentDiff","dpi","dotProduct","dpc","_abs","clone","sx","deg","angle","computeShear","dpcPa","perpendicular","r","sy","computeRotation","minus","computeFiguresFrame_","fromBounds","Figures","figuresSnapToPoints","editingFigures","snapTo","viewBounds","horizontalUserLines","userLine","_snap","snapPoint","_position","lx_ly","center","hx_hy","verticalUserLines","difference","activePageFigures","_figure$frame_$bounds","FiguresHandles","SelectAndTransformHandles","_selectHandles","FrameInteractionMixin","initFrameInteraction","_data","_editingItems","_originalTransforms","_downFrame","snapToPoints","transformWithFixedCenter","scaleOriginalXY","setEditionToolhelp","transformType","shiftToolhelp","shiftOnlyForSingleSelection","dragText","altText","startEditionMode","getOriginalTransforms","_frame","endEditionMode","translateItems","items","offset","transformItems","Matrix","translate","setOriginalPositions","originalTransforms","setOriginalTransforms","updateHandlesFrame","transform","transformed","batchRedraw","absoluteTransform","preview$","commit$","onTranslateStart","started","getOnTranslateValue","docPointRaw","mouseDownPos","isZero","alignmentLines","_alignmentLines","_visible","forceSnap","al_visible","al_snap","al_enabled","snapSize","viewDeltaToDoc","_downFrame$translated","translated","al_x","al_y","diff_x","Number","MAX_VALUE","diff_y","snap","s","name","diff","ax","ay","guideline_x","guideline_y","asFastOffset","onTranslateMove","onTranslateEnd","needsRedraw","onScaleStart","current","pos","scale","fixedCenter","scalePin","scaleDir","scaleDirFromHandle","os","getOnScaleValue","scaleY","scaleX","onScaleMove","doScaleMove","_data$scale","scaleFrom","onScaleEnd","onRotateStart","initialDeg","initialSnapDeg","getOnRotateValue","sm","round","onRotateMove","rotateAround","onRotateEnd","onShearStart","shear","shearPin","shearDir","shearDirFromHandle","shearHandlePos","shearOppPin","oppPin","getOnShearValue","ctrlKey","downPos","currentOppPin","plus","kp","dp","onShearMove","_data$shear","shearAround","onShearEnd","_data$shear2","Base","init","isPadHandle","SelectHandles","rotatestart","rotatemove","rotateend","scalestart","scalemove","scaleend","shearstart","shearmove","shearend","translatestart","translatemove","translateend","edit","onContentEdit","invalidatedItems","itemsEnabledTransforms","anisometricTransformsEnabled","anisometricTransforms","translateEnabled","scaleEnabled","rotateEnabled","rotate","shearEnabled","editEnabled","contentEdit","resize","computeItemsFrame_","map","matrix22","n","original","are","itemsEnabledContentEdit","invalidated","matrix","_matrix22","urm","m","s00","s11","fastTranslate_","fastTranslate","lastScale","_data$scale2","155","maxSideLength2","p0","p1","p2","p3","max","distance2","minSideLength2","min","canvasRotationPath","moveToXY","bezierCurveTo","closePath","canvasEditContentPath","lineToXY","owned","_handles","mode","nw","ne","se","sw","aniso","e","w","shearX","shearY","none","size","hs","h","hn","cursor","disabled","size2","_circlePadHandles","pick","_fillColor","_fillOverColor","_fillActiveColor","_strokeColor","_guidelineColor","addEvents","_currentActive","_currentOver","_setFrame","_inited","enable","_rotateHandlePosition","distance","de","normalized","scaled","_editHandlePosition","interpolate","p","forOwn","frameMinSideLength2","frameMaxSideLength2","vtds","vtds2","smallFrame","ex","extended","_anisometricTransformsEnabled","ps","padScaling","shearCut1","shearCut2","scaleCut1","scaleCut2","isEnabled","enabled","handleEnabled","_handleFromEvent","newOver","fastThrottle","arguments","apply","strokeFrame","strokeSegment","save","textureScale","viewDeltaToTexture","v","_drawScaleHandle","fillStyle","fill","rotateHandle","beginPath","rotationPos","rotationAngle","rotationPathTransform","concat","editHandle","editAngle","tp","arc","PI","restore","point","ps2","padHandles","k","kEnd","hk","norm2","contains","visible_","dirp","t1","tb","t2","t3","moveTo","lineTo","apply_","p0_x","p0_y","p1_x","p1_y","p2_x","p2_y","156","stableLine","onEnd","strokeColor","_pd","_fd","_sc","end","Bounds","ofPoints","157","ClipTool","_slicedToArray","sliceIterator","arr","i","_arr","_n","_d","_e","_s","_i","Symbol","iterator","next","done","err","Array","isArray","TypeError","_selectedFigure","lParent","clipTool","_selectedParent","lParentFrame","globalFrame_","lFigureFrame","lTransform","rwPowerClipTransform","lInvTransform","invert","lDeltaP0","lP","lDeltaP2","lRetry","lFailedToScale","lOldScaleFrom","lOldFigureFrame","lFigureDeltaP0","lFigureDeltaP2","preview","on_preview","parent","endEditClip$","on_keydown","altKey","_keyShortcuts","preventDefault","canRemove","clippedBy","isPrimary","_parent$getClippedBy","getClippedBy","_parent$getClippedBy2","lClipContent","lClipParent","beginEditClip$","isRaster","lId","_computeUniqueId","addClippingRect$","_parent$getClippedBy3","_parent$getClippedBy4","lDoc","lUniqueIdFound","lUniqueId","lUniqueIdx","id","Clip","158","PowerClipTool","usingPowerClipLink","invalidate","parentMatrix","inverted","invalidateView","pcContent","powerClipContents","parentMatrixInv","pcPoint","findLast","f","containsPoint","_outputFigure","PowerClip","159","DrawEllipseTool","DrawRectangleTool","DrawCurveTool","AddFigureTool","useCursor","_figure","update$","brush","brush_","isShape","polyregions","pen","pen_","cleanUpFigure","_commitFigure$","addedFigure","_addedFigure","resolve","_commit$","_cancel$","_minSize","_posDoc","_downPosDoc","bounds$","_initialWidth","_initialHeight","initialBounds","plus_","fit$","_originalMatrix22","_originalPin","_ctrlKey","computeTransform","cp","minSize","initialWidth","initialHeight","nextWidth","nextHeight","AddFigure","curve","defaultPen","defaultBrush","Shape","createFromCurve","_computeMatrix","polyregion","renderFrame","renderMatrix","anchor","AbsoluteAnchor","Boundary","createRectangle","DrawRectangle","createEllipse","DrawEllipse","160","DrawShapeTool","DrawTool","onChange","target","_closedConfig","closed","_flushShape","_flushPath","closeDistance","editingDistance","_paths","_closed","_nextPiece","_pieces","_redoPieces","_editingPiece","_initialPoint","on_nextpiece","pieces","slice","_pen","_brush","lastWasClosed","drawPath","setupContext","_type","_color","rgba","paths","paths_k","dotSize","_drawing","_pathIsClosed","ep","usingTouch","Curve","c1","P2","c2","P3","dot","_lastPieceWasModified","piece","last","l","P0","_downPos","_redoNextPiece","np","_currentPoint","nextPiece","_pushPathIfClosed","Segment","isEqual","_pushPath","rightClick","Cubic","editingPiece","isNear","fromSegment","P1","_editingPieceModified","lastPiece","PC","pop","_redoPaths","rp","_redotNextPiece","ip","fromNonTiedPieces","commitChanges$","pushPolyregion","regions","Polyregion","fillMode","region","Region","ofThings","keepSelection","Draw","DrawShape","161","FreeDrawTool","detectCorners","Modes","1","2","_bind","flushShape","_mode","flushCurrentPath","switchCorners","_detectCorners","solidBrush","inMode","currentPoints","_points","_nextPoint","stampPath","lastIsClosed","isCurve","scaleFactor","path","unshift","p4","areEqual","switchMode","stampBounds","_pointDown","_pointTo","_lastTime","_pointsR","_lastTimeR","ctrl","_ctrl","points","pointsR","lp","deltaVL","lp3TimeR","_lastTimeRPrevPrev","_lastTimeRPrev","delta","delta2","pointsR_length","lp0","lp1","lp2","lp3","lp4","lp5","lp6","turnAngle1","turnAngle","turnAngle2","__corner__","_lastTimePrev","lpd3","wa","ha","catmull2beziers","splice","q1","q2","q3","q4","_ret","addPolyregion","FreeDraw","162","EditTextTool","updateBrush","text","_text","_baseText","updatePen","_cursorOn","reset","Text","fontSize","baseTextUpdate","startEdit","_cursor","_cursorEnd","_center","_currentChar","_currentLine","_changed","_interval","setInterval","clearInterval","isEmpty","revert$","canEdit","findCurrentChar","lines","findCursor","triggerKeyboard","_this3","if$","isText","currentChar","currentLine","keyHome","keyEnd","line","find","_processes","Process","FitOnPath","FitEllipse","ClassicArc","FitEnvelope","updateText","floor","on_keypress","char","matrix_","layout","_textLayout","textLines","minDist","kl","klEnd","textLine","lineChars","allChars","charsLength","_chars","dToEnd","closerGlyph","_baselineRightGrip","kc","d","_grip","baseDist","_baseline","count","bs","before","_originalIdx","grip","frameDirX","dir_x","cursorH","normalize","drawCursorLine","EditText","canBeProcessedLocally","isMultiPart","163","CharsTransformTool","_char","updateText$","every","processes","outputsText","_matrix","charAtPoint_","_point","_downPoint","_charGrip","pn","invMatrix","placeAt","outputFigure","newOutput","shape","_cache","clear","textLayout","spaceWidth","docOffset","finalPos","idx","_idx","lineIdx","_lineIdx","_charData","_transformers","TextChar","PinPlacer","charsTransform","findByType","CharsTransform","_push","ctl","CharTransformList","to","_transforms","CharTransform","TangencialOffset","dirX","co_h","co_v","_h","Magnitude","absoluteMMValueFor","toFixed","_v","figureFrame","164","_toConsumableArray","arr2","from","drawDot","style","colors","pad","drawSegment","nextKi","side","ki","knotPoint","nextKnotPoint","pieceIndexAt","pieceAt","pi","controlPoint","nextControlPoint","oppSide","removeKnot","_owner","curves","_curves","indexOf","_regions","_remove","_polyregions","toolCurves","kiLeft","shift","pieceLeft","Point_sm","tieExtremePoints","forEachKnot","func","nEnd","Knot","findKnot","NodeEditEnvelopeTool","NodeEditTool","Point_add","Point_substract","Color_fromRgb","Color","fromRgb","knotSize","knotSelectedSize","rgb","alpha","knot","knot_selected","knot_over","controlSegment","curveControlSegment","cuspControlSegment","nextControlSegment","control","control_over","addKnot","addKnot_over","removeKnot_over","dragSelector","curvePadBack","ok","nextPoint","pointAt","eval","nextKnot","nki","tangentAt","tangent","normal","leftTangent","rightTangent","locked","__cadx_locked","splitPiece","_computeCorner","left","right","corner","_corner","changeCorner","_side","_opp","newCorner","sh","oh","norm","convertToCurve","convertToSegment","BaseState","_padSize","showToolhelp","baseToolhelp","undoState","state","a","b","curveToDoc","viewToCurve_dx","matrixInverted","curvePoint","_matrixInverted","focus","_possibleClick","cursor_","onUpdate","drawCurve","drawKnots","_strokeCurve","over_knot","_over_knot","_over_selectedKnots","selectedKnots","overKnot","padSize","overSelectedKnots","selectedKnot","_selectedKnots","_changeCursorTo","deleteAction","HandleBase","_state","_knot","_over","over","click","dblClick","drawCurvePadBack","strokeDot","Handle","Control","NextControl","AddKnot","newKnot","RemoveKnot","rs","strokeCross","ConvertToCurve","ConvertToSegment","State","Iddle","EditingKnot","moreHandles","DragSelection","fromPoint","_fromPoint","_toPoint","fixedTransform","knots","db","SelectedKnots","iEnd","knot_i","MovingKnots","originalLeft","originalRight","lFilteredPoints","cacheOppositeKnot","aKnotId","lOppositeKnot","_oppositeKnotId","_oppositeKnot","lOppositePoint","lOppositeLeft","lOppositeRight","toPoint","diffOpposite","lIdx","lOpposite","MovingControl","_knotPoint","_original","opp","_originalOpp","_handle","_oppHandle","oppVec","oppNorm","NodeEditBaseTool","startEditingFigure$","startEdition","unlock","createCurves","_undoState","on_keydown_alt","on_keyup","on_keyup_alt","_ref10","sk","_len","params","_key","Function","_ref11","drawIsolatedFigures","_alpha","lineJoin","ft","_ref12","_clickOut","_ref13","_ref14","co","_ref15","_onClickOut","_ref16","select","_hideOriginal","startIsolatedFiguresEdition","stopIsolatedFiguresEdition","referencePoint","referencePoint_","_anchor","_absolute","_pin","anchorBased","_fixUpPin$","NodeEdit","localFitEnvelope","process","_addOnCommit","createFromFigure","_process","envelope","cloneDeep","_this4","updateFigure$","addOnCommit","center$","matrix$","oldEnvelopeCenter","_envelope","currentPieces","createCurve","Envelope","newEnvelopeCenter","NodeEditEnvelope","165","RenderInfoTool","computeRenderFrame_","_downMatrix22","_polyregion","initialRenderFrame","globalMatrix_","downFrame","downMatrix22","mi","mi_transform","polyregionAtPoint_","ClippingBounds","clippingFrame","_downClippingBounds","clippingBounds","_downTextureOffset","textureOffset","clippingFrame_","frame_0","frame_1","fr_0","ocb","frs_0","ncb","dto","nto","RenderInfo","166","SelectBrushTool","getBrushAtPoint","SelectBrush"],"mappings":"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","file":"tools.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Grafika\"] = factory();\n\telse\n\t\troot[\"Grafika\"] = factory();\n})(this, function() {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Grafika\"] = factory();\n\telse\n\t\troot[\"Grafika\"] = factory();\n})(this, function() {\nreturn webpackJsonpGrafika([6],{\n\n/***/ 0:\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(151);\n\n\n/***/ },\n\n/***/ 151:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _tool = __webpack_require__(152);\n\t\n\tvar Tool = _interopRequireWildcard(_tool);\n\t\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\t\n\tvar _window = window;\n\tvar Cx = _window.Cx;\n\t\n\t\n\t(0, _lodash.assign)(Cx, Tool);\n\n/***/ },\n\n/***/ 152:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _select = __webpack_require__(153);\n\t\n\tObject.keys(_select).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _select[key];\n\t }\n\t });\n\t});\n\t\n\tvar _zoom = __webpack_require__(111);\n\t\n\tObject.keys(_zoom).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _zoom[key];\n\t }\n\t });\n\t});\n\t\n\tvar _pan = __webpack_require__(112);\n\t\n\tObject.keys(_pan).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _pan[key];\n\t }\n\t });\n\t});\n\t\n\tvar _clip = __webpack_require__(157);\n\t\n\tObject.keys(_clip).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _clip[key];\n\t }\n\t });\n\t});\n\t\n\tvar _powerClip = __webpack_require__(158);\n\t\n\tObject.keys(_powerClip).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _powerClip[key];\n\t }\n\t });\n\t});\n\t\n\tvar _addFigure = __webpack_require__(159);\n\t\n\tObject.keys(_addFigure).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _addFigure[key];\n\t }\n\t });\n\t});\n\t\n\tvar _draw = __webpack_require__(160);\n\t\n\tObject.keys(_draw).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _draw[key];\n\t }\n\t });\n\t});\n\t\n\tvar _freeDraw = __webpack_require__(161);\n\t\n\tObject.keys(_freeDraw).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _freeDraw[key];\n\t }\n\t });\n\t});\n\t\n\tvar _editText = __webpack_require__(162);\n\t\n\tObject.keys(_editText).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _editText[key];\n\t }\n\t });\n\t});\n\t\n\tvar _charsTransform = __webpack_require__(163);\n\t\n\tObject.keys(_charsTransform).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _charsTransform[key];\n\t }\n\t });\n\t});\n\t\n\tvar _nodeEdit = __webpack_require__(164);\n\t\n\tObject.keys(_nodeEdit).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _nodeEdit[key];\n\t }\n\t });\n\t});\n\t\n\tvar _renderInfo = __webpack_require__(165);\n\t\n\tObject.keys(_renderInfo).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _renderInfo[key];\n\t }\n\t });\n\t});\n\t\n\tvar _selectBrush = __webpack_require__(166);\n\t\n\tObject.keys(_selectBrush).forEach(function (key) {\n\t if (key === \"default\") return;\n\t Object.defineProperty(exports, key, {\n\t enumerable: true,\n\t get: function () {\n\t return _selectBrush[key];\n\t }\n\t });\n\t});\n\n/***/ },\n\n/***/ 153:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.SelectTool = exports.SelectBaseTool = undefined;\n\t\n\tvar _config = __webpack_require__(2);\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar _selectTransform = __webpack_require__(154);\n\t\n\tvar _dragSelector = __webpack_require__(156);\n\t\n\tvar SelectBaseTool = exports.SelectBaseTool = _view.Tool.extend({\n\t\n\t type: 'Select',\n\t\n\t toolbarName: 'selectTool',\n\t allowKeyShortcuts: true,\n\t isCommitable: false,\n\t\n\t Properties: {\n\t selectAndDragEnabled: { type: 'boolean', def: true }\n\t },\n\t\n\t resume: function () {\n\t this.callParent();\n\t this.handles.update();\n\t this.setIddleToolhelp();\n\t },\n\t initTool: function (view, config) {\n\t var _this = this;\n\t\n\t (0, _lodash.assign)(this, config || {});\n\t\n\t this.handles = new _selectTransform.OptimizedFiguresHandles({ view: view, tool: this,\n\t\n\t editingItems: function (view) {\n\t return view.selectedFigures;\n\t },\n\t onItemsDrag: function (event, figures) {\n\t view.fireEvent('figuresdrag', event, figures);\n\t },\n\t onItemsDrop: function (_ref, figures) {\n\t var view = _ref.view;\n\t var event = _ref.event;\n\t\n\t var onDrop = { cancelMove: false };\n\t if (event) {\n\t view.fireEvent('figuresdrop', event, figures, onDrop); // [TODO] FiguresDropEvent\n\t }\n\t\n\t var cancelMove = onDrop.cancelMove;\n\t if (cancelMove) {\n\t this.absoluteTranslate(new _cdl.Point(0, 0));\n\t }\n\t\n\t var notRemovedFigures = [];\n\t var doc = view.doc;\n\t\n\t (0, _lodash.forEach)(figures, function (figure) {\n\t if (figure.document === doc) {\n\t notRemovedFigures.push(figure);\n\t }\n\t });\n\t return notRemovedFigures.length > 0 && !cancelMove;\n\t },\n\t\n\t\n\t setIddleToolhelp: function () {\n\t return _this.setIddleToolhelp();\n\t }\n\t });\n\t\n\t this._transparentMode = false;\n\t },\n\t setIddleToolhelp: function () {\n\t var th = ['Click or draw rectangle to select', 'Ctrl and drag Canvas to pan'];\n\t if (this.view.selectedFigures.length > 0) {\n\t th.push('Shift to aggregate to selection');\n\t th.push('Alt to make selected figures transparent');\n\t th.push('Alt-Click to select figure below selection');\n\t }\n\t this.toolhelp(th);\n\t },\n\t link: function (view) {\n\t view.on({\n\t 'rendercomplete': this.on_rendercomplete //,\n\t //'change' : this.on_change,\n\t //'resize' : this.on_change\n\t }, this);\n\t\n\t this.handles.create();\n\t },\n\t unlink: function (view) {\n\t view.un(this);\n\t\n\t this.handles.dispose();\n\t },\n\t on_dblclick: function (_ref2) {\n\t var view = _ref2.view;\n\t var docPoint = _ref2.docPoint;\n\t\n\t\n\t var selectedFigures = view.selectedFigures;\n\t\n\t if (selectedFigures.length === 1) {\n\t var figure = selectedFigures[0];\n\t if (view.canEditContent(figure)) {\n\t // [TODO] && view._dblclickContentEditionEnabled(figure) ) {\n\t view.editContent(figure, docPoint);\n\t }\n\t } else if (view.editingContent()) {\n\t view.commitContent$();\n\t }\n\t },\n\t onSelectionChanged: function () /* view */{\n\t /*\r\n\t const tm = this._transparentMode;\r\n\t if( tm ) {\r\n\t forEach( this._transparentFigureViews, fv => { fv.hideMask(); });\r\n\t this._transparentMode = false;\r\n\t this.on_keydown_alt(view);\r\n\t }\r\n\t */\n\t this.setIddleToolhelp();\n\t this.redraw();\n\t },\n\t draw: function (config) {\n\t\n\t // Draw selected texture island, we should make this a plugin\n\t // [TODO] Hacking in missing features from v5, later clean up\n\t var view = config.view;\n\t var context = config.context;\n\t var transformModel = config.transformModel;\n\t\n\t var docIslands = (0, _lodash.filter)(view.selectedFigures, function (figure) {\n\t return figure.metadata.get('textureIslandName');\n\t });\n\t if (view.is3D && view.model && docIslands.length > 0) {\n\t (0, _lodash.forEach)(docIslands, function (docIsland) {\n\t var modelIsland = view.model.modelIslandFor(docIsland);\n\t context.strokeStyle = '#f2f2f2';\n\t context.lineWidth = 25;\n\t modelIsland.draw(context, transformModel, { customDraw: function (c) {\n\t return c.stroke();\n\t } });\n\t context.strokeStyle = '#388638';\n\t context.lineWidth = 20;\n\t (0, _gear.setLineDash)(context, [6, 4]);\n\t modelIsland.draw(context, transformModel, { customDraw: function (c) {\n\t return c.stroke();\n\t } });\n\t });\n\t } else {\n\t\n\t this.handles.draw(config);\n\t }\n\t },\n\t useAggregateMode: function (_ref3) {\n\t var shiftKey = _ref3.shiftKey;\n\t var cmdKey = _ref3.cmdKey;\n\t\n\t return shiftKey || _config.Config.ctrlAggregation && cmdKey;\n\t },\n\t useContentEditMode: function (_ref4) {\n\t var cmdKey = _ref4.cmdKey;\n\t\n\t return !_config.Config.ctrlAggregation && cmdKey;\n\t },\n\t try_pointerdown: function (_ref5) {\n\t var view = _ref5.view;\n\t var event = _ref5.event;\n\t var handles = this.handles;\n\t\n\t\n\t if (handles.isHandle(event)) {\n\t\n\t if (handles.isHandleEnabledAt(event)) {\n\t handles.down(event);\n\t event.stopPropagation();\n\t }\n\t\n\t // Clicking selection\n\t // If there is no mouse movement for a few milliseconds,\n\t // we should select this figure in the next mouse up.\n\t this._possibleClicking = { event: event, time: (0, _lodash.now)() };\n\t\n\t return true;\n\t }\n\t\n\t return false;\n\t },\n\t on_pointerdown: function (_ref6) {\n\t var _this2 = this;\n\t\n\t var view = _ref6.view;\n\t var event = _ref6.event;\n\t var which = _ref6.which;\n\t var cmdKey = _ref6.cmdKey;\n\t var docPoint = _ref6.docPoint;\n\t var pointers = _ref6.pointers;\n\t var handles = this.handles;\n\t\n\t\n\t if (pointers.length === 2) {\n\t\n\t if (handles._editionMode) {\n\t event.stopPropagation();\n\t return;\n\t }\n\t\n\t this._possibleDrag = null;\n\t this.helper = null;\n\t return;\n\t }\n\t\n\t if (handles._editionMode) {\n\t this._endMode(event);\n\t return;\n\t }\n\t\n\t var leftClick = which === 1;\n\t if (!leftClick) {\n\t // right click on empty design area?\n\t if (!event.figure) {\n\t // [EVENTS] some( view.selectedFigures, figure => figure.canBeSelected() && figure.frame_().contains(docPoint) )) {\n\t // [TODO] stop event?\n\t view.clearSelection();\n\t view.render$();\n\t }\n\t return;\n\t }\n\t\n\t if (!this.try_pointerdown(event)) {\n\t var figureHit = event.figureHit; // get top most figure at point\n\t\n\t var _handles = this.handles;\n\t\n\t\n\t var possibleDrag = function () {\n\t if (!cmdKey) {\n\t if (!_this2.useAggregateMode(event)) {\n\t view.clearSelection();\n\t }\n\t view.render$();\n\t _this2._possibleDrag = { event: event };\n\t }\n\t };\n\t\n\t if (figureHit) {\n\t // click directly on figure (not handle)?\n\t\n\t var figure = figureHit.figure;\n\t var tight = figureHit.tight;\n\t\n\t if (tight && this.selectAndDragEnabled && !(view.is3D && !view.selectAndDragEnabled)) {\n\t // [TODO] Review...\n\t\n\t this._figureClicked(figure, event);\n\t\n\t // [TODO] Review, hacking my way to production now, allow to select and drag the 3D model\n\t // in case the figure is not movable\n\t\n\t var movable = view.is(figure, 'movable');\n\t if (movable) {\n\t event.stopPropagation();\n\t _handles.update(); // Needed for select and drag\n\t _handles.down(event);\n\t }\n\t\n\t view.render$();\n\t } else {\n\t this._possibleClicking = { event: event, time: (0, _lodash.now)() };\n\t possibleDrag();\n\t }\n\t\n\t return;\n\t } else {\n\t // click on empty design area?\n\t possibleDrag();\n\t }\n\t }\n\t },\n\t on_mousemove: function (event) {\n\t this.handles.mousemove(event);\n\t },\n\t on_pointermove: function (_ref7) {\n\t var view = _ref7.view;\n\t var event = _ref7.event;\n\t var _possibleDrag = this._possibleDrag;\n\t\n\t if (_possibleDrag) {\n\t this.helper = new _dragSelector.DragSelectorHelper(_possibleDrag.event, this._dragEnd.bind(this));\n\t this._possibleDrag = null;\n\t }\n\t this.handles.move(event);\n\t },\n\t on_pointerup: function (event) {\n\t this._endMode(event);\n\t },\n\t _endMode: function (_ref8) {\n\t var view = _ref8.view;\n\t var event = _ref8.event;\n\t var viewPoint = _ref8.viewPoint;\n\t\n\t\n\t this.handles.up(event);\n\t\n\t this._possibleDrag = null;\n\t\n\t var pc = this._possibleClicking;\n\t if (pc) {\n\t var t = (0, _lodash.now)();\n\t if (t - pc.time < 500) {\n\t var pc_event = pc.event;\n\t var pcViewPoint = pc_event.viewPoint;\n\t\n\t // Allow small shifts, accepted as clicks\n\t if (Math.abs(pcViewPoint.x - viewPoint.x) <= 1 && Math.abs(pcViewPoint.y - viewPoint.y) <= 1) {\n\t var figure = pc.event.figure;\n\t\n\t\n\t if (figure) {\n\t // Add the selected figure\n\t this._figureClicked(figure, pc_event);\n\t view.render$();\n\t } else if (this.useContentEditMode(pc_event) && view.editingContent()) {\n\t view.commitContent$();\n\t }\n\t }\n\t }\n\t this._possibleClicking = null;\n\t }\n\t },\n\t on_rendercomplete: function () {\n\t this.handles.update();\n\t },\n\t _dragEnd: function (_ref9, bounds) {\n\t var view = _ref9.view;\n\t var event = _ref9.event;\n\t\n\t\n\t if (bounds.width > 0 && bounds.height > 0) {\n\t (function () {\n\t var selectedFigures = view.selectedFigures;\n\t\n\t var figures = view.activeSelectableFigures(); // [TODO]\n\t\n\t (0, _cdl.updateArray$)(figures).then(function () {\n\t\n\t var selection = (0, _lodash.filter)(figures, function (figure) {\n\t\n\t // Is Inside Bounds\n\t var fb = figure.bounds_();\n\t return fb.lx > bounds.lx && fb.ly > bounds.ly && fb.hx < bounds.hx && fb.hy < bounds.hy;\n\t });\n\t\n\t if (selection.length > 0) {\n\t // Force selection of upper layer figures first\n\t selection.reverse();\n\t\n\t selectedFigures.add(selection);\n\t }\n\t\n\t view.render$();\n\t });\n\t })();\n\t }\n\t },\n\t _figureClicked: function (figure, event) {\n\t var view = this.view;\n\t var selectedFigures = view.selectedFigures;\n\t\n\t view.activeDocument = figure.document;\n\t\n\t if (this.useContentEditMode(event) && view.canEditContent(figure)) {\n\t // [TODO] && view._dblclickContentEditionEnabled(figure) ) {\n\t return view.editContent(figure, view.docPoint(event));\n\t }\n\t\n\t if (this.useAggregateMode(event)) {\n\t\n\t if ((0, _lodash.includes)(selectedFigures, figure)) {\n\t selectedFigures.remove(figure);\n\t } else {\n\t selectedFigures.add(figure);\n\t }\n\t }\n\t // Avoid selectionChanged event in case it is already selected\n\t else if (!(selectedFigures.length === 1 && selectedFigures[0] === figure)) {\n\t\n\t selectedFigures.set([figure]);\n\t }\n\t },\n\t somethingToDraw: function () {\n\t return this.handles.visible;\n\t },\n\t needsToDrawFor: function (docIsland) {\n\t var frame = this.handles.frame;\n\t\n\t return !!frame && _cdl.Frame.areOverlapping(docIsland.frame_(), this.handles.frame);\n\t }\n\t});\n\t\n\tvar SelectTool = exports.SelectTool = SelectBaseTool.extend({ typeName: 'SelectTool',\n\t\n\t canUndo: function () {\n\t return this.view.doc.canUndo();\n\t },\n\t undo: function () {\n\t return this.view.doc.undo();\n\t },\n\t canRedo: function () {\n\t return this.view.doc.canRedo();\n\t },\n\t redo: function () {\n\t return this.view.doc.redo();\n\t },\n\t supportsClipboard: function () {\n\t return true;\n\t }\n\t});\n\t_view.Tool.Select = SelectTool;\n\n/***/ },\n\n/***/ 154:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.OptimizedFiguresHandles = exports.FiguresHandles = exports.SelectAndTransformHandles = undefined;\n\texports.computeScale = computeScale;\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _selectHandles = __webpack_require__(155);\n\t\n\tvar _abs = Math.abs;\n\t\n\tvar dotProduct = _cdl.Point.dotProduct;\n\tvar substract = _cdl.Point.substract;\n\tfunction computeScale(pin, dir, mousePos, initialMousePos, zoomScale) {\n\t\n\t var initialDiff = substract(initialMousePos, pin);\n\t\n\t var currentDiff = substract(mousePos, pin);\n\t\n\t var dpi = dotProduct(initialDiff, dir);\n\t\n\t var dpc = dotProduct(currentDiff, dir);\n\t if (_abs(dpc) < 8 * zoomScale) {\n\t if (_abs(dpi) < 8 * zoomScale) {\n\t dpc = dpi;\n\t } else {\n\t dpc = 8 * zoomScale * (dpc < 0 ? -1 : 1);\n\t }\n\t }\n\t\n\t return {\n\t pin: pin.clone(),\n\t sx: dpc / dpi,\n\t deg: dir.angle()\n\t };\n\t}\n\t\n\tfunction computeShear(pin, dir, mousePos, initialMousePos) {\n\t // http://www.w3.org/TR/SVG11/coords.html\n\t // http://jsfiddle.net/jbpEk/\n\t // http://jsfiddle.net/jbpEk/26/\n\t\n\t var initialDiff = substract(initialMousePos, pin);\n\t var currentDiff = substract(mousePos, pin);\n\t var dpc = dotProduct(currentDiff, dir);\n\t var dpi = dotProduct(initialDiff, dir);\n\t\n\t var dpcPa = _abs(dotProduct(initialDiff, dir.perpendicular(-1)));\n\t\n\t if (dpcPa < 8) {\n\t dpcPa = 8;\n\t }\n\t\n\t var r = {\n\t deg: dir.angle(),\n\t sx: (dpc - dpi) / dpcPa,\n\t sy: 0,\n\t pin: pin.clone()\n\t };\n\t\n\t return r;\n\t}\n\t\n\t// Computes the rotation in radians.\n\tfunction computeRotation(pin, mousePos) {\n\t return mousePos.minus(pin).angle();\n\t}\n\t\n\tfunction computeFiguresFrame_(figures) {\n\t if (figures.length === 1) {\n\t return figures[0].frame_();\n\t }\n\t return _cdl.Frame.fromBounds(_cdl.Figures.bounds_(figures));\n\t}\n\t\n\tfunction figuresSnapToPoints(view, editingFigures) {\n\t\n\t var snapTo = [];\n\t\n\t var viewBounds = view.bounds;\n\t (0, _lodash.forEach)(view.horizontalUserLines, function (userLine) {\n\t if (userLine._snap) {\n\t var snapPoint = new _cdl.Point(userLine._position, viewBounds.ly);\n\t snapTo.push({ lx_ly: snapPoint, center: snapPoint, hx_hy: snapPoint });\n\t }\n\t });\n\t (0, _lodash.forEach)(view.verticalUserLines, function (userLine) {\n\t if (userLine._snap) {\n\t var snapPoint = new _cdl.Point(viewBounds.lx, userLine._position);\n\t snapTo.push({ lx_ly: snapPoint, center: snapPoint, hx_hy: snapPoint });\n\t }\n\t });\n\t\n\t snapTo.push({ center: _cdl.Figures.bounds_(editingFigures).center });\n\t\n\t (0, _lodash.forEach)((0, _lodash.difference)(view.activePageFigures, editingFigures), function (figure) {\n\t var _figure$frame_$bounds = figure.frame_().bounds;\n\t var lx_ly = _figure$frame_$bounds.lx_ly;\n\t var center = _figure$frame_$bounds.center;\n\t var hx_hy = _figure$frame_$bounds.hx_hy;\n\t\n\t snapTo.push({ lx_ly: lx_ly, center: center, hx_hy: hx_hy });\n\t });\n\t\n\t return snapTo;\n\t}\n\t\n\t// We should divide this into several helpers\n\t\n\tvar FrameInteractionMixin = {\n\t\n\t // expects\n\t //\n\t // members:\n\t // view, handles\n\t //\n\t // functions:\n\t // editingItems(view) => items\n\t // getOriginalTransforms(items) => transforms\n\t // setOriginalTransforms(items,transforms)\n\t // transformItems(items,transform)\n\t //\n\t // optional:\n\t // setOriginalPositions(items,transforms)\n\t // translateItems(items,offset)\n\t // snapToPoints(view,items) => [ { lx_ly, center, hx_hy }, ... ]\n\t // transformWithFixedCenter(view,items) => boolean\n\t // scaleOriginalXY(view,items) => { scaleX : s00, scaleY : s11 }\n\t // setIddleToolhelp()\n\t\n\t initFrameInteraction: function () {\n\t (0, _lodash.assign)(this, {\n\t _data: null,\n\t _editingItems: null,\n\t _originalTransforms: null,\n\t _editionMode: false,\n\t _downFrame: null\n\t });\n\t },\n\t snapToPoints: function () /*view,items*/{\n\t return [];\n\t },\n\t transformWithFixedCenter: function () /*view,items*/{\n\t return false;\n\t },\n\t scaleOriginalXY: function () /*view,items*/{\n\t return null; // { scaleX : s00, scaleY : s11 };\n\t },\n\t setIddleToolhelp: function () {},\n\t setEditionToolhelp: function (transformType, shiftToolhelp, shiftOnlyForSingleSelection) {\n\t var tool = this.tool;\n\t var _editingItems = this._editingItems;\n\t\n\t var dragText = 'Drag to ' + transformType + ' selection';\n\t var altText = 'Alt to make selection transparent';\n\t if (_editingItems.length > 1) {\n\t tool.toolhelp(dragText + (shiftOnlyForSingleSelection ? '' : '\\n' + shiftToolhelp), altText);\n\t } else {\n\t tool.toolhelp(dragText, shiftToolhelp, altText);\n\t }\n\t },\n\t onItemsDrag: function () /*event, items*/{},\n\t onItemsDrop: function () /*event, items*/{\n\t return true;\n\t },\n\t\n\t\n\t // Internals\n\t //--------------------------------------------------------------------------------------\n\t\n\t startEditionMode: function (transformType, shiftToolhelp, shiftOnlyForSingleSelection) {\n\t var view = this.view;\n\t var handles = this.handles;\n\t\n\t\n\t var editingItems = this._editingItems = (0, _gear.clone)(this.editingItems(view));\n\t this._originalTransforms = this.getOriginalTransforms(editingItems);\n\t\n\t this._downFrame = handles._frame;\n\t this._editionMode = true;\n\t\n\t this.setEditionToolhelp(transformType, shiftToolhelp, shiftOnlyForSingleSelection);\n\t view.redraw('annotations');\n\t },\n\t endEditionMode: function () {\n\t this.setIddleToolhelp();\n\t this.initFrameInteraction();\n\t },\n\t\n\t\n\t // optional\n\t translateItems: function (items, offset) {\n\t this.transformItems(items, _cdl.Matrix.translate(offset));\n\t },\n\t setOriginalPositions: function (figures, originalTransforms) {\n\t this.setOriginalTransforms(figures, originalTransforms);\n\t },\n\t updateHandlesFrame: function (transform) {\n\t var view = this.view;\n\t var handles = this.handles;\n\t var _downFrame = this._downFrame;\n\t\n\t handles.update(_downFrame.transformed(transform));\n\t // Batch redraw, the frame will be drawn again at the same time as the document\n\t view.batchRedraw('tools');\n\t },\n\t absoluteTransform: function (transform) {\n\t var view = this.view;\n\t var _editingItems = this._editingItems;\n\t var _originalTransforms = this._originalTransforms;\n\t\n\t this.setOriginalTransforms(_editingItems, _originalTransforms);\n\t this.updateHandlesFrame(transform);\n\t this.transformItems(_editingItems, transform);\n\t view.preview$();\n\t },\n\t absoluteTranslate: function (offset) {\n\t var view = this.view;\n\t var _editingItems = this._editingItems;\n\t var _originalTransforms = this._originalTransforms;\n\t\n\t this.setOriginalPositions(_editingItems, _originalTransforms);\n\t this.updateHandlesFrame(_cdl.Matrix.translate(offset));\n\t this.translateItems(_editingItems, offset);\n\t view.preview$();\n\t },\n\t commit$: function () {\n\t this.view.commit$();\n\t },\n\t\n\t\n\t // Translate\n\t //-------------------------------------------------------------------------------------\n\t\n\t onTranslateStart: function (_ref) {\n\t var view = _ref.view;\n\t\n\t this._data = {\n\t offset: new _cdl.Point(0, 0),\n\t started: false,\n\t snapTo: this.snapToPoints(view, this.editingItems(view)) // [ { lx_ly, center, hx_hy }, ... ]\n\t };\n\t },\n\t\n\t\n\t // Use docPointRaw that allows jumps depending on the view used to see\n\t // the document (Canvas3D, TextureView)\n\t\n\t getOnTranslateValue: function (_ref2) {\n\t var view = _ref2.view;\n\t var docPointRaw = _ref2.docPointRaw;\n\t var cmdKey = _ref2.cmdKey;\n\t var shiftKey = _ref2.shiftKey;\n\t var handles = this.handles;\n\t var _data = this._data;\n\t var _downFrame = this._downFrame;\n\t\n\t\n\t var offset = substract(docPointRaw, handles.mouseDownPos);\n\t if (!offset.isZero()) {\n\t _data.started = true;\n\t }\n\t\n\t var snapTo = _data.snapTo;\n\t // [TODO] Move AlignmentLines logic to the plugin\n\t var alignmentLines = view._alignmentLines || { _visible: false, _snap: false };\n\t\n\t var forceSnap = shiftKey || cmdKey;\n\t var al_visible = forceSnap || alignmentLines._visible;\n\t var al_snap = forceSnap || alignmentLines._snap;\n\t var al_enabled = al_visible || al_snap;\n\t if (snapTo && al_enabled && _data.started) {\n\t (function () {\n\t // snap\n\t var snapSize = view.viewDeltaToDoc(14);\n\t\n\t var _downFrame$translated = _downFrame.translated(offset);\n\t\n\t var bounds = _downFrame$translated.bounds;\n\t\n\t var al_x = null,\n\t al_y = null,\n\t diff_x = Number.MAX_VALUE,\n\t diff_y = Number.MAX_VALUE;\n\t (0, _lodash.forEach)(snapTo, function (snap) {\n\t (0, _lodash.forEach)(snap, function (s, name) {\n\t\n\t var diff = substract(s, bounds[name]);\n\t\n\t var ax = _abs(diff.x);\n\t if (ax < snapSize && _abs(diff_x) > ax) {\n\t diff_x = diff.x;\n\t if (al_visible) {\n\t al_x = s.x;\n\t }\n\t }\n\t var ay = _abs(diff.y);\n\t if (ay < snapSize && _abs(diff_y) > ay) {\n\t diff_y = diff.y;\n\t if (al_visible) {\n\t al_y = s.y;\n\t }\n\t }\n\t });\n\t });\n\t\n\t handles.guideline_x = al_x;\n\t if (al_snap && diff_x !== Number.MAX_VALUE) {\n\t offset.x += diff_x;\n\t }\n\t\n\t handles.guideline_y = al_y;\n\t if (al_snap && diff_y !== Number.MAX_VALUE) {\n\t offset.y += diff_y;\n\t }\n\t })();\n\t } else {\n\t handles.guideline_x = null;\n\t handles.guideline_y = null;\n\t }\n\t\n\t return view.asFastOffset(offset);\n\t },\n\t onTranslateMove: function (event) {\n\t var _data = this._data;\n\t var _editionMode = this._editionMode;\n\t var _editingItems = this._editingItems;\n\t\n\t if (!_editionMode) {\n\t this.startEditionMode('translate', 'Shift to show snap guidelines');\n\t }\n\t var offset = _data.offset = this.getOnTranslateValue(event);\n\t this.absoluteTranslate(offset);\n\t this.onItemsDrag(event, _editingItems);\n\t },\n\t onTranslateEnd: function (event) {\n\t var _data = this._data;\n\t var _editionMode = this._editionMode;\n\t var _editingItems = this._editingItems;\n\t var handles = this.handles;\n\t\n\t if (_editionMode) {\n\t var offset = _data.offset;\n\t\n\t\n\t var needsRedraw = handles.guideline_x || handles.guideline_y;\n\t\n\t handles.guideline_x = null;\n\t handles.guideline_y = null;\n\t\n\t this.endEditionMode();\n\t\n\t if ((offset.x !== 0 || offset.y !== 0) && this.onItemsDrop(event, _editingItems)) {\n\t this.commit$();\n\t } else if (needsRedraw) {\n\t this.tool.redraw();\n\t }\n\t }\n\t },\n\t\n\t\n\t // Scale\n\t //-------------------------------------------------------------------------------------\n\t\n\t onScaleStart: function (_ref3) {\n\t var view = _ref3.view;\n\t var handles = this.handles;\n\t\n\t var editingItems = this.editingItems(view);\n\t var pin = handles.current.pin.pos;\n\t this._data = {\n\t scale: { pin: pin, sx: 1, sy: 1, deg: 0 },\n\t fixedCenter: this.transformWithFixedCenter(view, editingItems),\n\t center: handles.center,\n\t scalePin: pin,\n\t scaleDir: handles.scaleDirFromHandle(handles.current),\n\t os: this.scaleOriginalXY(view, editingItems)\n\t };\n\t },\n\t getOnScaleValue: function (_ref4) {\n\t var view = _ref4.view;\n\t var event = _ref4.event;\n\t var docPoint = _ref4.docPoint;\n\t var cmdKey = _ref4.cmdKey;\n\t var shiftKey = _ref4.shiftKey;\n\t var handles = this.handles;\n\t var _data = this._data;\n\t var current = handles.current;\n\t var mouseDownPos = handles.mouseDownPos;\n\t var fixedCenter = _data.fixedCenter;\n\t var center = _data.center;\n\t var scalePin = _data.scalePin;\n\t var scaleDir = _data.scaleDir;\n\t\n\t\n\t var pin = fixedCenter || cmdKey ? center : scalePin;\n\t\n\t var scale = computeScale(pin, scaleDir, docPoint, mouseDownPos, view.viewDeltaToDoc(1));\n\t\n\t var name = current.name;\n\t\n\t scale.sy = name === 'ne' || name === 'nw' || name === 'sw' || name === 'se' ? scale.sx : 1;\n\t\n\t var os = _data.os;\n\t\n\t if (shiftKey && os) {\n\t // Snapping to sx = sy\n\t if (name === 'n' || name === 's') {\n\t if (_abs(os.scaleY * scale.sx / os.scaleX - 1) < 0.15) {\n\t scale.sx = os.scaleX / os.scaleY;\n\t }\n\t } else if (name === 'e' || name === 'w') {\n\t if (_abs(os.scaleX * scale.sx / os.scaleY - 1) < 0.15) {\n\t scale.sx = os.scaleY / os.scaleX;\n\t }\n\t }\n\t }\n\t return scale;\n\t },\n\t onScaleMove: function (event) {\n\t var _editionMode = this._editionMode;\n\t\n\t if (!_editionMode) {\n\t this.startEditionMode('scale', 'Shift to lock to on isometric scaling', true);\n\t }\n\t\n\t this.doScaleMove(event);\n\t },\n\t doScaleMove: function (event) {\n\t var _data = this._data;\n\t\n\t var _data$scale = _data.scale = this.getOnScaleValue(event);\n\t\n\t var pin = _data$scale.pin;\n\t var sx = _data$scale.sx;\n\t var sy = _data$scale.sy;\n\t var deg = _data$scale.deg;\n\t\n\t\n\t var scaleFrom = _cdl.Matrix.scaleFrom(pin, sx, sy, deg);\n\t\n\t this.absoluteTransform(scaleFrom);\n\t },\n\t onScaleEnd: function () {\n\t var _data = this._data;\n\t var _editionMode = this._editionMode;\n\t\n\t if (_editionMode) {\n\t var sx = _data.scale.sx;\n\t\n\t\n\t this.endEditionMode();\n\t if (sx !== 1) {\n\t this.commit$();\n\t }\n\t }\n\t },\n\t\n\t\n\t // Rotate\n\t //-------------------------------------------------------------------------------------\n\t\n\t onRotateStart: function (_ref5) {\n\t var view = _ref5.view;\n\t var event = _ref5.event;\n\t var docPoint = _ref5.docPoint;\n\t var handles = this.handles;\n\t var center = handles.center;\n\t var current = handles.current;\n\t\n\t\n\t this._data = {\n\t deg: 0,\n\t center: center,\n\t initialDeg: computeRotation(center, docPoint),\n\t initialSnapDeg: computeRotation(center, current.pos)\n\t };\n\t },\n\t getOnRotateValue: function (_ref6) {\n\t var event = _ref6.event;\n\t var docPoint = _ref6.docPoint;\n\t var shiftKey = _ref6.shiftKey;\n\t var cmdKey = _ref6.cmdKey;\n\t var _data = this._data;\n\t var center = _data.center;\n\t var initialDeg = _data.initialDeg;\n\t var initialSnapDeg = _data.initialSnapDeg;\n\t\n\t\n\t var r = computeRotation(center, docPoint);\n\t if (shiftKey || cmdKey) {\n\t // Snap\n\t var sm = 15;\n\t return Math.round(r / sm) * sm - initialSnapDeg;\n\t } else {\n\t return r - initialDeg;\n\t }\n\t },\n\t onRotateMove: function (event) {\n\t var _editionMode = this._editionMode;\n\t var _data = this._data;\n\t\n\t\n\t if (!_editionMode) {\n\t this.startEditionMode('rotate', 'Shift to lock rotation on multiples of 15 degrees');\n\t }\n\t\n\t var deg = _data.deg = this.getOnRotateValue(event);\n\t var rotateAround = _cdl.Matrix.rotateAround(_data.center, deg);\n\t\n\t this.absoluteTransform(rotateAround);\n\t },\n\t onRotateEnd: function () {\n\t var _editionMode = this._editionMode;\n\t var _data = this._data;\n\t\n\t\n\t if (_editionMode) {\n\t var deg = _data.deg;\n\t\n\t this.endEditionMode();\n\t if (deg !== 0) {\n\t this.commit$();\n\t }\n\t }\n\t },\n\t\n\t\n\t // Shear\n\t //-------------------------------------------------------------------------------------\n\t\n\t onShearStart: function (_ref7) {\n\t var view = _ref7.view;\n\t var handles = this.handles;\n\t var current = handles.current;\n\t var center = handles.center;\n\t\n\t\n\t this._data = {\n\t shear: { sx: 0, sy: 0 },\n\t center: center,\n\t fixedCenter: this.transformWithFixedCenter(view, this.editingItems(view)),\n\t shearPin: current.pin.pos,\n\t shearDir: handles.shearDirFromHandle(current),\n\t shearHandlePos: current.pos,\n\t shearOppPin: current.oppPin.pos\n\t };\n\t },\n\t getOnShearValue: function (_ref8) {\n\t var view = _ref8.view;\n\t var event = _ref8.event;\n\t var docPoint = _ref8.docPoint;\n\t var handles = this.handles;\n\t var _data = this._data;\n\t var ctrlKey = handles.ctrlKey;\n\t var shiftKey = handles.shiftKey;\n\t var fixedCenter = _data.fixedCenter;\n\t var center = _data.center;\n\t var shearPin = _data.shearPin;\n\t var shearOppPin = _data.shearOppPin;\n\t var shearHandlePos = _data.shearHandlePos;\n\t var shearDir = _data.shearDir;\n\t\n\t\n\t var downPos = handles.mouseDownPos;\n\t\n\t var pos = docPoint;\n\t\n\t var pin = fixedCenter || ctrlKey ? center : shearPin;\n\t if (shiftKey) {\n\t // Snap\n\t var currentOppPin = pos.plus(substract(shearOppPin, shearHandlePos));\n\t var kp = substract(currentOppPin, pin);\n\t var dp = dotProduct(kp, shearDir);\n\t if (_abs(dp) < 15) {\n\t pos = pin.plus(substract(shearHandlePos, shearOppPin));\n\t downPos = shearHandlePos;\n\t }\n\t }\n\t\n\t return computeShear(pin, _data.shearDir, pos, downPos);\n\t },\n\t onShearMove: function (event) {\n\t var _data = this._data;\n\t var _editionMode = this._editionMode;\n\t\n\t\n\t if (!_editionMode) {\n\t this.startEditionMode('skew', 'Shift to lock when there is no skewing', true);\n\t }\n\t\n\t var _data$shear = _data.shear = this.getOnShearValue(event);\n\t\n\t var pin = _data$shear.pin;\n\t var sx = _data$shear.sx;\n\t var sy = _data$shear.sy;\n\t var deg = _data$shear.deg;\n\t\n\t var shearAround = _cdl.Matrix.shearAround(pin, sx, sy, deg);\n\t\n\t this.absoluteTransform(shearAround);\n\t },\n\t onShearEnd: function () {\n\t var _editionMode = this._editionMode;\n\t var _data = this._data;\n\t\n\t if (_editionMode) {\n\t var _data$shear2 = _data.shear;\n\t var sx = _data$shear2.sx;\n\t var sy = _data$shear2.sy;\n\t\n\t this.endEditionMode();\n\t if (sx !== 0 || sy !== 0) {\n\t this.commit$();\n\t }\n\t }\n\t }\n\t};\n\t\n\tvar SelectAndTransformHandles = exports.SelectAndTransformHandles = _gear.Base.extend(FrameInteractionMixin, {\n\t\n\t // To overwrite in the config\n\t\n\t // Check FrameInteractionMixin plus...\n\t //\n\t // functions:\n\t // computeItemsFrame_(items) => frame\n\t // itemsEnabledTransforms(items) => { anisometricTransforms, translate, scale, rotate, shear, contentEdit }\n\t //\n\t // optional:\n\t // invalidatedItems(items) => boolean\n\t\n\t\n\t init: function (config) {\n\t this.handles = null;\n\t (0, _lodash.assign)(this, config);\n\t this.initFrameInteraction();\n\t },\n\t isHandle: function (event) {\n\t return this.handles ? this.handles.isHandle(event) : false;\n\t },\n\t isHandleEnabledAt: function (event) {\n\t return this.handles ? this.handles.isHandleEnabledAt(event) : false;\n\t },\n\t isPadHandle: function (event) {\n\t return this.handles ? this.handles.isPadHandle(event) : false;\n\t },\n\t\n\t\n\t get frame() {\n\t return this.handles ? this.handles._frame : null;\n\t },\n\t\n\t get visible() {\n\t return this.handles ? this.handles.visible : false;\n\t },\n\t\n\t down: function (event) {\n\t if (this.handles) {\n\t this.handles.down(event);\n\t }\n\t },\n\t mousemove: function (event) {\n\t if (this.handles) {\n\t this.handles.mousemove(event);\n\t }\n\t },\n\t move: function (event) {\n\t if (this.handles) {\n\t this.handles.move(event);\n\t }\n\t },\n\t up: function (event) {\n\t if (this.handles) {\n\t this.handles.up(event);\n\t }\n\t },\n\t draw: function (config) {\n\t if (this.handles) {\n\t this.handles.draw(config);\n\t }\n\t },\n\t create: function () {\n\t if (this.handles) {\n\t this.dispose();\n\t }\n\t this.handles = new _selectHandles.SelectHandles({ view: this.view });\n\t this.handles.on({ 'rotatestart': this.onRotateStart,\n\t 'rotatemove': this.onRotateMove,\n\t 'rotateend': this.onRotateEnd,\n\t 'scalestart': this.onScaleStart,\n\t 'scalemove': this.onScaleMove,\n\t 'scaleend': this.onScaleEnd,\n\t 'shearstart': this.onShearStart,\n\t 'shearmove': this.onShearMove,\n\t 'shearend': this.onShearEnd,\n\t 'translatestart': this.onTranslateStart,\n\t 'translatemove': this.onTranslateMove,\n\t 'translateend': this.onTranslateEnd,\n\t 'edit': this.onContentEdit }, this);\n\t },\n\t dispose: function () {\n\t if (this.handles) {\n\t this.handles.un(this);\n\t this.handles = null;\n\t }\n\t },\n\t onContentEdit: function () {\n\t var view = this.view;\n\t\n\t var items = this.editingItems(view);\n\t if (items.length === 1) {\n\t view.editContent(items[0]);\n\t }\n\t },\n\t invalidatedItems: function () /*items*/{\n\t return false;\n\t },\n\t update: function (frame) {\n\t var view = this.view;\n\t var handles = this.handles;\n\t\n\t\n\t if (!handles) {\n\t return;\n\t }\n\t\n\t if (frame) {\n\t handles.update(frame);\n\t } else {\n\t\n\t var items = this.editingItems(view);\n\t if (items.length > 0) {\n\t\n\t // If edition mode is on, the frame is already updated while transforming\n\t if (!this._editionMode && !this.invalidatedItems(items)) {\n\t\n\t var config = this.itemsEnabledTransforms(view, items);\n\t\n\t handles.anisometricTransformsEnabled = config.anisometricTransforms || false;\n\t\n\t handles.translateEnabled = config.translate || false;\n\t handles.scaleEnabled = config.scale || false;\n\t handles.rotateEnabled = config.rotate || false;\n\t handles.shearEnabled = config.shear || false;\n\t\n\t handles.editEnabled = config.contentEdit || false;\n\t\n\t handles.resize(this.computeItemsFrame_(items));\n\t handles.visible = true;\n\t }\n\t } else {\n\t handles.visible = false;\n\t }\n\t }\n\t\n\t this.view.batchRedraw('tools');\n\t }\n\t});\n\t\n\tvar FiguresHandles = exports.FiguresHandles = SelectAndTransformHandles.extend({\n\t getOriginalTransforms: function (figures) {\n\t return (0, _lodash.map)(figures, function (figure) {\n\t return {\n\t matrix22: figure.matrix22.clone(),\n\t pin: figure.pin.clone()\n\t };\n\t });\n\t },\n\t setOriginalTransforms: function (figures, originalTransforms) {\n\t (0, _lodash.forEach)(figures, function (figure, n) {\n\t var original = originalTransforms[n];\n\t figure.pin = original.pin.clone();\n\t figure.matrix22 = original.matrix22.clone();\n\t });\n\t },\n\t itemsEnabledTransforms: function (view, figures) {\n\t return {\n\t anisometricTransforms: view.are(figures, 'aspectRatioChangeable'),\n\t\n\t translate: view.are(figures, 'movable'),\n\t scale: view.are(figures, 'scalable'),\n\t rotate: view.are(figures, 'rotatable'),\n\t shear: view.are(figures, 'skewable'),\n\t\n\t contentEdit: this.itemsEnabledContentEdit(view, figures)\n\t };\n\t },\n\t itemsEnabledContentEdit: function (view, figures) {\n\t return view.are(figures, 'contentEditable');\n\t },\n\t\n\t\n\t transformItems: _cdl.Figures.transform,\n\t invalidatedItems: _cdl.Figures.invalidated,\n\t\n\t computeItemsFrame_: computeFiguresFrame_,\n\t\n\t snapToPoints: figuresSnapToPoints,\n\t\n\t transformWithFixedCenter: function (view, figures) {\n\t return !view.are(figures, 'movable');\n\t },\n\t scaleOriginalXY: function (view, items) {\n\t var figure = items[0];\n\t var matrix = figure._matrix22;\n\t var urm = _cdl.Matrix.m(_cdl.Matrix.rotate(-matrix.angle()), matrix);\n\t return { scaleX: urm.s00, scaleY: urm.s11 };\n\t }\n\t});\n\t\n\t// Attempt to avoid an extra Process call to measure ProxyGroups after\n\t// isometric scaling (pr)\n\t\n\tvar OptimizedFiguresHandles = exports.OptimizedFiguresHandles = FiguresHandles.extend({\n\t\n\t translateItems: _cdl.Figures.fastTranslate_, // forced, offset is already fixed\n\t\n\t getOriginalTransforms: function (figures) {\n\t return (0, _lodash.map)(figures, function (figure) {\n\t return {\n\t matrix22: figure.matrix22.clone(),\n\t pin: figure.pin.clone()\n\t // cache: figure._cache.clone() (pr)\n\t };\n\t });\n\t },\n\t setOriginalPositions: function (figures, originalTransforms) {\n\t (0, _lodash.forEach)(figures, function (figure, n) {\n\t var original = originalTransforms[n];\n\t figure.fastTranslate(original.pin.minus(figure.pin));\n\t });\n\t },\n\t\n\t\n\t // Do it by hand, avoid need to compute bounds for proxy groups\n\t doScaleMove: function (event) {\n\t var _data = this._data;\n\t\n\t\n\t var lastScale = _data.scale;\n\t\n\t var _data$scale2 = _data.scale = this.getOnScaleValue(event);\n\t\n\t var pin = _data$scale2.pin;\n\t var sx = _data$scale2.sx;\n\t var sy = _data$scale2.sy;\n\t var deg = _data$scale2.deg;\n\t\n\t\n\t var scaleFrom = _cdl.Matrix.scaleFrom(pin, sx, sy, deg);\n\t\n\t var view = this.view;\n\t var _editingItems = this._editingItems;\n\t\n\t this.updateHandlesFrame(scaleFrom);\n\t\n\t // Revert last change and re-apply absolute scaling, caches are kept\n\t _cdl.Figures.scaleFrom(_editingItems, lastScale.pin, 1 / lastScale.sx, 1 / lastScale.sy, lastScale.deg);\n\t _cdl.Figures.scaleFrom(_editingItems, pin, sx, sy, deg);\n\t\n\t view.preview$();\n\t }\n\t});\n\n/***/ },\n\n/***/ 155:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.SelectHandles = undefined;\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar distance2 = _cdl.Point.distance2;\n\t\n\t\n\tfunction maxSideLength2(frame) {\n\t var p0 = frame.p0;\n\t var p1 = frame.p1;\n\t var p2 = frame.p2;\n\t var p3 = frame.p3;\n\t\n\t return Math.max(distance2(p1, p0), distance2(p2, p1), distance2(p3, p2), distance2(p0, p3));\n\t}\n\t\n\tfunction minSideLength2(frame) {\n\t var p0 = frame.p0;\n\t var p1 = frame.p1;\n\t var p2 = frame.p2;\n\t var p3 = frame.p3;\n\t\n\t return Math.min(distance2(p1, p0), distance2(p2, p1), distance2(p3, p2), distance2(p0, p3));\n\t}\n\t\n\t/* default */var SelectHandles = exports.SelectHandles = _gear.Base.extend({\n\t\n\t Properties: {\n\t view: { type: 'View', def: null, owned: false },\n\t\n\t anisometricTransformsEnabled: { type: 'boolean', def: true },\n\t translateEnabled: { type: 'boolean', def: true },\n\t scaleEnabled: { type: 'boolean', def: true },\n\t rotateEnabled: { type: 'boolean', def: true },\n\t shearEnabled: { type: 'boolean', def: true },\n\t editEnabled: { type: 'boolean', def: false }\n\t },\n\t init: function () {\n\t this._visible = false;\n\t\n\t this.guideline_x = null;\n\t this.guideline_y = null;\n\t\n\t this.mouseDownPos = new _cdl.Point(0, 0);\n\t\n\t this._handles = {\n\t center: { mode: 'translate' },\n\t nw: { mode: 'scale' },\n\t ne: { mode: 'scale' },\n\t se: { mode: 'scale' },\n\t sw: { mode: 'scale' },\n\t n: { mode: 'scale', aniso: true },\n\t e: { mode: 'scale', aniso: true },\n\t s: { mode: 'scale', aniso: true },\n\t w: { mode: 'scale', aniso: true },\n\t rotate: { mode: 'rotate' },\n\t shearX: { mode: 'shear', aniso: true },\n\t shearY: { mode: 'shear', aniso: true },\n\t edit: { mode: 'edit' },\n\t none: { mode: 'none' }\n\t };\n\t\n\t var size = 0.1 * 96;\n\t\n\t var hs = this._handles;\n\t (0, _lodash.forEach)(hs, function (h, hn) {\n\t h.name = hn;h.size = size;h.cursor = 'pointer';h.disabled = false;\n\t });\n\t hs.rotate.size = hs.edit.size = size;\n\t\n\t hs.center.cursor = 'move';\n\t hs.none.cursor = 'default';\n\t\n\t (0, _lodash.forEach)(hs, function (h) {\n\t h.size2 = h.size * h.size + 1;\n\t });\n\t\n\t hs.nw.pin = hs.se;hs.ne.pin = hs.sw;\n\t hs.se.pin = hs.nw;hs.sw.pin = hs.ne;\n\t hs.n.pin = hs.s;hs.e.pin = hs.w;\n\t hs.s.pin = hs.n;hs.w.pin = hs.e;\n\t hs.shearX.pin = hs.n;hs.shearX.oppPin = hs.s;\n\t hs.shearY.pin = hs.w;hs.shearY.oppPin = hs.w;\n\t\n\t this._circlePadHandles = (0, _lodash.pick)(hs, 'rotate', 'nw', 'ne', 'se', 'sw', 'n', 'e', 's', 'w', 'shearX', 'shearY', 'edit');\n\t\n\t this._fillColor = '#22CC33';\n\t this._fillOverColor = '#006633';\n\t this._fillActiveColor = '#fb603d';\n\t this._strokeColor = '#006633';\n\t this._guidelineColor = '#993300';\n\t\n\t this.addEvents('rotatestart', 'rotatemove', 'rotateend', 'scalestart', 'scalemove', 'scaleend', 'translatestart', 'translatemove', 'translateend', 'shearstart', 'shearmove', 'shearend', 'edit');\n\t\n\t this._currentActive = this._handles.none;\n\t this._currentOver = this._handles.none;\n\t this.current = this._handles.none;\n\t this._setFrame(_cdl.Frame.fromBounds({ lx: 100, ly: 100, hx: 200, hy: 200 }));\n\t this._inited = false;\n\t this.enable(true);\n\t },\n\t _rotateHandlePosition: function (p1, p2, distance) {\n\t var de = p2.minus(p1).normalized();\n\t return p2.plus(de.scaled(this.view.viewDeltaToDoc(distance)));\n\t },\n\t _editHandlePosition: function (p1, p2, distance) {\n\t var de = p2.minus(p1).normalized();\n\t return p2.plus(de.scaled(this.view.viewDeltaToDoc(distance)));\n\t },\n\t _setFrame: function (frame) {\n\t this._frame = frame;\n\t this._inited = true;\n\t var interpolate = _cdl.Point.interpolate;\n\t var nw = this._frame.p0,\n\t ne = this._frame.p1,\n\t se = this._frame.p2,\n\t sw = this._frame.p3;\n\t var p = {\n\t nw: nw, ne: ne, se: se, sw: sw,\n\t n: interpolate(nw, ne, 0.5),\n\t e: interpolate(ne, se, 0.5),\n\t s: interpolate(se, sw, 0.5),\n\t w: interpolate(sw, nw, 0.5)\n\t };\n\t\n\t p.shearX = interpolate(p.s, se, 0.5);\n\t p.shearY = interpolate(se, p.e, 0.5);\n\t\n\t p.rotate = this._rotateHandlePosition(p.w, p.e, 20);\n\t p.edit = this._editHandlePosition(p.e, p.w, 20);\n\t\n\t var hs = this._handles;\n\t (0, _lodash.forOwn)(p, function (pos, hn) {\n\t hs[hn].pos = pos;\n\t });\n\t },\n\t\n\t\n\t // frame: The figure frame in the View coordinates.\n\t resize: function (frame) {\n\t var view = this.view;\n\t\n\t var frameMinSideLength2 = minSideLength2(frame),\n\t frameMaxSideLength2 = maxSideLength2(frame);\n\t\n\t var vtds = view.viewDeltaToDoc(1),\n\t vtds2 = vtds * vtds;\n\t\n\t var smallFrame = frameMinSideLength2 < 30 * 30 * vtds2 && frameMaxSideLength2 < 60 * 60 * vtds2;\n\t if (smallFrame) {\n\t var ex = 12 * vtds;\n\t // console.log(vtds);\n\t frame = frame.extended(ex, ex, ex, ex);\n\t this._anisometricTransformsEnabled = false;\n\t }\n\t\n\t var ps = view.viewDeltaToDoc(_view.padScaling);\n\t\n\t var hs = this._handles;\n\t var _frame = frame;\n\t var width = _frame.width;\n\t var height = _frame.height;\n\t\n\t var shearCut1 = 40 * ps,\n\t shearCut2 = 60 * ps,\n\t scaleCut1 = 20 * ps,\n\t scaleCut2 = 30 * ps;\n\t hs.shearX.disabled = height < shearCut1 || width < shearCut2;\n\t hs.shearY.disabled = height < shearCut2 || width < shearCut1;\n\t hs.e.disabled = width < scaleCut1 || height < scaleCut2;\n\t hs.w.disabled = width < scaleCut1 || height < scaleCut2;\n\t hs.n.disabled = width < scaleCut2 || height < scaleCut1;\n\t hs.s.disabled = width < scaleCut2 || height < scaleCut1;\n\t this.update(frame);\n\t },\n\t update: function (frame) {\n\t this._setFrame(frame);\n\t },\n\t enable: function (isEnabled) {\n\t if (isEnabled === undefined) {\n\t this.enabled = true;\n\t } else {\n\t this.enabled = isEnabled;\n\t }\n\t },\n\t isEnabled: function () {\n\t return this.enabled;\n\t },\n\t handleEnabled: function (c) {\n\t return c.mode === 'none' || this[c.mode + 'Enabled'] && (this._anisometricTransformsEnabled || !c.aniso);\n\t },\n\t down: function (_ref) {\n\t var event = _ref.event;\n\t var docPoint = _ref.docPoint;\n\t\n\t if (!this.isEnabled()) {\n\t return;\n\t }\n\t\n\t var c = this._handleFromEvent(event);\n\t\n\t if (!this.handleEnabled(c)) {\n\t return;\n\t }\n\t this.current = c;\n\t\n\t if (c.mode === 'none') {\n\t return;\n\t } else if (c.mode === 'edit') {\n\t this.fireEvent('edit', event);\n\t this.current = this._handles.none;\n\t return;\n\t }\n\t\n\t this._currentActive = this.current;\n\t\n\t this._currentOver = this._handles.none;\n\t\n\t this.mouseDownPos = docPoint;\n\t\n\t this.fireEvent(this.current.mode + 'start', event); // shear, rotate, scale, or translate\n\t },\n\t mousemove: function (_ref2) {\n\t var view = _ref2.view;\n\t var event = _ref2.event;\n\t\n\t\n\t if (view.is3D) {\n\t // Ignore feedback for 3D views\n\t return;\n\t }\n\t\n\t // Handle pad Over\n\t if (this._visible && this.current.mode === 'none') {\n\t var newOver = this._handleFromEvent(event);\n\t if (this._currentOver !== newOver) {\n\t\n\t this._currentOver = newOver;\n\t\n\t if (newOver.mode === 'none' || this.handleEnabled(newOver)) {\n\t view.cursor = newOver.cursor;\n\t }\n\t\n\t view.redraw('tools');\n\t\n\t event.stopPropagation();\n\t }\n\t }\n\t },\n\t\n\t\n\t move: (0, _view.fastThrottle)(function (_ref3) {\n\t var view = _ref3.view;\n\t var event = _ref3.event;\n\t\n\t\n\t if (this.current.mode === 'none') {\n\t return;\n\t }\n\t this.fireEvent(this.current.mode + 'move', event); // rotate, scale, select, shear or translate\n\t }, 12),\n\t\n\t up: function (_ref4) {\n\t var view = _ref4.view;\n\t var event = _ref4.event;\n\t\n\t var mode = this.current.mode;\n\t if (mode === 'none') {\n\t return;\n\t }\n\t\n\t this._currentActive = this._handles.none;\n\t\n\t this.fireEvent(mode + 'end', event); // rotate, scale, select, or translate\n\t\n\t this.current = this._handles.none;\n\t\n\t if (mode !== 'translate') {\n\t // avoid glitch\n\t view.cursor = this.current.cursor;\n\t }\n\t },\n\t shearDirFromHandle: function (h) {\n\t var hs = this._handles;\n\t switch (h.name) {\n\t case 'shearX':\n\t return hs.e.pos.minus(hs.w.pos).normalized();\n\t case 'shearY':\n\t return hs.n.pos.minus(hs.s.pos).normalized();\n\t }\n\t },\n\t scaleDirFromHandle: function (h) {\n\t var transform = arguments.length <= 1 || arguments[1] === undefined ? (0, _cdl.Matrix)() : arguments[1];\n\t\n\t return transform.apply(h.pos).minus(transform.apply(h.pin.pos)).normalized();\n\t },\n\t strokeFrame: function (context, transform) {\n\t var hs = this._handles;\n\t\n\t // rotate arm\n\t if (this.rotateEnabled) {\n\t (0, _gear.strokeSegment)(context, hs.e.pos, this._rotateHandlePosition(hs.w.pos, hs.e.pos, 20), transform);\n\t }\n\t\n\t // Center handle\n\t this._frame.draw(context, transform);\n\t context.stroke();\n\t },\n\t draw: function (_ref5) {\n\t var _this = this;\n\t\n\t var view = _ref5.view;\n\t var context = _ref5.context;\n\t var transform = _ref5.transform;\n\t\n\t\n\t if (this._inited && this._visible) {\n\t (function () {\n\t\n\t context.save();\n\t\n\t var hs = _this._handles;\n\t\n\t var textureScale = view.viewDeltaToTexture(1);\n\t\n\t (0, _gear.setLineDash)(context, (0, _lodash.map)([5, 2], function (v) {\n\t return textureScale * v;\n\t }));\n\t context.lineWidth = 2.4 * textureScale;\n\t var strokeStyle = context.strokeStyle = '#e3e3e3';\n\t _this.strokeFrame(context, transform);\n\t\n\t (0, _gear.setLineDash)(context, (0, _lodash.map)([0, 0.5, 4, 2.5], function (v) {\n\t return textureScale * v;\n\t }));\n\t context.lineWidth = 1.2 * textureScale;\n\t context.strokeStyle = '#388638';\n\t _this.strokeFrame(context, transform);\n\t\n\t context.strokeStyle = strokeStyle;\n\t context.lineWidth = 1 * textureScale; // [TODO]\n\t (0, _gear.setLineDash)(context, []);\n\t\n\t if (_this.scaleEnabled) {\n\t (0, _lodash.forEach)(['nw', 'ne', 'se', 'sw'], function (hn) {\n\t var h = hs[hn];\n\t _this._drawScaleHandle(context, h, transform, textureScale);\n\t context.stroke();\n\t context.fillStyle = _this.fillStyle(h);\n\t context.fill();\n\t });\n\t }\n\t\n\t if (_this.rotateEnabled) {\n\t // Rotate handle, raphael was taking a lot of time to rotate the handle\n\t var rotateHandle = hs.rotate;\n\t context.beginPath();\n\t\n\t // [TODO] Clean up, running to release\n\t rotateHandle.pos = _this._rotateHandlePosition(hs.w.pos, hs.e.pos, 28);\n\t\n\t var rotationPos = transform.apply(rotateHandle.pos);\n\t var rotationAngle = transform.apply(hs.e.pos).minus(transform.apply(hs.w.pos)).angle();\n\t var rotationPathTransform = _cdl.Matrix.concat(_cdl.Matrix.translate(rotationPos), _cdl.Matrix.scale(0.65 * textureScale), _cdl.Matrix.rotate(rotationAngle));\n\t canvasRotationPath(context, rotationPathTransform);\n\t context.stroke();\n\t context.fillStyle = _this.fillStyle(rotateHandle);\n\t context.fill();\n\t }\n\t\n\t if (_this.editEnabled) {\n\t var editHandle = hs.edit;\n\t context.beginPath();\n\t\n\t // [TODO] Clean up, running to release\n\t editHandle.pos = _this._editHandlePosition(hs.e.pos, hs.w.pos, 20);\n\t\n\t var editAngle = transform.apply(hs.e.pos).minus(transform.apply(hs.w.pos)).angle();\n\t canvasEditContentPath(context, _cdl.Matrix.concat(_cdl.Matrix.translate(transform.apply(editHandle.pos)), _cdl.Matrix.scale(0.6 * textureScale), _cdl.Matrix.rotate(editAngle), _cdl.Matrix.translate(-16, -16)));\n\t context.stroke();\n\t context.fillStyle = _this.fillStyle(editHandle);\n\t context.fill();\n\t }\n\t\n\t if (_this._anisometricTransformsEnabled) {\n\t\n\t if (_this.scaleEnabled) {\n\t (0, _lodash.forEach)(['n', 'e', 's', 'w'], function (hn) {\n\t var h = hs[hn];\n\t if (!h.disabled) {\n\t _this._drawScaleHandle(context, h, transform, textureScale);\n\t context.stroke();\n\t context.fillStyle = _this.fillStyle(h);\n\t context.fill();\n\t }\n\t });\n\t }\n\t\n\t if (_this.shearEnabled) {\n\t (0, _lodash.forEach)(['shearX', 'shearY'], function (hn) {\n\t var h = hs[hn];\n\t if (!h.disabled) {\n\t\n\t var tp = transform.apply(h.pos);\n\t context.beginPath();context.arc(tp.x, tp.y, 3.5 * textureScale, 0, 2 * Math.PI); // [TODO] dot\n\t context.stroke();\n\t context.fillStyle = _this.fillStyle(h);\n\t context.fill();\n\t }\n\t });\n\t }\n\t }\n\t\n\t // Guidelines\n\t\n\t var bounds = view.bounds;\n\t context.strokeStyle = _this._guidelineColor;\n\t context.lineWidth = 0.75;\n\t (0, _gear.setLineDash)(context, [3, 2]);\n\t\n\t var x = _this.guideline_x;\n\t if (x !== null) {\n\t (0, _gear.strokeSegment)(context, new _cdl.Point(x, bounds.ly), new _cdl.Point(x, bounds.hy), transform);\n\t }\n\t\n\t var y = _this.guideline_y;\n\t if (y !== null) {\n\t (0, _gear.strokeSegment)(context, new _cdl.Point(bounds.lx, y), new _cdl.Point(bounds.hx, y), transform);\n\t }\n\t\n\t context.restore();\n\t })();\n\t }\n\t },\n\t fillStyle: function (h) {\n\t return h === this._currentActive ? this._fillActiveColor : h === this._currentOver ? this._fillOverColor : this._fillColor;\n\t },\n\t isHandle: function (event) {\n\t return this._handleFromEvent(event).name !== 'none';\n\t },\n\t isPadHandle: function (event) {\n\t var n = this._handleFromEvent(event).name;\n\t return n !== 'none' && n !== 'center';\n\t },\n\t isHandleEnabledAt: function (event) {\n\t return this.handleEnabled(this._handleFromEvent(event));\n\t },\n\t _handleFromEvent: function (_ref6) {\n\t var event = _ref6.event;\n\t var docPoint = _ref6.docPoint;\n\t\n\t var view = this.view;\n\t var hs = this._handles;\n\t if (this._visible) {\n\t var point = docPoint;\n\t var ps = view.viewDeltaToDoc(_view.padScaling),\n\t ps2 = ps * ps; // [TODO]\n\t\n\t var padHandles = (0, _lodash.keys)(this._circlePadHandles);\n\t for (var k = 0, kEnd = padHandles.length; k < kEnd; ++k) {\n\t var hk = hs[padHandles[k]];\n\t if (this.handleEnabled(hk) && !hk.disabled && hk.pos.minus(point).norm2() < hk.size2 * ps2) {\n\t return hk;\n\t }\n\t }\n\t\n\t if (this._frame.contains(point)) {\n\t return hs.center;\n\t }\n\t }\n\t return hs.none;\n\t },\n\t\n\t\n\t // Returns center point in View coordinates.\n\t get center() {\n\t return this._frame.center;\n\t },\n\t\n\t get visible() {\n\t return this._visible;\n\t },\n\t set visible(visible_) {\n\t this._visible = visible_;\n\t },\n\t\n\t _drawScaleHandle: function (context, h, transform, textureScale) {\n\t var scale = 4.5;\n\t var dir = this.scaleDirFromHandle(h, transform);\n\t var dirp = dir.perpendicular(-scale * textureScale);\n\t var p = transform.apply(h.pos).plus(dir.scaled(0.3 * scale * textureScale));\n\t var t1 = p.plus(dir.scaled(scale * textureScale));\n\t var tb = p.plus(dir.scaled(-scale * textureScale));\n\t var t2 = tb.plus(dirp.scaled(-scale * textureScale));\n\t var t3 = tb.plus(dirp.scaled(scale * textureScale));\n\t\n\t context.beginPath();\n\t (0, _gear.moveTo)(context, t1);\n\t (0, _gear.lineTo)(context, t2);\n\t (0, _gear.lineTo)(context, t3);\n\t context.closePath();\n\t }\n\t});\n\t\n\texports.default = SelectHandles;\n\t\n\t// Handle paths, we need to find a better way, this is here since we moved\n\t// away from Raphael. It was unrolled thinking on performance but it is\n\t// probably not making us gain much\n\t\n\tvar moveToXY = function (c, t, x, y) {\n\t var p = t.apply_(x, y);\n\t c.moveTo(p.x, p.y);\n\t};\n\t\n\tvar lineToXY = function (c, t, x, y) {\n\t var p = t.apply_(x, y);\n\t c.lineTo(p.x, p.y);\n\t};\n\t\n\tvar bezierCurveTo = function (c, t, p0_x, p0_y, p1_x, p1_y, p2_x, p2_y) {\n\t var p0 = t.apply_(p0_x, p0_y),\n\t p1 = t.apply_(p1_x, p1_y),\n\t p2 = t.apply_(p2_x, p2_y);\n\t c.bezierCurveTo(p0.x, p0.y, p1.x, p1.y, p2.x, p2.y);\n\t};\n\t\n\tfunction canvasRotationPath(c, t) {\n\t moveToXY(c, t, -8.084, 0.500);\n\t bezierCurveTo(c, t, -8.075, 5.240, -4.240, 9.074, 0.499, 9.083);\n\t bezierCurveTo(c, t, 5.240, 9.074, 9.076, 5.239, 9.084, 0.500);\n\t bezierCurveTo(c, t, 9.076, -4.241, 5.240, -8.077, 0.499, -8.085);\n\t bezierCurveTo(c, t, -1.414, -8.085, -3.166, -7.456, -4.591, -6.399);\n\t bezierCurveTo(c, t, -4.591, -6.399, -2.809, -4.616, -2.809, -4.616);\n\t bezierCurveTo(c, t, -2.809, -4.616, -11.238, -2.360, -11.238, -2.360);\n\t bezierCurveTo(c, t, -11.238, -2.360, -8.978, -10.787, -8.978, -10.787);\n\t bezierCurveTo(c, t, -8.978, -10.787, -7.088, -8.897, -7.088, -8.897);\n\t bezierCurveTo(c, t, -5.016, -10.574, -2.371, -11.585, 0.499, -11.585);\n\t bezierCurveTo(c, t, 7.173, -11.582, 12.581, -6.174, 12.583, 0.500);\n\t bezierCurveTo(c, t, 12.581, 7.175, 7.173, 12.583, 0.500, 12.583);\n\t bezierCurveTo(c, t, -6.175, 12.583, -11.584, 7.175, -11.584, 0.500);\n\t bezierCurveTo(c, t, -11.584, 0.500, -8.084, 0.500, -8.084, 0.500);\n\t bezierCurveTo(c, t, -8.084, 0.500, -8.084, 0.500, -8.084, 0.500);\n\t c.closePath();\n\t}\n\t\n\tfunction canvasEditContentPath(c, t) {\n\t moveToXY(c, t, 15.067, 2.250);\n\t bezierCurveTo(c, t, 9.088, 2.250, 4.032, 6.160, 2.289, 11.559);\n\t lineToXY(c, t, 5.502, 11.559);\n\t bezierCurveTo(c, t, 7.104, 7.854, 10.773, 5.258, 15.067, 5.250);\n\t bezierCurveTo(c, t, 20.831, 5.260, 25.495, 9.924, 25.504, 15.687);\n\t bezierCurveTo(c, t, 25.495, 21.451, 20.831, 26.115, 15.067, 26.125);\n\t bezierCurveTo(c, t, 10.773, 26.118, 7.103, 23.520, 5.501, 19.814);\n\t lineToXY(c, t, 2.289, 19.814);\n\t bezierCurveTo(c, t, 4.033, 25.213, 9.088, 29.124, 15.068, 29.126);\n\t bezierCurveTo(c, t, 22.487, 29.124, 28.505, 23.110, 28.506, 15.688);\n\t bezierCurveTo(c, t, 28.504, 8.265, 22.486, 2.252, 15.067, 2.250);\n\t c.closePath();\n\t\n\t moveToXY(c, t, 10.918, 19.813);\n\t lineToXY(c, t, 18.068, 15.687);\n\t lineToXY(c, t, 10.918, 11.558);\n\t lineToXY(c, t, 10.918, 13.855);\n\t lineToXY(c, t, -0.057, 13.855);\n\t lineToXY(c, t, -0.057, 17.516);\n\t lineToXY(c, t, 10.918, 17.516);\n\t lineToXY(c, t, 10.918, 19.813);\n\t c.closePath();\n\t}\n\n/***/ },\n\n/***/ 156:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.DragSelectorHelper = undefined;\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tfunction stableLine(context, p0, p1) {\n\t context.beginPath();\n\t context.moveTo(p0.x, p0.y);\n\t context.lineTo(p1.x, p1.y);\n\t context.stroke();\n\t}\n\t\n\tvar DragSelectorHelper = exports.DragSelectorHelper = function (_ref, onEnd) {\n\t var docPoint = _ref.docPoint;\n\t var strokeColor = arguments.length <= 2 || arguments[2] === undefined ? '#006633' : arguments[2];\n\t\n\t this.onEnd = onEnd;\n\t this._pd = docPoint;\n\t this._fd = docPoint;\n\t this._sc = strokeColor;\n\t};\n\tDragSelectorHelper.prototype = {\n\t draw: function (_ref2) {\n\t var context = _ref2.context;\n\t var transform = _ref2.transform;\n\t\n\t\n\t var frame = _cdl.Frame.fromBounds(this.bounds).transformed(transform);\n\t\n\t // This is done piece by piece so the dash will be\n\t // more stable when dragging, the direction of each line\n\t // is important to make this trick work\n\t\n\t context.save();\n\t context.strokeStyle = this._sc;\n\t context.lineWidth = 1;\n\t (0, _gear.setLineDash)(context, [4, 3]);\n\t\n\t stableLine(context, frame.p3, frame.p0);\n\t stableLine(context, frame.p2, frame.p1);\n\t stableLine(context, frame.p3, frame.p2);\n\t stableLine(context, frame.p0, frame.p1);\n\t context.restore();\n\t },\n\t move: function (_ref3) {\n\t var view = _ref3.view;\n\t var docPoint = _ref3.docPoint;\n\t\n\t this._pd = docPoint;\n\t },\n\t end: function (event) {\n\t var onEnd = this.onEnd;\n\t\n\t onEnd(event, this.bounds);\n\t },\n\t\n\t\n\t get bounds() {\n\t return _cdl.Bounds.ofPoints([this._pd, this._fd]);\n\t }\n\t};\n\n/***/ },\n\n/***/ 157:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.ClipTool = undefined;\n\t\n\tvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar _selectTransform = __webpack_require__(154);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar dotProduct = _cdl.Point.dotProduct;\n\tvar substract = _cdl.Point.substract;\n\t\n\tvar _abs = Math.abs;\n\t\n\tvar ClipTool = exports.ClipTool = _view.Tool.extend({ typeName: 'ClipTool',\n\t\n\t type: 'Final',\n\t toolbarName: 'clipTool',\n\t allowKeyShortcuts: true,\n\t\n\t initTool: function (view, config) {\n\t var _this = this;\n\t\n\t (0, _lodash.assign)(this, config || {});\n\t this._data = null;\n\t\n\t this.handles = new _selectTransform.FiguresHandles({ view: view, tool: this,\n\t\n\t editingItems: function () {\n\t var figure = _this._selectedFigure;\n\t return figure ? [figure] : [];\n\t },\n\t\n\t itemsEnabledContentEdit: function () /* view, figures */{\n\t return false;\n\t },\n\t\n\t\n\t commit$: function () {},\n\t\n\t itemsEnabledTransforms: function (view, figures) {\n\t return {\n\t anisometricTransforms: view.are(figures, 'aspectRatioChangeable'),\n\t translate: view.are(figures, 'movable'),\n\t scale: view.are(figures, 'scalable'),\n\t rotate: false,\n\t shear: false,\n\t contentEdit: false\n\t };\n\t },\n\t getOnTranslateValue: function (_ref) {\n\t var view = _ref.view;\n\t var docPointRaw = _ref.docPointRaw;\n\t var cmdKey = _ref.cmdKey;\n\t var shiftKey = _ref.shiftKey;\n\t var handles = this.handles;\n\t var _data = this._data;\n\t var _downFrame = this._downFrame;\n\t\n\t\n\t var offset = substract(docPointRaw, handles.mouseDownPos);\n\t if (!offset.isZero()) {\n\t _data.started = true;\n\t }\n\t\n\t var snapTo = _data.snapTo;\n\t var alignmentLines = view._alignmentLines || { _visible: false, _snap: false };\n\t var forceSnap = shiftKey || cmdKey;\n\t var al_visible = forceSnap || alignmentLines._visible;\n\t var al_snap = forceSnap || alignmentLines._snap;\n\t var al_enabled = al_visible || al_snap;\n\t if (snapTo && al_enabled && _data.started) {\n\t (function () {\n\t // snap\n\t var snapSize = view.viewDeltaToDoc(14);\n\t\n\t var _downFrame$translated = _downFrame.translated(offset);\n\t\n\t var bounds = _downFrame$translated.bounds;\n\t\n\t var al_x = null,\n\t al_y = null,\n\t diff_x = Number.MAX_VALUE,\n\t diff_y = Number.MAX_VALUE;\n\t (0, _lodash.forEach)(snapTo, function (snap) {\n\t (0, _lodash.forEach)(snap, function (s, name) {\n\t\n\t var diff = substract(s, bounds[name]);\n\t\n\t var ax = _abs(diff.x);\n\t if (ax < snapSize && _abs(diff_x) > ax) {\n\t diff_x = diff.x;\n\t if (al_visible) {\n\t al_x = s.x;\n\t }\n\t }\n\t var ay = _abs(diff.y);\n\t if (ay < snapSize && _abs(diff_y) > ay) {\n\t diff_y = diff.y;\n\t if (al_visible) {\n\t al_y = s.y;\n\t }\n\t }\n\t });\n\t });\n\t\n\t handles.guideline_x = al_x;\n\t if (al_snap && diff_x !== Number.MAX_VALUE) {\n\t offset.x += diff_x;\n\t }\n\t\n\t handles.guideline_y = al_y;\n\t if (al_snap && diff_y !== Number.MAX_VALUE) {\n\t offset.y += diff_y;\n\t }\n\t })();\n\t } else {\n\t handles.guideline_x = null;\n\t handles.guideline_y = null;\n\t }\n\t\n\t //get the minimum and maximum translation, then fix the offset if it will go out of the parent frame\n\t var lParent = this.clipTool._selectedParent;\n\t var lParentFrame = lParent.globalFrame_();\n\t var lFigureFrame = _downFrame.translated(offset);\n\t var lTransform = lParent.rwPowerClipTransform();\n\t var lInvTransform = _cdl.Matrix.invert(lTransform);\n\t lParentFrame.transform(lInvTransform);\n\t lFigureFrame.transform(lInvTransform);\n\t\n\t var lDeltaP0 = substract(lParentFrame.p0, lFigureFrame.p0);\n\t if (lDeltaP0.x > 0) {\n\t var lP = new _cdl.Point(lDeltaP0.x, 0);\n\t lP.transform(lTransform);\n\t lP.translate(-lParent.pin.x, -lParent.pin.y);\n\t offset.x += lP.x;\n\t offset.y += lP.y;\n\t }\n\t if (lDeltaP0.y > 0) {\n\t var _lP = new _cdl.Point(0, lDeltaP0.y);\n\t _lP.transform(lTransform);\n\t _lP.translate(-lParent.pin.x, -lParent.pin.y);\n\t offset.x += _lP.x;\n\t offset.y += _lP.y;\n\t }\n\t\n\t var lDeltaP2 = substract(lParentFrame.p2, lFigureFrame.p2);\n\t if (lDeltaP2.x < 0) {\n\t var _lP2 = new _cdl.Point(lDeltaP2.x, 0);\n\t _lP2.transform(lTransform);\n\t _lP2.translate(-lParent.pin.x, -lParent.pin.y);\n\t offset.x += _lP2.x;\n\t offset.y += _lP2.y;\n\t }\n\t if (lDeltaP2.y < 0) {\n\t var _lP3 = new _cdl.Point(0, lDeltaP2.y);\n\t _lP3.transform(lTransform);\n\t _lP3.translate(-lParent.pin.x, -lParent.pin.y);\n\t offset.x += _lP3.x;\n\t offset.y += _lP3.y;\n\t }\n\t\n\t return view.asFastOffset(offset);\n\t },\n\t getOnScaleValue: function (_ref2) {\n\t var view = _ref2.view;\n\t var event = _ref2.event;\n\t var docPoint = _ref2.docPoint;\n\t var cmdKey = _ref2.cmdKey;\n\t var shiftKey = _ref2.shiftKey;\n\t var handles = this.handles;\n\t var _data = this._data;\n\t var _downFrame = this._downFrame;\n\t var current = handles.current;\n\t var mouseDownPos = handles.mouseDownPos;\n\t var fixedCenter = _data.fixedCenter;\n\t var center = _data.center;\n\t var scalePin = _data.scalePin;\n\t var scaleDir = _data.scaleDir;\n\t\n\t\n\t var pin = scalePin;\n\t\n\t var scale = (0, _selectTransform.computeScale)(pin, scaleDir, docPoint, mouseDownPos, view.viewDeltaToDoc(1));\n\t\n\t var name = current.name;\n\t\n\t scale.sy = name === 'ne' || name === 'nw' || name === 'sw' || name === 'se' ? scale.sx : 1;\n\t\n\t var lRetry = 0;\n\t var lFailedToScale = true;\n\t var lParent = this.clipTool._selectedParent;\n\t var lParentFrame = lParent.globalFrame_();\n\t var lTransform = lParent.rwPowerClipTransform();\n\t var lInvTransform = _cdl.Matrix.invert(lTransform);\n\t lParentFrame.transform(lInvTransform);\n\t\n\t var lOldScaleFrom = _cdl.Matrix.scaleFrom(scale.pin, _data.scale.sx, _data.scale.sy, scale.deg);\n\t var lOldFigureFrame = _downFrame.clone().transform(lOldScaleFrom);\n\t lOldFigureFrame.transform(lInvTransform);\n\t\n\t while (lRetry++ < 5 && lFailedToScale) {\n\t if (scale.sx <= 0 || scale.sy <= 0) {\n\t break;\n\t }\n\t lFailedToScale = false;\n\t\n\t var scaleFrom = _cdl.Matrix.scaleFrom(scale.pin, scale.sx, scale.sy, scale.deg);\n\t var lFigureFrame = _downFrame.clone().transform(scaleFrom);\n\t lFigureFrame.transform(lInvTransform);\n\t\n\t var lFigureDeltaP0 = substract(lFigureFrame.p0, lOldFigureFrame.p0);\n\t var lFigureDeltaP2 = substract(lFigureFrame.p2, lOldFigureFrame.p2);\n\t\n\t var lDeltaP0 = substract(lParentFrame.p0, lFigureFrame.p0);\n\t if (lDeltaP0.x > 0 && lFigureDeltaP0.x < 0) {\n\t scale.sx = (_data.scale.sx + scale.sx) / 2;\n\t scale.sy = (_data.scale.sy + scale.sy) / 2;\n\t lFailedToScale = true;\n\t }\n\t if (lDeltaP0.y > 0 && lFigureDeltaP0.y < 0) {\n\t scale.sx = (_data.scale.sx + scale.sx) / 2;\n\t scale.sy = (_data.scale.sy + scale.sy) / 2;\n\t lFailedToScale = true;\n\t }\n\t\n\t var lDeltaP2 = substract(lParentFrame.p2, lFigureFrame.p2);\n\t if (lDeltaP2.x < 0 && lFigureDeltaP2.x > 0) {\n\t scale.sx = (_data.scale.sx + scale.sx) / 2;\n\t scale.sy = (_data.scale.sy + scale.sy) / 2;\n\t lFailedToScale = true;\n\t }\n\t if (lDeltaP2.y < 0 && lFigureDeltaP2.y > 0) {\n\t scale.sx = (_data.scale.sx + scale.sx) / 2;\n\t scale.sy = (_data.scale.sy + scale.sy) / 2;\n\t lFailedToScale = true;\n\t }\n\t }\n\t if (lFailedToScale) {\n\t scale.sx = _data.scale.sx;\n\t scale.sy = _data.scale.sy;\n\t }\n\t return scale;\n\t }\n\t });\n\t\n\t this.handles.clipTool = this;\n\t },\n\t link: function (view) {\n\t view.on({ 'preview': this.on_preview }, this);\n\t\n\t this.handles.create();\n\t },\n\t unlink: function (view) {\n\t var parent = this._selectedParent;\n\t if (parent) {\n\t parent.endEditClip$();\n\t }\n\t view.un(this);\n\t this.handles.dispose();\n\t },\n\t dispose: function () {\n\t this.handles.dispose();\n\t this.callParent();\n\t },\n\t draw: function (config) {\n\t this.handles.draw(config);\n\t },\n\t on_keydown: function (_ref3) {\n\t var view = _ref3.view;\n\t var event = _ref3.event;\n\t var altKey = _ref3.altKey;\n\t var which = _ref3.which;\n\t\n\t if (!view._keyShortcuts) {\n\t return;\n\t }\n\t\n\t switch (which) {\n\t case 46:\n\t // 'Del'\n\t event.preventDefault();\n\t if (view.canRemove(this._selectedFigure)) {\n\t\n\t this._selectedParent.clippedBy = \"\";\n\t view.remove(this._selectedFigure);\n\t this._selectedFigure = null;\n\t this._selectedParent = null;\n\t this.handles.update();\n\t return view.commit$();\n\t }\n\t break;\n\t }\n\t },\n\t on_pointerdown: function (_ref4) {\n\t var _this2 = this;\n\t\n\t var view = _ref4.view;\n\t var event = _ref4.event;\n\t var isPrimary = _ref4.isPrimary;\n\t var docPoint = _ref4.docPoint;\n\t\n\t if (!isPrimary) {\n\t return;\n\t }\n\t\n\t var handles = this.handles;\n\t\n\t if (handles._editionMode) {\n\t //this._endMode(event);\n\t return;\n\t }\n\t\n\t var leftClick = event.which === 1;\n\t if (!leftClick) {\n\t return;\n\t }\n\t\n\t if (handles.isHandle(event)) {\n\t event.stopPropagation();\n\t handles.down(event);\n\t } else {\n\t (function () {\n\t var parent = _this2._selectedParent;\n\t if (parent) {\n\t parent.endEditClip$();\n\t _this2._selectedFigure = null;\n\t _this2._selectedParent = null;\n\t _this2.handles.update();\n\t //return;\n\t }\n\t\n\t parent = event.figure; // [EVENTS] view.figureAtPoint( docPoint ); // get top most figure at point\n\t if (parent) {\n\t (function () {\n\t // click directly on figure (not handle)?\n\t\n\t event.stopPropagation();\n\t\n\t var _parent$getClippedBy = parent.getClippedBy();\n\t\n\t var _parent$getClippedBy2 = _slicedToArray(_parent$getClippedBy, 2);\n\t\n\t var lClipContent = _parent$getClippedBy2[0];\n\t var lClipParent = _parent$getClippedBy2[1];\n\t\n\t\n\t if (lClipContent) {\n\t parent.beginEditClip$().then(function () {\n\t _this2._figureClicked(lClipContent, parent);\n\t return view.render$();\n\t }).then(function () {\n\t handles.down(event);\n\t });\n\t } else if (parent.isRaster) {\n\t // TODO We are restricting to rasters now, but clipping can be done on any figure\n\t var lId = _this2._computeUniqueId();\n\t parent.addClippingRect$(lId).then(function () {\n\t var _parent$getClippedBy3 = parent.getClippedBy();\n\t\n\t var _parent$getClippedBy4 = _slicedToArray(_parent$getClippedBy3, 2);\n\t\n\t lClipContent = _parent$getClippedBy4[0];\n\t lClipParent = _parent$getClippedBy4[1];\n\t\n\t _this2._figureClicked(lClipContent, parent);\n\t return view.render$();\n\t }).then(function () {\n\t handles.down(event);\n\t });\n\t }\n\t })();\n\t } else {\n\t // click on empty design area?\n\t\n\t _this2._selectedFigure = null;\n\t _this2._selectedParent = null;\n\t _this2.handles.update();\n\t }\n\t })();\n\t }\n\t },\n\t _computeUniqueId: function () {\n\t var lDoc = this.view.document;\n\t var lUniqueIdFound = false;\n\t var lUniqueId = void 0;\n\t for (var lUniqueIdx = 1; !lUniqueIdFound; lUniqueIdx++) {\n\t lUniqueId = \"c\" + lUniqueIdx;\n\t lUniqueIdFound = true;\n\t for (var i = 0; lUniqueIdFound && i < lDoc.figures.length; i++) {\n\t if (lDoc.figures[i].id == lUniqueId) {\n\t lUniqueIdFound = false;\n\t }\n\t }\n\t }\n\t return lUniqueId;\n\t },\n\t _figureClicked: function (figure, parent) {\n\t\n\t this.view.activeDocument = parent.document;\n\t\n\t this._selectedFigure = figure;\n\t this._selectedParent = parent;\n\t\n\t this.handles.update();\n\t this.view.render$();\n\t },\n\t on_mousemove: function (event) {\n\t this.handles.mousemove(event);\n\t },\n\t on_pointermove: function (event) {\n\t this.handles.move(event);\n\t },\n\t on_pointerup: function (event) {\n\t this.handles.up(event);\n\t },\n\t on_preview: function () {\n\t this.handles.update();\n\t },\n\t somethingToDraw: function () {\n\t return this.handles.visible;\n\t },\n\t needsToDrawFor: function (docIsland) {\n\t var frame = this.handles.frame;\n\t\n\t return !!frame && _cdl.Frame.areOverlapping(docIsland.frame_(), this.handles.frame);\n\t }\n\t});\n\t\n\t_view.Tool.Clip = ClipTool;\n\n/***/ },\n\n/***/ 158:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.PowerClipTool = undefined;\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar _selectTransform = __webpack_require__(154);\n\t\n\t// [TODO] We should be able to allow multi selection\n\t\n\tvar PowerClipTool = exports.PowerClipTool = _view.Tool.extend({ typeName: 'PowerClipTool',\n\t\n\t type: 'Final',\n\t toolbarName: 'powerClipTool',\n\t\n\t initTool: function (view, config) {\n\t var _this = this;\n\t\n\t (0, _lodash.assign)(this, config || {});\n\t this._data = null;\n\t\n\t this.handles = new _selectTransform.FiguresHandles({ view: view, tool: this,\n\t\n\t editingItems: function () {\n\t var figure = _this._selectedFigure;\n\t return figure ? [figure] : [];\n\t },\n\t\n\t computeItemsFrame_: function () {\n\t var figure = _this._selectedFigure;\n\t var parent = _this._selectedParent;\n\t var frame = figure.frame_();\n\t return frame.transformed(parent.rwPowerClipTransform());\n\t },\n\t\n\t itemsEnabledContentEdit: function () /* view, figures */{\n\t return false;\n\t },\n\t\n\t\n\t translateItems: function (items, offset) {\n\t _this.transformItems(items, _cdl.Matrix.translate(offset));\n\t },\n\t\n\t transformItems: this.transformItems.bind(this),\n\t\n\t commit$: function () {\n\t var parent = _this._selectedParent;\n\t if (!parent.usingPowerClipLink()) {\n\t parent.invalidate();\n\t }\n\t view.commit$();\n\t }\n\t });\n\t },\n\t transformItems: function (items, transform) {\n\t // Ignore items\n\t var figure = this._selectedFigure;\n\t var parent = this._selectedParent;\n\t\n\t var parentMatrix = parent.rwPowerClipTransform();\n\t\n\t // And transform again\n\t figure.transform(_cdl.Matrix.concat(parentMatrix.inverted(), transform, parentMatrix));\n\t\n\t // We only need to invalidate the view, this should be automatic when\n\t // calling figure.transform(..) [TODO][PC]\n\t if (parent.usingPowerClipLink()) {\n\t parent.invalidateView();\n\t }\n\t },\n\t link: function (view) {\n\t view.on({ 'preview': this.on_preview }, this);\n\t\n\t this.handles.create();\n\t },\n\t unlink: function (view) {\n\t view.un(this);\n\t this.handles.dispose();\n\t },\n\t dispose: function () {\n\t this.handles.dispose();\n\t this.callParent();\n\t },\n\t draw: function (config) {\n\t this.handles.draw(config);\n\t },\n\t on_pointerdown: function (_ref) {\n\t var _this2 = this;\n\t\n\t var view = _ref.view;\n\t var event = _ref.event;\n\t var isPrimary = _ref.isPrimary;\n\t var docPoint = _ref.docPoint;\n\t\n\t if (!isPrimary) {\n\t return;\n\t }\n\t\n\t var handles = this.handles;\n\t\n\t if (handles._editionMode) {\n\t this._endMode(event);\n\t return;\n\t }\n\t\n\t var leftClick = event.which === 1;\n\t if (!leftClick) {\n\t return;\n\t }\n\t\n\t if (handles.isHandle(event)) {\n\t event.stopPropagation();\n\t handles.down(event);\n\t } else {\n\t\n\t var parent = event.figure; // [EVENTS] view.figureAtPoint( docPoint ); // get top most figure at point\n\t if (parent) {\n\t (function () {\n\t // click directly on figure (not handle)?\n\t\n\t event.stopPropagation();\n\t\n\t // Find figure inside of powerclip to move\n\t var pcContent = parent.powerClipContents[0];\n\t var parentMatrixInv = parent.rwPowerClipTransform().inverted();\n\t var pcPoint = parentMatrixInv.apply(docPoint);\n\t if (pcContent) {\n\t\n\t // [TODO] This needs to be abstracted\n\t var figure = (0, _lodash.findLast)(pcContent.figures, function (f) {\n\t return f.containsPoint(pcPoint);\n\t });\n\t if (!figure) {\n\t // Try frame hit testing\n\t figure = (0, _lodash.findLast)(pcContent.figures, function (f) {\n\t return f._outputFigure && f.frame_().contains(pcPoint);\n\t });\n\t }\n\t\n\t if (figure) {\n\t _this2._figureClicked(figure, parent);\n\t\n\t view.render$().then(function () {\n\t handles.down(event);\n\t });\n\t }\n\t }\n\t })();\n\t } else {\n\t // click on empty design area?\n\t\n\t this._selectedFigure = null;\n\t this._selectedParent = null;\n\t this.handles.update();\n\t }\n\t }\n\t },\n\t _figureClicked: function (figure, parent) {\n\t\n\t this.view.activeDocument = parent.document;\n\t\n\t this._selectedFigure = figure;\n\t this._selectedParent = parent;\n\t\n\t this.handles.update();\n\t this.view.render$();\n\t },\n\t on_mousemove: function (event) {\n\t this.handles.mousemove(event);\n\t },\n\t on_pointermove: function (event) {\n\t this.handles.move(event);\n\t },\n\t on_pointerup: function (event) {\n\t this.handles.up(event);\n\t },\n\t on_preview: function () {\n\t this.handles.update();\n\t },\n\t somethingToDraw: function () {\n\t return this.handles.visible;\n\t },\n\t needsToDrawFor: function (docIsland) {\n\t var frame = this.handles.frame;\n\t\n\t return !!frame && _cdl.Frame.areOverlapping(docIsland.frame_(), this.handles.frame);\n\t }\n\t});\n\t\n\t_view.Tool.PowerClip = PowerClipTool;\n\n/***/ },\n\n/***/ 159:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.DrawEllipseTool = exports.DrawRectangleTool = exports.DrawCurveTool = exports.AddFigureTool = undefined;\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar AddFigureTool = exports.AddFigureTool = _view.Tool.extend({ typeName: 'AddFigureTool',\n\t\n\t type: 'Final',\n\t\n\t toolbarName: 'addFigureTool',\n\t\n\t useCursor: 'crosshair',\n\t\n\t initTool: function (view, figure) {\n\t this._figure = figure;\n\t return figure.update$();\n\t },\n\t link: function (view) {\n\t view.cursor = 'crosshair';\n\t },\n\t unlink: function (view) {\n\t view.cursor = 'default';\n\t },\n\t\n\t\n\t get brush() {\n\t return this._figure.brush;\n\t },\n\t set brush(brush_) {\n\t var figure = this._figure;\n\t if (figure.isShape) {\n\t (0, _lodash.forEach)(figure.polyregions, function (p) {\n\t return p.brush = brush_;\n\t });\n\t } else {\n\t figure.brush = brush_;\n\t }\n\t },\n\t\n\t get pen() {\n\t return this._figure.pen;\n\t },\n\t set pen(pen_) {\n\t var figure = this._figure;\n\t if (figure.isShape) {\n\t (0, _lodash.forEach)(figure.polyregions, function (p) {\n\t return p.pen = pen_;\n\t });\n\t } else {\n\t figure.pen = pen_;\n\t }\n\t },\n\t\n\t cleanUpFigure: function () /*figure*/{\n\t // ...\n\t },\n\t _commitFigure$: function () {\n\t var addedFigure = this._addedFigure;\n\t if (!addedFigure) {\n\t return (0, _gear.resolve)();\n\t }\n\t\n\t this.cleanUpFigure(addedFigure);\n\t this._addedFigure = null;\n\t return this.view.commit$();\n\t },\n\t _commit$: function () {\n\t return this._commitFigure$();\n\t },\n\t _cancel$: function (view) {\n\t view.remove(this._addedFigure);\n\t return view.preview$();\n\t },\n\t on_pointerdown: function (_ref) {\n\t var _this = this;\n\t\n\t var view = _ref.view;\n\t var event = _ref.event;\n\t var docPoint = _ref.docPoint;\n\t var which = _ref.which;\n\t\n\t var leftClick = which === 1;\n\t\n\t if (leftClick) {\n\t (function () {\n\t event.stopPropagation();\n\t\n\t _this._minSize = view.viewDeltaToDoc(10);\n\t\n\t _this._posDoc = docPoint;\n\t _this._downPosDoc = _this._posDoc.clone();\n\t\n\t var figure = _this._addedFigure = _this._figure.clone();\n\t figure.bounds$().then(function (bounds) {\n\t\n\t _this._initialWidth = view.viewDeltaToDoc(400);\n\t _this._initialHeight = _this._initialWidth * bounds.height / bounds.width;\n\t var initialBounds = _cdl.Bounds.ofPoints([_this._downPosDoc, _this._downPosDoc.plus_(_this._initialWidth, _this._initialHeight)]);\n\t\n\t figure.fit$(initialBounds).then(function () {\n\t\n\t _this._originalMatrix22 = figure.matrix22.clone();\n\t _this._originalPin = figure.pin.clone();\n\t\n\t view.add(figure);\n\t\n\t _this.on_pointermove(event);\n\t });\n\t });\n\t })();\n\t }\n\t },\n\t\n\t\n\t on_pointermove: (0, _view.fastThrottle)(function (_ref2) {\n\t var view = _ref2.view;\n\t var event = _ref2.event;\n\t var docPoint = _ref2.docPoint;\n\t var cmdKey = _ref2.cmdKey;\n\t\n\t var figure = this._addedFigure;\n\t if (!figure) {\n\t return;\n\t }\n\t\n\t this._posDoc = docPoint;\n\t\n\t this._ctrlKey = cmdKey;\n\t var t = this.computeTransform();\n\t\n\t figure.matrix22 = this._originalMatrix22.clone();\n\t figure.pin = this._originalPin.clone();\n\t\n\t figure.transform(t);\n\t\n\t view.preview$();\n\t }, 10),\n\t\n\t on_pointerup: function () {\n\t this._commitFigure$();\n\t },\n\t computeTransform: function () {\n\t var cp = this._posDoc,\n\t dp = this._downPosDoc;\n\t var bounds = _cdl.Bounds.ofPoints([cp, dp]);\n\t\n\t var minSize = this._minSize;\n\t\n\t var initialWidth = this._initialWidth,\n\t initialHeight = this._initialHeight;\n\t\n\t var nextWidth = bounds.width;\n\t var nextHeight = bounds.height;\n\t\n\t // Guard against to small figures\n\t if (nextWidth < minSize) {\n\t nextWidth = minSize;\n\t if (cp.x < dp.x) {\n\t bounds.lx = dp.x - minSize;\n\t }\n\t }\n\t if (nextHeight < minSize) {\n\t nextHeight = minSize;\n\t if (cp.y < dp.y) {\n\t bounds.ly = dp.y - minSize;\n\t }\n\t }\n\t\n\t var sx = nextWidth / initialWidth,\n\t sy = nextHeight / initialHeight;\n\t\n\t if (this._ctrlKey) {\n\t // Isometric locking\n\t if (sx > sy) {\n\t sy = sx;\n\t if (cp.y < dp.y) {\n\t bounds.ly = dp.y - initialHeight * sy;\n\t }\n\t } else {\n\t sx = sy;\n\t if (cp.x < dp.x) {\n\t bounds.lx = dp.x - initialWidth * sx;\n\t }\n\t }\n\t }\n\t\n\t var lx_ly = bounds.lx_ly;\n\t\n\t var transform = _cdl.Matrix.m(_cdl.Matrix.scaleFrom(lx_ly, sx, sy), _cdl.Matrix.translate(lx_ly.minus(dp)));\n\t return transform;\n\t }\n\t});\n\t\n\t_view.Tool.AddFigure = AddFigureTool;\n\t\n\tvar DrawCurveTool = exports.DrawCurveTool = AddFigureTool.extend({ typeName: 'DrawCurveTool',\n\t initTool: function (view, curve) {\n\t var config = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\t\n\t if (!config.pen) {\n\t config.pen = _view.Tool.defaultPen();\n\t }\n\t if (!config.brush) {\n\t config.brush = _view.Tool.defaultBrush();\n\t }\n\t var figure = _cdl.Shape.createFromCurve(curve, config);\n\t\n\t this.callParent(view, figure, config);\n\t },\n\t cleanUpFigure: function (figure) {\n\t // Apply transform to the polyregion\n\t var matrix = figure._computeMatrix();\n\t\n\t var polyregion = figure.polyregions[0];\n\t\n\t polyregion.transform(matrix);\n\t polyregion.renderFrame = null;\n\t polyregion.renderMatrix = null;\n\t\n\t var center = polyregion.bounds.center;\n\t figure.anchor = (0, _cdl.AbsoluteAnchor)(center.clone());\n\t figure.matrix22 = new _cdl.Matrix();\n\t figure.pin = center.clone();\n\t }\n\t});\n\t\n\tvar DrawRectangleTool = exports.DrawRectangleTool = DrawCurveTool.extend({ typeName: 'DrawRectangleTool',\n\t toolbarName: 'drawRectangleTool',\n\t initTool: function (view, config) {\n\t var curve = _cdl.Boundary.createRectangle((0, _lodash.assign)({ width: 500, height: 500 }, config));\n\t this.callParent(view, curve, config);\n\t }\n\t});\n\t_view.Tool.DrawRectangle = DrawRectangleTool;\n\t\n\tvar DrawEllipseTool = exports.DrawEllipseTool = DrawCurveTool.extend({ typeName: 'DrawEllipseTool',\n\t toolbarName: 'drawEllipseTool',\n\t initTool: function (view, config) {\n\t var curve = _cdl.Boundary.createEllipse((0, _lodash.assign)({ width: 500, height: 500 }, config));\n\t this.callParent(view, curve, config);\n\t }\n\t});\n\t_view.Tool.DrawEllipse = DrawEllipseTool;\n\n/***/ },\n\n/***/ 160:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.DrawShapeTool = exports.DrawTool = undefined;\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar redraw = function () {\n\t this.view.redraw('tools');\n\t};\n\t\n\tvar DrawTool = exports.DrawTool = _view.Tool.extend({ typeName: 'DrawTool',\n\t\n\t Properties: {\n\t pen: { type: 'Pen', def: _view.Tool.defaultPen(), onChange: redraw },\n\t brush: { type: 'Brush', def: _view.Tool.defaultBrush(), onChange: redraw }\n\t },\n\t\n\t target: 'document',\n\t\n\t type: 'Final',\n\t toolbarName: 'drawTool',\n\t\n\t initTool: function (view) {\n\t var config = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\t\n\t this._closedConfig = config.closed !== undefined ? config.closed : false;\n\t this._flushShape();\n\t this._flushPath();\n\t this.closeDistance = 0.1 * 96;\n\t this.editingDistance = 0.05 * 96;\n\t },\n\t _flushShape: function () {\n\t this._paths = [];\n\t this._closed = this._closedConfig;\n\t },\n\t _flushPath: function () {\n\t this.toolhelp('Click to begin path', 'Enter or Double Click to commit, Esc to cancel');\n\t this._nextPiece = null;\n\t this._pieces = [];\n\t this._redoPieces = [];\n\t this._editingPiece = null;\n\t this._initialPoint = null;\n\t },\n\t on_nextpiece: function () {\n\t this.toolhelp('Click to add new point', 'Click and hold to add a curve', 'Click on the initial point to close', 'Double Click to leave open');\n\t },\n\t draw: function (_ref) {\n\t var view = _ref.view;\n\t var context = _ref.context;\n\t var transform = _ref.transform;\n\t\n\t\n\t // Draw semitransparent mask\n\t // context.fillStyle = 'rgba(255,255,255,0.75)';\n\t // view.fill(context);\n\t\n\t var pieces = this._pieces.slice();\n\t var pen = this._pen,\n\t brush = this._brush;\n\t\n\t var lastWasClosed = false;\n\t\n\t var drawPath = function (closed) {\n\t pen.setupContext(context, transform);\n\t context.stroke();\n\t\n\t if (closed) {\n\t if (brush._type === 'Brush') {\n\t context.fillStyle = brush._color.rgba;\n\t } else {\n\t // Draw temporary semitransparent mask\n\t // Brush is applied to the Polyregion in commitChanges$()\n\t // This way all brush types are supported\n\t context.fillStyle = 'rgba(255,255,255,0.5)';\n\t }\n\t\n\t context.fill('evenodd');\n\t }\n\t\n\t context.beginPath();\n\t };\n\t\n\t context.beginPath();\n\t var paths = 0;\n\t\n\t for (var k = 0, kEnd = this._paths.length; k < kEnd; ++k) {\n\t var paths_k = this._paths[k];\n\t var closed = paths_k.closed;\n\t\n\t\n\t if (closed !== lastWasClosed && paths > 0) {\n\t drawPath(lastWasClosed);\n\t paths = 0;\n\t }\n\t\n\t paths_k.draw(context, transform);\n\t paths++;\n\t lastWasClosed = closed;\n\t }\n\t\n\t var dotSize = view.viewDeltaToTexture(3);\n\t\n\t if (this._drawing) {\n\t\n\t var _closed = this._closed || this._pathIsClosed();\n\t\n\t if (_closed !== lastWasClosed && paths > 0) {\n\t drawPath(lastWasClosed);\n\t paths = 0;\n\t }\n\t\n\t var ep = this._editingPiece;\n\t if (ep) {\n\t pieces.push(ep);\n\t } else if (this._nextPiece && !_view.usingTouch) {\n\t pieces.push(this._nextPiece);\n\t }\n\t if (pieces.length > 0) {\n\t var curve = new _cdl.Curve(pieces, _closed); // Always false to show feedback on the missing part\n\t curve.draw(context, transform);\n\t paths++;\n\t\n\t drawPath(_closed);\n\t paths = 0;\n\t\n\t context.lineWidth = view.viewDeltaToTexture(1);\n\t context.strokeStyle = 'rgba(10,150,50,1.0)';\n\t\n\t if (ep && ep instanceof _cdl.Cubic) {\n\t context.beginPath();\n\t var c1 = ep.P2,\n\t c2 = ep.P3.plus(ep.P3.minus(ep.P2));\n\t (0, _gear.strokeSegment)(context, c1, c2, transform);\n\t context.fillStyle = 'rgba(10,100,30,1.0)';\n\t (0, _gear.dot)(context, c1, dotSize, transform);\n\t (0, _gear.dot)(context, c2, dotSize, transform);\n\t } else if (this._lastPieceWasModified && this._pieces.length > 0) {\n\t var piece = (0, _lodash.last)(this._pieces);\n\t if (piece instanceof _cdl.Cubic) {\n\t context.beginPath();\n\t var _c = piece.P2,\n\t _c2 = piece.P3.plus(piece.P3.minus(piece.P2));\n\t (0, _gear.strokeSegment)(context, _c, _c2, transform);\n\t context.stroke();\n\t }\n\t }\n\t }\n\t }\n\t\n\t if (paths > 0) {\n\t drawPath(lastWasClosed);\n\t }\n\t\n\t if (this._drawing) {\n\t var l = this._nextPiece ? this._nextPiece.P0 : this._pieces.length > 0 ? (0, _lodash.last)(this._pieces).last() : null;\n\t if (l) {\n\t // Draw a dot in the last commited point, because we do not have pointer move feedback in touch\n\t context.beginPath();\n\t context.fillStyle = 'rgba(240,60,40,1.0)';\n\t (0, _gear.dot)(context, l, dotSize, transform);\n\t }\n\t }\n\t },\n\t on_pointerdown: function (_ref2) {\n\t var event = _ref2.event;\n\t var isPrimary = _ref2.isPrimary;\n\t var which = _ref2.which;\n\t var docPoint = _ref2.docPoint;\n\t var viewPoint = _ref2.viewPoint;\n\t\n\t\n\t if (!isPrimary) {\n\t return; // ignore multitouch\n\t }\n\t\n\t var leftClick = which === 1;\n\t if (leftClick) {\n\t\n\t event.stopPropagation();\n\t\n\t this._downPos = viewPoint;\n\t\n\t this._drawing = true;\n\t this.on_nextpiece();\n\t\n\t this._redoNextPiece = null;\n\t this._redoPieces = [];\n\t var np = docPoint;\n\t this._currentPoint = np;\n\t\n\t var nextPiece = this._nextPiece;\n\t if (nextPiece) {\n\t if (nextPiece.P2) {\n\t nextPiece.P2 = np.clone();\n\t }\n\t nextPiece.last(np.clone());\n\t }\n\t\n\t if (this._pushPathIfClosed()) {\n\t return;\n\t }\n\t\n\t if (!this._initialPoint) {\n\t this._initialPoint = np.clone();\n\t }\n\t\n\t this._editingPiece = this._nextPiece;\n\t\n\t this._nextPiece = new _cdl.Segment(np, np);\n\t\n\t if (this._pieces.length > 0 && np.isEqual((0, _lodash.last)(this._pieces).P0)) {\n\t this._nextPiece = null;\n\t this._pushPath(this._closed);\n\t }\n\t\n\t this.redraw();\n\t }\n\t var rightClick = event.which === 3;\n\t if (rightClick) {\n\t event.stopPropagation();\n\t this.commit$();\n\t }\n\t },\n\t on_mousemove: function (event) {\n\t this.on_pointermove(event);\n\t event.stopPropagation();\n\t },\n\t on_pointermove: function (_ref3) {\n\t var event = _ref3.event;\n\t var view = _ref3.view;\n\t var isPrimary = _ref3.isPrimary;\n\t\n\t if (!isPrimary) {\n\t return; // ignore multitouch\n\t }\n\t if (!this._drawing) {\n\t return;\n\t }\n\t\n\t var editingDistance = this.editingDistance * _view.padScaling;\n\t\n\t var np = event.docPoint;\n\t this._currentPoint = np;\n\t\n\t var pieces = this._pieces,\n\t nextPiece = this._nextPiece;\n\t\n\t if (!nextPiece && pieces.length > 0) {\n\t var P0 = (0, _lodash.last)(pieces).last();\n\t nextPiece = this._nextPiece = this._lastPieceWasModified ? new _cdl.Cubic(P0, np, np, np) : new _cdl.Segment(P0, np);\n\t this._redoNextPiece = null;\n\t }\n\t\n\t var editingPiece = this._editingPiece;\n\t\n\t if (editingPiece && !this._downPos.isNear(event.viewPoint, editingDistance)) {\n\t if (editingPiece instanceof _cdl.Segment) {\n\t this.toolhelp('Hold and move to change control point');\n\t editingPiece = this._editingPiece = _cdl.Cubic.fromSegment(editingPiece.P0, editingPiece.P1);\n\t editingPiece.P1 = editingPiece.P0.clone();\n\t }\n\t editingPiece.P2 = editingPiece.P3.plus(editingPiece.P3.minus(np));\n\t this._editingPieceModified = true;\n\t } else if (nextPiece) {\n\t if (nextPiece.P2) {\n\t nextPiece.P2 = np.clone();\n\t }\n\t nextPiece.last(np.clone());\n\t }\n\t\n\t this.redraw();\n\t },\n\t on_pointerup: function (_ref4) {\n\t var event = _ref4.event;\n\t var isPrimary = _ref4.isPrimary;\n\t\n\t if (!isPrimary) {\n\t return; // ignore multitouch\n\t }\n\t if (!this._drawing) {\n\t return;\n\t }\n\t\n\t var editingDistance = this.editingDistance * _view.padScaling;\n\t\n\t var editingPiece = this._editingPiece,\n\t pieces = this._pieces;\n\t\n\t if (editingPiece && !editingPiece.P0.isNear(editingPiece.last(), editingDistance)) {\n\t\n\t pieces.push(editingPiece);\n\t\n\t if (this._editingPieceModified) {\n\t var lastPiece = (0, _lodash.last)(pieces);\n\t var P0 = lastPiece.P3;\n\t var PC = P0.plus(P0.minus(lastPiece.P2));\n\t this._nextPiece = new _cdl.Cubic(P0, PC.clone(), PC.clone(), PC.clone());\n\t this.on_nextpiece();\n\t }\n\t }\n\t this._editingPiece = null;\n\t this._lastPieceWasModified = this._editingPieceModified;\n\t this._editingPieceModified = false;\n\t this._downPos = null;\n\t this.redraw();\n\t },\n\t on_dblclick: function () {\n\t this.commit$();\n\t },\n\t undo: function () {\n\t if (!this._drawing) {\n\t if (this._paths.length > 0) {\n\t this._redoPaths.push(this._paths.pop());\n\t }\n\t this.view.redraw('tools');\n\t } else {\n\t if (this._nextPiece) {\n\t this._redoNextPiece = this._nextPiece;\n\t this._nextPiece = null;\n\t } else if (this._pieces.length > 0) {\n\t this._redoPieces.push(this._pieces.pop());\n\t }\n\t this.view.redraw('tools');\n\t }\n\t },\n\t redo: function () {\n\t if (!this._drawing) {\n\t if (this._redoPaths.length > 0) {\n\t this._paths.push(this._redoPaths.pop());\n\t }\n\t this.view.redraw('tools');\n\t } else {\n\t if (this._redoPieces.length > 0) {\n\t var rp = this._redoPieces.pop();\n\t this._pieces.push(rp);\n\t this._nextPiece = null;\n\t } else if (this._redoNextPiece) {\n\t this._nextPiece = this._redoNextPiece;\n\t this._redotNextPiece = null;\n\t }\n\t this.view.redraw('tools');\n\t }\n\t },\n\t _pathIsClosed: function () {\n\t var view = this.view;\n\t\n\t\n\t var ip = this._initialPoint,\n\t cp = this._currentPoint;\n\t return ip && cp && this._pieces.length > 0 && ip.isNear(cp, view.viewDeltaToDoc(this.closeDistance) * _view.padScaling);\n\t },\n\t _pushPathIfClosed: function () {\n\t if (this._pathIsClosed()) {\n\t if (this._nextPiece) {\n\t this._nextPiece.last(this._initialPoint);\n\t this._pieces.push(this._nextPiece);\n\t this._nextPiece = this._editingPiece = null;\n\t }\n\t var closed = true;\n\t this._pushPath(closed);\n\t return true;\n\t }\n\t return false;\n\t },\n\t _pushPath: function (closed) {\n\t if (closed === undefined) {\n\t if (this._pushPathIfClosed()) {\n\t return (0, _gear.resolve)();\n\t } else {\n\t closed = false;\n\t }\n\t }\n\t\n\t var pieces = this._pieces;\n\t\n\t var nextPiece = this._nextPiece;\n\t if (nextPiece && !nextPiece.P0.isEqual(nextPiece.last())) {\n\t pieces.push(nextPiece.clone());\n\t }\n\t\n\t this._pieces = [];\n\t if (pieces.length >= 1) {\n\t if (closed && !pieces[0].P0.isEqual((0, _lodash.last)(pieces).last())) {\n\t pieces.push(new _cdl.Segment(nextPiece.last(), pieces[0].P0));\n\t }\n\t\n\t var curve = _cdl.Curve.fromNonTiedPieces(pieces, closed);\n\t this._paths.push(curve);\n\t this.view.redraw('tools');\n\t }\n\t\n\t this._flushPath();\n\t\n\t // Force a commit after each path\n\t return this.commitChanges$();\n\t },\n\t _cancel$: function () {\n\t // Nothing to do...\n\t },\n\t commit$: function () {\n\t if (this._drawing && this._pieces.length > 0) {\n\t return this._pushPath(this._closed);\n\t } else {\n\t return this.callParent();\n\t }\n\t },\n\t _commit$: function () {\n\t this.commitChanges$();\n\t },\n\t commitChanges$: function () {\n\t var view = this.view;\n\t if (this._paths.length === 0) {\n\t return;\n\t }\n\t var pen = this._pen,\n\t brush = this._brush;\n\t\n\t var polyregions = [];\n\t var pushPolyregion = function (regions, closed) {\n\t var polyregion = new _cdl.Polyregion({ regions: regions, pen: pen, fillMode: 'Alternate' });\n\t if (closed) {\n\t polyregion.brush = brush;\n\t }\n\t polyregions.push(polyregion);\n\t };\n\t\n\t var regions = [];\n\t var lastWasClosed = false;\n\t\n\t for (var k = 0, kEnd = this._paths.length; k < kEnd; ++k) {\n\t var paths_k = this._paths[k];\n\t var closed = paths_k.closed;\n\t if (closed !== lastWasClosed && regions.length > 0) {\n\t pushPolyregion(regions, lastWasClosed);\n\t regions = [];\n\t }\n\t var region = new _cdl.Region([paths_k]);\n\t regions.push(region);\n\t lastWasClosed = closed;\n\t }\n\t\n\t if (regions.length > 0) {\n\t pushPolyregion(regions, lastWasClosed);\n\t }\n\t var anchor = _cdl.Bounds.ofThings(polyregions).center;\n\t view.add((0, _cdl.Shape)({ polyregions: polyregions,\n\t anchor: (0, _cdl.AbsoluteAnchor)(anchor),\n\t pin: anchor.clone() }));\n\t\n\t this._flushPath();\n\t this._flushShape();\n\t view.keepSelection();\n\t return view.commit$();\n\t }\n\t});\n\t_view.Tool.Draw = DrawTool;\n\t\n\tvar DrawShapeTool = exports.DrawShapeTool = DrawTool.extend({ typeName: 'DrawShapeTool',\n\t init: function () {\n\t var config = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\t\n\t config.closed = true;\n\t this.callParent(config);\n\t }\n\t});\n\t_view.Tool.DrawShape = DrawShapeTool;\n\n/***/ },\n\n/***/ 161:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.FreeDrawTool = undefined;\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar distance2 = _cdl.Point.distance2;\n\tvar FreeDrawTool = exports.FreeDrawTool = _view.Tool.extend({ typeName: 'FreeDrawTool',\n\t\n\t Properties: {\n\t pen: { type: 'Pen', def: _view.Tool.defaultPen(), onChange: function () {\n\t this.redraw();\n\t }\n\t },\n\t brush: { type: 'Brush', def: _view.Tool.defaultBrush(), onChange: function () {\n\t this.redraw();\n\t }\n\t },\n\t detectCorners: { type: 'boolean', def: true }\n\t },\n\t\n\t type: 'Final',\n\t toolbarName: 'freeDrawTool',\n\t\n\t Modes: { 0: 'Free', 1: 'Rectangle', 2: 'Circle' },\n\t\n\t initTool: function (view) {\n\t var config = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\t\n\t this._bind('switchCorners');\n\t\n\t this._closedConfig = config.closed !== undefined ? config.closed : false;\n\t this.flushShape();\n\t this._mode = 0; // 'Free'\n\t this.closeDistance = 0.1 * 96;\n\t this.flushCurrentPath();\n\t },\n\t flushShape: function () {\n\t this._closed = this._closedConfig;\n\t this._paths = [];\n\t this._redoPaths = [];\n\t },\n\t switchCorners: function () {\n\t this._detectCorners = !this._detectCorners;\n\t // this.updateActions();\n\t },\n\t draw: function (_ref) {\n\t var view = _ref.view;\n\t var context = _ref.context;\n\t var transform = _ref.transform;\n\t\n\t\n\t // Draw semitransparent mask\n\t //context.fillStyle = 'rgba(255,255,255,0.75)';\n\t //fillContext(context);\n\t\n\t this._pen.setupContext(context, transform);\n\t\n\t var brush = this._brush,\n\t solidBrush = brush._type === 'Brush';\n\t\n\t if (solidBrush) {\n\t context.fillStyle = brush._color.rgba;\n\t } else {\n\t // Draw temporary semitransparent mask\n\t // Brush is applied to the Polyregion in commitChanges$()\n\t // This way all brush types are supported\n\t context.fillStyle = 'rgba(255,255,255,0.5)';\n\t }\n\t\n\t context.beginPath();\n\t\n\t var paths = (0, _gear.clone)(this._paths);\n\t\n\t if (this.inMode('Free')) {\n\t var currentPoints = (0, _gear.clone)(this._points);\n\t if (this._nextPoint) {\n\t currentPoints.push(this._nextPoint);\n\t }\n\t if (currentPoints.length > 1) {\n\t paths.push(currentPoints);\n\t }\n\t } else if (this._drawing) {\n\t var stampPath = this.stampPath();\n\t if (stampPath) {\n\t paths.push(stampPath);\n\t }\n\t }\n\t\n\t var lastIsClosed = false;\n\t\n\t for (var k = 0, kEnd = paths.length; k < kEnd; ++k) {\n\t\n\t var paths_k = paths[k];\n\t\n\t var isCurve = paths_k instanceof _cdl.Curve;\n\t\n\t var closed = isCurve || this._closed || paths_k[0].isNear((0, _lodash.last)(paths_k), this.closeDistance / transform.scaleFactor() * _view.padScaling);\n\t\n\t if (!closed && lastIsClosed) {\n\t context.stroke();\n\t if (solidBrush) {\n\t context.fill('evenodd');\n\t }\n\t context.beginPath();\n\t }\n\t\n\t if (paths_k instanceof _cdl.Curve) {\n\t paths_k.draw(context, transform);\n\t } else {\n\t var path = (0, _lodash.map)(paths_k, function (p) {\n\t return transform.apply(p);\n\t });\n\t var length = path.length - 1;\n\t\n\t path.unshift(path[0]);\n\t path.push(path[path.length - 1]);\n\t\n\t if (length <= 0) {\n\t return;\n\t }\n\t for (var n = 0; n < length; n++) {\n\t var p1 = path[n],\n\t p2 = path[n + 1],\n\t p3 = path[n + 2],\n\t p4 = path[n + 3];\n\t\n\t if (n === 0) {\n\t context.moveTo(p2.x, p2.y);\n\t }\n\t if (!(0, _gear.areEqual)(p2, p3)) {\n\t context.bezierCurveTo(p2.x + (p3.x - p1.x) / 6, p2.y + (p3.y - p1.y) / 6, p3.x + (p2.x - p4.x) / 6, p3.y + (p2.y - p4.y) / 6, p3.x, p3.y);\n\t }\n\t }\n\t\n\t if (closed) {\n\t context.closePath();\n\t } else {\n\t context.stroke();\n\t context.beginPath();\n\t }\n\t lastIsClosed = closed;\n\t }\n\t }\n\t if (lastIsClosed) {\n\t context.stroke();\n\t if (solidBrush) {\n\t context.fill('evenodd');\n\t }\n\t context.beginPath();\n\t }\n\t },\n\t switchMode: function () {\n\t this._mode++;\n\t if (this._mode >= (0, _lodash.size)(this.Modes)) {\n\t this._mode = 0;\n\t }\n\t this.redraw();\n\t },\n\t inMode: function (m) {\n\t return this.Modes[this._mode] === m;\n\t },\n\t stampBounds: function () {\n\t return _cdl.Bounds.ofPoints([this._pointDown, this._pointTo]);\n\t },\n\t stampPath: function () {\n\t if ((0, _gear.areEqual)(this._pointDown, this._pointTo)) {\n\t return null;\n\t }\n\t var bounds = this.stampBounds();\n\t if (this.inMode('Rectangle')) {\n\t return _cdl.Boundary.createRectangle(bounds);\n\t } else if (this.inMode('Circle')) {\n\t return _cdl.Boundary.createEllipse(bounds);\n\t }\n\t return null;\n\t },\n\t on_pointerdown: function (_ref2) {\n\t var event = _ref2.event;\n\t var isPrimary = _ref2.isPrimary;\n\t var which = _ref2.which;\n\t var docPoint = _ref2.docPoint;\n\t\n\t if (isPrimary === false) {\n\t return; // ignore multitouch\n\t }\n\t var t = (0, _lodash.now)();\n\t if (t - this._lastTime < 500) {\n\t this.commit$();\n\t return;\n\t }\n\t\n\t event.stopPropagation();\n\t\n\t this._lastTime = t;\n\t\n\t var leftClick = which === 1;\n\t if (leftClick) {\n\t this.toolhelp('Hold and move to draw path', 'Release near initial point to close');\n\t this._drawing = true;\n\t var np = docPoint;\n\t\n\t if (this.inMode('Free')) {\n\t\n\t this._points.push(np);\n\t this._lastTime = t;\n\t\n\t this._pointsR.push(np);\n\t this._lastTimeR = t;\n\t } else {\n\t this._pointDown = np;\n\t this._pointTo = np;\n\t }\n\t\n\t this.redraw();\n\t this._redoPaths = [];\n\t }\n\t },\n\t on_pointermove: function (_ref3) {\n\t var event = _ref3.event;\n\t var view = _ref3.view;\n\t var isPrimary = _ref3.isPrimary;\n\t var cmdKey = _ref3.cmdKey;\n\t\n\t if (!isPrimary) {\n\t return; // ignore multitouch\n\t }\n\t\n\t var ctrl = this._ctrl = cmdKey;\n\t if (this._drawing) {\n\t var points = this._points,\n\t pointsR = this._pointsR;\n\t\n\t var t = (0, _lodash.now)();\n\t var docPoint = event.docPoint;\n\t\n\t\n\t if (this.inMode('Free')) {\n\t\n\t if (this._detectCorners) {\n\t\n\t if (t - this._lastTimeR > 25) {\n\t\n\t var lp = (0, _lodash.last)(pointsR);\n\t\n\t var deltaVL = view.viewDeltaToDoc(3);\n\t\n\t if (distance2(docPoint, lp) > deltaVL * deltaVL) {\n\t var lp3TimeR = this._lastTimeRPrevPrev;\n\t\n\t pointsR.push(docPoint);\n\t\n\t this._lastTimeRPrevPrev = this._lastTimeRPrev;\n\t this._lastTimeRPrev = this._lastTimeR;\n\t this._lastTimeR = t;\n\t\n\t var delta = view.viewDeltaToDoc(14),\n\t delta2 = delta * delta;\n\t\n\t var pointsR_length = pointsR.length;\n\t if (pointsR_length > 7) {\n\t\n\t var lp0 = pointsR[pointsR_length - 1];\n\t var lp1 = pointsR[pointsR_length - 2];\n\t var lp2 = pointsR[pointsR_length - 3];\n\t var lp3 = pointsR[pointsR_length - 4];\n\t var lp4 = pointsR[pointsR_length - 5];\n\t var lp5 = pointsR[pointsR_length - 6];\n\t var lp6 = pointsR[pointsR_length - 7];\n\t\n\t var turnAngle1 = _cdl.Point.turnAngle(lp2.minus(lp3), lp3.minus(lp4));\n\t\n\t var turnAngle2 = _cdl.Point.turnAngle(lp0.minus(lp3).add(lp1.minus(lp3).add(lp2.minus(lp3))), lp3.minus(lp6).add(lp3.minus(lp5).add(lp3.minus(lp6))));\n\t\n\t if (Math.abs(turnAngle1) > 50 && Math.abs(turnAngle2) > 75) {\n\t if (!(0, _lodash.last)(points).__corner__ && (lp3TimeR < this._lastTime || distance2((0, _lodash.last)(points), lp3) < delta2)) {\n\t points.pop();\n\t }\n\t if (points.length > 0 && !(0, _lodash.last)(points).__corner__ && (lp3TimeR < this._lastTimePrev || distance2((0, _lodash.last)(points), lp3) < delta2)) {\n\t points.pop();\n\t }\n\t while (points.length > 0 && !(0, _lodash.last)(points).__corner__ && distance2((0, _lodash.last)(points), lp3) < delta2) {\n\t points.pop();\n\t }\n\t\n\t var lpd3 = pointsR[pointsR.length - 4];\n\t points.push(lpd3);\n\t points.push(lpd3);\n\t lpd3.__corner__ = true;\n\t }\n\t }\n\t }\n\t }\n\t }\n\t\n\t if (ctrl && points.length > 2) {\n\t var l = points.length;\n\t if (!(0, _gear.areEqual)(points[l - 1], points[l - 2])) {\n\t points.push(points[l - 1]);\n\t points[l - 1].__corner__ = true;\n\t }\n\t this._nextPoint = docPoint;\n\t this.redraw();\n\t } else if (t - this._lastTime > 40) {\n\t var _delta = view.viewDeltaToDoc(17);\n\t if (distance2(docPoint, (0, _lodash.last)(points)) > _delta * _delta) {\n\t points.push(docPoint);\n\t this.redraw();\n\t this._lastTimePrev = this._lastTime;\n\t this._lastTime = t;\n\t this._nextPoint = null;\n\t }\n\t }\n\t if (this._lastTime !== t) {\n\t this._nextPoint = docPoint;\n\t this.redraw();\n\t }\n\t } else {\n\t this._pointTo = docPoint;\n\t if (ctrl) {\n\t var w = this._pointTo.x - this._pointDown.x;\n\t var h = this._pointTo.y - this._pointDown.y;\n\t if (w && h) {\n\t var wa = Math.abs(w);\n\t var ha = Math.abs(h);\n\t if (wa > ha) {\n\t this._pointTo.y = this._pointDown.y + h * wa / ha;\n\t } else if (ha > wa) {\n\t this._pointTo.x = this._pointDown.x + w * ha / wa;\n\t }\n\t }\n\t }\n\t this.redraw();\n\t }\n\t }\n\t },\n\t on_pointerup: function (event) {\n\t if (event.isPrimary === false) {\n\t return; // ignore multitouch\n\t }\n\t if (!this._drawing) {\n\t return;\n\t }\n\t\n\t if (this.inMode('Free')) {\n\t var np = this._nextPoint;\n\t if (np && !np.isEqual((0, _lodash.last)(this._points))) {\n\t this._points.push(np);\n\t }\n\t if (this._points.length > 2) {\n\t this._paths.push(this._points);\n\t }\n\t } else {\n\t var stampPath = this.stampPath();\n\t if (stampPath) {\n\t this._paths.push(stampPath);\n\t }\n\t }\n\t this.flushCurrentPath();\n\t this.commitChanges$();\n\t },\n\t flushCurrentPath: function () {\n\t this.toolhelp('Click and hold to draw path');\n\t this._redoPaths = [];\n\t this._points = [];\n\t this._pointsR = [];\n\t this._nextPoint = null;\n\t this._drawing = false;\n\t this._ctrl = false;\n\t },\n\t catmull2beziers: function (points) {\n\t var path = points.slice(0);\n\t\n\t var length = path.length - 1;\n\t\n\t path.splice(0, 0, path[0]);\n\t path.push(path[path.length - 1]);\n\t\n\t var pieces = [];\n\t if (length <= 0) {\n\t return;\n\t }\n\t for (var n = 0; n < length; n++) {\n\t var p1 = path[n],\n\t p2 = path[n + 1],\n\t p3 = path[n + 2],\n\t p4 = path[n + 3];\n\t\n\t if (!(0, _gear.areEqual)(p2, p3)) {\n\t var q1 = p2.clone(),\n\t q2 = new _cdl.Point(p2.x + (p3.x - p1.x) / 6, p2.y + (p3.y - p1.y) / 6),\n\t q3 = new _cdl.Point(p3.x + (p2.x - p4.x) / 6, p3.y + (p2.y - p4.y) / 6),\n\t q4 = p3.clone();\n\t\n\t pieces.push(new _cdl.Cubic(q1, q2, q3, q4));\n\t }\n\t }\n\t return pieces;\n\t },\n\t undo: function () {\n\t if (!this._drawing) {\n\t if (this._paths.length > 0) {\n\t this._redoPaths.push(this._paths.pop());\n\t }\n\t this.redraw();\n\t }\n\t },\n\t redo: function () {\n\t if (!this._drawing) {\n\t if (this._redoPaths.length > 0) {\n\t this._paths.push(this._redoPaths.pop());\n\t }\n\t this.redraw();\n\t }\n\t },\n\t _cancel$: function () {\n\t // Nothing to do...\n\t },\n\t _commit$: function () {\n\t return this.commitChanges$();\n\t },\n\t commitChanges$: function () {\n\t var _this = this;\n\t\n\t var view = this.view,\n\t paths = this._paths;\n\t if (paths.length > 0) {\n\t var _ret = function () {\n\t\n\t var pen = _this._pen,\n\t brush = _this._brush;\n\t\n\t var polyregions = [];\n\t var addPolyregion = function (regions, closed) {\n\t\n\t var polyregion = new _cdl.Polyregion({ regions: regions, fillMode: 'Alternate', pen: pen });\n\t if (closed) {\n\t polyregion.brush = brush;\n\t }\n\t polyregions.push(polyregion);\n\t };\n\t\n\t var regions = [];\n\t var lastWasClosed = false;\n\t for (var k = 0, kEnd = paths.length; k < kEnd; ++k) {\n\t var paths_k = paths[k];\n\t var isCurve = paths_k instanceof _cdl.Curve;\n\t\n\t var curve = void 0;\n\t\n\t // [TODO] We need to perform this check at the mousemove level, and not here.\n\t var closed = isCurve || _this._closed || paths_k[0].isNear((0, _lodash.last)(paths_k), _this.view.viewDeltaToDoc(_this.closeDistance) * _view.padScaling);\n\t\n\t if (closed !== lastWasClosed && regions.length > 0) {\n\t addPolyregion(regions, lastWasClosed);\n\t regions = [];\n\t }\n\t\n\t if (isCurve) {\n\t curve = paths_k;\n\t } else {\n\t var pieces = _this.catmull2beziers(paths_k);\n\t curve = _cdl.Curve.fromNonTiedPieces(pieces, closed);\n\t }\n\t var region = new _cdl.Region([curve]);\n\t regions.push(region);\n\t\n\t lastWasClosed = closed;\n\t }\n\t\n\t if (regions.length > 0) {\n\t addPolyregion(regions, lastWasClosed);\n\t regions = [];\n\t }\n\t\n\t var anchor = _cdl.Bounds.ofThings(polyregions).center;\n\t\n\t view.add((0, _cdl.Shape)({ polyregions: polyregions,\n\t anchor: (0, _cdl.AbsoluteAnchor)(anchor),\n\t pin: anchor.clone() }));\n\t\n\t _this.flushShape();\n\t view.keepSelection();\n\t return {\n\t v: view.commit$()\n\t };\n\t }();\n\t\n\t if (typeof _ret === \"object\") return _ret.v;\n\t }\n\t }\n\t});\n\t\n\t_view.Tool.FreeDraw = FreeDrawTool;\n\n/***/ },\n\n/***/ 162:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.EditTextTool = undefined;\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar updateBrush = function () {\n\t var brush = this._brush,\n\t text = this._text;\n\t\n\t this._baseText.brush = brush;\n\t\n\t if (text) {\n\t text.brush = brush;\n\t this.view.commit$();\n\t }\n\t};\n\t\n\tvar updatePen = function () {\n\t var pen = this._pen,\n\t text = this._text;\n\t\n\t this._baseText.pen = pen;\n\t\n\t if (text) {\n\t text.pen = pen;\n\t this.view.commit$();\n\t }\n\t};\n\t\n\tvar EditTextTool = exports.EditTextTool = _view.Tool.extend({ typeName: 'EditTextTool',\n\t\n\t Properties: {\n\t pen: { type: 'Pen', def: _view.Tool.defaultPen(), onChange: updatePen },\n\t brush: { type: 'Brush', def: _view.Tool.defaultBrush(), onChange: updateBrush }\n\t },\n\t\n\t type: 'Final',\n\t toolbarName: 'textTool',\n\t\n\t initTool: function (view, text) {\n\t var config = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\t\n\t var _this = this;\n\t _this._cursorOn = true;\n\t _this.reset();\n\t _this._baseText = new _cdl.Text({ text: '',\n\t brush: _this._brush,\n\t fontSize: view.viewDeltaToDoc(30), // [TODO] do we want a stable one?\n\t pen: _this._pen\n\t });\n\t var baseTextUpdate = _this._baseText.update$();\n\t return text ? this.startEdit(text, config.event) : baseTextUpdate;\n\t },\n\t reset: function () {\n\t var _this = this;\n\t _this._cursor = null;\n\t _this._cursorEnd = null;\n\t _this._center = null;\n\t _this._currentChar = 0;\n\t _this._currentLine = 0;\n\t _this._changed = false;\n\t _this._text = null;\n\t },\n\t link: function (view) {\n\t var _this = this;\n\t view.cursor = 'text';\n\t _this._interval = setInterval(function () {\n\t _this._cursorOn = !_this._cursorOn;\n\t _this.view.redraw('tools');\n\t }, 500);\n\t },\n\t unlink: function (view) {\n\t clearInterval(this._interval);\n\t view.cursor = 'default';\n\t },\n\t _commit$: function (view, doc) {\n\t if (!this._center) {\n\t return;\n\t }\n\t var text = this._text;\n\t if (text.isEmpty) {\n\t doc.remove(text);\n\t } else {\n\t view.selectedFigures = [text];\n\t }\n\t return doc.commit$();\n\t },\n\t _cancel$: function (view) {\n\t return view.revert$();\n\t },\n\t canEdit: function (figure) {\n\t return EditTextTool.canEdit(figure);\n\t },\n\t startEdit: function (text, event) {\n\t var _this2 = this;\n\t\n\t var _this = this,\n\t view = _this.view;\n\t if (_this.canEdit(text)) {\n\t _this._text = text;\n\t _this._center = text.pin;\n\t return text.update$().then(function () {\n\t if (event) {\n\t var point = event.docPoint;\n\t _this.findCurrentChar(point);\n\t } else {\n\t _this._currentChar = text.lines[0].length;\n\t _this._currentLine = 0;\n\t }\n\t _this.findCursor();\n\t _this2.triggerKeyboard(event);\n\t view.preview$();\n\t });\n\t } else {\n\t _this.reset();\n\t view.fireEvent('textedit', view, text, event);\n\t }\n\t },\n\t on_pointerdown: function (_ref) {\n\t var _this3 = this;\n\t\n\t var event = _ref.event;\n\t var view = _ref.view;\n\t var which = _ref.which;\n\t var docPoint = _ref.docPoint;\n\t\n\t var _this = this;\n\t (0, _gear.if$)(_this._text && _this._changed, function () {\n\t\n\t var text = _this._text;\n\t _this.reset();\n\t if (text.isEmpty) {\n\t view.remove(text);\n\t }\n\t view.keepSelection();\n\t return view.commit$();\n\t }).then(function () {\n\t\n\t var leftClick = which === 1;\n\t\n\t if (leftClick) {\n\t var point = docPoint;\n\t\n\t var figure = event.figure; // [EVENTS] view.figureAtPoint(point);\n\t if (figure && figure.isText) {\n\t _this.startEdit(figure, event);\n\t } else {\n\t _this._text = _this._baseText.clone();\n\t _this._text.fontSize = view.viewDeltaToDoc(30);\n\t var center = _this._center = point;\n\t _this._text.pin = center;\n\t _this._currentChar = 0;\n\t _this._currentLine = 0;\n\t _this._changed = true;\n\t _this.findCursor();\n\t _this3.triggerKeyboard(event);\n\t view.add(_this._text); // We need a better abstraction here\n\t view.preview$();\n\t }\n\t }\n\t });\n\t },\n\t on_keydown: function (_ref2) {\n\t var event = _ref2.event;\n\t var cmdKey = _ref2.cmdKey;\n\t var which = _ref2.which;\n\t\n\t\n\t // console.log('edit text - keydown');\n\t\n\t var _this = this;\n\t var currentChar = _this._currentChar;\n\t var currentLine = _this._currentLine;\n\t var keyHome = which === 36,\n\t keyEnd = which === 35;\n\t\n\t if (which === 27) {\n\t event.stopPropagation();\n\t return this.commit$();\n\t }\n\t\n\t var figure = _this._text;\n\t\n\t if (!figure) {\n\t return;\n\t }\n\t\n\t var lines = figure.lines;\n\t var line = lines[currentLine];\n\t\n\t if (which === 13) {\n\t // Enter\n\t event.stopPropagation();\n\t\n\t if (_this._text.isEmpty) {\n\t return;\n\t }\n\t\n\t if ((0, _lodash.find)(figure._processes, function (p) {\n\t return p instanceof _cdl.Process.FitOnPath || p instanceof _cdl.Process.FitEllipse || p instanceof _cdl.Process.ClassicArc || p instanceof _cdl.Process.FitEnvelope;\n\t })) {\n\t // Do not accept line break\n\t return;\n\t }\n\t\n\t _this._changed = true;\n\t lines[currentLine] = line.slice(0, currentChar);\n\t lines.splice(currentLine + 1, 0, \"\");\n\t lines[currentLine + 1] = line.slice(currentChar);\n\t figure.lines = lines;\n\t if (currentChar > 0) {\n\t _this._currentLine++;\n\t _this._currentChar = 0;\n\t }\n\t _this.updateText();\n\t } else if (which === 8) {\n\t // Backspace\n\t event.preventDefault();\n\t if (currentChar > 0) {\n\t _this._changed = true;\n\t lines[currentLine] = line.slice(0, currentChar - 1) + line.slice(currentChar);\n\t figure.lines = lines;\n\t _this._currentChar--;\n\t _this.updateText();\n\t } else if (currentChar === 0 && currentLine > 0) {\n\t _this._changed = true;\n\t _this._currentChar = lines[currentLine - 1].length;\n\t _this._currentLine--;\n\t lines[currentLine - 1] = lines[currentLine - 1] + lines[currentLine];\n\t lines.splice(currentLine, 1);\n\t figure.lines = lines;\n\t _this.updateText();\n\t }\n\t } else if (which === 46) {\n\t // Delete\n\t event.stopPropagation();\n\t if (currentChar < line.length) {\n\t _this._changed = true;\n\t lines[currentLine] = line.slice(0, currentChar) + line.slice(currentChar + 1);\n\t figure.lines = lines;\n\t _this.updateText();\n\t } else if (currentChar === line.length && currentLine < lines.length) {\n\t _this._changed = true;\n\t lines[currentLine] = lines[currentLine] + lines[currentLine + 1];\n\t lines.splice(currentLine + 1, 1);\n\t figure.lines = lines;\n\t _this.updateText();\n\t }\n\t } else if (which === 37 || keyHome) {\n\t // Left arrow\n\t event.stopPropagation();\n\t if (currentChar > 0) {\n\t if (cmdKey || keyHome) {\n\t _this._currentChar = 0;\n\t } else {\n\t _this._currentChar--;\n\t }\n\t _this.updateText();\n\t }\n\t } else if (which === 39 || keyEnd) {\n\t // Right arrow\n\t event.stopPropagation();\n\t if (currentChar < line.length) {\n\t if (cmdKey || keyEnd) {\n\t _this._currentChar = line.length;\n\t } else {\n\t _this._currentChar++;\n\t }\n\t _this.updateText();\n\t }\n\t } else if (which === 38) {\n\t // Up\n\t event.stopPropagation();\n\t if (currentLine > 0) {\n\t _this._currentLine--;\n\t _this._currentChar = Math.floor(lines[_this._currentLine].length / 2);\n\t _this.updateText();\n\t }\n\t } else if (which === 40) {\n\t // Down\n\t event.stopPropagation();\n\t if (currentLine < lines.length - 1) {\n\t _this._currentLine++;\n\t _this._currentChar = Math.floor(lines[_this._currentLine].length / 2);\n\t _this.updateText();\n\t }\n\t }\n\t },\n\t on_keypress: function (_ref3) {\n\t var event = _ref3.event;\n\t var which = _ref3.which;\n\t var char = _ref3.char;\n\t\n\t // console.log('edit text - keypress');\n\t var _this = this;\n\t if (!_this._text) {\n\t return;\n\t }\n\t event.stopPropagation();\n\t if (which === 13) {\n\t // We handle Enter on keydown\n\t return;\n\t }\n\t\n\t var currentChar = _this._currentChar,\n\t currentLine = _this._currentLine;\n\t var figure = _this._text;\n\t var lines = figure.lines;\n\t\n\t var line = lines[currentLine];\n\t\n\t _this._changed = true;\n\t lines[currentLine] = line.slice(0, currentChar) + char + line.slice(currentChar);\n\t figure.lines = lines;\n\t _this._currentChar++;\n\t\n\t _this.updateText();\n\t },\n\t updateText: function () {\n\t var _this = this,\n\t view = _this.view,\n\t text = _this._text;\n\t\n\t text.update$().then(function () {\n\t _this.findCursor();\n\t\n\t view.preview$();\n\t });\n\t },\n\t findCurrentChar: function (point) {\n\t var figure = this._text;\n\t if (figure.isEmpty) {\n\t this._currentChar = 0;\n\t this._currentLine = 0;\n\t } else {\n\t var matrix = figure.matrix_(),\n\t tp = matrix.inverted().apply(point),\n\t layout = figure._textLayout,\n\t textLines = layout.textLines();\n\t\n\t var currentChar = 0,\n\t currentLine = 0,\n\t minDist = Number.MAX_VALUE;\n\t\n\t for (var kl = 0, klEnd = textLines.length; kl < klEnd; ++kl) {\n\t\n\t var textLine = textLines[kl],\n\t lineChars = textLine.allChars(),\n\t charsLength = lineChars.length;\n\t\n\t if (textLine._chars.length > 0) {\n\t // there should be at least one proper glyph (do not use _allChars here)\n\t var dToEnd = _cdl.Point.distance2(this.closerGlyph(lineChars, charsLength - 1)._baselineRightGrip, tp);\n\t if (dToEnd < minDist) {\n\t minDist = dToEnd;\n\t currentChar = charsLength;\n\t currentLine = kl;\n\t }\n\t for (var kc = 0; kc < charsLength; kc++) {\n\t var char = lineChars[kc];\n\t if (char) {\n\t var d = _cdl.Point.distance2(char._grip, tp);\n\t if (d < minDist) {\n\t minDist = d;\n\t currentChar = kc;\n\t currentLine = kl;\n\t }\n\t }\n\t }\n\t } else {\n\t var baseDist = _cdl.Point.distance2(textLine._baseline.P0, tp);\n\t if (baseDist < minDist) {\n\t minDist = baseDist;\n\t currentChar = 0;\n\t currentLine = kl;\n\t }\n\t }\n\t }\n\t this._currentChar = currentChar;\n\t this._currentLine = currentLine;\n\t }\n\t },\n\t closerGlyph: function (allChars, pos) {\n\t var count = allChars.length;\n\t var char = allChars[pos],\n\t n = pos - 1;\n\t while (!char && n >= 0) {\n\t char = allChars[n--];\n\t }\n\t n = pos + 1;\n\t while (!char && n < count) {\n\t char = allChars[n++];\n\t }\n\t return char;\n\t },\n\t findCursor: function () {\n\t var figure = this._text,\n\t center = this._center;\n\t var fontSize = figure.fontSize;\n\t var matrix = figure.matrix_();\n\t if (figure.isEmpty) {\n\t this._cursor = center;\n\t this._cursorEnd = matrix.apply(matrix.inverted().apply(center).plus_(0, fontSize));\n\t } else {\n\t var currentChar = this._currentChar;\n\t var layout = figure._textLayout;\n\t var line = layout.textLines()[this._currentLine];\n\t var allChars = line.allChars();\n\t var bs = line._baseline;\n\t if (line._chars.length > 0) {\n\t // If there is a proper glyph\n\t var char = this.closerGlyph(allChars, currentChar);\n\t var before = char._originalIdx <= currentChar;\n\t var grip = before ? char._baselineRightGrip : char._grip;\n\t var frameDirX = char._frame.dir_x;\n\t var c = grip.plus(frameDirX.scaled(fontSize / 20 * (before ? 1 : -1)));\n\t this._cursor = matrix.apply(c);\n\t\n\t if (figure._processes.length > 0) {\n\t var frame = char._frame;\n\t var cursorH = before ? frame.p2.minus(frame.p1) : frame.p3.minus(frame.p0);\n\t this._cursorEnd = matrix.apply(c.plus(cursorH));\n\t } else {\n\t this._cursorEnd = matrix.apply(c.plus(bs.P1.minus(bs.P0).normalize().perpendicular().sm(fontSize)));\n\t }\n\t } else {\n\t this._cursor = matrix.apply(bs.P0);\n\t this._cursorEnd = matrix.apply(bs.P0.plus(bs.P1.minus(bs.P0).normalize().perpendicular().sm(fontSize)));\n\t }\n\t }\n\t this.view.redraw('tools');\n\t },\n\t drawCursorLine: function (context, transform, lineWidth, strokeStyle) {\n\t context.lineWidth = lineWidth;\n\t context.strokeStyle = strokeStyle;\n\t (0, _gear.strokeSegment)(context, this._cursor, this._cursorEnd, transform);\n\t },\n\t draw: function (_ref4) {\n\t var view = _ref4.view;\n\t var context = _ref4.context;\n\t var transform = _ref4.transform;\n\t\n\t var center = this._center;\n\t if (!center || !this._cursorOn || !this._cursor) {\n\t return;\n\t }\n\t var textureScale = view.viewDeltaToTexture(1);\n\t this.drawCursorLine(context, transform, 3 * textureScale, \"#dbdbdb\");\n\t this.drawCursorLine(context, transform, 1 * textureScale, \"#248e1f\");\n\t }\n\t});\n\t\n\t_view.Tool.Text = _view.Tool.EditText = EditTextTool;\n\t\n\tEditTextTool.canEdit = function (figure) {\n\t return figure.isText && figure.canBeProcessedLocally() && !figure.isMultiPart;\n\t};\n\n/***/ },\n\n/***/ 163:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.CharsTransformTool = undefined;\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar CharsTransformTool = exports.CharsTransformTool = _view.Tool.extend({ typeName: 'CharsTransformTool',\n\t type: 'Final',\n\t toolbarName: 'charsTransformTool',\n\t initTool: function (view, text) {\n\t var _this = this;\n\t _this._char = null;\n\t _this._text = null;\n\t\n\t if (text && _this.canEdit(text)) {\n\t _this._text = text;\n\t return _this.updateText$();\n\t }\n\t },\n\t canEdit: function (figure) {\n\t return figure.isText && figure.canBeProcessedLocally() && (0, _lodash.every)(figure.processes, function (p) {\n\t return p.outputsText();\n\t }) && !figure.isMultiPart;\n\t },\n\t updateText$: function () {\n\t var _this = this;\n\t return _this._text.update$().then(function () {\n\t _this._matrix = _this._text.matrix_();\n\t _this.view.redraw('tools');\n\t });\n\t },\n\t link: function (view) {\n\t view.cursor = 'pointer';\n\t },\n\t unlink: function (view) {\n\t view.cursor = 'default';\n\t },\n\t _commit$: function (view, doc) {\n\t var text = this._text;\n\t if (text) {\n\t view.selectedFigures = [text];\n\t }\n\t return doc.commit$();\n\t },\n\t _cancel$: function (view) {\n\t return view.revert$();\n\t },\n\t on_pointerdown: function (_ref) {\n\t var view = _ref.view;\n\t var event = _ref.event;\n\t var which = _ref.which;\n\t var docPoint = _ref.docPoint;\n\t\n\t var _this = this;\n\t var leftClick = which === 1;\n\t if (leftClick) {\n\t var _ret = function () {\n\t var point = docPoint;\n\t\n\t var text = _this._text;\n\t if (text) {\n\t var char = _this._char = text.charAtPoint_(point);\n\t if (char) {\n\t event.stopPropagation();\n\t _this._point = point;\n\t _this._downPoint = point.clone();\n\t var matrix = text.matrix_();\n\t _this._charGrip = matrix.apply(char._grip);\n\t _this.view.redraw('tools');\n\t return {\n\t v: void 0\n\t };\n\t }\n\t }\n\t\n\t var figure = event.figure; // [EVENTS] view.figureAtPoint(point);\n\t if (figure && _this.canEdit(figure)) {\n\t event.stopPropagation();\n\t (0, _gear.if$)(_this._changed, function () {\n\t _this._changed = false;\n\t return view.commit$();\n\t }).then(function () {\n\t _this._text = figure;\n\t _this.updateText$();\n\t });\n\t } else {\n\t _this._point = _this._downPoint = null;\n\t _this.view.redraw('tools');\n\t }\n\t }();\n\t\n\t if (typeof _ret === \"object\") return _ret.v;\n\t }\n\t },\n\t on_pointermove: function (_ref2) {\n\t var event = _ref2.event;\n\t var view = _ref2.view;\n\t\n\t var char = this._char;\n\t if (char && this._point) {\n\t var text = this._text;\n\t var pn = this._point = event.docPoint;\n\t var invMatrix = text.matrix_().inverted();\n\t var offset = pn.minus(this._downPoint);\n\t\n\t char.placeAt('Grip', invMatrix.apply(this._charGrip.plus(offset)));\n\t\n\t // Regenerate output figure, we need a helper here.\n\t // Manually preserve the anchor for the moment\n\t var anchor = text.outputFigure.anchor;\n\t var newOutput = text._textLayout.shape();\n\t newOutput.anchor = anchor;\n\t\n\t text.outputFigure = newOutput;\n\t\n\t text._cache.clear();\n\t text.invalidateView();\n\t\n\t view.batchRedraw('tools');\n\t\n\t view.preview$();\n\t }\n\t },\n\t on_pointerup: function () {\n\t var _this2 = this;\n\t\n\t var char = this._char;\n\t if (char) {\n\t (function () {\n\t _this2._changed = true;\n\t\n\t var text = _this2._text,\n\t textLayout = text._textLayout,\n\t spaceWidth = textLayout.spaceWidth(),\n\t invMatrix = _this2._matrix.inverted(),\n\t docOffset = _this2._point.minus(_this2._downPoint),\n\t finalPos = invMatrix.apply(_this2._charGrip.plus(docOffset)),\n\t offset = finalPos.minus(invMatrix.apply(_this2._charGrip));\n\t\n\t var idx = char._idx,\n\t lineIdx = char._lineIdx;\n\t\n\t // Update layout transforms, in case other processes call layout.outdate()\n\t char._charData._transformers.push(new _cdl.TextChar.PinPlacer('Grip', char._grip.clone()));\n\t\n\t // Update text processes\n\t var processes = text._processes;\n\t var charsTransform = (0, _gear.findByType)(processes, _cdl.Process.CharsTransform);\n\t if (!charsTransform) {\n\t charsTransform = new _cdl.Process.CharsTransform();\n\t processes._push(charsTransform); // Avoid events, the output is already modified\n\t }\n\t var ctl = (0, _lodash.find)(charsTransform._chars, function (c) {\n\t return c._lineIdx === lineIdx && c._idx === idx;\n\t });\n\t if (!ctl) {\n\t ctl = new _cdl.CharTransformList({ lineIdx: lineIdx, idx: idx });\n\t charsTransform._chars._push(ctl);\n\t }\n\t var to = (0, _gear.findByType)(ctl._transforms, _cdl.CharTransform.TangencialOffset);\n\t if (!to) {\n\t to = new _cdl.CharTransform.TangencialOffset();\n\t ctl._transforms._push(to);\n\t }\n\t var dirX = char._frame.dir_x;\n\t var co_h = _cdl.Point.dotProduct(dirX, offset);\n\t var co_v = _cdl.Point.dotProduct(dirX.perpendicular(), offset);\n\t to._h = new _gear.Magnitude(((_gear.Magnitude.absoluteMMValueFor(to._h, spaceWidth) + co_h) / spaceWidth * 100).toFixed(4), '%');\n\t to._v = new _gear.Magnitude(((_gear.Magnitude.absoluteMMValueFor(to._v, spaceWidth) + co_v) / spaceWidth * 100).toFixed(4), '%');\n\t\n\t _this2._point = _this2._downPoint = null;\n\t })();\n\t }\n\t },\n\t draw: function (_ref3) {\n\t var view = _ref3.view;\n\t var context = _ref3.context;\n\t var transform = _ref3.transform;\n\t\n\t var char = this._char;\n\t var e = view.viewDeltaToTexture(3);\n\t context.lineWidth = view.viewDeltaToTexture(1);\n\t if (char) {\n\t context.strokeStyle = \"#248e1f\";\n\t var frame = char._frame.transformed(this._matrix).extended(e, e, e, e);\n\t frame.draw(context, transform);\n\t context.stroke();\n\t } else if (this._text) {\n\t var figure = this._text;\n\t var figureFrame = figure.frame_().transformed(transform).extended(e, e, e, e);\n\t context.strokeStyle = \"#248e1f\";\n\t figureFrame.draw(context);\n\t context.stroke();\n\t }\n\t }\n\t});\n\t\n\t_view.Tool.CharsTransform = CharsTransformTool;\n\n/***/ },\n\n/***/ 164:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.NodeEditEnvelopeTool = exports.NodeEditTool = undefined;\n\t\n\tvar _config = __webpack_require__(2);\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _gear = __webpack_require__(8);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\t\n\tvar Point_add = _cdl.Point.add,\n\t Point_substract = _cdl.Point.substract,\n\t Point_sm = _cdl.Point.sm,\n\t Color_fromRgb = _cdl.Color.fromRgb,\n\t knotSize = 3,\n\t knotSelectedSize = 4;\n\t\n\t// [TODO] directly use fillStyle colors here, and flatten this object\n\tvar colors = {\n\t pad: new _cdl.Color({ rgb: 'FFFFFF', alpha: 0.7 }),\n\t curve: Color_fromRgb('8888FF'),\n\t knot: Color_fromRgb('4444FF'),\n\t knot_selected: Color_fromRgb('000000'),\n\t knot_over: Color_fromRgb('44AA88'),\n\t controlSegment: Color_fromRgb('4444FF'),\n\t curveControlSegment: Color_fromRgb('9944CC'),\n\t cuspControlSegment: Color_fromRgb('AA4433'),\n\t nextControlSegment: Color_fromRgb('666666'),\n\t control: Color_fromRgb('0000FF'),\n\t control_over: Color_fromRgb('44AA88'),\n\t addKnot: Color_fromRgb('000000'),\n\t addKnot_over: Color_fromRgb('44AA88'),\n\t removeKnot: Color_fromRgb('FF0000'),\n\t removeKnot_over: Color_fromRgb('44AA88'),\n\t dragSelector: Color_fromRgb('009900'),\n\t curvePadBack: Color_fromRgb('E8E8FF')\n\t};\n\t\n\tfunction drawDot(context, style, size, point, transform, textureScale) {\n\t context.fillStyle = colors.pad.rgba;\n\t (0, _gear.dot)(context, point, (size + 1.4) * textureScale, transform);\n\t context.fillStyle = style;\n\t (0, _gear.dot)(context, point, size * textureScale, transform);\n\t}\n\t\n\tfunction drawSegment(context, style, p0, p1, transform, textureScale) {\n\t context.lineWidth = 3.5 * textureScale;\n\t context.strokeStyle = colors.pad.rgba;\n\t (0, _gear.strokeSegment)(context, p0, p1, transform);\n\t context.lineWidth = 1.5 * textureScale;\n\t context.strokeStyle = style;\n\t (0, _gear.strokeSegment)(context, p0, p1, transform);\n\t}\n\t\n\t// States\n\t// Iddle: nothing is selected, waiting for user input\n\t// DragSelection: user is selecting multiple knots with a rectangle\n\t// EditingKnot: one knot is selected, user can move it and move the control points\n\t// SelectedKnots:\n\t// MovingControlPoint: control point is being moved\n\t// MovingKnots: multiple knots are selected\n\t\n\tfunction nextKi(side, curve, ki) {\n\t var length = curve.pieces.length,\n\t closed = curve.closed;\n\t if (side === 'left') {\n\t if (!closed && ki === 0) {\n\t return null;\n\t }\n\t return ki === 0 && closed ? length - 1 : ki - 1;\n\t } else {\n\t // right\n\t\n\t if (!closed && ki === length) {\n\t return null;\n\t }\n\t return ki === length - 1 && closed ? 0 : ki + 1;\n\t }\n\t}\n\t\n\tfunction knotPoint(curve, ki) {\n\t var pieces = curve.pieces;\n\t if (ki === null) {\n\t return null;\n\t }\n\t if (ki >= pieces.length) {\n\t return (0, _lodash.last)(pieces).last();\n\t }\n\t return pieces[ki].P0;\n\t}\n\t\n\tfunction nextKnotPoint(side, curve, ki) {\n\t return knotPoint(curve, nextKi(side, curve, ki));\n\t}\n\t\n\tfunction pieceIndexAt(side, curve, ki) {\n\t if (side === 'left') {\n\t return nextKi(side, curve, ki);\n\t } else {\n\t return !curve.closed && ki === curve.pieces.length ? null : ki;\n\t }\n\t}\n\t\n\tfunction pieceAt(side, curve, ki) {\n\t var pi = pieceIndexAt(side, curve, ki);\n\t return pi !== null ? curve.pieces[pi] : null;\n\t}\n\t\n\tfunction controlPoint(side, curve, ki) {\n\t var pieces = curve.pieces;\n\t\n\t var piece = void 0;\n\t if (ki === null) {\n\t return null;\n\t }\n\t if (side === 'left') {\n\t piece = null;\n\t if (ki === 0 && curve.closed) {\n\t piece = (0, _lodash.last)(pieces);\n\t } else {\n\t piece = pieces[ki - 1];\n\t }\n\t if (piece && piece.type === 'Cubic') {\n\t return piece.P2;\n\t }\n\t return null;\n\t } else {\n\t // 'right'\n\t if (ki >= pieces.length) {\n\t return null;\n\t }\n\t piece = pieces[ki];\n\t if (piece && piece.type === 'Cubic') {\n\t return piece.P1;\n\t }\n\t return null;\n\t }\n\t}\n\t\n\tfunction nextControlPoint(side, curve, ki) {\n\t return controlPoint(oppSide(side), curve, nextKi(side, curve, ki));\n\t}\n\t\n\tfunction removeKnot(curve, ki, tool) {\n\t\n\t // Check if it is the last knot\n\t if (curve.pieces.length === 1) {\n\t // [TODO] Curves should be included in the type system, remove lazy loading, is not gaining us much\n\t var region = curve._owner;\n\t var curves = region._curves;\n\t curves.splice(curves.indexOf(curve), 1);\n\t\n\t if (curves.length === 0) {\n\t var polyregion = region._owner;\n\t var regions = polyregion._regions;\n\t\n\t regions._remove(region);\n\t if (regions.length === 0) {\n\t var figure = polyregion._owner;\n\t figure._polyregions._remove(polyregion);\n\t }\n\t }\n\t var toolCurves = tool._curves;\n\t toolCurves.splice(toolCurves.indexOf(curve), 1);\n\t return;\n\t }\n\t\n\t var pieces = curve.pieces;\n\t if (ki === pieces.length) {\n\t // open curve\n\t pieces.pop();\n\t return;\n\t }\n\t\n\t var kiLeft = nextKi('left', curve, ki);\n\t if (kiLeft === null) {\n\t // open curve\n\t pieces.shift();\n\t return;\n\t }\n\t\n\t var pieceLeft = pieces[kiLeft];\n\t var piece = pieces[ki];\n\t\n\t pieceLeft.last(piece.last());\n\t if (pieceLeft.P3) {\n\t if (piece.P3) {\n\t // Both are cubic, try to avoid big modifications in the curve\n\t pieceLeft.P1 = Point_sm(pieceLeft.P1, 2).substract(pieceLeft.P0);\n\t pieceLeft.P2 = Point_sm(piece.P2, 2).substract(piece.P3);\n\t } else {\n\t pieces[kiLeft] = new _cdl.Segment(pieceLeft.P0, piece.last());\n\t }\n\t }\n\t pieces.splice(ki, 1);\n\t curve.tieExtremePoints();\n\t}\n\t\n\tfunction oppSide(side) {\n\t return side === 'left' ? 'right' : 'left';\n\t}\n\t\n\tvar Knot = function (curve, ki) {\n\t this.curve = curve;\n\t this.ki = ki;\n\t};\n\tKnot.prototype = {\n\t isEqual: function (ok) {\n\t return ok && this.curve === ok.curve && this.ki === ok.ki;\n\t },\n\t point: function () {\n\t return knotPoint(this.curve, this.ki);\n\t },\n\t nextKi: function (side) {\n\t return nextKi(side, this.curve, this.ki);\n\t },\n\t nextPoint: function (side) {\n\t return nextKnotPoint(side, this.curve, this.ki);\n\t },\n\t pieceAt: function (side) {\n\t return pieceAt(side, this.curve, this.ki);\n\t },\n\t pieceIndexAt: function (side) {\n\t return pieceIndexAt(side, this.curve, this.ki);\n\t },\n\t pointAt: function (side, t) {\n\t return this.pieceAt(side).eval(t);\n\t },\n\t controlPoint: function (side) {\n\t return controlPoint(side, this.curve, this.ki);\n\t },\n\t nextControlPoint: function (side) {\n\t return nextControlPoint(side, this.curve, this.ki);\n\t },\n\t nextKnot: function (side) {\n\t var nki = nextKi(side, this.curve, this.ki);\n\t if (nki === null) {\n\t return null;\n\t }\n\t return new Knot(this.curve, nki);\n\t },\n\t tangentAt: function (side) {\n\t var to = this.controlPoint(side) || this.nextPoint(side);\n\t if (!to) {\n\t return null;\n\t }\n\t var from = this.point();\n\t var tangent = Point_substract(from, to);\n\t if (tangent.isZero()) {\n\t return null;\n\t }\n\t return tangent.normalized();\n\t },\n\t normal: function () {\n\t var leftTangent = this.tangentAt(\"left\");\n\t var rightTangent = this.tangentAt(\"right\");\n\t if (!leftTangent && !rightTangent) {\n\t leftTangent = new _cdl.Point(1.0, 0.0);\n\t rightTangent = new _cdl.Point(-1.0, 0.0);\n\t } else if (!leftTangent) {\n\t leftTangent = _cdl.Point.minus(rightTangent);\n\t } else if (!rightTangent) {\n\t rightTangent = _cdl.Point.minus(leftTangent);\n\t }\n\t\n\t var normal = new _cdl.Point(leftTangent.y - rightTangent.y, -leftTangent.x + rightTangent.x);\n\t\n\t return normal.isZero() ? leftTangent : normal.normalize();\n\t },\n\t locked: function () {\n\t return this.point().__cadx_locked === true;\n\t },\n\t\n\t // You can not use the knot after calling this function\n\t remove: function (tool) {\n\t removeKnot(this.curve, this.ki, tool);\n\t },\n\t addKnot: function (side) {\n\t var curve = this.curve;\n\t var pi = this.pieceIndexAt(side);\n\t // [TODO] Move locked annotations out of points\n\t var locked = curve.pieces[pi].P0.__cadx_locked;\n\t this.curve.splitPiece(pi, 0.5);\n\t if (locked) {\n\t curve.pieces[pi].P0.__cadx_locked = true;\n\t }\n\t return new Knot(this.curve, side === 'left' ? this.ki : this.ki + 1);\n\t },\n\t _computeCorner: function () {\n\t var left = this.controlPoint('left');\n\t var right = this.controlPoint('right');\n\t if (left && right) {\n\t var point = this.point();\n\t if (point.isNear(left, 0.01) || point.isNear(right, 0.01)) {\n\t return 'cusp';\n\t }\n\t var lp = Point_substract(point, left);\n\t var rp = Point_substract(right, point);\n\t if (lp.isNear(rp, 0.01)) {\n\t return 'symmetric';\n\t }\n\t if (Math.abs(lp.x * rp.y - lp.y * rp.x) < 0.01) {\n\t return 'curve';\n\t }\n\t return 'cusp';\n\t }\n\t return 'cusp';\n\t },\n\t corner: function () {\n\t if (!this._corner) {\n\t this._corner = this._computeCorner();\n\t }\n\t return this._corner;\n\t },\n\t changeCorner: function (side) {\n\t var _side = this.controlPoint(side);\n\t var _opp = this.controlPoint(oppSide(side));\n\t var point = this.point();\n\t var corner = this.corner();\n\t var newCorner = corner === 'cusp' ? 'curve' : corner === 'curve' ? 'symmetric' : 'cusp';\n\t if (!(_side && _opp)) {\n\t return;\n\t }\n\t var sh = Point_substract(point, _side);\n\t if (newCorner === 'symmetric') {\n\t _opp.set(Point_add(point, sh));\n\t } else if (newCorner === 'curve') {\n\t if (corner === 'cusp') {\n\t var oh = Point_substract(_opp, point);\n\t sh = Point_sm(sh.normalized(), oh.norm());\n\t _opp.set(Point_add(point, sh));\n\t } else {\n\t // Symmetric\n\t sh = Point_add(sh, Point_sm(sh.normalized(), 0.1));\n\t _opp.set(Point_add(point, sh));\n\t }\n\t } else if (newCorner === 'cusp') {\n\t var p = sh.perpendicular(-1);\n\t sh = Point_add(Point_substract(_opp, point), Point_sm(p.normalized(), 0.1));\n\t _opp.set(Point_add(point, sh));\n\t }\n\t this._corner = newCorner;\n\t },\n\t convertToCurve: function (side) {\n\t var pieces = this.curve.pieces;\n\t var kp = side === 'left' ? nextKi(side, this.curve, this.ki) : this.ki;\n\t var p = pieces[kp];\n\t pieces.splice(kp, 1, _cdl.Cubic.fromSegment(p.P0, p.P1));\n\t this.curve.tieExtremePoints();\n\t this._corner = null;\n\t },\n\t convertToSegment: function (side) {\n\t var pieces = this.curve.pieces;\n\t var kp = side === 'left' ? nextKi(side, this.curve, this.ki) : this.ki;\n\t var p = pieces[kp];\n\t pieces.splice(kp, 1, new _cdl.Segment(p.P0, p.last()));\n\t this.curve.tieExtremePoints();\n\t this._corner = null;\n\t }\n\t};\n\t\n\tfunction forEachKnot(curve, func) {\n\t var pieces = curve.pieces;\n\t for (var n = 0, nEnd = pieces.length; n < nEnd; ++n) {\n\t if (func(new Knot(curve, n)) === false) {\n\t return curve;\n\t }\n\t }\n\t if (!curve.closed) {\n\t if (func(new Knot(curve, curve.pieces.length)) === false) {\n\t return curve;\n\t }\n\t }\n\t return curve;\n\t}\n\t\n\tfunction findKnot(curve, func) {\n\t var pieces = curve.pieces;\n\t var k = void 0;\n\t for (var n = 0, nEnd = pieces.length; n < nEnd; ++n) {\n\t k = new Knot(curve, n);\n\t if (func(k) === true) {\n\t return k;\n\t }\n\t }\n\t if (!curve.closed) {\n\t k = new Knot(curve, pieces.length);\n\t if (func(k) === true) {\n\t return k;\n\t }\n\t }\n\t return null;\n\t}\n\t\n\tvar BaseState = _gear.Base.extend({\n\t init: function (tool) {\n\t this._tool = tool;\n\t this._padSize = 0.1 * 96;\n\t this._cursor = null;\n\t this.showToolhelp();\n\t },\n\t showToolhelp: function () {\n\t this._tool.toolhelp(this.toolhelp().concat(this.baseToolhelp()));\n\t },\n\t toolhelp: function () {\n\t return [];\n\t },\n\t baseToolhelp: function () {\n\t return ['Click or Draw rectangle to select knots', 'Enter to Commit, Escape to Cancel'];\n\t },\n\t undoState: function () {\n\t this._tool.undoState();\n\t },\n\t state: function (s, k, a, b, c) {\n\t this._tool.state(s, k, a, b, c);\n\t },\n\t curveToDoc: function (point) {\n\t return this.matrix.apply(point);\n\t },\n\t viewToCurve_dx: function (d) {\n\t return this.matrixInverted.scaleFactor() * this.view.viewDeltaToDoc(d);\n\t },\n\t curvePoint: function (_ref) {\n\t var docPoint = _ref.docPoint;\n\t\n\t return this.matrixInverted.apply(docPoint);\n\t },\n\t\n\t\n\t get textureScale() {\n\t return this.view.viewDeltaToTexture(1);\n\t },\n\t\n\t get view() {\n\t return this._tool.view;\n\t },\n\t get matrix() {\n\t return this._tool._matrix;\n\t },\n\t get matrixInverted() {\n\t return this._tool._matrixInverted;\n\t },\n\t\n\t focus: function () {\n\t this.showToolhelp();\n\t this._possibleClick = null;\n\t },\n\t\n\t\n\t get cursor() {\n\t return this._tool.cursor;\n\t },\n\t set cursor(cursor_) {\n\t this._tool.cursor = cursor_;\n\t },\n\t\n\t redraw: function () {\n\t this._tool.redraw();\n\t },\n\t onUpdate: function () {\n\t this._tool.onUpdate();\n\t },\n\t draw: function (context, transform) {\n\t this.drawCurve(context, transform);\n\t this.drawKnots(context, transform);\n\t },\n\t drawCurve: function (context, transform) {\n\t var textureScale = this.textureScale;\n\t\n\t context.lineWidth = 3.5 * textureScale;\n\t context.strokeStyle = colors.pad.rgba;\n\t this._strokeCurve(context, transform);\n\t context.lineWidth = 1.5 * textureScale;\n\t context.strokeStyle = colors.curve.rgba;\n\t this._strokeCurve(context, transform);\n\t },\n\t _strokeCurve: function (context, transform) {\n\t (0, _lodash.forEach)(this._tool._curves, function (curve) {\n\t context.beginPath();\n\t curve.draw(context, transform);\n\t context.stroke();\n\t });\n\t },\n\t drawKnots: function (context, transform) {\n\t var tool = this._tool;\n\t var over_knot = this._over_knot;\n\t var textureScale = this.textureScale;\n\t\n\t (0, _lodash.forEach)(tool._curves, function (curve) {\n\t forEachKnot(curve, function (knot) {\n\t var ok = knot.isEqual(over_knot);\n\t drawDot(context, ok ? colors.knot_over.rgba : colors.knot.rgba, ok ? knotSelectedSize : knotSize, knot.point(), transform, textureScale);\n\t });\n\t });\n\t var fillStyle = this._over_selectedKnots ? colors.knot_over.rgba : colors.knot_selected.rgba;\n\t (0, _lodash.forEach)(this.selectedKnots(), function (knot) {\n\t drawDot(context, fillStyle, knotSelectedSize, knot.point(), transform, textureScale);\n\t });\n\t },\n\t overKnot: function (event) {\n\t var padSize = this.viewToCurve_dx(this._padSize * _view.padScaling),\n\t point = this.curvePoint(event);\n\t var overKnot = null;\n\t (0, _lodash.find)(this._tool._curves, function (curve) {\n\t overKnot = findKnot(curve, function (knot) {\n\t return point.isNear(knot.point(), padSize);\n\t });\n\t if (overKnot) {\n\t return true;\n\t }\n\t });\n\t return overKnot;\n\t },\n\t overSelectedKnots: function (event) {\n\t var padSize = this.viewToCurve_dx(this._padSize * _view.padScaling),\n\t point = this.curvePoint(event);\n\t\n\t return (0, _lodash.find)(this.selectedKnots(), function (knot) {\n\t return point.isNear(knot.point(), padSize);\n\t });\n\t },\n\t selectedKnot: function () {\n\t return this._tool._selectedKnots[0];\n\t },\n\t selectedKnots: function () {\n\t return this._tool._selectedKnots;\n\t },\n\t down: function (_ref2) {\n\t var event = _ref2.event;\n\t var docPoint = _ref2.docPoint;\n\t var shiftKey = _ref2.shiftKey;\n\t\n\t var selectedKnots = this.selectedKnots();\n\t var knot = this.overKnot(event);\n\t if (knot) {\n\t if (shiftKey && selectedKnots) {\n\t return this.state('SelectedKnots', selectedKnots.concat(knot));\n\t } else {\n\t this._possibleClick = { docPoint: docPoint, knot: knot };\n\t return true;\n\t }\n\t }\n\t this.state('DragSelection', selectedKnots, docPoint);\n\t return false;\n\t },\n\t move: function (_ref3) {\n\t var event = _ref3.event;\n\t var docPoint = _ref3.docPoint;\n\t\n\t if (this._possibleClick && !docPoint.isEqual(this._possibleClick.docPoint)) {\n\t this.state('EditingKnot', this._possibleClick.knot);\n\t this.state('MovingKnots', this._possibleClick.knot, this.curvePoint(event));\n\t this._possibleClick = null;\n\t this.redraw();\n\t }\n\t },\n\t mousemove: function (event) {\n\t this._over_knot = this.overKnot(event);\n\t this._over_selectedKnots = this.overSelectedKnots(event);\n\t if (this._changeCursorTo) {\n\t this.cursor = this._changeCursorTo;\n\t this._changeCursorTo = null;\n\t } else if (this._over_knot || this._over_selectedKnots) {\n\t this.cursor = 'pointer';\n\t } else {\n\t this.cursor = 'default';\n\t }\n\t this.redraw(); // [TODO] Avoid redrawing when it is not needed\n\t },\n\t up: function () /*view,event*/{\n\t if (this._possibleClick) {\n\t this.state('EditingKnot', this._possibleClick.knot);\n\t this._possibleClick = null;\n\t }\n\t },\n\t on_dblclick: function () /*view,event*/{\n\t // ...\n\t },\n\t deleteAction: function () {\n\t // nothing...\n\t }\n\t});\n\t\n\tvar HandleBase = _gear.Base.extend({\n\t init: function (state, side) {\n\t this._state = state;\n\t this._knot = state._knot;\n\t this._side = side;\n\t this._over = false;\n\t this._point = this.point();\n\t this._padSize = 0.1 * 96;\n\t },\n\t over: function (event) {\n\t var state = this._state;\n\t var p = this._point;\n\t return p && state.curvePoint(event).isNear(p, state.viewToCurve_dx(this._padSize * _view.padScaling));\n\t },\n\t down: function (event) {\n\t if (!this._point) {\n\t return;\n\t }\n\t\n\t if (this.over(event)) {\n\t this.click(event);\n\t return true;\n\t }\n\t return false;\n\t },\n\t move: function () /* event */{},\n\t mousemove: function (event) {\n\t if (!this._point) {\n\t return;\n\t }\n\t this._over = this.over(event);\n\t if (this._over) {\n\t this._state._changeCursorTo = 'pointer';\n\t }\n\t },\n\t on_dblclick: function (event) {\n\t if (!this._point) {\n\t return;\n\t }\n\t if (this.over(event)) {\n\t this.dblClick(event);\n\t return true;\n\t }\n\t return false;\n\t },\n\t click: function () /*view,event*/{},\n\t dblClick: function () /*view,event*/{},\n\t drawCurvePadBack: function (context, transform) {\n\t var textureScale = this.textureScale;\n\t\n\t context.strokeStyle = colors.curve.rgba;\n\t context.lineWidth = 1;\n\t (0, _gear.strokeDot)(context, this._point, 5 * textureScale, transform);\n\t context.fillStyle = colors.curvePadBack.rgba;\n\t (0, _gear.dot)(context, this._point, 4.5 * textureScale, transform);\n\t },\n\t state: function (a, b, c, d, e) {\n\t this._state.state(a, b, c, d, e);\n\t },\n\t curvePoint: function (event) {\n\t return this._state.curvePoint(event);\n\t },\n\t viewToCurve_dx: function (d) {\n\t return this._state.viewToCurve_dx(d);\n\t },\n\t onUpdate: function () {\n\t this._state.onUpdate();\n\t },\n\t\n\t\n\t get textureScale() {\n\t return this._state.textureScale;\n\t }\n\t});\n\t\n\tvar Handle = {\n\t\n\t 'Control': HandleBase.extend({\n\t //==========================================================================\n\t\n\t point: function () {\n\t return this._knot.controlPoint(this._side);\n\t },\n\t draw: function (context, transform) {\n\t if (!this._point) {\n\t return;\n\t }\n\t\n\t // [TODO]\n\t\n\t var corner = this._knot.corner();\n\t var strokeStyle = this._side === 'right' ? colors.controlSegment.rgba : corner === 'cusp' ? colors.cuspControlSegment.rgba : corner === 'curve' ? colors.curveControlSegment.rgba : colors.controlSegment.rgba;\n\t\n\t var textureScale = this.textureScale;\n\t\n\t\n\t drawSegment(context, strokeStyle, this._knot.point(), this._point, transform, textureScale);\n\t\n\t drawDot(context, this._over ? colors.control_over.rgba : colors.control.rgba, 2, this._point, transform, textureScale);\n\t },\n\t click: function (event) {\n\t return this.state('MovingControl', this._knot, this._side, this.curvePoint(event));\n\t },\n\t dblClick: function () /*view,event*/{\n\t this._knot.changeCorner(this._side);\n\t this.onUpdate();\n\t this._state.focus();\n\t }\n\t }),\n\t\n\t 'NextControl': HandleBase.extend({\n\t //==========================================================================\n\t point: function () {\n\t return this._knot.nextControlPoint(this._side);\n\t },\n\t draw: function (context, transform) {\n\t\n\t if (!this._point) {\n\t return;\n\t }\n\t\n\t var textureScale = this.textureScale;\n\t\n\t\n\t drawSegment(context, colors.nextControlSegment.rgba, this._knot.nextKnot(this._side).point(), this._point, transform, textureScale);\n\t\n\t drawDot(context, this._over ? colors.control_over.rgba : colors.control.rgba, 2, this._point, transform, textureScale);\n\t },\n\t click: function (event) {\n\t var nextKnot = this._knot.nextKnot(this._side);\n\t this.state('EditingKnot', nextKnot);\n\t this.state('MovingControl', nextKnot, oppSide(this._side), this.curvePoint(event));\n\t }\n\t }),\n\t\n\t 'AddKnot': HandleBase.extend({\n\t //==========================================================================\n\t point: function () {\n\t // Use the middle of the curve\n\t var p = this._knot.pieceAt(this._side);\n\t return p ? p.eval(0.5) : null;\n\t },\n\t draw: function (context, transform) {\n\t if (!this._point) {\n\t return;\n\t }\n\t this.drawCurvePadBack(context, transform);\n\t var textureScale = this.textureScale;\n\t\n\t if (this._over) {\n\t context.fillStyle = colors.addKnot_over.rgba;\n\t (0, _gear.dot)(context, this._point, textureScale * knotSelectedSize, transform);\n\t } else {\n\t context.strokeStyle = colors.addKnot.rgba;\n\t context.lineWidth = textureScale * 0.5;\n\t (0, _gear.strokeDot)(context, this._point, textureScale * 2, transform);\n\t }\n\t },\n\t click: function (event) {\n\t var newKnot = this._knot.addKnot(this._side);\n\t this.state('EditingKnot', newKnot);\n\t this.state('MovingKnots', newKnot, this.curvePoint(event));\n\t }\n\t }),\n\t\n\t 'RemoveKnot': HandleBase.extend({\n\t //==========================================================================\n\t\n\t point: function () {\n\t var k = this._knot;\n\t return Point_add(k.point(), Point_sm(k.normal(), this.viewToCurve_dx(30)));\n\t },\n\t draw: function (context, transform) {\n\t if (!this.point) {\n\t return;\n\t }\n\t var textureScale = this.textureScale;\n\t // [TODO]\n\t\n\t var lineWidth = (this._over ? 2 : 1) * textureScale;\n\t var rs = (this._over ? 4 : 2) * textureScale;\n\t var point = this._point;\n\t\n\t context.lineWidth = lineWidth + 2 * textureScale;\n\t context.strokeStyle = colors.pad.rgba;\n\t (0, _gear.strokeCross)(context, point, rs + 1 * textureScale, transform);\n\t\n\t context.lineWidth = lineWidth;\n\t context.strokeStyle = colors.removeKnot.rgba;\n\t (0, _gear.strokeCross)(context, point, rs, transform);\n\t if (this._over) {\n\t context.lineWidth = lineWidth + 2 * textureScale;\n\t context.strokeStyle = colors.pad.rgba;\n\t (0, _gear.strokeDot)(context, this._knot.point(), (knotSelectedSize + 3) * textureScale, transform);\n\t\n\t context.strokeStyle = colors.removeKnot.rgba;\n\t context.lineWidth = lineWidth;\n\t (0, _gear.strokeDot)(context, this._knot.point(), (knotSelectedSize + 3) * textureScale, transform);\n\t }\n\t },\n\t click: function () /*view,event*/{\n\t this._knot.remove(this._state._tool);\n\t this.state('Iddle');\n\t this.onUpdate();\n\t }\n\t }),\n\t\n\t 'ConvertToCurve': HandleBase.extend({\n\t //==========================================================================\n\t point: function () {\n\t var p = this._knot.pieceAt(this._side);\n\t if (!(p instanceof _cdl.Segment)) {\n\t return null;\n\t }\n\t return p.eval(this._side === 'left' ? 2 / 3.0 : 1 / 3.0);\n\t },\n\t draw: function (context, transform) {\n\t if (!this._point) {\n\t return;\n\t }\n\t this.drawCurvePadBack(context, transform);\n\t\n\t var textureScale = this.textureScale;\n\t\n\t\n\t drawSegment(context, colors.controlSegment.rgba, this._knot.point(), this._point, transform, textureScale);\n\t\n\t context.fillStyle = colors.control.rgba;\n\t (0, _gear.dot)(context, this._point, 2 * textureScale, transform);\n\t },\n\t click: function (event) {\n\t this._knot.convertToCurve(this._side);\n\t this.state('MovingControl', this._knot, this._side, this.curvePoint(event));\n\t this.onUpdate();\n\t }\n\t }),\n\t\n\t 'ConvertToSegment': HandleBase.extend({\n\t //==========================================================================\n\t point: function () {\n\t var p = this._knot.pieceAt(this._side);\n\t if (!p || p instanceof _cdl.Segment) {\n\t return null;\n\t }\n\t return p.eval(this._side === 'left' ? 2 / 3.0 : 1 / 3.0);\n\t },\n\t draw: function (context, transform) {\n\t if (!this._point) {\n\t return;\n\t }\n\t\n\t var textureScale = this.textureScale;\n\t\n\t\n\t if (this._over) {\n\t var piece = this._knot.pieceAt(this._side);\n\t context.lineWidth = 4 * textureScale;\n\t context.strokeStyle = colors.pad.rgba;\n\t context.beginPath();\n\t piece.draw(context, transform);\n\t context.stroke();\n\t\n\t context.lineWidth = 2 * textureScale;\n\t context.strokeStyle = colors.removeKnot.rgba;\n\t context.beginPath();\n\t piece.draw(context, transform);\n\t context.stroke();\n\t\n\t context.lineWidth = 1 * textureScale;\n\t drawSegment(context, colors.curve.rgba, this._knot.point(), this._knot.nextKnot(this._side).point(), transform, textureScale);\n\t }\n\t\n\t this.drawCurvePadBack(context, transform);\n\t\n\t context.strokeStyle = colors.removeKnot.rgba;\n\t context.lineWidth = 1 * textureScale;\n\t var rs = 2 * textureScale;\n\t (0, _gear.strokeCross)(context, this._point, rs, transform);\n\t },\n\t click: function () /*view,event*/{\n\t this._knot.convertToSegment(this._side);\n\t this._state.focus();\n\t }\n\t })\n\t};\n\t\n\tvar State = {\n\t\n\t 'Iddle': BaseState.extend({\n\t // =========================================================\n\t }),\n\t\n\t 'EditingKnot': BaseState.extend({\n\t // =========================================================\n\t init: function (tool) {\n\t this.callParent(tool);\n\t this.focus();\n\t },\n\t toolhelp: function () {\n\t return ['Drag knots and control handles to modify curve', 'Double Click control handle to change curve type'];\n\t },\n\t focus: function () {\n\t var _this2 = this;\n\t\n\t this.showToolhelp();\n\t\n\t var knot = this._knot = this.selectedKnot();\n\t\n\t this._handles = [];\n\t\n\t var moreHandles = [new Handle.AddKnot(this, 'left'), new Handle.AddKnot(this, 'right'), new Handle.ConvertToCurve(this, 'left'), new Handle.ConvertToCurve(this, 'right'), new Handle.ConvertToSegment(this, 'left'), new Handle.ConvertToSegment(this, 'right')];\n\t\n\t // Only add handles if the buttons aren't that close to the knot\n\t var knotPoint = knot.point();\n\t var delta = this.view.viewDeltaToDoc(15);\n\t (0, _lodash.forEach)(moreHandles, function (h) {\n\t var point = h.point();\n\t if (point && !point.isNear(knotPoint, delta)) {\n\t _this2._handles.push(h);\n\t }\n\t });\n\t\n\t // Order is important, first move control points, then knots...\n\t this._handles = this._handles.concat([new Handle.Control(this, 'left'), new Handle.Control(this, 'right'), new Handle.NextControl(this, 'left'), new Handle.NextControl(this, 'right')]);\n\t\n\t // Do not let the user remove locked knots\n\t if (!this._knot.locked()) {\n\t this._handles.push(new Handle.RemoveKnot(this));\n\t }\n\t },\n\t draw: function (context, transform) {\n\t this.drawCurve(context, transform);\n\t (0, _lodash.forEach)(this._handles, function (h) {\n\t h.draw(context, transform);\n\t });\n\t this.drawKnots(context, transform);\n\t },\n\t down: function (event) {\n\t if ((0, _lodash.find)(this._handles, function (h) {\n\t return h.down(event);\n\t })) {\n\t return true;\n\t }\n\t return this.callParent(event);\n\t },\n\t mousemove: function (event) {\n\t (0, _lodash.forEach)(this._handles, function (h) {\n\t h.mousemove(event);\n\t });\n\t this.redraw();\n\t this.callParent(event);\n\t },\n\t move: function (event) {\n\t (0, _lodash.forEach)(this._handles, function (h) {\n\t h.move(event);\n\t });\n\t this.redraw();\n\t this.callParent(event);\n\t },\n\t on_dblclick: function (event) {\n\t (0, _lodash.find)(this._handles, function (h) {\n\t return h.on_dblclick(event);\n\t });\n\t },\n\t deleteAction: function () {\n\t var knot = this._knot;\n\t if (!knot.locked()) {\n\t knot.remove(this._tool);\n\t this.state('Iddle');\n\t this.onUpdate();\n\t }\n\t }\n\t }),\n\t\n\t 'DragSelection': BaseState.extend({\n\t // =========================================================\n\t init: function (tool, fromPoint) {\n\t this.callParent(tool);\n\t this._fromPoint = fromPoint;\n\t this._toPoint = fromPoint;\n\t },\n\t draw: function (context, transform) {\n\t this.callParent(context, transform);\n\t context.strokeStyle = colors.dragSelector.rgba;\n\t var fixedTransform = _cdl.Matrix.m(transform, this.matrixInverted);\n\t\n\t var frame = _cdl.Frame.ofPoints([this._fromPoint, this._toPoint]);\n\t frame.draw(context, fixedTransform);\n\t context.lineWidth = this.textureScale * 1;\n\t context.stroke();\n\t },\n\t down: function () {\n\t this.state('Iddle');\n\t return false;\n\t },\n\t move: function (_ref4) {\n\t var event = _ref4.event;\n\t var docPoint = _ref4.docPoint;\n\t\n\t this._toPoint = docPoint;\n\t this.redraw();\n\t },\n\t up: function (_ref5) {\n\t var _this3 = this;\n\t\n\t var event = _ref5.event;\n\t var shiftKey = _ref5.shiftKey;\n\t\n\t var tool = this._tool;\n\t var knots = [];\n\t var db = _cdl.Bounds.ofPoints([this._fromPoint, this._toPoint]);\n\t (0, _lodash.forEach)(tool._curves, function (curve) {\n\t forEachKnot(curve, function (knot) {\n\t if (db.contains(_this3.curveToDoc(knot.point()))) {\n\t knots.push(knot);\n\t }\n\t });\n\t });\n\t if (shiftKey) {\n\t knots = this.selectedKnots().concat(knots);\n\t }\n\t if (knots.length === 1) {\n\t this.state('EditingKnot', knots[0]);\n\t } else if (knots.length > 0) {\n\t this.state('SelectedKnots', knots);\n\t } else {\n\t this.state('Iddle');\n\t }\n\t }\n\t }),\n\t\n\t 'SelectedKnots': BaseState.extend({\n\t // =========================================================\n\t init: function (tool) {\n\t this.callParent(tool);\n\t },\n\t toolhelp: function () {\n\t return ['Drag knots to modify curve'];\n\t },\n\t focus: function () {\n\t this.showToolhelp();\n\t var c = this._possibleClick;\n\t if (c && (0, _lodash.now)() - c.time < 500) {\n\t this.state('EditingKnot', c.knot);\n\t } else {\n\t this._possibleClick = null;\n\t }\n\t },\n\t down: function (_ref6) {\n\t var event = _ref6.event;\n\t var shiftKey = _ref6.shiftKey;\n\t\n\t var knot = this.overSelectedKnots(event);\n\t if (knot) {\n\t if (!shiftKey) {\n\t this._possibleClick = { knot: knot, time: (0, _lodash.now)() };\n\t }\n\t this.state('MovingKnots', this.selectedKnots(), this.curvePoint(event));\n\t return true;\n\t }\n\t return this.callParent(event);\n\t },\n\t move: function (event) {\n\t this.callParent(event);\n\t },\n\t deleteAction: function () {\n\t var tool = this._tool;\n\t var knots = this.selectedKnots();\n\t for (var k = 0, kEnd = knots.length; k < kEnd; k++) {\n\t var knot = knots[k];\n\t if (!knot.locked()) {\n\t\n\t var ki = knot.ki;\n\t knot.remove(tool);\n\t\n\t // Correct indexes, to be able to continue removing other knots\n\t // This ended up quite complex because of using a direct view of\n\t // the curve representation [curve,ki]\n\t for (var i = k + 1, iEnd = knots.length; i < iEnd; i++) {\n\t var knot_i = knots[i];\n\t if (knot_i.ki > ki) {\n\t knot_i.ki--;\n\t }\n\t }\n\t }\n\t }\n\t this.state('Iddle');\n\t this.onUpdate();\n\t }\n\t }),\n\t\n\t 'MovingKnots': BaseState.extend({\n\t // =========================================================\n\t init: function (tool, fromPoint) {\n\t this.callParent(tool);\n\t this._fromPoint = fromPoint;\n\t this._points = (0, _lodash.map)(this.selectedKnots(), function (knot) {\n\t var point = knot.point();\n\t var left = knot.controlPoint('left');\n\t var right = knot.controlPoint('right');\n\t var r = { point: point, original: point.clone() };\n\t if (left) {\n\t r.left = left;\n\t r.originalLeft = left.clone();\n\t }\n\t if (right) {\n\t r.right = right;\n\t r.originalRight = right.clone();\n\t }\n\t return r;\n\t });\n\t\n\t //filter duplicated selected points\n\t var lFilteredPoints = [];\n\t this._points.forEach(function (p1) {\n\t if (!(0, _lodash.find)(lFilteredPoints, function (p2) {\n\t return p1.point == p2.point;\n\t })) lFilteredPoints.push(p1);\n\t });\n\t this._points = lFilteredPoints;\n\t },\n\t down: function () {\n\t this.state('Iddle');\n\t return false;\n\t },\n\t cacheOppositeKnot: function (aKnotId) {\n\t var lOppositeKnot = new Knot(this._tool._curves[0], aKnotId);\n\t if (this._oppositeKnotId != aKnotId) {\n\t if (this._oppositeKnotId != undefined) {\n\t this._oppositeKnot.point.set(this._oppositeKnot.original);\n\t this._oppositeKnot.left.set(this._oppositeKnot.originalLeft);\n\t this._oppositeKnot.right.set(this._oppositeKnot.originalRight);\n\t }\n\t\n\t this._oppositeKnotId = aKnotId;\n\t var lOppositePoint = lOppositeKnot.point();\n\t var lOppositeLeft = lOppositeKnot.controlPoint('left');\n\t var lOppositeRight = lOppositeKnot.controlPoint('right');\n\t this._oppositeKnot = { point: lOppositePoint, original: lOppositePoint.clone() };\n\t if (lOppositeLeft) {\n\t this._oppositeKnot.left = lOppositeLeft;\n\t this._oppositeKnot.originalLeft = lOppositeLeft.clone();\n\t }\n\t if (lOppositeRight) {\n\t this._oppositeKnot.right = lOppositeRight;\n\t this._oppositeKnot.originalRight = lOppositeRight.clone();\n\t }\n\t }\n\t return this._oppositeKnot;\n\t },\n\t move: function (event) {\n\t var fromPoint = this._fromPoint;\n\t var toPoint = this.curvePoint(event);\n\t var diff = Point_substract(toPoint, fromPoint);\n\t var diffOpposite = void 0;\n\t //This special shortcut works only if the figure is an envelope with no removed or added knots\n\t //So just 1 curve, with 8 knots\n\t //Also the user need to have only 1 point selected\n\t if ((event.ctrlKey || event.shiftKey) && this._points.length == 1 && this._tool._curves.length == 1 && this._tool._curves[0].pieces.length == 8) {\n\t var lIdx = this.selectedKnots()[0].ki;\n\t var p = this._points[0];\n\t var lOppositeKnot = void 0;\n\t //lIdx is the envelope knot index:\n\t // 6 5 4\n\t // 7 3\n\t // 0 1 2\n\t\n\t var lOpposite = 0;\n\t if (lIdx == 3 //3 and 7 move only right-left\n\t || lIdx == 7 || Math.abs(diff.x) > Math.abs(diff.y) && lIdx != 1 && lIdx != 5) //1 and 5 cant be moved right-left\n\t {\n\t switch (lIdx) {\n\t case 0:\n\t lOpposite = 2;break;\n\t case 2:\n\t lOpposite = 0;break;\n\t case 3:\n\t lOpposite = 7;break;\n\t case 4:\n\t lOpposite = 6;break;\n\t case 6:\n\t lOpposite = 4;break;\n\t case 7:\n\t lOpposite = 3;break;\n\t }\n\t diff = new _cdl.Point(diff.x, 0);\n\t lOppositeKnot = this.cacheOppositeKnot(lOpposite);\n\t if (event.shiftKey) diffOpposite = new _cdl.Point(-diff.x, p.original.y - lOppositeKnot.original.y);else diffOpposite = new _cdl.Point(diff.x, p.original.y - lOppositeKnot.original.y);\n\t } else {\n\t switch (lIdx) {\n\t case 0:\n\t lOpposite = 6;break;\n\t case 1:\n\t lOpposite = 5;break;\n\t case 2:\n\t lOpposite = 4;break;\n\t case 4:\n\t lOpposite = 2;break;\n\t case 5:\n\t lOpposite = 1;break;\n\t case 6:\n\t lOpposite = 0;break;\n\t }\n\t diff = new _cdl.Point(0, diff.y);\n\t lOppositeKnot = this.cacheOppositeKnot(lOpposite);\n\t if (event.shiftKey) diffOpposite = new _cdl.Point(p.original.x - lOppositeKnot.original.x, -diff.y);else diffOpposite = new _cdl.Point(p.original.x - lOppositeKnot.original.x, diff.y);\n\t }\n\t p.point.set(Point_add(p.original, diff));\n\t p.left.set(Point_add(p.originalLeft, diff));\n\t p.right.set(Point_add(p.originalRight, diff));\n\t lOppositeKnot.point.set(Point_add(lOppositeKnot.original, diffOpposite));\n\t lOppositeKnot.left.set(Point_add(lOppositeKnot.originalLeft, diffOpposite));\n\t lOppositeKnot.right.set(Point_add(lOppositeKnot.originalRight, diffOpposite));\n\t } else {\n\t if (this._oppositeKnotId != undefined) {\n\t this._oppositeKnotId = undefined;\n\t this._oppositeKnot.point.set(this._oppositeKnot.original);\n\t this._oppositeKnot.left.set(this._oppositeKnot.originalLeft);\n\t this._oppositeKnot.right.set(this._oppositeKnot.originalRight);\n\t }\n\t\n\t (0, _lodash.forEach)(this._points, function (p) {\n\t p.point.set(Point_add(p.original, diff));\n\t if (p.left) {\n\t p.left.set(Point_add(p.originalLeft, diff));\n\t }\n\t if (p.right) {\n\t p.right.set(Point_add(p.originalRight, diff));\n\t }\n\t });\n\t }\n\t this.redraw();\n\t this.callParent(event);\n\t },\n\t up: function () /*view,event*/{\n\t this.onUpdate();\n\t this.undoState();\n\t }\n\t }),\n\t\n\t 'MovingControl': BaseState.extend({\n\t // =========================================================\n\t init: function (tool, side, fromPoint) {\n\t var _this = this;\n\t _this.callParent(tool);\n\t _this._side = side;\n\t _this._fromPoint = fromPoint;\n\t var knot = _this._knot = _this.selectedKnot();\n\t _this._knotPoint = knot.point();\n\t _this._point = knot.controlPoint(side);\n\t _this._original = _this._point.clone();\n\t _this._corner = knot.corner();\n\t var opp = _this._opp = knot.controlPoint(oppSide(side));\n\t if (opp) {\n\t _this._originalOpp = opp.clone();\n\t }\n\t _this._handle = new Handle.Control(_this, side);\n\t _this._oppHandle = new Handle.Control(_this, oppSide(side));\n\t },\n\t draw: function (context, transform) {\n\t this._handle.draw(context, transform);\n\t this._oppHandle.draw(context, transform);\n\t this.callParent(context, transform);\n\t },\n\t down: function () {\n\t this.state('Iddle');\n\t return false;\n\t },\n\t move: function (event) {\n\t var _this = this,\n\t fromPoint = _this._fromPoint,\n\t toPoint = _this.curvePoint(event),\n\t diff = Point_substract(toPoint, fromPoint),\n\t point = _this._point,\n\t opp = _this._opp,\n\t knotPoint = _this._knotPoint;\n\t\n\t point.set(Point_add(_this._original, diff));\n\t _this._handle._point = point;\n\t\n\t if (opp) {\n\t var oppVec = Point_substract(point, knotPoint).sm(-1);\n\t if (_this._corner === 'curve') {\n\t if (!oppVec.isZero()) {\n\t var oppNorm = Point_substract(opp, knotPoint).norm();\n\t oppVec.sm(oppNorm / oppVec.norm());\n\t }\n\t opp.set(Point_add(knotPoint, oppVec));\n\t } else if (_this._corner === 'symmetric') {\n\t opp.set(Point_add(knotPoint, oppVec));\n\t }\n\t _this._oppHandle._point = opp;\n\t }\n\t\n\t _this.redraw();\n\t },\n\t up: function () {\n\t this.onUpdate();\n\t this.undoState();\n\t }\n\t })\n\t // =========================================================\n\t};\n\t\n\tvar NodeEditBaseTool = _view.Tool.extend({\n\t Properties: {\n\t alpha: { type: 'number', def: 1 }\n\t },\n\t initTool: function (view, figure) {\n\t if (figure && this.canEdit(figure)) {\n\t return this.startEditingFigure$(figure);\n\t }\n\t },\n\t startEdition: function () /*figure*/{},\n\t startEditingFigure$: function (figure) {\n\t var _this = this,\n\t view = this.view;\n\t _this._figure = null;\n\t return figure.update$().then(function () {\n\t view.unlock();\n\t _this._figure = figure;\n\t _this.startEdition(figure);\n\t _this._matrix = figure.matrix_();\n\t _this._matrixInverted = _this._matrix.inverted();\n\t _this._curves = _this.createCurves(figure);\n\t _this._undoState = [];\n\t _this._selectedKnots = [];\n\t _this._state = new State.Iddle(_this);\n\t _this.redraw();\n\t view.preview$();\n\t });\n\t },\n\t on_keydown: function (_ref7) {\n\t var view = _ref7.view;\n\t var event = _ref7.event;\n\t var altKey = _ref7.altKey;\n\t var which = _ref7.which;\n\t\n\t if (altKey) {\n\t event.preventDefault();\n\t this.on_keydown_alt(event);\n\t }\n\t\n\t if (!view._keyShortcuts) {\n\t return;\n\t }\n\t\n\t switch (which) {\n\t case 46:\n\t // 'Del'\n\t event.preventDefault();\n\t this._state.deleteAction();\n\t break;\n\t }\n\t },\n\t on_keyup: function (_ref8) {\n\t var event = _ref8.event;\n\t var altKey = _ref8.altKey;\n\t\n\t if (!altKey) {\n\t event.preventDefault();\n\t return this.on_keyup_alt(event);\n\t }\n\t },\n\t on_keydown_alt: function (_ref9) {\n\t var view = _ref9.view;\n\t\n\t if (!this._transparentMode) {\n\t this._transparentMode = true;\n\t view.redraw('document');\n\t this.redraw();\n\t view.render$();\n\t }\n\t },\n\t on_keyup_alt: function (_ref10) {\n\t var view = _ref10.view;\n\t\n\t if (this._transparentMode) {\n\t this._transparentMode = false;\n\t view.redraw('document');\n\t this.redraw();\n\t view.render$();\n\t }\n\t },\n\t state: function (s, sk) {\n\t var _this = this,\n\t undoState = _this._undoState;\n\t undoState.push(_this._state);\n\t if (undoState.length > 10) {\n\t undoState.shift();\n\t }\n\t\n\t _this._selectedKnots = !sk ? [] : (0, _gear.isArray)(sk) ? sk : [sk];\n\t\n\t for (var _len = arguments.length, params = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n\t params[_key - 2] = arguments[_key];\n\t }\n\t\n\t _this._state = new (Function.prototype.bind.apply(State[s], [null].concat([_this], _toConsumableArray(params))))();\n\t _this.redraw();\n\t },\n\t undoState: function () {\n\t this._state = this._undoState.pop();\n\t this._state.focus();\n\t this.redraw();\n\t },\n\t somethingToDraw: function () {\n\t return !!this._figure;\n\t },\n\t draw: function (_ref11) {\n\t var view = _ref11.view;\n\t var context = _ref11.context;\n\t var transform = _ref11.transform;\n\t\n\t if (!this._figure) {\n\t return;\n\t }\n\t\n\t // Draw figure being edited\n\t view.drawIsolatedFigures(this._alpha * (this._transparentMode ? 0.6 : 1));\n\t\n\t // Draw curves, knots and handles\n\t context.lineJoin = 'round';\n\t var ft = _cdl.Matrix.m(transform, this._matrix);\n\t this._state.draw(context, ft);\n\t },\n\t try_pointerdown: function (_ref12) {\n\t var event = _ref12.event;\n\t var isPrimary = _ref12.isPrimary;\n\t var docPoint = _ref12.docPoint;\n\t\n\t if (!this._figure) {\n\t return;\n\t }\n\t if (!isPrimary) {\n\t return; // ignore multitouch\n\t }\n\t if (!this._state.down(event)) {\n\t this._clickOut = { docPoint: docPoint };\n\t } else {\n\t event.stopPropagation();\n\t }\n\t },\n\t on_pointerdown: function (event) {\n\t this.try_pointerdown(event);\n\t },\n\t on_mousemove: function (_ref13) {\n\t var event = _ref13.event;\n\t\n\t if (!this._figure) {\n\t return;\n\t }\n\t this._state.mousemove(event);\n\t },\n\t on_pointermove: function (_ref14) {\n\t var event = _ref14.event;\n\t var isPrimary = _ref14.isPrimary;\n\t\n\t if (!this._figure) {\n\t return;\n\t }\n\t if (!isPrimary) {\n\t return; // ignore multitouch\n\t }\n\t var co = this._clickOut;\n\t if (co && !event.docPoint.isEqual(co.docPoint)) {\n\t this._clickOut = null;\n\t }\n\t this._state.move(event);\n\t },\n\t on_pointerup: function (_ref15) {\n\t var isPrimary = _ref15.isPrimary;\n\t var event = _ref15.event;\n\t\n\t if (!isPrimary) {\n\t return; // ignore multitouch\n\t }\n\t if (this._figure) {\n\t this._state.up(event);\n\t }\n\t\n\t if (this._clickOut || !this._figure) {\n\t this._clickOut = null;\n\t this._onClickOut(event);\n\t }\n\t },\n\t _onClickOut: function (_ref16) {\n\t var view = _ref16.view;\n\t var event = _ref16.event;\n\t var docPoint = _ref16.docPoint;\n\t var cmdKey = _ref16.cmdKey;\n\t\n\t\n\t var _this = this;\n\t var figure = event.figure; // [EVENTS] view.figureAtPoint( docPoint );\n\t if (figure && _this.canEdit(figure)) {\n\t _this.commitChanges$({ select: false }).then(function () {\n\t _this.startEditingFigure$(figure);\n\t });\n\t } else if (cmdKey) {\n\t _this.commit$();\n\t }\n\t },\n\t on_dblclick: function (event) {\n\t if (!this._figure || !this._state.on_dblclick(event)) {\n\t this.commit$();\n\t }\n\t },\n\t onUpdate: function () {\n\t // ...\n\t }\n\t});\n\t\n\tvar NodeEditTool = exports.NodeEditTool = NodeEditBaseTool.extend({ typeName: 'NodeEditTool',\n\t toolbarName: 'nodeEditTool',\n\t _hideOriginal: true,\n\t redraw: function () {\n\t this.callParent();\n\t if (this._figure) {\n\t this._figure.invalidateView();\n\t }\n\t this.view.preview$();\n\t },\n\t createCurves: function (figure) {\n\t var curves = [];\n\t (0, _lodash.forEach)(figure.polyregions, function (p) {\n\t (0, _lodash.forEach)(p.regions, function (r) {\n\t (0, _lodash.forEach)(r.curves, function (c, i) {\n\t if (!(c instanceof _cdl.Curve)) {\n\t c = c.convertToCurve();\n\t r.curves[i] = c;\n\t }\n\t // Curves are not currently properly owned\n\t // I am thinking that we should remove lazyCDL curves loading so we can just include it in our type system\n\t c._owner = r;\n\t curves.push(c);\n\t });\n\t });\n\t });\n\t return curves;\n\t },\n\t canEdit: function (figure) {\n\t return this.view.is(figure, 'nodeEditable');\n\t },\n\t startEdition: function (figure) {\n\t this.view.startIsolatedFiguresEdition([figure]);\n\t },\n\t _cancel$: function (view, doc) {\n\t view.stopIsolatedFiguresEdition();\n\t view.selectedFigures.set(this._figure);\n\t return doc.revert$();\n\t },\n\t _commit$: function (view) {\n\t view.stopIsolatedFiguresEdition();\n\t return this.commitChanges$();\n\t },\n\t commitChanges$: function (config) {\n\t var view = this.view,\n\t doc = view.document;\n\t // This is really important, grab the first envelope point\n\t // before the figure is invalidated\n\t var figure = this._figure;\n\t if (!figure) {\n\t return (0, _gear.resolve)();\n\t }\n\t if (figure._polyregions.length === 0) {\n\t view.remove(figure);\n\t return doc.commit$();\n\t }\n\t\n\t var referencePoint = figure.referencePoint_().clone();\n\t\n\t figure.invalidate();\n\t figure.visible = true;\n\t\n\t if (config && config.select !== false) {\n\t view.selectedFigures.set(figure);\n\t }\n\t\n\t return (0, _gear.if$)(!(figure._anchor._absolute && figure._pin.anchorBased()), function () {\n\t return figure._fixUpPin$('referencePoint_', referencePoint);\n\t }).then(function () {\n\t if (figure.document !== doc) {\n\t view.add(figure);\n\t }\n\t return doc.commit$();\n\t });\n\t }\n\t});\n\t_view.Tool.NodeEdit = NodeEditTool;\n\t\n\tvar NodeEditEnvelopeTool = exports.NodeEditEnvelopeTool = NodeEditBaseTool.extend({ typeName: 'NodeEditEnvelopeTool',\n\t toolbarName: 'nodeEditEnvelopeTool',\n\t canEdit: function (figure) {\n\t return figure.isText && !figure.isMultiPart || !!(0, _gear.findByType)(figure._processes, _cdl.Process.FitEnvelope);\n\t },\n\t startEdition: function (figure) {\n\t this.view.startIsolatedFiguresEdition([figure]);\n\t },\n\t _cancel$: function (view, doc) {\n\t if (_config.Config.localFitEnvelope) {\n\t return view.revert$();\n\t } else {\n\t view.selectedFigures.set(this._figure);\n\t }\n\t view.stopIsolatedFiguresEdition();\n\t },\n\t _commit$: function (view) {\n\t view.stopIsolatedFiguresEdition();\n\t return this.commitChanges$();\n\t },\n\t createCurves: function (figure) {\n\t // We create a envelope { figure, process, editable } for every envelope in the figure\n\t var process = (0, _gear.findByType)(figure.processes, _cdl.Process.FitEnvelope);\n\t this._addOnCommit = !process;\n\t if (!process) {\n\t process = _cdl.Process.FitEnvelope.createFromFigure(figure);\n\t }\n\t this._process = process;\n\t\n\t // Convert the envelope to one closed curve\n\t var pieces = [];\n\t (0, _lodash.forEach)(process.envelope().curves, function (c) {\n\t // Flag it\n\t var ps = (0, _gear.cloneDeep)(c.pieces);\n\t ps[0].P0.__cadx_locked = true;\n\t pieces = pieces.concat(ps);\n\t });\n\t\n\t return [_cdl.Curve.fromNonTiedPieces(pieces, true)];\n\t },\n\t onUpdate: function () {\n\t var _this4 = this;\n\t\n\t if (_config.Config.localFitEnvelope) {\n\t var _ret = function () {\n\t var view = _this4.view;\n\t return {\n\t v: _this4.updateFigure$().then(function () {\n\t view.unlock();\n\t _this4.redraw();\n\t view.preview$();\n\t })\n\t };\n\t }();\n\t\n\t if (typeof _ret === \"object\") return _ret.v;\n\t }\n\t },\n\t updateFigure$: function () {\n\t var _this = this;\n\t var figure = _this._figure;\n\t if (!figure) {\n\t return (0, _gear.resolve)();\n\t }\n\t var process = _this._process;\n\t var addOnCommit = _this._addOnCommit;\n\t return (0, _gear.if$)(addOnCommit, function () {\n\t _this._addOnCommit = false;\n\t return figure.center$().then(function (center) {\n\t figure._processes.add(process);\n\t figure.pin = center;\n\t });\n\t }).then(function () {\n\t\n\t return figure.matrix$().then(function (matrix) {\n\t\n\t var oldEnvelopeCenter = matrix.apply(process._envelope.center);\n\t\n\t var curve = _this._curves[0];\n\t\n\t // Get the four curves from envelopeCurve\n\t var curves = [];\n\t var currentPieces = [];\n\t var createCurve = function () {\n\t if (currentPieces.length > 0) {\n\t curves.push(new _cdl.Curve.fromNonTiedPieces(currentPieces, false));\n\t currentPieces = [];\n\t }\n\t };\n\t (0, _lodash.forEach)(curve.pieces, function (p) {\n\t if (p.P0.__cadx_locked === true) {\n\t createCurve();\n\t }\n\t currentPieces.push(p.clone());\n\t });\n\t createCurve();\n\t\n\t process.envelope(new _cdl.Envelope(curves));\n\t\n\t var newEnvelopeCenter = matrix.apply(process._envelope.center);\n\t\n\t var offset = _cdl.Point.substract(newEnvelopeCenter, oldEnvelopeCenter);\n\t figure.translate(offset);\n\t\n\t return figure;\n\t });\n\t });\n\t },\n\t commitChanges$: function (config) {\n\t var view = this.view,\n\t figure = this._figure;\n\t return this.updateFigure$().then(function () {\n\t if (config && config.select !== false) {\n\t view.selectedFigures.set(figure);\n\t }\n\t return view.commit$();\n\t });\n\t }\n\t});\n\t_view.Tool.NodeEditEnvelope = NodeEditEnvelopeTool;\n\n/***/ },\n\n/***/ 165:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.RenderInfoTool = undefined;\n\t\n\tvar _lodash = __webpack_require__(4);\n\t\n\tvar _cdl = __webpack_require__(15);\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar _selectTransform = __webpack_require__(154);\n\t\n\tvar RenderInfoTool = exports.RenderInfoTool = _view.Tool.extend({ typeName: 'RenderInfoTool',\n\t type: 'Final',\n\t toolbarName: 'renderInfoTool',\n\t initTool: function (view, figure) {\n\t var _this = this;\n\t\n\t this.handles = new _selectTransform.SelectAndTransformHandles({\n\t\n\t view: this.view,\n\t tool: this,\n\t\n\t editingItems: function () {\n\t var figure = _this._figure;\n\t return figure ? [figure] : [];\n\t },\n\t\n\t getOriginalTransforms: function () {\n\t _this._downFrame = _this.computeRenderFrame_();\n\t _this._downMatrix22 = _this._polyregion.renderMatrix || new _cdl.Matrix();\n\t },\n\t\n\t setOriginalTransforms: function () {\n\t // Directly handle revert in transformItems\n\t },\n\t\n\t computeItemsFrame_: this.computeRenderFrame_.bind(this),\n\t\n\t transformItems: this.transformItems.bind(this),\n\t\n\t itemsEnabledTransforms: function () {\n\t return {\n\t translate: true,\n\t scale: true,\n\t rotate: true\n\t };\n\t }\n\t });\n\t\n\t if (figure) {\n\t this.startEdit(figure);\n\t }\n\t },\n\t computeRenderFrame_: function () {\n\t var polyregion = this._polyregion;\n\t return (polyregion.renderFrame || polyregion.initialRenderFrame()).transformed(this._figure.globalMatrix_());\n\t },\n\t transformItems: function (items, transform) {\n\t var figure = this._figure,\n\t polyregion = this._polyregion,\n\t downFrame = this._downFrame,\n\t downMatrix22 = this._downMatrix22;\n\t\n\t var mi = figure.matrix_().inverted();\n\t\n\t var mi_transform = _cdl.Matrix.m(mi, transform);\n\t\n\t polyregion.renderMatrix = _cdl.Matrix.m(_cdl.Matrix.rotate(mi_transform.angle()), downMatrix22);\n\t polyregion.renderFrame = downFrame.transformed(mi_transform);\n\t },\n\t startEdit: function (figure, point) {\n\t var view = this.view;\n\t this._figure = figure;\n\t this._polyregion = point ? figure.polyregionAtPoint_(point) : (0, _lodash.last)(figure._polyregions);\n\t this.handles.update();\n\t this.redraw();\n\t view.render$();\n\t },\n\t link: function (view) {\n\t this.handles.create();\n\t // [TODO] Abstract\n\t var h = this.handles.handles; // grab internal handles\n\t h._fillColor = '#6e78d1';\n\t h._fillOverColor = '#243788';\n\t h._fillActiveColor = '#fb603d';\n\t h._strokeColor = '#243788';\n\t\n\t view.on({ 'rendercomplete': this.on_rendercomplete }, this);\n\t },\n\t unlink: function (view) {\n\t view.un(this);\n\t this.handles.dispose();\n\t },\n\t on_rendercomplete: function () {\n\t if (!(0, _lodash.includes)(this.view.figures, this._figure)) {\n\t this._figure = null;\n\t }\n\t this.handles.update();\n\t },\n\t on_pointerdown: function (_ref) {\n\t var view = _ref.view;\n\t var event = _ref.event;\n\t var isPrimary = _ref.isPrimary;\n\t var docPoint = _ref.docPoint;\n\t\n\t if (!isPrimary) {\n\t return;\n\t }\n\t\n\t var hs = this.handles;\n\t if (hs._editionMode) {\n\t hs.up(event);\n\t return;\n\t }\n\t\n\t var leftClick = event.which === 1;\n\t if (!leftClick) {\n\t return;\n\t }\n\t\n\t if (hs.isHandle(event)) {\n\t event.stopPropagation();\n\t hs.down(event);\n\t } else {\n\t\n\t var figure = event.figure; // [EVENTS] view.figureAtPoint(docPoint);\n\t if (figure && figure.isShape) {\n\t this.startEdit(figure, docPoint);\n\t }\n\t }\n\t },\n\t on_pointermove: function (event) {\n\t this.handles.move(event);\n\t },\n\t on_pointerup: function (event) {\n\t this.handles.up(event);\n\t },\n\t draw: function (config) {\n\t this.handles.draw(config);\n\t }\n\t});\n\t\n\t_view.Tool.ClippingBounds = _view.Tool.extend({ typeName: 'ClippingBoundsTool',\n\t type: 'Final',\n\t toolbarName: 'clippingBoundsTool',\n\t initTool: function (view, figure) {\n\t var _this2 = this;\n\t\n\t this.handles = new _selectTransform.SelectAndTransformHandles({\n\t\n\t view: this.view,\n\t tool: this,\n\t\n\t editingItems: function () {\n\t var figure = _this2._figure;\n\t return figure ? [figure] : [];\n\t },\n\t\n\t getOriginalTransforms: function () {\n\t _this2._downFrame = _this2.clippingFrame();\n\t _this2._downClippingBounds = _this2._brush.clippingBounds.clone();\n\t _this2._downTextureOffset = _this2._brush.textureOffset.clone();\n\t // this._downPin = this._figure.globalMatrix_().apply( this.clippingFrame().center );\n\t },\n\t\n\t setOriginalTransforms: function () {\n\t // Directly handle revert in transformItems\n\t },\n\t\n\t computeItemsFrame_: this.clippingFrame.bind(this),\n\t\n\t transformItems: this.transformItems.bind(this),\n\t\n\t itemsEnabledTransforms: function () {\n\t return {\n\t translate: true,\n\t scale: true\n\t };\n\t }\n\t });\n\t\n\t if (figure) {\n\t this.startEdit(figure);\n\t }\n\t },\n\t startEdit: function (figure, point) {\n\t var view = this.view;\n\t this._figure = null;\n\t if (figure.isShape) {\n\t var polyregion = point ? figure.polyregionAtPoint_(point) : (0, _lodash.last)(figure._polyregions);\n\t var brush = polyregion.brush;\n\t if (brush instanceof _cdl.TextureBrushBase) {\n\t this._figure = figure;\n\t this._polyregion = polyregion;\n\t this._brush = brush;\n\t }\n\t }\n\t this.handles.update();\n\t this.redraw();\n\t view.render$();\n\t },\n\t link: function (view) {\n\t this.handles.create();\n\t\n\t var h = this.handles.handles;\n\t h._fillColor = '#6e78d1';\n\t h._fillOverColor = '#243788';\n\t h._fillActiveColor = '#fb603d';\n\t h._strokeColor = '#243788';\n\t\n\t view.on({ 'rendercomplete': this.on_rendercomplete }, this);\n\t },\n\t unlink: function (view) {\n\t view.un(this);\n\t this.handles.dispose();\n\t },\n\t on_rendercomplete: function () {\n\t if (!(0, _lodash.includes)(this.view.figures, this._figure)) {\n\t this._figure = null;\n\t }\n\t this.handles.update();\n\t },\n\t on_pointerdown: function (_ref2) {\n\t var view = _ref2.view;\n\t var event = _ref2.event;\n\t var isPrimary = _ref2.isPrimary;\n\t var which = _ref2.which;\n\t var docPoint = _ref2.docPoint;\n\t\n\t if (!isPrimary) {\n\t return;\n\t }\n\t\n\t var hs = this.handles;\n\t if (hs._editionMode) {\n\t hs.up(event);\n\t return;\n\t }\n\t\n\t var leftClick = which === 1;\n\t if (!leftClick) {\n\t return;\n\t }\n\t\n\t if (hs.isHandle(event)) {\n\t event.stopPropagation();\n\t hs.down(event);\n\t } else {\n\t\n\t var figure = event.figure; // [EVENTS] view.figureAtPoint(docPoint);\n\t if (figure && figure.isShape) {\n\t this.startEdit(figure, docPoint);\n\t }\n\t }\n\t },\n\t on_pointermove: function (event) {\n\t this.handles.move(event);\n\t },\n\t on_pointerup: function (event) {\n\t this.handles.up(event);\n\t },\n\t draw: function (config) {\n\t this.handles.draw(config);\n\t },\n\t renderFrame: function () {\n\t var figure = this._figure,\n\t polyregion = this._polyregion;\n\t var matrix = figure.globalMatrix_();\n\t return (polyregion.renderFrame || polyregion.initialRenderFrame()).transformed(matrix);\n\t },\n\t clippingFrame: function () {\n\t return this._brush.clippingFrame_(this.renderFrame());\n\t },\n\t transformItems: function (items, transform) {\n\t\n\t var brush = this._brush,\n\t frame_0 = this._downFrame;\n\t\n\t var frame_1 = frame_0.transformed(transform);\n\t\n\t var rotate = _cdl.Matrix.rotate(-frame_0.angle());\n\t\n\t var fr_0 = frame_0.transformed(rotate);\n\t\n\t var ocb = this._downClippingBounds;\n\t\n\t var scale = _cdl.Matrix.scale(ocb.width / fr_0.width, ocb.height / fr_0.height);\n\t\n\t var frs_0 = fr_0.transformed(scale);\n\t\n\t var translate = _cdl.Matrix.translate(ocb.lx_ly.minus(frs_0.p0));\n\t\n\t var ncb = frame_1.transformed(_cdl.Matrix.concat(translate, scale, rotate)).bounds;\n\t\n\t brush.clippingBounds = ncb;\n\t\n\t var dto = this._downTextureOffset;\n\t\n\t var nto = new _cdl.Point((ocb.lx + dto.x * ocb.width - ncb.lx) / ncb.width, (ocb.ly + dto.y * ocb.height - ncb.ly) / ncb.height);\n\t\n\t brush.textureOffset = nto;\n\t }\n\t});\n\t\n\t_view.Tool.RenderInfo = RenderInfoTool;\n\n/***/ },\n\n/***/ 166:\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.SelectBrushTool = undefined;\n\t\n\tvar _view = __webpack_require__(84);\n\t\n\tvar SelectBrushTool = exports.SelectBrushTool = _view.Tool.extend({\n\t\n\t type: 'Select',\n\t\n\t toolbarName: 'selectBrush',\n\t allowKeyShortcuts: true,\n\t\n\t initTool: function (view, config) {\n\t var th = ['Click to select a brush'];\n\t this.toolhelp(th);\n\t },\n\t on_pointerdown: function (_ref) {\n\t var view = _ref.view;\n\t var event = _ref.event;\n\t var which = _ref.which;\n\t var cmdKey = _ref.cmdKey;\n\t var docPoint = _ref.docPoint;\n\t var pointers = _ref.pointers;\n\t\n\t var leftClick = which === 1;\n\t if (!leftClick) {\n\t return;\n\t }\n\t view.fireEvent('brushselected', view.getBrushAtPoint(docPoint));\n\t event.stopPropagation();\n\t },\n\t on_pointerup: function (event) {}\n\t});\n\t\n\t_view.Tool.SelectBrush = SelectBrushTool;\n\n/***/ }\n\n})\n});\n;\n\n\n/** WEBPACK FOOTER **\n ** tools.js\n **/","import { assign } from 'lodash';\r\n\r\nimport * as Tool from '../ui/tool';\r\n\r\nlet { Cx } = window;\r\n\r\nassign( Cx, Tool );\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/web/tools.js\n **/","export * from './select';\r\nexport * from './zoom';\r\nexport * from './pan';\r\nexport * from './clip';\r\nexport * from './power-clip';\r\nexport * from './add-figure';\r\nexport * from './draw';\r\nexport * from './free-draw';\r\nexport * from './edit-text';\r\nexport * from './chars-transform';\r\nexport * from './node-edit';\r\nexport * from './render-info';\r\nexport * from './select-brush';\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/index.js\n **/","import { Config } from 'config';\r\n\r\nimport { forEach, filter, includes, now, assign } from 'lodash';\r\n\r\nimport { setLineDash } from 'gear';\r\n\r\nimport { Point, Frame, updateArray$ } from 'cdl';\r\n\r\nimport { Tool } from '../view';\r\n\r\nimport { OptimizedFiguresHandles } from './select-transform';\r\n\r\nimport { DragSelectorHelper } from './drag-selector';\r\n\r\nexport const SelectBaseTool = Tool.extend({\r\n\r\n type: 'Select',\r\n\r\n toolbarName: 'selectTool',\r\n allowKeyShortcuts: true,\r\n isCommitable: false,\r\n\r\n Properties: {\r\n selectAndDragEnabled: { type: 'boolean', def: true },\r\n },\r\n\r\n resume() {\r\n this.callParent();\r\n this.handles.update();\r\n this.setIddleToolhelp();\r\n },\r\n\r\n initTool( view, config ) {\r\n assign(this, config || {});\r\n\r\n this.handles = new OptimizedFiguresHandles({ view, tool: this,\r\n\r\n editingItems( view ) {\r\n return view.selectedFigures;\r\n },\r\n\r\n onItemsDrag( event, figures ) {\r\n view.fireEvent('figuresdrag',event,figures);\r\n },\r\n onItemsDrop({ view, event }, figures ) {\r\n const onDrop = { cancelMove: false };\r\n if( event ) {\r\n view.fireEvent('figuresdrop',event,figures,onDrop); // [TODO] FiguresDropEvent\r\n }\r\n\r\n const cancelMove = onDrop.cancelMove;\r\n if( cancelMove ) {\r\n this.absoluteTranslate( new Point(0,0) );\r\n }\r\n\r\n const notRemovedFigures = [];\r\n const { doc } = view;\r\n forEach( figures, figure => {\r\n if( figure.document === doc ) {\r\n notRemovedFigures.push( figure );\r\n }\r\n });\r\n return notRemovedFigures.length > 0 && ! cancelMove;\r\n },\r\n\r\n setIddleToolhelp: () => this.setIddleToolhelp()\r\n });\r\n\r\n this._transparentMode = false;\r\n },\r\n\r\n setIddleToolhelp() {\r\n const th = ['Click or draw rectangle to select','Ctrl and drag Canvas to pan'];\r\n if( this.view.selectedFigures.length > 0 ) {\r\n th.push('Shift to aggregate to selection');\r\n th.push('Alt to make selected figures transparent');\r\n th.push('Alt-Click to select figure below selection');\r\n }\r\n this.toolhelp(th);\r\n },\r\n\r\n link( view ) {\r\n view.on({\r\n 'rendercomplete': this.on_rendercomplete//,\r\n //'change' : this.on_change,\r\n //'resize' : this.on_change\r\n }, this );\r\n\r\n this.handles.create();\r\n },\r\n\r\n unlink( view ) {\r\n view.un(this);\r\n\r\n this.handles.dispose();\r\n },\r\n\r\n on_dblclick({ view, docPoint }) {\r\n\r\n const selectedFigures = view.selectedFigures;\r\n\r\n if( selectedFigures.length === 1 ) {\r\n const figure = selectedFigures[0];\r\n if( view.canEditContent(figure) ) { // [TODO] && view._dblclickContentEditionEnabled(figure) ) {\r\n view.editContent(figure,docPoint);\r\n }\r\n }\r\n else if( view.editingContent() ) {\r\n view.commitContent$();\r\n }\r\n },\r\n\r\n onSelectionChanged(/* view */) {\r\n /*\r\n const tm = this._transparentMode;\r\n if( tm ) {\r\n forEach( this._transparentFigureViews, fv => { fv.hideMask(); });\r\n this._transparentMode = false;\r\n this.on_keydown_alt(view);\r\n }\r\n */\r\n this.setIddleToolhelp();\r\n this.redraw();\r\n },\r\n\r\n draw( config ) {\r\n\r\n // Draw selected texture island, we should make this a plugin\r\n // [TODO] Hacking in missing features from v5, later clean up\r\n const { view, context, transformModel } = config;\r\n const docIslands = filter( view.selectedFigures, figure => figure.metadata.get('textureIslandName') );\r\n if( view.is3D && view.model && docIslands.length > 0 ) {\r\n forEach( docIslands, docIsland => {\r\n const modelIsland = view.model.modelIslandFor(docIsland);\r\n context.strokeStyle = '#f2f2f2';\r\n context.lineWidth = 25;\r\n modelIsland.draw(context,transformModel,{ customDraw: c => c.stroke() });\r\n context.strokeStyle = '#388638';\r\n context.lineWidth = 20;\r\n setLineDash(context,[6,4]);\r\n modelIsland.draw(context,transformModel,{ customDraw: c => c.stroke() });\r\n });\r\n }\r\n else {\r\n\r\n this.handles.draw(config);\r\n }\r\n },\r\n\r\n useAggregateMode({ shiftKey, cmdKey }) {\r\n return shiftKey || ( Config.ctrlAggregation && cmdKey );\r\n },\r\n useContentEditMode({ cmdKey }) {\r\n return ! Config.ctrlAggregation && cmdKey;\r\n },\r\n\r\n try_pointerdown({ view, event }) {\r\n\r\n const { handles } = this;\r\n\r\n if( handles.isHandle(event) ) {\r\n\r\n if( handles.isHandleEnabledAt(event) ) {\r\n handles.down(event);\r\n event.stopPropagation();\r\n }\r\n\r\n // Clicking selection\r\n // If there is no mouse movement for a few milliseconds,\r\n // we should select this figure in the next mouse up.\r\n this._possibleClicking = { event, time: now() };\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n on_pointerdown({ view, event, which, cmdKey, docPoint, pointers }) {\r\n\r\n const { handles } = this;\r\n\r\n if( pointers.length === 2 ) {\r\n\r\n if( handles._editionMode ) {\r\n event.stopPropagation();\r\n return;\r\n }\r\n\r\n this._possibleDrag = null;\r\n this.helper = null;\r\n return;\r\n }\r\n\r\n if( handles._editionMode ) {\r\n this._endMode(event);\r\n return;\r\n }\r\n\r\n const leftClick = which === 1;\r\n if( ! leftClick ) {\r\n // right click on empty design area?\r\n if( ! event.figure ) { // [EVENTS] some( view.selectedFigures, figure => figure.canBeSelected() && figure.frame_().contains(docPoint) )) {\r\n // [TODO] stop event?\r\n view.clearSelection();\r\n view.render$();\r\n }\r\n return ;\r\n }\r\n\r\n if( ! this.try_pointerdown(event) ) {\r\n\r\n const { figureHit } = event; // get top most figure at point\r\n\r\n const { handles } = this;\r\n\r\n const possibleDrag = () => {\r\n if( ! cmdKey ) {\r\n if( ! this.useAggregateMode(event) ) {\r\n view.clearSelection();\r\n }\r\n view.render$();\r\n this._possibleDrag = { event };\r\n }\r\n };\r\n\r\n if( figureHit ) { // click directly on figure (not handle)?\r\n\r\n const { figure, tight } = figureHit;\r\n if( tight && this.selectAndDragEnabled && ! ( view.is3D && ! view.selectAndDragEnabled ) ) { // [TODO] Review...\r\n\r\n this._figureClicked( figure, event );\r\n\r\n // [TODO] Review, hacking my way to production now, allow to select and drag the 3D model\r\n // in case the figure is not movable\r\n\r\n const movable = view.is(figure,'movable');\r\n if( movable ) {\r\n event.stopPropagation();\r\n handles.update(); // Needed for select and drag\r\n handles.down(event);\r\n }\r\n\r\n view.render$();\r\n }\r\n else {\r\n this._possibleClicking = { event, time: now() };\r\n possibleDrag();\r\n }\r\n\r\n return;\r\n }\r\n else { // click on empty design area?\r\n possibleDrag();\r\n }\r\n }\r\n },\r\n\r\n on_mousemove( event ) {\r\n this.handles.mousemove(event);\r\n },\r\n\r\n on_pointermove({ view, event }) {\r\n const { _possibleDrag } = this;\r\n if( _possibleDrag ) {\r\n this.helper = new DragSelectorHelper(_possibleDrag.event,this._dragEnd.bind(this));\r\n this._possibleDrag = null;\r\n }\r\n this.handles.move(event);\r\n },\r\n\r\n on_pointerup( event ) {\r\n this._endMode(event);\r\n },\r\n\r\n _endMode({ view, event, viewPoint }) {\r\n\r\n this.handles.up(event);\r\n\r\n this._possibleDrag = null;\r\n\r\n const pc = this._possibleClicking;\r\n if( pc ) {\r\n const t = now();\r\n if( t - pc.time < 500 ) {\r\n const pc_event = pc.event;\r\n const pcViewPoint = pc_event.viewPoint;\r\n\r\n // Allow small shifts, accepted as clicks\r\n if( Math.abs(pcViewPoint.x-viewPoint.x) <= 1 &&\r\n Math.abs(pcViewPoint.y-viewPoint.y) <= 1 ) {\r\n\r\n const { figure } = pc.event;\r\n\r\n if( figure ) {\r\n // Add the selected figure\r\n this._figureClicked( figure, pc_event );\r\n view.render$();\r\n }\r\n else if( this.useContentEditMode(pc_event) && view.editingContent() ) {\r\n view.commitContent$();\r\n }\r\n }\r\n }\r\n this._possibleClicking = null;\r\n }\r\n },\r\n\r\n on_rendercomplete() {\r\n this.handles.update();\r\n },\r\n\r\n _dragEnd({ view, event }, bounds ) {\r\n\r\n if( bounds.width > 0 && bounds.height > 0 ) {\r\n\r\n const { selectedFigures } = view;\r\n const figures = view.activeSelectableFigures(); // [TODO]\r\n\r\n updateArray$(figures) .then( () => {\r\n\r\n const selection = filter( figures, figure => {\r\n\r\n // Is Inside Bounds\r\n const fb = figure.bounds_();\r\n return fb.lx > bounds.lx &&\r\n fb.ly > bounds.ly &&\r\n fb.hx < bounds.hx &&\r\n fb.hy < bounds.hy ;\r\n });\r\n\r\n if( selection.length > 0 ) {\r\n // Force selection of upper layer figures first\r\n selection.reverse();\r\n\r\n selectedFigures.add(selection);\r\n }\r\n\r\n view.render$();\r\n });\r\n }\r\n },\r\n\r\n _figureClicked( figure, event ) {\r\n const view = this.view;\r\n const selectedFigures = view.selectedFigures;\r\n\r\n view.activeDocument = figure.document;\r\n\r\n if( this.useContentEditMode(event) &&\r\n view.canEditContent(figure) ) { // [TODO] && view._dblclickContentEditionEnabled(figure) ) {\r\n return view.editContent(figure,view.docPoint(event));\r\n }\r\n\r\n if( this.useAggregateMode(event) ) {\r\n\r\n if( includes(selectedFigures,figure) ) {\r\n selectedFigures.remove(figure);\r\n }\r\n else {\r\n selectedFigures.add(figure);\r\n }\r\n }\r\n // Avoid selectionChanged event in case it is already selected\r\n else if( ! ( selectedFigures.length === 1 && selectedFigures[0] === figure ) ) {\r\n\r\n selectedFigures.set( [ figure ] );\r\n }\r\n\r\n },\r\n\r\n somethingToDraw() {\r\n return this.handles.visible;\r\n },\r\n\r\n needsToDrawFor( docIsland ) {\r\n const { frame } = this.handles;\r\n return !!frame && Frame.areOverlapping( docIsland.frame_(), this.handles.frame );\r\n }\r\n});\r\n\r\nexport const SelectTool = SelectBaseTool.extend({ typeName: 'SelectTool',\r\n\r\n canUndo() {\r\n return this.view.doc.canUndo();\r\n },\r\n undo() {\r\n return this.view.doc.undo();\r\n },\r\n\r\n canRedo() {\r\n return this.view.doc.canRedo();\r\n },\r\n redo() {\r\n return this.view.doc.redo();\r\n },\r\n\r\n supportsClipboard() {\r\n return true;\r\n }\r\n});\r\nTool.Select = SelectTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/select.js\n **/","import { forEach, map, difference, assign } from 'lodash';\r\n\r\nimport { Base, clone } from 'gear';\r\n\r\nimport { Point, Matrix, Frame, Figures } from 'cdl';\r\n\r\nimport { SelectHandles } from './select-handles';\r\n\r\nconst _abs = Math.abs;\r\n\r\nconst { dotProduct, substract } = Point;\r\n\r\nexport function computeScale( pin, dir, mousePos, initialMousePos, zoomScale ) {\r\n\r\n const initialDiff = substract(initialMousePos,pin);\r\n\r\n const currentDiff = substract(mousePos,pin);\r\n\r\n const dpi = dotProduct(initialDiff,dir);\r\n\r\n let dpc = dotProduct(currentDiff,dir);\r\n if( _abs(dpc) < 8 * zoomScale ) {\r\n if( _abs(dpi) < 8 * zoomScale ) {\r\n dpc = dpi ;\r\n }\r\n else {\r\n dpc = 8 * zoomScale * ((dpc<0)?-1:1) ;\r\n }\r\n }\r\n\r\n return {\r\n pin: pin.clone(),\r\n sx: dpc / dpi,\r\n deg: dir.angle()\r\n };\r\n}\r\n\r\nfunction computeShear( pin, dir, mousePos, initialMousePos ) {\r\n // http://www.w3.org/TR/SVG11/coords.html\r\n // http://jsfiddle.net/jbpEk/\r\n // http://jsfiddle.net/jbpEk/26/\r\n\r\n const initialDiff = substract(initialMousePos,pin);\r\n const currentDiff = substract(mousePos ,pin);\r\n const dpc = dotProduct(currentDiff,dir) ;\r\n const dpi = dotProduct(initialDiff,dir) ;\r\n\r\n let dpcPa = _abs( dotProduct(initialDiff,dir.perpendicular(-1)) ) ;\r\n\r\n if( dpcPa < 8 ) {\r\n dpcPa = 8;\r\n }\r\n\r\n const r = {\r\n deg: dir.angle(),\r\n sx: (dpc-dpi)/dpcPa,\r\n sy: 0,\r\n pin: pin.clone()\r\n };\r\n\r\n return r;\r\n}\r\n\r\n// Computes the rotation in radians.\r\nfunction computeRotation( pin, mousePos) {\r\n return mousePos. minus( pin ) .angle();\r\n}\r\n\r\nfunction computeFiguresFrame_( figures ) {\r\n if( figures.length === 1 ) {\r\n return figures[0].frame_();\r\n }\r\n return Frame.fromBounds( Figures.bounds_(figures) );\r\n}\r\n\r\nfunction figuresSnapToPoints( view, editingFigures ) {\r\n\r\n const snapTo = [];\r\n\r\n const viewBounds = view.bounds;\r\n forEach( view.horizontalUserLines, userLine => {\r\n if( userLine._snap ) {\r\n const snapPoint = new Point(userLine._position,viewBounds.ly);\r\n snapTo.push({ lx_ly: snapPoint, center: snapPoint, hx_hy: snapPoint });\r\n }\r\n });\r\n forEach( view.verticalUserLines, userLine => {\r\n if( userLine._snap ) {\r\n const snapPoint = new Point(viewBounds.lx,userLine._position);\r\n snapTo.push({ lx_ly: snapPoint, center: snapPoint, hx_hy: snapPoint });\r\n }\r\n });\r\n\r\n snapTo.push({ center: Figures.bounds_(editingFigures).center });\r\n\r\n forEach( difference(view.activePageFigures,editingFigures), figure => {\r\n const { lx_ly, center, hx_hy } = figure.frame_().bounds;\r\n snapTo.push({ lx_ly, center, hx_hy });\r\n });\r\n\r\n return snapTo;\r\n}\r\n\r\n\r\n// We should divide this into several helpers\r\n\r\nconst FrameInteractionMixin = {\r\n\r\n // expects\r\n //\r\n // members:\r\n // view, handles\r\n //\r\n // functions:\r\n // editingItems(view) => items\r\n // getOriginalTransforms(items) => transforms\r\n // setOriginalTransforms(items,transforms)\r\n // transformItems(items,transform)\r\n //\r\n // optional:\r\n // setOriginalPositions(items,transforms)\r\n // translateItems(items,offset)\r\n // snapToPoints(view,items) => [ { lx_ly, center, hx_hy }, ... ]\r\n // transformWithFixedCenter(view,items) => boolean\r\n // scaleOriginalXY(view,items) => { scaleX : s00, scaleY : s11 }\r\n // setIddleToolhelp()\r\n\r\n initFrameInteraction() {\r\n assign( this, {\r\n _data: null,\r\n _editingItems: null,\r\n _originalTransforms: null,\r\n _editionMode: false,\r\n _downFrame: null\r\n });\r\n },\r\n\r\n snapToPoints( /*view,items*/) {\r\n return [];\r\n },\r\n transformWithFixedCenter( /*view,items*/) {\r\n return false;\r\n },\r\n scaleOriginalXY( /*view,items*/) {\r\n return null; // { scaleX : s00, scaleY : s11 };\r\n },\r\n\r\n setIddleToolhelp() { },\r\n setEditionToolhelp( transformType, shiftToolhelp, shiftOnlyForSingleSelection ) {\r\n const { tool, _editingItems } = this;\r\n const dragText = 'Drag to '+transformType+' selection';\r\n const altText = 'Alt to make selection transparent';\r\n if( _editingItems.length > 1 ) {\r\n tool.toolhelp( dragText + (shiftOnlyForSingleSelection ? '':('\\n'+shiftToolhelp)), altText );\r\n }\r\n else {\r\n tool.toolhelp( dragText, shiftToolhelp, altText );\r\n }\r\n },\r\n\r\n onItemsDrag( /*event, items*/ ) { },\r\n onItemsDrop( /*event, items*/ ) {\r\n return true;\r\n },\r\n\r\n // Internals\r\n //--------------------------------------------------------------------------------------\r\n\r\n startEditionMode( transformType, shiftToolhelp, shiftOnlyForSingleSelection ) {\r\n const { view, handles } = this;\r\n\r\n const editingItems = this._editingItems = clone(this.editingItems(view));\r\n this._originalTransforms = this.getOriginalTransforms(editingItems);\r\n\r\n this._downFrame = handles._frame;\r\n this._editionMode = true;\r\n\r\n this.setEditionToolhelp(transformType,shiftToolhelp,shiftOnlyForSingleSelection);\r\n view.redraw('annotations');\r\n },\r\n\r\n endEditionMode() {\r\n this.setIddleToolhelp();\r\n this.initFrameInteraction();\r\n },\r\n\r\n // optional\r\n translateItems( items, offset ) {\r\n this.transformItems(items,Matrix.translate(offset));\r\n },\r\n\r\n setOriginalPositions( figures, originalTransforms ) {\r\n this.setOriginalTransforms(figures,originalTransforms);\r\n },\r\n\r\n updateHandlesFrame( transform ) {\r\n const { view, handles, _downFrame } = this;\r\n handles.update( _downFrame.transformed(transform) );\r\n // Batch redraw, the frame will be drawn again at the same time as the document\r\n view.batchRedraw('tools');\r\n },\r\n\r\n absoluteTransform( transform ) {\r\n const { view, _editingItems, _originalTransforms } = this;\r\n this.setOriginalTransforms(_editingItems,_originalTransforms);\r\n this.updateHandlesFrame(transform);\r\n this.transformItems(_editingItems,transform);\r\n view.preview$();\r\n },\r\n\r\n absoluteTranslate( offset ) {\r\n const { view, _editingItems, _originalTransforms } = this;\r\n this.setOriginalPositions(_editingItems,_originalTransforms);\r\n this.updateHandlesFrame( Matrix.translate(offset) );\r\n this.translateItems(_editingItems,offset);\r\n view.preview$();\r\n },\r\n\r\n commit$() {\r\n this.view.commit$();\r\n },\r\n\r\n // Translate\r\n //-------------------------------------------------------------------------------------\r\n\r\n onTranslateStart({ view }) {\r\n this._data = {\r\n offset: new Point(0,0),\r\n started: false,\r\n snapTo: this.snapToPoints(view,this.editingItems(view)), // [ { lx_ly, center, hx_hy }, ... ]\r\n };\r\n },\r\n\r\n // Use docPointRaw that allows jumps depending on the view used to see\r\n // the document (Canvas3D, TextureView)\r\n\r\n getOnTranslateValue({ view, docPointRaw, cmdKey, shiftKey }) {\r\n const { handles, _data, _downFrame } = this;\r\n\r\n const offset = substract( docPointRaw, handles.mouseDownPos );\r\n if( ! offset.isZero() ) {\r\n _data.started = true;\r\n }\r\n\r\n const snapTo = _data.snapTo;\r\n // [TODO] Move AlignmentLines logic to the plugin\r\n const alignmentLines = view._alignmentLines || { _visible: false, _snap: false };\r\n\r\n const forceSnap = shiftKey || cmdKey;\r\n const al_visible = forceSnap || alignmentLines._visible;\r\n const al_snap = forceSnap || alignmentLines._snap;\r\n const al_enabled = al_visible || al_snap;\r\n if( snapTo && al_enabled && _data.started ) { // snap\r\n const snapSize = view.viewDeltaToDoc(14);\r\n const { bounds } = _downFrame.translated(offset);\r\n let al_x = null, al_y = null, diff_x = Number.MAX_VALUE, diff_y = Number.MAX_VALUE;\r\n forEach( snapTo, snap => {\r\n forEach( snap, (s,name) => {\r\n\r\n const diff = substract( s, bounds[name] );\r\n\r\n const ax = _abs(diff.x);\r\n if( ax < snapSize && _abs(diff_x) > ax ) {\r\n diff_x = diff.x;\r\n if( al_visible ) {\r\n al_x = s.x;\r\n }\r\n }\r\n const ay = _abs(diff.y);\r\n if( ay < snapSize && _abs(diff_y) > ay ) {\r\n diff_y = diff.y;\r\n if( al_visible ) {\r\n al_y = s.y;\r\n }\r\n }\r\n });\r\n });\r\n\r\n handles.guideline_x = al_x;\r\n if( al_snap && diff_x !== Number.MAX_VALUE ) {\r\n offset.x += diff_x;\r\n }\r\n\r\n handles.guideline_y = al_y;\r\n if( al_snap && diff_y !== Number.MAX_VALUE ) {\r\n offset.y += diff_y;\r\n }\r\n }\r\n else {\r\n handles.guideline_x = null;\r\n handles.guideline_y = null;\r\n }\r\n\r\n return view.asFastOffset(offset);\r\n },\r\n\r\n onTranslateMove( event ) {\r\n const { _data, _editionMode, _editingItems } = this;\r\n if( ! _editionMode ) {\r\n this.startEditionMode('translate','Shift to show snap guidelines');\r\n }\r\n const offset = _data.offset = this.getOnTranslateValue(event);\r\n this.absoluteTranslate( offset );\r\n this.onItemsDrag(event,_editingItems);\r\n },\r\n\r\n onTranslateEnd( event ) {\r\n const { _data, _editionMode, _editingItems, handles } = this;\r\n if( _editionMode ) {\r\n const { offset } = _data;\r\n\r\n const needsRedraw = ( handles.guideline_x || handles.guideline_y );\r\n\r\n handles.guideline_x = null;\r\n handles.guideline_y = null;\r\n\r\n this.endEditionMode();\r\n\r\n if( ( offset.x !== 0 || offset.y !== 0 ) && this.onItemsDrop(event,_editingItems) ) {\r\n this.commit$();\r\n }\r\n else if( needsRedraw ) {\r\n this.tool.redraw();\r\n }\r\n\r\n }\r\n },\r\n\r\n // Scale\r\n //-------------------------------------------------------------------------------------\r\n\r\n onScaleStart({ view }) {\r\n const { handles } = this;\r\n const editingItems = this.editingItems(view);\r\n const pin = handles.current.pin.pos;\r\n this._data = {\r\n scale : { pin: pin, sx:1, sy:1, deg: 0 } ,\r\n fixedCenter : this.transformWithFixedCenter( view, editingItems ),\r\n center : handles.center,\r\n scalePin : pin,\r\n scaleDir : handles.scaleDirFromHandle( handles.current ),\r\n os : this.scaleOriginalXY( view, editingItems )\r\n };\r\n },\r\n\r\n getOnScaleValue({ view, event, docPoint, cmdKey, shiftKey }) {\r\n const { handles, _data } = this;\r\n const { current, mouseDownPos } = handles;\r\n const { fixedCenter, center, scalePin, scaleDir } = _data;\r\n\r\n const pin = ( fixedCenter || cmdKey ) ? center : scalePin;\r\n\r\n const scale = computeScale( pin, scaleDir, docPoint, mouseDownPos, view.viewDeltaToDoc(1) );\r\n\r\n const { name } = current;\r\n scale.sy = ( name === 'ne' || name === 'nw' || name === 'sw' || name === 'se' ) ? scale.sx : 1;\r\n\r\n const { os } = _data;\r\n if( shiftKey && os ) { // Snapping to sx = sy\r\n if( name === 'n' || name === 's') {\r\n if( _abs( (os.scaleY * scale.sx) / os.scaleX - 1 ) < 0.15 ) {\r\n scale.sx = os.scaleX / os.scaleY ;\r\n }\r\n }\r\n else if( name === 'e' || name === 'w' ) {\r\n if( _abs( (os.scaleX * scale.sx) / os.scaleY - 1 ) < 0.15 ) {\r\n scale.sx = os.scaleY / os.scaleX ;\r\n }\r\n }\r\n }\r\n return scale;\r\n },\r\n onScaleMove( event ) {\r\n const { _editionMode } = this;\r\n if( ! _editionMode ) {\r\n this.startEditionMode('scale','Shift to lock to on isometric scaling',true);\r\n }\r\n\r\n this.doScaleMove(event);\r\n },\r\n\r\n doScaleMove( event ) {\r\n const { _data } = this;\r\n\r\n const { pin, sx, sy, deg } = _data.scale = this.getOnScaleValue(event);\r\n\r\n const scaleFrom = Matrix.scaleFrom( pin, sx, sy, deg );\r\n\r\n this.absoluteTransform( scaleFrom );\r\n },\r\n\r\n onScaleEnd() {\r\n const { _data, _editionMode } = this;\r\n if( _editionMode ) {\r\n const { sx } = _data.scale;\r\n\r\n this.endEditionMode();\r\n if( sx !== 1 ) {\r\n this.commit$();\r\n }\r\n }\r\n },\r\n\r\n // Rotate\r\n //-------------------------------------------------------------------------------------\r\n\r\n onRotateStart({ view, event, docPoint }) {\r\n const { handles } = this;\r\n const { center, current } = handles;\r\n\r\n this._data = {\r\n deg: 0,\r\n center,\r\n initialDeg: computeRotation(center,docPoint),\r\n initialSnapDeg: computeRotation(center,current.pos)\r\n };\r\n },\r\n getOnRotateValue({ event, docPoint, shiftKey, cmdKey }) {\r\n const { _data } = this;\r\n const { center, initialDeg, initialSnapDeg } = _data;\r\n\r\n const r = computeRotation(center,docPoint);\r\n if( shiftKey || cmdKey ) { // Snap\r\n const sm = 15;\r\n return Math.round(r/sm) * sm - initialSnapDeg;\r\n }\r\n else {\r\n return r - initialDeg;\r\n }\r\n },\r\n onRotateMove( event ) {\r\n const { _editionMode, _data } = this;\r\n\r\n if( ! _editionMode ) {\r\n this.startEditionMode('rotate','Shift to lock rotation on multiples of 15 degrees');\r\n }\r\n\r\n const deg = _data.deg = this.getOnRotateValue(event);\r\n const rotateAround = Matrix.rotateAround(_data.center,deg);\r\n\r\n this.absoluteTransform( rotateAround );\r\n },\r\n onRotateEnd() {\r\n const { _editionMode, _data } = this;\r\n\r\n if( _editionMode ) {\r\n const { deg } = _data;\r\n this.endEditionMode();\r\n if( deg !== 0 ) {\r\n this.commit$();\r\n }\r\n }\r\n },\r\n\r\n // Shear\r\n //-------------------------------------------------------------------------------------\r\n\r\n onShearStart({ view }) {\r\n const { handles } = this;\r\n const { current, center } = handles;\r\n\r\n this._data = {\r\n shear : { sx: 0, sy: 0 },\r\n center ,\r\n fixedCenter : this.transformWithFixedCenter(view,this.editingItems(view)),\r\n shearPin : current.pin.pos,\r\n shearDir : handles.shearDirFromHandle(current),\r\n shearHandlePos : current.pos,\r\n shearOppPin : current.oppPin.pos\r\n };\r\n },\r\n\r\n getOnShearValue({ view, event, docPoint }) {\r\n const { handles, _data } = this;\r\n const { ctrlKey, shiftKey } = handles;\r\n const { fixedCenter, center, shearPin, shearOppPin,\r\n shearHandlePos, shearDir } = _data;\r\n\r\n let downPos = handles.mouseDownPos;\r\n\r\n let pos = docPoint;\r\n\r\n const pin = ( fixedCenter || ctrlKey ) ? center : shearPin;\r\n if( shiftKey ) { // Snap\r\n const currentOppPin = pos .plus( substract( shearOppPin, shearHandlePos ) );\r\n const kp = substract( currentOppPin, pin );\r\n const dp = dotProduct( kp, shearDir );\r\n if( _abs(dp) < 15 ) {\r\n pos = pin .plus( substract( shearHandlePos, shearOppPin ) );\r\n downPos = shearHandlePos;\r\n }\r\n }\r\n\r\n return computeShear(pin, _data.shearDir, pos, downPos);\r\n },\r\n\r\n onShearMove( event ) {\r\n const { _data, _editionMode } = this;\r\n\r\n if( ! _editionMode ) {\r\n this.startEditionMode('skew','Shift to lock when there is no skewing',true);\r\n }\r\n const { pin, sx, sy, deg } = _data.shear = this.getOnShearValue(event);\r\n const shearAround = Matrix.shearAround( pin, sx, sy, deg );\r\n\r\n this.absoluteTransform( shearAround );\r\n },\r\n\r\n onShearEnd() {\r\n const { _editionMode, _data } = this;\r\n if( _editionMode ) {\r\n const { sx, sy } = _data.shear;\r\n this.endEditionMode();\r\n if( sx !== 0 || sy !== 0 ) {\r\n this.commit$();\r\n }\r\n }\r\n }\r\n};\r\n\r\nexport const SelectAndTransformHandles = Base.extend( FrameInteractionMixin, {\r\n\r\n // To overwrite in the config\r\n\r\n // Check FrameInteractionMixin plus...\r\n //\r\n // functions:\r\n // computeItemsFrame_(items) => frame\r\n // itemsEnabledTransforms(items) => { anisometricTransforms, translate, scale, rotate, shear, contentEdit }\r\n //\r\n // optional:\r\n // invalidatedItems(items) => boolean\r\n\r\n\r\n init( config ) {\r\n this.handles = null;\r\n assign(this,config);\r\n this.initFrameInteraction();\r\n },\r\n\r\n isHandle( event ) {\r\n return this.handles ? this.handles.isHandle(event) : false;\r\n },\r\n\r\n isHandleEnabledAt( event ) {\r\n return this.handles ? this.handles.isHandleEnabledAt(event) : false;\r\n },\r\n\r\n isPadHandle( event ) {\r\n return this.handles ? this.handles.isPadHandle(event) : false;\r\n },\r\n\r\n get frame() {\r\n return this.handles ? this.handles._frame : null;\r\n },\r\n\r\n get visible() {\r\n return this.handles ? this.handles.visible : false;\r\n },\r\n\r\n down( event ) {\r\n if( this.handles ) {\r\n this.handles.down(event);\r\n }\r\n },\r\n\r\n mousemove( event ) {\r\n if( this.handles ) {\r\n this.handles.mousemove(event);\r\n }\r\n },\r\n\r\n move( event ) {\r\n if( this.handles ) {\r\n this.handles.move(event);\r\n }\r\n },\r\n\r\n up( event ) {\r\n if( this.handles ) {\r\n this.handles.up(event);\r\n }\r\n },\r\n\r\n draw( config ) {\r\n if( this.handles ) {\r\n this.handles.draw(config);\r\n }\r\n },\r\n\r\n create() {\r\n if( this.handles ) {\r\n this.dispose();\r\n }\r\n this.handles = new SelectHandles({ view: this.view });\r\n this.handles.on({ 'rotatestart' : this.onRotateStart,\r\n 'rotatemove' : this.onRotateMove,\r\n 'rotateend' : this.onRotateEnd,\r\n 'scalestart' : this.onScaleStart,\r\n 'scalemove' : this.onScaleMove,\r\n 'scaleend' : this.onScaleEnd,\r\n 'shearstart' : this.onShearStart,\r\n 'shearmove' : this.onShearMove,\r\n 'shearend' : this.onShearEnd,\r\n 'translatestart' : this.onTranslateStart,\r\n 'translatemove' : this.onTranslateMove,\r\n 'translateend' : this.onTranslateEnd,\r\n 'edit' : this.onContentEdit }, this );\r\n },\r\n\r\n dispose() {\r\n if( this.handles ) {\r\n this.handles.un(this);\r\n this.handles = null;\r\n }\r\n },\r\n\r\n onContentEdit() {\r\n const { view } = this;\r\n const items = this.editingItems(view);\r\n if( items.length === 1 ) {\r\n view.editContent( items[0] );\r\n }\r\n },\r\n\r\n invalidatedItems( /*items*/) {\r\n return false;\r\n },\r\n\r\n update( frame ) {\r\n const { view, handles } = this;\r\n\r\n if( ! handles ) {\r\n return;\r\n }\r\n\r\n if( frame ) {\r\n handles.update(frame);\r\n }\r\n else {\r\n\r\n const items = this.editingItems(view);\r\n if( items.length > 0 ) {\r\n\r\n // If edition mode is on, the frame is already updated while transforming\r\n if( ! this._editionMode && ! this.invalidatedItems(items) ) {\r\n\r\n const config = this.itemsEnabledTransforms(view,items);\r\n\r\n handles.anisometricTransformsEnabled = config.anisometricTransforms || false;\r\n\r\n handles.translateEnabled = config.translate || false;\r\n handles.scaleEnabled = config.scale || false;\r\n handles.rotateEnabled = config.rotate || false;\r\n handles.shearEnabled = config.shear || false;\r\n\r\n handles.editEnabled = config.contentEdit || false;\r\n\r\n handles.resize( this.computeItemsFrame_(items) );\r\n handles.visible = true;\r\n }\r\n }\r\n else {\r\n handles.visible = false;\r\n }\r\n }\r\n\r\n this.view.batchRedraw('tools');\r\n }\r\n});\r\n\r\nexport const FiguresHandles = SelectAndTransformHandles.extend({\r\n\r\n getOriginalTransforms( figures ) {\r\n return map( figures, figure => {\r\n return {\r\n matrix22: figure.matrix22.clone(),\r\n pin: figure.pin.clone()\r\n };\r\n });\r\n },\r\n\r\n setOriginalTransforms( figures, originalTransforms ) {\r\n forEach( figures, (figure,n) => {\r\n const original = originalTransforms[n];\r\n figure.pin = original.pin.clone();\r\n figure.matrix22 = original.matrix22.clone();\r\n });\r\n },\r\n\r\n itemsEnabledTransforms( view, figures ) {\r\n return {\r\n anisometricTransforms: view.are(figures,'aspectRatioChangeable'),\r\n\r\n translate: view.are(figures,'movable'),\r\n scale: view.are(figures,'scalable'),\r\n rotate: view.are(figures,'rotatable'),\r\n shear: view.are(figures,'skewable'),\r\n\r\n contentEdit: this.itemsEnabledContentEdit(view,figures)\r\n };\r\n },\r\n\r\n itemsEnabledContentEdit(view,figures) {\r\n return view.are(figures,'contentEditable');\r\n },\r\n\r\n transformItems: Figures.transform,\r\n invalidatedItems: Figures.invalidated,\r\n\r\n computeItemsFrame_: computeFiguresFrame_,\r\n\r\n snapToPoints: figuresSnapToPoints,\r\n\r\n transformWithFixedCenter( view, figures ) {\r\n return ! view.are(figures,'movable');\r\n },\r\n\r\n scaleOriginalXY( view, items ) {\r\n const figure = items[0];\r\n const matrix = figure._matrix22;\r\n const urm = Matrix.m( Matrix.rotate( -matrix.angle() ), matrix );\r\n return { scaleX : urm.s00, scaleY : urm.s11 };\r\n }\r\n});\r\n\r\n// Attempt to avoid an extra Process call to measure ProxyGroups after\r\n// isometric scaling (pr)\r\n\r\nexport const OptimizedFiguresHandles = FiguresHandles.extend({\r\n\r\n translateItems: Figures.fastTranslate_, // forced, offset is already fixed\r\n\r\n getOriginalTransforms( figures ) {\r\n return map( figures, figure => {\r\n return {\r\n matrix22: figure.matrix22.clone(),\r\n pin: figure.pin.clone(),\r\n // cache: figure._cache.clone() (pr)\r\n };\r\n });\r\n },\r\n\r\n setOriginalPositions( figures, originalTransforms ) {\r\n forEach( figures, (figure,n) => {\r\n const original = originalTransforms[n];\r\n figure.fastTranslate( original.pin .minus( figure.pin ) );\r\n });\r\n },\r\n\r\n // Do it by hand, avoid need to compute bounds for proxy groups\r\n doScaleMove( event ) {\r\n const { _data } = this;\r\n\r\n const lastScale = _data.scale;\r\n\r\n const { pin, sx, sy, deg } = _data.scale = this.getOnScaleValue(event);\r\n\r\n const scaleFrom = Matrix.scaleFrom( pin, sx, sy, deg );\r\n\r\n const { view, _editingItems } = this;\r\n this.updateHandlesFrame(scaleFrom);\r\n\r\n // Revert last change and re-apply absolute scaling, caches are kept\r\n Figures.scaleFrom(_editingItems,lastScale.pin,1/lastScale.sx,1/lastScale.sy,lastScale.deg);\r\n Figures.scaleFrom(_editingItems,pin,sx,sy,deg);\r\n\r\n view.preview$();\r\n }\r\n\r\n});\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/select-transform.js\n **/","import { forEach, forOwn, map, keys, pick } from 'lodash';\r\n\r\nimport { Base, moveTo, lineTo, setLineDash, strokeSegment } from 'gear';\r\n\r\nimport { Point, Matrix, Frame } from 'cdl';\r\n\r\nimport { padScaling, fastThrottle } from '../view';\r\n\r\nconst { distance2 } = Point;\r\n\r\nfunction maxSideLength2( frame ) {\r\n const { p0, p1, p2, p3 } = frame;\r\n return Math.max( distance2(p1,p0), distance2(p2,p1), distance2(p3,p2), distance2(p0,p3) );\r\n}\r\n\r\nfunction minSideLength2( frame ) {\r\n const { p0, p1, p2, p3 } = frame;\r\n return Math.min( distance2(p1,p0), distance2(p2,p1), distance2(p3,p2), distance2(p0,p3) );\r\n}\r\n\r\nexport /* default */ let SelectHandles = Base.extend({\r\n\r\n Properties: {\r\n view : { type: 'View', def: null, owned: false },\r\n\r\n anisometricTransformsEnabled : { type: 'boolean', def: true },\r\n translateEnabled : { type: 'boolean', def: true },\r\n scaleEnabled : { type: 'boolean', def: true },\r\n rotateEnabled : { type: 'boolean', def: true },\r\n shearEnabled : { type: 'boolean', def: true },\r\n editEnabled : { type: 'boolean', def: false }\r\n },\r\n init() {\r\n this._visible = false;\r\n\r\n this.guideline_x = null;\r\n this.guideline_y = null;\r\n\r\n this.mouseDownPos = new Point(0,0);\r\n\r\n this._handles = {\r\n center : { mode: 'translate' },\r\n nw : { mode: 'scale' },\r\n ne : { mode: 'scale' },\r\n se : { mode: 'scale' },\r\n sw : { mode: 'scale' },\r\n n : { mode: 'scale' , aniso: true },\r\n e : { mode: 'scale' , aniso: true },\r\n s : { mode: 'scale' , aniso: true },\r\n w : { mode: 'scale' , aniso: true },\r\n rotate : { mode: 'rotate' },\r\n shearX : { mode: 'shear' , aniso: true },\r\n shearY : { mode: 'shear' , aniso: true },\r\n edit : { mode: 'edit' },\r\n none : { mode: 'none' }\r\n };\r\n\r\n const size = 0.1 * 96;\r\n\r\n const hs = this._handles;\r\n forEach( hs, (h,hn) => {\r\n h.name = hn; h.size = size; h.cursor = 'pointer'; h.disabled=false;\r\n });\r\n hs.rotate.size = hs.edit.size = size;\r\n\r\n hs.center.cursor = 'move';\r\n hs.none.cursor = 'default';\r\n\r\n forEach( hs, h => {\r\n h.size2 = h.size*h.size+1;\r\n });\r\n\r\n hs.nw.pin = hs.se; hs.ne.pin = hs.sw;\r\n hs.se.pin = hs.nw; hs.sw.pin = hs.ne;\r\n hs.n .pin = hs.s ; hs.e .pin = hs.w ;\r\n hs.s .pin = hs.n ; hs.w .pin = hs.e ;\r\n hs.shearX.pin = hs.n; hs.shearX.oppPin = hs.s;\r\n hs.shearY.pin = hs.w; hs.shearY.oppPin = hs.w;\r\n\r\n this._circlePadHandles = pick(hs,'rotate','nw','ne','se','sw','n','e','s','w','shearX','shearY','edit');\r\n\r\n this._fillColor = '#22CC33';\r\n this._fillOverColor = '#006633';\r\n this._fillActiveColor = '#fb603d';\r\n this._strokeColor = '#006633';\r\n this._guidelineColor = '#993300';\r\n\r\n this.addEvents( 'rotatestart', 'rotatemove', 'rotateend' ,\r\n 'scalestart', 'scalemove', 'scaleend' ,\r\n 'translatestart', 'translatemove', 'translateend' ,\r\n 'shearstart', 'shearmove', 'shearend' , 'edit');\r\n\r\n this._currentActive = this._handles.none;\r\n this._currentOver = this._handles.none;\r\n this.current = this._handles.none;\r\n this._setFrame( Frame.fromBounds({lx: 100, ly: 100, hx: 200, hy: 200 }) );\r\n this._inited = false;\r\n this.enable(true);\r\n },\r\n\r\n _rotateHandlePosition( p1, p2, distance ) {\r\n const de = p2.minus(p1) .normalized();\r\n return p2.plus( de.scaled( this.view.viewDeltaToDoc(distance) ) );\r\n },\r\n\r\n _editHandlePosition( p1, p2, distance ) {\r\n const de = p2.minus(p1) .normalized();\r\n return p2.plus( de.scaled( this.view.viewDeltaToDoc(distance) ) );\r\n },\r\n\r\n _setFrame( frame ) {\r\n this._frame = frame;\r\n this._inited = true;\r\n const interpolate = Point.interpolate;\r\n const nw = this._frame.p0, ne = this._frame.p1, se = this._frame.p2, sw = this._frame.p3;\r\n const p = {\r\n nw: nw, ne: ne, se: se, sw: sw,\r\n n: interpolate(nw,ne,0.5),\r\n e: interpolate(ne,se,0.5),\r\n s: interpolate(se,sw,0.5),\r\n w: interpolate(sw,nw,0.5)\r\n };\r\n\r\n p.shearX = interpolate(p.s,se,0.5);\r\n p.shearY = interpolate(se,p.e,0.5);\r\n\r\n p.rotate = this._rotateHandlePosition(p.w,p.e,20);\r\n p.edit = this._editHandlePosition(p.e,p.w,20);\r\n\r\n const hs = this._handles;\r\n forOwn( p, (pos,hn) => {\r\n hs[hn].pos = pos;\r\n });\r\n },\r\n\r\n// frame: The figure frame in the View coordinates.\r\n resize( frame ) {\r\n\r\n const { view } = this;\r\n const frameMinSideLength2 = minSideLength2(frame),\r\n frameMaxSideLength2 = maxSideLength2(frame);\r\n\r\n const vtds = view.viewDeltaToDoc(1), vtds2 = vtds*vtds;\r\n\r\n const smallFrame = frameMinSideLength2 < 30*30 *vtds2 && frameMaxSideLength2 < 60*60 *vtds2;\r\n if( smallFrame ) {\r\n const ex = 12 * vtds;\r\n // console.log(vtds);\r\n frame = frame.extended(ex,ex,ex,ex);\r\n this._anisometricTransformsEnabled = false;\r\n }\r\n\r\n const ps = view.viewDeltaToDoc(padScaling);\r\n\r\n const hs = this._handles;\r\n const { width, height } = frame;\r\n const shearCut1 = 40 * ps,\r\n shearCut2 = 60 * ps,\r\n scaleCut1 = 20 * ps,\r\n scaleCut2 = 30 * ps;\r\n hs.shearX.disabled = height < shearCut1 || width < shearCut2;\r\n hs.shearY.disabled = height < shearCut2 || width < shearCut1;\r\n hs.e.disabled = width < scaleCut1 || height < scaleCut2;\r\n hs.w.disabled = width < scaleCut1 || height < scaleCut2;\r\n hs.n.disabled = width < scaleCut2 || height < scaleCut1;\r\n hs.s.disabled = width < scaleCut2 || height < scaleCut1;\r\n this.update(frame);\r\n },\r\n\r\n update( frame ) {\r\n this._setFrame( frame );\r\n },\r\n\r\n enable( isEnabled ) {\r\n if( isEnabled === undefined ) {\r\n this.enabled = true ;\r\n }\r\n else {\r\n this.enabled = isEnabled ;\r\n }\r\n },\r\n isEnabled() {\r\n return this.enabled ;\r\n },\r\n\r\n handleEnabled( c ) {\r\n return c.mode === 'none' || ( this[ c.mode + 'Enabled' ] && ( this._anisometricTransformsEnabled || ! c.aniso ) );\r\n },\r\n\r\n down({ event, docPoint }) {\r\n if( ! this.isEnabled() ) {\r\n return ;\r\n }\r\n\r\n const c = this._handleFromEvent(event);\r\n\r\n if( ! this.handleEnabled(c) ) {\r\n return;\r\n }\r\n this.current = c;\r\n\r\n if( c.mode === 'none' ) {\r\n return;\r\n }\r\n else if( c.mode === 'edit' ) {\r\n this.fireEvent('edit', event);\r\n this.current = this._handles.none;\r\n return;\r\n }\r\n\r\n this._currentActive = this.current;\r\n\r\n this._currentOver = this._handles.none;\r\n\r\n this.mouseDownPos = docPoint;\r\n\r\n this.fireEvent(this.current.mode + 'start', event); // shear, rotate, scale, or translate\r\n },\r\n\r\n mousemove({ view, event }) {\r\n\r\n if( view.is3D ) {\r\n // Ignore feedback for 3D views\r\n return;\r\n }\r\n\r\n // Handle pad Over\r\n if( this._visible && this.current.mode === 'none' ) {\r\n const newOver = this._handleFromEvent(event);\r\n if( this._currentOver !== newOver ) {\r\n\r\n this._currentOver = newOver;\r\n\r\n if( newOver.mode === 'none' || this.handleEnabled(newOver) ) {\r\n view.cursor = newOver.cursor;\r\n }\r\n\r\n view.redraw('tools');\r\n\r\n event.stopPropagation();\r\n }\r\n }\r\n },\r\n\r\n move: fastThrottle( function({ view, event }) {\r\n\r\n if( this.current.mode === 'none' ) {\r\n return;\r\n }\r\n this.fireEvent(this.current.mode + 'move', event); // rotate, scale, select, shear or translate\r\n }, 12 ),\r\n\r\n up({ view, event }) {\r\n const mode = this.current.mode;\r\n if( mode === 'none' ) {\r\n return;\r\n }\r\n\r\n this._currentActive = this._handles.none;\r\n\r\n this.fireEvent(mode + 'end', event); // rotate, scale, select, or translate\r\n\r\n this.current = this._handles.none;\r\n\r\n if( mode !== 'translate' ) { // avoid glitch\r\n view.cursor = this.current.cursor;\r\n }\r\n },\r\n\r\n shearDirFromHandle( h ) {\r\n const hs = this._handles;\r\n switch( h.name ) {\r\n case 'shearX':\r\n return hs.e.pos.minus(hs.w.pos) .normalized();\r\n case 'shearY':\r\n return hs.n.pos.minus(hs.s.pos) .normalized();\r\n }\r\n },\r\n\r\n scaleDirFromHandle( h, transform = Matrix() ) {\r\n return transform.apply(h.pos).minus( transform.apply(h.pin.pos) ) .normalized();\r\n },\r\n\r\n strokeFrame( context, transform ) {\r\n const hs = this._handles;\r\n\r\n // rotate arm\r\n if( this.rotateEnabled ) {\r\n strokeSegment(context,hs.e.pos,this._rotateHandlePosition(hs.w.pos,hs.e.pos,20),transform);\r\n }\r\n\r\n // Center handle\r\n this._frame.draw(context,transform);\r\n context.stroke();\r\n },\r\n\r\n draw({ view, context, transform }) {\r\n\r\n if( this._inited && this._visible ) {\r\n\r\n context.save();\r\n\r\n const hs = this._handles;\r\n\r\n const textureScale = view.viewDeltaToTexture(1);\r\n\r\n setLineDash(context, map( [5,2], v => textureScale*v ) );\r\n context.lineWidth = 2.4 * textureScale;\r\n const strokeStyle = context.strokeStyle = '#e3e3e3';\r\n this.strokeFrame(context,transform);\r\n\r\n setLineDash(context, map( [0,0.5,4,2.5], v => textureScale*v ) );\r\n context.lineWidth = 1.2 * textureScale;\r\n context.strokeStyle = '#388638';\r\n this.strokeFrame(context,transform);\r\n\r\n context.strokeStyle = strokeStyle;\r\n context.lineWidth = 1 * textureScale; // [TODO]\r\n setLineDash(context,[]);\r\n\r\n if( this.scaleEnabled ) {\r\n forEach(['nw','ne','se','sw'], hn => {\r\n const h = hs[hn];\r\n this._drawScaleHandle(context,h,transform,textureScale);\r\n context.stroke();\r\n context.fillStyle = this.fillStyle(h);\r\n context.fill();\r\n });\r\n }\r\n\r\n if( this.rotateEnabled ) {\r\n // Rotate handle, raphael was taking a lot of time to rotate the handle\r\n const rotateHandle = hs.rotate;\r\n context.beginPath();\r\n\r\n // [TODO] Clean up, running to release\r\n rotateHandle.pos = this._rotateHandlePosition(hs.w.pos,hs.e.pos,28);\r\n\r\n const rotationPos = transform.apply(rotateHandle.pos);\r\n const rotationAngle = transform.apply(hs.e.pos).minus( transform.apply(hs.w.pos) ) .angle();\r\n const rotationPathTransform = Matrix.concat( Matrix.translate(rotationPos),\r\n Matrix.scale( 0.65 * textureScale ),\r\n Matrix.rotate(rotationAngle) );\r\n canvasRotationPath(context,rotationPathTransform);\r\n context.stroke();\r\n context.fillStyle = this.fillStyle(rotateHandle);\r\n context.fill();\r\n }\r\n\r\n if( this.editEnabled ) {\r\n const editHandle = hs.edit;\r\n context.beginPath();\r\n\r\n // [TODO] Clean up, running to release\r\n editHandle.pos = this._editHandlePosition(hs.e.pos,hs.w.pos,20);\r\n\r\n const editAngle = transform.apply(hs.e.pos) .minus( transform.apply(hs.w.pos) ) .angle();\r\n canvasEditContentPath( context, Matrix.concat(\r\n Matrix.translate( transform.apply(editHandle.pos) ),\r\n Matrix.scale( 0.6 * textureScale ),\r\n Matrix.rotate(editAngle),\r\n Matrix.translate(-16,-16)\r\n ));\r\n context.stroke();\r\n context.fillStyle = this.fillStyle(editHandle);\r\n context.fill();\r\n }\r\n\r\n if( this._anisometricTransformsEnabled ) {\r\n\r\n if( this.scaleEnabled ) {\r\n forEach(['n','e','s','w'], hn => {\r\n const h = hs[hn];\r\n if( ! h.disabled ) {\r\n this._drawScaleHandle(context,h,transform,textureScale);\r\n context.stroke();\r\n context.fillStyle = this.fillStyle(h);\r\n context.fill();\r\n }\r\n });\r\n }\r\n\r\n if( this.shearEnabled ) {\r\n forEach(['shearX','shearY'], hn => {\r\n const h = hs[hn];\r\n if( ! h.disabled ) {\r\n\r\n const tp = transform.apply(h.pos);\r\n context.beginPath(); context.arc( tp.x, tp.y, 3.5*textureScale, 0,2*Math.PI); // [TODO] dot\r\n context.stroke();\r\n context.fillStyle = this.fillStyle(h);\r\n context.fill();\r\n }\r\n });\r\n }\r\n }\r\n\r\n // Guidelines\r\n\r\n const bounds = view.bounds;\r\n context.strokeStyle = this._guidelineColor;\r\n context.lineWidth = 0.75;\r\n setLineDash(context,[3,2]);\r\n\r\n const x = this.guideline_x;\r\n if( x !== null ) {\r\n strokeSegment(context,new Point(x,bounds.ly),new Point(x,bounds.hy),transform);\r\n }\r\n\r\n const y = this.guideline_y;\r\n if( y !== null) {\r\n strokeSegment(context,new Point(bounds.lx,y),new Point(bounds.hx,y),transform);\r\n }\r\n\r\n context.restore();\r\n }\r\n },\r\n\r\n fillStyle( h ) {\r\n return h === this._currentActive ? this._fillActiveColor\r\n : h === this._currentOver ? this._fillOverColor\r\n : this._fillColor ;\r\n },\r\n\r\n isHandle( event ) {\r\n return this._handleFromEvent(event).name !== 'none';\r\n },\r\n\r\n isPadHandle( event ) {\r\n const n = this._handleFromEvent(event).name;\r\n return n !== 'none' && n !== 'center';\r\n },\r\n\r\n isHandleEnabledAt( event ) {\r\n return this.handleEnabled( this._handleFromEvent(event) );\r\n },\r\n\r\n _handleFromEvent({ event, docPoint }) {\r\n const view = this.view;\r\n const hs = this._handles;\r\n if( this._visible ) {\r\n const point = docPoint;\r\n const ps = view.viewDeltaToDoc(padScaling), ps2 = ps*ps; // [TODO]\r\n\r\n const padHandles = keys(this._circlePadHandles);\r\n for( let k = 0, kEnd = padHandles.length; k < kEnd; ++k ) {\r\n const hk = hs[padHandles[k]];\r\n if( this.handleEnabled(hk) && ! hk.disabled &&\r\n hk.pos.minus(point) .norm2() < hk.size2 * ps2 ) {\r\n return hk;\r\n }\r\n }\r\n\r\n if( this._frame.contains(point) ) {\r\n return hs.center;\r\n }\r\n }\r\n return hs.none;\r\n },\r\n\r\n // Returns center point in View coordinates.\r\n get center() {\r\n return this._frame.center;\r\n },\r\n\r\n get visible() {\r\n return this._visible;\r\n },\r\n set visible( visible_ ) {\r\n this._visible = visible_;\r\n },\r\n\r\n _drawScaleHandle( context, h, transform, textureScale ) {\r\n const scale = 4.5;\r\n const dir = this.scaleDirFromHandle(h,transform);\r\n const dirp = dir.perpendicular( -scale * textureScale );\r\n const p = transform.apply(h.pos).plus( dir.scaled( 0.3 * scale * textureScale ) );\r\n const t1 = p.plus( dir.scaled( scale * textureScale ) );\r\n const tb = p.plus( dir.scaled( -scale * textureScale ) );\r\n const t2 = tb.plus( dirp.scaled( -scale * textureScale ) );\r\n const t3 = tb.plus( dirp.scaled( scale * textureScale ) );\r\n\r\n context.beginPath();\r\n moveTo(context,t1);\r\n lineTo(context,t2);\r\n lineTo(context,t3);\r\n context.closePath();\r\n }\r\n});\r\n\r\nexport default SelectHandles;\r\n\r\n\r\n// Handle paths, we need to find a better way, this is here since we moved\r\n// away from Raphael. It was unrolled thinking on performance but it is\r\n// probably not making us gain much\r\n\r\nconst moveToXY = function( c,t, x,y ) {\r\n const p = t.apply_(x,y);\r\n c.moveTo( p.x,p.y );\r\n};\r\n\r\nconst lineToXY = function( c,t, x,y ) {\r\n const p = t.apply_(x,y);\r\n c.lineTo( p.x,p.y );\r\n};\r\n\r\nconst bezierCurveTo = function(c,t,p0_x,p0_y,p1_x,p1_y,p2_x,p2_y) {\r\n const p0 = t.apply_(p0_x,p0_y),\r\n p1 = t.apply_(p1_x,p1_y),\r\n p2 = t.apply_(p2_x,p2_y);\r\n c.bezierCurveTo( p0.x,p0.y, p1.x,p1.y, p2.x,p2.y );\r\n};\r\n\r\nfunction canvasRotationPath(c,t) {\r\n moveToXY(c,t,-8.084,0.500);\r\n bezierCurveTo(c,t, -8.075,5.240, -4.240,9.074, 0.499,9.083);\r\n bezierCurveTo(c,t, 5.240,9.074, 9.076,5.239, 9.084,0.500);\r\n bezierCurveTo(c,t, 9.076,-4.241, 5.240,-8.077, 0.499,-8.085);\r\n bezierCurveTo(c,t, -1.414,-8.085, -3.166,-7.456, -4.591,-6.399);\r\n bezierCurveTo(c,t, -4.591,-6.399, -2.809,-4.616, -2.809,-4.616);\r\n bezierCurveTo(c,t, -2.809,-4.616, -11.238,-2.360, -11.238,-2.360);\r\n bezierCurveTo(c,t, -11.238,-2.360, -8.978,-10.787, -8.978,-10.787);\r\n bezierCurveTo(c,t, -8.978,-10.787, -7.088,-8.897, -7.088,-8.897);\r\n bezierCurveTo(c,t, -5.016,-10.574, -2.371,-11.585, 0.499,-11.585);\r\n bezierCurveTo(c,t, 7.173,-11.582, 12.581,-6.174, 12.583,0.500);\r\n bezierCurveTo(c,t, 12.581, 7.175, 7.173,12.583, 0.500,12.583);\r\n bezierCurveTo(c,t, -6.175,12.583, -11.584,7.175, -11.584,0.500);\r\n bezierCurveTo(c,t, -11.584,0.500, -8.084,0.500, -8.084,0.500);\r\n bezierCurveTo(c,t, - 8.084,0.500, -8.084,0.500, -8.084,0.500);\r\n c.closePath();\r\n}\r\n\r\nfunction canvasEditContentPath(c,t) {\r\n moveToXY(c,t,15.067,2.250);\r\n bezierCurveTo(c,t, 9.088,2.250, 4.032,6.160, 2.289,11.559);\r\n lineToXY(c,t, 5.502,11.559);\r\n bezierCurveTo(c,t, 7.104,7.854, 10.773,5.258, 15.067,5.250);\r\n bezierCurveTo(c,t, 20.831,5.260, 25.495,9.924, 25.504,15.687);\r\n bezierCurveTo(c,t, 25.495,21.451, 20.831,26.115, 15.067,26.125);\r\n bezierCurveTo(c,t, 10.773,26.118, 7.103,23.520, 5.501,19.814);\r\n lineToXY(c,t, 2.289,19.814);\r\n bezierCurveTo(c,t, 4.033,25.213, 9.088,29.124, 15.068,29.126);\r\n bezierCurveTo(c,t, 22.487,29.124, 28.505,23.110, 28.506,15.688);\r\n bezierCurveTo(c,t, 28.504,8.265, 22.486,2.252, 15.067,2.250);\r\n c.closePath();\r\n\r\n moveToXY(c,t, 10.918,19.813);\r\n lineToXY(c,t, 18.068,15.687);\r\n lineToXY(c,t, 10.918,11.558);\r\n lineToXY(c,t, 10.918,13.855);\r\n lineToXY(c,t, -0.057,13.855);\r\n lineToXY(c,t, -0.057,17.516);\r\n lineToXY(c,t, 10.918,17.516);\r\n lineToXY(c,t, 10.918,19.813);\r\n c.closePath();\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/select-handles.js\n **/","import { setLineDash } from 'gear';\r\n\r\nimport { Bounds, Frame } from 'cdl';\r\n\r\nfunction stableLine(context, p0, p1 ) {\r\n context.beginPath();\r\n context.moveTo(p0.x,p0.y);\r\n context.lineTo(p1.x,p1.y);\r\n context.stroke();\r\n}\r\n\r\nexport const DragSelectorHelper = function({ docPoint }, onEnd, strokeColor = '#006633' ) {\r\n this.onEnd = onEnd;\r\n this._pd = docPoint;\r\n this._fd = docPoint;\r\n this._sc = strokeColor;\r\n};\r\nDragSelectorHelper.prototype = {\r\n\r\n draw({ context, transform }) {\r\n\r\n const frame = Frame.fromBounds( this.bounds ).transformed(transform);\r\n\r\n // This is done piece by piece so the dash will be\r\n // more stable when dragging, the direction of each line\r\n // is important to make this trick work\r\n\r\n context.save();\r\n context.strokeStyle = this._sc;\r\n context.lineWidth = 1;\r\n setLineDash(context,[4,3]);\r\n\r\n stableLine( context, frame.p3, frame.p0 );\r\n stableLine( context, frame.p2, frame.p1 );\r\n stableLine( context, frame.p3, frame.p2 );\r\n stableLine( context, frame.p0, frame.p1 );\r\n context.restore();\r\n },\r\n\r\n move({ view, docPoint }) {\r\n this._pd = docPoint;\r\n },\r\n\r\n end(event) {\r\n const { onEnd } = this;\r\n onEnd(event,this.bounds);\r\n },\r\n\r\n get bounds() {\r\n return Bounds.ofPoints([this._pd,this._fd]);\r\n }\r\n};\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/drag-selector.js\n **/","import { forEach, map, difference, assign } from 'lodash';\r\n\r\nimport { Tool } from '../view';\r\n\r\nimport { computeScale, FiguresHandles } from './select-transform';\r\n\r\nimport { Point, Matrix, Frame, Figures } from 'cdl';\r\n\r\nconst { dotProduct, substract } = Point;\r\nconst _abs = Math.abs;\r\n\r\nexport const ClipTool = Tool.extend({ typeName: 'ClipTool',\r\n\r\n type: 'Final',\r\n toolbarName: 'clipTool',\r\n allowKeyShortcuts: true,\r\n\r\n initTool( view, config ) {\r\n assign(this, config || {});\r\n this._data = null;\r\n\r\n this.handles = new FiguresHandles({ view, tool: this,\r\n\r\n editingItems: () => {\r\n const figure = this._selectedFigure;\r\n return figure ? [ figure ] : [];\r\n },\r\n\r\n itemsEnabledContentEdit( /* view, figures */ ) {\r\n return false;\r\n },\r\n\r\n\r\n commit$: () => {\r\n },\r\n\r\n itemsEnabledTransforms( view, figures ) {\r\n return {\r\n anisometricTransforms: view.are(figures,'aspectRatioChangeable'),\r\n translate: view.are(figures,'movable'),\r\n scale: view.are(figures,'scalable'),\r\n rotate: false,\r\n shear: false,\r\n contentEdit: false\r\n };\r\n },\r\n\r\n getOnTranslateValue({ view, docPointRaw, cmdKey, shiftKey }) {\r\n const { handles, _data, _downFrame } = this;\r\n \r\n const offset = substract( docPointRaw, handles.mouseDownPos );\r\n if( ! offset.isZero() ) {\r\n _data.started = true;\r\n }\r\n \r\n const snapTo = _data.snapTo;\r\n const alignmentLines = view._alignmentLines || { _visible: false, _snap: false }; \r\n const forceSnap = shiftKey || cmdKey;\r\n const al_visible = forceSnap || alignmentLines._visible;\r\n const al_snap = forceSnap || alignmentLines._snap;\r\n const al_enabled = al_visible || al_snap;\r\n if( snapTo && al_enabled && _data.started ) { // snap\r\n const snapSize = view.viewDeltaToDoc(14);\r\n const { bounds } = _downFrame.translated(offset);\r\n let al_x = null, al_y = null, diff_x = Number.MAX_VALUE, diff_y = Number.MAX_VALUE;\r\n forEach( snapTo, snap => {\r\n forEach( snap, (s,name) => {\r\n \r\n const diff = substract( s, bounds[name] );\r\n \r\n const ax = _abs(diff.x);\r\n if( ax < snapSize && _abs(diff_x) > ax ) {\r\n diff_x = diff.x;\r\n if( al_visible ) {\r\n al_x = s.x;\r\n }\r\n }\r\n const ay = _abs(diff.y);\r\n if( ay < snapSize && _abs(diff_y) > ay ) {\r\n diff_y = diff.y;\r\n if( al_visible ) {\r\n al_y = s.y;\r\n }\r\n }\r\n });\r\n });\r\n \r\n handles.guideline_x = al_x;\r\n if( al_snap && diff_x !== Number.MAX_VALUE ) {\r\n offset.x += diff_x;\r\n }\r\n \r\n handles.guideline_y = al_y;\r\n if( al_snap && diff_y !== Number.MAX_VALUE ) {\r\n offset.y += diff_y;\r\n }\r\n }\r\n else {\r\n handles.guideline_x = null;\r\n handles.guideline_y = null;\r\n }\r\n \r\n //get the minimum and maximum translation, then fix the offset if it will go out of the parent frame\r\n let lParent = this.clipTool._selectedParent\r\n let lParentFrame = lParent.globalFrame_();\r\n let lFigureFrame = _downFrame.translated(offset);\r\n let lTransform = lParent.rwPowerClipTransform();\r\n let lInvTransform = Matrix.invert(lTransform);\r\n lParentFrame.transform(lInvTransform);\r\n lFigureFrame.transform(lInvTransform);\r\n\r\n let lDeltaP0 = substract(lParentFrame.p0, lFigureFrame.p0);\r\n if (lDeltaP0.x > 0)\r\n {\r\n let lP = new Point(lDeltaP0.x,0);\r\n lP.transform(lTransform);\r\n lP.translate(-lParent.pin.x,-lParent.pin.y)\r\n offset.x += lP.x;\r\n offset.y += lP.y;\r\n }\r\n if (lDeltaP0.y > 0)\r\n {\r\n let lP = new Point(0, lDeltaP0.y);\r\n lP.transform(lTransform);\r\n lP.translate(-lParent.pin.x,-lParent.pin.y)\r\n offset.x += lP.x;\r\n offset.y += lP.y;\r\n }\r\n\r\n let lDeltaP2 = substract(lParentFrame.p2, lFigureFrame.p2);\r\n if (lDeltaP2.x < 0)\r\n {\r\n let lP = new Point(lDeltaP2.x,0);\r\n lP.transform(lTransform);\r\n lP.translate(-lParent.pin.x,-lParent.pin.y)\r\n offset.x += lP.x;\r\n offset.y += lP.y;\r\n }\r\n if (lDeltaP2.y < 0)\r\n {\r\n let lP = new Point(0, lDeltaP2.y);\r\n lP.transform(lTransform);\r\n lP.translate(-lParent.pin.x,-lParent.pin.y)\r\n offset.x += lP.x;\r\n offset.y += lP.y;\r\n }\r\n\r\n return view.asFastOffset(offset);\r\n },\r\n\r\n getOnScaleValue({ view, event, docPoint, cmdKey, shiftKey }) {\r\n const { handles, _data, _downFrame } = this;\r\n const { current, mouseDownPos } = handles;\r\n const { fixedCenter, center, scalePin, scaleDir } = _data;\r\n \r\n const pin = scalePin;\r\n \r\n const scale = computeScale( pin, scaleDir, docPoint, mouseDownPos, view.viewDeltaToDoc(1) );\r\n \r\n const { name } = current;\r\n scale.sy = ( name === 'ne' || name === 'nw' || name === 'sw' || name === 'se' ) ? scale.sx : 1;\r\n\r\n let lRetry = 0;\r\n let lFailedToScale = true;\r\n let lParent = this.clipTool._selectedParent\r\n let lParentFrame = lParent.globalFrame_();\r\n let lTransform = lParent.rwPowerClipTransform();\r\n let lInvTransform = Matrix.invert(lTransform);\r\n lParentFrame.transform(lInvTransform);\r\n\r\n const lOldScaleFrom = Matrix.scaleFrom( scale.pin, _data.scale.sx, _data.scale.sy, scale.deg );\r\n let lOldFigureFrame = _downFrame.clone().transform(lOldScaleFrom);\r\n lOldFigureFrame.transform(lInvTransform);\r\n\r\n while (lRetry++ < 5 && lFailedToScale) {\r\n if (scale.sx <= 0 || scale.sy <= 0) {\r\n break;\r\n }\r\n lFailedToScale = false;\r\n\r\n const scaleFrom = Matrix.scaleFrom( scale.pin, scale.sx, scale.sy, scale.deg );\r\n let lFigureFrame = _downFrame.clone().transform(scaleFrom);\r\n lFigureFrame.transform(lInvTransform);\r\n\r\n let lFigureDeltaP0 = substract(lFigureFrame.p0, lOldFigureFrame.p0);\r\n let lFigureDeltaP2 = substract(lFigureFrame.p2, lOldFigureFrame.p2);\r\n\r\n let lDeltaP0 = substract(lParentFrame.p0, lFigureFrame.p0);\r\n if (lDeltaP0.x > 0 && lFigureDeltaP0.x < 0)\r\n {\r\n scale.sx = (_data.scale.sx+scale.sx)/2;\r\n scale.sy = (_data.scale.sy+scale.sy)/2;\r\n lFailedToScale = true;\r\n }\r\n if (lDeltaP0.y > 0 && lFigureDeltaP0.y < 0)\r\n {\r\n scale.sx = (_data.scale.sx+scale.sx)/2;\r\n scale.sy = (_data.scale.sy+scale.sy)/2;\r\n lFailedToScale = true;\r\n }\r\n \r\n let lDeltaP2 = substract(lParentFrame.p2, lFigureFrame.p2);\r\n if (lDeltaP2.x < 0 && lFigureDeltaP2.x > 0) \r\n {\r\n scale.sx = (_data.scale.sx+scale.sx)/2;\r\n scale.sy = (_data.scale.sy+scale.sy)/2;\r\n lFailedToScale = true;\r\n }\r\n if (lDeltaP2.y < 0 && lFigureDeltaP2.y > 0)\r\n {\r\n scale.sx = (_data.scale.sx+scale.sx)/2;\r\n scale.sy = (_data.scale.sy+scale.sy)/2;\r\n lFailedToScale = true;\r\n }\r\n }\r\n if (lFailedToScale) {\r\n scale.sx = _data.scale.sx\r\n scale.sy = _data.scale.sy;\r\n }\r\n return scale;\r\n },\r\n \r\n });\r\n\r\n this.handles.clipTool = this;\r\n },\r\n\r\n link( view ) {\r\n view.on({ 'preview': this.on_preview }, this );\r\n\r\n this.handles.create();\r\n },\r\n\r\n unlink( view ) {\r\n const parent = this._selectedParent;\r\n if (parent) {\r\n parent.endEditClip$();\r\n }\r\n view.un(this);\r\n this.handles.dispose();\r\n },\r\n\r\n dispose() {\r\n this.handles.dispose();\r\n this.callParent();\r\n },\r\n\r\n draw( config ) {\r\n this.handles.draw(config);\r\n },\r\n\r\n on_keydown({ view, event, altKey, which }) {\r\n if( ! view._keyShortcuts ) {\r\n return;\r\n }\r\n\r\n switch( which ) {\r\n case 46: // 'Del'\r\n event.preventDefault();\r\n if( view.canRemove(this._selectedFigure) ) {\r\n\r\n this._selectedParent.clippedBy = \"\";\r\n view.remove(this._selectedFigure);\r\n this._selectedFigure = null;\r\n this._selectedParent = null;\r\n this.handles.update();\r\n return view.commit$();\r\n }\r\n break;\r\n }\r\n },\r\n\r\n on_pointerdown({ view, event, isPrimary, docPoint }) {\r\n if( ! isPrimary ) {\r\n return;\r\n }\r\n\r\n const { handles } = this;\r\n if( handles._editionMode ) {\r\n //this._endMode(event);\r\n return;\r\n }\r\n\r\n const leftClick = event.which === 1;\r\n if( ! leftClick ) {\r\n return;\r\n }\r\n\r\n if( handles.isHandle(event) ) {\r\n event.stopPropagation();\r\n handles.down(event);\r\n }\r\n else {\r\n let parent = this._selectedParent;\r\n if (parent) {\r\n parent.endEditClip$();\r\n this._selectedFigure = null;\r\n this._selectedParent = null;\r\n this.handles.update();\r\n //return;\r\n }\r\n \r\n parent = event.figure; // [EVENTS] view.figureAtPoint( docPoint ); // get top most figure at point\r\n if( parent ) { // click directly on figure (not handle)?\r\n\r\n event.stopPropagation();\r\n\r\n let [lClipContent, lClipParent] = parent.getClippedBy();\r\n\r\n if( lClipContent ) {\r\n parent.beginEditClip$().then( () => {\r\n this._figureClicked( lClipContent, parent );\r\n return view.render$();\r\n }).then( () => {\r\n handles.down(event);\r\n });\r\n }\r\n else if ( parent.isRaster ) {// TODO We are restricting to rasters now, but clipping can be done on any figure\r\n const lId = this._computeUniqueId();\r\n parent.addClippingRect$(lId).then( () => {\r\n [lClipContent, lClipParent] = parent.getClippedBy();\r\n this._figureClicked( lClipContent, parent );\r\n return view.render$();\r\n }).then( () => {\r\n handles.down(event);\r\n });\r\n }\r\n }\r\n else { // click on empty design area?\r\n\r\n this._selectedFigure = null;\r\n this._selectedParent = null;\r\n this.handles.update();\r\n }\r\n }\r\n },\r\n\r\n _computeUniqueId() {\r\n const lDoc = this.view.document;\r\n let lUniqueIdFound = false;\r\n let lUniqueId;\r\n for (let lUniqueIdx = 1; !lUniqueIdFound; lUniqueIdx++) {\r\n lUniqueId = \"c\" + lUniqueIdx;\r\n lUniqueIdFound = true;\r\n for( let i = 0; lUniqueIdFound && i < lDoc.figures.length; i++) {\r\n if (lDoc.figures[i].id == lUniqueId) {\r\n lUniqueIdFound = false;\r\n }\r\n }\r\n }\r\n return lUniqueId;\r\n },\r\n\r\n _figureClicked( figure, parent ) {\r\n\r\n this.view.activeDocument = parent.document;\r\n\r\n this._selectedFigure = figure;\r\n this._selectedParent = parent;\r\n\r\n this.handles.update();\r\n this.view.render$();\r\n },\r\n\r\n on_mousemove( event ) {\r\n this.handles.mousemove(event);\r\n },\r\n\r\n on_pointermove( event ) {\r\n this.handles.move(event);\r\n },\r\n\r\n on_pointerup( event ) {\r\n this.handles.up(event);\r\n },\r\n\r\n on_preview() {\r\n this.handles.update();\r\n },\r\n\r\n somethingToDraw() {\r\n return this.handles.visible;\r\n },\r\n\r\n needsToDrawFor( docIsland ) {\r\n const { frame } = this.handles;\r\n return !!frame && Frame.areOverlapping( docIsland.frame_(), this.handles.frame );\r\n }\r\n});\r\n\r\nTool.Clip = ClipTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/clip.js\n **/","import { findLast, assign } from 'lodash';\r\n\r\nimport { Matrix, Frame } from 'cdl';\r\n\r\nimport { Tool } from '../view';\r\n\r\nimport { FiguresHandles } from './select-transform';\r\n\r\n// [TODO] We should be able to allow multi selection\r\n\r\nexport const PowerClipTool = Tool.extend({ typeName: 'PowerClipTool',\r\n\r\n type: 'Final',\r\n toolbarName: 'powerClipTool',\r\n\r\n initTool( view, config ) {\r\n assign(this, config || {});\r\n this._data = null;\r\n\r\n this.handles = new FiguresHandles({ view, tool: this,\r\n\r\n editingItems: () => {\r\n const figure = this._selectedFigure;\r\n return figure ? [ figure ] : [];\r\n },\r\n\r\n computeItemsFrame_: () => {\r\n const figure = this._selectedFigure;\r\n const parent = this._selectedParent;\r\n const frame = figure.frame_();\r\n return frame.transformed( parent.rwPowerClipTransform() );\r\n },\r\n\r\n itemsEnabledContentEdit( /* view, figures */ ) {\r\n return false;\r\n },\r\n\r\n translateItems: ( items, offset ) => {\r\n this.transformItems(items,Matrix.translate(offset));\r\n },\r\n\r\n transformItems: this.transformItems.bind(this),\r\n\r\n commit$: () => {\r\n const parent = this._selectedParent;\r\n if( ! parent.usingPowerClipLink() ) {\r\n parent.invalidate();\r\n }\r\n view.commit$();\r\n }\r\n });\r\n },\r\n\r\n transformItems( items, transform ) { // Ignore items\r\n const figure = this._selectedFigure;\r\n const parent = this._selectedParent;\r\n\r\n const parentMatrix = parent.rwPowerClipTransform();\r\n\r\n // And transform again\r\n figure.transform( Matrix.concat( parentMatrix.inverted(), transform, parentMatrix ) );\r\n\r\n // We only need to invalidate the view, this should be automatic when\r\n // calling figure.transform(..) [TODO][PC]\r\n if( parent.usingPowerClipLink() ) {\r\n parent.invalidateView();\r\n }\r\n },\r\n\r\n link( view ) {\r\n view.on({ 'preview': this.on_preview }, this );\r\n\r\n this.handles.create();\r\n },\r\n\r\n unlink( view ) {\r\n view.un(this);\r\n this.handles.dispose();\r\n },\r\n\r\n dispose() {\r\n this.handles.dispose();\r\n this.callParent();\r\n },\r\n\r\n draw( config ) {\r\n this.handles.draw(config);\r\n },\r\n\r\n on_pointerdown({ view, event, isPrimary, docPoint }) {\r\n if( ! isPrimary ) {\r\n return;\r\n }\r\n\r\n const { handles } = this;\r\n if( handles._editionMode ) {\r\n this._endMode(event);\r\n return;\r\n }\r\n\r\n const leftClick = event.which === 1;\r\n if( ! leftClick ) {\r\n return;\r\n }\r\n\r\n if( handles.isHandle(event) ) {\r\n event.stopPropagation();\r\n handles.down(event);\r\n }\r\n else {\r\n\r\n const parent = event.figure; // [EVENTS] view.figureAtPoint( docPoint ); // get top most figure at point\r\n if( parent ) { // click directly on figure (not handle)?\r\n\r\n event.stopPropagation();\r\n\r\n // Find figure inside of powerclip to move\r\n const pcContent = parent.powerClipContents[0];\r\n const parentMatrixInv = parent.rwPowerClipTransform().inverted();\r\n const pcPoint = parentMatrixInv.apply(docPoint);\r\n if( pcContent ) {\r\n\r\n // [TODO] This needs to be abstracted\r\n let figure = findLast( pcContent.figures, f => f.containsPoint(pcPoint) );\r\n if( ! figure ) {\r\n // Try frame hit testing\r\n figure = findLast( pcContent.figures, f => f._outputFigure && f.frame_().contains(pcPoint) );\r\n }\r\n\r\n if( figure ) {\r\n this._figureClicked( figure, parent );\r\n\r\n view.render$() .then( () => {\r\n handles.down(event);\r\n });\r\n }\r\n }\r\n }\r\n else { // click on empty design area?\r\n\r\n this._selectedFigure = null;\r\n this._selectedParent = null;\r\n this.handles.update();\r\n }\r\n }\r\n },\r\n\r\n _figureClicked( figure, parent ) {\r\n\r\n this.view.activeDocument = parent.document;\r\n\r\n this._selectedFigure = figure;\r\n this._selectedParent = parent;\r\n\r\n this.handles.update();\r\n this.view.render$();\r\n },\r\n\r\n on_mousemove( event ) {\r\n this.handles.mousemove(event);\r\n },\r\n\r\n on_pointermove( event ) {\r\n this.handles.move(event);\r\n },\r\n\r\n on_pointerup( event ) {\r\n this.handles.up(event);\r\n },\r\n\r\n on_preview() {\r\n this.handles.update();\r\n },\r\n\r\n somethingToDraw() {\r\n return this.handles.visible;\r\n },\r\n\r\n needsToDrawFor( docIsland ) {\r\n const { frame } = this.handles;\r\n return !!frame && Frame.areOverlapping( docIsland.frame_(), this.handles.frame );\r\n }\r\n});\r\n\r\nTool.PowerClip = PowerClipTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/power-clip.js\n **/","import { forEach, assign } from 'lodash';\r\n\r\nimport { resolve } from 'gear';\r\n\r\nimport { Matrix, Bounds, Boundary,\r\n AbsoluteAnchor, Shape } from 'cdl';\r\n\r\nimport { Tool, fastThrottle } from '../view';\r\n\r\nexport const AddFigureTool = Tool.extend({ typeName: 'AddFigureTool',\r\n\r\n type: 'Final',\r\n\r\n toolbarName: 'addFigureTool',\r\n\r\n useCursor: 'crosshair',\r\n\r\n initTool( view, figure ) {\r\n this._figure = figure;\r\n return figure.update$();\r\n },\r\n\r\n link( view ) {\r\n view.cursor = 'crosshair';\r\n },\r\n unlink( view ) {\r\n view.cursor = 'default';\r\n },\r\n\r\n get brush() {\r\n return this._figure.brush;\r\n },\r\n set brush( brush_ ) {\r\n const figure = this._figure;\r\n if( figure.isShape ) {\r\n forEach( figure.polyregions, p => p.brush = brush_ );\r\n }\r\n else {\r\n figure.brush = brush_;\r\n }\r\n },\r\n\r\n get pen() {\r\n return this._figure.pen;\r\n },\r\n set pen( pen_ ) {\r\n const figure = this._figure;\r\n if( figure.isShape ) {\r\n forEach( figure.polyregions, p => p.pen = pen_ );\r\n }\r\n else {\r\n figure.pen = pen_;\r\n }\r\n },\r\n\r\n cleanUpFigure( /*figure*/ ) {\r\n // ...\r\n },\r\n\r\n _commitFigure$() {\r\n const addedFigure = this._addedFigure;\r\n if( ! addedFigure ) {\r\n return resolve();\r\n }\r\n\r\n this.cleanUpFigure(addedFigure);\r\n this._addedFigure = null;\r\n return this.view.commit$();\r\n },\r\n\r\n _commit$() {\r\n return this._commitFigure$();\r\n },\r\n\r\n _cancel$( view ) {\r\n view.remove(this._addedFigure);\r\n return view.preview$();\r\n },\r\n\r\n on_pointerdown({ view, event, docPoint, which }) {\r\n const leftClick = which === 1 ;\r\n\r\n if( leftClick ) {\r\n event.stopPropagation();\r\n\r\n this._minSize = view.viewDeltaToDoc(10);\r\n\r\n this._posDoc = docPoint;\r\n this._downPosDoc = this._posDoc.clone();\r\n\r\n const figure = this._addedFigure = this._figure.clone();\r\n figure.bounds$() .then( bounds => {\r\n\r\n this._initialWidth = view.viewDeltaToDoc(400);\r\n this._initialHeight = this._initialWidth * bounds.height/bounds.width;\r\n const initialBounds = Bounds.ofPoints([this._downPosDoc, this._downPosDoc.plus_(this._initialWidth,this._initialHeight)]);\r\n\r\n figure.fit$(initialBounds) .then( () => {\r\n\r\n this._originalMatrix22 = figure.matrix22.clone();\r\n this._originalPin = figure.pin.clone();\r\n\r\n view.add(figure);\r\n\r\n this.on_pointermove(event);\r\n\r\n }); });\r\n }\r\n },\r\n\r\n on_pointermove: fastThrottle(function({ view, event, docPoint, cmdKey }) {\r\n const figure = this._addedFigure;\r\n if( ! figure ) {\r\n return;\r\n }\r\n\r\n this._posDoc = docPoint;\r\n\r\n this._ctrlKey = cmdKey;\r\n const t = this.computeTransform();\r\n\r\n figure.matrix22 = this._originalMatrix22.clone();\r\n figure.pin = this._originalPin.clone();\r\n\r\n figure.transform(t);\r\n\r\n view.preview$();\r\n\r\n }, 10),\r\n\r\n on_pointerup() {\r\n this._commitFigure$();\r\n },\r\n\r\n computeTransform() {\r\n const cp = this._posDoc, dp = this._downPosDoc ;\r\n const bounds = Bounds.ofPoints([cp,dp]);\r\n\r\n const minSize = this._minSize;\r\n\r\n const initialWidth = this._initialWidth,\r\n initialHeight = this._initialHeight;\r\n\r\n let nextWidth = bounds.width;\r\n let nextHeight = bounds.height;\r\n\r\n // Guard against to small figures\r\n if( nextWidth < minSize ) {\r\n nextWidth = minSize;\r\n if( cp.x < dp.x ) {\r\n bounds.lx = dp.x - minSize;\r\n }\r\n }\r\n if( nextHeight < minSize ) {\r\n nextHeight = minSize;\r\n if( cp.y < dp.y ) {\r\n bounds.ly = dp.y - minSize;\r\n }\r\n }\r\n\r\n let sx = nextWidth / initialWidth,\r\n sy = nextHeight / initialHeight;\r\n\r\n if( this._ctrlKey ) {\r\n // Isometric locking\r\n if( sx > sy ) {\r\n sy = sx;\r\n if(cp.y < dp.y) {\r\n bounds.ly = dp.y - initialHeight * sy;\r\n }\r\n }\r\n else {\r\n sx = sy;\r\n if(cp.x < dp.x) {\r\n bounds.lx = dp.x - initialWidth * sx;\r\n }\r\n }\r\n }\r\n\r\n const { lx_ly } = bounds;\r\n const transform = Matrix.m( Matrix.scaleFrom( lx_ly, sx,sy ),\r\n Matrix.translate( lx_ly .minus( dp ) ) );\r\n return transform;\r\n }\r\n});\r\n\r\nTool.AddFigure = AddFigureTool;\r\n\r\nexport const DrawCurveTool = AddFigureTool.extend({ typeName: 'DrawCurveTool',\r\n initTool( view, curve, config = {} ) {\r\n if( ! config.pen ) {\r\n config.pen = Tool.defaultPen();\r\n }\r\n if( ! config.brush ) {\r\n config.brush = Tool.defaultBrush();\r\n }\r\n const figure = Shape.createFromCurve( curve, config );\r\n\r\n this.callParent(view,figure,config);\r\n },\r\n cleanUpFigure( figure ) {\r\n // Apply transform to the polyregion\r\n const matrix = figure._computeMatrix();\r\n\r\n const polyregion = figure.polyregions[0];\r\n\r\n polyregion.transform(matrix);\r\n polyregion.renderFrame = null;\r\n polyregion.renderMatrix = null;\r\n\r\n const center = polyregion.bounds.center;\r\n figure.anchor = AbsoluteAnchor(center.clone());\r\n figure.matrix22 = new Matrix();\r\n figure.pin = center.clone();\r\n }\r\n});\r\n\r\nexport const DrawRectangleTool = DrawCurveTool.extend({ typeName: 'DrawRectangleTool',\r\n toolbarName: 'drawRectangleTool',\r\n initTool( view, config ) {\r\n const curve = Boundary.createRectangle(assign({ width: 500, height: 500 },config));\r\n this.callParent(view,curve,config);\r\n }\r\n});\r\nTool.DrawRectangle = DrawRectangleTool;\r\n\r\nexport const DrawEllipseTool = DrawCurveTool.extend({ typeName: 'DrawEllipseTool',\r\n toolbarName: 'drawEllipseTool',\r\n initTool( view, config ) {\r\n const curve = Boundary.createEllipse(assign({ width: 500, height: 500 },config));\r\n this.callParent(view,curve,config);\r\n }\r\n});\r\nTool.DrawEllipse = DrawEllipseTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/add-figure.js\n **/","import { last } from 'lodash';\r\n\r\nimport { resolve, strokeSegment, dot } from 'gear';\r\n\r\nimport { Bounds, Curve, Cubic, Segment,\r\n Shape, Polyregion, Region, AbsoluteAnchor } from 'cdl';\r\n\r\nimport { Tool, usingTouch, padScaling } from '../view';\r\n\r\nconst redraw = function() {\r\n this.view.redraw('tools');\r\n};\r\n\r\nexport const DrawTool = Tool.extend({ typeName: 'DrawTool',\r\n\r\n Properties: {\r\n pen : { type: 'Pen' , def: Tool.defaultPen() , onChange: redraw },\r\n brush : { type: 'Brush', def: Tool.defaultBrush(), onChange: redraw }\r\n },\r\n\r\n target: 'document',\r\n\r\n type: 'Final',\r\n toolbarName: 'drawTool',\r\n\r\n initTool( view, config = {} ) {\r\n this._closedConfig = config.closed !== undefined ? config.closed : false;\r\n this._flushShape();\r\n this._flushPath();\r\n this.closeDistance = 0.1 * 96;\r\n this.editingDistance = 0.05 * 96;\r\n },\r\n\r\n _flushShape() {\r\n this._paths = [];\r\n this._closed = this._closedConfig;\r\n },\r\n\r\n _flushPath() {\r\n this.toolhelp('Click to begin path',\r\n 'Enter or Double Click to commit, Esc to cancel');\r\n this._nextPiece = null;\r\n this._pieces = [];\r\n this._redoPieces = [];\r\n this._editingPiece = null;\r\n this._initialPoint = null;\r\n },\r\n\r\n on_nextpiece() {\r\n this.toolhelp('Click to add new point',\r\n 'Click and hold to add a curve',\r\n 'Click on the initial point to close',\r\n 'Double Click to leave open');\r\n },\r\n\r\n draw({ view, context, transform }) {\r\n\r\n // Draw semitransparent mask\r\n // context.fillStyle = 'rgba(255,255,255,0.75)';\r\n // view.fill(context);\r\n\r\n const pieces = this._pieces.slice();\r\n const pen = this._pen, brush = this._brush;\r\n\r\n let lastWasClosed = false;\r\n\r\n const drawPath = function(closed) {\r\n pen.setupContext(context,transform);\r\n context.stroke();\r\n\r\n if (closed) {\r\n if (brush._type === 'Brush') {\r\n context.fillStyle = brush._color.rgba;\r\n } else {\r\n // Draw temporary semitransparent mask\r\n // Brush is applied to the Polyregion in commitChanges$()\r\n // This way all brush types are supported\r\n context.fillStyle = 'rgba(255,255,255,0.5)';\r\n }\r\n\r\n context.fill('evenodd');\r\n }\r\n\r\n context.beginPath();\r\n };\r\n\r\n context.beginPath();\r\n let paths = 0;\r\n\r\n for(let k=0,kEnd=this._paths.length;k 0 ) {\r\n drawPath(lastWasClosed);\r\n paths = 0;\r\n }\r\n\r\n paths_k.draw(context,transform);\r\n paths++;\r\n lastWasClosed = closed;\r\n }\r\n\r\n const dotSize = view.viewDeltaToTexture(3);\r\n\r\n if( this._drawing ) {\r\n\r\n const closed = this._closed || this._pathIsClosed();\r\n\r\n if( closed !== lastWasClosed && paths > 0 ) {\r\n drawPath(lastWasClosed);\r\n paths = 0;\r\n }\r\n\r\n const ep = this._editingPiece;\r\n if( ep ) {\r\n pieces.push( ep );\r\n }\r\n else if( this._nextPiece && ! usingTouch ) {\r\n pieces.push( this._nextPiece );\r\n }\r\n if( pieces.length > 0 ) {\r\n const curve = new Curve(pieces,closed); // Always false to show feedback on the missing part\r\n curve.draw(context,transform);\r\n paths++;\r\n\r\n drawPath(closed);\r\n paths = 0;\r\n\r\n context.lineWidth = view.viewDeltaToTexture(1);\r\n context.strokeStyle = 'rgba(10,150,50,1.0)';\r\n\r\n if( ep && ep instanceof Cubic ) {\r\n context.beginPath();\r\n const c1 = ep.P2, c2 = ep.P3 .plus( ep.P3.minus(ep.P2) );\r\n strokeSegment(context,c1,c2,transform);\r\n context.fillStyle = 'rgba(10,100,30,1.0)';\r\n dot(context,c1,dotSize,transform);\r\n dot(context,c2,dotSize,transform);\r\n }\r\n else if( this._lastPieceWasModified && this._pieces.length > 0 ) {\r\n const piece = last(this._pieces);\r\n if( piece instanceof Cubic ) {\r\n context.beginPath();\r\n const c1 = piece.P2, c2 = piece.P3 .plus( piece.P3.minus(piece.P2) );\r\n strokeSegment(context,c1,c2,transform);\r\n context.stroke();\r\n }\r\n }\r\n }\r\n }\r\n\r\n if( paths > 0 ) {\r\n drawPath(lastWasClosed);\r\n }\r\n\r\n if( this._drawing ) {\r\n const l = this._nextPiece ? this._nextPiece.P0 : ( this._pieces.length > 0 ? last(this._pieces).last() : null );\r\n if( l ) {\r\n // Draw a dot in the last commited point, because we do not have pointer move feedback in touch\r\n context.beginPath();\r\n context.fillStyle = 'rgba(240,60,40,1.0)';\r\n dot(context,l,dotSize,transform);\r\n }\r\n }\r\n },\r\n\r\n on_pointerdown({ event, isPrimary, which, docPoint, viewPoint }) {\r\n\r\n if( ! isPrimary ) {\r\n return; // ignore multitouch\r\n }\r\n\r\n const leftClick = which === 1 ;\r\n if( leftClick ) {\r\n\r\n event.stopPropagation();\r\n\r\n this._downPos = viewPoint;\r\n\r\n this._drawing = true;\r\n this.on_nextpiece();\r\n\r\n this._redoNextPiece = null;\r\n this._redoPieces = [];\r\n const np = docPoint;\r\n this._currentPoint = np;\r\n\r\n const nextPiece = this._nextPiece;\r\n if( nextPiece ) {\r\n if( nextPiece.P2 ) {\r\n nextPiece.P2 = np.clone();\r\n }\r\n nextPiece.last(np.clone());\r\n }\r\n\r\n if( this._pushPathIfClosed() ) {\r\n return;\r\n }\r\n\r\n if( ! this._initialPoint ) {\r\n this._initialPoint = np.clone();\r\n }\r\n\r\n this._editingPiece = this._nextPiece;\r\n\r\n this._nextPiece = new Segment(np,np);\r\n\r\n if( this._pieces.length > 0 && np.isEqual(last(this._pieces).P0) ) {\r\n this._nextPiece = null;\r\n this._pushPath(this._closed);\r\n }\r\n\r\n this.redraw();\r\n }\r\n const rightClick = event.which === 3;\r\n if( rightClick ) {\r\n event.stopPropagation();\r\n this.commit$();\r\n }\r\n },\r\n\r\n on_mousemove(event) {\r\n this.on_pointermove(event);\r\n event.stopPropagation();\r\n },\r\n\r\n on_pointermove({ event, view, isPrimary }) {\r\n if( ! isPrimary ) {\r\n return; // ignore multitouch\r\n }\r\n if( ! this._drawing ) {\r\n return;\r\n }\r\n\r\n const editingDistance = this.editingDistance * padScaling;\r\n\r\n const np = event.docPoint;\r\n this._currentPoint = np;\r\n\r\n let pieces = this._pieces, nextPiece = this._nextPiece;\r\n\r\n if( ! nextPiece && pieces.length > 0 ) {\r\n const P0 = last(pieces).last();\r\n nextPiece = this._nextPiece =\r\n this._lastPieceWasModified ? new Cubic(P0,np,np,np)\r\n : new Segment(P0,np) ;\r\n this._redoNextPiece = null;\r\n }\r\n\r\n let editingPiece = this._editingPiece;\r\n\r\n if( editingPiece && ! this._downPos.isNear( event.viewPoint, editingDistance ) ) {\r\n if( editingPiece instanceof Segment ) {\r\n this.toolhelp('Hold and move to change control point');\r\n editingPiece = this._editingPiece = Cubic.fromSegment(editingPiece.P0,editingPiece.P1);\r\n editingPiece.P1 = editingPiece.P0.clone();\r\n }\r\n editingPiece.P2 = editingPiece.P3 .plus( editingPiece.P3.minus(np) );\r\n this._editingPieceModified = true;\r\n }\r\n else if( nextPiece ) {\r\n if( nextPiece.P2 ) {\r\n nextPiece.P2 = np.clone();\r\n }\r\n nextPiece.last(np.clone());\r\n }\r\n\r\n this.redraw();\r\n },\r\n\r\n on_pointerup({ event, isPrimary }) {\r\n if( ! isPrimary ) {\r\n return; // ignore multitouch\r\n }\r\n if( ! this._drawing ) {\r\n return;\r\n }\r\n\r\n\r\n const editingDistance = this.editingDistance * padScaling;\r\n\r\n const editingPiece = this._editingPiece, pieces = this._pieces;\r\n\r\n if( editingPiece && ! editingPiece.P0.isNear(editingPiece.last(),editingDistance) ) {\r\n\r\n pieces.push( editingPiece );\r\n\r\n if( this._editingPieceModified ) {\r\n const lastPiece = last(pieces);\r\n const P0 = lastPiece.P3;\r\n const PC = P0 .plus( P0.minus(lastPiece.P2) );\r\n this._nextPiece = new Cubic(P0,PC.clone(),PC.clone(),PC.clone());\r\n this.on_nextpiece();\r\n }\r\n }\r\n this._editingPiece = null;\r\n this._lastPieceWasModified = this._editingPieceModified;\r\n this._editingPieceModified = false;\r\n this._downPos = null;\r\n this.redraw();\r\n },\r\n\r\n on_dblclick() {\r\n this.commit$();\r\n },\r\n\r\n undo() {\r\n if( ! this._drawing ) {\r\n if( this._paths.length > 0 ) {\r\n this._redoPaths.push(this._paths.pop());\r\n }\r\n this.view.redraw('tools');\r\n }\r\n else {\r\n if( this._nextPiece ) {\r\n this._redoNextPiece = this._nextPiece;\r\n this._nextPiece = null;\r\n }\r\n else if( this._pieces.length > 0 ) {\r\n this._redoPieces.push( this._pieces.pop() );\r\n }\r\n this.view.redraw('tools');\r\n }\r\n },\r\n\r\n redo() {\r\n if( ! this._drawing ) {\r\n if( this._redoPaths.length > 0 ) {\r\n this._paths.push( this._redoPaths.pop() );\r\n }\r\n this.view.redraw('tools');\r\n }\r\n else {\r\n if( this._redoPieces.length > 0 ) {\r\n const rp = this._redoPieces.pop();\r\n this._pieces.push(rp);\r\n this._nextPiece = null;\r\n }\r\n else if( this._redoNextPiece ) {\r\n this._nextPiece = this._redoNextPiece;\r\n this._redotNextPiece = null;\r\n }\r\n this.view.redraw('tools');\r\n }\r\n },\r\n\r\n _pathIsClosed() {\r\n const { view } = this;\r\n\r\n const ip = this._initialPoint, cp = this._currentPoint;\r\n return ip && cp &&\r\n this._pieces.length > 0 &&\r\n ip.isNear( cp, view.viewDeltaToDoc(this.closeDistance) * padScaling );\r\n },\r\n\r\n _pushPathIfClosed() {\r\n if( this._pathIsClosed() ) {\r\n if( this._nextPiece ) {\r\n this._nextPiece.last(this._initialPoint);\r\n this._pieces.push(this._nextPiece);\r\n this._nextPiece = this._editingPiece = null;\r\n }\r\n const closed = true;\r\n this._pushPath(closed);\r\n return true;\r\n }\r\n return false;\r\n },\r\n\r\n _pushPath( closed) {\r\n if( closed === undefined ) {\r\n if( this._pushPathIfClosed() ) {\r\n return resolve();\r\n }\r\n else {\r\n closed = false;\r\n }\r\n }\r\n\r\n const pieces = this._pieces;\r\n\r\n const nextPiece = this._nextPiece;\r\n if( nextPiece && !nextPiece.P0.isEqual(nextPiece.last()) ) {\r\n pieces.push(nextPiece.clone());\r\n }\r\n\r\n this._pieces = [];\r\n if( pieces.length >= 1 ) {\r\n if( closed && !pieces[0].P0.isEqual(last(pieces).last())) {\r\n pieces.push(new Segment(nextPiece.last(),pieces[0].P0));\r\n }\r\n\r\n const curve = Curve.fromNonTiedPieces(pieces,closed);\r\n this._paths.push( curve );\r\n this.view.redraw('tools');\r\n }\r\n\r\n this._flushPath();\r\n\r\n // Force a commit after each path\r\n return this.commitChanges$();\r\n },\r\n\r\n _cancel$() {\r\n // Nothing to do...\r\n },\r\n\r\n commit$() {\r\n if( this._drawing && this._pieces.length > 0 ) {\r\n return this._pushPath(this._closed);\r\n }\r\n else {\r\n return this.callParent();\r\n }\r\n },\r\n\r\n _commit$() {\r\n this.commitChanges$();\r\n },\r\n\r\n commitChanges$() {\r\n const view = this.view;\r\n if( this._paths.length === 0 ) {\r\n return;\r\n }\r\n const pen = this._pen, brush = this._brush;\r\n\r\n const polyregions = [];\r\n const pushPolyregion = function( regions, closed ) {\r\n const polyregion = new Polyregion({ regions, pen, fillMode: 'Alternate' });\r\n if( closed ) {\r\n polyregion.brush = brush;\r\n }\r\n polyregions.push(polyregion);\r\n };\r\n\r\n let regions = [];\r\n let lastWasClosed = false;\r\n\r\n for(let k=0,kEnd=this._paths.length;k 0 ) {\r\n pushPolyregion(regions,lastWasClosed);\r\n regions = [];\r\n }\r\n const region = new Region([paths_k]);\r\n regions.push(region);\r\n lastWasClosed = closed;\r\n }\r\n\r\n if( regions.length > 0 ) {\r\n pushPolyregion(regions,lastWasClosed);\r\n }\r\n const anchor = Bounds.ofThings(polyregions).center;\r\n view.add( Shape({ polyregions:polyregions,\r\n anchor: AbsoluteAnchor(anchor),\r\n pin: anchor.clone() }) );\r\n\r\n this._flushPath();\r\n this._flushShape();\r\n view.keepSelection();\r\n return view.commit$();\r\n }\r\n});\r\nTool.Draw = DrawTool;\r\n\r\nexport const DrawShapeTool = DrawTool.extend({ typeName: 'DrawShapeTool',\r\n init( config = {} ) {\r\n config.closed = true;\r\n this.callParent(config);\r\n }\r\n});\r\nTool.DrawShape = DrawShapeTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/draw.js\n **/","import { map, size, last, now } from 'lodash';\r\n\r\nimport { areEqual, clone } from 'gear';\r\n\r\nimport { Point, Bounds, Cubic, Curve, Boundary,\r\n Shape, AbsoluteAnchor, Polyregion, Region } from 'cdl';\r\n\r\nimport { Tool, padScaling } from '../view';\r\n\r\nconst { distance2 } = Point;\r\n\r\nexport const FreeDrawTool = Tool.extend({ typeName: 'FreeDrawTool',\r\n\r\n Properties: {\r\n pen : { type: 'Pen' , def: Tool.defaultPen(), onChange() { this.redraw(); } },\r\n brush : { type: 'Brush' , def: Tool.defaultBrush(), onChange() { this.redraw(); } },\r\n detectCorners: { type: 'boolean', def: true }\r\n },\r\n\r\n type: 'Final',\r\n toolbarName: 'freeDrawTool',\r\n\r\n Modes: { 0: 'Free', 1: 'Rectangle', 2: 'Circle' },\r\n\r\n initTool( view, config = {} ) {\r\n this._bind('switchCorners');\r\n\r\n this._closedConfig = config.closed !== undefined ? config.closed : false;\r\n this.flushShape();\r\n this._mode = 0; // 'Free'\r\n this.closeDistance = 0.1 * 96;\r\n this.flushCurrentPath();\r\n },\r\n\r\n flushShape() {\r\n this._closed = this._closedConfig;\r\n this._paths = [];\r\n this._redoPaths = [];\r\n },\r\n\r\n switchCorners() {\r\n this._detectCorners = ! this._detectCorners;\r\n // this.updateActions();\r\n },\r\n\r\n draw({ view, context, transform }) {\r\n\r\n // Draw semitransparent mask\r\n //context.fillStyle = 'rgba(255,255,255,0.75)';\r\n //fillContext(context);\r\n\r\n this._pen.setupContext(context,transform);\r\n\r\n const brush = this._brush, solidBrush = ( brush._type === 'Brush' );\r\n\r\n if( solidBrush ) {\r\n context.fillStyle = brush._color.rgba;\r\n } else {\r\n // Draw temporary semitransparent mask\r\n // Brush is applied to the Polyregion in commitChanges$()\r\n // This way all brush types are supported\r\n context.fillStyle = 'rgba(255,255,255,0.5)';\r\n }\r\n\r\n context.beginPath();\r\n\r\n const paths = clone(this._paths);\r\n\r\n if( this.inMode('Free') ) {\r\n const currentPoints = clone(this._points);\r\n if( this._nextPoint ) {\r\n currentPoints.push( this._nextPoint );\r\n }\r\n if( currentPoints.length > 1 ) {\r\n paths.push( currentPoints );\r\n }\r\n }\r\n else if( this._drawing ) {\r\n const stampPath = this.stampPath();\r\n if( stampPath ) {\r\n paths.push( stampPath );\r\n }\r\n }\r\n\r\n let lastIsClosed = false;\r\n\r\n for( let k = 0, kEnd = paths.length; k transform.apply(p) );\r\n const length = path.length - 1;\r\n\r\n path.unshift(path[0]);\r\n path.push( path[path.length - 1] );\r\n\r\n if( length <= 0 ) {\r\n return;\r\n }\r\n for(let n = 0; n < length; n ++) {\r\n const p1 = path[n ],\r\n p2 = path[n + 1],\r\n p3 = path[n + 2],\r\n p4 = path[n + 3];\r\n\r\n if(n === 0) {\r\n context.moveTo(p2.x, p2.y);\r\n }\r\n if( ! areEqual(p2,p3) ) {\r\n context.bezierCurveTo(\r\n p2.x + ( p3.x - p1.x) / 6, p2.y + ( p3.y - p1.y) / 6,\r\n p3.x + ( p2.x - p4.x) / 6, p3.y + ( p2.y - p4.y) / 6,\r\n p3.x , p3.y\r\n );\r\n }\r\n }\r\n\r\n if( closed ) {\r\n context.closePath();\r\n }\r\n else {\r\n context.stroke();\r\n context.beginPath();\r\n }\r\n lastIsClosed = closed;\r\n }\r\n }\r\n if( lastIsClosed ) {\r\n context.stroke();\r\n if( solidBrush ) {\r\n context.fill('evenodd');\r\n }\r\n context.beginPath();\r\n }\r\n\r\n },\r\n switchMode() {\r\n this._mode++;\r\n if( this._mode >= size(this.Modes) ) {\r\n this._mode = 0;\r\n }\r\n this.redraw();\r\n },\r\n inMode( m) {\r\n return this.Modes[this._mode] === m ;\r\n },\r\n stampBounds() {\r\n return Bounds.ofPoints([this._pointDown,this._pointTo]);\r\n },\r\n stampPath() {\r\n if( areEqual(this._pointDown, this._pointTo )) {\r\n return null;\r\n }\r\n const bounds = this.stampBounds();\r\n if( this.inMode('Rectangle') ) {\r\n return Boundary.createRectangle(bounds);\r\n }\r\n else if( this.inMode('Circle') ) {\r\n return Boundary.createEllipse(bounds);\r\n }\r\n return null;\r\n },\r\n\r\n on_pointerdown({ event, isPrimary, which, docPoint }) {\r\n if( isPrimary === false ) {\r\n return; // ignore multitouch\r\n }\r\n const t = now();\r\n if( t - this._lastTime < 500 ) {\r\n this.commit$();\r\n return;\r\n }\r\n\r\n event.stopPropagation();\r\n\r\n this._lastTime = t;\r\n\r\n const leftClick = which === 1 ;\r\n if( leftClick ) {\r\n this.toolhelp('Hold and move to draw path',\r\n 'Release near initial point to close');\r\n this._drawing = true;\r\n const np = docPoint;\r\n\r\n if( this.inMode('Free') ) {\r\n\r\n this._points.push(np);\r\n this._lastTime = t;\r\n\r\n this._pointsR.push(np);\r\n this._lastTimeR = t;\r\n }\r\n else {\r\n this._pointDown = np;\r\n this._pointTo = np;\r\n }\r\n\r\n this.redraw();\r\n this._redoPaths = [];\r\n }\r\n },\r\n\r\n on_pointermove({ event, view, isPrimary, cmdKey }) {\r\n if( ! isPrimary ) {\r\n return; // ignore multitouch\r\n }\r\n\r\n const ctrl = this._ctrl = cmdKey;\r\n if( this._drawing ) {\r\n const points = this._points, pointsR = this._pointsR;\r\n\r\n const t = now();\r\n const { docPoint } = event;\r\n\r\n if( this.inMode('Free') ) {\r\n\r\n if( this._detectCorners ) {\r\n\r\n if( t - this._lastTimeR > 25 ) {\r\n\r\n let lp = last(pointsR);\r\n\r\n const deltaVL = view.viewDeltaToDoc(3);\r\n\r\n if( distance2( docPoint, lp ) > deltaVL*deltaVL ) {\r\n const lp3TimeR = this._lastTimeRPrevPrev;\r\n\r\n pointsR.push( docPoint );\r\n\r\n this._lastTimeRPrevPrev = this._lastTimeRPrev;\r\n this._lastTimeRPrev = this._lastTimeR;\r\n this._lastTimeR = t;\r\n\r\n const delta = view.viewDeltaToDoc(14), delta2 = delta*delta;\r\n\r\n const pointsR_length = pointsR.length;\r\n if( pointsR_length > 7 ) {\r\n\r\n const lp0 = pointsR[pointsR_length-1];\r\n const lp1 = pointsR[pointsR_length-2];\r\n const lp2 = pointsR[pointsR_length-3];\r\n const lp3 = pointsR[pointsR_length-4];\r\n const lp4 = pointsR[pointsR_length-5];\r\n const lp5 = pointsR[pointsR_length-6];\r\n const lp6 = pointsR[pointsR_length-7];\r\n\r\n const turnAngle1 = Point.turnAngle( lp2.minus(lp3) ,\r\n lp3.minus(lp4) );\r\n\r\n const turnAngle2 = Point.turnAngle( lp0.minus(lp3).add( lp1.minus(lp3).add( lp2.minus(lp3) ) ) ,\r\n lp3.minus(lp6).add( lp3.minus(lp5).add( lp3.minus(lp6) ) ) );\r\n\r\n if( Math.abs( turnAngle1 ) > 50 && Math.abs( turnAngle2 ) > 75 ) {\r\n if( ! last(points).__corner__ && ( lp3TimeR < this._lastTime || distance2(last(points),lp3) < delta2 ) ) {\r\n points.pop();\r\n }\r\n if( points.length > 0 && ! last(points).__corner__ && ( lp3TimeR < this._lastTimePrev || distance2(last(points),lp3) < delta2 ) ) {\r\n points.pop();\r\n }\r\n while( points.length > 0 && ! last(points).__corner__ && distance2(last(points),lp3) < delta2 ) {\r\n points.pop();\r\n }\r\n\r\n const lpd3 = pointsR[pointsR.length-4];\r\n points.push( lpd3 );\r\n points.push( lpd3 );\r\n lpd3.__corner__ = true;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if( ctrl && points.length > 2 ) {\r\n const l = points.length;\r\n if( ! areEqual(points[l-1],points[l-2]) ) {\r\n points.push(points[l-1]);\r\n points[l-1].__corner__ = true;\r\n }\r\n this._nextPoint = docPoint;\r\n this.redraw();\r\n }\r\n else if( t - this._lastTime > 40 ) {\r\n const delta = view.viewDeltaToDoc(17);\r\n if( distance2( docPoint, last(points) ) > delta*delta ) {\r\n points.push( docPoint );\r\n this.redraw();\r\n this._lastTimePrev = this._lastTime;\r\n this._lastTime = t;\r\n this._nextPoint = null;\r\n }\r\n }\r\n if( this._lastTime !== t ) {\r\n this._nextPoint = docPoint;\r\n this.redraw();\r\n }\r\n }\r\n else {\r\n this._pointTo = docPoint;\r\n if( ctrl ) {\r\n const w = this._pointTo.x-this._pointDown.x;\r\n const h = this._pointTo.y-this._pointDown.y;\r\n if( w && h ) {\r\n const wa = Math.abs(w);\r\n const ha = Math.abs(h);\r\n if( wa > ha ) {\r\n this._pointTo.y = this._pointDown.y + h * wa/ha;\r\n }\r\n else if( ha > wa ) {\r\n this._pointTo.x = this._pointDown.x + w * ha/wa;\r\n }\r\n }\r\n }\r\n this.redraw();\r\n }\r\n }\r\n },\r\n\r\n on_pointerup( event ) {\r\n if( event.isPrimary === false ) {\r\n return; // ignore multitouch\r\n }\r\n if( ! this._drawing ) {\r\n return;\r\n }\r\n\r\n if( this.inMode('Free' ) ) {\r\n const np = this._nextPoint;\r\n if( np && ! np.isEqual( last(this._points) ) ) {\r\n this._points.push(np);\r\n }\r\n if( this._points.length > 2 ) {\r\n this._paths.push( this._points );\r\n }\r\n }\r\n else {\r\n const stampPath = this.stampPath();\r\n if( stampPath ) {\r\n this._paths.push( stampPath );\r\n }\r\n }\r\n this.flushCurrentPath();\r\n this.commitChanges$();\r\n },\r\n flushCurrentPath() {\r\n this.toolhelp('Click and hold to draw path');\r\n this._redoPaths = [];\r\n this._points = [];\r\n this._pointsR = [];\r\n this._nextPoint = null;\r\n this._drawing = false;\r\n this._ctrl = false;\r\n },\r\n\r\n catmull2beziers( points) {\r\n const path = points.slice(0);\r\n\r\n const length = path.length - 1;\r\n\r\n path.splice(0, 0, path[0]);\r\n path.push(path[path.length - 1]);\r\n\r\n const pieces = [];\r\n if( length <= 0 ) {\r\n return;\r\n }\r\n for(let n = 0; n < length; n ++) {\r\n const p1 = path[n ],\r\n p2 = path[n + 1],\r\n p3 = path[n + 2],\r\n p4 = path[n + 3];\r\n\r\n if( ! areEqual(p2,p3) ) {\r\n const q1 = p2.clone(),\r\n q2 = new Point( p2.x + (p3.x - p1.x) / 6, p2.y + (p3.y - p1.y) / 6 ),\r\n q3 = new Point( p3.x + (p2.x - p4.x) / 6, p3.y + (p2.y - p4.y) / 6 ),\r\n q4 = p3.clone();\r\n\r\n pieces.push( new Cubic(q1,q2,q3,q4) );\r\n }\r\n }\r\n return pieces;\r\n },\r\n undo() {\r\n if( ! this._drawing ) {\r\n if( this._paths.length > 0 ) {\r\n this._redoPaths.push(this._paths.pop());\r\n }\r\n this.redraw();\r\n }\r\n },\r\n redo() {\r\n if( ! this._drawing ) {\r\n if( this._redoPaths.length > 0 ) {\r\n this._paths.push( this._redoPaths.pop() );\r\n }\r\n this.redraw();\r\n }\r\n },\r\n _cancel$() {\r\n // Nothing to do...\r\n },\r\n _commit$() {\r\n return this.commitChanges$();\r\n },\r\n commitChanges$() {\r\n const view = this.view, paths = this._paths;\r\n if( paths.length > 0 ) {\r\n\r\n const pen = this._pen, brush = this._brush;\r\n\r\n const polyregions = [];\r\n const addPolyregion = function(regions,closed) {\r\n\r\n const polyregion = new Polyregion({ regions:regions, fillMode: 'Alternate', pen:pen });\r\n if( closed ) {\r\n polyregion.brush = brush;\r\n }\r\n polyregions.push(polyregion);\r\n };\r\n\r\n let regions = [];\r\n let lastWasClosed = false;\r\n for( let k = 0, kEnd = paths.length; k 0 ) {\r\n addPolyregion(regions,lastWasClosed);\r\n regions = [];\r\n }\r\n\r\n if( isCurve ) {\r\n curve = paths_k;\r\n }\r\n else {\r\n const pieces = this.catmull2beziers(paths_k);\r\n curve = Curve.fromNonTiedPieces(pieces,closed);\r\n }\r\n const region = new Region([curve]);\r\n regions.push( region );\r\n\r\n lastWasClosed = closed;\r\n }\r\n\r\n if( regions.length > 0 ) {\r\n addPolyregion(regions,lastWasClosed);\r\n regions = [];\r\n }\r\n\r\n const anchor = Bounds.ofThings(polyregions).center;\r\n\r\n view.add( Shape({ polyregions: polyregions,\r\n anchor: AbsoluteAnchor(anchor),\r\n pin: anchor.clone() }) );\r\n\r\n this.flushShape();\r\n view.keepSelection();\r\n return view.commit$();\r\n }\r\n }\r\n});\r\n\r\nTool.FreeDraw = FreeDrawTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/free-draw.js\n **/","import { find } from 'lodash';\r\n\r\nimport { if$, strokeSegment } from 'gear';\r\n\r\nimport { Point, Process, Text } from 'cdl';\r\n\r\nimport { Tool } from '../view';\r\n\r\nconst updateBrush = function() {\r\n var brush = this._brush,\r\n text = this._text;\r\n\r\n this._baseText.brush = brush;\r\n\r\n if (text) {\r\n text.brush = brush;\r\n this.view.commit$();\r\n }\r\n};\r\n\r\nconst updatePen = function() {\r\n var pen = this._pen,\r\n text = this._text;\r\n\r\n this._baseText.pen = pen;\r\n\r\n if (text) {\r\n text.pen = pen;\r\n this.view.commit$();\r\n }\r\n};\r\n\r\nexport const EditTextTool = Tool.extend({ typeName: 'EditTextTool',\r\n\r\n Properties: {\r\n pen : { type: 'Pen' , def: Tool.defaultPen() , onChange: updatePen },\r\n brush : { type: 'Brush', def: Tool.defaultBrush(), onChange: updateBrush }\r\n },\r\n\r\n type: 'Final',\r\n toolbarName: 'textTool',\r\n\r\n initTool( view, text, config = {} ) {\r\n const _this = this;\r\n _this._cursorOn = true;\r\n _this.reset();\r\n _this._baseText = new Text({ text: '',\r\n brush: _this._brush,\r\n fontSize: view.viewDeltaToDoc(30), // [TODO] do we want a stable one?\r\n pen: _this._pen\r\n });\r\n const baseTextUpdate = _this._baseText.update$();\r\n return text ? this.startEdit(text,config.event) : baseTextUpdate;\r\n },\r\n\r\n reset() {\r\n const _this = this;\r\n _this._cursor = null;\r\n _this._cursorEnd = null;\r\n _this._center = null;\r\n _this._currentChar = 0;\r\n _this._currentLine = 0;\r\n _this._changed = false;\r\n _this._text = null;\r\n },\r\n\r\n link( view ) {\r\n const _this = this;\r\n view.cursor = 'text';\r\n _this._interval = setInterval( () => {\r\n _this._cursorOn = ! _this._cursorOn;\r\n _this.view.redraw('tools');\r\n }, 500);\r\n },\r\n\r\n unlink( view ) {\r\n clearInterval( this._interval );\r\n view.cursor = 'default';\r\n },\r\n\r\n _commit$( view, doc ) {\r\n if( ! this._center ) {\r\n return;\r\n }\r\n const text = this._text;\r\n if( text.isEmpty ) {\r\n doc.remove(text);\r\n }\r\n else {\r\n view.selectedFigures = [text];\r\n }\r\n return doc.commit$();\r\n },\r\n\r\n _cancel$( view ) {\r\n return view.revert$();\r\n },\r\n\r\n canEdit( figure ) {\r\n return EditTextTool.canEdit(figure);\r\n },\r\n\r\n startEdit( text, event ) {\r\n const _this = this, view = _this.view;\r\n if( _this.canEdit(text) ) {\r\n _this._text = text;\r\n _this._center = text.pin;\r\n return text.update$() .then( () => {\r\n if( event ) {\r\n const point = event.docPoint;\r\n _this.findCurrentChar(point);\r\n }\r\n else {\r\n _this._currentChar = text.lines[0].length;\r\n _this._currentLine = 0;\r\n }\r\n _this.findCursor();\r\n this.triggerKeyboard(event);\r\n view.preview$();\r\n });\r\n }\r\n else {\r\n _this.reset();\r\n view.fireEvent('textedit',view,text,event);\r\n }\r\n },\r\n\r\n on_pointerdown({ event, view, which, docPoint }) {\r\n const _this = this;\r\n if$( _this._text && _this._changed, () => {\r\n\r\n const text = _this._text;\r\n _this.reset();\r\n if( text.isEmpty ) {\r\n view.remove(text);\r\n }\r\n view.keepSelection();\r\n return view.commit$();\r\n\r\n }) .then( () => {\r\n\r\n const leftClick = which === 1 ;\r\n\r\n if( leftClick ) {\r\n const point = docPoint;\r\n\r\n const figure = event.figure; // [EVENTS] view.figureAtPoint(point);\r\n if( figure && figure.isText ) {\r\n _this.startEdit(figure,event);\r\n }\r\n else {\r\n _this._text = _this._baseText.clone();\r\n _this._text.fontSize = view.viewDeltaToDoc(30);\r\n const center = _this._center = point;\r\n _this._text.pin = center;\r\n _this._currentChar = 0;\r\n _this._currentLine = 0;\r\n _this._changed = true;\r\n _this.findCursor();\r\n this.triggerKeyboard(event);\r\n view.add(_this._text); // We need a better abstraction here\r\n view.preview$();\r\n }\r\n }\r\n });\r\n },\r\n\r\n on_keydown({ event, cmdKey, which }) {\r\n\r\n // console.log('edit text - keydown');\r\n\r\n const _this = this;\r\n const currentChar = _this._currentChar;\r\n const currentLine = _this._currentLine;\r\n const keyHome = which === 36, keyEnd = which === 35;\r\n\r\n if( which === 27 ) {\r\n event.stopPropagation();\r\n return this.commit$();\r\n }\r\n\r\n const figure = _this._text;\r\n\r\n if( ! figure ) {\r\n return;\r\n }\r\n\r\n const lines = figure.lines;\r\n const line = lines[currentLine];\r\n\r\n if( which === 13 ) { // Enter\r\n event.stopPropagation();\r\n\r\n if( _this._text.isEmpty ) {\r\n return;\r\n }\r\n\r\n if( find( figure._processes, p =>\r\n p instanceof Process.FitOnPath ||\r\n p instanceof Process.FitEllipse ||\r\n p instanceof Process.ClassicArc ||\r\n p instanceof Process.FitEnvelope ) ) {\r\n // Do not accept line break\r\n return;\r\n }\r\n\r\n _this._changed = true;\r\n lines[currentLine] = line.slice(0,currentChar);\r\n lines.splice(currentLine+1,0, \"\");\r\n lines[currentLine+1] = line.slice(currentChar);\r\n figure.lines = lines;\r\n if( currentChar > 0 ) {\r\n _this._currentLine++;\r\n _this._currentChar = 0;\r\n }\r\n _this.updateText();\r\n }\r\n else if( which === 8 ) { // Backspace\r\n event.preventDefault();\r\n if( currentChar > 0 ) {\r\n _this._changed = true;\r\n lines[currentLine] = line.slice(0, currentChar-1) + line.slice(currentChar);\r\n figure.lines = lines;\r\n _this._currentChar--;\r\n _this.updateText();\r\n }\r\n else if( currentChar === 0 && currentLine > 0 ) {\r\n _this._changed = true;\r\n _this._currentChar = lines[currentLine-1].length;\r\n _this._currentLine--;\r\n lines[currentLine-1] = lines[currentLine-1]+lines[currentLine];\r\n lines.splice(currentLine,1);\r\n figure.lines = lines;\r\n _this.updateText();\r\n }\r\n }\r\n else if( which === 46 ) { // Delete\r\n event.stopPropagation();\r\n if( currentChar < line.length ) {\r\n _this._changed = true;\r\n lines[currentLine] = line.slice(0, currentChar) + line.slice(currentChar+1);\r\n figure.lines = lines;\r\n _this.updateText();\r\n }\r\n else if( currentChar === line.length && currentLine < lines.length ) {\r\n _this._changed = true;\r\n lines[currentLine] = lines[currentLine]+lines[currentLine+1];\r\n lines.splice(currentLine+1,1);\r\n figure.lines = lines;\r\n _this.updateText();\r\n }\r\n }\r\n else if( which === 37 || keyHome ) { // Left arrow\r\n event.stopPropagation();\r\n if( currentChar > 0 ) {\r\n if( cmdKey || keyHome ) {\r\n _this._currentChar = 0;\r\n }\r\n else {\r\n _this._currentChar--;\r\n }\r\n _this.updateText();\r\n }\r\n }\r\n else if( which === 39 || keyEnd ) { // Right arrow\r\n event.stopPropagation();\r\n if( currentChar < line.length ) {\r\n if( cmdKey || keyEnd ) {\r\n _this._currentChar = line.length;\r\n }\r\n else {\r\n _this._currentChar++;\r\n }\r\n _this.updateText();\r\n }\r\n }\r\n else if( which === 38 ) { // Up\r\n event.stopPropagation();\r\n if( currentLine > 0 ) {\r\n _this._currentLine--;\r\n _this._currentChar = Math.floor(lines[_this._currentLine].length/2);\r\n _this.updateText();\r\n }\r\n }\r\n else if( which === 40 ) { // Down\r\n event.stopPropagation();\r\n if( currentLine < lines.length-1 ) {\r\n _this._currentLine++;\r\n _this._currentChar = Math.floor(lines[_this._currentLine].length/2);\r\n _this.updateText();\r\n }\r\n }\r\n },\r\n\r\n on_keypress({ event, which, char }) {\r\n // console.log('edit text - keypress');\r\n const _this = this;\r\n if( ! _this._text ) {\r\n return;\r\n }\r\n event.stopPropagation();\r\n if( which === 13 ) {\r\n // We handle Enter on keydown\r\n return;\r\n }\r\n\r\n const currentChar = _this._currentChar, currentLine = _this._currentLine;\r\n const figure = _this._text;\r\n const lines = figure.lines;\r\n\r\n const line = lines[currentLine];\r\n\r\n _this._changed = true;\r\n lines[currentLine] = line.slice(0,currentChar) + char + line.slice(currentChar);\r\n figure.lines = lines;\r\n _this._currentChar++;\r\n\r\n _this.updateText();\r\n },\r\n\r\n updateText() {\r\n const _this = this, view = _this.view, text = _this._text;\r\n\r\n text.update$() .then( () => {\r\n _this.findCursor();\r\n\r\n view.preview$();\r\n });\r\n },\r\n\r\n findCurrentChar( point ) {\r\n const figure = this._text;\r\n if( figure.isEmpty ) {\r\n this._currentChar = 0;\r\n this._currentLine = 0;\r\n }\r\n else {\r\n const matrix = figure.matrix_(),\r\n tp = matrix.inverted().apply(point),\r\n layout = figure._textLayout,\r\n textLines = layout.textLines();\r\n\r\n let currentChar = 0,\r\n currentLine = 0,\r\n minDist = Number.MAX_VALUE;\r\n\r\n for( let kl = 0, klEnd = textLines.length; kl < klEnd; ++kl ) {\r\n\r\n const textLine = textLines[kl],\r\n lineChars = textLine.allChars(),\r\n charsLength = lineChars.length;\r\n\r\n if( textLine._chars.length > 0 ) { // there should be at least one proper glyph (do not use _allChars here)\r\n const dToEnd = Point.distance2(this.closerGlyph(lineChars,charsLength-1)._baselineRightGrip,tp);\r\n if( dToEnd < minDist ) {\r\n minDist = dToEnd;\r\n currentChar = charsLength;\r\n currentLine = kl;\r\n }\r\n for( let kc = 0; kc < charsLength; kc++ ) {\r\n const char = lineChars[kc];\r\n if( char ) {\r\n const d = Point.distance2(char._grip,tp);\r\n if( d < minDist ) {\r\n minDist = d;\r\n currentChar = kc;\r\n currentLine = kl;\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n const baseDist = Point.distance2(textLine._baseline.P0,tp);\r\n if( baseDist < minDist ) {\r\n minDist = baseDist;\r\n currentChar = 0;\r\n currentLine = kl;\r\n }\r\n }\r\n }\r\n this._currentChar = currentChar;\r\n this._currentLine = currentLine;\r\n }\r\n },\r\n\r\n closerGlyph( allChars, pos ) {\r\n const count = allChars.length;\r\n let char = allChars[pos],\r\n n = pos-1;\r\n while( ! char && n >= 0 ) {\r\n char = allChars[n--];\r\n }\r\n n = pos+1;\r\n while( ! char && n < count ) {\r\n char = allChars[n++];\r\n }\r\n return char;\r\n },\r\n\r\n findCursor() {\r\n const figure = this._text, center = this._center;\r\n const fontSize = figure.fontSize;\r\n const matrix = figure.matrix_();\r\n if( figure.isEmpty ) {\r\n this._cursor = center;\r\n this._cursorEnd = matrix.apply( matrix.inverted().apply(center) .plus_(0,fontSize) );\r\n }\r\n else {\r\n const currentChar = this._currentChar;\r\n const layout = figure._textLayout;\r\n const line = layout.textLines()[this._currentLine];\r\n const allChars = line.allChars();\r\n const bs = line._baseline;\r\n if( line._chars.length > 0 ) { // If there is a proper glyph\r\n const char = this.closerGlyph( allChars, currentChar );\r\n const before = char._originalIdx <= currentChar;\r\n const grip = before ? char._baselineRightGrip : char._grip;\r\n const frameDirX = char._frame.dir_x;\r\n const c = grip .plus( frameDirX .scaled( fontSize/20 * ( before ? 1 : -1 ) ) );\r\n this._cursor = matrix.apply( c );\r\n\r\n if( figure._processes.length > 0 ) {\r\n const frame = char._frame;\r\n const cursorH = ( before ) ? frame.p2 .minus( frame.p1 ) : frame.p3 .minus( frame.p0 );\r\n this._cursorEnd = matrix.apply( c .plus( cursorH ) );\r\n }\r\n else {\r\n this._cursorEnd = matrix.apply( c .plus( ( bs.P1 .minus( bs.P0 ) ).normalize().perpendicular().sm(fontSize) ) );\r\n }\r\n }\r\n else{\r\n this._cursor = matrix.apply(bs.P0);\r\n this._cursorEnd = matrix.apply( bs.P0 .plus( ( bs.P1 .minus( bs.P0 ) ).normalize().perpendicular().sm(fontSize) ) );\r\n }\r\n }\r\n this.view.redraw('tools');\r\n },\r\n\r\n drawCursorLine( context, transform, lineWidth, strokeStyle ) {\r\n context.lineWidth = lineWidth;\r\n context.strokeStyle = strokeStyle;\r\n strokeSegment( context, this._cursor, this._cursorEnd, transform );\r\n },\r\n\r\n draw({ view, context, transform }) {\r\n const center = this._center;\r\n if( ! center || ! this._cursorOn || ! this._cursor ) {\r\n return;\r\n }\r\n const textureScale = view.viewDeltaToTexture(1);\r\n this.drawCursorLine(context,transform,3*textureScale,\"#dbdbdb\");\r\n this.drawCursorLine(context,transform,1*textureScale,\"#248e1f\");\r\n }\r\n});\r\n\r\nTool.Text = Tool.EditText = EditTextTool;\r\n\r\nEditTextTool.canEdit = function( figure ) {\r\n return figure.isText &&\r\n figure.canBeProcessedLocally() &&\r\n ! figure.isMultiPart;\r\n};\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/edit-text.js\n **/","import { find, every } from 'lodash';\r\n\r\nimport { Magnitude, findByType, if$ } from 'gear';\r\n\r\nimport { Point, Process, TextChar,\r\n CharTransform, CharTransformList } from 'cdl';\r\n\r\nimport { Tool } from '../view';\r\n\r\n\r\nexport const CharsTransformTool = Tool.extend({ typeName: 'CharsTransformTool',\r\n type: 'Final',\r\n toolbarName: 'charsTransformTool',\r\n initTool( view, text ) {\r\n const _this = this;\r\n _this._char = null;\r\n _this._text = null;\r\n\r\n if( text && _this.canEdit(text) ) {\r\n _this._text = text;\r\n return _this.updateText$();\r\n }\r\n },\r\n canEdit( figure ) {\r\n return figure.isText &&\r\n figure.canBeProcessedLocally() &&\r\n every( figure.processes, p => p.outputsText() ) &&\r\n ! figure.isMultiPart;\r\n },\r\n updateText$() {\r\n const _this = this;\r\n return _this._text.update$() .then( () => {\r\n _this._matrix = _this._text.matrix_();\r\n _this.view.redraw('tools');\r\n });\r\n },\r\n\r\n link( view ) {\r\n view.cursor = 'pointer';\r\n },\r\n\r\n unlink( view ) {\r\n view.cursor = 'default';\r\n },\r\n\r\n _commit$( view, doc ) {\r\n const text = this._text;\r\n if( text ) {\r\n view.selectedFigures = [text];\r\n }\r\n return doc.commit$();\r\n },\r\n\r\n _cancel$( view ) {\r\n return view.revert$();\r\n },\r\n\r\n on_pointerdown({ view, event, which, docPoint }) {\r\n const _this = this;\r\n const leftClick = which === 1 ;\r\n if( leftClick ) {\r\n const point = docPoint;\r\n\r\n const text = _this._text;\r\n if( text ) {\r\n const char = _this._char = text.charAtPoint_(point);\r\n if( char ) {\r\n event.stopPropagation();\r\n _this._point = point;\r\n _this._downPoint = point.clone();\r\n const matrix = text.matrix_();\r\n _this._charGrip = matrix.apply( char._grip );\r\n _this.view.redraw('tools');\r\n return;\r\n }\r\n }\r\n\r\n const figure = event.figure; // [EVENTS] view.figureAtPoint(point);\r\n if( figure && _this.canEdit(figure) ) {\r\n event.stopPropagation();\r\n if$( _this._changed, () => {\r\n _this._changed = false;\r\n return view.commit$();\r\n }) .then( () => {\r\n _this._text = figure;\r\n _this.updateText$();\r\n });\r\n }\r\n else {\r\n _this._point = _this._downPoint = null;\r\n _this.view.redraw('tools');\r\n }\r\n }\r\n },\r\n on_pointermove({ event, view }) {\r\n const char = this._char;\r\n if( char && this._point ) {\r\n const text = this._text;\r\n const pn = this._point = event.docPoint;\r\n const invMatrix = text.matrix_().inverted();\r\n const offset = pn.minus(this._downPoint);\r\n\r\n char.placeAt('Grip',invMatrix.apply( this._charGrip.plus(offset) ));\r\n\r\n // Regenerate output figure, we need a helper here.\r\n // Manually preserve the anchor for the moment\r\n const anchor = text.outputFigure.anchor;\r\n const newOutput = text._textLayout.shape();\r\n newOutput.anchor = anchor;\r\n\r\n text.outputFigure = newOutput;\r\n\r\n text._cache.clear();\r\n text.invalidateView();\r\n\r\n view.batchRedraw('tools');\r\n\r\n view.preview$();\r\n }\r\n },\r\n on_pointerup() {\r\n const char = this._char;\r\n if( char ) {\r\n this._changed = true;\r\n\r\n const text = this._text,\r\n textLayout = text._textLayout,\r\n spaceWidth = textLayout.spaceWidth(),\r\n invMatrix = this._matrix.inverted(),\r\n docOffset = this._point .minus( this._downPoint),\r\n finalPos = invMatrix.apply( this._charGrip .plus( docOffset )),\r\n offset = finalPos .minus( invMatrix.apply(this._charGrip) );\r\n\r\n const idx = char._idx, lineIdx = char._lineIdx;\r\n\r\n // Update layout transforms, in case other processes call layout.outdate()\r\n char._charData._transformers.push( new TextChar.PinPlacer('Grip', char._grip.clone() ) );\r\n\r\n // Update text processes\r\n const processes = text._processes;\r\n let charsTransform = findByType(processes,Process.CharsTransform);\r\n if( ! charsTransform ) {\r\n charsTransform = new Process.CharsTransform();\r\n processes._push( charsTransform ); // Avoid events, the output is already modified\r\n }\r\n let ctl = find( charsTransform._chars, c => c._lineIdx === lineIdx && c._idx === idx );\r\n if( ! ctl ) {\r\n ctl = new CharTransformList({ lineIdx: lineIdx, idx: idx });\r\n charsTransform._chars._push(ctl);\r\n }\r\n let to = findByType(ctl._transforms,CharTransform.TangencialOffset);\r\n if( ! to ) {\r\n to = new CharTransform.TangencialOffset();\r\n ctl._transforms._push(to);\r\n }\r\n const dirX = char._frame.dir_x;\r\n const co_h = Point.dotProduct(dirX,offset);\r\n const co_v = Point.dotProduct(dirX.perpendicular(),offset);\r\n to._h = new Magnitude(((Magnitude.absoluteMMValueFor(to._h,spaceWidth)+co_h) / spaceWidth * 100).toFixed(4), '%');\r\n to._v = new Magnitude(((Magnitude.absoluteMMValueFor(to._v,spaceWidth)+co_v) / spaceWidth * 100).toFixed(4), '%');\r\n\r\n this._point = this._downPoint = null;\r\n }\r\n },\r\n\r\n draw({ view, context, transform }) {\r\n const char = this._char;\r\n const e = view.viewDeltaToTexture(3);\r\n context.lineWidth = view.viewDeltaToTexture(1);\r\n if( char ) {\r\n context.strokeStyle = \"#248e1f\";\r\n const frame = char._frame.transformed(this._matrix).extended(e,e,e,e);\r\n frame.draw(context,transform);\r\n context.stroke();\r\n }\r\n else if( this._text ) {\r\n const figure = this._text;\r\n const figureFrame = figure.frame_().transformed(transform).extended(e,e,e,e);\r\n context.strokeStyle = \"#248e1f\";\r\n figureFrame.draw(context);\r\n context.stroke();\r\n }\r\n }\r\n});\r\n\r\nTool.CharsTransform = CharsTransformTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/chars-transform.js\n **/","import { Config } from 'config';\r\n\r\nimport { forEach, map, find, last, now } from 'lodash';\r\n\r\nimport { Base, isArray, cloneDeep, findByType, resolve, if$,\r\n dot, strokeDot, strokeCross, strokeSegment } from 'gear';\r\n\r\nimport { Point, Matrix, Bounds, Frame, Segment, Cubic, Curve,\r\n Color, Process, Envelope } from 'cdl';\r\n\r\nimport { Tool, padScaling } from '../view';\r\n\r\nconst Point_add = Point.add,\r\n Point_substract = Point.substract,\r\n Point_sm = Point.sm,\r\n Color_fromRgb = Color.fromRgb,\r\n knotSize = 3,\r\n knotSelectedSize = 4;\r\n\r\n// [TODO] directly use fillStyle colors here, and flatten this object\r\nconst colors = {\r\n pad : new Color({rgb:'FFFFFF',alpha:0.7}),\r\n curve : Color_fromRgb('8888FF'),\r\n knot : Color_fromRgb('4444FF'),\r\n knot_selected : Color_fromRgb('000000'),\r\n knot_over : Color_fromRgb('44AA88'),\r\n controlSegment : Color_fromRgb('4444FF'),\r\n curveControlSegment: Color_fromRgb('9944CC'),\r\n cuspControlSegment : Color_fromRgb('AA4433'),\r\n nextControlSegment : Color_fromRgb('666666'),\r\n control : Color_fromRgb('0000FF'),\r\n control_over : Color_fromRgb('44AA88'),\r\n addKnot : Color_fromRgb('000000'),\r\n addKnot_over : Color_fromRgb('44AA88'),\r\n removeKnot : Color_fromRgb('FF0000'),\r\n removeKnot_over : Color_fromRgb('44AA88'),\r\n dragSelector : Color_fromRgb('009900'),\r\n curvePadBack : Color_fromRgb('E8E8FF')\r\n};\r\n\r\nfunction drawDot( context, style, size, point, transform, textureScale ) {\r\n context.fillStyle = colors.pad.rgba;\r\n dot(context,point,(size+1.4)*textureScale,transform);\r\n context.fillStyle = style;\r\n dot(context,point,size*textureScale,transform);\r\n}\r\n\r\nfunction drawSegment( context, style, p0, p1, transform, textureScale ) {\r\n context.lineWidth = 3.5 * textureScale;\r\n context.strokeStyle = colors.pad.rgba;\r\n strokeSegment(context,p0,p1,transform);\r\n context.lineWidth = 1.5 * textureScale;\r\n context.strokeStyle = style;\r\n strokeSegment(context,p0,p1,transform);\r\n}\r\n\r\n// States\r\n// Iddle: nothing is selected, waiting for user input\r\n// DragSelection: user is selecting multiple knots with a rectangle\r\n// EditingKnot: one knot is selected, user can move it and move the control points\r\n// SelectedKnots:\r\n// MovingControlPoint: control point is being moved\r\n// MovingKnots: multiple knots are selected\r\n\r\nfunction nextKi( side, curve, ki ) {\r\n const length = curve.pieces.length, closed = curve.closed;\r\n if( side === 'left' ) {\r\n if( !closed && ki === 0 ) {\r\n return null;\r\n }\r\n return ( ki === 0 && closed ) ? length-1 : ki-1;\r\n }\r\n else { // right\r\n\r\n if( !closed && ki === length ) {\r\n return null;\r\n }\r\n return (ki === length-1 && closed ) ? 0 : ki+1;\r\n }\r\n}\r\n\r\nfunction knotPoint( curve, ki ) {\r\n const pieces = curve.pieces;\r\n if( ki === null ) {\r\n return null;\r\n }\r\n if( ki >= pieces.length ) {\r\n return last(pieces).last();\r\n }\r\n return pieces[ki].P0;\r\n}\r\n\r\nfunction nextKnotPoint( side, curve, ki ) {\r\n return knotPoint(curve,nextKi(side,curve,ki));\r\n}\r\n\r\nfunction pieceIndexAt( side, curve, ki ) {\r\n if( side === 'left' ) {\r\n return nextKi(side,curve,ki);\r\n }\r\n else {\r\n return ! curve.closed && ki === curve.pieces.length ? null : ki;\r\n }\r\n}\r\n\r\nfunction pieceAt( side, curve, ki ) {\r\n const pi = pieceIndexAt(side,curve,ki);\r\n return pi !== null ? curve.pieces[pi] : null;\r\n}\r\n\r\nfunction controlPoint( side, curve, ki ) {\r\n const { pieces } = curve;\r\n let piece;\r\n if( ki === null ) {\r\n return null;\r\n }\r\n if( side === 'left' ) {\r\n piece = null;\r\n if( ki === 0 && curve.closed) {\r\n piece = last(pieces);\r\n }\r\n else {\r\n piece = pieces[ki-1];\r\n }\r\n if( piece && piece.type === 'Cubic' ) {\r\n return piece.P2;\r\n }\r\n return null;\r\n }\r\n else { // 'right'\r\n if( ki >= pieces.length ) {\r\n return null;\r\n }\r\n piece = pieces[ki];\r\n if( piece && piece.type === 'Cubic' ) {\r\n return piece.P1;\r\n }\r\n return null;\r\n }\r\n}\r\n\r\nfunction nextControlPoint( side, curve, ki ) {\r\n return controlPoint(oppSide(side),curve,nextKi(side,curve,ki));\r\n}\r\n\r\nfunction removeKnot( curve, ki, tool ) {\r\n\r\n // Check if it is the last knot\r\n if( curve.pieces.length === 1 ) {\r\n // [TODO] Curves should be included in the type system, remove lazy loading, is not gaining us much\r\n const region = curve._owner;\r\n const curves = region._curves;\r\n curves.splice( curves.indexOf(curve), 1 );\r\n\r\n if( curves.length === 0 ) {\r\n const polyregion = region._owner;\r\n const regions = polyregion._regions;\r\n\r\n regions._remove(region);\r\n if( regions.length === 0 ) {\r\n const figure = polyregion._owner;\r\n figure._polyregions._remove( polyregion );\r\n }\r\n }\r\n const toolCurves = tool._curves;\r\n toolCurves.splice( toolCurves.indexOf(curve), 1 );\r\n return;\r\n }\r\n\r\n const pieces = curve.pieces;\r\n if( ki === pieces.length ) { // open curve\r\n pieces.pop();\r\n return;\r\n }\r\n\r\n const kiLeft = nextKi('left' ,curve,ki);\r\n if( kiLeft === null ) { // open curve\r\n pieces.shift();\r\n return;\r\n }\r\n\r\n const pieceLeft = pieces[kiLeft];\r\n const piece = pieces[ki];\r\n\r\n pieceLeft.last(piece.last());\r\n if( pieceLeft.P3 ) {\r\n if( piece.P3 ) { // Both are cubic, try to avoid big modifications in the curve\r\n pieceLeft.P1 = Point_sm(pieceLeft.P1,2).substract(pieceLeft.P0);\r\n pieceLeft.P2 = Point_sm(piece.P2 ,2).substract(piece.P3);\r\n }\r\n else {\r\n pieces[kiLeft] = new Segment(pieceLeft.P0,piece.last());\r\n }\r\n }\r\n pieces.splice(ki,1);\r\n curve.tieExtremePoints();\r\n}\r\n\r\nfunction oppSide( side ) {\r\n return side === 'left' ? 'right' : 'left';\r\n}\r\n\r\nconst Knot = function( curve, ki ) {\r\n this.curve = curve;\r\n this.ki = ki;\r\n};\r\nKnot.prototype = {\r\n isEqual( ok ) {\r\n return ok && this.curve === ok.curve && this.ki === ok.ki;\r\n },\r\n point() {\r\n return knotPoint(this.curve,this.ki);\r\n },\r\n nextKi( side ) {\r\n return nextKi(side,this.curve,this.ki);\r\n },\r\n nextPoint( side ) {\r\n return nextKnotPoint(side,this.curve,this.ki);\r\n },\r\n pieceAt( side ) {\r\n return pieceAt(side,this.curve,this.ki);\r\n },\r\n pieceIndexAt( side ) {\r\n return pieceIndexAt(side,this.curve,this.ki);\r\n },\r\n pointAt( side,t) {\r\n return this.pieceAt(side).eval(t);\r\n },\r\n controlPoint( side ) {\r\n return controlPoint(side,this.curve,this.ki);\r\n },\r\n nextControlPoint( side ) {\r\n return nextControlPoint(side,this.curve,this.ki);\r\n },\r\n nextKnot( side ) {\r\n const nki = nextKi(side,this.curve,this.ki);\r\n if( nki === null ) {\r\n return null;\r\n }\r\n return new Knot(this.curve,nki);\r\n },\r\n tangentAt( side ) {\r\n const to = this.controlPoint(side) || this.nextPoint(side);\r\n if( ! to ) {\r\n return null;\r\n }\r\n const from = this.point();\r\n const tangent = Point_substract(from,to);\r\n if( tangent.isZero() ) {\r\n return null;\r\n }\r\n return tangent.normalized();\r\n },\r\n normal() {\r\n let leftTangent = this.tangentAt(\"left\");\r\n let rightTangent = this.tangentAt(\"right\");\r\n if( ! leftTangent && ! rightTangent ) {\r\n leftTangent = new Point( 1.0,0.0);\r\n rightTangent = new Point(-1.0,0.0);\r\n }\r\n else if( ! leftTangent ) {\r\n leftTangent = Point.minus(rightTangent);\r\n }\r\n else if( ! rightTangent ) {\r\n rightTangent = Point.minus( leftTangent);\r\n }\r\n\r\n const normal = new Point( leftTangent.y - rightTangent.y, -leftTangent.x + rightTangent.x);\r\n\r\n return normal.isZero() ? leftTangent : normal.normalize();\r\n },\r\n locked() {\r\n return this.point().__cadx_locked === true;\r\n },\r\n // You can not use the knot after calling this function\r\n remove( tool) {\r\n removeKnot(this.curve,this.ki,tool);\r\n },\r\n addKnot( side ) {\r\n const curve = this.curve;\r\n const pi = this.pieceIndexAt(side);\r\n // [TODO] Move locked annotations out of points\r\n const locked = curve.pieces[pi].P0.__cadx_locked;\r\n this.curve.splitPiece(pi,0.5);\r\n if( locked ) {\r\n curve.pieces[pi].P0.__cadx_locked = true;\r\n }\r\n return new Knot(this.curve, side==='left' ? this.ki : this.ki+1 );\r\n },\r\n _computeCorner() {\r\n const left = this.controlPoint('left');\r\n const right = this.controlPoint('right');\r\n if( left && right ) {\r\n const point = this.point();\r\n if( point.isNear(left,0.01) || point.isNear(right,0.01) ) {\r\n return 'cusp';\r\n }\r\n const lp = Point_substract(point,left);\r\n const rp = Point_substract(right,point);\r\n if( lp.isNear(rp,0.01) ) {\r\n return 'symmetric';\r\n }\r\n if( Math.abs( (lp.x*rp.y) - (lp.y*rp.x) ) < 0.01 ) {\r\n return 'curve';\r\n }\r\n return 'cusp';\r\n }\r\n return 'cusp';\r\n },\r\n corner() {\r\n if( !this._corner ) {\r\n this._corner = this._computeCorner();\r\n }\r\n return this._corner;\r\n },\r\n changeCorner( side ) {\r\n const _side = this.controlPoint(side);\r\n const _opp = this.controlPoint(oppSide(side));\r\n const point = this.point();\r\n const corner = this.corner();\r\n const newCorner = corner === 'cusp' ? 'curve'\r\n : corner === 'curve' ? 'symmetric'\r\n : 'cusp';\r\n if( ! ( _side && _opp ) ) {\r\n return;\r\n }\r\n let sh = Point_substract(point,_side);\r\n if( newCorner === 'symmetric' ) {\r\n _opp.set( Point_add(point,sh) );\r\n }\r\n else if( newCorner === 'curve' ) {\r\n if( corner === 'cusp' ) {\r\n const oh = Point_substract(_opp,point);\r\n sh = Point_sm(sh.normalized(),oh.norm());\r\n _opp.set( Point_add(point,sh) );\r\n }\r\n else { // Symmetric\r\n sh = Point_add(sh,Point_sm(sh.normalized(),0.1));\r\n _opp.set( Point_add(point,sh) );\r\n }\r\n }\r\n else if( newCorner === 'cusp' ) {\r\n const p = sh.perpendicular(-1);\r\n sh = Point_add(Point_substract(_opp,point),Point_sm(p.normalized(),0.1));\r\n _opp.set( Point_add(point,sh) );\r\n }\r\n this._corner = newCorner;\r\n },\r\n convertToCurve( side ) {\r\n const pieces = this.curve.pieces;\r\n const kp = side === 'left' ? nextKi(side,this.curve,this.ki) : this.ki;\r\n const p = pieces[kp];\r\n pieces.splice(kp,1,Cubic.fromSegment(p.P0,p.P1));\r\n this.curve.tieExtremePoints();\r\n this._corner = null;\r\n },\r\n convertToSegment( side ) {\r\n const pieces = this.curve.pieces;\r\n const kp = side === 'left' ? nextKi(side,this.curve,this.ki) : this.ki;\r\n const p = pieces[kp];\r\n pieces.splice(kp,1,new Segment(p.P0,p.last()));\r\n this.curve.tieExtremePoints();\r\n this._corner = null;\r\n }\r\n};\r\n\r\nfunction forEachKnot( curve, func ) {\r\n const pieces = curve.pieces;\r\n for(let n = 0, nEnd = pieces.length; n < nEnd; ++n ) {\r\n if( func(new Knot(curve,n)) === false ) {\r\n return curve;\r\n }\r\n }\r\n if( ! curve.closed ) {\r\n if( func(new Knot(curve,curve.pieces.length)) === false ) {\r\n return curve;\r\n }\r\n }\r\n return curve;\r\n}\r\n\r\nfunction findKnot( curve, func ) {\r\n const pieces = curve.pieces;\r\n let k;\r\n for(let n = 0, nEnd = pieces.length; n < nEnd; ++n ) {\r\n k = new Knot(curve,n);\r\n if( func(k) === true ) {\r\n return k;\r\n }\r\n }\r\n if( ! curve.closed ) {\r\n k = new Knot(curve,pieces.length);\r\n if( func(k) === true ) {\r\n return k;\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nconst BaseState = Base.extend({\r\n init( tool ) {\r\n this._tool = tool;\r\n this._padSize = 0.1 * 96;\r\n this._cursor = null;\r\n this.showToolhelp();\r\n },\r\n showToolhelp() {\r\n this._tool.toolhelp(this.toolhelp().concat(this.baseToolhelp()));\r\n },\r\n toolhelp() {\r\n return [];\r\n },\r\n baseToolhelp() {\r\n return ['Click or Draw rectangle to select knots',\r\n 'Enter to Commit, Escape to Cancel'];\r\n },\r\n undoState() {\r\n this._tool.undoState();\r\n },\r\n state( s, k, a, b, c ) {\r\n this._tool.state(s,k,a,b,c);\r\n },\r\n\r\n curveToDoc( point ) {\r\n return this.matrix.apply(point);\r\n },\r\n\r\n viewToCurve_dx( d ) {\r\n return this.matrixInverted.scaleFactor() * this.view.viewDeltaToDoc(d);\r\n },\r\n\r\n curvePoint({ docPoint }) {\r\n return this.matrixInverted.apply( docPoint );\r\n },\r\n\r\n get textureScale() {\r\n return this.view.viewDeltaToTexture(1);\r\n },\r\n\r\n get view() {\r\n return this._tool.view;\r\n },\r\n get matrix() {\r\n return this._tool._matrix;\r\n },\r\n get matrixInverted() {\r\n return this._tool._matrixInverted;\r\n },\r\n\r\n focus() {\r\n this.showToolhelp();\r\n this._possibleClick = null;\r\n },\r\n\r\n get cursor() {\r\n return this._tool.cursor;\r\n },\r\n set cursor( cursor_ ) {\r\n this._tool.cursor = cursor_;\r\n },\r\n\r\n redraw() {\r\n this._tool.redraw();\r\n },\r\n onUpdate() {\r\n this._tool.onUpdate();\r\n },\r\n\r\n draw( context, transform ) {\r\n this.drawCurve(context,transform);\r\n this.drawKnots(context,transform);\r\n },\r\n\r\n drawCurve( context, transform ) {\r\n const { textureScale } = this;\r\n context.lineWidth = 3.5 * textureScale;\r\n context.strokeStyle = colors.pad.rgba;\r\n this._strokeCurve(context,transform);\r\n context.lineWidth = 1.5 * textureScale;\r\n context.strokeStyle = colors.curve.rgba;\r\n this._strokeCurve(context,transform);\r\n },\r\n\r\n _strokeCurve( context, transform ) {\r\n forEach( this._tool._curves, curve => {\r\n context.beginPath();\r\n curve.draw(context,transform);\r\n context.stroke();\r\n });\r\n },\r\n\r\n drawKnots( context, transform ) {\r\n const tool = this._tool;\r\n const over_knot = this._over_knot;\r\n const { textureScale } = this;\r\n forEach( tool._curves, curve => {\r\n forEachKnot( curve, knot => {\r\n const ok = knot.isEqual(over_knot);\r\n drawDot(context, ok ? colors.knot_over.rgba : colors.knot.rgba, ok ? knotSelectedSize : knotSize,\r\n knot.point(),transform,textureScale);\r\n });\r\n });\r\n const fillStyle = this._over_selectedKnots ? colors.knot_over.rgba : colors.knot_selected.rgba;\r\n forEach( this.selectedKnots(), knot => {\r\n drawDot(context,fillStyle,knotSelectedSize,\r\n knot.point(),transform,textureScale);\r\n });\r\n },\r\n\r\n overKnot( event ) {\r\n const padSize = this.viewToCurve_dx(this._padSize*padScaling),\r\n point = this.curvePoint(event);\r\n let overKnot = null;\r\n find( this._tool._curves, curve => {\r\n overKnot = findKnot( curve, knot => point.isNear(knot.point(),padSize) );\r\n if( overKnot ) {\r\n return true;\r\n }\r\n });\r\n return overKnot;\r\n },\r\n\r\n overSelectedKnots( event ) {\r\n const padSize = this.viewToCurve_dx(this._padSize*padScaling),\r\n point = this.curvePoint(event);\r\n\r\n return find( this.selectedKnots(), knot => point.isNear(knot.point(),padSize) );\r\n },\r\n\r\n selectedKnot() {\r\n return this._tool._selectedKnots[0];\r\n },\r\n\r\n selectedKnots() {\r\n return this._tool._selectedKnots;\r\n },\r\n\r\n down({ event, docPoint, shiftKey }) {\r\n const selectedKnots = this.selectedKnots();\r\n const knot = this.overKnot(event);\r\n if( knot ) {\r\n if( shiftKey && selectedKnots ) {\r\n return this.state('SelectedKnots',selectedKnots.concat(knot));\r\n }\r\n else {\r\n this._possibleClick = { docPoint, knot };\r\n return true;\r\n }\r\n }\r\n this.state('DragSelection',selectedKnots,docPoint);\r\n return false;\r\n },\r\n\r\n move({ event, docPoint }) {\r\n if( this._possibleClick && ! docPoint.isEqual( this._possibleClick.docPoint ) ) {\r\n this.state('EditingKnot',this._possibleClick.knot);\r\n this.state('MovingKnots',this._possibleClick.knot,this.curvePoint(event));\r\n this._possibleClick = null;\r\n this.redraw();\r\n }\r\n },\r\n\r\n mousemove( event ) {\r\n this._over_knot = this.overKnot(event);\r\n this._over_selectedKnots = this.overSelectedKnots(event);\r\n if( this._changeCursorTo ) {\r\n this.cursor = this._changeCursorTo;\r\n this._changeCursorTo = null;\r\n }\r\n else if( this._over_knot || this._over_selectedKnots ) {\r\n this.cursor = 'pointer';\r\n }\r\n else{\r\n this.cursor = 'default';\r\n }\r\n this.redraw(); // [TODO] Avoid redrawing when it is not needed\r\n },\r\n\r\n up( /*view,event*/) {\r\n if( this._possibleClick ) {\r\n this.state('EditingKnot',this._possibleClick.knot);\r\n this._possibleClick = null;\r\n }\r\n },\r\n\r\n on_dblclick( /*view,event*/) {\r\n // ...\r\n },\r\n\r\n deleteAction() {\r\n // nothing...\r\n }\r\n});\r\n\r\nconst HandleBase = Base.extend({\r\n init( state, side ) {\r\n this._state = state;\r\n this._knot = state._knot;\r\n this._side = side;\r\n this._over = false;\r\n this._point = this.point();\r\n this._padSize = 0.1 * 96;\r\n },\r\n\r\n over( event ) {\r\n const state = this._state;\r\n const p = this._point;\r\n return ( p && state.curvePoint(event).isNear( p, state.viewToCurve_dx(this._padSize*padScaling) ) );\r\n },\r\n\r\n down( event ) {\r\n if( ! this._point ) {\r\n return;\r\n }\r\n\r\n if( this.over(event) ) {\r\n this.click(event);\r\n return true;\r\n }\r\n return false;\r\n },\r\n\r\n move( /* event */ ) {\r\n\r\n },\r\n\r\n mousemove( event ) {\r\n if( ! this._point ) {\r\n return;\r\n }\r\n this._over = this.over(event);\r\n if( this._over ) {\r\n this._state._changeCursorTo = 'pointer';\r\n }\r\n },\r\n\r\n on_dblclick( event ) {\r\n if( ! this._point ) {\r\n return;\r\n }\r\n if( this.over(event) ) {\r\n this.dblClick(event);\r\n return true;\r\n }\r\n return false;\r\n },\r\n\r\n click( /*view,event*/) {},\r\n dblClick( /*view,event*/) {},\r\n\r\n drawCurvePadBack( context, transform ) {\r\n const { textureScale } = this;\r\n context.strokeStyle = colors.curve.rgba;\r\n context.lineWidth = 1;\r\n strokeDot(context,this._point,5*textureScale,transform);\r\n context.fillStyle = colors.curvePadBack.rgba;\r\n dot(context,this._point,4.5*textureScale,transform);\r\n },\r\n\r\n state( a,b,c,d,e) {\r\n this._state.state(a,b,c,d,e);\r\n },\r\n\r\n curvePoint( event ) {\r\n return this._state.curvePoint(event);\r\n },\r\n\r\n viewToCurve_dx( d ) {\r\n return this._state.viewToCurve_dx(d);\r\n },\r\n\r\n onUpdate() {\r\n this._state.onUpdate();\r\n },\r\n\r\n get textureScale() {\r\n return this._state.textureScale;\r\n }\r\n});\r\n\r\n\r\nconst Handle = {\r\n\r\n 'Control': HandleBase.extend({\r\n//==========================================================================\r\n\r\n point() {\r\n return this._knot.controlPoint(this._side);\r\n },\r\n\r\n draw( context, transform ) {\r\n if( ! this._point ) {\r\n return;\r\n }\r\n\r\n // [TODO]\r\n\r\n const corner = this._knot.corner();\r\n const strokeStyle = this._side === 'right' ? colors.controlSegment.rgba\r\n : corner === 'cusp' ? colors.cuspControlSegment.rgba\r\n : corner === 'curve' ? colors.curveControlSegment.rgba\r\n : colors.controlSegment.rgba;\r\n\r\n const { textureScale } = this;\r\n\r\n drawSegment(context,strokeStyle,this._knot.point(),this._point,transform,textureScale);\r\n\r\n drawDot(context, this._over ? colors.control_over.rgba : colors.control.rgba, 2,\r\n this._point,transform,textureScale);\r\n },\r\n\r\n click( event ) {\r\n return this.state('MovingControl',this._knot,this._side,this.curvePoint(event));\r\n },\r\n\r\n dblClick( /*view,event*/) {\r\n this._knot.changeCorner(this._side);\r\n this.onUpdate();\r\n this._state.focus();\r\n }\r\n }),\r\n\r\n 'NextControl': HandleBase.extend({\r\n//==========================================================================\r\n point() {\r\n return this._knot.nextControlPoint(this._side);\r\n },\r\n draw( context, transform ) {\r\n\r\n if( ! this._point ) {\r\n return;\r\n }\r\n\r\n const { textureScale } = this;\r\n\r\n drawSegment(context,colors.nextControlSegment.rgba,\r\n this._knot.nextKnot(this._side).point(),this._point,transform,textureScale);\r\n\r\n drawDot(context,this._over ? colors.control_over.rgba : colors.control.rgba, 2,\r\n this._point,transform,textureScale);\r\n },\r\n click( event ) {\r\n const nextKnot = this._knot.nextKnot(this._side);\r\n this.state('EditingKnot',nextKnot);\r\n this.state('MovingControl',nextKnot,oppSide(this._side),this.curvePoint(event));\r\n }\r\n }),\r\n\r\n 'AddKnot': HandleBase.extend({\r\n//==========================================================================\r\n point() {\r\n // Use the middle of the curve\r\n const p = this._knot.pieceAt(this._side);\r\n return p ? p.eval(0.5) : null;\r\n },\r\n\r\n draw( context, transform ) {\r\n if( ! this._point ) {\r\n return;\r\n }\r\n this.drawCurvePadBack(context,transform);\r\n const { textureScale } = this;\r\n if( this._over ) {\r\n context.fillStyle = colors.addKnot_over.rgba;\r\n dot(context,this._point,textureScale*knotSelectedSize,transform);\r\n }\r\n else {\r\n context.strokeStyle = colors.addKnot.rgba;\r\n context.lineWidth = textureScale*0.5;\r\n strokeDot(context,this._point,textureScale*2,transform);\r\n }\r\n },\r\n\r\n click( event ) {\r\n const newKnot = this._knot.addKnot(this._side);\r\n this.state('EditingKnot',newKnot);\r\n this.state('MovingKnots',newKnot,this.curvePoint(event));\r\n }\r\n }),\r\n\r\n 'RemoveKnot': HandleBase.extend({\r\n//==========================================================================\r\n\r\n point() {\r\n const k = this._knot;\r\n return Point_add(k.point(),Point_sm(k.normal(),this.viewToCurve_dx(30)));\r\n },\r\n\r\n draw( context, transform ) {\r\n if( ! this.point ) {\r\n return;\r\n }\r\n const { textureScale } = this;\r\n // [TODO]\r\n const lineWidth = ( this._over ? 2 : 1 ) * textureScale;\r\n const rs = ( this._over ? 4 : 2 ) * textureScale;\r\n const point = this._point;\r\n\r\n context.lineWidth = lineWidth + 2 * textureScale;\r\n context.strokeStyle = colors.pad.rgba;\r\n strokeCross(context,point, rs + 1 * textureScale, transform);\r\n\r\n context.lineWidth = lineWidth;\r\n context.strokeStyle = colors.removeKnot.rgba;\r\n strokeCross(context,point,rs,transform);\r\n if( this._over ) {\r\n context.lineWidth = lineWidth + 2 * textureScale;\r\n context.strokeStyle = colors.pad.rgba;\r\n strokeDot(context,this._knot.point(), (knotSelectedSize + 3) * textureScale,transform);\r\n\r\n context.strokeStyle = colors.removeKnot.rgba;\r\n context.lineWidth = lineWidth;\r\n strokeDot(context,this._knot.point(), (knotSelectedSize + 3) * textureScale,transform);\r\n }\r\n },\r\n click( /*view,event*/) {\r\n this._knot.remove(this._state._tool);\r\n this.state('Iddle');\r\n this.onUpdate();\r\n }\r\n }),\r\n\r\n 'ConvertToCurve': HandleBase.extend({\r\n//==========================================================================\r\n point() {\r\n const p = this._knot.pieceAt(this._side);\r\n if( ! ( p instanceof Segment ) ) {\r\n return null;\r\n }\r\n return p.eval( this._side === 'left' ? 2/3.0 : 1/3.0 );\r\n },\r\n\r\n draw( context, transform ) {\r\n if( ! this._point ) {\r\n return;\r\n }\r\n this.drawCurvePadBack(context,transform);\r\n\r\n const { textureScale } = this;\r\n\r\n drawSegment(context,colors.controlSegment.rgba,\r\n this._knot.point(),this._point,transform,textureScale);\r\n\r\n context.fillStyle = colors.control.rgba;\r\n dot(context,this._point, 2 * textureScale ,transform);\r\n },\r\n\r\n click( event ) {\r\n this._knot.convertToCurve(this._side);\r\n this.state('MovingControl',this._knot,this._side,this.curvePoint(event));\r\n this.onUpdate();\r\n }\r\n }),\r\n\r\n 'ConvertToSegment': HandleBase.extend({\r\n//==========================================================================\r\n point() {\r\n const p = this._knot.pieceAt(this._side);\r\n if( !p || p instanceof Segment ) {\r\n return null;\r\n }\r\n return p.eval( this._side === 'left' ? 2/3.0 : 1/3.0 );\r\n },\r\n\r\n draw( context, transform ) {\r\n if( ! this._point ) {\r\n return;\r\n }\r\n\r\n const { textureScale } = this;\r\n\r\n if( this._over ) {\r\n const piece = this._knot.pieceAt(this._side);\r\n context.lineWidth = 4 * textureScale;\r\n context.strokeStyle = colors.pad.rgba;\r\n context.beginPath();\r\n piece.draw(context,transform);\r\n context.stroke();\r\n\r\n context.lineWidth = 2 * textureScale;\r\n context.strokeStyle = colors.removeKnot.rgba;\r\n context.beginPath();\r\n piece.draw(context,transform);\r\n context.stroke();\r\n\r\n context.lineWidth = 1 * textureScale;\r\n drawSegment(context,colors.curve.rgba,\r\n this._knot.point(),this._knot.nextKnot(this._side).point(),transform,textureScale);\r\n }\r\n\r\n this.drawCurvePadBack(context,transform);\r\n\r\n context.strokeStyle = colors.removeKnot.rgba;\r\n context.lineWidth = 1 * textureScale;\r\n const rs = 2 * textureScale;\r\n strokeCross(context,this._point,rs,transform);\r\n },\r\n\r\n click( /*view,event*/) {\r\n this._knot.convertToSegment(this._side);\r\n this._state.focus();\r\n }\r\n })\r\n};\r\n\r\nconst State = {\r\n\r\n 'Iddle': BaseState.extend({\r\n// =========================================================\r\n }),\r\n\r\n 'EditingKnot': BaseState.extend({\r\n// =========================================================\r\n init( tool) {\r\n this.callParent(tool);\r\n this.focus();\r\n },\r\n toolhelp() {\r\n return [\r\n 'Drag knots and control handles to modify curve',\r\n 'Double Click control handle to change curve type'\r\n ];\r\n },\r\n focus() {\r\n this.showToolhelp();\r\n\r\n const knot = this._knot = this.selectedKnot();\r\n\r\n this._handles = [];\r\n\r\n const moreHandles = [\r\n new Handle.AddKnot(this,'left'),\r\n new Handle.AddKnot(this,'right'),\r\n new Handle.ConvertToCurve(this,'left'),\r\n new Handle.ConvertToCurve(this,'right'),\r\n new Handle.ConvertToSegment(this,'left'),\r\n new Handle.ConvertToSegment(this,'right')\r\n ];\r\n\r\n // Only add handles if the buttons aren't that close to the knot\r\n const knotPoint = knot.point();\r\n const delta = this.view.viewDeltaToDoc(15);\r\n forEach( moreHandles, h => {\r\n const point = h.point();\r\n if( point && ! point.isNear( knotPoint, delta ) ) {\r\n this._handles.push(h);\r\n }\r\n });\r\n\r\n // Order is important, first move control points, then knots...\r\n this._handles = this._handles.concat([\r\n new Handle.Control(this,'left'),\r\n new Handle.Control(this,'right'),\r\n new Handle.NextControl(this,'left'),\r\n new Handle.NextControl(this,'right'),\r\n ]);\r\n\r\n // Do not let the user remove locked knots\r\n if( ! this._knot.locked() ) {\r\n this._handles.push( new Handle.RemoveKnot(this) );\r\n }\r\n },\r\n\r\n draw( context, transform ) {\r\n this.drawCurve(context,transform);\r\n forEach( this._handles, h => {\r\n h.draw(context,transform);\r\n });\r\n this.drawKnots(context,transform);\r\n },\r\n\r\n down( event ) {\r\n if( find( this._handles, h => h.down(event) ) ) {\r\n return true;\r\n }\r\n return this.callParent(event);\r\n },\r\n\r\n mousemove( event ) {\r\n forEach( this._handles, h => { h.mousemove(event); });\r\n this.redraw();\r\n this.callParent(event);\r\n },\r\n\r\n move( event ) {\r\n forEach( this._handles, h => { h.move(event); });\r\n this.redraw();\r\n this.callParent(event);\r\n },\r\n\r\n on_dblclick( event ) {\r\n find( this._handles, h => h.on_dblclick(event) );\r\n },\r\n\r\n deleteAction() {\r\n const knot = this._knot;\r\n if( ! knot.locked() ) {\r\n knot.remove(this._tool);\r\n this.state('Iddle');\r\n this.onUpdate();\r\n }\r\n }\r\n\r\n }),\r\n\r\n 'DragSelection': BaseState.extend({\r\n// =========================================================\r\n init( tool,fromPoint) {\r\n this.callParent(tool);\r\n this._fromPoint = fromPoint;\r\n this._toPoint = fromPoint;\r\n },\r\n\r\n draw( context, transform ) {\r\n this.callParent(context,transform);\r\n context.strokeStyle = colors.dragSelector.rgba;\r\n const fixedTransform = Matrix.m( transform, this.matrixInverted );\r\n\r\n const frame = Frame.ofPoints([ this._fromPoint, this._toPoint ]);\r\n frame.draw(context,fixedTransform);\r\n context.lineWidth = this.textureScale * 1;\r\n context.stroke();\r\n },\r\n\r\n down() {\r\n this.state('Iddle');\r\n return false;\r\n },\r\n\r\n move({ event, docPoint }) {\r\n this._toPoint = docPoint;\r\n this.redraw();\r\n },\r\n\r\n up({ event, shiftKey }) {\r\n const tool = this._tool;\r\n let knots = [];\r\n const db = Bounds.ofPoints([this._fromPoint,this._toPoint]);\r\n forEach( tool._curves, curve => {\r\n forEachKnot( curve, knot => {\r\n if( db.contains( this.curveToDoc(knot.point()) ) ) {\r\n knots.push(knot);\r\n }\r\n });\r\n });\r\n if( shiftKey ) {\r\n knots = this.selectedKnots().concat(knots);\r\n }\r\n if( knots.length === 1 ) {\r\n this.state('EditingKnot',knots[0]);\r\n }\r\n else if( knots.length > 0 ) {\r\n this.state('SelectedKnots',knots);\r\n }\r\n else {\r\n this.state('Iddle');\r\n }\r\n }\r\n }),\r\n\r\n 'SelectedKnots': BaseState.extend({\r\n// =========================================================\r\n init( tool) {\r\n this.callParent(tool);\r\n },\r\n toolhelp() {\r\n return ['Drag knots to modify curve'];\r\n },\r\n\r\n focus() {\r\n this.showToolhelp();\r\n const c = this._possibleClick;\r\n if( c && now()-c.time<500 ) {\r\n this.state('EditingKnot',c.knot);\r\n }\r\n else {\r\n this._possibleClick = null;\r\n }\r\n },\r\n\r\n down({ event, shiftKey }) {\r\n const knot = this.overSelectedKnots(event);\r\n if( knot ) {\r\n if( ! shiftKey ) {\r\n this._possibleClick = { knot: knot, time: now() };\r\n }\r\n this.state('MovingKnots',this.selectedKnots(),this.curvePoint(event));\r\n return true;\r\n }\r\n return this.callParent(event);\r\n },\r\n\r\n move( event ) {\r\n this.callParent(event);\r\n },\r\n\r\n deleteAction() {\r\n const tool = this._tool;\r\n const knots = this.selectedKnots();\r\n for(let k = 0, kEnd = knots.length; k < kEnd; k++ ) {\r\n const knot = knots[k];\r\n if( ! knot.locked() ) {\r\n\r\n const ki = knot.ki;\r\n knot.remove(tool);\r\n\r\n // Correct indexes, to be able to continue removing other knots\r\n // This ended up quite complex because of using a direct view of\r\n // the curve representation [curve,ki]\r\n for(let i = k+1, iEnd = knots.length; i < iEnd; i++ ) {\r\n const knot_i = knots[i];\r\n if( knot_i.ki > ki ) {\r\n knot_i.ki--;\r\n }\r\n }\r\n }\r\n }\r\n this.state('Iddle');\r\n this.onUpdate();\r\n }\r\n }),\r\n\r\n 'MovingKnots': BaseState.extend({\r\n// =========================================================\r\n init( tool, fromPoint ) {\r\n this.callParent(tool);\r\n this._fromPoint = fromPoint;\r\n this._points = map( this.selectedKnots(), knot => {\r\n const point = knot.point();\r\n const left = knot.controlPoint('left');\r\n const right = knot.controlPoint('right');\r\n const r = { point: point, original: point.clone() };\r\n if( left ) {\r\n r.left = left;\r\n r.originalLeft = left.clone();\r\n }\r\n if( right ) {\r\n r.right = right;\r\n r.originalRight = right.clone();\r\n }\r\n return r;\r\n });\r\n\r\n //filter duplicated selected points\r\n let lFilteredPoints = [];\r\n this._points.forEach(p1 => {\r\n if (!find( lFilteredPoints, p2 => p1.point == p2.point ))\r\n lFilteredPoints.push(p1);\r\n });\r\n this._points = lFilteredPoints;\r\n },\r\n\r\n down() {\r\n this.state('Iddle');\r\n return false;\r\n },\r\n\r\n cacheOppositeKnot ( aKnotId )\r\n {\r\n const lOppositeKnot = new Knot(this._tool._curves[0],aKnotId);\r\n if (this._oppositeKnotId != aKnotId)\r\n {\r\n if (this._oppositeKnotId != undefined)\r\n {\r\n this._oppositeKnot.point.set(this._oppositeKnot.original);\r\n this._oppositeKnot.left.set( this._oppositeKnot.originalLeft);\r\n this._oppositeKnot.right.set( this._oppositeKnot.originalRight);\r\n }\r\n\r\n this._oppositeKnotId = aKnotId;\r\n let lOppositePoint = lOppositeKnot.point();\r\n let lOppositeLeft = lOppositeKnot.controlPoint('left');\r\n let lOppositeRight = lOppositeKnot.controlPoint('right');\r\n this._oppositeKnot = { point: lOppositePoint, original: lOppositePoint.clone() };\r\n if( lOppositeLeft ) {\r\n this._oppositeKnot.left = lOppositeLeft;\r\n this._oppositeKnot.originalLeft = lOppositeLeft.clone();\r\n }\r\n if( lOppositeRight ) {\r\n this._oppositeKnot.right = lOppositeRight;\r\n this._oppositeKnot.originalRight = lOppositeRight.clone();\r\n }\r\n }\r\n return this._oppositeKnot;\r\n },\r\n move( event ) {\r\n const fromPoint = this._fromPoint;\r\n const toPoint = this.curvePoint(event);\r\n let diff = Point_substract(toPoint,fromPoint);\r\n let diffOpposite;\r\n //This special shortcut works only if the figure is an envelope with no removed or added knots\r\n //So just 1 curve, with 8 knots\r\n //Also the user need to have only 1 point selected\r\n if ( (event.ctrlKey || event.shiftKey) \r\n && this._points.length == 1\r\n && this._tool._curves.length == 1\r\n && this._tool._curves[0].pieces.length == 8)\r\n {\r\n let lIdx = this.selectedKnots()[0].ki;\r\n const p = this._points[0];\r\n let lOppositeKnot;\r\n //lIdx is the envelope knot index:\r\n // 6 5 4\r\n // 7 3\r\n // 0 1 2\r\n\r\n let lOpposite = 0;\r\n if ( lIdx == 3 //3 and 7 move only right-left\r\n || lIdx == 7 \r\n || (Math.abs(diff.x)>Math.abs(diff.y) && lIdx != 1 && lIdx != 5))//1 and 5 cant be moved right-left\r\n {\r\n switch (lIdx)\r\n {\r\n case 0: lOpposite = 2; break;\r\n case 2: lOpposite = 0; break;\r\n case 3: lOpposite = 7; break;\r\n case 4: lOpposite = 6; break;\r\n case 6: lOpposite = 4; break;\r\n case 7: lOpposite = 3; break;\r\n }\r\n diff = new Point(diff.x,0);\r\n lOppositeKnot = this.cacheOppositeKnot(lOpposite); \r\n if (event.shiftKey)\r\n diffOpposite = new Point(-diff.x,p.original.y-lOppositeKnot.original.y);\r\n else\r\n diffOpposite = new Point( diff.x,p.original.y-lOppositeKnot.original.y);\r\n }\r\n else\r\n {\r\n switch (lIdx)\r\n {\r\n case 0: lOpposite = 6; break;\r\n case 1: lOpposite = 5; break;\r\n case 2: lOpposite = 4; break;\r\n case 4: lOpposite = 2; break;\r\n case 5: lOpposite = 1; break;\r\n case 6: lOpposite = 0; break;\r\n }\r\n diff = new Point(0,diff.y);\r\n lOppositeKnot = this.cacheOppositeKnot(lOpposite); \r\n if (event.shiftKey)\r\n diffOpposite = new Point(p.original.x-lOppositeKnot.original.x, -diff.y);\r\n else\r\n diffOpposite = new Point(p.original.x-lOppositeKnot.original.x, diff.y);\r\n }\r\n p.point.set( Point_add(p.original,diff) );\r\n p.left.set( Point_add(p.originalLeft ,diff) );\r\n p.right.set( Point_add(p.originalRight,diff) );\r\n lOppositeKnot.point.set( Point_add(lOppositeKnot.original,diffOpposite) );\r\n lOppositeKnot.left.set( Point_add(lOppositeKnot.originalLeft ,diffOpposite) );\r\n lOppositeKnot.right.set( Point_add(lOppositeKnot.originalRight,diffOpposite) ); \r\n }\r\n else\r\n {\r\n if (this._oppositeKnotId != undefined)\r\n {\r\n this._oppositeKnotId = undefined;\r\n this._oppositeKnot.point.set(this._oppositeKnot.original);\r\n this._oppositeKnot.left.set( this._oppositeKnot.originalLeft);\r\n this._oppositeKnot.right.set( this._oppositeKnot.originalRight);\r\n }\r\n\r\n forEach( this._points, p => {\r\n p.point.set( Point_add(p.original,diff) );\r\n if( p.left ) {\r\n p.left.set( Point_add(p.originalLeft ,diff) );\r\n }\r\n if( p.right ) {\r\n p.right.set( Point_add(p.originalRight,diff) );\r\n }\r\n });\r\n }\r\n this.redraw();\r\n this.callParent(event);\r\n },\r\n\r\n up( /*view,event*/) {\r\n this.onUpdate();\r\n this.undoState();\r\n }\r\n }),\r\n\r\n 'MovingControl': BaseState.extend({\r\n// =========================================================\r\n init( tool,side,fromPoint) {\r\n const _this = this;\r\n _this.callParent(tool);\r\n _this._side = side;\r\n _this._fromPoint = fromPoint;\r\n const knot = _this._knot = _this.selectedKnot();\r\n _this._knotPoint = knot.point();\r\n _this._point = knot.controlPoint(side);\r\n _this._original = _this._point.clone();\r\n _this._corner = knot.corner();\r\n const opp = _this._opp = knot.controlPoint(oppSide(side));\r\n if( opp ) {\r\n _this._originalOpp = opp.clone();\r\n }\r\n _this._handle = new Handle.Control(_this,side);\r\n _this._oppHandle = new Handle.Control(_this,oppSide(side));\r\n },\r\n\r\n draw( context, transform ) {\r\n this._handle.draw(context,transform);\r\n this._oppHandle.draw(context,transform);\r\n this.callParent(context,transform);\r\n },\r\n\r\n down() {\r\n this.state('Iddle');\r\n return false;\r\n },\r\n\r\n move( event ) {\r\n const _this = this,\r\n fromPoint = _this._fromPoint,\r\n toPoint = _this.curvePoint(event),\r\n diff = Point_substract(toPoint,fromPoint),\r\n point = _this._point,\r\n opp = _this._opp,\r\n knotPoint = _this._knotPoint;\r\n\r\n point.set( Point_add(_this._original,diff) );\r\n _this._handle._point = point;\r\n\r\n if( opp ) {\r\n const oppVec = Point_substract(point,knotPoint).sm(-1);\r\n if( _this._corner === 'curve' ) {\r\n if( ! oppVec.isZero()) {\r\n const oppNorm = Point_substract(opp,knotPoint).norm();\r\n oppVec.sm(oppNorm/oppVec.norm());\r\n }\r\n opp.set( Point_add(knotPoint,oppVec) );\r\n }\r\n else if( _this._corner === 'symmetric' ) {\r\n opp.set( Point_add(knotPoint,oppVec) );\r\n }\r\n _this._oppHandle._point = opp;\r\n }\r\n\r\n _this.redraw();\r\n },\r\n\r\n up() {\r\n this.onUpdate();\r\n this.undoState();\r\n }\r\n })\r\n// =========================================================\r\n};\r\n\r\nlet NodeEditBaseTool = Tool.extend({\r\n Properties: {\r\n alpha: { type: 'number', def: 1 }\r\n },\r\n initTool( view, figure ) {\r\n if( figure && this.canEdit(figure) ) {\r\n return this.startEditingFigure$(figure);\r\n }\r\n },\r\n startEdition( /*figure*/) {\r\n\r\n },\r\n startEditingFigure$( figure ) {\r\n const _this = this, view = this.view;\r\n _this._figure = null;\r\n return figure.update$() .then( () => {\r\n view.unlock();\r\n _this._figure = figure;\r\n _this.startEdition(figure);\r\n _this._matrix = figure.matrix_();\r\n _this._matrixInverted = _this._matrix.inverted();\r\n _this._curves = _this.createCurves(figure);\r\n _this._undoState = [];\r\n _this._selectedKnots = [];\r\n _this._state = new State.Iddle(_this);\r\n _this.redraw();\r\n view.preview$();\r\n });\r\n },\r\n\r\n on_keydown({ view, event, altKey, which }) {\r\n if( altKey ) {\r\n event.preventDefault();\r\n this.on_keydown_alt(event);\r\n }\r\n\r\n if( ! view._keyShortcuts ) {\r\n return;\r\n }\r\n\r\n switch( which ) {\r\n case 46: // 'Del'\r\n event.preventDefault();\r\n this._state.deleteAction();\r\n break;\r\n }\r\n },\r\n\r\n on_keyup({ event, altKey }) {\r\n if( ! altKey ) {\r\n event.preventDefault();\r\n return this.on_keyup_alt(event);\r\n }\r\n },\r\n\r\n on_keydown_alt({ view }) {\r\n if( ! this._transparentMode ) {\r\n this._transparentMode = true;\r\n view.redraw('document');\r\n this.redraw();\r\n view.render$();\r\n }\r\n },\r\n on_keyup_alt({ view }) {\r\n if( this._transparentMode ) {\r\n this._transparentMode = false;\r\n view.redraw('document');\r\n this.redraw();\r\n view.render$();\r\n }\r\n },\r\n\r\n state( s, sk, ...params ) {\r\n const _this = this, undoState = _this._undoState;\r\n undoState.push( _this._state );\r\n if( undoState.length > 10 ) { undoState.shift(); }\r\n\r\n _this._selectedKnots = !sk ? [] : isArray(sk) ? sk : [sk];\r\n _this._state = new State[s](_this,...params);\r\n _this.redraw();\r\n },\r\n\r\n undoState() {\r\n this._state = this._undoState.pop();\r\n this._state.focus();\r\n this.redraw();\r\n },\r\n\r\n somethingToDraw() {\r\n return !!this._figure;\r\n },\r\n\r\n draw({ view, context, transform }) {\r\n if( !this._figure ) {\r\n return;\r\n }\r\n\r\n // Draw figure being edited\r\n view.drawIsolatedFigures( this._alpha * ( this._transparentMode ? 0.6 : 1 ) );\r\n\r\n // Draw curves, knots and handles\r\n context.lineJoin = 'round';\r\n const ft = Matrix.m(transform,this._matrix);\r\n this._state.draw(context,ft);\r\n },\r\n\r\n try_pointerdown({ event, isPrimary, docPoint }) {\r\n if( !this._figure ) {\r\n return;\r\n }\r\n if( ! isPrimary ) {\r\n return; // ignore multitouch\r\n }\r\n if( ! this._state.down(event) ) {\r\n this._clickOut = { docPoint };\r\n }\r\n else {\r\n event.stopPropagation();\r\n }\r\n },\r\n\r\n on_pointerdown(event) {\r\n this.try_pointerdown(event);\r\n },\r\n\r\n on_mousemove({ event }) {\r\n if( !this._figure ) {\r\n return;\r\n }\r\n this._state.mousemove(event);\r\n },\r\n\r\n on_pointermove({ event, isPrimary }) {\r\n if( !this._figure ) {\r\n return;\r\n }\r\n if( ! isPrimary ) {\r\n return; // ignore multitouch\r\n }\r\n const co = this._clickOut;\r\n if( co && ! event.docPoint.isEqual( co.docPoint ) ) {\r\n this._clickOut = null;\r\n }\r\n this._state.move(event);\r\n },\r\n\r\n on_pointerup({ isPrimary, event }) {\r\n if( ! isPrimary ) {\r\n return; // ignore multitouch\r\n }\r\n if( this._figure ) {\r\n this._state.up(event);\r\n }\r\n\r\n if( this._clickOut || ! this._figure ) {\r\n this._clickOut = null;\r\n this._onClickOut(event);\r\n }\r\n },\r\n\r\n _onClickOut({ view, event, docPoint, cmdKey }) {\r\n\r\n const _this = this;\r\n const figure = event.figure; // [EVENTS] view.figureAtPoint( docPoint );\r\n if( figure && _this.canEdit(figure) ) {\r\n _this.commitChanges$({ select: false }) .then( () => {\r\n _this.startEditingFigure$(figure);\r\n });\r\n }\r\n else if( cmdKey ) {\r\n _this.commit$();\r\n }\r\n },\r\n\r\n on_dblclick( event ) {\r\n if( !this._figure || !this._state.on_dblclick(event) ) {\r\n this.commit$();\r\n }\r\n },\r\n\r\n onUpdate() {\r\n // ...\r\n }\r\n});\r\n\r\nexport const NodeEditTool = NodeEditBaseTool.extend({ typeName: 'NodeEditTool',\r\n toolbarName: 'nodeEditTool',\r\n _hideOriginal: true,\r\n redraw() {\r\n this.callParent();\r\n if( this._figure ) {\r\n this._figure.invalidateView();\r\n }\r\n this.view.preview$();\r\n },\r\n createCurves( figure ) {\r\n const curves = [];\r\n forEach( figure.polyregions, p => {\r\n forEach( p.regions, r => {\r\n forEach( r.curves, (c,i) => {\r\n if( ! ( c instanceof Curve ) ) {\r\n c = c.convertToCurve();\r\n r.curves[i] = c;\r\n }\r\n // Curves are not currently properly owned\r\n // I am thinking that we should remove lazyCDL curves loading so we can just include it in our type system\r\n c._owner = r;\r\n curves.push(c);\r\n });\r\n });\r\n });\r\n return curves;\r\n },\r\n canEdit( figure ) {\r\n return this.view.is(figure,'nodeEditable');\r\n },\r\n startEdition( figure ) {\r\n this.view.startIsolatedFiguresEdition([figure]);\r\n },\r\n _cancel$( view, doc ) {\r\n view.stopIsolatedFiguresEdition();\r\n view.selectedFigures.set(this._figure);\r\n return doc.revert$();\r\n },\r\n _commit$( view ) {\r\n view.stopIsolatedFiguresEdition();\r\n return this.commitChanges$();\r\n },\r\n commitChanges$( config ) {\r\n const view = this.view, doc = view.document;\r\n // This is really important, grab the first envelope point\r\n // before the figure is invalidated\r\n const figure = this._figure;\r\n if( ! figure ) {\r\n return resolve();\r\n }\r\n if( figure._polyregions.length === 0 ) {\r\n view.remove(figure);\r\n return doc.commit$();\r\n }\r\n\r\n const referencePoint = figure.referencePoint_().clone();\r\n\r\n figure.invalidate();\r\n figure.visible = true;\r\n\r\n if( config && config.select !== false ) {\r\n view.selectedFigures.set(figure);\r\n }\r\n\r\n return if$( ! ( figure._anchor._absolute && figure._pin.anchorBased() ), () => {\r\n return figure._fixUpPin$('referencePoint_',referencePoint);\r\n }).then( () => {\r\n if( figure.document !== doc ) {\r\n view.add( figure );\r\n }\r\n return doc.commit$();\r\n });\r\n }\r\n});\r\nTool.NodeEdit = NodeEditTool;\r\n\r\nexport const NodeEditEnvelopeTool = NodeEditBaseTool.extend({ typeName: 'NodeEditEnvelopeTool',\r\n toolbarName: 'nodeEditEnvelopeTool',\r\n canEdit( figure ) {\r\n return ( figure.isText && ! figure.isMultiPart ) ||\r\n ( !! findByType( figure._processes, Process.FitEnvelope ) ) ;\r\n },\r\n\r\n startEdition( figure ) {\r\n this.view.startIsolatedFiguresEdition([figure]);\r\n },\r\n _cancel$( view, doc ) {\r\n if( Config.localFitEnvelope ) {\r\n return view.revert$();\r\n }\r\n else {\r\n view.selectedFigures.set(this._figure);\r\n }\r\n view.stopIsolatedFiguresEdition();\r\n },\r\n _commit$( view ) {\r\n view.stopIsolatedFiguresEdition();\r\n return this.commitChanges$();\r\n },\r\n\r\n createCurves( figure ) {\r\n // We create a envelope { figure, process, editable } for every envelope in the figure\r\n let process = findByType(figure.processes,Process.FitEnvelope) ;\r\n this._addOnCommit = !process;\r\n if( ! process ) {\r\n process = Process.FitEnvelope.createFromFigure(figure);\r\n }\r\n this._process = process;\r\n\r\n // Convert the envelope to one closed curve\r\n let pieces = [] ;\r\n forEach( process.envelope().curves, c => {\r\n // Flag it\r\n const ps = cloneDeep(c.pieces);\r\n ps[0].P0.__cadx_locked = true ;\r\n pieces = pieces.concat(ps);\r\n });\r\n\r\n return [ Curve.fromNonTiedPieces(pieces,true) ];\r\n },\r\n onUpdate() {\r\n if( Config.localFitEnvelope ) {\r\n const view = this.view;\r\n return this.updateFigure$() .then( () => {\r\n view.unlock();\r\n this.redraw();\r\n view.preview$();\r\n });\r\n }\r\n },\r\n updateFigure$() {\r\n const _this = this;\r\n const figure = _this._figure;\r\n if( ! figure ) {\r\n return resolve();\r\n }\r\n const process = _this._process;\r\n const addOnCommit = _this._addOnCommit;\r\n return if$( addOnCommit, () => {\r\n _this._addOnCommit = false;\r\n return figure.center$() .then( center => {\r\n figure._processes.add(process);\r\n figure.pin = center;\r\n });\r\n }) .then( () => {\r\n\r\n return figure.matrix$() .then( matrix => {\r\n\r\n const oldEnvelopeCenter = matrix.apply( process._envelope.center );\r\n\r\n const curve = _this._curves[0];\r\n\r\n // Get the four curves from envelopeCurve\r\n const curves = [];\r\n let currentPieces = [];\r\n const createCurve = function() {\r\n if( currentPieces.length > 0 ) {\r\n curves.push( new Curve.fromNonTiedPieces(currentPieces,false) );\r\n currentPieces = [] ;\r\n }\r\n };\r\n forEach( curve.pieces, p => {\r\n if( p.P0.__cadx_locked === true ) {\r\n createCurve();\r\n }\r\n currentPieces.push(p.clone());\r\n });\r\n createCurve();\r\n\r\n process.envelope( new Envelope(curves) );\r\n\r\n const newEnvelopeCenter = matrix.apply( process._envelope.center );\r\n\r\n const offset = Point.substract(newEnvelopeCenter,oldEnvelopeCenter);\r\n figure.translate( offset );\r\n\r\n return figure;\r\n });});\r\n },\r\n commitChanges$( config ) {\r\n const view = this.view, figure = this._figure;\r\n return this.updateFigure$() .then( () => {\r\n if( config && config.select !== false ) {\r\n view.selectedFigures.set(figure);\r\n }\r\n return view.commit$();\r\n });\r\n }\r\n});\r\nTool.NodeEditEnvelope = NodeEditEnvelopeTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/node-edit.js\n **/","import { includes, last } from 'lodash';\r\n\r\nimport { Point, Matrix, TextureBrushBase } from 'cdl';\r\n\r\nimport { Tool } from '../view';\r\n\r\nimport { SelectAndTransformHandles } from './select-transform';\r\n\r\nexport const RenderInfoTool = Tool.extend({ typeName: 'RenderInfoTool',\r\n type: 'Final',\r\n toolbarName: 'renderInfoTool',\r\n initTool( view, figure ) {\r\n\r\n this.handles = new SelectAndTransformHandles({\r\n\r\n view: this.view,\r\n tool: this,\r\n\r\n editingItems: () => {\r\n const figure = this._figure;\r\n return figure ? [ figure ] : [];\r\n },\r\n\r\n getOriginalTransforms: () => {\r\n this._downFrame = this.computeRenderFrame_();\r\n this._downMatrix22 = this._polyregion.renderMatrix || new Matrix();\r\n },\r\n\r\n setOriginalTransforms: () => {\r\n // Directly handle revert in transformItems\r\n },\r\n\r\n computeItemsFrame_: this.computeRenderFrame_.bind(this),\r\n\r\n transformItems: this.transformItems.bind(this),\r\n\r\n itemsEnabledTransforms: () => {\r\n return {\r\n translate: true,\r\n scale: true,\r\n rotate: true\r\n };\r\n }\r\n });\r\n\r\n if( figure ) {\r\n this.startEdit(figure);\r\n }\r\n },\r\n\r\n computeRenderFrame_() {\r\n const polyregion = this._polyregion;\r\n return ( polyregion.renderFrame || polyregion.initialRenderFrame() ).transformed(this._figure.globalMatrix_());\r\n },\r\n\r\n transformItems( items, transform ) {\r\n const figure = this._figure,\r\n polyregion = this._polyregion,\r\n downFrame = this._downFrame,\r\n downMatrix22 = this._downMatrix22;\r\n\r\n const mi = figure.matrix_().inverted();\r\n\r\n const mi_transform = Matrix.m( mi, transform );\r\n\r\n polyregion.renderMatrix = Matrix.m( Matrix.rotate(mi_transform.angle()), downMatrix22 );\r\n polyregion.renderFrame = downFrame.transformed(mi_transform);\r\n },\r\n\r\n startEdit( figure, point ) { const view = this.view;\r\n this._figure = figure;\r\n this._polyregion = point ? figure.polyregionAtPoint_(point) : last(figure._polyregions);\r\n this.handles.update();\r\n this.redraw();\r\n view.render$();\r\n },\r\n\r\n link( view ) {\r\n this.handles.create();\r\n // [TODO] Abstract\r\n const h = this.handles.handles; // grab internal handles\r\n h._fillColor = '#6e78d1';\r\n h._fillOverColor = '#243788';\r\n h._fillActiveColor = '#fb603d';\r\n h._strokeColor = '#243788';\r\n\r\n\r\n view.on({ 'rendercomplete': this.on_rendercomplete }, this );\r\n },\r\n\r\n unlink( view ) {\r\n view.un(this);\r\n this.handles.dispose();\r\n },\r\n\r\n on_rendercomplete() {\r\n if( ! includes(this.view.figures,this._figure) ) {\r\n this._figure = null;\r\n }\r\n this.handles.update();\r\n },\r\n\r\n on_pointerdown({ view, event, isPrimary, docPoint }) {\r\n if( ! isPrimary ) {\r\n return;\r\n }\r\n\r\n const hs = this.handles;\r\n if( hs._editionMode ) {\r\n hs.up(event);\r\n return;\r\n }\r\n\r\n const leftClick = event.which === 1;\r\n if( ! leftClick ) {\r\n return;\r\n }\r\n\r\n if( hs.isHandle(event) ) {\r\n event.stopPropagation();\r\n hs.down(event);\r\n }\r\n else {\r\n\r\n const figure = event.figure; // [EVENTS] view.figureAtPoint(docPoint);\r\n if( figure && figure.isShape ) {\r\n this.startEdit(figure,docPoint);\r\n }\r\n }\r\n },\r\n on_pointermove( event ) {\r\n this.handles.move(event);\r\n },\r\n on_pointerup( event ) {\r\n this.handles.up(event);\r\n },\r\n\r\n draw( config ) {\r\n this.handles.draw( config );\r\n }\r\n\r\n});\r\n\r\n\r\nTool.ClippingBounds = Tool.extend({ typeName: 'ClippingBoundsTool',\r\n type: 'Final',\r\n toolbarName: 'clippingBoundsTool',\r\n initTool( view,figure ) {\r\n\r\n this.handles = new SelectAndTransformHandles({\r\n\r\n view: this.view,\r\n tool: this,\r\n\r\n editingItems: () => {\r\n const figure = this._figure;\r\n return figure ? [ figure ] : [];\r\n },\r\n\r\n getOriginalTransforms: () => {\r\n this._downFrame = this.clippingFrame();\r\n this._downClippingBounds = this._brush.clippingBounds.clone();\r\n this._downTextureOffset = this._brush.textureOffset.clone();\r\n // this._downPin = this._figure.globalMatrix_().apply( this.clippingFrame().center );\r\n },\r\n\r\n setOriginalTransforms: () => {\r\n // Directly handle revert in transformItems\r\n },\r\n\r\n computeItemsFrame_: this.clippingFrame.bind(this),\r\n\r\n transformItems: this.transformItems.bind(this),\r\n\r\n itemsEnabledTransforms: () => {\r\n return {\r\n translate: true,\r\n scale: true\r\n };\r\n }\r\n });\r\n\r\n if( figure ) {\r\n this.startEdit(figure);\r\n }\r\n },\r\n startEdit( figure, point ) { const view = this.view;\r\n this._figure = null;\r\n if( figure.isShape ) {\r\n const polyregion = point ? figure.polyregionAtPoint_(point) : last(figure._polyregions);\r\n const brush = polyregion.brush;\r\n if( brush instanceof TextureBrushBase ) {\r\n this._figure = figure;\r\n this._polyregion = polyregion;\r\n this._brush = brush;\r\n }\r\n }\r\n this.handles.update();\r\n this.redraw();\r\n view.render$();\r\n },\r\n\r\n link( view ) {\r\n this.handles.create();\r\n\r\n const h = this.handles.handles;\r\n h._fillColor = '#6e78d1';\r\n h._fillOverColor = '#243788';\r\n h._fillActiveColor = '#fb603d';\r\n h._strokeColor = '#243788';\r\n\r\n view.on({ 'rendercomplete': this.on_rendercomplete }, this );\r\n },\r\n unlink( view ) {\r\n view.un(this);\r\n this.handles.dispose();\r\n },\r\n\r\n on_rendercomplete() {\r\n if( ! includes(this.view.figures,this._figure) ) {\r\n this._figure = null;\r\n }\r\n this.handles.update();\r\n },\r\n\r\n on_pointerdown({ view, event, isPrimary, which, docPoint }) {\r\n if( ! isPrimary ) {\r\n return;\r\n }\r\n\r\n const hs = this.handles;\r\n if( hs._editionMode ) {\r\n hs.up(event);\r\n return;\r\n }\r\n\r\n const leftClick = which === 1;\r\n if( ! leftClick ) {\r\n return;\r\n }\r\n\r\n if( hs.isHandle(event) ) {\r\n event.stopPropagation();\r\n hs.down(event);\r\n }\r\n else {\r\n\r\n const figure = event.figure; // [EVENTS] view.figureAtPoint(docPoint);\r\n if( figure && figure.isShape ) {\r\n this.startEdit(figure,docPoint);\r\n }\r\n }\r\n },\r\n on_pointermove( event ) {\r\n this.handles.move(event);\r\n },\r\n on_pointerup( event ) {\r\n this.handles.up(event);\r\n },\r\n\r\n draw(config) {\r\n this.handles.draw(config);\r\n },\r\n\r\n renderFrame() {\r\n const figure = this._figure, polyregion = this._polyregion;\r\n const matrix = figure.globalMatrix_();\r\n return ( polyregion.renderFrame || polyregion.initialRenderFrame() ).transformed(matrix);\r\n },\r\n\r\n clippingFrame() {\r\n return this._brush.clippingFrame_(this.renderFrame());\r\n },\r\n\r\n transformItems( items, transform ) {\r\n\r\n const brush = this._brush,\r\n frame_0 = this._downFrame;\r\n\r\n const frame_1 = frame_0.transformed(transform);\r\n\r\n const rotate = Matrix.rotate(-frame_0.angle());\r\n\r\n const fr_0 = frame_0.transformed(rotate);\r\n\r\n const ocb = this._downClippingBounds;\r\n\r\n const scale = Matrix.scale( ocb.width / fr_0.width,\r\n ocb.height / fr_0.height );\r\n\r\n const frs_0 = fr_0.transformed(scale);\r\n\r\n const translate = Matrix.translate( ocb.lx_ly .minus( frs_0.p0 ) );\r\n\r\n const ncb = frame_1.transformed( Matrix.concat(translate,scale,rotate) ).bounds;\r\n\r\n brush.clippingBounds = ncb;\r\n\r\n const dto = this._downTextureOffset;\r\n\r\n const nto = new Point( ( ocb.lx + dto.x * ocb.width - ncb.lx ) / ncb.width ,\r\n ( ocb.ly + dto.y * ocb.height - ncb.ly ) / ncb.height );\r\n\r\n brush.textureOffset = nto;\r\n }\r\n\r\n});\r\n\r\nTool.RenderInfo = RenderInfoTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/render-info.js\n **/","\r\nimport { Tool } from '../view';\r\n\r\nexport const SelectBrushTool = Tool.extend({\r\n\r\n type: 'Select',\r\n\r\n toolbarName: 'selectBrush',\r\n allowKeyShortcuts: true,\r\n\r\n initTool( view, config ) {\r\n const th = ['Click to select a brush'];\r\n this.toolhelp(th);\r\n },\r\n\r\n on_pointerdown({ view, event, which, cmdKey, docPoint, pointers }) {\r\n const leftClick = which === 1;\r\n if( ! leftClick ) {\r\n return ;\r\n }\r\n view.fireEvent('brushselected',view.getBrushAtPoint(docPoint));\r\n event.stopPropagation();\r\n\r\n },\r\n\r\n on_pointerup( event ) {\r\n }\r\n\r\n});\r\n\r\nTool.SelectBrush = SelectBrushTool;\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/ui/tool/select-brush.js\n **/"],"sourceRoot":""}