From e94ddb7d3fb30beef76b0480bb37d59db0ee06f7 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Fri, 29 Apr 2016 02:21:40 +0200 Subject: [PATCH] Built dist and bump to 1.6.1 (#2919) bumped to 1.6.1 --- CHANGELOG.md | 17 + HEADER.js | 2 +- ISSUE_TEMPLATE.md | 2 +- dist/fabric.js | 263 +- dist/fabric.min.js | 23 +- dist/fabric.min.js.gz | Bin 64874 -> 75936 bytes dist/fabric.require.js | 11906 +-------------------------------------- package.json | 2 +- 8 files changed, 221 insertions(+), 11994 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6fa1d04..4f80ad66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +**Version 1.6.1** + +- Fix: image with broken element throwing error on toObject() [#2878](https://github.com/kangax/fabric.js/pull/2878) +- Fix: Warning on trying to set proprietary browser version of ctxImageSmoothingEnabled [#2880](https://github.com/kangax/fabric.js/pull/2880) +- Fix: Fixed Svg import regression on color and drawing polylines [#2887](https://github.com/kangax/fabric.js/pull/2887) +- Fix: Fixed animation ease that starts and stop at same value [#2888](https://github.com/kangax/fabric.js/pull/2888) +- Fix: Allow a not stateful canvas to fire object:modified at end of transform. [#2890](https://github.com/kangax/fabric.js/pull/2890) +- Fix: Made event handler removal safer. Removing firing events will not cause errors. [#2883](https://github.com/kangax/fabric.js/pull/2883) +- Fix: Proper handling of perPixelTargetFind and multi selections [#2894](https://github.com/kangax/fabric.js/pull/2894) +- Fix: Do not clear contextTop on drawingMode, to allow drawing over animations [#2895](https://github.com/kangax/fabric.js/pull/2895) +- Change the dependencies to optional. Allow npm to continue installing if nodecanvas installation fail.[#2901](https://github.com/kangax/fabric.js/pull/2901) +- Fix: Check again the target on mouseup [#2902](https://github.com/kangax/fabric.js/pull/2902) +- Fix: On perPixelTargetFind detect corners only if target is active [#2903](https://github.com/kangax/fabric.js/pull/2903) +- Improvement: Add canvas mouseout event listener [#2907](https://github.com/kangax/fabric.js/pull/2907) +- Improvement: Make small object draggable easier [#2907](https://github.com/kangax/fabric.js/pull/2907) +- Improvement: Use sendToBack, bringToFront, bringForward, sendBackwards for multiple selections [#2908](https://github.com/kangax/fabric.js/pull/2908) + **Version 1.6.0** - Fix rendering of activeGroup objects while preserveObjectStacking is active. [ regression from [#2083](https://github.com/kangax/fabric.js/pull/2083) ] diff --git a/HEADER.js b/HEADER.js index 5376fd25..53fcfd16 100644 --- a/HEADER.js +++ b/HEADER.js @@ -1,6 +1,6 @@ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: "1.6.0" }; +var fabric = fabric || { version: "1.6.1" }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index fcc15adb..ac72aa0d 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -24,7 +24,7 @@ Remove the template from below and provide thoughtful commentary *and code sampl ## Version -1.6.0 +1.6.1 ## Test Case http://jsfiddle.net/fabricjs/Da7SP/ diff --git a/dist/fabric.js b/dist/fabric.js index 1528cbc5..31705dff 100644 --- a/dist/fabric.js +++ b/dist/fabric.js @@ -1,7 +1,7 @@ -/* build: `node build.js modules=ALL exclude=gestures,json minifier=uglifyjs` */ +/* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: "1.6.0-rc.1" }; +var fabric = fabric || { version: "1.6.1" }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } @@ -185,8 +185,8 @@ fabric.devicePixelRatio = fabric.window.devicePixelRatio || /** * @namespace fabric.Observable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#events} - * @see {@link http://fabricjs.com/events/|Events demo} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events} + * @see {@link http://fabricjs.com/events|Events demo} */ fabric.Observable = { observe: observe, @@ -5148,7 +5148,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { /** * Gradient class * @class fabric.Gradient - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#gradients} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients} * @see {@link fabric.Gradient#initialize} for constructor definition */ fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ { @@ -5499,8 +5499,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() { /** * Pattern class * @class fabric.Pattern - * @see {@link http://fabricjs.com/patterns/|Pattern demo} - * @see {@link http://fabricjs.com/dynamic-patterns/|DynamicPattern demo} + * @see {@link http://fabricjs.com/patterns|Pattern demo} + * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo} * @see {@link fabric.Pattern#initialize} for constructor definition */ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ { @@ -5680,7 +5680,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ /** * Shadow class * @class fabric.Shadow - * @see {@link http://fabricjs.com/shadows/|Shadow demo} + * @see {@link http://fabricjs.com/shadows|Shadow demo} * @see {@link fabric.Shadow#initialize} for constructor definition */ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { @@ -5872,7 +5872,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @class fabric.StaticCanvas * @mixes fabric.Collection * @mixes fabric.Observable - * @see {@link http://fabricjs.com/static_canvas/|StaticCanvas demo} + * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo} * @see {@link fabric.StaticCanvas#initialize} for constructor definition * @fires before:render * @fires after:render @@ -7040,7 +7040,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @param {String} [options.height] desired height of svg with or without units * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation. * @return {String} SVG string - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#serialization} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo} * @example Normal SVG output * var svg = canvas.toSVG(); @@ -7199,47 +7199,97 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ /* _TO_SVG_END_ */ /** - * Moves an object to the bottom of the stack of drawn objects + * Moves an object or the objects of a multiple selection + * to the bottom of the stack of drawn objects * @param {fabric.Object} object Object to send to back * @return {fabric.Canvas} thisArg * @chainable */ sendToBack: function (object) { - removeFromArray(this._objects, object); - this._objects.unshift(object); + if (!object) { + return this; + } + var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + i, obj, objs; + if (object === activeGroup) { + objs = activeGroup._objects; + for (i = objs.length; i--;) { + obj = objs[i]; + removeFromArray(this._objects, obj); + this._objects.unshift(obj); + } + } + else { + removeFromArray(this._objects, object); + this._objects.unshift(object); + } return this.renderAll && this.renderAll(); }, /** - * Moves an object to the top of the stack of drawn objects + * Moves an object or the objects of a multiple selection + * to the top of the stack of drawn objects * @param {fabric.Object} object Object to send * @return {fabric.Canvas} thisArg * @chainable */ bringToFront: function (object) { - removeFromArray(this._objects, object); - this._objects.push(object); + if (!object) { + return this; + } + var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + i, obj, objs; + if (object === activeGroup) { + objs = activeGroup._objects; + for (i = 0; i < objs.length; i++) { + obj = objs[i]; + removeFromArray(this._objects, obj); + this._objects.push(obj); + } + } + else { + removeFromArray(this._objects, object); + this._objects.push(object); + } return this.renderAll && this.renderAll(); }, /** - * Moves an object down in stack of drawn objects + * Moves an object or a selection down in stack of drawn objects * @param {fabric.Object} object Object to send * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object * @return {fabric.Canvas} thisArg * @chainable */ sendBackwards: function (object, intersecting) { - var idx = this._objects.indexOf(object); - - // if object is not on the bottom of stack - if (idx !== 0) { - var newIdx = this._findNewLowerIndex(object, idx, intersecting); - - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - this.renderAll && this.renderAll(); + if (!object) { + return this; } + var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + i, obj, idx, newIdx, objs; + + if (object === activeGroup) { + objs = activeGroup._objects; + for (i = 0; i < objs.length; i++) { + obj = objs[i]; + idx = this._objects.indexOf(obj); + if (idx !== 0) { + newIdx = idx - 1; + removeFromArray(this._objects, obj); + this._objects.splice(newIdx, 0, obj); + } + } + } + else { + idx = this._objects.indexOf(object); + if (idx !== 0) { + // if object is not on the bottom of stack + newIdx = this._findNewLowerIndex(object, idx, intersecting); + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + } + } + this.renderAll && this.renderAll(); return this; }, @@ -7273,23 +7323,41 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ }, /** - * Moves an object up in stack of drawn objects + * Moves an object or a selection up in stack of drawn objects * @param {fabric.Object} object Object to send * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object * @return {fabric.Canvas} thisArg * @chainable */ bringForward: function (object, intersecting) { - var idx = this._objects.indexOf(object); - - // if object is not on top of stack (last item in an array) - if (idx !== this._objects.length - 1) { - var newIdx = this._findNewUpperIndex(object, idx, intersecting); - - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - this.renderAll && this.renderAll(); + if (!object) { + return this; } + var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + i, obj, idx, newIdx, objs; + + if (object === activeGroup) { + objs = activeGroup._objects; + for (i = objs.length; i--;) { + obj = objs[i]; + idx = this._objects.indexOf(obj); + if (idx !== this._objects.length - 1) { + newIdx = idx + 1; + removeFromArray(this._objects, obj); + this._objects.splice(newIdx, 0, obj); + } + } + } + else { + idx = this._objects.indexOf(object); + if (idx !== this._objects.length - 1) { + // if object is not on top of stack (last item in an array) + newIdx = this._findNewUpperIndex(object, idx, intersecting); + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + } + } + this.renderAll && this.renderAll(); return this; }, @@ -7419,7 +7487,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @function * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output * @return {String} JSON string - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#serialization} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo} * @example JSON without additional properties * var json = canvas.toJSON(); @@ -7437,7 +7505,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ /** * BaseBrush class * @class fabric.BaseBrush - * @see {@link http://fabricjs.com/freedrawing/|Freedrawing demo} + * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo} */ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ { @@ -8162,7 +8230,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * Canvas class * @class fabric.Canvas * @extends fabric.StaticCanvas - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#canvas} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas} * @see {@link fabric.Canvas#initialize} for constructor definition * * @fires object:modified @@ -8333,7 +8401,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing. * After mousedown, mousemove creates a shape, * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas. - * @tutorial {@link http://fabricjs.com/fabric-intro-part-4/#free_drawing} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing} * @type Boolean * @default */ @@ -8454,20 +8522,27 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ isTargetTransparent: function (target, x, y) { var hasBorders = target.hasBorders, - transparentCorners = target.transparentCorners; + transparentCorners = target.transparentCorners, + ctx = this.contextCache, + shouldTransform = target.group && target.group === this.getActiveGroup(); target.hasBorders = target.transparentCorners = false; - target.render(this.contextCache); - target._renderControls(this.contextCache); + if (shouldTransform) { + ctx.save(); + ctx.transform.apply(ctx, target.group.calcTransformMatrix()); + } + target.render(ctx); + target.active && target._renderControls(ctx); target.hasBorders = hasBorders; target.transparentCorners = transparentCorners; var isTransparent = fabric.util.isTransparent( - this.contextCache, x, y, this.targetFindTolerance); + ctx, x, y, this.targetFindTolerance); + shouldTransform && ctx.restore(); - this.clearContext(this.contextCache); + this.clearContext(ctx); return isTransparent; }, @@ -9059,7 +9134,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab // first check current group (if one exists) var activeGroup = this.getActiveGroup(); - if (activeGroup && !skipGroup && this.containsPoint(e, activeGroup)) { + if (!skipGroup && this._checkTarget(e, activeGroup, this.getPointer(e, true))) { return activeGroup; } @@ -9479,6 +9554,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab } /** + * @ignore * @class fabric.Element * @alias fabric.Canvas * @deprecated Use {@link fabric.Canvas} instead. @@ -9534,6 +9610,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab addListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); addListener(this.upperCanvasEl, 'mousewheel', this._onMouseWheel); + addListener(this.upperCanvasEl, 'mouseout', this._onMouseOut); // touch events addListener(this.upperCanvasEl, 'touchstart', this._onMouseDown); @@ -9562,6 +9639,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this._onLongPress = this._onLongPress.bind(this); this._onOrientationChange = this._onOrientationChange.bind(this); this._onMouseWheel = this._onMouseWheel.bind(this); + this._onMouseOut = this._onMouseOut.bind(this); }, /** @@ -9573,6 +9651,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); removeListener(this.upperCanvasEl, 'mousewheel', this._onMouseWheel); + removeListener(this.upperCanvasEl, 'mouseout', this._onMouseOut); removeListener(this.upperCanvasEl, 'touchstart', this._onMouseDown); removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove); @@ -9613,6 +9692,17 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this.__onMouseWheel && this.__onMouseWheel(e, self); }, + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseOut: function(e) { + var target = this._hoveredTarget; + this.fire('mouse:out', { target: target, e: e }); + this._hoveredTarget = null; + target && target.fire('mouseout', { e: e }); + }, + /** * @private * @param {Event} [e] Event object fired on Event.js orientation change @@ -9739,21 +9829,20 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @param {Event} e Event object fired on mouseup */ __onMouseUp: function (e) { - var target; + var target, searchTarget = true, transform = this._currentTransform; if (this.isDrawingMode && this._isCurrentlyDrawing) { this._onMouseUpInDrawingMode(e); return; } - if (this._currentTransform) { + if (transform) { this._finalizeCurrentTransform(); - target = this._currentTransform.target; - } - else { - target = this.findTarget(e, true); + searchTarget = !transform.actionPerformed; } + target = searchTarget ? this.findTarget(e, true) : transform.target; + var shouldRender = this._shouldRender(target, this.getPointer(e)); this._maybeGroupObjects(e); @@ -9770,11 +9859,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab _handleCursorAndEvent: function(e, target) { this._setCursorFromEvent(e, target); + // Can't find any reason, disabling for now // TODO: why are we doing this? - var _this = this; + /* var _this = this; setTimeout(function () { _this._setCursorFromEvent(e, target); - }, 50); + }, 50); */ this.fire('mouse:up', { target: target, e: e }); target && target.fire('mouseup', { e: e }); @@ -9925,9 +10015,16 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab target = this.getActiveGroup(); } - if (target && target.selectable && (target.__corner || !shouldGroup)) { - this._beforeTransform(e, target); - this._setupCurrentTransform(e, target); + if (target) { + if (target.selectable && (target.__corner || !shouldGroup)) { + this._beforeTransform(e, target); + this._setupCurrentTransform(e, target); + } + + if (target !== this.getActiveGroup() && target !== this.getActiveObject()) { + this.deactivateAll(); + this.setActiveObject(target, e); + } } // we must renderAll so that active image is placed on the top canvas shouldRender && this.renderAll(); @@ -9947,10 +10044,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this.onBeforeScaleRotate(target); } - if (target !== this.getActiveGroup() && target !== this.getActiveObject()) { - this.deactivateAll(); - this.setActiveObject(target, e); - } }, /** @@ -10666,7 +10759,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. * @return {fabric.Canvas} instance * @chainable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#deserialization} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization} */ loadFromDatalessJSON: function (json, callback, reviver) { return this.loadFromJSON(json, callback, reviver); @@ -10682,7 +10775,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. * @return {fabric.Canvas} instance * @chainable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#deserialization} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization} * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo} * @example loadFromJSON * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas)); @@ -10888,7 +10981,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Root object class from which all 2d shape classes inherit from * @class fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#objects} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects} * @see {@link fabric.Object#initialize} for constructor definition * * @fires added @@ -10903,6 +10996,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * * @fires mousedown * @fires mouseup + * @fires mouseover + * @fires mouseout */ fabric.Object = fabric.util.createClass(/** @lends fabric.Object.prototype */ { @@ -13868,7 +13963,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @param {String|Object} property Property to animate (if string) or properties to animate (if object) * @param {Number|Object} value Value to animate property to (if string was given first) or options object * @return {fabric.Object} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#animation} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation} * @chainable * * As object — multiple properties @@ -15591,7 +15686,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Path class * @class fabric.Path * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#path_and_pathgroup} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup} * @see {@link fabric.Path#initialize} for constructor definition */ fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ { @@ -16543,7 +16638,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Path group class * @class fabric.PathGroup * @extends fabric.Path - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#path_and_pathgroup} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup} * @see {@link fabric.PathGroup#initialize} for constructor definition */ fabric.PathGroup = fabric.util.createClass(fabric.Path, /** @lends fabric.PathGroup.prototype */ { @@ -16833,7 +16928,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @class fabric.Group * @extends fabric.Object * @mixes fabric.Collection - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#groups} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups} * @see {@link fabric.Group#initialize} for constructor definition */ fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ { @@ -17360,7 +17455,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Image class * @class fabric.Image * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#images} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images} * @see {@link fabric.Image#initialize} for constructor definition */ fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ { @@ -18064,8 +18159,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * @namespace fabric.Image.filters * @memberOf fabric.Image - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#image_filters} - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} */ fabric.Image.filters = fabric.Image.filters || { }; @@ -18135,7 +18230,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Brightness({ * brightness: 200 @@ -18219,7 +18314,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example Sharpen filter * var filter = new fabric.Image.filters.Convolute({ * matrix: [ 0, -1, 0, @@ -18377,7 +18472,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.GradientTransparency#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.GradientTransparency({ * threshold: 200 @@ -18458,7 +18553,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Grayscale * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Grayscale(); * object.filters.push(filter); @@ -18521,7 +18616,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Invert * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Invert(); * object.filters.push(filter); @@ -18689,7 +18784,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Noise({ * noise: 700 @@ -18776,7 +18871,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Pixelate({ * blocksize: 8 @@ -18888,7 +18983,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.RemoveWhite#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.RemoveWhite({ * threshold: 40, @@ -18988,7 +19083,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Sepia * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Sepia(); * object.filters.push(filter); @@ -19048,7 +19143,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Sepia2 * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Sepia2(); * object.filters.push(filter); @@ -19114,7 +19209,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Tint#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example Tint filter with hex color and opacity * var filter = new fabric.Image.filters.Tint({ * color: '#3513B0', @@ -19467,7 +19562,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Resize * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Resize(); * object.filters.push(filter); @@ -19812,7 +19907,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Text * @extends fabric.Object * @return {fabric.Text} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#text} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text} * @see {@link fabric.Text#initialize} for constructor definition */ fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ { diff --git a/dist/fabric.min.js b/dist/fabric.min.js index b749434a..27a14cde 100644 --- a/dist/fabric.min.js +++ b/dist/fabric.min.js @@ -1,12 +1,11 @@ -var fabric=fabric||{version:"1.6.0-rc.1"};"undefined"!=typeof exports&&(exports.fabric=fabric),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window,window.fabric=fabric):(fabric.document=require("jsdom").jsdom(""),fabric.window=fabric.document.createWindow?fabric.document.createWindow():fabric.document.parentWindow),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,fabric.isLikelyNode="undefined"!=typeof Buffer&&"undefined"==typeof window,fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,function(){function t(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.util.array.fill(i,!1)}}function e(t,e){if(this.__eventListeners||(this.__eventListeners={}),1===arguments.length)for(var i in t)this.on(i,t[i]);else this.__eventListeners[t]||(this.__eventListeners[t]=[]),this.__eventListeners[t].push(e);return this}function i(e,i){if(this.__eventListeners){if(0===arguments.length)for(e in this.__eventListeners)t.call(this,e);else if(1===arguments.length&&"object"==typeof arguments[0])for(var r in e)t.call(this,r,e[r]);else t.call(this,e,i);return this}}function r(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;n>r;r++)i[r]&&i[r].call(this,e||{});return this.__eventListeners[t]=i.filter(function(t){return t!==!1}),this}}}fabric.Observable={observe:e,stopObserving:i,fire:r,on:e,off:i,trigger:r}}(),fabric.Collection={add:function(){this._objects.push.apply(this._objects,arguments);for(var t=0,e=arguments.length;e>t;t++)this._onObjectAdded(arguments[t]);return this.renderOnAddRemove&&this.renderAll(),this},insertAt:function(t,e,i){var r=this.getObjects();return i?r[e]=t:r.splice(e,0,t),this._onObjectAdded(t),this.renderOnAddRemove&&this.renderAll(),this},remove:function(){for(var t,e=this.getObjects(),i=0,r=arguments.length;r>i;i++)t=e.indexOf(arguments[i]),-1!==t&&(e.splice(t,1),this._onObjectRemoved(arguments[i]));return this.renderOnAddRemove&&this.renderAll(),this},forEachObject:function(t,e){for(var i=this.getObjects(),r=i.length;r--;)t.call(e,i[r],r,i);return this},getObjects:function(t){return"undefined"==typeof t?this._objects:this._objects.filter(function(e){return e.type===t})},item:function(t){return this.getObjects()[t]},isEmpty:function(){return 0===this.getObjects().length},size:function(){return this.getObjects().length},contains:function(t){return this.getObjects().indexOf(t)>-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},function(t){var e=Math.sqrt,i=Math.atan2,r=Math.pow,n=Math.abs,s=Math.PI/180;fabric.util={removeFromArray:function(t,e){var i=t.indexOf(e);return-1!==i&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*s},radiansToDegrees:function(t){return t/s},rotatePoint:function(t,e,i){t.subtractEquals(e);var r=fabric.util.rotateVector(t,i);return new fabric.Point(r.x,r.y).addEquals(e)},rotateVector:function(t,e){var i=Math.sin(e),r=Math.cos(e),n=t.x*r-t.y*i,s=t.x*i+t.y*r;return{x:n,y:s}},transformPoint:function(t,e,i){return i?new fabric.Point(e[0]*t.x+e[2]*t.y,e[1]*t.x+e[3]*t.y):new fabric.Point(e[0]*t.x+e[2]*t.y+e[4],e[1]*t.x+e[3]*t.y+e[5])},makeBoundingBoxFromPoints:function(t){var e=[t[0].x,t[1].x,t[2].x,t[3].x],i=fabric.util.array.min(e),r=fabric.util.array.max(e),n=Math.abs(i-r),s=[t[0].y,t[1].y,t[2].y,t[3].y],o=fabric.util.array.min(s),a=fabric.util.array.max(s),h=Math.abs(o-a);return{left:i,top:o,width:n,height:h}},invertTransform:function(t){var e=1/(t[0]*t[3]-t[1]*t[2]),i=[e*t[3],-e*t[1],-e*t[2],e*t[0]],r=fabric.util.transformPoint({x:t[4],y:t[5]},i,!0);return i[4]=-r.x,i[5]=-r.y,i},toFixed:function(t,e){return parseFloat(Number(t).toFixed(e))},parseUnit:function(t,e){var i=/\D{0,2}$/.exec(t),r=parseFloat(t);switch(e||(e=fabric.Text.DEFAULT_SVG_FONT_SIZE),i[0]){case"mm":return r*fabric.DPI/25.4;case"cm":return r*fabric.DPI/2.54;case"in":return r*fabric.DPI;case"pt":return r*fabric.DPI/72;case"pc":return r*fabric.DPI/72*12;case"em":return r*e;default:return r}},falseFunction:function(){return!1},getKlass:function(t,e){return t=fabric.util.string.camelize(t.charAt(0).toUpperCase()+t.slice(1)),fabric.util.resolveNamespace(e)[t]},resolveNamespace:function(e){if(!e)return fabric;for(var i=e.split("."),r=i.length,n=t||fabric.window,s=0;r>s;++s)n=n[i[s]];return n},loadImage:function(t,e,i,r){if(!t)return void(e&&e.call(i,t));var n=fabric.util.createImage();n.onload=function(){e&&e.call(i,n),n=n.onload=n.onerror=null},n.onerror=function(){fabric.log("Error loading "+n.src),e&&e.call(i,null,!0),n=n.onload=n.onerror=null},0!==t.indexOf("data")&&r&&(n.crossOrigin=r),n.src=t},enlivenObjects:function(t,e,i,r){function n(){++o===a&&e&&e(s)}t=t||[];var s=[],o=0,a=t.length;return a?void t.forEach(function(t,e){if(!t||!t.type)return void n();var o=fabric.util.getKlass(t.type,i);o.async?o.fromObject(t,function(i,o){o||(s[e]=i,r&&r(t,s[e])),n()}):(s[e]=o.fromObject(t),r&&r(t,s[e]),n())}):void(e&&e(s))},groupSVGElements:function(t,e,i){var r;return r=new fabric.PathGroup(t,e),"undefined"!=typeof i&&r.setSourcePath(i),r},populateWithProperties:function(t,e,i){if(i&&"[object Array]"===Object.prototype.toString.call(i))for(var r=0,n=i.length;n>r;r++)i[r]in t&&(e[i[r]]=t[i[r]])},drawDashedLine:function(t,r,n,s,o,a){var h=s-r,c=o-n,l=e(h*h+c*c),u=i(c,h),f=a.length,d=0,g=!0;for(t.save(),t.translate(r,n),t.moveTo(0,0),t.rotate(u),r=0;l>r;)r+=a[d++%f],r>l&&(r=l),t[g?"lineTo":"moveTo"](r,0),g=!g;t.restore()},createCanvasElement:function(t){return t||(t=fabric.document.createElement("canvas")),t.getContext||"undefined"==typeof G_vmlCanvasManager||G_vmlCanvasManager.initElement(t),t},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(t){for(var e=t.prototype,i=e.stateProperties.length;i--;){var r=e.stateProperties[i],n=r.charAt(0).toUpperCase()+r.slice(1),s="set"+n,o="get"+n;e[o]||(e[o]=function(t){return new Function('return this.get("'+t+'")')}(r)),e[s]||(e[s]=function(t){return new Function("value",'return this.set("'+t+'", value)')}(r))}},clipContext:function(t,e){e.save(),e.beginPath(),t.clipTo(e),e.clip()},multiplyTransformMatrices:function(t,e,i){return[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],i?0:t[0]*e[4]+t[2]*e[5]+t[4],i?0:t[1]*e[4]+t[3]*e[5]+t[5]]},qrDecompose:function(t){var n=i(t[1],t[0]),o=r(t[0],2)+r(t[1],2),a=e(o),h=(t[0]*t[3]-t[2]*t[1])/a,c=i(t[0]*t[2]+t[1]*t[3],o);return{angle:n/s,scaleX:a,scaleY:h,skewX:c/s,skewY:0,translateX:t[4],translateY:t[5]}},customTransformMatrix:function(t,e,i){var r=[1,0,n(Math.tan(i*s)),1],o=[n(t),0,0,n(e)];return fabric.util.multiplyTransformMatrices(o,r,!0)},resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.setAngle(0)},getFunctionBody:function(t){return(String(t).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(t,e,i,r){r>0&&(e>r?e-=r:e=0,i>r?i-=r:i=0);for(var n=!0,s=t.getImageData(e,i,2*r||1,2*r||1),o=3,a=s.data.length;a>o;o+=4){var h=s.data[o];if(n=0>=h,n===!1)break}return s=null,n},parsePreserveAspectRatioAttribute:function(t){var e,i="meet",r="Mid",n="Mid",s=t.split(" ");return s&&s.length&&(i=s.pop(),"meet"!==i&&"slice"!==i?(e=i,i="meet"):s.length&&(e=s.pop())),r="none"!==e?e.slice(1,4):"none",n="none"!==e?e.slice(5,8):"none",{meetOrSlice:i,alignX:r,alignY:n}}}}("undefined"!=typeof exports?exports:this),function(){function t(t,r,s,o,h,c,l){var u=a.call(arguments);if(n[u])return n[u];var f=Math.PI,d=l*f/180,g=Math.sin(d),p=Math.cos(d),v=0,m=0;s=Math.abs(s),o=Math.abs(o);var b=-p*t*.5-g*r*.5,y=-p*r*.5+g*t*.5,_=s*s,x=o*o,S=y*y,C=b*b,w=_*x-_*S-x*C,O=0;if(0>w){var T=Math.sqrt(1-w/(_*x));s*=T,o*=T}else O=(h===c?-1:1)*Math.sqrt(w/(_*S+x*C));var k=O*s*y/o,j=-O*o*b/s,A=p*k-g*j+.5*t,P=g*k+p*j+.5*r,M=i(1,0,(b-k)/s,(y-j)/o),L=i((b-k)/s,(y-j)/o,(-b-k)/s,(-y-j)/o);0===c&&L>0?L-=2*f:1===c&&0>L&&(L+=2*f);for(var D=Math.ceil(Math.abs(L/f*2)),E=[],I=L/D,R=8/3*Math.sin(I/4)*Math.sin(I/4)/Math.sin(I/2),F=M+I,B=0;D>B;B++)E[B]=e(M,F,p,g,s,o,A,P,R,v,m),v=E[B][4],m=E[B][5],M=F,F+=I;return n[u]=E,E}function e(t,e,i,r,n,o,h,c,l,u,f){var d=a.call(arguments);if(s[d])return s[d];var g=Math.cos(t),p=Math.sin(t),v=Math.cos(e),m=Math.sin(e),b=i*n*v-r*o*m+h,y=r*n*v+i*o*m+c,_=u+l*(-i*n*p-r*o*g),x=f+l*(-r*n*p+i*o*g),S=b+l*(i*n*m+r*o*v),C=y+l*(r*n*m-i*o*v);return s[d]=[_,x,S,C,b,y],s[d]}function i(t,e,i,r){var n=Math.atan2(e,t),s=Math.atan2(r,i);return s>=n?s-n:2*Math.PI-(n-s)}function r(t,e,i,r,n,s,h,c){var l=a.call(arguments);if(o[l])return o[l];var u,f,d,g,p,v,m,b,y=Math.sqrt,_=Math.min,x=Math.max,S=Math.abs,C=[],w=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*h,d=3*i-3*t;for(var O=0;2>O;++O)if(O>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*c,d=3*r-3*e),S(u)<1e-12){if(S(f)<1e-12)continue;g=-d/f,g>0&&1>g&&C.push(g)}else m=f*f-4*d*u,0>m||(b=y(m),p=(-f+b)/(2*u),p>0&&1>p&&C.push(p),v=(-f-b)/(2*u),v>0&&1>v&&C.push(v));for(var T,k,j,A=C.length,P=A;A--;)g=C[A],j=1-g,T=j*j*j*t+3*j*j*g*i+3*j*g*g*n+g*g*g*h,w[0][A]=T,k=j*j*j*e+3*j*j*g*r+3*j*g*g*s+g*g*g*c,w[1][A]=k;w[0][P]=t,w[1][P]=e,w[0][P+1]=h,w[1][P+1]=c;var M=[{x:_.apply(null,w[0]),y:_.apply(null,w[1])},{x:x.apply(null,w[0]),y:x.apply(null,w[1])}];return o[l]=M,M}var n={},s={},o={},a=Array.prototype.join;fabric.util.drawArc=function(e,i,r,n){for(var s=n[0],o=n[1],a=n[2],h=n[3],c=n[4],l=n[5],u=n[6],f=[[],[],[],[]],d=t(l-i,u-r,s,o,h,c,a),g=0,p=d.length;p>g;g++)f[g][0]=d[g][0]+i,f[g][1]=d[g][1]+r,f[g][2]=d[g][2]+i,f[g][3]=d[g][3]+r,f[g][4]=d[g][4]+i,f[g][5]=d[g][5]+r,e.bezierCurveTo.apply(e,f[g])},fabric.util.getBoundsOfArc=function(e,i,n,s,o,a,h,c,l){for(var u=0,f=0,d=[],g=[],p=t(c-e,l-i,n,s,a,h,o),v=[[],[]],m=0,b=p.length;b>m;m++)d=r(u,f,p[m][0],p[m][1],p[m][2],p[m][3],p[m][4],p[m][5]),v[0].x=d[0].x+e,v[0].y=d[0].y+i,v[1].x=d[1].x+e,v[1].y=d[1].y+i,g.push(v[0]),g.push(v[1]),u=p[m][4],f=p[m][5];return g},fabric.util.getBoundsOfCurve=r}(),function(){function t(t,e){for(var i=s.call(arguments,2),r=[],n=0,o=t.length;o>n;n++)r[n]=i.length?t[n][e].apply(t[n],i):t[n][e].call(t[n]);return r}function e(t,e){return n(t,e,function(t,e){return t>=e})}function i(t,e){return n(t,e,function(t,e){return e>t})}function r(t,e){for(var i=t.length;i--;)t[i]=e;return t}function n(t,e,i){if(t&&0!==t.length){var r=t.length-1,n=e?t[r][e]:t[r];if(e)for(;r--;)i(t[r][e],n)&&(n=t[r][e]);else for(;r--;)i(t[r],n)&&(n=t[r]);return n}}var s=Array.prototype.slice;Array.prototype.indexOf||(Array.prototype.indexOf=function(t){if(void 0===this||null===this)throw new TypeError;var e=Object(this),i=e.length>>>0;if(0===i)return-1;var r=0;if(arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:0!==r&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r)))),r>=i)return-1;for(var n=r>=0?r:Math.max(i-Math.abs(r),0);i>n;n++)if(n in e&&e[n]===t)return n;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){for(var i=0,r=this.length>>>0;r>i;i++)i in this&&t.call(e,this[i],i,this)}),Array.prototype.map||(Array.prototype.map=function(t,e){for(var i=[],r=0,n=this.length>>>0;n>r;r++)r in this&&(i[r]=t.call(e,this[r],r,this));return i}),Array.prototype.every||(Array.prototype.every=function(t,e){for(var i=0,r=this.length>>>0;r>i;i++)if(i in this&&!t.call(e,this[i],i,this))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t,e){for(var i=0,r=this.length>>>0;r>i;i++)if(i in this&&t.call(e,this[i],i,this))return!0;return!1}),Array.prototype.filter||(Array.prototype.filter=function(t,e){for(var i,r=[],n=0,s=this.length>>>0;s>n;n++)n in this&&(i=this[n],t.call(e,i,n,this)&&r.push(i));return r}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var e,i=this.length>>>0,r=0;if(arguments.length>1)e=arguments[1];else for(;;){if(r in this){e=this[r++];break}if(++r>=i)throw new TypeError}for(;i>r;r++)r in this&&(e=t.call(null,e,this[r],r,this));return e}),fabric.util.array={fill:r,invoke:t,min:i,max:e}}(),function(){function t(t,e){for(var i in e)t[i]=e[i];return t}function e(e){return t({},e)}fabric.util.object={extend:t,clone:e}}(),function(){function t(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})}function e(t,e){return t.charAt(0).toUpperCase()+(e?t.slice(1):t.slice(1).toLowerCase())}function i(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:t,capitalize:e,escapeXml:i}}(),function(){var t=Array.prototype.slice,e=Function.prototype.apply,i=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var n,s=this,o=t.call(arguments,1);return n=o.length?function(){return e.call(s,this instanceof i?this:r,o.concat(t.call(arguments)))}:function(){return e.call(s,this instanceof i?this:r,arguments)},i.prototype=this.prototype,n.prototype=new i,n})}(),function(){function t(){}function e(t){var e=this.constructor.superclass.prototype[t];return arguments.length>1?e.apply(this,r.call(arguments,1)):e.call(this)}function i(){function i(){this.initialize.apply(this,arguments)}var s=null,a=r.call(arguments,0);"function"==typeof a[0]&&(s=a.shift()),i.superclass=s,i.subclasses=[],s&&(t.prototype=s.prototype,i.prototype=new t,s.subclasses.push(i));for(var h=0,c=a.length;c>h;h++)o(i,a[h],s);return i.prototype.initialize||(i.prototype.initialize=n),i.prototype.constructor=i,i.prototype.callSuper=e,i}var r=Array.prototype.slice,n=function(){},s=function(){for(var t in{toString:1})if("toString"===t)return!1;return!0}(),o=function(t,e,i){for(var r in e)t.prototype[r]=r in t.prototype&&"function"==typeof t.prototype[r]&&(e[r]+"").indexOf("callSuper")>-1?function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);return this.constructor.superclass=r,"initialize"!==t?n:void 0}}(r):e[r],s&&(e.toString!==Object.prototype.toString&&(t.prototype.toString=e.toString),e.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=e.valueOf))};fabric.util.createClass=i}(),function(){function t(t){var e,i,r=Array.prototype.slice.call(arguments,1),n=r.length;for(i=0;n>i;i++)if(e=typeof t[r[i]],!/^(?:function|object|unknown)$/.test(e))return!1;return!0}function e(t,e){return{handler:e,wrappedHandler:i(t,e)}}function i(t,e){return function(i){e.call(o(t),i||fabric.window.event)}}function r(t,e){return function(i){if(p[t]&&p[t][e])for(var r=p[t][e],n=0,s=r.length;s>n;n++)r[n].call(this,i||fabric.window.event)}}function n(t){t||(t=fabric.window.event);var e=t.target||(typeof t.srcElement!==h?t.srcElement:null),i=fabric.util.getScrollLeftTop(e);return{x:v(t)+i.left,y:m(t)+i.top}}function s(t,e,i){var r="touchend"===t.type?"changedTouches":"touches";return t[r]&&t[r][0]?t[r][0][e]-(t[r][0][e]-t[r][0][i])||t[i]:t[i]}var o,a,h="unknown",c=function(){var t=0;return function(e){return e.__uniqueID||(e.__uniqueID="uniqueID__"+t++)}}();!function(){var t={};o=function(e){return t[e]},a=function(e,i){t[e]=i}}();var l,u,f=t(fabric.document.documentElement,"addEventListener","removeEventListener")&&t(fabric.window,"addEventListener","removeEventListener"),d=t(fabric.document.documentElement,"attachEvent","detachEvent")&&t(fabric.window,"attachEvent","detachEvent"),g={},p={};f?(l=function(t,e,i){t.addEventListener(e,i,!1)},u=function(t,e,i){t.removeEventListener(e,i,!1)}):d?(l=function(t,i,r){var n=c(t);a(n,t),g[n]||(g[n]={}),g[n][i]||(g[n][i]=[]);var s=e(n,r);g[n][i].push(s),t.attachEvent("on"+i,s.wrappedHandler)},u=function(t,e,i){var r,n=c(t);if(g[n]&&g[n][e])for(var s=0,o=g[n][e].length;o>s;s++)r=g[n][e][s],r&&r.handler===i&&(t.detachEvent("on"+e,r.wrappedHandler),g[n][e][s]=null)}):(l=function(t,e,i){var n=c(t);if(p[n]||(p[n]={}),!p[n][e]){p[n][e]=[];var s=t["on"+e];s&&p[n][e].push(s),t["on"+e]=r(n,e)}p[n][e].push(i)},u=function(t,e,i){var r=c(t);if(p[r]&&p[r][e])for(var n=p[r][e],s=0,o=n.length;o>s;s++)n[s]===i&&n.splice(s,1)}),fabric.util.addListener=l,fabric.util.removeListener=u;var v=function(t){return typeof t.clientX!==h?t.clientX:0},m=function(t){return typeof t.clientY!==h?t.clientY:0};fabric.isTouchSupported&&(v=function(t){return s(t,"pageX","clientX")},m=function(t){return s(t,"pageY","clientY")}),fabric.util.getPointer=n,fabric.util.object.extend(fabric.util,fabric.Observable)}(),function(){function t(t,e){var i=t.style;if(!i)return t;if("string"==typeof e)return t.style.cssText+=";"+e,e.indexOf("opacity")>-1?s(t,e.match(/opacity:\s*(\d?\.?\d*)/)[1]):t;for(var r in e)if("opacity"===r)s(t,e[r]);else{var n="float"===r||"cssFloat"===r?"undefined"==typeof i.styleFloat?"cssFloat":"styleFloat":r;i[n]=e[r]}return t}var e=fabric.document.createElement("div"),i="string"==typeof e.style.opacity,r="string"==typeof e.style.filter,n=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(t){return t};i?s=function(t,e){return t.style.opacity=e,t}:r&&(s=function(t,e){var i=t.style;return t.currentStyle&&!t.currentStyle.hasLayout&&(i.zoom=1),n.test(i.filter)?(e=e>=.9999?"":"alpha(opacity="+100*e+")",i.filter=i.filter.replace(n,e)):i.filter+=" alpha(opacity="+100*e+")",t}),fabric.util.setStyle=t}(),function(){function t(t){return"string"==typeof t?fabric.document.getElementById(t):t}function e(t,e){var i=fabric.document.createElement(t);for(var r in e)"class"===r?i.className=e[r]:"for"===r?i.htmlFor=e[r]:i.setAttribute(r,e[r]);return i}function i(t,e){t&&-1===(" "+t.className+" ").indexOf(" "+e+" ")&&(t.className+=(t.className?" ":"")+e)}function r(t,i,r){return"string"==typeof i&&(i=e(i,r)),t.parentNode&&t.parentNode.replaceChild(i,t),i.appendChild(t),i}function n(t){for(var e=0,i=0,r=fabric.document.documentElement,n=fabric.document.body||{scrollLeft:0,scrollTop:0};t&&(t.parentNode||t.host)&&(t=t.parentNode||t.host,t===fabric.document?(e=n.scrollLeft||r.scrollLeft||0,i=n.scrollTop||r.scrollTop||0):(e+=t.scrollLeft||0,i+=t.scrollTop||0),1!==t.nodeType||"fixed"!==fabric.util.getElementStyle(t,"position")););return{left:e,top:i}}function s(t){var e,i,r=t&&t.ownerDocument,s={left:0,top:0},o={left:0,top:0},a={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!r)return o;for(var h in a)o[a[h]]+=parseInt(l(t,h),10)||0;return e=r.documentElement,"undefined"!=typeof t.getBoundingClientRect&&(s=t.getBoundingClientRect()),i=n(t),{left:s.left+i.left-(e.clientLeft||0)+o.left,top:s.top+i.top-(e.clientTop||0)+o.top}}var o,a=Array.prototype.slice,h=function(t){return a.call(t,0)};try{o=h(fabric.document.childNodes)instanceof Array}catch(c){}o||(h=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var l;l=fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?function(t,e){var i=fabric.document.defaultView.getComputedStyle(t,null);return i?i[e]:void 0}:function(t,e){var i=t.style[e];return!i&&t.currentStyle&&(i=t.currentStyle[e]),i},function(){function t(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=fabric.util.falseFunction),r?t.style[r]="none":"string"==typeof t.unselectable&&(t.unselectable="on"),t}function e(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=null),r?t.style[r]="":"string"==typeof t.unselectable&&(t.unselectable=""),t}var i=fabric.document.documentElement.style,r="userSelect"in i?"userSelect":"MozUserSelect"in i?"MozUserSelect":"WebkitUserSelect"in i?"WebkitUserSelect":"KhtmlUserSelect"in i?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=t,fabric.util.makeElementSelectable=e}(),function(){function t(t,e){var i=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),n=!0;r.onload=r.onreadystatechange=function(t){if(n){if("string"==typeof this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)return;n=!1,e(t||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=t,i.appendChild(r)}fabric.util.getScript=t}(),fabric.util.getById=t,fabric.util.toArray=h,fabric.util.makeElement=e,fabric.util.addClass=i,fabric.util.wrapElement=r,fabric.util.getScrollLeftTop=n,fabric.util.getElementOffset=s,fabric.util.getElementStyle=l}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}function i(i,n){n||(n={});var s,o=n.method?n.method.toUpperCase():"GET",a=n.onComplete||function(){},h=r();return h.onreadystatechange=function(){4===h.readyState&&(a(h),h.onreadystatechange=e)},"GET"===o&&(s=null,"string"==typeof n.parameters&&(i=t(i,n.parameters))),h.open(o,i,!0),("POST"===o||"PUT"===o)&&h.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),h.send(s),h}var r=function(){for(var t=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}],e=t.length;e--;)try{var i=t[e]();if(i)return t[e]}catch(r){}}();fabric.util.request=i}(),fabric.log=function(){},fabric.warn=function(){},"undefined"!=typeof console&&["log","warn"].forEach(function(t){"undefined"!=typeof console[t]&&"function"==typeof console[t].apply&&(fabric[t]=function(){return console[t].apply(console,arguments)})}),function(){function t(t){e(function(i){t||(t={});var r,n=i||+new Date,s=t.duration||500,o=n+s,a=t.onChange||function(){},h=t.abort||function(){return!1},c=t.easing||function(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e},l="startValue"in t?t.startValue:0,u="endValue"in t?t.endValue:100,f=t.byValue||u-l;t.onStart&&t.onStart(),function d(i){r=i||+new Date;var u=r>o?s:r-n;return h()?void(t.onComplete&&t.onComplete()):(a(c(u,l,f,s)),r>o?void(t.onComplete&&t.onComplete()):void e(d))}(n)})}function e(){return i.apply(fabric.window,arguments)}var i=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(t){fabric.window.setTimeout(t,1e3/60)};fabric.util.animate=t,fabric.util.requestAnimFrame=e}(),function(){function t(t,e,i,r){return tt?i/2*t*t*t+e:i/2*((t-=2)*t*t+2)+e}function n(t,e,i,r){return i*(t/=r)*t*t*t+e}function s(t,e,i,r){return-i*((t=t/r-1)*t*t*t-1)+e}function o(t,e,i,r){return t/=r/2,1>t?i/2*t*t*t*t+e:-i/2*((t-=2)*t*t*t-2)+e}function a(t,e,i,r){return i*(t/=r)*t*t*t*t+e}function h(t,e,i,r){return i*((t=t/r-1)*t*t*t*t+1)+e}function c(t,e,i,r){return t/=r/2,1>t?i/2*t*t*t*t*t+e:i/2*((t-=2)*t*t*t*t+2)+e}function l(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e}function u(t,e,i,r){return i*Math.sin(t/r*(Math.PI/2))+e}function f(t,e,i,r){return-i/2*(Math.cos(Math.PI*t/r)-1)+e}function d(t,e,i,r){return 0===t?e:i*Math.pow(2,10*(t/r-1))+e}function g(t,e,i,r){return t===r?e+i:i*(-Math.pow(2,-10*t/r)+1)+e}function p(t,e,i,r){return 0===t?e:t===r?e+i:(t/=r/2,1>t?i/2*Math.pow(2,10*(t-1))+e:i/2*(-Math.pow(2,-10*--t)+2)+e)}function v(t,e,i,r){return-i*(Math.sqrt(1-(t/=r)*t)-1)+e}function m(t,e,i,r){return i*Math.sqrt(1-(t=t/r-1)*t)+e}function b(t,e,i,r){return t/=r/2,1>t?-i/2*(Math.sqrt(1-t*t)-1)+e:i/2*(Math.sqrt(1-(t-=2)*t)+1)+e}function y(i,r,n,s){var o=1.70158,a=0,h=n;if(0===i)return r;if(i/=s,1===i)return r+n;a||(a=.3*s);var c=t(h,n,a,o);return-e(c,i,s)+r}function _(e,i,r,n){var s=1.70158,o=0,a=r;if(0===e)return i;if(e/=n,1===e)return i+r;o||(o=.3*n);var h=t(a,r,o,s);return h.a*Math.pow(2,-10*e)*Math.sin(2*(e*n-h.s)*Math.PI/h.p)+h.c+i}function x(i,r,n,s){var o=1.70158,a=0,h=n;if(0===i)return r;if(i/=s/2,2===i)return r+n;a||(a=.3*s*1.5);var c=t(h,n,a,o);return 1>i?-.5*e(c,i,s)+r:c.a*Math.pow(2,-10*(i-=1))*Math.sin(2*(i*s-c.s)*Math.PI/c.p)*.5+c.c+r}function S(t,e,i,r,n){return void 0===n&&(n=1.70158),i*(t/=r)*t*((n+1)*t-n)+e}function C(t,e,i,r,n){return void 0===n&&(n=1.70158),i*((t=t/r-1)*t*((n+1)*t+n)+1)+e}function w(t,e,i,r,n){return void 0===n&&(n=1.70158),t/=r/2,1>t?i/2*t*t*(((n*=1.525)+1)*t-n)+e:i/2*((t-=2)*t*(((n*=1.525)+1)*t+n)+2)+e}function O(t,e,i,r){return i-T(r-t,0,i,r)+e}function T(t,e,i,r){return(t/=r)<1/2.75?7.5625*i*t*t+e:2/2.75>t?i*(7.5625*(t-=1.5/2.75)*t+.75)+e:2.5/2.75>t?i*(7.5625*(t-=2.25/2.75)*t+.9375)+e:i*(7.5625*(t-=2.625/2.75)*t+.984375)+e}function k(t,e,i,r){return r/2>t?.5*O(2*t,0,i,r)+e:.5*T(2*t-r,0,i,r)+.5*i+e}fabric.util.ease={easeInQuad:function(t,e,i,r){return i*(t/=r)*t+e},easeOutQuad:function(t,e,i,r){return-i*(t/=r)*(t-2)+e},easeInOutQuad:function(t,e,i,r){return t/=r/2,1>t?i/2*t*t+e:-i/2*(--t*(t-2)-1)+e},easeInCubic:function(t,e,i,r){return i*(t/=r)*t*t+e},easeOutCubic:i,easeInOutCubic:r,easeInQuart:n,easeOutQuart:s,easeInOutQuart:o,easeInQuint:a,easeOutQuint:h,easeInOutQuint:c,easeInSine:l,easeOutSine:u,easeInOutSine:f,easeInExpo:d,easeOutExpo:g,easeInOutExpo:p,easeInCirc:v,easeOutCirc:m,easeInOutCirc:b,easeInElastic:y,easeOutElastic:_,easeInOutElastic:x,easeInBack:S,easeOutBack:C,easeInOutBack:w,easeInBounce:O,easeOutBounce:T,easeInOutBounce:k}}(),function(t){"use strict";function e(t){return t in T?T[t]:t}function i(t,e,i,r){var n,s="[object Array]"===Object.prototype.toString.call(e);return"fill"!==t&&"stroke"!==t||"none"!==e?"strokeDashArray"===t?e=e.replace(/,/g," ").split(/\s+/).map(function(t){return parseFloat(t)}):"transformMatrix"===t?e=i&&i.transformMatrix?x(i.transformMatrix,p.parseTransformAttribute(e)):p.parseTransformAttribute(e):"visible"===t?(e="none"===e||"hidden"===e?!1:!0,i&&i.visible===!1&&(e=!1)):"originX"===t?e="start"===e?"left":"end"===e?"right":"center":n=s?e.map(_):_(e,r):e="",!s&&isNaN(n)?e:n}function r(t){for(var e in k)if("undefined"!=typeof t[k[e]]&&""!==t[e]){if("undefined"==typeof t[e]){if(!p.Object.prototype[e])continue;t[e]=p.Object.prototype[e]}if(0!==t[e].indexOf("url(")){var i=new p.Color(t[e]);t[e]=i.setAlpha(y(i.getAlpha()*t[k[e]],2)).toRgba()}}return t}function n(t,r){var n,s;t.replace(/;\s*$/,"").split(";").forEach(function(t){var o=t.split(":");n=e(o[0].trim().toLowerCase()),s=i(n,o[1].trim()),r[n]=s})}function s(t,r){var n,s;for(var o in t)"undefined"!=typeof t[o]&&(n=e(o.toLowerCase()),s=i(n,t[o]),r[n]=s)}function o(t,e){var i={};for(var r in p.cssRules[e])if(a(t,r.split(" ")))for(var n in p.cssRules[e][r])i[n]=p.cssRules[e][r][n];return i}function a(t,e){var i,r=!0;return i=c(t,e.pop()),i&&e.length&&(r=h(t,e)),i&&r&&0===e.length}function h(t,e){for(var i,r=!0;t.parentNode&&1===t.parentNode.nodeType&&e.length;)r&&(i=e.pop()),t=t.parentNode,r=c(t,i);return 0===e.length}function c(t,e){var i,r=t.nodeName,n=t.getAttribute("class"),s=t.getAttribute("id");if(i=new RegExp("^"+r,"i"),e=e.replace(i,""),s&&e.length&&(i=new RegExp("#"+s+"(?![a-zA-Z\\-]+)","i"),e=e.replace(i,"")),n&&e.length){n=n.split(" ");for(var o=n.length;o--;)i=new RegExp("\\."+n[o]+"(?![a-zA-Z\\-]+)","i"),e=e.replace(i,"")}return 0===e.length}function l(t,e){var i;if(t.getElementById&&(i=t.getElementById(e)),i)return i;var r,n,s=t.getElementsByTagName("*");for(n=0;ns;s++)n=o.item(s),m.setAttribute(n.nodeName,n.nodeValue);for(;null!=g.firstChild;)m.appendChild(g.firstChild);g=m}for(s=0,o=h.attributes,a=o.length;a>s;s++)n=o.item(s),"x"!==n.nodeName&&"y"!==n.nodeName&&"xlink:href"!==n.nodeName&&("transform"===n.nodeName?p=n.nodeValue+" "+p:g.setAttribute(n.nodeName,n.nodeValue));g.setAttribute("transform",p),g.setAttribute("instantiated_by_use","1"),g.removeAttribute("id"),r=h.parentNode,r.replaceChild(g,h),e.length===v&&i++}}function f(t){var e,i,r,n,s=t.getAttribute("viewBox"),o=1,a=1,h=0,c=0,l=t.getAttribute("width"),u=t.getAttribute("height"),f=t.getAttribute("x")||0,d=t.getAttribute("y")||0,g=t.getAttribute("preserveAspectRatio")||"",v=!s||!C.test(t.tagName)||!(s=s.match(j)),m=!l||!u||"100%"===l||"100%"===u,b=v&&m,y={},x="";if(y.width=0,y.height=0,y.toBeParsed=b,b)return y;if(v)return y.width=_(l),y.height=_(u),y;if(h=-parseFloat(s[1]),c=-parseFloat(s[2]),e=parseFloat(s[3]),i=parseFloat(s[4]),m?(y.width=e,y.height=i):(y.width=_(l),y.height=_(u),o=y.width/e,a=y.height/i),g=p.util.parsePreserveAspectRatioAttribute(g),"none"!==g.alignX&&(a=o=o>a?a:o),1===o&&1===a&&0===h&&0===c&&0===f&&0===d)return y;if((f||d)&&(x=" translate("+_(f)+" "+_(d)+") "),r=x+" matrix("+o+" 0 0 "+a+" "+h*o+" "+c*a+") ","svg"===t.tagName){for(n=t.ownerDocument.createElement("g");null!=t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else n=t,r=n.getAttribute("transform")+r;return n.setAttribute("transform",r),y}function d(t){var e=t.objects,i=t.options;return e=e.map(function(t){return p[m(t.type)].fromObject(t)}),{objects:e,options:i}}function g(t,e,i){e[i]&&e[i].toSVG&&t.push(' \n',' \n \n')}var p=t.fabric||(t.fabric={}),v=p.util.object.extend,m=p.util.string.capitalize,b=p.util.object.clone,y=p.util.toFixed,_=p.util.parseUnit,x=p.util.multiplyTransformMatrices,S=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,C=/^(symbol|image|marker|pattern|view|svg)$/i,w=/^(?:pattern|defs|symbol|metadata)$/i,O=/^(symbol|g|a|svg)$/i,T={cx:"left",x:"left",r:"radius",cy:"top",y:"top",display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"originX"},k={stroke:"strokeOpacity",fill:"fillOpacity"};p.cssRules={},p.gradientDefs={},p.parseTransformAttribute=function(){function t(t,e){var i=e[0],r=3===e.length?e[1]:0,n=3===e.length?e[2]:0;t[0]=Math.cos(i),t[1]=Math.sin(i),t[2]=-Math.sin(i),t[3]=Math.cos(i),t[4]=r-(t[0]*r+t[2]*n),t[5]=n-(t[1]*r+t[3]*n)}function e(t,e){var i=e[0],r=2===e.length?e[1]:e[0];t[0]=i,t[3]=r}function i(t,e){t[2]=Math.tan(p.util.degreesToRadians(e[0]))}function r(t,e){t[1]=Math.tan(p.util.degreesToRadians(e[0]))}function n(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var s=[1,0,0,1,0,0],o=p.reNum,a="(?:\\s+,?\\s*|,\\s*)",h="(?:(skewX)\\s*\\(\\s*("+o+")\\s*\\))",c="(?:(skewY)\\s*\\(\\s*("+o+")\\s*\\))",l="(?:(rotate)\\s*\\(\\s*("+o+")(?:"+a+"("+o+")"+a+"("+o+"))?\\s*\\))",u="(?:(scale)\\s*\\(\\s*("+o+")(?:"+a+"("+o+"))?\\s*\\))",f="(?:(translate)\\s*\\(\\s*("+o+")(?:"+a+"("+o+"))?\\s*\\))",d="(?:(matrix)\\s*\\(\\s*("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")\\s*\\))",g="(?:"+d+"|"+f+"|"+u+"|"+l+"|"+h+"|"+c+")",v="(?:"+g+"(?:"+a+"*"+g+")*)",m="^\\s*(?:"+v+"?)\\s*$",b=new RegExp(m),y=new RegExp(g,"g"); - -return function(o){var a=s.concat(),h=[];if(!o||o&&!b.test(o))return a;o.replace(y,function(o){var c=new RegExp(g).exec(o).filter(function(t){return""!==t&&null!=t}),l=c[1],u=c.slice(2).map(parseFloat);switch(l){case"translate":n(a,u);break;case"rotate":u[0]=p.util.degreesToRadians(u[0]),t(a,u);break;case"scale":e(a,u);break;case"skewX":i(a,u);break;case"skewY":r(a,u);break;case"matrix":a=u}h.push(a.concat()),a=s.concat()});for(var c=h[0];h.length>1;)h.shift(),c=p.util.multiplyTransformMatrices(c,h[0]);return c}}();var j=new RegExp("^\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*$");p.parseSVGDocument=function(){function t(t,e){for(;t&&(t=t.parentNode);)if(e.test(t.nodeName)&&!t.getAttribute("instantiated_by_use"))return!0;return!1}return function(e,i,r){if(e){u(e);var n=new Date,s=p.Object.__uid++,o=f(e),a=p.util.toArray(e.getElementsByTagName("*"));if(o.svgUid=s,0===a.length&&p.isLikelyNode){a=e.selectNodes('//*[name(.)!="svg"]');for(var h=[],c=0,l=a.length;l>c;c++)h[c]=a[c];a=h}var d=a.filter(function(e){return f(e),S.test(e.tagName)&&!t(e,w)});if(!d||d&&!d.length)return void(i&&i([],{}));p.gradientDefs[s]=p.getGradientDefs(e),p.cssRules[s]=p.getCSSRules(e),p.parseElements(d,function(t){p.documentParsingTime=new Date-n,i&&i(t,o)},b(o),r)}}}();var A={has:function(t,e){e(!1)},get:function(){},set:function(){}},P=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+p.reNum+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+p.reNum+"))?\\s+(.*)");v(p,{parseFontDeclaration:function(t,e){var i=t.match(P);if(i){var r=i[1],n=i[3],s=i[4],o=i[5],a=i[6];r&&(e.fontStyle=r),n&&(e.fontWeight=isNaN(parseFloat(n))?n:parseFloat(n)),s&&(e.fontSize=_(s)),a&&(e.fontFamily=a),o&&(e.lineHeight="normal"===o?1:o)}},getGradientDefs:function(t){var e,i,r,n,s=t.getElementsByTagName("linearGradient"),o=t.getElementsByTagName("radialGradient"),a=0,h=[],c={},l={};for(h.length=s.length+o.length,i=s.length;i--;)h[a++]=s[i];for(i=o.length;i--;)h[a++]=o[i];for(;a--;)e=h[a],n=e.getAttribute("xlink:href"),r=e.getAttribute("id"),n&&(l[r]=n.substr(1)),c[r]=e;for(r in l){var u=c[l[r]].cloneNode(!0);for(e=c[r];u.firstChild;)e.appendChild(u.firstChild)}return c},parseAttributes:function(t,n,s){if(t){var a,h,c={};"undefined"==typeof s&&(s=t.getAttribute("svgUid")),t.parentNode&&O.test(t.parentNode.nodeName)&&(c=p.parseAttributes(t.parentNode,n,s)),h=c&&c.fontSize||t.getAttribute("font-size")||p.Text.DEFAULT_SVG_FONT_SIZE;var l=n.reduce(function(r,n){return a=t.getAttribute(n),a&&(n=e(n),a=i(n,a,c,h),r[n]=a),r},{});return l=v(l,v(o(t,s),p.parseStyleAttribute(t))),l.font&&p.parseFontDeclaration(l.font,l),r(v(c,l))}},parseElements:function(t,e,i,r){new p.ElementsParser(t,e,i,r).parse()},parseStyleAttribute:function(t){var e={},i=t.getAttribute("style");return i?("string"==typeof i?n(i,e):s(i,e),e):e},parsePointsAttribute:function(t){if(!t)return null;t=t.replace(/,/g," ").trim(),t=t.split(/\s+/);var e,i,r=[];for(e=0,i=t.length;i>e;e+=2)r.push({x:parseFloat(t[e]),y:parseFloat(t[e+1])});return r},getCSSRules:function(t){for(var r,n=t.getElementsByTagName("style"),s={},o=0,a=n.length;a>o;o++){var h=n[o].textContent||n[o].text;h=h.replace(/\/\*[\s\S]*?\*\//g,""),""!==h.trim()&&(r=h.match(/[^{]*\{[\s\S]*?\}/g),r=r.map(function(t){return t.trim()}),r.forEach(function(t){for(var r=t.match(/([\s\S]*?)\s*\{([^}]*)\}/),n={},o=r[2].trim(),a=o.replace(/;$/,"").split(/\s*;\s*/),h=0,c=a.length;c>h;h++){var l=a[h].split(/\s*:\s*/),u=e(l[0]),f=i(u,l[1],l[0]);n[u]=f}t=r[1],t.split(",").forEach(function(t){t=t.replace(/^svg/i,"").trim(),""!==t&&(s[t]=p.util.object.clone(n))})}))}return s},loadSVGFromURL:function(t,e,i){function r(r){var n=r.responseXML;n&&!n.documentElement&&p.window.ActiveXObject&&r.responseText&&(n=new ActiveXObject("Microsoft.XMLDOM"),n.async="false",n.loadXML(r.responseText.replace(//i,""))),n&&n.documentElement&&p.parseSVGDocument(n.documentElement,function(i,r){A.set(t,{objects:p.util.array.invoke(i,"toObject"),options:r}),e(i,r)},i)}t=t.replace(/^\n\s*/,"").trim(),A.has(t,function(i){i?A.get(t,function(t){var i=d(t);e(i.objects,i.options)}):new p.util.request(t,{method:"get",onComplete:r})})},loadSVGFromString:function(t,e,i){t=t.trim();var r;if("undefined"!=typeof DOMParser){var n=new DOMParser;n&&n.parseFromString&&(r=n.parseFromString(t,"text/xml"))}else p.window.ActiveXObject&&(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(t.replace(//i,"")));p.parseSVGDocument(r.documentElement,function(t,i){e(t,i)},i)},createSVGFontFacesMarkup:function(t){for(var e,i,r,n,s,o,a,h="",c={},l=p.fontPaths,u=0,f=t.length;f>u;u++)if(e=t[u],i=e.fontFamily,-1!==e.type.indexOf("text")&&!c[i]&&l[i]&&(c[i]=!0,e.styles)){r=e.styles;for(s in r){o=r[s];for(a in n)o=n[a],i=o.fontFamily,!c[i]&&l[i]&&(c[i]=!0)}}for(var d in c)h+=[" @font-face {\n"," font-family: '",d,"';\n"," src: url('",l[d],"');\n"," }\n"].join("");return h&&(h=[' \n"].join("")),h},createSVGRefElementsMarkup:function(t){var e=[];return g(e,t,"backgroundColor"),g(e,t,"overlayColor"),e.join("")}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;e>t;t++)this.elements[t].setAttribute("svgUid",this.svgUid),function(t,e){setTimeout(function(){t.createObject(t.elements[e],e)},0)}(this,t)},fabric.ElementsParser.prototype.createObject=function(t,e){var i=fabric[fabric.util.string.capitalize(t.tagName)];if(i&&i.fromElement)try{this._createObject(i,t,e)}catch(r){fabric.log(r)}else this.checkIfDone()},fabric.ElementsParser.prototype._createObject=function(t,e,i){if(t.async)t.fromElement(e,this.createCallback(i,e),this.options);else{var r=t.fromElement(e,this.options);this.resolveGradient(r,"fill"),this.resolveGradient(r,"stroke"),this.reviver&&this.reviver(e,r),this.instances[i]=r,this.checkIfDone()}},fabric.ElementsParser.prototype.createCallback=function(t,e){var i=this;return function(r){i.resolveGradient(r,"fill"),i.resolveGradient(r,"stroke"),i.reviver&&i.reviver(e,r),i.instances[t]=r,i.checkIfDone()}},fabric.ElementsParser.prototype.resolveGradient=function(t,e){var i=t.get(e);if(/^url\(/.test(i)){var r=i.slice(5,i.length-1);fabric.gradientDefs[this.svgUid][r]&&t.set(e,fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][r],t))}},fabric.ElementsParser.prototype.checkIfDone=function(){0===--this.numElements&&(this.instances=this.instances.filter(function(t){return null!=t}),this.callback(this.instances))},function(t){"use strict";function e(t,e){this.x=t,this.y=e}var i=t.fabric||(t.fabric={});return i.Point?void i.warn("fabric.Point is already defined"):(i.Point=e,void(e.prototype={constructor:e,add:function(t){return new e(this.x+t.x,this.y+t.y)},addEquals:function(t){return this.x+=t.x,this.y+=t.y,this},scalarAdd:function(t){return new e(this.x+t,this.y+t)},scalarAddEquals:function(t){return this.x+=t,this.y+=t,this},subtract:function(t){return new e(this.x-t.x,this.y-t.y)},subtractEquals:function(t){return this.x-=t.x,this.y-=t.y,this},scalarSubtract:function(t){return new e(this.x-t,this.y-t)},scalarSubtractEquals:function(t){return this.x-=t,this.y-=t,this},multiply:function(t){return new e(this.x*t,this.y*t)},multiplyEquals:function(t){return this.x*=t,this.y*=t,this},divide:function(t){return new e(this.x/t,this.y/t)},divideEquals:function(t){return this.x/=t,this.y/=t,this},eq:function(t){return this.x===t.x&&this.y===t.y},lt:function(t){return this.xt.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,i){return new e(this.x+(t.x-this.x)*i,this.y+(t.y-this.y)*i)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return new e(this.x+(t.x-this.x)/2,this.y+(t.y-this.y)/2)},min:function(t){return new e(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new e(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){this.x=t,this.y=e},setFromPoint:function(t){this.x=t.x,this.y=t.y},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i}}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){this.status=t,this.points=[]}var i=t.fabric||(t.fabric={});return i.Intersection?void i.warn("fabric.Intersection is already defined"):(i.Intersection=e,i.Intersection.prototype={appendPoint:function(t){this.points.push(t)},appendPoints:function(t){this.points=this.points.concat(t)}},i.Intersection.intersectLineLine=function(t,r,n,s){var o,a=(s.x-n.x)*(t.y-n.y)-(s.y-n.y)*(t.x-n.x),h=(r.x-t.x)*(t.y-n.y)-(r.y-t.y)*(t.x-n.x),c=(s.y-n.y)*(r.x-t.x)-(s.x-n.x)*(r.y-t.y);if(0!==c){var l=a/c,u=h/c;l>=0&&1>=l&&u>=0&&1>=u?(o=new e("Intersection"),o.points.push(new i.Point(t.x+l*(r.x-t.x),t.y+l*(r.y-t.y)))):o=new e}else o=new e(0===a||0===h?"Coincident":"Parallel");return o},i.Intersection.intersectLinePolygon=function(t,i,r){for(var n=new e,s=r.length,o=0;s>o;o++){var a=r[o],h=r[(o+1)%s],c=e.intersectLineLine(t,i,a,h);n.appendPoints(c.points)}return n.points.length>0&&(n.status="Intersection"),n},i.Intersection.intersectPolygonPolygon=function(t,i){for(var r=new e,n=t.length,s=0;n>s;s++){var o=t[s],a=t[(s+1)%n],h=e.intersectLinePolygon(o,a,i);r.appendPoints(h.points)}return r.points.length>0&&(r.status="Intersection"),r},void(i.Intersection.intersectPolygonRectangle=function(t,r,n){var s=r.min(n),o=r.max(n),a=new i.Point(o.x,s.y),h=new i.Point(s.x,o.y),c=e.intersectLinePolygon(s,a,t),l=e.intersectLinePolygon(a,o,t),u=e.intersectLinePolygon(o,h,t),f=e.intersectLinePolygon(h,s,t),d=new e;return d.appendPoints(c.points),d.appendPoints(l.points),d.appendPoints(u.points),d.appendPoints(f.points),d.points.length>0&&(d.status="Intersection"),d}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){t?this._tryParsingColor(t):this.setSource([0,0,0,1])}function i(t,e,i){return 0>i&&(i+=1),i>1&&(i-=1),1/6>i?t+6*(e-t)*i:.5>i?e:2/3>i?t+(e-t)*(2/3-i)*6:t}var r=t.fabric||(t.fabric={});return r.Color?void r.warn("fabric.Color is already defined."):(r.Color=e,r.Color.prototype={_tryParsingColor:function(t){var i;return t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t?void this.setSource([255,255,255,0]):(i=e.sourceFromHex(t),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),void(i&&this.setSource(i)))},_rgbToHsl:function(t,e,i){t/=255,e/=255,i/=255;var n,s,o,a=r.util.array.max([t,e,i]),h=r.util.array.min([t,e,i]);if(o=(a+h)/2,a===h)n=s=0;else{var c=a-h;switch(s=o>.5?c/(2-a-h):c/(a+h),a){case t:n=(e-i)/c+(i>e?6:0);break;case e:n=(i-t)/c+2;break;case i:n=(t-e)/c+4}n/=6}return[Math.round(360*n),Math.round(100*s),Math.round(100*o)]},getSource:function(){return this._source},setSource:function(t){this._source=t},toRgb:function(){var t=this.getSource();return"rgb("+t[0]+","+t[1]+","+t[2]+")"},toRgba:function(){var t=this.getSource();return"rgba("+t[0]+","+t[1]+","+t[2]+","+t[3]+")"},toHsl:function(){var t=this.getSource(),e=this._rgbToHsl(t[0],t[1],t[2]);return"hsl("+e[0]+","+e[1]+"%,"+e[2]+"%)"},toHsla:function(){var t=this.getSource(),e=this._rgbToHsl(t[0],t[1],t[2]);return"hsla("+e[0]+","+e[1]+"%,"+e[2]+"%,"+t[3]+")"},toHex:function(){var t,e,i,r=this.getSource();return t=r[0].toString(16),t=1===t.length?"0"+t:t,e=r[1].toString(16),e=1===e.length?"0"+e:e,i=r[2].toString(16),i=1===i.length?"0"+i:i,t.toUpperCase()+e.toUpperCase()+i.toUpperCase()},getAlpha:function(){return this.getSource()[3]},setAlpha:function(t){var e=this.getSource();return e[3]=t,this.setSource(e),this},toGrayscale:function(){var t=this.getSource(),e=parseInt((.3*t[0]+.59*t[1]+.11*t[2]).toFixed(0),10),i=t[3];return this.setSource([e,e,e,i]),this},toBlackWhite:function(t){var e=this.getSource(),i=(.3*e[0]+.59*e[1]+.11*e[2]).toFixed(0),r=e[3];return t=t||127,i=Number(i)a;a++)i.push(Math.round(s[a]*(1-n)+o[a]*n));return i[3]=r,this.setSource(i),this}},r.Color.reRGBa=/^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/,r.Color.reHSLa=/^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/,r.Color.reHex=/^#?([0-9a-f]{6}|[0-9a-f]{3})$/i,r.Color.colorNameMap={aqua:"#00FFFF",black:"#000000",blue:"#0000FF",fuchsia:"#FF00FF",gray:"#808080",green:"#008000",lime:"#00FF00",maroon:"#800000",navy:"#000080",olive:"#808000",orange:"#FFA500",purple:"#800080",red:"#FF0000",silver:"#C0C0C0",teal:"#008080",white:"#FFFFFF",yellow:"#FFFF00"},r.Color.fromRgb=function(t){return e.fromSource(e.sourceFromRgb(t))},r.Color.sourceFromRgb=function(t){var i=t.match(e.reRGBa);if(i){var r=parseInt(i[1],10)/(/%$/.test(i[1])?100:1)*(/%$/.test(i[1])?255:1),n=parseInt(i[2],10)/(/%$/.test(i[2])?100:1)*(/%$/.test(i[2])?255:1),s=parseInt(i[3],10)/(/%$/.test(i[3])?100:1)*(/%$/.test(i[3])?255:1);return[parseInt(r,10),parseInt(n,10),parseInt(s,10),i[4]?parseFloat(i[4]):1]}},r.Color.fromRgba=e.fromRgb,r.Color.fromHsl=function(t){return e.fromSource(e.sourceFromHsl(t))},r.Color.sourceFromHsl=function(t){var r=t.match(e.reHSLa);if(r){var n,s,o,a=(parseFloat(r[1])%360+360)%360/360,h=parseFloat(r[2])/(/%$/.test(r[2])?100:1),c=parseFloat(r[3])/(/%$/.test(r[3])?100:1);if(0===h)n=s=o=c;else{var l=.5>=c?c*(h+1):c+h-c*h,u=2*c-l;n=i(u,l,a+1/3),s=i(u,l,a),o=i(u,l,a-1/3)}return[Math.round(255*n),Math.round(255*s),Math.round(255*o),r[4]?parseFloat(r[4]):1]}},r.Color.fromHsla=e.fromHsl,r.Color.fromHex=function(t){return e.fromSource(e.sourceFromHex(t))},r.Color.sourceFromHex=function(t){if(t.match(e.reHex)){var i=t.slice(t.indexOf("#")+1),r=3===i.length,n=r?i.charAt(0)+i.charAt(0):i.substring(0,2),s=r?i.charAt(1)+i.charAt(1):i.substring(2,4),o=r?i.charAt(2)+i.charAt(2):i.substring(4,6);return[parseInt(n,16),parseInt(s,16),parseInt(o,16),1]}},void(r.Color.fromSource=function(t){var i=new e;return i.setSource(t),i}))}("undefined"!=typeof exports?exports:this),function(){function t(t){var e,i,r,n=t.getAttribute("style"),s=t.getAttribute("offset")||0;if(s=parseFloat(s)/(/%$/.test(s)?100:1),s=0>s?0:s>1?1:s,n){var o=n.split(/\s*;\s*/);""===o[o.length-1]&&o.pop();for(var a=o.length;a--;){var h=o[a].split(/\s*:\s*/),c=h[0].trim(),l=h[1].trim();"stop-color"===c?e=l:"stop-opacity"===c&&(r=l)}}return e||(e=t.getAttribute("stop-color")||"rgb(0,0,0)"),r||(r=t.getAttribute("stop-opacity")),e=new fabric.Color(e),i=e.getAlpha(),r=isNaN(parseFloat(r))?1:parseFloat(r),r*=i,{offset:s,color:e.toRgb(),opacity:r}}function e(t){return{x1:t.getAttribute("x1")||0,y1:t.getAttribute("y1")||0,x2:t.getAttribute("x2")||"100%",y2:t.getAttribute("y2")||0}}function i(t){return{x1:t.getAttribute("fx")||t.getAttribute("cx")||"50%",y1:t.getAttribute("fy")||t.getAttribute("cy")||"50%",r1:0,x2:t.getAttribute("cx")||"50%",y2:t.getAttribute("cy")||"50%",r2:t.getAttribute("r")||"50%"}}function r(t,e,i){var r,n=0,s=1,o="";for(var a in e)r=parseFloat(e[a],10),s="string"==typeof e[a]&&/^\d+%$/.test(e[a])?.01:1,"x1"===a||"x2"===a||"r2"===a?(s*="objectBoundingBox"===i?t.width:1,n="objectBoundingBox"===i?t.left||0:0):("y1"===a||"y2"===a)&&(s*="objectBoundingBox"===i?t.height:1,n="objectBoundingBox"===i?t.top||0:0),e[a]=r*s+n;if("ellipse"===t.type&&null!==e.r2&&"objectBoundingBox"===i&&t.rx!==t.ry){var h=t.ry/t.rx;o=" scale(1, "+h+")",e.y1&&(e.y1/=h),e.y2&&(e.y2/=h)}return o}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(t){t||(t={});var e={};this.id=fabric.Object.__uid++,this.type=t.type||"linear",e={x1:t.coords.x1||0,y1:t.coords.y1||0,x2:t.coords.x2||0,y2:t.coords.y2||0},"radial"===this.type&&(e.r1=t.coords.r1||0,e.r2=t.coords.r2||0),this.coords=e,this.colorStops=t.colorStops.slice(),t.gradientTransform&&(this.gradientTransform=t.gradientTransform),this.offsetX=t.offsetX||this.offsetX,this.offsetY=t.offsetY||this.offsetY},addColorStop:function(t){for(var e in t){var i=new fabric.Color(t[e]);this.colorStops.push({offset:e,color:i.toRgb(),opacity:i.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform}},toSVG:function(t){var e,i,r=fabric.util.object.clone(this.coords);if(this.colorStops.sort(function(t,e){return t.offset-e.offset}),!t.group||"path-group"!==t.group.type)for(var n in r)"x1"===n||"x2"===n||"r2"===n?r[n]+=this.offsetX-t.width/2:("y1"===n||"y2"===n)&&(r[n]+=this.offsetY-t.height/2);i='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(i+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),"linear"===this.type?e=["\n']:"radial"===this.type&&(e=["\n']);for(var s=0;s\n');return e.push("linear"===this.type?"\n":"\n"),e.join("")},toLive:function(t,e){var i,r,n=fabric.util.object.clone(this.coords);if(this.type){if(e.group&&"path-group"===e.group.type)for(r in n)"x1"===r||"x2"===r?n[r]+=-this.offsetX+e.width/2:("y1"===r||"y2"===r)&&(n[r]+=-this.offsetY+e.height/2);"linear"===this.type?i=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(i=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2));for(var s=0,o=this.colorStops.length;o>s;s++){var a=this.colorStops[s].color,h=this.colorStops[s].opacity,c=this.colorStops[s].offset;"undefined"!=typeof h&&(a=new fabric.Color(a).setAlpha(h).toRgba()),i.addColorStop(parseFloat(c),a)}return i}}}),fabric.util.object.extend(fabric.Gradient,{fromElement:function(n,s){var o,a=n.getElementsByTagName("stop"),h="linearGradient"===n.nodeName?"linear":"radial",c=n.getAttribute("gradientUnits")||"objectBoundingBox",l=n.getAttribute("gradientTransform"),u=[],f={};"linear"===h?f=e(n):"radial"===h&&(f=i(n));for(var d=a.length;d--;)u.push(t(a[d]));o=r(s,f,c);var g=new fabric.Gradient({type:h,coords:f,colorStops:u,offsetX:-s.left,offsetY:-s.top});return(l||""!==o)&&(g.gradientTransform=fabric.parseTransformAttribute((l||"")+o)),g},forObject:function(t,e){return e||(e={}),r(t,e.coords,"userSpaceOnUse"),new fabric.Gradient(e)}})}(),fabric.Pattern=fabric.util.createClass({repeat:"repeat",offsetX:0,offsetY:0,initialize:function(t){if(t||(t={}),this.id=fabric.Object.__uid++,t.source)if("string"==typeof t.source)if("undefined"!=typeof fabric.util.getFunctionBody(t.source))this.source=new Function(fabric.util.getFunctionBody(t.source));else{var e=this;this.source=fabric.util.createImage(),fabric.util.loadImage(t.source,function(t){e.source=t})}else this.source=t.source;t.repeat&&(this.repeat=t.repeat),t.offsetX&&(this.offsetX=t.offsetX),t.offsetY&&(this.offsetY=t.offsetY)},toObject:function(){var t;return"function"==typeof this.source?t=String(this.source):"string"==typeof this.source.src?t=this.source.src:"object"==typeof this.source&&this.source.toDataURL&&(t=this.source.toDataURL()),{source:t,repeat:this.repeat,offsetX:this.offsetX,offsetY:this.offsetY}},toSVG:function(t){var e="function"==typeof this.source?this.source():this.source,i=e.width/t.getWidth(),r=e.height/t.getHeight(),n=this.offsetX/t.getWidth(),s=this.offsetY/t.getHeight(),o="";return("repeat-x"===this.repeat||"no-repeat"===this.repeat)&&(r=1),("repeat-y"===this.repeat||"no-repeat"===this.repeat)&&(i=1),e.src?o=e.src:e.toDataURL&&(o=e.toDataURL()),'\n\n\n'},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if("undefined"!=typeof e.src){if(!e.complete)return"";if(0===e.naturalWidth||0===e.naturalHeight)return""}return t.createPattern(e,this.repeat)}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.toFixed;return e.Shadow?void e.warn("fabric.Shadow is already defined."):(e.Shadow=e.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){"string"==typeof t&&(t=this._parseShadow(t));for(var i in t)this[i]=t[i];this.id=e.Object.__uid++},_parseShadow:function(t){var i=t.trim(),r=e.Shadow.reOffsetsAndBlur.exec(i)||[],n=i.replace(e.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:n.trim(),offsetX:parseInt(r[1],10)||0,offsetY:parseInt(r[2],10)||0,blur:parseInt(r[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var r=40,n=40,s=e.Object.NUM_FRACTION_DIGITS,o=e.util.rotateVector({x:this.offsetX,y:this.offsetY},e.util.degreesToRadians(-t.angle)),a=20;return t.width&&t.height&&(r=100*i((Math.abs(o.x)+this.blur)/t.width,s)+a,n=100*i((Math.abs(o.y)+this.blur)/t.height,s)+a),t.flipX&&(o.x*=-1),t.flipY&&(o.y*=-1),'\n \n \n \n \n \n \n \n \n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var t={},i=e.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(e){this[e]!==i[e]&&(t[e]=this[e])},this),t}}),void(e.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/))}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)return void fabric.warn("fabric.StaticCanvas is already defined.");var t=fabric.util.object.extend,e=fabric.util.getElementOffset,i=fabric.util.removeFromArray,r=fabric.util.toFixed,n=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(t,e){e||(e={}),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!0,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,preserveObjectStacking:!1,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},enableRetinaScaling:!0,_initStatic:function(t,e){this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,this.renderAll.bind(this)),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,this.renderAll.bind(this)),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,this.renderAll.bind(this)),e.overlayColor&&this.setOverlayColor(e.overlayColor,this.renderAll.bind(this)),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio))},calcOffset:function(){return this._offset=e(this.lowerCanvasEl),this},setOverlayImage:function(t,e,i){return this.__setBgOverlayImage("overlayImage",t,e,i)},setBackgroundImage:function(t,e,i){return this.__setBgOverlayImage("backgroundImage",t,e,i)},setOverlayColor:function(t,e){return this.__setBgOverlayColor("overlayColor",t,e)},setBackgroundColor:function(t,e){return this.__setBgOverlayColor("backgroundColor",t,e)},_setImageSmoothing:function(){var t=this.getContext();t.imageSmoothingEnabled=t.imageSmoothingEnabled||t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled||t.oImageSmoothingEnabled,t.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(t,e,i,r){return"string"==typeof e?fabric.util.loadImage(e,function(e){this[t]=new fabric.Image(e,r),i&&i(e)},this,r&&r.crossOrigin):(r&&e.setOptions(r),this[t]=e,i&&i(e)),this},__setBgOverlayColor:function(t,e,i){if(e&&e.source){var r=this;fabric.util.loadImage(e.source,function(n){r[t]=new fabric.Pattern({source:n,repeat:e.repeat,offsetX:e.offsetX,offsetY:e.offsetY}),i&&i()})}else this[t]=e,i&&i();return this},_createCanvasElement:function(){var t=fabric.document.createElement("canvas");if(t.style||(t.style={}),!t)throw n;return this._initCanvasElement(t),t},_initCanvasElement:function(t){if(fabric.util.createCanvasElement(t),"undefined"==typeof t.getContext)throw n},_initOptions:function(t){for(var e in t)this[e]=t[e];this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(),this._initCanvasElement(this.lowerCanvasEl),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;e=e||{};for(var r in t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.renderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(t){var e=this.getActiveGroup();this.viewportTransform=t,this.renderAll();for(var i=0,r=this._objects.length;r>i;i++)this._objects[i].setCoords();return e&&e.setCoords(),this},zoomToPoint:function(t,e){var i=t;t=fabric.util.transformPoint(t,fabric.util.invertTransform(this.viewportTransform)),this.viewportTransform[0]=e,this.viewportTransform[3]=e;var r=fabric.util.transformPoint(t,this.viewportTransform);this.viewportTransform[4]+=i.x-r.x,this.viewportTransform[5]+=i.y-r.y,this.renderAll();for(var n=0,s=this._objects.length;s>n;n++)this._objects[n].setCoords();return this},setZoom:function(t){return this.zoomToPoint(new fabric.Point(0,0),t),this},absolutePan:function(t){this.viewportTransform[4]=-t.x,this.viewportTransform[5]=-t.y,this.renderAll();for(var e=0,i=this._objects.length;i>e;e++)this._objects[e].setCoords();return this},relativePan:function(t){return this.absolutePan(new fabric.Point(-t.x-this.viewportTransform[4],-t.y-this.viewportTransform[5]))},getElement:function(){return this.lowerCanvasEl},getActiveObject:function(){return null},getActiveGroup:function(){return null},_onObjectAdded:function(t){this.stateful&&t.setupState(),t._set("canvas",this),t.setCoords(),this.fire("object:added",{target:t}),t.fire("added")},_onObjectRemoved:function(t){this.getActiveObject()===t&&(this.fire("before:selection:cleared",{target:t}),this._discardActiveObject(),this.fire("selection:cleared")),this.fire("object:removed",{target:t}),t.fire("removed")},clearContext:function(t){return t.clearRect(0,0,this.width,this.height),this},getContext:function(){return this.contextContainer},clear:function(){return this._objects.length=0,this.discardActiveGroup&&this.discardActiveGroup(),this.discardActiveObject&&this.discardActiveObject(),this.clearContext(this.contextContainer),this.contextTop&&this.clearContext(this.contextTop),this.fire("canvas:cleared"),this.renderAll(),this},_chooseObjectsToRender:function(){var t,e=this.getActiveGroup(),i=[],r=[];if(e&&!this.preserveObjectStacking){for(var n=0,s=this._objects.length;s>n;n++)t=this._objects[n],e.contains(t)?r.push(t):i.push(t);e._set("_objects",r)}else i=this._objects;return i},renderAll:function(){var t,e=this.contextContainer;return this.contextTop&&this.selection&&!this._groupSelector&&!this.isDrawingMode&&this.clearContext(this.contextTop),this.clearContext(e),this.fire("before:render"),this.clipTo&&fabric.util.clipContext(this,e),this._renderBackground(e),e.save(),t=this._chooseObjectsToRender(),e.transform.apply(e,this.viewportTransform),this._renderObjects(e,t),this.preserveObjectStacking||this._renderObjects(e,[this.getActiveGroup()]),e.restore(),!this.controlsAboveOverlay&&this.interactive&&this.drawControls(e),this.clipTo&&e.restore(),this._renderOverlay(e),this.controlsAboveOverlay&&this.interactive&&this.drawControls(e),this.fire("after:render"),this},_renderObjects:function(t,e){for(var i=0,r=e.length;r>i;++i)e[i]&&e[i].render(t)},_renderBackgroundOrOverlay:function(t,e){var i=this[e+"Color"];i&&(t.fillStyle=i.toLive?i.toLive(t):i,t.fillRect(i.offsetX||0,i.offsetY||0,this.width,this.height)),i=this[e+"Image"],i&&i.render(t)},_renderBackground:function(t){this._renderBackgroundOrOverlay(t,"background")},_renderOverlay:function(t){this._renderBackgroundOrOverlay(t,"overlay")},renderTop:function(){var t=this.contextTop||this.contextContainer;return this.clearContext(t),this.selection&&this._groupSelector&&this._drawSelection(),this.fire("after:render"),this},getCenter:function(){return{top:this.getHeight()/2,left:this.getWidth()/2}},centerObjectH:function(t){return this._centerObject(t,new fabric.Point(this.getCenter().left,t.getCenterPoint().y)),this.renderAll(),this},centerObjectV:function(t){return this._centerObject(t,new fabric.Point(t.getCenterPoint().x,this.getCenter().top)),this.renderAll(),this},centerObject:function(t){var e=this.getCenter();return this._centerObject(t,new fabric.Point(e.left,e.top)),this.renderAll(),this},_centerObject:function(t,e){return t.setPositionByOrigin(e,"center","center"),this},toDatalessJSON:function(t){return this.toDatalessObject(t)},toObject:function(t){return this._toObjectMethod("toObject",t)},toDatalessObject:function(t){return this._toObjectMethod("toDatalessObject",t)},_toObjectMethod:function(e,i){var r={objects:this._toObjects(e,i)};return t(r,this.__serializeBgOverlay()),fabric.util.populateWithProperties(this,r,i),r},_toObjects:function(t,e){return this.getObjects().map(function(i){ -return this._toObject(i,t,e)},this)},_toObject:function(t,e,i){var r;this.includeDefaultValues||(r=t.includeDefaultValues,t.includeDefaultValues=!1);var n=this._realizeGroupTransformOnObject(t),s=t[e](i);return this.includeDefaultValues||(t.includeDefaultValues=r),this._unwindGroupTransformOnObject(t,n),s},_realizeGroupTransformOnObject:function(t){var e=["angle","flipX","flipY","height","left","scaleX","scaleY","top","width"];if(t.group&&t.group===this.getActiveGroup()){var i={};return e.forEach(function(e){i[e]=t[e]}),this.getActiveGroup().realizeTransform(t),i}return null},_unwindGroupTransformOnObject:function(t,e){e&&t.set(e)},__serializeBgOverlay:function(){var t={background:this.backgroundColor&&this.backgroundColor.toObject?this.backgroundColor.toObject():this.backgroundColor};return this.overlayColor&&(t.overlay=this.overlayColor.toObject?this.overlayColor.toObject():this.overlayColor),this.backgroundImage&&(t.backgroundImage=this.backgroundImage.toObject()),this.overlayImage&&(t.overlayImage=this.overlayImage.toObject()),t},svgViewportTransformation:!0,toSVG:function(t,e){t||(t={});var i=[];return this._setSVGPreamble(i,t),this._setSVGHeader(i,t),this._setSVGBgOverlayColor(i,"backgroundColor"),this._setSVGBgOverlayImage(i,"backgroundImage"),this._setSVGObjects(i,e),this._setSVGBgOverlayColor(i,"overlayColor"),this._setSVGBgOverlayImage(i,"overlayImage"),i.push(""),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,n=e.width||this.width,s=e.height||this.height,o='viewBox="0 0 '+this.width+" "+this.height+'" ',a=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?o='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,o='viewBox="'+r(-i[4]/i[0],a)+" "+r(-i[5]/i[3],a)+" "+r(this.width/i[0],a)+" "+r(this.height/i[3],a)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"\n")},_setSVGObjects:function(t,e){for(var i=0,r=this.getObjects(),n=r.length;n>i;i++){var s=r[i],o=this._realizeGroupTransformOnObject(s);t.push(s.toSVG(e)),this._unwindGroupTransformOnObject(s,o)}},_setSVGBgOverlayImage:function(t,e){this[e]&&this[e].toSVG&&t.push(this[e].toSVG())},_setSVGBgOverlayColor:function(t,e){this[e]&&this[e].source?t.push('\n"):this[e]&&"overlayColor"===e&&t.push('\n")},sendToBack:function(t){return i(this._objects,t),this._objects.unshift(t),this.renderAll&&this.renderAll()},bringToFront:function(t){return i(this._objects,t),this._objects.push(t),this.renderAll&&this.renderAll()},sendBackwards:function(t,e){var r=this._objects.indexOf(t);if(0!==r){var n=this._findNewLowerIndex(t,r,e);i(this._objects,t),this._objects.splice(n,0,t),this.renderAll&&this.renderAll()}return this},_findNewLowerIndex:function(t,e,i){var r;if(i){r=e;for(var n=e-1;n>=0;--n){var s=t.intersectsWithObject(this._objects[n])||t.isContainedWithinObject(this._objects[n])||this._objects[n].isContainedWithinObject(t);if(s){r=n;break}}}else r=e-1;return r},bringForward:function(t,e){var r=this._objects.indexOf(t);if(r!==this._objects.length-1){var n=this._findNewUpperIndex(t,r,e);i(this._objects,t),this._objects.splice(n,0,t),this.renderAll&&this.renderAll()}return this},_findNewUpperIndex:function(t,e,i){var r;if(i){r=e;for(var n=e+1;n"}}),t(fabric.StaticCanvas.prototype,fabric.Observable),t(fabric.StaticCanvas.prototype,fabric.Collection),t(fabric.StaticCanvas.prototype,fabric.DataURLExporter),t(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(t){var e=fabric.util.createCanvasElement();if(!e||!e.getContext)return null;var i=e.getContext("2d");if(!i)return null;switch(t){case"getImageData":return"undefined"!=typeof i.getImageData;case"setLineDash":return"undefined"!=typeof i.setLineDash;case"toDataURL":return"undefined"!=typeof e.toDataURL;case"toDataURLWithQuality":try{return e.toDataURL("image/jpeg",0),!0}catch(r){}return!1;default:return null}}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeDashArray:null,setShadow:function(t){return this.shadow=new fabric.Shadow(t),this},_setBrushStyles:function(){var t=this.canvas.contextTop;t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")&&t.setLineDash(this.strokeDashArray)},_setShadow:function(){if(this.shadow){var t=this.canvas.contextTop;t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur,t.shadowOffsetX=this.shadow.offsetX,t.shadowOffsetY=this.shadow.offsetY}},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}}),function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(t){this.canvas=t,this._points=[]},onMouseDown:function(t){this._prepareForDrawing(t),this._captureDrawingPath(t),this._render()},onMouseMove:function(t){this._captureDrawingPath(t),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(t){var e=new fabric.Point(t.x,t.y);this._reset(),this._addPoint(e),this.canvas.contextTop.moveTo(e.x,e.y)},_addPoint:function(t){this._points.push(t)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(t){var e=new fabric.Point(t.x,t.y);this._addPoint(e)},_render:function(){var t=this.canvas.contextTop,e=this.canvas.viewportTransform,i=this._points[0],r=this._points[1];t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5]),t.beginPath(),2===this._points.length&&i.x===r.x&&i.y===r.y&&(i.x-=.5,r.x+=.5),t.moveTo(i.x,i.y);for(var n=1,s=this._points.length;s>n;n++){var o=i.midPointFrom(r);t.quadraticCurveTo(i.x,i.y,o.x,o.y),i=this._points[n],r=this._points[n+1]}t.lineTo(i.x,i.y),t.stroke(),t.restore()},convertPointsToSVGPath:function(t){var e=[],i=new fabric.Point(t[0].x,t[0].y),r=new fabric.Point(t[1].x,t[1].y);e.push("M ",t[0].x," ",t[0].y," ");for(var n=1,s=t.length;s>n;n++){var o=i.midPointFrom(r);e.push("Q ",i.x," ",i.y," ",o.x," ",o.y," "),i=new fabric.Point(t[n].x,t[n].y),n+1i;i++){var n=this.points[i],s=new fabric.Circle({radius:n.radius,left:n.x,top:n.y,originX:"center",originY:"center",fill:n.fill});this.shadow&&s.setShadow(this.shadow),e.push(s)}var o=new fabric.Group(e,{originX:"center",originY:"center"});o.canvas=this.canvas,this.canvas.add(o),this.canvas.fire("path:created",{path:o}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=t,this.canvas.renderAll()},addPoint:function(t){var e=new fabric.Point(t.x,t.y),i=fabric.util.getRandomInt(Math.max(0,this.width-20),this.width+20)/2,r=new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0,100)/100).toRgba();return e.radius=i,e.fill=r,this.points.push(e),e}}),fabric.SprayBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,density:20,dotWidth:1,dotWidthVariance:1,randomOpacity:!1,optimizeOverlapping:!0,initialize:function(t){this.canvas=t,this.sprayChunks=[]},onMouseDown:function(t){this.sprayChunks.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.addSprayChunk(t),this.render()},onMouseMove:function(t){this.addSprayChunk(t),this.render()},onMouseUp:function(){var t=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;for(var e=[],i=0,r=this.sprayChunks.length;r>i;i++)for(var n=this.sprayChunks[i],s=0,o=n.length;o>s;s++){var a=new fabric.Rect({width:n[s].width,height:n[s].width,left:n[s].x+1,top:n[s].y+1,originX:"center",originY:"center",fill:this.color});this.shadow&&a.setShadow(this.shadow),e.push(a)}this.optimizeOverlapping&&(e=this._getOptimizedRects(e));var h=new fabric.Group(e,{originX:"center",originY:"center"});h.canvas=this.canvas,this.canvas.add(h),this.canvas.fire("path:created",{path:h}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=t,this.canvas.renderAll()},_getOptimizedRects:function(t){for(var e,i={},r=0,n=t.length;n>r;r++)e=t[r].left+""+t[r].top,i[e]||(i[e]=t[r]);var s=[];for(e in i)s.push(i[e]);return s},render:function(){var t=this.canvas.contextTop;t.fillStyle=this.color;var e=this.canvas.viewportTransform;t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5]);for(var i=0,r=this.sprayChunkPoints.length;r>i;i++){var n=this.sprayChunkPoints[i];"undefined"!=typeof n.opacity&&(t.globalAlpha=n.opacity),t.fillRect(n.x,n.y,n.width,n.width)}t.restore()},addSprayChunk:function(t){this.sprayChunkPoints=[];for(var e,i,r,n=this.width/2,s=0;s0?1:-1,"y"===i&&(s=e.target.skewY,o="top",a="bottom",r="originY"),n[-1]=o,n[1]=a,e.target.flipX&&(c*=-1),e.target.flipY&&(c*=-1),0===s?(e.skewSign=-h*t*c,e[r]=n[-t]):(s=s>0?1:-1,e.skewSign=s,e[r]=n[s*h*c])},_skewObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=!1,o=n.get("lockSkewingX"),a=n.get("lockSkewingY");if(o&&"x"===i||a&&"y"===i)return!1;var h,c,l=n.getCenterPoint(),u=n.toLocalPoint(new fabric.Point(t,e),"center","center")[i],f=n.toLocalPoint(new fabric.Point(r.lastX,r.lastY),"center","center")[i],d=n._getTransformedDimensions();return this._changeSkewTransformOrigin(u-f,r,i),h=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY)[i],c=n.translateToOriginPoint(l,r.originX,r.originY),s=this._setObjectSkew(h,r,i,d),r.lastX=t,r.lastY=e,n.setPositionByOrigin(c,r.originX,r.originY),s},_setObjectSkew:function(t,e,i,r){var n,s,o,a,h,c,l,u,f,d=e.target,g=!1,p=e.skewSign;return"x"===i?(a="y",h="Y",c="X",u=0,f=d.skewY):(a="x",h="X",c="Y",u=d.skewX,f=0),o=d._getTransformedDimensions(u,f),l=2*Math.abs(t)-o[i],2>=l?n=0:(n=p*Math.atan(l/d["scale"+c]/(o[a]/d["scale"+h])),n=fabric.util.radiansToDegrees(n)),g=d["skew"+c]!==n,d.set("skew"+c,n),0!==d["skew"+h]&&(s=d._getTransformedDimensions(),n=r[a]/s[a]*d["scale"+h],d.set("scale"+h,n)),g},_scaleObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=n.get("lockScalingX"),o=n.get("lockScalingY"),a=n.get("lockScalingFlip");if(s&&o)return!1;var h=n.translateToOriginPoint(n.getCenterPoint(),r.originX,r.originY),c=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY),l=n._getTransformedDimensions(),u=!1;return this._setLocalMouse(c,r),u=this._setObjectScale(c,r,s,o,i,a,l),n.setPositionByOrigin(h,r.originX,r.originY),u},_setObjectScale:function(t,e,i,r,n,s,o){var a,h,c,l,u=e.target,f=!1,d=!1,g=!1;return c=t.x*u.scaleX/o.x,l=t.y*u.scaleY/o.y,a=u.scaleX!==c,h=u.scaleY!==l,s&&0>=c&&c=l&&li.padding?t.x<0?t.x+=i.padding:t.x-=i.padding:t.x=0,n(t.y)>i.padding?t.y<0?t.y+=i.padding:t.y-=i.padding:t.y=0},_rotateObject:function(t,e){var n=this._currentTransform;if(n.target.get("lockRotation"))return!1;var s=r(n.ey-n.top,n.ex-n.left),o=r(e-n.top,t-n.left),a=i(o-s+n.theta);return 0>a&&(a=360+a),n.target.angle=a%360,!0},setCursor:function(t){this.upperCanvasEl.style.cursor=t},_resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.setAngle(0)},_drawSelection:function(){var t=this.contextTop,e=this._groupSelector,i=e.left,r=e.top,o=n(i),a=n(r);if(t.fillStyle=this.selectionColor,t.fillRect(e.ex-(i>0?0:-i),e.ey-(r>0?0:-r),o,a),t.lineWidth=this.selectionLineWidth,t.strokeStyle=this.selectionBorderColor,this.selectionDashArray.length>1){var h=e.ex+s-(i>0?0:o),c=e.ey+s-(r>0?0:a);t.beginPath(),fabric.util.drawDashedLine(t,h,c,h+o,c,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c+a-1,h+o,c+a-1,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c,h,c+a,this.selectionDashArray),fabric.util.drawDashedLine(t,h+o-1,c,h+o-1,c+a,this.selectionDashArray),t.closePath(),t.stroke()}else t.strokeRect(e.ex+s-(i>0?0:o),e.ey+s-(r>0?0:a),o,a)},_isLastRenderedObject:function(t){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(t,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(t,!0))},findTarget:function(t,e){if(!this.skipTargetFind){if(this._isLastRenderedObject(t))return this.lastRenderedObjectWithControlsAboveOverlay;var i=this.getActiveGroup();if(i&&!e&&this.containsPoint(t,i))return i;var r=this._searchPossibleTargets(t,e);return this._fireOverOutEvents(r,t),r}},_fireOverOutEvents:function(t,e){t?this._hoveredTarget!==t&&(this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire("mouseout")),this.fire("mouse:over",{target:t,e:e}),t.fire("mouseover"),this._hoveredTarget=t):this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire("mouseout"),this._hoveredTarget=null)},_checkTarget:function(t,e,i){if(e&&e.visible&&e.evented&&this.containsPoint(t,e)){if(!this.perPixelTargetFind&&!e.perPixelTargetFind||e.isEditing)return!0;var r=this.isTargetTransparent(e,i.x,i.y);if(!r)return!0}},_searchPossibleTargets:function(t,e){for(var i,r=this.getPointer(t,!0),n=this._objects.length;n--;)if((!this._objects[n].group||e)&&this._checkTarget(t,this._objects[n],r)){this.relatedTarget=this._objects[n],i=this._objects[n];break}return i},getPointer:function(e,i,r){r||(r=this.upperCanvasEl);var n,s=t(e),o=r.getBoundingClientRect(),a=o.width||0,h=o.height||0;return a&&h||("top"in o&&"bottom"in o&&(h=Math.abs(o.top-o.bottom)),"right"in o&&"left"in o&&(a=Math.abs(o.right-o.left))),this.calcOffset(),s.x=s.x-this._offset.left,s.y=s.y-this._offset.top,i||(s=fabric.util.transformPoint(s,fabric.util.invertTransform(this.viewportTransform))),n=0===a||0===h?{width:1,height:1}:{width:r.width/a,height:r.height/h},{x:s.x*n.width,y:s.y*n.height}},_createUpperCanvas:function(){var t=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement(),fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+t),this.wrapperEl.appendChild(this.upperCanvasEl),this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl),this._applyCanvasStyle(this.upperCanvasEl),this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement(),this.cacheCanvasEl.setAttribute("width",this.width),this.cacheCanvasEl.setAttribute("height",this.height),this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{"class":this.containerClass}),fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+"px",height:this.getHeight()+"px",position:"relative"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(t){var e=this.getWidth()||t.width,i=this.getHeight()||t.height;fabric.util.setStyle(t,{position:"absolute",width:e+"px",height:i+"px",left:0,top:0}),t.width=e,t.height=i,fabric.util.makeElementUnselectable(t)},_copyCanvasStyle:function(t,e){e.style.cssText=t.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(t){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=t,t.set("active",!0)},setActiveObject:function(t,e){return this._setActiveObject(t),this.renderAll(),this.fire("object:selected",{target:t,e:e}),t.fire("selected",{e:e}),this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=null},discardActiveObject:function(t){return this._discardActiveObject(),this.renderAll(),this.fire("selection:cleared",{e:t}),this},_setActiveGroup:function(t){this._activeGroup=t,t&&t.set("active",!0)},setActiveGroup:function(t,e){return this._setActiveGroup(t),t&&(this.fire("object:selected",{target:t,e:e}),t.fire("selected",{e:e})),this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var t=this.getActiveGroup();t&&t.destroy(),this.setActiveGroup(null)},discardActiveGroup:function(t){return this._discardActiveGroup(),this.fire("selection:cleared",{e:t}),this},deactivateAll:function(){for(var t=this.getObjects(),e=0,i=t.length;i>e;e++)t[e].set("active",!1);return this._discardActiveGroup(),this._discardActiveObject(),this},deactivateAllWithDispatch:function(t){var e=this.getActiveGroup()||this.getActiveObject();return e&&this.fire("before:selection:cleared",{target:e,e:t}),this.deactivateAll(),e&&this.fire("selection:cleared",{e:t}),this},dispose:function(){this.callSuper("dispose");var t=this.wrapperEl;return this.removeListeners(),t.removeChild(this.upperCanvasEl),t.removeChild(this.lowerCanvasEl),delete this.upperCanvasEl,t.parentNode&&t.parentNode.replaceChild(this.lowerCanvasEl,this.wrapperEl),delete this.wrapperEl,this},drawControls:function(t){var e=this.getActiveGroup();e?e._renderControls(t):this._drawObjectsControls(t)},_drawObjectsControls:function(t){for(var e=0,i=this._objects.length;i>e;++e)this._objects[e]&&this._objects[e].active&&(this._objects[e]._renderControls(t),this.lastRenderedObjectWithControlsAboveOverlay=this._objects[e])}});for(var o in fabric.StaticCanvas)"prototype"!==o&&(fabric.Canvas[o]=fabric.StaticCanvas[o]);fabric.isTouchSupported&&(fabric.Canvas.prototype._setCursorFromEvent=function(){}),fabric.Element=fabric.Canvas}(),function(){var t={mt:0,tr:1,mr:2,br:3,mb:4,bl:5,ml:6,tl:7},e=fabric.util.addListener,i=fabric.util.removeListener;fabric.util.object.extend(fabric.Canvas.prototype,{cursorMap:["n-resize","ne-resize","e-resize","se-resize","s-resize","sw-resize","w-resize","nw-resize"],_initEventListeners:function(){this._bindEvents(),e(fabric.window,"resize",this._onResize),e(this.upperCanvasEl,"mousedown",this._onMouseDown),e(this.upperCanvasEl,"mousemove",this._onMouseMove),e(this.upperCanvasEl,"mousewheel",this._onMouseWheel),e(this.upperCanvasEl,"touchstart",this._onMouseDown),e(this.upperCanvasEl,"touchmove",this._onMouseMove),"undefined"!=typeof eventjs&&"add"in eventjs&&(eventjs.add(this.upperCanvasEl,"gesture",this._onGesture),eventjs.add(this.upperCanvasEl,"drag",this._onDrag),eventjs.add(this.upperCanvasEl,"orientation",this._onOrientationChange),eventjs.add(this.upperCanvasEl,"shake",this._onShake),eventjs.add(this.upperCanvasEl,"longpress",this._onLongPress))},_bindEvents:function(){this._onMouseDown=this._onMouseDown.bind(this),this._onMouseMove=this._onMouseMove.bind(this),this._onMouseUp=this._onMouseUp.bind(this),this._onResize=this._onResize.bind(this),this._onGesture=this._onGesture.bind(this),this._onDrag=this._onDrag.bind(this),this._onShake=this._onShake.bind(this),this._onLongPress=this._onLongPress.bind(this),this._onOrientationChange=this._onOrientationChange.bind(this),this._onMouseWheel=this._onMouseWheel.bind(this)},removeListeners:function(){i(fabric.window,"resize",this._onResize),i(this.upperCanvasEl,"mousedown",this._onMouseDown),i(this.upperCanvasEl,"mousemove",this._onMouseMove),i(this.upperCanvasEl,"mousewheel",this._onMouseWheel),i(this.upperCanvasEl,"touchstart",this._onMouseDown),i(this.upperCanvasEl,"touchmove",this._onMouseMove),"undefined"!=typeof eventjs&&"remove"in eventjs&&(eventjs.remove(this.upperCanvasEl,"gesture",this._onGesture),eventjs.remove(this.upperCanvasEl,"drag",this._onDrag),eventjs.remove(this.upperCanvasEl,"orientation",this._onOrientationChange),eventjs.remove(this.upperCanvasEl,"shake",this._onShake),eventjs.remove(this.upperCanvasEl,"longpress",this._onLongPress))},_onGesture:function(t,e){this.__onTransformGesture&&this.__onTransformGesture(t,e)},_onDrag:function(t,e){this.__onDrag&&this.__onDrag(t,e)},_onMouseWheel:function(t,e){this.__onMouseWheel&&this.__onMouseWheel(t,e)},_onOrientationChange:function(t,e){this.__onOrientationChange&&this.__onOrientationChange(t,e)},_onShake:function(t,e){this.__onShake&&this.__onShake(t,e)},_onLongPress:function(t,e){this.__onLongPress&&this.__onLongPress(t,e)},_onMouseDown:function(t){this.__onMouseDown(t),e(fabric.document,"touchend",this._onMouseUp),e(fabric.document,"touchmove",this._onMouseMove),i(this.upperCanvasEl,"mousemove",this._onMouseMove),i(this.upperCanvasEl,"touchmove",this._onMouseMove),"touchstart"===t.type?i(this.upperCanvasEl,"mousedown",this._onMouseDown):(e(fabric.document,"mouseup",this._onMouseUp),e(fabric.document,"mousemove",this._onMouseMove))},_onMouseUp:function(t){if(this.__onMouseUp(t),i(fabric.document,"mouseup",this._onMouseUp),i(fabric.document,"touchend",this._onMouseUp),i(fabric.document,"mousemove",this._onMouseMove),i(fabric.document,"touchmove",this._onMouseMove),e(this.upperCanvasEl,"mousemove",this._onMouseMove),e(this.upperCanvasEl,"touchmove",this._onMouseMove),"touchend"===t.type){var r=this;setTimeout(function(){e(r.upperCanvasEl,"mousedown",r._onMouseDown)},400)}},_onMouseMove:function(t){!this.allowTouchScrolling&&t.preventDefault&&t.preventDefault(),this.__onMouseMove(t)},_onResize:function(){this.calcOffset()},_shouldRender:function(t,e){var i=this.getActiveGroup()||this.getActiveObject();return!!(t&&(t.isMoving||t!==i)||!t&&i||!t&&!i&&!this._groupSelector||e&&this._previousPointer&&this.selection&&(e.x!==this._previousPointer.x||e.y!==this._previousPointer.y))},__onMouseUp:function(t){var e;if(this.isDrawingMode&&this._isCurrentlyDrawing)return void this._onMouseUpInDrawingMode(t);this._currentTransform?(this._finalizeCurrentTransform(),e=this._currentTransform.target):e=this.findTarget(t,!0);var i=this._shouldRender(e,this.getPointer(t));this._maybeGroupObjects(t),e&&(e.isMoving=!1),i&&this.renderAll(),this._handleCursorAndEvent(t,e)},_handleCursorAndEvent:function(t,e){this._setCursorFromEvent(t,e);var i=this;setTimeout(function(){i._setCursorFromEvent(t,e)},50),this.fire("mouse:up",{target:e,e:t}),e&&e.fire("mouseup",{e:t})},_finalizeCurrentTransform:function(){var t=this._currentTransform,e=t.target;e._scaling&&(e._scaling=!1),e.setCoords(),this._restoreOriginXY(e),(t.actionPerformed||this.stateful&&e.hasStateChanged())&&(this.fire("object:modified",{target:e}),e.fire("modified"))},_restoreOriginXY:function(t){if(this._previousOriginX&&this._previousOriginY){var e=t.translateToOriginPoint(t.getCenterPoint(),this._previousOriginX,this._previousOriginY); - -t.originX=this._previousOriginX,t.originY=this._previousOriginY,t.left=e.x,t.top=e.y,this._previousOriginX=null,this._previousOriginY=null}},_onMouseDownInDrawingMode:function(t){this._isCurrentlyDrawing=!0,this.discardActiveObject(t).renderAll(),this.clipTo&&fabric.util.clipContext(this,this.contextTop);var e=fabric.util.invertTransform(this.viewportTransform),i=fabric.util.transformPoint(this.getPointer(t,!0),e);this.freeDrawingBrush.onMouseDown(i),this.fire("mouse:down",{e:t});var r=this.findTarget(t);"undefined"!=typeof r&&r.fire("mousedown",{e:t,target:r})},_onMouseMoveInDrawingMode:function(t){if(this._isCurrentlyDrawing){var e=fabric.util.invertTransform(this.viewportTransform),i=fabric.util.transformPoint(this.getPointer(t,!0),e);this.freeDrawingBrush.onMouseMove(i)}this.setCursor(this.freeDrawingCursor),this.fire("mouse:move",{e:t});var r=this.findTarget(t);"undefined"!=typeof r&&r.fire("mousemove",{e:t,target:r})},_onMouseUpInDrawingMode:function(t){this._isCurrentlyDrawing=!1,this.clipTo&&this.contextTop.restore(),this.freeDrawingBrush.onMouseUp(),this.fire("mouse:up",{e:t});var e=this.findTarget(t);"undefined"!=typeof e&&e.fire("mouseup",{e:t,target:e})},__onMouseDown:function(t){var e="which"in t?1===t.which:0===t.button;if(e||fabric.isTouchSupported){if(this.isDrawingMode)return void this._onMouseDownInDrawingMode(t);if(!this._currentTransform){var i=this.findTarget(t),r=this.getPointer(t,!0);this._previousPointer=r;var n=this._shouldRender(i,r),s=this._shouldGroup(t,i);this._shouldClearSelection(t,i)?this._clearSelection(t,i,r):s&&(this._handleGrouping(t,i),i=this.getActiveGroup()),i&&i.selectable&&(i.__corner||!s)&&(this._beforeTransform(t,i),this._setupCurrentTransform(t,i)),n&&this.renderAll(),this.fire("mouse:down",{target:i,e:t}),i&&i.fire("mousedown",{e:t})}}},_beforeTransform:function(t,e){this.stateful&&e.saveState(),e._findTargetCorner(this.getPointer(t))&&this.onBeforeScaleRotate(e),e!==this.getActiveGroup()&&e!==this.getActiveObject()&&(this.deactivateAll(),this.setActiveObject(e,t))},_clearSelection:function(t,e,i){this.deactivateAllWithDispatch(t),e&&e.selectable?this.setActiveObject(e,t):this.selection&&(this._groupSelector={ex:i.x,ey:i.y,top:0,left:0})},_setOriginToCenter:function(t){this._previousOriginX=this._currentTransform.target.originX,this._previousOriginY=this._currentTransform.target.originY;var e=t.getCenterPoint();t.originX="center",t.originY="center",t.left=e.x,t.top=e.y,this._currentTransform.left=t.left,this._currentTransform.top=t.top},_setCenterToOrigin:function(t){var e=t.translateToOriginPoint(t.getCenterPoint(),this._previousOriginX,this._previousOriginY);t.originX=this._previousOriginX,t.originY=this._previousOriginY,t.left=e.x,t.top=e.y,this._previousOriginX=null,this._previousOriginY=null},__onMouseMove:function(t){var e,i;if(this.isDrawingMode)return void this._onMouseMoveInDrawingMode(t);if(!("undefined"!=typeof t.touches&&t.touches.length>1)){var r=this._groupSelector;r?(i=this.getPointer(t,!0),r.left=i.x-r.ex,r.top=i.y-r.ey,this.renderTop()):this._currentTransform?this._transformObject(t):(e=this.findTarget(t),!e||e&&!e.selectable?this.setCursor(this.defaultCursor):this._setCursorFromEvent(t,e)),this.fire("mouse:move",{target:e,e:t}),e&&e.fire("mousemove",{e:t})}},_transformObject:function(t){var e=this.getPointer(t),i=this._currentTransform;i.reset=!1,i.target.isMoving=!0,this._beforeScaleTransform(t,i),this._performTransformAction(t,i,e),this.renderAll()},_performTransformAction:function(t,e,i){var r=i.x,n=i.y,s=e.target,o=e.action,a=!1;"rotate"===o?(a=this._rotateObject(r,n))&&this._fire("rotating",s,t):"scale"===o?(a=this._onScale(t,e,r,n))&&this._fire("scaling",s,t):"scaleX"===o?(a=this._scaleObject(r,n,"x"))&&this._fire("scaling",s,t):"scaleY"===o?(a=this._scaleObject(r,n,"y"))&&this._fire("scaling",s,t):"skewX"===o?(a=this._skewObject(r,n,"x"))&&this._fire("skewing",s,t):"skewY"===o?(a=this._skewObject(r,n,"y"))&&this._fire("skewing",s,t):((a=this._translateObject(r,n))&&this._fire("moving",s,t),this.setCursor(this.moveCursor)),e.actionPerformed=a},_fire:function(t,e,i){this.fire("object:"+t,{target:e,e:i}),e.fire(t,{e:i})},_beforeScaleTransform:function(t,e){if("scale"===e.action||"scaleX"===e.action||"scaleY"===e.action){var i=this._shouldCenterTransform(e.target);(i&&("center"!==e.originX||"center"!==e.originY)||!i&&"center"===e.originX&&"center"===e.originY)&&(this._resetCurrentTransform(),e.reset=!0)}},_onScale:function(t,e,i,r){return!t.shiftKey&&!this.uniScaleTransform||e.target.get("lockUniScaling")?(e.reset||"scale"!==e.currentAction||this._resetCurrentTransform(),e.currentAction="scaleEqually",this._scaleObject(i,r,"equally")):(e.currentAction="scale",this._scaleObject(i,r))},_setCursorFromEvent:function(t,e){if(!e||!e.selectable)return this.setCursor(this.defaultCursor),!1;var i=this.getActiveGroup(),r=e._findTargetCorner&&(!i||!i.contains(e))&&e._findTargetCorner(this.getPointer(t,!0));return r?this._setCornerCursor(r,e,t):this.setCursor(e.hoverCursor||this.hoverCursor),!0},_setCornerCursor:function(e,i,r){if(e in t)this.setCursor(this._getRotatedCornerCursor(e,i,r));else{if("mtr"!==e||!i.hasRotatingPoint)return this.setCursor(this.defaultCursor),!1;this.setCursor(this.rotationCursor)}},_getRotatedCornerCursor:function(e,i,r){var n=Math.round(i.getAngle()%360/45);return 0>n&&(n+=8),n+=t[e],r.shiftKey&&t[e]%2===0&&(n+=2),n%=8,this.cursorMap[n]}})}(),function(){var t=Math.min,e=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(t,e){var i=this.getActiveObject();return t.shiftKey&&e&&e.selectable&&(this.getActiveGroup()||i&&i!==e)&&this.selection},_handleGrouping:function(t,e){(e!==this.getActiveGroup()||(e=this.findTarget(t,!0),e&&!e.isType("group")))&&(this.getActiveGroup()?this._updateActiveGroup(e,t):this._createActiveGroup(e,t),this._activeGroup&&this._activeGroup.saveCoords())},_updateActiveGroup:function(t,e){var i=this.getActiveGroup();if(i.contains(t)){if(i.removeWithUpdate(t),t.set("active",!1),1===i.size())return this.discardActiveGroup(e),void this.setActiveObject(i.item(0))}else i.addWithUpdate(t);this.fire("selection:created",{target:i,e:e}),i.set("active",!0)},_createActiveGroup:function(t,e){if(this._activeObject&&t!==this._activeObject){var i=this._createGroup(t);i.addWithUpdate(),this.setActiveGroup(i),this._activeObject=null,this.fire("selection:created",{target:i,e:e})}t.set("active",!0)},_createGroup:function(t){var e=this.getObjects(),i=e.indexOf(this._activeObject)1&&(e=new fabric.Group(e.reverse(),{canvas:this}),e.addWithUpdate(),this.setActiveGroup(e,t),e.saveCoords(),this.fire("selection:created",{target:e}),this.renderAll())},_collectObjects:function(){for(var i,r=[],n=this._groupSelector.ex,s=this._groupSelector.ey,o=n+this._groupSelector.left,a=s+this._groupSelector.top,h=new fabric.Point(t(n,o),t(s,a)),c=new fabric.Point(e(n,o),e(s,a)),l=n===o&&s===a,u=this._objects.length;u--&&(i=this._objects[u],!(i&&i.selectable&&i.visible&&(i.intersectsWithRect(h,c)||i.isContainedWithinRect(h,c)||i.containsPoint(h)||i.containsPoint(c))&&(i.set("active",!0),r.push(i),l))););return r},_maybeGroupObjects:function(t){this.selection&&this._groupSelector&&this._groupSelectedObjects(t);var e=this.getActiveGroup();e&&(e.setObjectsCoords().setCoords(),e.isMoving=!1,this.setCursor(this.defaultCursor)),this._groupSelector=null,this._currentTransform=null}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(t){t||(t={});var e=t.format||"png",i=t.quality||1,r=t.multiplier||1,n={left:t.left,top:t.top,width:t.width,height:t.height};return this._isRetinaScaling()&&(r*=fabric.devicePixelRatio),1!==r?this.__toDataURLWithMultiplier(e,i,n,r):this.__toDataURL(e,i,n)},__toDataURL:function(t,e,i){this.renderAll();var r=this.contextContainer.canvas,n=this.__getCroppedCanvas(r,i);"jpg"===t&&(t="jpeg");var s=fabric.StaticCanvas.supports("toDataURLWithQuality")?(n||r).toDataURL("image/"+t,e):(n||r).toDataURL("image/"+t);return n&&(n=null),s},__getCroppedCanvas:function(t,e){var i,r,n="left"in e||"top"in e||"width"in e||"height"in e;return n&&(i=fabric.util.createCanvasElement(),r=i.getContext("2d"),i.width=e.width||this.width,i.height=e.height||this.height,r.drawImage(t,-e.left||0,-e.top||0)),i},__toDataURLWithMultiplier:function(t,e,i,r){var n=this.getWidth(),s=this.getHeight(),o=n*r,a=s*r,h=this.getActiveObject(),c=this.getActiveGroup(),l=this.contextContainer;r>1&&this.setDimensions({width:o,height:a}),l.save(),l.scale(r/fabric.devicePixelRatio,r/fabric.devicePixelRatio),i.left&&(i.left*=r),i.top&&(i.top*=r),i.width?i.width*=r:1>r&&(i.width=o),i.height?i.height*=r:1>r&&(i.height=a),c?this._tempRemoveBordersControlsFromGroup(c):h&&this.deactivateAll&&this.deactivateAll();var u=this.__toDataURL(t,e,i);return this.width=n,this.height=s,this.setDimensions({width:n,height:s}),c?this._restoreBordersControlsOnGroup(c):h&&this.setActiveObject&&this.setActiveObject(h),this.contextTop&&this.clearContext(this.contextTop),this.renderAll(),u},toDataURLWithMultiplier:function(t,e,i){return this.toDataURL({format:t,multiplier:e,quality:i})},_tempRemoveBordersControlsFromGroup:function(t){t.origHasControls=t.hasControls,t.origBorderColor=t.borderColor,t.hasControls=!0,t.borderColor="rgba(0,0,0,0)",t.forEachObject(function(t){t.origBorderColor=t.borderColor,t.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(t){t.hideControls=t.origHideControls,t.borderColor=t.origBorderColor,t.forEachObject(function(t){t.borderColor=t.origBorderColor,delete t.origBorderColor})}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(t,e,i){return this.loadFromJSON(t,e,i)},loadFromJSON:function(t,e,i){if(t){var r="string"==typeof t?JSON.parse(t):t;this.clear();var n=this;return this._enlivenObjects(r.objects,function(){n._setBgOverlay(r,e)},i),this}},_setBgOverlay:function(t,e){var i=this,r={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(!(t.backgroundImage||t.overlayImage||t.background||t.overlay))return void(e&&e());var n=function(){r.backgroundImage&&r.overlayImage&&r.backgroundColor&&r.overlayColor&&(i.renderAll(),e&&e())};this.__setBgOverlay("backgroundImage",t.backgroundImage,r,n),this.__setBgOverlay("overlayImage",t.overlayImage,r,n),this.__setBgOverlay("backgroundColor",t.background,r,n),this.__setBgOverlay("overlayColor",t.overlay,r,n),n()},__setBgOverlay:function(t,e,i,r){var n=this;return e?void("backgroundImage"===t||"overlayImage"===t?fabric.Image.fromObject(e,function(e){n[t]=e,i[t]=!0,r&&r()}):this["set"+fabric.util.string.capitalize(t,!0)](e,function(){i[t]=!0,r&&r()})):void(i[t]=!0)},_enlivenObjects:function(t,e,i){var r=this;if(!t||0===t.length)return void(e&&e());var n=this.renderOnAddRemove;this.renderOnAddRemove=!1,fabric.util.enlivenObjects(t,function(t){t.forEach(function(t,e){r.insertAt(t,e,!0)}),r.renderOnAddRemove=n,e&&e()},null,i)},_toDataURL:function(t,e){this.clone(function(i){e(i.toDataURL(t))})},_toDataURLWithMultiplier:function(t,e,i){this.clone(function(r){i(r.toDataURLWithMultiplier(t,e))})},clone:function(t,e){var i=JSON.stringify(this.toJSON(e));this.cloneWithoutData(function(e){e.loadFromJSON(i,function(){t&&t(e)})})},cloneWithoutData:function(t){var e=fabric.document.createElement("canvas");e.width=this.getWidth(),e.height=this.getHeight();var i=new fabric.Canvas(e);i.clipTo=this.clipTo,this.backgroundImage?(i.setBackgroundImage(this.backgroundImage.src,function(){i.renderAll(),t&&t(i)}),i.backgroundImageOpacity=this.backgroundImageOpacity,i.backgroundImageStretch=this.backgroundImageStretch):t&&t(i)}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.toFixed,n=e.util.string.capitalize,s=e.util.degreesToRadians,o=e.StaticCanvas.supports("setLineDash");e.Object||(e.Object=e.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:!1,flipY:!1,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:12,transparentCorners:!0,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:!1,centeredRotation:!0,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:!0,evented:!0,visible:!0,hasControls:!0,hasBorders:!0,hasRotatingPoint:!0,rotatingPointOffset:40,perPixelTargetFind:!1,includeDefaultValues:!0,clipTo:null,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockUniScaling:!1,lockSkewingX:!1,lockSkewingY:!1,lockScalingFlip:!1,stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor alignX alignY meetOrSlice skewX skewY".split(" "),initialize:function(t){t&&this.setOptions(t)},_initGradient:function(t){!t.fill||!t.fill.colorStops||t.fill instanceof e.Gradient||this.set("fill",new e.Gradient(t.fill)),!t.stroke||!t.stroke.colorStops||t.stroke instanceof e.Gradient||this.set("stroke",new e.Gradient(t.stroke))},_initPattern:function(t){!t.fill||!t.fill.source||t.fill instanceof e.Pattern||this.set("fill",new e.Pattern(t.fill)),!t.stroke||!t.stroke.source||t.stroke instanceof e.Pattern||this.set("stroke",new e.Pattern(t.stroke))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var i=e.util.getFunctionBody(t.clipTo);"undefined"!=typeof i&&(this.clipTo=new Function("ctx",i))}},setOptions:function(t){for(var e in t)this.set(e,t[e]);this._initGradient(t),this._initPattern(t),this._initClipping(t)},transform:function(t,e){this.group&&this.canvas.preserveObjectStacking&&this.group===this.canvas._activeGroup&&this.group.transform(t);var i=e?this._getLeftTopCoords():this.getCenterPoint();t.translate(i.x,i.y),t.rotate(s(this.angle)),t.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1)),t.transform(1,0,Math.tan(s(this.skewX)),1,0,0),t.transform(1,Math.tan(s(this.skewY)),0,1,0,0)},toObject:function(t){var i=e.Object.NUM_FRACTION_DIGITS,n={type:this.type,originX:this.originX,originY:this.originY,left:r(this.left,i),top:r(this.top,i),width:r(this.width,i),height:r(this.height,i),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:r(this.strokeWidth,i),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:r(this.strokeMiterLimit,i),scaleX:r(this.scaleX,i),scaleY:r(this.scaleY,i),angle:r(this.getAngle(),i),flipX:this.flipX,flipY:this.flipY,opacity:r(this.opacity,i),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():this.transformMatrix,skewX:r(this.skewX,i),skewY:r(this.skewY,i)};return this.includeDefaultValues||(n=this._removeDefaultValues(n)),e.util.populateWithProperties(this,n,t),n},toDatalessObject:function(t){return this.toObject(t)},_removeDefaultValues:function(t){var i=e.util.getKlass(t.type).prototype,r=i.stateProperties;return r.forEach(function(e){t[e]===i[e]&&delete t[e];var r="[object Array]"===Object.prototype.toString.call(t[e])&&"[object Array]"===Object.prototype.toString.call(i[e]);r&&0===t[e].length&&0===i[e].length&&delete t[e]}),t},toString:function(){return"#"},get:function(t){return this[t]},_setObject:function(t){for(var e in t)this._set(e,t[e])},set:function(t,e){return"object"==typeof t?this._setObject(t):"function"==typeof e&&"clipTo"!==t?this._set(t,e(this.get(t))):this._set(t,e),this},_set:function(t,i){var n="scaleX"===t||"scaleY"===t;return n&&(i=this._constrainScale(i)),"scaleX"===t&&0>i?(this.flipX=!this.flipX,i*=-1):"scaleY"===t&&0>i?(this.flipY=!this.flipY,i*=-1):"width"===t||"height"===t?this.minScaleLimit=r(Math.min(.1,1/Math.max(this.width,this.height)),2):"shadow"!==t||!i||i instanceof e.Shadow||(i=new e.Shadow(i)),this[t]=i,this},setOnGroup:function(){},toggle:function(t){var e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this},setSourcePath:function(t){return this.sourcePath=t,this},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:[1,0,0,1,0,0]},render:function(t,i){0===this.width&&0===this.height||!this.visible||(t.save(),this._setupCompositeOperation(t),i||this.transform(t),this._setStrokeStyles(t),this._setFillStyles(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this._setOpacity(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t),this._render(t,i),this.clipTo&&t.restore(),t.restore())},_setOpacity:function(t){this.group&&this.group._setOpacity(t),t.globalAlpha*=this.opacity},_setStrokeStyles:function(t){this.stroke&&(t.lineWidth=this.strokeWidth,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,t.miterLimit=this.strokeMiterLimit,t.strokeStyle=this.stroke.toLive?this.stroke.toLive(t,this):this.stroke)},_setFillStyles:function(t){this.fill&&(t.fillStyle=this.fill.toLive?this.fill.toLive(t,this):this.fill)},_renderControls:function(t,i){if(!(!this.active||i||this.group&&this.group!==this.canvas.getActiveGroup())){var r,n=this.getViewportTransform(),o=this.calcTransformMatrix();o=e.util.multiplyTransformMatrices(n,o),r=e.util.qrDecompose(o),t.save(),t.translate(r.translateX,r.translateY),this.group&&this.group===this.canvas.getActiveGroup()?(t.rotate(s(r.angle)),this.drawBordersInGroup(t,r)):(t.rotate(s(this.angle)),this.drawBorders(t)),this.drawControls(t),t.restore()}},_setShadow:function(t){if(this.shadow){var i=this.canvas&&this.canvas.viewportTransform[0]||1,r=this.canvas&&this.canvas.viewportTransform[3]||1;this.canvas&&this.canvas._isRetinaScaling()&&(i*=e.devicePixelRatio,r*=e.devicePixelRatio),t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*(i+r)*(this.scaleX+this.scaleY)/4,t.shadowOffsetX=this.shadow.offsetX*i*this.scaleX,t.shadowOffsetY=this.shadow.offsetY*r*this.scaleY}},_removeShadow:function(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)},_renderFill:function(t){if(this.fill){if(t.save(),this.fill.gradientTransform){var e=this.fill.gradientTransform;t.transform.apply(t,e)}this.fill.toLive&&t.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0),"evenodd"===this.fillRule?t.fill("evenodd"):t.fill(),t.restore()}},_renderStroke:function(t){if(this.stroke&&0!==this.strokeWidth){if(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this.strokeDashArray)1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),o?(t.setLineDash(this.strokeDashArray),this._stroke&&this._stroke(t)):this._renderDashedStroke&&this._renderDashedStroke(t),t.stroke();else{if(this.stroke.gradientTransform){var e=this.stroke.gradientTransform;t.transform.apply(t,e)}this._stroke?this._stroke(t):t.stroke()}t.restore()}},clone:function(t,i){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(i),t):new e.Object(this.toObject(i))},cloneAsImage:function(t){var i=this.toDataURL();return e.util.loadImage(i,function(i){t&&t(new e.Image(i))}),this},toDataURL:function(t){t||(t={});var i=e.util.createCanvasElement(),r=this.getBoundingRect();i.width=r.width,i.height=r.height,e.util.wrapElement(i,"div");var n=new e.StaticCanvas(i);"jpg"===t.format&&(t.format="jpeg"),"jpeg"===t.format&&(n.backgroundColor="#fff");var s={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",!1),this.setPositionByOrigin(new e.Point(i.width/2,i.height/2),"center","center");var o=this.canvas;n.add(this);var a=n.toDataURL(t);return this.set(s).setCoords(),this.canvas=o,n.dispose(),n=null,a},isType:function(t){return this.type===t},complexity:function(){return 0},toJSON:function(t){return this.toObject(t)},setGradient:function(t,i){i||(i={});var r={colorStops:[]};r.type=i.type||(i.r1||i.r2?"radial":"linear"),r.coords={x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2},(i.r1||i.r2)&&(r.coords.r1=i.r1,r.coords.r2=i.r2),i.gradientTransform&&(r.gradientTransform=i.gradientTransform);for(var n in i.colorStops){var s=new e.Color(i.colorStops[n]);r.colorStops.push({offset:n,color:s.toRgb(),opacity:s.getAlpha()})}return this.set(t,e.Gradient.forObject(this,r))},setPatternFill:function(t){return this.set("fill",new e.Pattern(t))},setShadow:function(t){return this.set("shadow",t?new e.Shadow(t):null)},setColor:function(t){return this.set("fill",t),this},setAngle:function(t){var e=("center"!==this.originX||"center"!==this.originY)&&this.centeredRotation;return e&&this._setOriginToCenter(),this.set("angle",t),e&&this._resetOrigin(),this},centerH:function(){return this.canvas.centerObjectH(this),this},centerV:function(){return this.canvas.centerObjectV(this),this},center:function(){return this.canvas.centerObject(this),this},remove:function(){return this.canvas.remove(this),this},getLocalPointer:function(t,i){i=i||this.canvas.getPointer(t);var r=new e.Point(i.x,i.y),n=this._getLeftTopCoords();return this.angle&&(r=e.util.rotatePoint(r,n,e.util.degreesToRadians(-this.angle))),{x:r.x-n.x,y:r.y-n.y}},_setupCompositeOperation:function(t){this.globalCompositeOperation&&(t.globalCompositeOperation=this.globalCompositeOperation)}}),e.util.createAccessors(e.Object),e.Object.prototype.rotate=e.Object.prototype.setAngle,i(e.Object.prototype,e.Observable),e.Object.NUM_FRACTION_DIGITS=2,e.Object.__uid=0)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.degreesToRadians,e={left:-.5,center:0,right:.5},i={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(t,r,n,s,o){var a,h=t.x,c=t.y,l=e[s]-e[r],u=i[o]-i[n];return(l||u)&&(a=this._getTransformedDimensions(),h=t.x+l*a.x,c=t.y+u*a.y),new fabric.Point(h,c)},translateToCenterPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,i,r,"center","center");return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},translateToOriginPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,"center","center",i,r);return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},getCenterPoint:function(){var t=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(t,this.originX,this.originY)},getPointByOrigin:function(t,e){var i=this.getCenterPoint();return this.translateToOriginPoint(i,t,e)},toLocalPoint:function(e,i,r){var n,s,o=this.getCenterPoint();return n=i&&r?this.translateToGivenOrigin(o,"center","center",i,r):new fabric.Point(this.left,this.top),s=new fabric.Point(e.x,e.y),this.angle&&(s=fabric.util.rotatePoint(s,o,-t(this.angle))),s.subtractEquals(n)},setPositionByOrigin:function(t,e,i){var r=this.translateToCenterPoint(t,e,i),n=this.translateToOriginPoint(r,this.originX,this.originY);this.set("left",n.x),this.set("top",n.y)},adjustPosition:function(i){var r=t(this.angle),n=this.getWidth(),s=Math.cos(r)*n,o=Math.sin(r)*n;this.left+=s*(e[i]-e[this.originX]),this.top+=o*(e[i]-e[this.originX]),this.setCoords(),this.originX=i},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var t=this.getCenterPoint();this.originX="center",this.originY="center",this.left=t.x,this.top=t.y},_resetOrigin:function(){var t=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=t.x,this.top=t.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")}})}(),function(){function t(t){return[new fabric.Point(t.tl.x,t.tl.y),new fabric.Point(t.tr.x,t.tr.y),new fabric.Point(t.br.x,t.br.y),new fabric.Point(t.bl.x,t.bl.y)]}var e=fabric.util.degreesToRadians,i=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(e,i){var r=t(this.oCoords),n=fabric.Intersection.intersectPolygonRectangle(r,e,i);return"Intersection"===n.status},intersectsWithObject:function(e){var i=fabric.Intersection.intersectPolygonPolygon(t(this.oCoords),t(e.oCoords));return"Intersection"===i.status},isContainedWithinObject:function(t){var e=t.getBoundingRect(),i=new fabric.Point(e.left,e.top),r=new fabric.Point(e.left+e.width,e.top+e.height);return this.isContainedWithinRect(i,r)},isContainedWithinRect:function(t,e){var i=this.getBoundingRect();return i.left>=t.x&&i.left+i.width<=e.x&&i.top>=t.y&&i.top+i.height<=e.y},containsPoint:function(t){var e=this._getImageLines(this.oCoords),i=this._findCrossPoints(t,e);return 0!==i&&i%2===1},_getImageLines:function(t){return{topline:{o:t.tl,d:t.tr},rightline:{o:t.tr,d:t.br},bottomline:{o:t.br,d:t.bl},leftline:{o:t.bl,d:t.tl}}},_findCrossPoints:function(t,e){var i,r,n,s,o,a,h,c=0;for(var l in e)if(h=e[l],!(h.o.y=t.y&&h.d.y>=t.y||(h.o.x===h.d.x&&h.o.x>=t.x?(o=h.o.x,a=t.y):(i=0,r=(h.d.y-h.o.y)/(h.d.x-h.o.x),n=t.y-i*t.x,s=h.o.y-r*h.o.x,o=-(n-s)/(i-r),a=n+i*o),o>=t.x&&(c+=1),2!==c)))break;return c},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){return this.oCoords||this.setCoords(),fabric.util.makeBoundingBoxFromPoints([this.oCoords.tl,this.oCoords.tr,this.oCoords.br,this.oCoords.bl])},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)t?-this.minScaleLimit:this.minScaleLimit:t},scale:function(t){return t=this._constrainScale(t),0>t&&(this.flipX=!this.flipX,this.flipY=!this.flipY,t*=-1),this.scaleX=t,this.scaleY=t,this.setCoords(),this},scaleToWidth:function(t){var e=this.getBoundingRect().width/this.getWidth();return this.scale(t/this.width/e)},scaleToHeight:function(t){var e=this.getBoundingRect().height/this.getHeight();return this.scale(t/this.height/e)},setCoords:function(){var t=e(this.angle),i=this.getViewportTransform(),r=this._calculateCurrentDimensions(),n=r.x,s=r.y;0>n&&(n=Math.abs(n));var o=Math.sin(t),a=Math.cos(t),h=n>0?Math.atan(s/n):0,c=n/Math.cos(h)/2,l=Math.cos(h+t)*c,u=Math.sin(h+t)*c,f=fabric.util.transformPoint(this.getCenterPoint(),i),d=new fabric.Point(f.x-l,f.y-u),g=new fabric.Point(d.x+n*a,d.y+n*o),p=new fabric.Point(d.x-s*o,d.y+s*a),v=new fabric.Point(f.x+l,f.y+u),m=new fabric.Point((d.x+p.x)/2,(d.y+p.y)/2),b=new fabric.Point((g.x+d.x)/2,(g.y+d.y)/2),y=new fabric.Point((v.x+g.x)/2,(v.y+g.y)/2),_=new fabric.Point((v.x+p.x)/2,(v.y+p.y)/2),x=new fabric.Point(b.x+o*this.rotatingPointOffset,b.y-a*this.rotatingPointOffset);return this.oCoords={tl:d,tr:g,br:v,bl:p,ml:m,mt:b,mr:y,mb:_,mtr:x},this._setCornerCoords&&this._setCornerCoords(),this},_calcRotateMatrix:function(){if(this.angle){var t=e(this.angle),i=Math.cos(t),r=Math.sin(t);return[i,r,-r,i,0,0]}return[1,0,0,1,0,0]},calcTransformMatrix:function(){var t=this.getCenterPoint(),e=[1,0,0,1,t.x,t.y],r=this._calcRotateMatrix(),n=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,!0),s=this.group?this.group.calcTransformMatrix():[1,0,0,1,0,0];return s=i(s,e),s=i(s,r),s=i(s,n)},_calcDimensionsTransformMatrix:function(t,r,n){var s=[1,0,Math.tan(e(t)),1],o=[1,Math.tan(e(r)),0,1],a=this.scaleX*(n&&this.flipX?-1:1),h=this.scaleY*(n&&this.flipY?-1:1),c=[a,0,0,h],l=i(c,s,!0);return i(l,o,!0)}})}(),fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){return this.group?fabric.StaticCanvas.prototype.sendToBack.call(this.group,this):this.canvas.sendToBack(this),this},bringToFront:function(){return this.group?fabric.StaticCanvas.prototype.bringToFront.call(this.group,this):this.canvas.bringToFront(this),this},sendBackwards:function(t){return this.group?fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,t):this.canvas.sendBackwards(this,t),this},bringForward:function(t){return this.group?fabric.StaticCanvas.prototype.bringForward.call(this.group,this,t):this.canvas.bringForward(this,t),this},moveTo:function(t){return this.group?fabric.StaticCanvas.prototype.moveTo.call(this.group,this,t):this.canvas.moveTo(this,t),this}}),fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(t){var e=this.fill?this.fill.toLive?"url(#SVGID_"+this.fill.id+")":this.fill:"none",i=this.fillRule,r=this.stroke?this.stroke.toLive?"url(#SVGID_"+this.stroke.id+")":this.stroke:"none",n=this.strokeWidth?this.strokeWidth:"0",s=this.strokeDashArray?this.strokeDashArray.join(" "):"none",o=this.strokeLineCap?this.strokeLineCap:"butt",a=this.strokeLineJoin?this.strokeLineJoin:"miter",h=this.strokeMiterLimit?this.strokeMiterLimit:"4",c="undefined"!=typeof this.opacity?this.opacity:"1",l=this.visible?"":" visibility: hidden;",u=t?"":this.getSvgFilter();return["stroke: ",r,"; ","stroke-width: ",n,"; ","stroke-dasharray: ",s,"; ","stroke-linecap: ",o,"; ","stroke-linejoin: ",a,"; ","stroke-miterlimit: ",h,"; ","fill: ",e,"; ","fill-rule: ",i,"; ","opacity: ",c,";",u,l].join("")},getSvgFilter:function(){return this.shadow?"filter: url(#SVGID_"+this.shadow.id+");":""},getSvgTransform:function(){if(this.group&&"path-group"===this.group.type)return"";var t=fabric.util.toFixed,e=this.getAngle(),i=this.getSkewX()%360,r=this.getSkewY()%360,n=this.getCenterPoint(),s=fabric.Object.NUM_FRACTION_DIGITS,o="path-group"===this.type?"":"translate("+t(n.x,s)+" "+t(n.y,s)+")",a=0!==e?" rotate("+t(e,s)+")":"",h=1===this.scaleX&&1===this.scaleY?"":" scale("+t(this.scaleX,s)+" "+t(this.scaleY,s)+")",c=0!==i?" skewX("+t(i,s)+")":"",l=0!==r?" skewY("+t(r,s)+")":"",u="path-group"===this.type?this.width:0,f=this.flipX?" matrix(-1 0 0 1 "+u+" 0) ":"",d="path-group"===this.type?this.height:0,g=this.flipY?" matrix(1 0 0 -1 0 "+d+")":"";return[o,a,h,f,g,c,l].join("")},getSvgTransformMatrix:function(){return this.transformMatrix?" matrix("+this.transformMatrix.join(" ")+") ":""},_createBaseSVGMarkup:function(){var t=[];return this.fill&&this.fill.toLive&&t.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&t.push(this.stroke.toSVG(this,!1)),this.shadow&&t.push(this.shadow.toSVG(this)),t}}),fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(t){return this.get(t)!==this.originalState[t]},this)},saveState:function(t){return this.stateProperties.forEach(function(t){this.originalState[t]=this.get(t)},this),t&&t.stateProperties&&t.stateProperties.forEach(function(t){this.originalState[t]=this.get(t)},this),this},setupState:function(){return this.originalState={},this.saveState(),this}}),function(){var t=fabric.util.degreesToRadians,e=function(){return"undefined"!=typeof G_vmlCanvasManager};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(t){if(!this.hasControls||!this.active)return!1;var e,i,r=t.x,n=t.y;this.__corner=0;for(var s in this.oCoords)if(this.isControlVisible(s)&&("mtr"!==s||this.hasRotatingPoint)&&(!this.get("lockUniScaling")||"mt"!==s&&"mr"!==s&&"mb"!==s&&"ml"!==s)&&(i=this._getImageLines(this.oCoords[s].corner),e=this._findCrossPoints({ -x:r,y:n},i),0!==e&&e%2===1))return this.__corner=s,s;return!1},_setCornerCoords:function(){var e,i,r=this.oCoords,n=t(45-this.angle),s=.707106*this.cornerSize,o=s*Math.cos(n),a=s*Math.sin(n);for(var h in r)e=r[h].x,i=r[h].y,r[h].corner={tl:{x:e-a,y:i-o},tr:{x:e+o,y:i-a},bl:{x:e-o,y:i+a},br:{x:e+a,y:i+o}}},_getNonTransformedDimensions:function(){var t=this.strokeWidth,e=this.width,i=this.height,r=!0,n=!0;return"line"===this.type&&"butt"===this.strokeLineCap&&(n=e,r=i),n&&(i+=0>i?-t:t),r&&(e+=0>e?-t:t),{x:e,y:i}},_getTransformedDimensions:function(t,e){"undefined"==typeof t&&(t=this.skewX),"undefined"==typeof e&&(e=this.skewY);var i,r,n=this._getNonTransformedDimensions(),s=n.x/2,o=n.y/2,a=[{x:-s,y:-o},{x:s,y:-o},{x:-s,y:o},{x:s,y:o}],h=this._calcDimensionsTransformMatrix(t,e,!1);for(i=0;ir;r++)t=i[r],e=r!==n-1,this._animate(t,arguments[0][t],arguments[1],e)}else this._animate.apply(this,arguments);return this},_animate:function(t,e,i,r){var n,s=this;e=e.toString(),i=i?fabric.util.object.clone(i):{},~t.indexOf(".")&&(n=t.split("."));var o=n?this.get(n[0])[n[1]]:this.get(t);"from"in i||(i.from=o),e=~e.indexOf("=")?o+parseFloat(e.replace("=","")):parseFloat(e),fabric.util.animate({startValue:i.from,endValue:e,byValue:i.by,easing:i.easing,duration:i.duration,abort:i.abort&&function(){return i.abort.call(s)},onChange:function(e){n?s[n[0]][n[1]]=e:s.set(t,e),r||i.onChange&&i.onChange()},onComplete:function(){r||(s.setCoords(),i.onComplete&&i.onComplete())}})}}),function(t){"use strict";function e(t,e){var i=t.origin,r=t.axis1,n=t.axis2,s=t.dimension,o=e.nearest,a=e.center,h=e.farthest;return function(){switch(this.get(i)){case o:return Math.min(this.get(r),this.get(n));case a:return Math.min(this.get(r),this.get(n))+.5*this.get(s);case h:return Math.max(this.get(r),this.get(n))}}}var i=t.fabric||(t.fabric={}),r=i.util.object.extend,n={x1:1,x2:1,y1:1,y2:1},s=i.StaticCanvas.supports("setLineDash");return i.Line?void i.warn("fabric.Line is already defined"):(i.Line=i.util.createClass(i.Object,{type:"line",x1:0,y1:0,x2:0,y2:0,initialize:function(t,e){e=e||{},t||(t=[0,0,0,0]),this.callSuper("initialize",e),this.set("x1",t[0]),this.set("y1",t[1]),this.set("x2",t[2]),this.set("y2",t[3]),this._setWidthHeight(e)},_setWidthHeight:function(t){t||(t={}),this.width=Math.abs(this.x2-this.x1),this.height=Math.abs(this.y2-this.y1),this.left="left"in t?t.left:this._getLeftToOriginX(),this.top="top"in t?t.top:this._getTopToOriginY()},_set:function(t,e){return this.callSuper("_set",t,e),"undefined"!=typeof n[t]&&this._setWidthHeight(),this},_getLeftToOriginX:e({origin:"originX",axis1:"x1",axis2:"x2",dimension:"width"},{nearest:"left",center:"center",farthest:"right"}),_getTopToOriginY:e({origin:"originY",axis1:"y1",axis2:"y2",dimension:"height"},{nearest:"top",center:"center",farthest:"bottom"}),_render:function(t,e){if(t.beginPath(),e){var i=this.getCenterPoint();t.translate(i.x-this.strokeWidth/2,i.y-this.strokeWidth/2)}if(!this.strokeDashArray||this.strokeDashArray&&s){var r=this.calcLinePoints();t.moveTo(r.x1,r.y1),t.lineTo(r.x2,r.y2)}t.lineWidth=this.strokeWidth;var n=t.strokeStyle;t.strokeStyle=this.stroke||t.fillStyle,this.stroke&&this._renderStroke(t),t.strokeStyle=n},_renderDashedStroke:function(t){var e=this.calcLinePoints();t.beginPath(),i.util.drawDashedLine(t,e.x1,e.y1,e.x2,e.y2,this.strokeDashArray),t.closePath()},toObject:function(t){return r(this.callSuper("toObject",t),this.calcLinePoints())},calcLinePoints:function(){var t=this.x1<=this.x2?-1:1,e=this.y1<=this.y2?-1:1,i=t*this.width*.5,r=e*this.height*.5,n=t*this.width*-.5,s=e*this.height*-.5;return{x1:i,x2:n,y1:r,y2:s}},toSVG:function(t){var e=this._createBaseSVGMarkup(),i={x1:this.x1,x2:this.x2,y1:this.y1,y2:this.y2};return this.group&&"path-group"===this.group.type||(i=this.calcLinePoints()),e.push("\n'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),i.Line.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),i.Line.fromElement=function(t,e){var n=i.parseAttributes(t,i.Line.ATTRIBUTE_NAMES),s=[n.x1||0,n.y1||0,n.x2||0,n.y2||0];return new i.Line(s,r(n,e))},void(i.Line.fromObject=function(t){var e=[t.x1,t.y1,t.x2,t.y2];return new i.Line(e,t)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){return"radius"in t&&t.radius>=0}var i=t.fabric||(t.fabric={}),r=Math.PI,n=i.util.object.extend;return i.Circle?void i.warn("fabric.Circle is already defined."):(i.Circle=i.util.createClass(i.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*r,initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("radius",t.radius||0),this.startAngle=t.startAngle||this.startAngle,this.endAngle=t.endAngle||this.endAngle},_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return n(this.callSuper("toObject",t),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,n=0,s=(this.endAngle-this.startAngle)%(2*r);if(0===s)this.group&&"path-group"===this.group.type&&(i=this.left+this.radius,n=this.top+this.radius),e.push("\n');else{var o=Math.cos(this.startAngle)*this.radius,a=Math.sin(this.startAngle)*this.radius,h=Math.cos(this.endAngle)*this.radius,c=Math.sin(this.endAngle)*this.radius,l=s>r?"1":"0";e.push('\n')}return t?t(e.join("")):e.join("")},_render:function(t,e){t.beginPath(),t.arc(e?this.left+this.radius:0,e?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,!1),this._renderFill(t),this._renderStroke(t)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(t){return this.radius=t,this.set("width",2*t).set("height",2*t)},complexity:function(){return 1}}),i.Circle.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),i.Circle.fromElement=function(t,r){r||(r={});var s=i.parseAttributes(t,i.Circle.ATTRIBUTE_NAMES);if(!e(s))throw new Error("value of `r` attribute is required and can not be negative");s.left=s.left||0,s.top=s.top||0;var o=new i.Circle(n(s,r));return o.left-=o.radius,o.top-=o.radius,o},void(i.Circle.fromObject=function(t){return new i.Circle(t)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});return e.Triangle?void e.warn("fabric.Triangle is already defined"):(e.Triangle=e.util.createClass(e.Object,{type:"triangle",initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("width",t.width||100).set("height",t.height||100)},_render:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,i),t.lineTo(0,-i),t.lineTo(e,i),t.closePath(),this._renderFill(t),this._renderStroke(t)},_renderDashedStroke:function(t){var i=this.width/2,r=this.height/2;t.beginPath(),e.util.drawDashedLine(t,-i,r,0,-r,this.strokeDashArray),e.util.drawDashedLine(t,0,-r,i,r,this.strokeDashArray),e.util.drawDashedLine(t,i,r,-i,r,this.strokeDashArray),t.closePath()},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.width/2,r=this.height/2,n=[-i+" "+r,"0 "+-r,i+" "+r].join(",");return e.push("'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),void(e.Triangle.fromObject=function(t){return new e.Triangle(t)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=2*Math.PI,r=e.util.object.extend;return e.Ellipse?void e.warn("fabric.Ellipse is already defined."):(e.Ellipse=e.util.createClass(e.Object,{type:"ellipse",rx:0,ry:0,initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("rx",t.rx||0),this.set("ry",t.ry||0)},_set:function(t,e){switch(this.callSuper("_set",t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(t){return r(this.callSuper("toObject",t),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,r=0;return this.group&&"path-group"===this.group.type&&(i=this.left+this.rx,r=this.top+this.ry),e.push("\n'),t?t(e.join("")):e.join("")},_render:function(t,e){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(e?this.left+this.rx:0,e?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,i,!1),t.restore(),this._renderFill(t),this._renderStroke(t)},complexity:function(){return 1}}),e.Ellipse.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),e.Ellipse.fromElement=function(t,i){i||(i={});var n=e.parseAttributes(t,e.Ellipse.ATTRIBUTE_NAMES);n.left=n.left||0,n.top=n.top||0;var s=new e.Ellipse(r(n,i));return s.top-=s.ry,s.left-=s.rx,s},void(e.Ellipse.fromObject=function(t){return new e.Ellipse(t)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;if(e.Rect)return void e.warn("fabric.Rect is already defined");var r=e.Object.prototype.stateProperties.concat();r.push("rx","ry","x","y"),e.Rect=e.util.createClass(e.Object,{stateProperties:r,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(t){t=t||{},this.callSuper("initialize",t),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(t,e){if(1===this.width&&1===this.height)return void t.fillRect(-.5,-.5,1,1);var i=this.rx?Math.min(this.rx,this.width/2):0,r=this.ry?Math.min(this.ry,this.height/2):0,n=this.width,s=this.height,o=e?this.left:-this.width/2,a=e?this.top:-this.height/2,h=0!==i||0!==r,c=.4477152502;t.beginPath(),t.moveTo(o+i,a),t.lineTo(o+n-i,a),h&&t.bezierCurveTo(o+n-c*i,a,o+n,a+c*r,o+n,a+r),t.lineTo(o+n,a+s-r),h&&t.bezierCurveTo(o+n,a+s-c*r,o+n-c*i,a+s,o+n-i,a+s),t.lineTo(o+i,a+s),h&&t.bezierCurveTo(o+c*i,a+s,o,a+s-c*r,o,a+s-r),t.lineTo(o,a+r),h&&t.bezierCurveTo(o,a+c*r,o+c*i,a,o+i,a),t.closePath(),this._renderFill(t),this._renderStroke(t)},_renderDashedStroke:function(t){var i=-this.width/2,r=-this.height/2,n=this.width,s=this.height;t.beginPath(),e.util.drawDashedLine(t,i,r,i+n,r,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r,i+n,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r+s,i,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i,r+s,i,r,this.strokeDashArray),t.closePath()},toObject:function(t){var e=i(this.callSuper("toObject",t),{rx:this.get("rx")||0,ry:this.get("ry")||0});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.left,r=this.top;return this.group&&"path-group"===this.group.type||(i=-this.width/2,r=-this.height/2),e.push("\n'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),e.Rect.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),e.Rect.fromElement=function(t,r){if(!t)return null;r=r||{};var n=e.parseAttributes(t,e.Rect.ATTRIBUTE_NAMES);n.left=n.left||0,n.top=n.top||0;var s=new e.Rect(i(r?e.util.object.clone(r):{},n));return s.visible=s.width>0&&s.height>0,s},e.Rect.fromObject=function(t){return new e.Rect(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});return e.Polyline?void e.warn("fabric.Polyline is already defined"):(e.Polyline=e.util.createClass(e.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(t,i){return e.Polygon.prototype.initialize.call(this,t,i)},_calcDimensions:function(){return e.Polygon.prototype._calcDimensions.call(this)},_applyPointOffset:function(){return e.Polygon.prototype._applyPointOffset.call(this)},toObject:function(t){return e.Polygon.prototype.toObject.call(this,t)},toSVG:function(t){return e.Polygon.prototype.toSVG.call(this,t)},_render:function(t,i){e.Polygon.prototype.commonRender.call(this,t,i)&&(this._renderFill(t),this._renderStroke(t))},_renderDashedStroke:function(t){var i,r;t.beginPath();for(var n=0,s=this.points.length;s>n;n++)i=this.points[n],r=this.points[n+1]||i,e.util.drawDashedLine(t,i.x,i.y,r.x,r.y,this.strokeDashArray)},complexity:function(){return this.get("points").length}}),e.Polyline.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(),e.Polyline.fromElement=function(t,i){if(!t)return null;i||(i={});var r=e.parsePointsAttribute(t.getAttribute("points")),n=e.parseAttributes(t,e.Polyline.ATTRIBUTE_NAMES);return new e.Polyline(r,e.util.object.extend(n,i))},void(e.Polyline.fromObject=function(t){var i=t.points;return new e.Polyline(i,t,!0)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.min,n=e.util.array.max,s=e.util.toFixed;return e.Polygon?void e.warn("fabric.Polygon is already defined"):(e.Polygon=e.util.createClass(e.Object,{type:"polygon",points:null,minX:0,minY:0,initialize:function(t,e){e=e||{},this.points=t||[],this.callSuper("initialize",e),this._calcDimensions(),"top"in e||(this.top=this.minY),"left"in e||(this.left=this.minX),this.pathOffset={x:this.minX+this.width/2,y:this.minY+this.height/2}},_calcDimensions:function(){var t=this.points,e=r(t,"x"),i=r(t,"y"),s=n(t,"x"),o=n(t,"y");this.width=s-e||0,this.height=o-i||0,this.minX=e||0,this.minY=i||0},toObject:function(t){return i(this.callSuper("toObject",t),{points:this.points.concat()})},toSVG:function(t){for(var e,i=[],r=this._createBaseSVGMarkup(),n=0,o=this.points.length;o>n;n++)i.push(s(this.points[n].x,2),",",s(this.points[n].y,2)," ");return this.group&&"path-group"===this.group.type||(e=" translate("+-this.pathOffset.x+", "+-this.pathOffset.y+") "),r.push("<",this.type," ",'points="',i.join(""),'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform(),e," ",this.getSvgTransformMatrix(),'"/>\n'),t?t(r.join("")):r.join("")},_render:function(t,e){this.commonRender(t,e)&&(this._renderFill(t),(this.stroke||this.strokeDashArray)&&(t.closePath(),this._renderStroke(t)))},commonRender:function(t,e){var i,r=this.points.length;if(!r||isNaN(this.points[r-1].y))return!1;e||t.translate(-this.pathOffset.x,-this.pathOffset.y),t.beginPath(),t.moveTo(this.points[0].x,this.points[0].y);for(var n=0;r>n;n++)i=this.points[n],t.lineTo(i.x,i.y);return!0},_renderDashedStroke:function(t){e.Polyline.prototype._renderDashedStroke.call(this,t),t.closePath()},complexity:function(){return this.points.length}}),e.Polygon.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(),e.Polygon.fromElement=function(t,r){if(!t)return null;r||(r={});var n=e.parsePointsAttribute(t.getAttribute("points")),s=e.parseAttributes(t,e.Polygon.ATTRIBUTE_NAMES);return new e.Polygon(n,i(s,r))},void(e.Polygon.fromObject=function(t){return new e.Polygon(t.points,t,!0)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.array.min,r=e.util.array.max,n=e.util.object.extend,s=Object.prototype.toString,o=e.util.drawArc,a={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},h={m:"l",M:"L"};return e.Path?void e.warn("fabric.Path is already defined"):(e.Path=e.util.createClass(e.Object,{type:"path",path:null,minX:0,minY:0,initialize:function(t,e){e=e||{},this.setOptions(e),t||(t=[]);var i="[object Array]"===s.call(t);this.path=i?t:t.match&&t.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi),this.path&&(i||(this.path=this._parsePath()),this._setPositionDimensions(e),e.sourcePath&&this.setSourcePath(e.sourcePath))},_setPositionDimensions:function(t){var e=this._parseDimensions();this.minX=e.left,this.minY=e.top,this.width=e.width,this.height=e.height,"undefined"==typeof t.left&&(this.left=e.left+("center"===this.originX?this.width/2:"right"===this.originX?this.width:0)),"undefined"==typeof t.top&&(this.top=e.top+("center"===this.originY?this.height/2:"bottom"===this.originY?this.height:0)),this.pathOffset=this.pathOffset||{x:this.minX+this.width/2,y:this.minY+this.height/2}},_render:function(t){var e,i,r,n=null,s=0,a=0,h=0,c=0,l=0,u=0,f=-this.pathOffset.x,d=-this.pathOffset.y;this.group&&"path-group"===this.group.type&&(f=0,d=0),t.beginPath();for(var g=0,p=this.path.length;p>g;++g){switch(e=this.path[g],e[0]){case"l":h+=e[1],c+=e[2],t.lineTo(h+f,c+d);break;case"L":h=e[1],c=e[2],t.lineTo(h+f,c+d);break;case"h":h+=e[1],t.lineTo(h+f,c+d);break;case"H":h=e[1],t.lineTo(h+f,c+d);break;case"v":c+=e[1],t.lineTo(h+f,c+d);break;case"V":c=e[1],t.lineTo(h+f,c+d);break;case"m":h+=e[1],c+=e[2],s=h,a=c,t.moveTo(h+f,c+d);break;case"M":h=e[1],c=e[2],s=h,a=c,t.moveTo(h+f,c+d);break;case"c":i=h+e[5],r=c+e[6],l=h+e[3],u=c+e[4],t.bezierCurveTo(h+e[1]+f,c+e[2]+d,l+f,u+d,i+f,r+d),h=i,c=r;break;case"C":h=e[5],c=e[6],l=e[3],u=e[4],t.bezierCurveTo(e[1]+f,e[2]+d,l+f,u+d,h+f,c+d);break;case"s":i=h+e[3],r=c+e[4],null===n[0].match(/[CcSs]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.bezierCurveTo(l+f,u+d,h+e[1]+f,c+e[2]+d,i+f,r+d),l=h+e[1],u=c+e[2],h=i,c=r;break;case"S":i=e[3],r=e[4],null===n[0].match(/[CcSs]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.bezierCurveTo(l+f,u+d,e[1]+f,e[2]+d,i+f,r+d),h=i,c=r,l=e[1],u=e[2];break;case"q":i=h+e[3],r=c+e[4],l=h+e[1],u=c+e[2],t.quadraticCurveTo(l+f,u+d,i+f,r+d),h=i,c=r;break;case"Q":i=e[3],r=e[4],t.quadraticCurveTo(e[1]+f,e[2]+d,i+f,r+d),h=i,c=r,l=e[1],u=e[2];break;case"t":i=h+e[1],r=c+e[2],null===n[0].match(/[QqTt]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.quadraticCurveTo(l+f,u+d,i+f,r+d),h=i,c=r;break;case"T":i=e[1],r=e[2],null===n[0].match(/[QqTt]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.quadraticCurveTo(l+f,u+d,i+f,r+d),h=i,c=r;break;case"a":o(t,h+f,c+d,[e[1],e[2],e[3],e[4],e[5],e[6]+h+f,e[7]+c+d]),h+=e[6],c+=e[7];break;case"A":o(t,h+f,c+d,[e[1],e[2],e[3],e[4],e[5],e[6]+f,e[7]+d]),h=e[6],c=e[7];break;case"z":case"Z":h=s,c=a,t.closePath()}n=e}this._renderFill(t),this._renderStroke(t)},toString:function(){return"#"},toObject:function(t){var e=n(this.callSuper("toObject",t),{path:this.path.map(function(t){return t.slice()}),pathOffset:this.pathOffset});return this.sourcePath&&(e.sourcePath=this.sourcePath),this.transformMatrix&&(e.transformMatrix=this.transformMatrix),e},toDatalessObject:function(t){var e=this.toObject(t);return this.sourcePath&&(e.path=this.sourcePath),delete e.sourcePath,e},toSVG:function(t){for(var e=[],i=this._createBaseSVGMarkup(),r="",n=0,s=this.path.length;s>n;n++)e.push(this.path[n].join(" "));var o=e.join(" ");return this.group&&"path-group"===this.group.type||(r=" translate("+-this.pathOffset.x+", "+-this.pathOffset.y+") "),i.push("\n"),t?t(i.join("")):i.join("")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,n,s=[],o=[],c=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,l=0,u=this.path.length;u>l;l++){for(t=this.path[l],r=t.slice(1).trim(),o.length=0;i=c.exec(r);)o.push(i[0]);n=[t.charAt(0)];for(var f=0,d=o.length;d>f;f++)e=parseFloat(o[f]),isNaN(e)||n.push(e);var g=n[0],p=a[g.toLowerCase()],v=h[g]||g;if(n.length-1>p)for(var m=1,b=n.length;b>m;m+=p)s.push([g].concat(n.slice(m,m+p))),g=v;else s.push(n)}return s},_parseDimensions:function(){for(var t,n,s,o,a=[],h=[],c=null,l=0,u=0,f=0,d=0,g=0,p=0,v=0,m=this.path.length;m>v;++v){switch(t=this.path[v],t[0]){case"l":f+=t[1],d+=t[2],o=[];break;case"L":f=t[1],d=t[2],o=[];break;case"h":f+=t[1],o=[];break;case"H":f=t[1],o=[];break;case"v":d+=t[1],o=[];break;case"V":d=t[1],o=[];break;case"m":f+=t[1],d+=t[2],l=f,u=d,o=[];break;case"M":f=t[1],d=t[2],l=f,u=d,o=[];break;case"c":n=f+t[5],s=d+t[6],g=f+t[3],p=d+t[4],o=e.util.getBoundsOfCurve(f,d,f+t[1],d+t[2],g,p,n,s),f=n,d=s;break;case"C":f=t[5],d=t[6],g=t[3],p=t[4],o=e.util.getBoundsOfCurve(f,d,t[1],t[2],g,p,f,d);break;case"s":n=f+t[3],s=d+t[4],null===c[0].match(/[CcSs]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,f+t[1],d+t[2],n,s),g=f+t[1],p=d+t[2],f=n,d=s;break;case"S":n=t[3],s=t[4],null===c[0].match(/[CcSs]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,t[1],t[2],n,s),f=n,d=s,g=t[1],p=t[2];break;case"q":n=f+t[3],s=d+t[4],g=f+t[1],p=d+t[2],o=e.util.getBoundsOfCurve(f,d,g,p,g,p,n,s),f=n,d=s;break;case"Q":g=t[1],p=t[2],o=e.util.getBoundsOfCurve(f,d,g,p,g,p,t[3],t[4]),f=t[3],d=t[4];break;case"t":n=f+t[1],s=d+t[2],null===c[0].match(/[QqTt]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,g,p,n,s),f=n,d=s;break;case"T":n=t[1],s=t[2],null===c[0].match(/[QqTt]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,g,p,n,s),f=n,d=s;break;case"a":o=e.util.getBoundsOfArc(f,d,t[1],t[2],t[3],t[4],t[5],t[6]+f,t[7]+d),f+=t[6],d+=t[7];break;case"A":o=e.util.getBoundsOfArc(f,d,t[1],t[2],t[3],t[4],t[5],t[6],t[7]),f=t[6],d=t[7];break;case"z":case"Z":f=l,d=u}c=t,o.forEach(function(t){a.push(t.x),h.push(t.y)}),a.push(f),h.push(d)}var b=i(a)||0,y=i(h)||0,_=r(a)||0,x=r(h)||0,S=_-b,C=x-y,w={left:b,top:y,width:S,height:C};return w}}),e.Path.fromObject=function(t,i){"string"==typeof t.path?e.loadSVGFromURL(t.path,function(r){var n=r[0],s=t.path;delete t.path,e.util.object.extend(n,t),n.setSourcePath(s),i(n)}):i(new e.Path(t.path,t))},e.Path.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(["d"]),e.Path.fromElement=function(t,i,r){var s=e.parseAttributes(t,e.Path.ATTRIBUTE_NAMES);i&&i(new e.Path(s.d,n(s,r)))},void(e.Path.async=!0))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.invoke,n=e.Object.prototype.toObject;return e.PathGroup?void e.warn("fabric.PathGroup is already defined"):(e.PathGroup=e.util.createClass(e.Path,{type:"path-group",fill:"",initialize:function(t,e){e=e||{},this.paths=t||[];for(var i=this.paths.length;i--;)this.paths[i].group=this;e.toBeParsed&&(this.parseDimensionsFromPaths(e),delete e.toBeParsed),this.setOptions(e),this.setCoords(),e.sourcePath&&this.setSourcePath(e.sourcePath)},parseDimensionsFromPaths:function(t){for(var i,r,n,s,o,a,h=[],c=[],l=this.paths.length;l--;){n=this.paths[l],s=n.height+n.strokeWidth,o=n.width+n.strokeWidth,i=[{x:n.left,y:n.top},{x:n.left+o,y:n.top},{x:n.left,y:n.top+s},{x:n.left+o,y:n.top+s}],a=this.paths[l].transformMatrix;for(var u=0;ui;++i)this.paths[i].render(t,!0);this.clipTo&&t.restore(),t.restore()}},_set:function(t,e){if("fill"===t&&e&&this.isSameColor())for(var i=this.paths.length;i--;)this.paths[i]._set(t,e);return this.callSuper("_set",t,e)},toObject:function(t){var e=i(n.call(this,t),{paths:r(this.getObjects(),"toObject",t)});return this.sourcePath&&(e.sourcePath=this.sourcePath),e},toDatalessObject:function(t){var e=this.toObject(t);return this.sourcePath&&(e.paths=this.sourcePath),e},toSVG:function(t){var e=this.getObjects(),i=this.getPointByOrigin("left","top"),r="translate("+i.x+" "+i.y+")",n=this._createBaseSVGMarkup();n.push("\n");for(var s=0,o=e.length;o>s;s++)n.push(" ",e[s].toSVG(t));return n.push("\n"),t?t(n.join("")):n.join("")},toString:function(){return"#"},isSameColor:function(){var t=this.getObjects()[0].get("fill")||"";return"string"!=typeof t?!1:(t=t.toLowerCase(),this.getObjects().every(function(e){var i=e.get("fill")||"";return"string"==typeof i&&i.toLowerCase()===t}))},complexity:function(){return this.paths.reduce(function(t,e){return t+(e&&e.complexity?e.complexity():0)},0)},getObjects:function(){return this.paths}}),e.PathGroup.fromObject=function(t,i){"string"==typeof t.paths?e.loadSVGFromURL(t.paths,function(r){var n=t.paths;delete t.paths;var s=e.util.groupSVGElements(r,t,n);i(s)}):e.util.enlivenObjects(t.paths,function(r){delete t.paths,i(new e.PathGroup(r,t))})},void(e.PathGroup.async=!0))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.min,n=e.util.array.max,s=e.util.array.invoke;if(!e.Group){var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};e.Group=e.util.createClass(e.Object,e.Collection,{type:"group",strokeWidth:0,initialize:function(t,e,i){e=e||{},this._objects=[],i&&this.callSuper("initialize",e),this._objects=t||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;this.originalState={},e.originX&&(this.originX=e.originX),e.originY&&(this.originY=e.originY),i?this._updateObjectsCoords(!0):(this._calcBounds(),this._updateObjectsCoords(),this.callSuper("initialize",e)),this.setCoords(),this.saveCoords()},_updateObjectsCoords:function(t){for(var e=this._objects.length;e--;)this._updateObjectCoords(this._objects[e],t)},_updateObjectCoords:function(t,e){if(t.__origHasControls=t.hasControls,t.hasControls=!1,!e){var i=t.getLeft(),r=t.getTop(),n=this.getCenterPoint();t.set({originalLeft:i,originalTop:r,left:i-n.x,top:r-n.y}),t.setCoords()}},toString:function(){return"#"},addWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),t&&(this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this.forEachObject(this._setObjectActive,this),this._calcBounds(),this._updateObjectsCoords(),this},_setObjectActive:function(t){t.set("active",!0),t.group=this},removeWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),this.forEachObject(this._setObjectActive,this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this},_onObjectAdded:function(t){t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){delete t.group,t.set("active",!1)},delegatedProperties:{fill:!0,stroke:!0,strokeWidth:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textAlign:!0,backgroundColor:!0},_set:function(t,e){var i=this._objects.length;if(this.delegatedProperties[t]||"canvas"===t)for(;i--;)this._objects[i].set(t,e);else for(;i--;)this._objects[i].setOnGroup(t,e);this.callSuper("_set",t,e)},toObject:function(t){return i(this.callSuper("toObject",t),{objects:s(this._objects,"toObject",t)})},render:function(t){if(this.visible){t.save(),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.transform(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t);for(var i=0,r=this._objects.length;r>i;i++)this._renderObject(this._objects[i],t);this.clipTo&&t.restore(),t.restore()}},_renderControls:function(t,e){this.callSuper("_renderControls",t,e);for(var i=0,r=this._objects.length;r>i;i++)this._objects[i]._renderControls(t)},_renderObject:function(t,e){if(t.visible){var i=t.hasRotatingPoint;t.hasRotatingPoint=!1,t.render(e),t.hasRotatingPoint=i}},_restoreObjectsState:function(){return this._objects.forEach(this._restoreObjectState,this), -this},realizeTransform:function(t){var i=t.calcTransformMatrix(),r=e.util.qrDecompose(i),n=new e.Point(r.translateX,r.translateY);return t.scaleX=r.scaleX,t.scaleY=r.scaleY,t.skewX=r.skewX,t.skewY=r.skewY,t.angle=r.angle,t.flipX=!1,t.flipY=!1,t.setPositionByOrigin(n,"center","center"),t},_restoreObjectState:function(t){return this.realizeTransform(t),t.setCoords(),t.hasControls=t.__origHasControls,delete t.__origHasControls,t.set("active",!1),delete t.group,this},destroy:function(){return this._restoreObjectsState()},saveCoords:function(){return this._originalLeft=this.get("left"),this._originalTop=this.get("top"),this},hasMoved:function(){return this._originalLeft!==this.get("left")||this._originalTop!==this.get("top")},setObjectsCoords:function(){return this.forEachObject(function(t){t.setCoords()}),this},_calcBounds:function(t){for(var e,i,r,n=[],s=[],o=["tr","br","bl","tl"],a=0,h=this._objects.length,c=o.length;h>a;++a)for(e=this._objects[a],e.setCoords(),r=0;c>r;r++)i=o[r],n.push(e.oCoords[i].x),s.push(e.oCoords[i].y);this.set(this._getBounds(n,s,t))},_getBounds:function(t,i,s){var o=e.util.invertTransform(this.getViewportTransform()),a=e.util.transformPoint(new e.Point(r(t),r(i)),o),h=e.util.transformPoint(new e.Point(n(t),n(i)),o),c={width:h.x-a.x||0,height:h.y-a.y||0};return s||(c.left=a.x||0,c.top=a.y||0,"center"===this.originX&&(c.left+=c.width/2),"right"===this.originX&&(c.left+=c.width),"center"===this.originY&&(c.top+=c.height/2),"bottom"===this.originY&&(c.top+=c.height)),c},toSVG:function(t){var e=this._createBaseSVGMarkup();e.push('\n');for(var i=0,r=this._objects.length;r>i;i++)e.push(" ",this._objects[i].toSVG(t));return e.push("\n"),t?t(e.join("")):e.join("")},get:function(t){if(t in o){if(this[t])return this[t];for(var e=0,i=this._objects.length;i>e;e++)if(this._objects[e][t])return!0;return!1}return t in this.delegatedProperties?this._objects[0]&&this._objects[0].get(t):this[t]}}),e.Group.fromObject=function(t,i){e.util.enlivenObjects(t.objects,function(r){delete t.objects,i&&i(new e.Group(r,t,!0))})},e.Group.async=!0}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=fabric.util.object.extend;return t.fabric||(t.fabric={}),t.fabric.Image?void fabric.warn("fabric.Image is already defined."):(fabric.Image=fabric.util.createClass(fabric.Object,{type:"image",crossOrigin:"",alignX:"none",alignY:"none",meetOrSlice:"meet",strokeWidth:0,_lastScaleX:1,_lastScaleY:1,initialize:function(t,e){e||(e={}),this.filters=[],this.resizeFilters=[],this.callSuper("initialize",e),this._initElement(t,e)},getElement:function(){return this._element},setElement:function(t,e,i){return this._element=t,this._originalElement=t,this._initConfig(i),0!==this.filters.length?this.applyFilters(e):e&&e(),this},setCrossOrigin:function(t){return this.crossOrigin=t,this._element.crossOrigin=t,this},getOriginalSize:function(){var t=this.getElement();return{width:t.width,height:t.height}},_stroke:function(t){t.save(),this._setStrokeStyles(t),t.beginPath(),t.strokeRect(-this.width/2,-this.height/2,this.width,this.height),t.closePath(),t.restore()},_renderDashedStroke:function(t){var e=-this.width/2,i=-this.height/2,r=this.width,n=this.height;t.save(),this._setStrokeStyles(t),t.beginPath(),fabric.util.drawDashedLine(t,e,i,e+r,i,this.strokeDashArray),fabric.util.drawDashedLine(t,e+r,i,e+r,i+n,this.strokeDashArray),fabric.util.drawDashedLine(t,e+r,i+n,e,i+n,this.strokeDashArray),fabric.util.drawDashedLine(t,e,i+n,e,i,this.strokeDashArray),t.closePath(),t.restore()},toObject:function(t){var i=[],r=this._originalElement;this.filters.forEach(function(t){t&&i.push(t.toObject())});var n=e(this.callSuper("toObject",t),{src:r?r.src||r._src:"",filters:i,crossOrigin:this.crossOrigin,alignX:this.alignX,alignY:this.alignY,meetOrSlice:this.meetOrSlice});return this.resizeFilters.length>0&&(n.resizeFilters=this.resizeFilters.map(function(t){return t&&t.toObject()})),this.includeDefaultValues||this._removeDefaultValues(n),n},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=-this.width/2,r=-this.height/2,n="none";if(this.group&&"path-group"===this.group.type&&(i=this.left,r=this.top),"none"!==this.alignX&&"none"!==this.alignY&&(n="x"+this.alignX+"Y"+this.alignY+" "+this.meetOrSlice),e.push('\n','\n"),this.stroke||this.strokeDashArray){var s=this.fill;this.fill=null,e.push("\n'),this.fill=s}return e.push("\n"),t?t(e.join("")):e.join("")},getSrc:function(){return this.getElement()?this.getElement().src||this.getElement()._src:void 0},setSrc:function(t,e,i){fabric.util.loadImage(t,function(t){return this.setElement(t,e,i)},this,i&&i.crossOrigin)},toString:function(){return'#'},clone:function(t,e){this.constructor.fromObject(this.toObject(e),t)},applyFilters:function(t,e,i,r){if(e=e||this.filters,i=i||this._originalElement){var n=i,s=fabric.util.createCanvasElement(),o=fabric.util.createImage(),a=this;return s.width=n.width,s.height=n.height,s.getContext("2d").drawImage(n,0,0,n.width,n.height),0===e.length?(this._element=i,t&&t(),s):(e.forEach(function(t){t&&t.applyTo(s,t.scaleX||a.scaleX,t.scaleY||a.scaleY),!r&&t&&"Resize"===t.type&&(a.width*=t.scaleX,a.height*=t.scaleY)}),o.width=s.width,o.height=s.height,fabric.isLikelyNode?(o.src=s.toBuffer(void 0,fabric.Image.pngCompression),a._element=o,!r&&(a._filteredEl=o),t&&t()):(o.onload=function(){a._element=o,!r&&(a._filteredEl=o),t&&t(),o.onload=s=n=null},o.src=s.toDataURL("image/png")),s)}},_render:function(t,e){var i,r,n,s=this._findMargins();i=e?this.left:-this.width/2,r=e?this.top:-this.height/2,"slice"===this.meetOrSlice&&(t.beginPath(),t.rect(i,r,this.width,this.height),t.clip()),this.isMoving===!1&&this.resizeFilters.length&&this._needsResize()?(this._lastScaleX=this.scaleX,this._lastScaleY=this.scaleY,n=this.applyFilters(null,this.resizeFilters,this._filteredEl||this._originalElement,!0)):n=this._element,n&&t.drawImage(n,i+s.marginX,r+s.marginY,s.width,s.height),this._renderStroke(t)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_findMargins:function(){var t,e,i=this.width,r=this.height,n=0,s=0;return("none"!==this.alignX||"none"!==this.alignY)&&(t=[this.width/this._element.width,this.height/this._element.height],e="meet"===this.meetOrSlice?Math.min.apply(null,t):Math.max.apply(null,t),i=this._element.width*e,r=this._element.height*e,"Mid"===this.alignX&&(n=(this.width-i)/2),"Max"===this.alignX&&(n=this.width-i),"Mid"===this.alignY&&(s=(this.height-r)/2),"Max"===this.alignY&&(s=this.height-r)),{width:i,height:r,marginX:n,marginY:s}},_resetWidthHeight:function(){var t=this.getElement();this.set("width",t.width),this.set("height",t.height)},_initElement:function(t,e){this.setElement(fabric.util.getById(t),null,e),fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(t){t||(t={}),this.setOptions(t),this._setWidthHeight(t),this._element&&this.crossOrigin&&(this._element.crossOrigin=this.crossOrigin)},_initFilters:function(t,e){t&&t.length?fabric.util.enlivenObjects(t,function(t){e&&e(t)},"fabric.Image.filters"):e&&e()},_setWidthHeight:function(t){this.width="width"in t?t.width:this.getElement()?this.getElement().width||0:0,this.height="height"in t?t.height:this.getElement()?this.getElement().height||0:0},complexity:function(){return 1}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(t,e){fabric.util.loadImage(t.src,function(i){fabric.Image.prototype._initFilters.call(t,t.filters,function(r){t.filters=r||[],fabric.Image.prototype._initFilters.call(t,t.resizeFilters,function(r){t.resizeFilters=r||[];var n=new fabric.Image(i,t);e&&e(n)})})},null,t.crossOrigin)},fabric.Image.fromURL=function(t,e,i){fabric.util.loadImage(t,function(t){e&&e(new fabric.Image(t,i))},null,i&&i.crossOrigin)},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".split(" ")),fabric.Image.fromElement=function(t,i,r){var n,s=fabric.parseAttributes(t,fabric.Image.ATTRIBUTE_NAMES);s.preserveAspectRatio&&(n=fabric.util.parsePreserveAspectRatioAttribute(s.preserveAspectRatio),e(s,n)),fabric.Image.fromURL(s["xlink:href"],i,e(r?fabric.util.object.clone(r):{},s))},fabric.Image.async=!0,void(fabric.Image.pngCompression=1))}("undefined"!=typeof exports?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var t=this.getAngle()%360;return t>0?90*Math.round((t-1)/90):90*Math.round(t/90)},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(t){t=t||{};var e=function(){},i=t.onComplete||e,r=t.onChange||e,n=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(t){n.setAngle(t),r()},onComplete:function(){n.setCoords(),i()},onStart:function(){n.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(t){return t.straighten(),this.renderAll(),this},fxStraightenObject:function(t){return t.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(t){t&&this.setOptions(t)},setOptions:function(t){for(var e in t)this[e]=t[e]},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Brightness=e.util.createClass(e.Image.filters.BaseFilter,{type:"Brightness",initialize:function(t){t=t||{},this.brightness=t.brightness||0},applyTo:function(t){for(var e=t.getContext("2d"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.brightness,s=0,o=r.length;o>s;s+=4)r[s]+=n,r[s+1]+=n,r[s+2]+=n;e.putImageData(i,0,0)},toObject:function(){return i(this.callSuper("toObject"),{brightness:this.brightness})}}),e.Image.filters.Brightness.fromObject=function(t){return new e.Image.filters.Brightness(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Convolute=e.util.createClass(e.Image.filters.BaseFilter,{type:"Convolute",initialize:function(t){t=t||{},this.opaque=t.opaque,this.matrix=t.matrix||[0,0,0,0,1,0,0,0,0]},applyTo:function(t){for(var e,i,r,n,s,o,a,h,c,l=this.matrix,u=t.getContext("2d"),f=u.getImageData(0,0,t.width,t.height),d=Math.round(Math.sqrt(l.length)),g=Math.floor(d/2),p=f.data,v=f.width,m=f.height,b=u.createImageData(v,m),y=b.data,_=this.opaque?1:0,x=0;m>x;x++)for(var S=0;v>S;S++){s=4*(x*v+S),e=0,i=0,r=0,n=0;for(var C=0;d>C;C++)for(var w=0;d>w;w++)a=x+C-g,o=S+w-g,0>a||a>m||0>o||o>v||(h=4*(a*v+o),c=l[C*d+w],e+=p[h]*c,i+=p[h+1]*c,r+=p[h+2]*c,n+=p[h+3]*c);y[s]=e,y[s+1]=i,y[s+2]=r,y[s+3]=n+_*(255-n)}u.putImageData(b,0,0)},toObject:function(){return i(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}}),e.Image.filters.Convolute.fromObject=function(t){return new e.Image.filters.Convolute(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.GradientTransparency=e.util.createClass(e.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(t){t=t||{},this.threshold=t.threshold||100},applyTo:function(t){for(var e=t.getContext("2d"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.threshold,s=r.length,o=0,a=r.length;a>o;o+=4)r[o+3]=n+255*(s-o)/s;e.putImageData(i,0,0)},toObject:function(){return i(this.callSuper("toObject"),{threshold:this.threshold})}}),e.Image.filters.GradientTransparency.fromObject=function(t){return new e.Image.filters.GradientTransparency(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.Image.filters.Grayscale=e.util.createClass(e.Image.filters.BaseFilter,{type:"Grayscale",applyTo:function(t){for(var e,i=t.getContext("2d"),r=i.getImageData(0,0,t.width,t.height),n=r.data,s=r.width*r.height*4,o=0;s>o;)e=(n[o]+n[o+1]+n[o+2])/3,n[o]=e,n[o+1]=e,n[o+2]=e,o+=4;i.putImageData(r,0,0)}}),e.Image.filters.Grayscale.fromObject=function(){return new e.Image.filters.Grayscale}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.Image.filters.Invert=e.util.createClass(e.Image.filters.BaseFilter,{type:"Invert",applyTo:function(t){var e,i=t.getContext("2d"),r=i.getImageData(0,0,t.width,t.height),n=r.data,s=n.length;for(e=0;s>e;e+=4)n[e]=255-n[e],n[e+1]=255-n[e+1],n[e+2]=255-n[e+2];i.putImageData(r,0,0)}}),e.Image.filters.Invert.fromObject=function(){return new e.Image.filters.Invert}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Mask=e.util.createClass(e.Image.filters.BaseFilter,{type:"Mask",initialize:function(t){t=t||{},this.mask=t.mask,this.channel=[0,1,2,3].indexOf(t.channel)>-1?t.channel:0},applyTo:function(t){if(this.mask){var i,r=t.getContext("2d"),n=r.getImageData(0,0,t.width,t.height),s=n.data,o=this.mask.getElement(),a=e.util.createCanvasElement(),h=this.channel,c=n.width*n.height*4;a.width=t.width,a.height=t.height,a.getContext("2d").drawImage(o,0,0,t.width,t.height);var l=a.getContext("2d").getImageData(0,0,t.width,t.height),u=l.data;for(i=0;c>i;i+=4)s[i+3]=u[i+h];r.putImageData(n,0,0)}},toObject:function(){return i(this.callSuper("toObject"),{mask:this.mask.toObject(),channel:this.channel})}}),e.Image.filters.Mask.fromObject=function(t,i){e.util.loadImage(t.mask.src,function(r){t.mask=new e.Image(r,t.mask),i&&i(new e.Image.filters.Mask(t))})},e.Image.filters.Mask.async=!0}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Noise=e.util.createClass(e.Image.filters.BaseFilter,{type:"Noise",initialize:function(t){t=t||{},this.noise=t.noise||0},applyTo:function(t){for(var e,i=t.getContext("2d"),r=i.getImageData(0,0,t.width,t.height),n=r.data,s=this.noise,o=0,a=n.length;a>o;o+=4)e=(.5-Math.random())*s,n[o]+=e,n[o+1]+=e,n[o+2]+=e;i.putImageData(r,0,0)},toObject:function(){return i(this.callSuper("toObject"),{noise:this.noise})}}),e.Image.filters.Noise.fromObject=function(t){return new e.Image.filters.Noise(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Pixelate=e.util.createClass(e.Image.filters.BaseFilter,{type:"Pixelate",initialize:function(t){t=t||{},this.blocksize=t.blocksize||4},applyTo:function(t){var e,i,r,n,s,o,a,h=t.getContext("2d"),c=h.getImageData(0,0,t.width,t.height),l=c.data,u=c.height,f=c.width;for(i=0;u>i;i+=this.blocksize)for(r=0;f>r;r+=this.blocksize){e=4*i*f+4*r,n=l[e],s=l[e+1],o=l[e+2],a=l[e+3];for(var d=i,g=i+this.blocksize;g>d;d++)for(var p=r,v=r+this.blocksize;v>p;p++)e=4*d*f+4*p,l[e]=n,l[e+1]=s,l[e+2]=o,l[e+3]=a}h.putImageData(c,0,0)},toObject:function(){return i(this.callSuper("toObject"),{blocksize:this.blocksize})}}),e.Image.filters.Pixelate.fromObject=function(t){return new e.Image.filters.Pixelate(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.RemoveWhite=e.util.createClass(e.Image.filters.BaseFilter,{type:"RemoveWhite",initialize:function(t){t=t||{},this.threshold=t.threshold||30,this.distance=t.distance||20},applyTo:function(t){for(var e,i,r,n=t.getContext("2d"),s=n.getImageData(0,0,t.width,t.height),o=s.data,a=this.threshold,h=this.distance,c=255-a,l=Math.abs,u=0,f=o.length;f>u;u+=4)e=o[u],i=o[u+1],r=o[u+2],e>c&&i>c&&r>c&&l(e-i)e;e+=4)i=.3*s[e]+.59*s[e+1]+.11*s[e+2],s[e]=i+100,s[e+1]=i+50,s[e+2]=i+255;r.putImageData(n,0,0)}}),e.Image.filters.Sepia.fromObject=function(){return new e.Image.filters.Sepia}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.Image.filters.Sepia2=e.util.createClass(e.Image.filters.BaseFilter,{type:"Sepia2",applyTo:function(t){var e,i,r,n,s=t.getContext("2d"),o=s.getImageData(0,0,t.width,t.height),a=o.data,h=a.length;for(e=0;h>e;e+=4)i=a[e],r=a[e+1],n=a[e+2],a[e]=(.393*i+.769*r+.189*n)/1.351,a[e+1]=(.349*i+.686*r+.168*n)/1.203,a[e+2]=(.272*i+.534*r+.131*n)/2.14;s.putImageData(o,0,0)}}),e.Image.filters.Sepia2.fromObject=function(){return new e.Image.filters.Sepia2}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Tint=e.util.createClass(e.Image.filters.BaseFilter,{type:"Tint",initialize:function(t){t=t||{},this.color=t.color||"#000000",this.opacity="undefined"!=typeof t.opacity?t.opacity:new e.Color(this.color).getAlpha()},applyTo:function(t){var i,r,n,s,o,a,h,c,l,u=t.getContext("2d"),f=u.getImageData(0,0,t.width,t.height),d=f.data,g=d.length;for(l=new e.Color(this.color).getSource(),r=l[0]*this.opacity,n=l[1]*this.opacity,s=l[2]*this.opacity,c=1-this.opacity,i=0;g>i;i+=4)o=d[i],a=d[i+1],h=d[i+2],d[i]=r+o*c,d[i+1]=n+a*c,d[i+2]=s+h*c;u.putImageData(f,0,0)},toObject:function(){return i(this.callSuper("toObject"),{color:this.color,opacity:this.opacity})}}),e.Image.filters.Tint.fromObject=function(t){return new e.Image.filters.Tint(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Multiply=e.util.createClass(e.Image.filters.BaseFilter,{type:"Multiply",initialize:function(t){t=t||{},this.color=t.color||"#000000"},applyTo:function(t){var i,r,n=t.getContext("2d"),s=n.getImageData(0,0,t.width,t.height),o=s.data,a=o.length;for(r=new e.Color(this.color).getSource(),i=0;a>i;i+=4)o[i]*=r[0]/255,o[i+1]*=r[1]/255,o[i+2]*=r[2]/255;n.putImageData(s,0,0)},toObject:function(){return i(this.callSuper("toObject"),{color:this.color})}}),e.Image.filters.Multiply.fromObject=function(t){return new e.Image.filters.Multiply(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric;e.Image.filters.Blend=e.util.createClass({type:"Blend",initialize:function(t){t=t||{},this.color=t.color||"#000",this.image=t.image||!1,this.mode=t.mode||"multiply",this.alpha=t.alpha||1},applyTo:function(t){var i,r,n,s,o,a,h,c,l,u,f=t.getContext("2d"),d=f.getImageData(0,0,t.width,t.height),g=d.data,p=!1;if(this.image){p=!0;var v=e.util.createCanvasElement();v.width=this.image.width,v.height=this.image.height;var m=new e.StaticCanvas(v);m.add(this.image);var b=m.getContext("2d");u=b.getImageData(0,0,m.width,m.height).data}else u=new e.Color(this.color).getSource(),i=u[0]*this.alpha,r=u[1]*this.alpha,n=u[2]*this.alpha;for(var y=0,_=g.length;_>y;y+=4)switch(s=g[y],o=g[y+1],a=g[y+2],p&&(i=u[y]*this.alpha,r=u[y+1]*this.alpha,n=u[y+2]*this.alpha),this.mode){case"multiply":g[y]=s*i/255,g[y+1]=o*r/255,g[y+2]=a*n/255;break;case"screen":g[y]=1-(1-s)*(1-i),g[y+1]=1-(1-o)*(1-r),g[y+2]=1-(1-a)*(1-n);break;case"add":g[y]=Math.min(255,s+i),g[y+1]=Math.min(255,o+r),g[y+2]=Math.min(255,a+n);break;case"diff":case"difference":g[y]=Math.abs(s-i),g[y+1]=Math.abs(o-r),g[y+2]=Math.abs(a-n);break;case"subtract":h=s-i,c=o-r,l=a-n,g[y]=0>h?0:h,g[y+1]=0>c?0:c,g[y+2]=0>l?0:l;break;case"darken":g[y]=Math.min(s,i),g[y+1]=Math.min(o,r),g[y+2]=Math.min(a,n);break;case"lighten":g[y]=Math.max(s,i),g[y+1]=Math.max(o,r),g[y+2]=Math.max(a,n)}f.putImageData(d,0,0)},toObject:function(){return{color:this.color,image:this.image,mode:this.mode,alpha:this.alpha}}}),e.Image.filters.Blend.fromObject=function(t){return new e.Image.filters.Blend(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=Math.pow,r=Math.floor,n=Math.sqrt,s=Math.abs,o=Math.max,a=Math.round,h=Math.sin,c=Math.ceil;e.Image.filters.Resize=e.util.createClass(e.Image.filters.BaseFilter,{type:"Resize",resizeType:"hermite",scaleX:0,scaleY:0,lanczosLobes:3,applyTo:function(t,e,i){this.rcpScaleX=1/e,this.rcpScaleY=1/i;var r,n=t.width,s=t.height,o=a(n*e),h=a(s*i);"sliceHack"===this.resizeType&&(r=this.sliceByTwo(t,n,s,o,h)),"hermite"===this.resizeType&&(r=this.hermiteFastResize(t,n,s,o,h)),"bilinear"===this.resizeType&&(r=this.bilinearFiltering(t,n,s,o,h)),"lanczos"===this.resizeType&&(r=this.lanczosResize(t,n,s,o,h)),t.width=o,t.height=h,t.getContext("2d").putImageData(r,0,0)},sliceByTwo:function(t,i,n,s,a){var h,c=t.getContext("2d"),l=.5,u=.5,f=1,d=1,g=!1,p=!1,v=i,m=n,b=e.util.createCanvasElement(),y=b.getContext("2d");for(s=r(s),a=r(a),b.width=o(s,i),b.height=o(a,n),s>i&&(l=2,f=-1),a>n&&(u=2,d=-1),h=c.getImageData(0,0,i,n),t.width=o(s,i),t.height=o(a,n),c.putImageData(h,0,0);!g||!p;)i=v,n=m,s*ft)return 0;if(e*=Math.PI,s(e)<1e-16)return 1;var i=e/t;return h(e)*h(i)/e/i}}function f(t){var h,c,u,d,g,j,A,P,M,L,D;for(T.x=(t+.5)*y,k.x=r(T.x),h=0;l>h;h++){for(T.y=(h+.5)*_,k.y=r(T.y),g=0,j=0,A=0,P=0,M=0,c=k.x-C;c<=k.x+C;c++)if(!(0>c||c>=e)){L=r(1e3*s(c-T.x)),O[L]||(O[L]={});for(var E=k.y-w;E<=k.y+w;E++)0>E||E>=o||(D=r(1e3*s(E-T.y)),O[L][D]||(O[L][D]=b(n(i(L*x,2)+i(D*S,2))/1e3)),u=O[L][D],u>0&&(d=4*(E*e+c),g+=u,j+=u*v[d],A+=u*v[d+1],P+=u*v[d+2],M+=u*v[d+3]))}d=4*(h*a+t),m[d]=j/g,m[d+1]=A/g,m[d+2]=P/g,m[d+3]=M/g}return++tf;f++)for(d=0;n>d;d++)for(l=r(_*d),u=r(x*f),g=_*d-l,p=x*f-u,b=4*(u*e+l),v=0;4>v;v++)o=O[b+v],a=O[b+4+v],h=O[b+C+v],c=O[b+C+4+v],m=o*(1-g)*(1-p)+a*g*(1-p)+h*p*(1-g)+c*g*p,k[y++]=m;return T},hermiteFastResize:function(t,e,i,o,a){for(var h=this.rcpScaleX,l=this.rcpScaleY,u=c(h/2),f=c(l/2),d=t.getContext("2d"),g=d.getImageData(0,0,e,i),p=g.data,v=d.getImageData(0,0,o,a),m=v.data,b=0;a>b;b++)for(var y=0;o>y;y++){for(var _=4*(y+b*o),x=0,S=0,C=0,w=0,O=0,T=0,k=0,j=(b+.5)*l,A=r(b*l);(b+1)*l>A;A++)for(var P=s(j-(A+.5))/f,M=(y+.5)*h,L=P*P,D=r(y*h);(y+1)*h>D;D++){var E=s(M-(D+.5))/u,I=n(L+E*E);I>1&&-1>I||(x=2*I*I*I-3*I*I+1,x>0&&(E=4*(D+A*e),k+=x*p[E+3],C+=x,p[E+3]<255&&(x=x*p[E+3]/250),w+=x*p[E],O+=x*p[E+1],T+=x*p[E+2],S+=x))}m[_]=w/S,m[_+1]=O/S,m[_+2]=T/S,m[_+3]=k/C}return v},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}}),e.Image.filters.Resize.fromObject=function(t){return new e.Image.filters.Resize(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.object.clone,n=e.util.toFixed,s=e.StaticCanvas.supports("setLineDash"),o=e.Object.NUM_FRACTION_DIGITS;if(e.Text)return void e.warn("fabric.Text is already defined");var a=e.Object.prototype.stateProperties.concat();a.push("fontFamily","fontWeight","fontSize","text","textDecoration","textAlign","fontStyle","lineHeight","textBackgroundColor"),e.Text=e.util.createClass(e.Object,{_dimensionAffectingProps:{fontSize:!0,fontWeight:!0,fontFamily:!0,fontStyle:!0,lineHeight:!0,stroke:!0,strokeWidth:!0,text:!0,textAlign:!0},_reNewline:/\r?\n/,_reSpacesAndTabs:/[ \t\r]+/g,type:"text",fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",textDecoration:"",textAlign:"left",fontStyle:"",lineHeight:1.16,textBackgroundColor:"",stateProperties:a,stroke:null,shadow:null,_fontSizeFraction:.25,_fontSizeMult:1.13,initialize:function(t,e){e=e||{},this.text=t,this.__skipDimension=!0,this.setOptions(e),this.__skipDimension=!1,this._initDimensions()},_initDimensions:function(t){this.__skipDimension||(t||(t=e.util.createCanvasElement().getContext("2d"),this._setTextStyles(t)),this._textLines=this._splitTextIntoLines(),this._clearCache(),this._cacheLinesWidth="justify"!==this.textAlign,this.width=this._getTextWidth(t),this._cacheLinesWidth=!0,this.height=this._getTextHeight(t))},toString:function(){return"#'},_render:function(t){this.clipTo&&e.util.clipContext(this,t),this._setOpacity(t),this._setShadow(t),this._setupCompositeOperation(t),this._renderTextBackground(t),this._setStrokeStyles(t),this._setFillStyles(t),this._renderText(t),this._renderTextDecoration(t),this.clipTo&&t.restore()},_renderText:function(t){this._translateForTextAlign(t),this._renderTextFill(t),this._renderTextStroke(t),this._translateForTextAlign(t,!0)},_translateForTextAlign:function(t,e){if("left"!==this.textAlign&&"justify"!==this.textAlign){var i=e?-1:1;t.translate("center"===this.textAlign?i*this.width/2:i*this.width,0)}},_setTextStyles:function(t){t.textBaseline="alphabetic",this.skipTextAlign||(t.textAlign=this.textAlign),t.font=this._getFontDeclaration()},_getTextHeight:function(){return this._textLines.length*this._getHeightOfLine()},_getTextWidth:function(t){for(var e=this._getLineWidth(t,0),i=1,r=this._textLines.length;r>i;i++){var n=this._getLineWidth(t,i);n>e&&(e=n)}return e},_renderChars:function(t,e,i,r,n){var s=t.slice(0,-4);if(this[s].toLive){var o=-this.width/2+this[s].offsetX||0,a=-this.height/2+this[s].offsetY||0;e.save(),e.translate(o,a),r-=o,n-=a}e[t](i,r,n),this[s].toLive&&e.restore()},_renderTextLine:function(t,e,i,r,n,s){n-=this.fontSize*this._fontSizeFraction;var o=this._getLineWidth(e,s);if("justify"!==this.textAlign||this.width0?u/f:0,g=0,p=0,v=h.length;v>p;p++){for(;" "===i[c]&&ci;i++){var n=this._getHeightOfLine(t,i),s=n/this.lineHeight;this._renderTextLine("fillText",t,this._textLines[i],this._getLeftOffset(),this._getTopOffset()+e+s,i),e+=n}},_renderTextStroke:function(t){if(this.stroke&&0!==this.strokeWidth||!this.isEmptyStyles()){var e=0;this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this.strokeDashArray&&(1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),s&&t.setLineDash(this.strokeDashArray)),t.beginPath();for(var i=0,r=this._textLines.length;r>i;i++){var n=this._getHeightOfLine(t,i),o=n/this.lineHeight;this._renderTextLine("strokeText",t,this._textLines[i],this._getLeftOffset(),this._getTopOffset()+e+o,i),e+=n}t.closePath(),t.restore()}},_getHeightOfLine:function(){return this.fontSize*this._fontSizeMult*this.lineHeight},_renderTextBackground:function(t){this._renderTextBoxBackground(t),this._renderTextLinesBackground(t)},_renderTextBoxBackground:function(t){this.backgroundColor&&(t.fillStyle=this.backgroundColor,t.fillRect(this._getLeftOffset(),this._getTopOffset(),this.width,this.height),this._removeShadow(t))},_renderTextLinesBackground:function(t){if(this.textBackgroundColor){var e,i,r,n=0;t.fillStyle=this.textBackgroundColor;for(var s=0,o=this._textLines.length;o>s;s++)e=this._getHeightOfLine(t,s),""!==this._textLines[s]&&(i="justify"===this.textAlign?this.width:this._getLineWidth(t,s),r=this._getLineLeftOffset(i),t.fillRect(this._getLeftOffset()+r,this._getTopOffset()+n,i,e/this.lineHeight)),n+=e;this._removeShadow(t)}},_getLineLeftOffset:function(t){return"center"===this.textAlign?(this.width-t)/2:"right"===this.textAlign?this.width-t:0},_clearCache:function(){this.__lineWidths=[],this.__lineHeights=[]},_shouldClearCache:function(){var t=!1;if(this._forceClearCache)return this._forceClearCache=!1,!0;for(var e in this._dimensionAffectingProps)this["__"+e]!==this[e]&&(this["__"+e]=this[e],t=!0);return t},_getLineWidth:function(t,e){if(this.__lineWidths[e])return this.__lineWidths[e];var i,r,n=this._textLines[e];return""===n?i=0:"justify"===this.textAlign&&this._cacheLinesWidth?(r=n.split(/\s+/),i=r.length>1?this.width:t.measureText(n).width):i=t.measureText(n).width,this._cacheLinesWidth&&(this.__lineWidths[e]=i),i},_renderTextDecoration:function(t){function e(e){var n,s,o,a,h,c,l,u=0;for(n=0,s=r._textLines.length;s>n;n++){for(h=r._getLineWidth(t,n),c=r._getLineLeftOffset(h),l=r._getHeightOfLine(t,n),o=0,a=e.length;a>o;o++)t.fillRect(r._getLeftOffset()+c,u+(r._fontSizeMult-1+e[o])*r.fontSize-i,h,r.fontSize/15);u+=l}}if(this.textDecoration){var i=this.height/2,r=this,n=[];this.textDecoration.indexOf("underline")>-1&&n.push(.85),this.textDecoration.indexOf("line-through")>-1&&n.push(.43),this.textDecoration.indexOf("overline")>-1&&n.push(-.12),n.length>0&&e(n)}},_getFontDeclaration:function(){return[e.isLikelyNode?this.fontWeight:this.fontStyle,e.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",e.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(t,e){this.visible&&(t.save(),this._setTextStyles(t),this._shouldClearCache()&&this._initDimensions(t),e||this.transform(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.group&&"path-group"===this.group.type&&t.translate(this.left,this.top),this._render(t),t.restore())},_splitTextIntoLines:function(){return this.text.split(this._reNewline)},toObject:function(t){var e=i(this.callSuper("toObject",t),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this._getSVGLeftTopOffsets(this.ctx),r=this._getSVGTextAndBg(i.textTop,i.textLeft);return this._wrapSVGTextAndBg(e,r),t?t(e.join("")):e.join("")},_getSVGLeftTopOffsets:function(t){var e=this._getHeightOfLine(t,0),i=-this.width/2,r=0;return{textLeft:i+(this.group&&"path-group"===this.group.type?this.left:0),textTop:r+(this.group&&"path-group"===this.group.type?-this.top:0),lineTop:e}},_wrapSVGTextAndBg:function(t,e){var i=!0,r=this.getSvgFilter(),n=""===r?"":' style="'+r+'"';t.push(' \n",e.textBgRects.join("")," \n',e.textSpans.join("")," \n"," \n"); - -},_getSVGTextAndBg:function(t,e){var i=[],r=[],n=0;this._setSVGBg(r);for(var s=0,o=this._textLines.length;o>s;s++)this.textBackgroundColor&&this._setSVGTextLineBg(r,s,e,t,n),this._setSVGTextLineText(s,i,n,e,t,r),n+=this._getHeightOfLine(this.ctx,s);return{textSpans:i,textBgRects:r}},_setSVGTextLineText:function(t,i,r,s,a){var h=this.fontSize*(this._fontSizeMult-this._fontSizeFraction)-a+r-this.height/2;return"justify"===this.textAlign?void this._setSVGTextLineJustifed(t,i,h,s):void i.push(' ",e.util.string.escapeXml(this._textLines[t]),"\n")},_setSVGTextLineJustifed:function(t,i,r,s){var a=e.util.createCanvasElement().getContext("2d");this._setTextStyles(a);var h,c,l=this._textLines[t],u=l.split(/\s+/),f=this._getWidthOfWords(a,l),d=this.width-f,g=u.length-1,p=g>0?d/g:0,v=this._getFillAttributes(this.fill);for(s+=this._getLineLeftOffset(this._getLineWidth(a,t)),t=0,c=u.length;c>t;t++)h=u[t],i.push(' ",e.util.string.escapeXml(h),"\n"),s+=this._getWidthOfWords(a,h)+p},_setSVGTextLineBg:function(t,e,i,r,s){t.push(" \n')},_setSVGBg:function(t){this.backgroundColor&&t.push(" \n')},_getFillAttributes:function(t){var i=t&&"string"==typeof t?new e.Color(t):"";return i&&i.getSource()&&1!==i.getAlpha()?'opacity="'+i.getAlpha()+'" fill="'+i.setAlpha(1).toRgb()+'"':'fill="'+t+'"'},_set:function(t,e){this.callSuper("_set",t,e),t in this._dimensionAffectingProps&&(this._initDimensions(),this.setCoords())},complexity:function(){return 1}}),e.Text.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")),e.Text.DEFAULT_SVG_FONT_SIZE=16,e.Text.fromElement=function(t,i){if(!t)return null;var r=e.parseAttributes(t,e.Text.ATTRIBUTE_NAMES);i=e.util.object.extend(i?e.util.object.clone(i):{},r),i.top=i.top||0,i.left=i.left||0,"dx"in r&&(i.left+=r.dx),"dy"in r&&(i.top+=r.dy),"fontSize"in i||(i.fontSize=e.Text.DEFAULT_SVG_FONT_SIZE),i.originX||(i.originX="left");var n="";"textContent"in t?n=t.textContent:"firstChild"in t&&null!==t.firstChild&&"data"in t.firstChild&&null!==t.firstChild.data&&(n=t.firstChild.data),n=n.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var s=new e.Text(n,i),o=0;return"left"===s.originX&&(o=s.getWidth()/2),"right"===s.originX&&(o=-s.getWidth()/2),s.set({left:s.getLeft()+o,top:s.getTop()-s.getHeight()/2+s.fontSize*(.18+s._fontSizeFraction)}),s},e.Text.fromObject=function(t){return new e.Text(t.text,r(t))},e.util.createAccessors(e.Text)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:!1,editable:!0,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:!0,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,_charWidthsCache:{},__widthOfSpace:[],initialize:function(t,e){this.styles=e?e.styles||{}:{},this.callSuper("initialize",t,e),this.initBehavior()},_clearCache:function(){this.callSuper("_clearCache"),this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles)return!0;var t=this.styles;for(var e in t)for(var i in t[e])for(var r in t[e][i])return!1;return!0},setSelectionStart:function(t){t=Math.max(t,0),this.selectionStart!==t&&(this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this}),this.selectionStart=t),this._updateTextarea()},setSelectionEnd:function(t){t=Math.min(t,this.text.length),this.selectionEnd!==t&&(this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this}),this.selectionEnd=t),this._updateTextarea()},getSelectionStyles:function(t,e){if(2===arguments.length){for(var i=[],r=t;e>r;r++)i.push(this.getSelectionStyles(r));return i}var n=this.get2DCursorLocation(t),s=this._getStyleDeclaration(n.lineIndex,n.charIndex);return s||{}},setSelectionStyles:function(t){if(this.selectionStart===this.selectionEnd)this._extendStyles(this.selectionStart,t);else for(var e=this.selectionStart;ei;i++){if(t<=this._textLines[i].length)return{lineIndex:i,charIndex:t};t-=this._textLines[i].length+1}return{lineIndex:i-1,charIndex:this._textLines[i-1].length=a;a++){var h=this._getLineLeftOffset(this._getLineWidth(i,a))||0,c=this._getHeightOfLine(this.ctx,a),l=0,u=this._textLines[a];if(a===s)for(var f=0,d=u.length;d>f;f++)f>=r.charIndex&&(a!==o||fs&&o>a)l+=this._getLineWidth(i,a)||5;else if(a===o)for(var g=0,p=n.charIndex;p>g;g++)l+=this._getWidthOfChar(i,u[g],a,g);i.fillRect(e.left+h,e.top+e.topOffset,l,c),e.topOffset+=c}},_renderChars:function(t,e,i,r,n,s,o){if(this.isEmptyStyles())return this._renderCharsFast(t,e,i,r,n);o=o||0,this.skipTextAlign=!0,r-="center"===this.textAlign?this.width/2:"right"===this.textAlign?this.width:0;var a,h,c=this._getHeightOfLine(e,s),l=this._getLineLeftOffset(this._getLineWidth(e,s)),u="";r+=l||0,e.save(),n-=c/this.lineHeight*this._fontSizeFraction;for(var f=o,d=i.length+o;d>=f;f++)a=a||this.getCurrentCharStyle(s,f),h=this.getCurrentCharStyle(s,f+1),(this._hasStyleChanged(a,h)||f===d)&&(this._renderChar(t,e,s,f-1,u,r,n,c),u="",a=h),u+=i[f-o];e.restore()},_renderCharsFast:function(t,e,i,r,n){this.skipTextAlign=!1,"fillText"===t&&this.fill&&this.callSuper("_renderChars",t,e,i,r,n),"strokeText"===t&&(this.stroke&&this.strokeWidth>0||this.skipFillStrokeCheck)&&this.callSuper("_renderChars",t,e,i,r,n)},_renderChar:function(t,e,i,r,n,s,o,a){var h,c,l,u,f,d,g=this._getStyleDeclaration(i,r);g?(c=this._getHeightOfChar(e,n,i,r),u=g.stroke,l=g.fill,d=g.textDecoration):c=this.fontSize,u=(u||this.stroke)&&"strokeText"===t,l=(l||this.fill)&&"fillText"===t,g&&e.save(),h=this._applyCharStylesGetWidth(e,n,i,r,g||{}),d=d||this.textDecoration,g&&g.textBackgroundColor&&this._removeShadow(e),l&&e.fillText(n,s,o),u&&e.strokeText(n,s,o),(d||""!==d)&&(f=this._fontSizeFraction*a/this.lineHeight,this._renderCharDecoration(e,d,s,o,f,h,c)),g&&e.restore(),e.translate(h,0)},_hasStyleChanged:function(t,e){return t.fill!==e.fill||t.fontSize!==e.fontSize||t.textBackgroundColor!==e.textBackgroundColor||t.textDecoration!==e.textDecoration||t.fontFamily!==e.fontFamily||t.fontWeight!==e.fontWeight||t.fontStyle!==e.fontStyle||t.stroke!==e.stroke||t.strokeWidth!==e.strokeWidth},_renderCharDecoration:function(t,e,i,r,n,s,o){if(e){var a,h,c=o/15,l={underline:r+o/10,"line-through":r-o*(this._fontSizeFraction+this._fontSizeMult-1)+c,overline:r-(this._fontSizeMult-this._fontSizeFraction)*o},u=["underline","line-through","overline"];for(a=0;a-1&&t.fillRect(i,l[h],s,c)}},_renderTextLine:function(t,e,i,r,n,s){this.isEmptyStyles()||(n+=this.fontSize*(this._fontSizeFraction+.03)),this.callSuper("_renderTextLine",t,e,i,r,n,s)},_renderTextDecoration:function(t){return this.isEmptyStyles()?this.callSuper("_renderTextDecoration",t):void 0},_renderTextLinesBackground:function(t){this.callSuper("_renderTextLinesBackground",t);for(var e,i,r,n,s,o,a=0,h=this._getLeftOffset(),c=this._getTopOffset(),l=0,u=this._textLines.length;u>l;l++)if(e=this._getHeightOfLine(t,l),n=this._textLines[l],""!==n&&this.styles&&this._getLineStyle(l)){i=this._getLineWidth(t,l),r=this._getLineLeftOffset(i);for(var f=0,d=n.length;d>f;f++)o=this._getStyleDeclaration(l,f),o&&o.textBackgroundColor&&(s=n[f],t.fillStyle=o.textBackgroundColor,t.fillRect(h+r+this._getWidthOfCharsAt(t,l,f),c+a,this._getWidthOfChar(t,s,l,f)+1,e/this.lineHeight));a+=e}else a+=e},_getCacheProp:function(t,e){return t+e.fontFamily+e.fontSize+e.fontWeight+e.fontStyle+e.shadow},_applyCharStylesGetWidth:function(e,i,r,n,s){var o,a=this._getStyleDeclaration(r,n),h=s&&t(s)||t(a);this._applyFontStyles(h);var c=this._getCacheProp(i,h);if(!a&&this._charWidthsCache[c]&&this.caching)return this._charWidthsCache[c];"string"==typeof h.shadow&&(h.shadow=new fabric.Shadow(h.shadow));var l=h.fill||this.fill;return e.fillStyle=l.toLive?l.toLive(e,this):l,h.stroke&&(e.strokeStyle=h.stroke&&h.stroke.toLive?h.stroke.toLive(e,this):h.stroke),e.lineWidth=h.strokeWidth||this.strokeWidth,e.font=this._getFontDeclaration.call(h),h.shadow&&(h.scaleX=this.scaleX,h.scaleY=this.scaleY,h.canvas=this.canvas,this._setShadow.call(h,e)),this.caching&&this._charWidthsCache[c]||(o=e.measureText(i).width,this.caching&&(this._charWidthsCache[c]=o)),this._charWidthsCache[c]},_applyFontStyles:function(t){t.fontFamily||(t.fontFamily=this.fontFamily),t.fontSize||(t.fontSize=this.fontSize),t.fontWeight||(t.fontWeight=this.fontWeight),t.fontStyle||(t.fontStyle=this.fontStyle)},_getStyleDeclaration:function(e,i,r){return r?this.styles[e]&&this.styles[e][i]?t(this.styles[e][i]):{}:this.styles[e]&&this.styles[e][i]?this.styles[e][i]:null},_setStyleDeclaration:function(t,e,i){this.styles[t][e]=i},_deleteStyleDeclaration:function(t,e){delete this.styles[t][e]},_getLineStyle:function(t){return this.styles[t]},_setLineStyle:function(t,e){this.styles[t]=e},_deleteLineStyle:function(t){delete this.styles[t]},_getWidthOfChar:function(t,e,i,r){if("justify"===this.textAlign&&this._reSpacesAndTabs.test(e))return this._getWidthOfSpace(t,i);var n=this._getStyleDeclaration(i,r,!0);this._applyFontStyles(n);var s=this._getCacheProp(e,n);if(this._charWidthsCache[s]&&this.caching)return this._charWidthsCache[s];if(t){t.save();var o=this._applyCharStylesGetWidth(t,e,i,r);return t.restore(),o}},_getHeightOfChar:function(t,e,i){var r=this._getStyleDeclaration(e,i);return r&&r.fontSize?r.fontSize:this.fontSize},_getWidthOfCharsAt:function(t,e,i){var r,n,s=0;for(r=0;i>r;r++)n=this._textLines[e][r],s+=this._getWidthOfChar(t,n,e,r);return s},_getLineWidth:function(t,e){return this.__lineWidths[e]?this.__lineWidths[e]:(this.__lineWidths[e]=this._getWidthOfCharsAt(t,e,this._textLines[e].length),this.__lineWidths[e])},_getWidthOfSpace:function(t,e){if(this.__widthOfSpace[e])return this.__widthOfSpace[e];var i=this._textLines[e],r=this._getWidthOfWords(t,i,e,0),n=this.width-r,s=i.length-i.replace(this._reSpacesAndTabs,"").length,o=n/s;return this.__widthOfSpace[e]=o,o},_getWidthOfWords:function(t,e,i,r){for(var n=0,s=0;sn;n++){var o=this._getHeightOfChar(t,e,n);o>r&&(r=o)}return this.__lineHeights[e]=r*this.lineHeight*this._fontSizeMult,this.__lineHeights[e]},_getTextHeight:function(t){for(var e=0,i=0,r=this._textLines.length;r>i;i++)e+=this._getHeightOfLine(t,i);return e},toObject:function(e){var i,r,n,s={};for(i in this.styles){n=this.styles[i],s[i]={};for(r in n)s[i][r]=t(n[r])}return fabric.util.object.extend(this.callSuper("toObject",e),{styles:s})}}),fabric.IText.fromObject=function(e){return new fabric.IText(e.text,t(e))}}(),function(){var t=fabric.util.object.clone;fabric.util.object.extend(fabric.IText.prototype,{initBehavior:function(){this.initAddedHandler(),this.initRemovedHandler(),this.initCursorSelectionHandlers(),this.initDoubleClickSimulation()},initSelectedHandler:function(){this.on("selected",function(){var t=this;setTimeout(function(){t.selected=!0},100)})},initAddedHandler:function(){var t=this;this.on("added",function(){this.canvas&&!this.canvas._hasITextHandlers&&(this.canvas._hasITextHandlers=!0,this._initCanvasHandlers()),t.canvas&&(t.canvas._iTextInstances=t.canvas._iTextInstances||[],t.canvas._iTextInstances.push(t))})},initRemovedHandler:function(){var t=this;this.on("removed",function(){t.canvas&&(t.canvas._iTextInstances=t.canvas._iTextInstances||[],fabric.util.removeFromArray(t.canvas._iTextInstances,t))})},_initCanvasHandlers:function(){var t=this;this.canvas.on("selection:cleared",function(){fabric.IText.prototype.exitEditingOnOthers(t.canvas)}),this.canvas.on("mouse:up",function(){t.canvas._iTextInstances&&t.canvas._iTextInstances.forEach(function(t){t.__isMousedown=!1})}),this.canvas.on("object:selected",function(){fabric.IText.prototype.exitEditingOnOthers(t.canvas)})},_tick:function(){this._currentTickState=this._animateCursor(this,1,this.cursorDuration,"_onTickComplete")},_animateCursor:function(t,e,i,r){var n;return n={isAborted:!1,abort:function(){this.isAborted=!0}},t.animate("_currentCursorOpacity",e,{duration:i,onComplete:function(){n.isAborted||t[r]()},onChange:function(){t.canvas&&(t.canvas.clearContext(t.canvas.contextTop||t.ctx),t.renderCursorOrSelection())},abort:function(){return n.isAborted}}),n},_onTickComplete:function(){var t=this;this._cursorTimeout1&&clearTimeout(this._cursorTimeout1),this._cursorTimeout1=setTimeout(function(){t._currentTickCompleteState=t._animateCursor(t,0,this.cursorDuration/2,"_tick")},100)},initDelayedCursor:function(t){var e=this,i=t?0:this.cursorDelay;this._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),this._currentCursorOpacity=1,this.canvas&&(this.canvas.clearContext(this.canvas.contextTop||this.ctx),this.renderCursorOrSelection()),this._cursorTimeout2&&clearTimeout(this._cursorTimeout2),this._cursorTimeout2=setTimeout(function(){e._tick()},i)},abortCursorAnimation:function(){this._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),clearTimeout(this._cursorTimeout2),this._currentCursorOpacity=0,this.canvas&&this.canvas.clearContext(this.canvas.contextTop||this.ctx)},selectAll:function(){this.setSelectionStart(0),this.setSelectionEnd(this.text.length)},getSelectedText:function(){return this.text.slice(this.selectionStart,this.selectionEnd)},findWordBoundaryLeft:function(t){var e=0,i=t-1;if(this._reSpace.test(this.text.charAt(i)))for(;this._reSpace.test(this.text.charAt(i));)e++,i--;for(;/\S/.test(this.text.charAt(i))&&i>-1;)e++,i--;return t-e},findWordBoundaryRight:function(t){var e=0,i=t;if(this._reSpace.test(this.text.charAt(i)))for(;this._reSpace.test(this.text.charAt(i));)e++,i++;for(;/\S/.test(this.text.charAt(i))&&i-1;)e++,i--;return t-e},findLineBoundaryRight:function(t){for(var e=0,i=t;!/\n/.test(this.text.charAt(i))&&ii;i++)"\n"===t[i]&&e++;return e},searchWordBoundary:function(t,e){for(var i=this._reSpace.test(this.text.charAt(t))?t-1:t,r=this.text.charAt(i),n=/[ \n\.,;!\?\-]/;!n.test(r)&&i>0&&i=t.__selectionStartOnMouseDown?(t.setSelectionStart(t.__selectionStartOnMouseDown),t.setSelectionEnd(i)):(t.setSelectionStart(i),t.setSelectionEnd(t.__selectionStartOnMouseDown))}})},_setEditingProps:function(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},_updateTextarea:function(){if(this.hiddenTextarea&&!this.inCompositionMode&&(this.hiddenTextarea.value=this.text,this.hiddenTextarea.selectionStart=this.selectionStart,this.hiddenTextarea.selectionEnd=this.selectionEnd,this.selectionStart===this.selectionEnd)){var t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.x+"px",this.hiddenTextarea.style.top=t.y+"px"}},_calcTextareaPosition:function(){var t=this.text.split(""),e=this._getCursorBoundaries(t,"cursor"),i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex,s=this.getCurrentCharFontSize(r,n),o=0===r&&0===n?this._getLineLeftOffset(this._getLineWidth(this.ctx,r)):e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s};return this.hiddenTextarea.style.fontSize=s+"px",fabric.util.transformPoint(h,a)},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.overCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor))},exitEditing:function(){return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null,this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this.fire("editing:exited"),this.canvas&&this.canvas.fire("text:editing:exited",{target:this}),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},_removeCharsFromTo:function(t,e){for(;e!==t;)this._removeSingleCharAndStyle(t+1),e--;this.setSelectionStart(t)},_removeSingleCharAndStyle:function(t){var e="\n"===this.text[t-1],i=e?t:t-1;this.removeStyleObject(e,i),this.text=this.text.slice(0,t-1)+this.text.slice(t),this._textLines=this._splitTextIntoLines()},insertChars:function(t,e){var i;if(this.selectionEnd-this.selectionStart>1&&(this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.setSelectionEnd(this.selectionStart)),!e&&this.isEmptyStyles())return void this.insertChar(t,!1);for(var r=0,n=t.length;n>r;r++)e&&(i=fabric.copiedTextStyle[r]),this.insertChar(t[r],n-1>r,i)},insertChar:function(t,e,i){var r="\n"===this.text[this.selectionStart];this.text=this.text.slice(0,this.selectionStart)+t+this.text.slice(this.selectionEnd),this._textLines=this._splitTextIntoLines(),this.insertStyleObjects(t,r,i),this.selectionStart+=t.length,this.selectionEnd=this.selectionStart,e||(this._updateTextarea(),this.canvas&&this.canvas.renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this}))},insertNewlineStyleObject:function(e,i,r){this.shiftLineStyles(e,1),this.styles[e+1]||(this.styles[e+1]={});var n={},s={};if(this.styles[e]&&this.styles[e][i-1]&&(n=this.styles[e][i-1]),r)s[0]=t(n),this.styles[e+1]=s;else{for(var o in this.styles[e])parseInt(o,10)>=i&&(s[parseInt(o,10)-i]=this.styles[e][o],delete this.styles[e][o]);this.styles[e+1]=s}this._forceClearCache=!0},insertCharStyleObject:function(e,i,r){var n=this.styles[e],s=t(n);0!==i||r||(i=1);for(var o in s){var a=parseInt(o,10);a>=i&&(n[a+1]=s[a],s[a-1]||delete n[a])}this.styles[e][i]=r||t(n[i-1]),this._forceClearCache=!0},insertStyleObjects:function(t,e,i){var r=this.get2DCursorLocation(),n=r.lineIndex,s=r.charIndex;this._getLineStyle(n)||this._setLineStyle(n,{}),"\n"===t?this.insertNewlineStyleObject(n,s,e):this.insertCharStyleObject(n,s,i)},shiftLineStyles:function(e,i){var r=t(this.styles);for(var n in this.styles){var s=parseInt(n,10);s>e&&(this.styles[s+i]=r[s],r[s-i]||delete this.styles[s])}},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=i.lineIndex,n=i.charIndex;this._removeStyleObject(t,i,r,n)},_getTextOnPreviousLine:function(t){return this._textLines[t-1]},_removeStyleObject:function(e,i,r,n){if(e){var s=this._getTextOnPreviousLine(i.lineIndex),o=s?s.length:0;this.styles[r-1]||(this.styles[r-1]={});for(n in this.styles[r])this.styles[r-1][parseInt(n,10)+o]=this.styles[r][n];this.shiftLineStyles(i.lineIndex,-1)}else{var a=this.styles[r];a&&delete a[n];var h=t(a);for(var c in h){var l=parseInt(c,10);l>=n&&0!==l&&(a[l-1]=h[l],delete a[l])}}},insertNewline:function(){this.insertChars("\n")}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(t){this.__newClickTime=+new Date;var e=this.canvas.getPointer(t.e);this.isTripleClick(e)?(this.fire("tripleclick",t),this._stopEvent(t.e)):this.isDoubleClick(e)&&(this.fire("dblclick",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isDoubleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y&&this.__lastIsEditing},isTripleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y},_stopEvent:function(t){t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler(),this.initMousedownHandler(),this.initMouseupHandler(),this.initClicks()},initClicks:function(){this.on("dblclick",function(t){this.selectWord(this.getSelectionStartFromPointer(t.e))}),this.on("tripleclick",function(t){this.selectLine(this.getSelectionStartFromPointer(t.e))})},initMousedownHandler:function(){this.on("mousedown",function(t){if(this.editable){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.hiddenTextarea&&this.canvas&&this.canvas.wrapperEl.appendChild(this.hiddenTextarea),this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.initDelayedCursor(!0))}})},_isObjectMoved:function(t){var e=this.canvas.getPointer(t);return this.__mousedownX!==e.x||this.__mousedownY!==e.y},initMouseupHandler:function(){this.on("mouseup",function(t){this.__isMousedown=!1,this.editable&&!this._isObjectMoved(t.e)&&(this.__lastSelected&&!this.__corner&&(this.enterEditing(t.e),this.initDelayedCursor(!0)),this.selected=!0)})},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t);t.shiftKey?eh;h++){i=this._textLines[h],o+=this._getHeightOfLine(this.ctx,h)*this.scaleY;var l=this._getLineWidth(this.ctx,h),u=this._getLineLeftOffset(l);s=u*this.scaleX;for(var f=0,d=i.length;d>f;f++){if(n=s,s+=this._getWidthOfChar(this.ctx,i[f],h,this.flipX?d-f:f)*this.scaleX,!(o<=r.y||s<=r.x))return this._getNewSelectionStartFromOffset(r,n,s,a+h,d);a++}if(r.ys?0:1,h=r+a;return this.flipX&&(h=n-h),h>this.text.length&&(h=this.text.length),h}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(t){var e;t&&this.canvas?e=this.canvas.getPointer(t):(this.oCoords||this.setCoords(),e=this.oCoords.tl),this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.style.cssText="position: absolute; top: "+e.y+"px; left: "+e.x+"px; opacity: 0; width: 0px; height: 0px; z-index: -999;",this.canvas?this.canvas.lowerCanvasEl.parentNode.appendChild(this.hiddenTextarea):fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.cut.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},_keysMap:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",67:"copy",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){this.isEditing&&t.keyCode in this._keysMap&&(this[this._keysMap[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll())},onKeyUp:function(t){return!this.isEditing||this._copyDone?void(this._copyDone=!1):void(t.keyCode in this._ctrlKeysMap&&(t.ctrlKey||t.metaKey)&&(this[this._ctrlKeysMap[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()))},onInput:function(t){if(this.isEditing&&!this.inCompositionMode){var e,i,r,n=this.selectionStart||0,s=this.selectionEnd||0,o=this.text.length,a=this.hiddenTextarea.value.length;a>o?(r="left"===this._selectionDirection?s:n,e=a-o,i=this.hiddenTextarea.value.slice(r,r+e)):(e=a-o+s-n,i=this.hiddenTextarea.value.slice(n,n+e)),this.insertChars(i),t.stopPropagation()}},onCompositionStart:function(){this.inCompositionMode=!0,this.prevCompositionLength=0,this.compositionStart=this.selectionStart},onCompositionEnd:function(){this.inCompositionMode=!1},onCompositionUpdate:function(t){var e=t.data;this.selectionStart=this.compositionStart,this.selectionEnd=this.selectionEnd===this.selectionStart?this.compositionStart+this.prevCompositionLength:this.selectionEnd,this.insertChars(e,!1),this.prevCompositionLength=e.length},forwardDelete:function(t){if(this.selectionStart===this.selectionEnd){if(this.selectionStart===this.text.length)return;this.moveCursorRight(t)}this.removeChars(t)},copy:function(t){if(this.selectionStart!==this.selectionEnd){var e=this.getSelectedText(),i=this._getClipboardData(t);i&&i.setData("text",e),fabric.copiedText=e,fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd),t.stopImmediatePropagation(),t.preventDefault(),this._copyDone=!0}},paste:function(t){var e=null,i=this._getClipboardData(t),r=!0;i?(e=i.getData("text").replace(/\r/g,""),fabric.copiedTextStyle&&fabric.copiedText===e||(r=!1)):e=fabric.copiedText,e&&this.insertChars(e,r),t.stopImmediatePropagation(),t.preventDefault(); - -},cut:function(t){this.selectionStart!==this.selectionEnd&&(this.copy(t),this.removeChars(t))},_getClipboardData:function(t){return t&&t.clipboardData||fabric.window.clipboardData},getDownCursorOffset:function(t,e){var i,r,n=e?this.selectionEnd:this.selectionStart,s=this.get2DCursorLocation(n),o=s.lineIndex,a=this._textLines[o].slice(0,s.charIndex),h=this._textLines[o].slice(s.charIndex),c=this._textLines[o+1]||"";if(o===this._textLines.length-1||t.metaKey||34===t.keyCode)return this.text.length-n;var l=this._getLineWidth(this.ctx,o);r=this._getLineLeftOffset(l);for(var u=r,f=0,d=a.length;d>f;f++)i=a[f],u+=this._getWidthOfChar(this.ctx,i,o,f);var g=this._getIndexOnNextLine(s,c,u);return h.length+1+g},_getIndexOnNextLine:function(t,e,i){for(var r,n=t.lineIndex+1,s=this._getLineWidth(this.ctx,n),o=this._getLineLeftOffset(s),a=o,h=0,c=0,l=e.length;l>c;c++){var u=e[c],f=this._getWidthOfChar(this.ctx,u,n,c);if(a+=f,a>i){r=!0;var d=a-f,g=a,p=Math.abs(d-i),v=Math.abs(g-i);h=p>v?c+1:c;break}}return r||(h=e.length),h},moveCursorDown:function(t){this.abortCursorAnimation(),this._currentCursorOpacity=1;var e=this.getDownCursorOffset(t,"right"===this._selectionDirection);t.shiftKey?this.moveCursorDownWithShift(e):this.moveCursorDownWithoutShift(e),this.initDelayedCursor()},moveCursorDownWithoutShift:function(t){this._selectionDirection="right",this.setSelectionStart(this.selectionStart+t),this.setSelectionEnd(this.selectionStart)},swapSelectionPoints:function(){var t=this.selectionEnd;this.setSelectionEnd(this.selectionStart),this.setSelectionStart(t)},moveCursorDownWithShift:function(t){this.selectionEnd===this.selectionStart&&(this._selectionDirection="right"),"right"===this._selectionDirection?this.setSelectionEnd(this.selectionEnd+t):this.setSelectionStart(this.selectionStart+t),this.selectionEndthis.text.length&&this.setSelectionEnd(this.text.length)},getUpCursorOffset:function(t,e){var i=e?this.selectionEnd:this.selectionStart,r=this.get2DCursorLocation(i),n=r.lineIndex;if(0===n||t.metaKey||33===t.keyCode)return i;for(var s,o=this._textLines[n].slice(0,r.charIndex),a=this._textLines[n-1]||"",h=this._getLineWidth(this.ctx,r.lineIndex),c=this._getLineLeftOffset(h),l=c,u=0,f=o.length;f>u;u++)s=o[u],l+=this._getWidthOfChar(this.ctx,s,n,u);var d=this._getIndexOnPrevLine(r,a,l);return a.length-d+o.length},_getIndexOnPrevLine:function(t,e,i){for(var r,n=t.lineIndex-1,s=this._getLineWidth(this.ctx,n),o=this._getLineLeftOffset(s),a=o,h=0,c=0,l=e.length;l>c;c++){var u=e[c],f=this._getWidthOfChar(this.ctx,u,n,c);if(a+=f,a>i){r=!0;var d=a-f,g=a,p=Math.abs(d-i),v=Math.abs(g-i);h=p>v?c:c-1;break}}return r||(h=e.length-1),h},moveCursorUp:function(t){this.abortCursorAnimation(),this._currentCursorOpacity=1;var e=this.getUpCursorOffset(t,"right"===this._selectionDirection);t.shiftKey?this.moveCursorUpWithShift(e):this.moveCursorUpWithoutShift(e),this.initDelayedCursor()},moveCursorUpWithShift:function(t){this.selectionEnd===this.selectionStart&&(this._selectionDirection="left"),"right"===this._selectionDirection?this.setSelectionEnd(this.selectionEnd-t):this.setSelectionStart(this.selectionStart-t),this.selectionEnd=this.text.length&&this.selectionEnd>=this.text.length||(this.abortCursorAnimation(),this._currentCursorOpacity=1,t.shiftKey?this.moveCursorRightWithShift(t):this.moveCursorRightWithoutShift(t),this.initDelayedCursor())},moveCursorRightWithShift:function(t){"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):(this._selectionDirection="right",this._moveRight(t,"selectionEnd"))},moveCursorRightWithoutShift:function(t){this._selectionDirection="right",this.selectionStart===this.selectionEnd?(this._moveRight(t,"selectionStart"),this.setSelectionEnd(this.selectionStart)):(this.setSelectionEnd(this.selectionEnd+this.getNumNewLinesInSelectedText()),this.setSelectionStart(this.selectionEnd))},removeChars:function(t){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.setSelectionEnd(this.selectionStart),this._removeExtraneousStyles(),this.canvas&&this.canvas.renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(t){if(0!==this.selectionStart)if(t.metaKey){var e=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(e,this.selectionStart),this.setSelectionStart(e)}else if(t.altKey){var i=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(i,this.selectionStart),this.setSelectionStart(i)}else this._removeSingleCharAndStyle(this.selectionStart),this.setSelectionStart(this.selectionStart-1)}}),function(){var t=fabric.util.toFixed,e=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(t,e,i,r,n,s){this._getLineStyle(t)?this._setSVGTextLineChars(t,e,i,r,s):fabric.Text.prototype._setSVGTextLineText.call(this,t,e,i,r,n)},_setSVGTextLineChars:function(t,e,i,r,n){for(var s=this._textLines[t],o=0,a=this._getLineLeftOffset(this._getLineWidth(this.ctx,t))-this.width/2,h=this._getSVGLineTopOffset(t),c=this._getHeightOfLine(this.ctx,t),l=0,u=s.length;u>l;l++){var f=this._getStyleDeclaration(t,l)||{};e.push(this._createTextCharSpan(s[l],f,a,h.lineTop+h.offset,o));var d=this._getWidthOfChar(this.ctx,s[l],t,l);f.textBackgroundColor&&n.push(this._createTextCharBg(f,a,h.lineTop,c,d,o)),o+=d}},_getSVGLineTopOffset:function(t){for(var e=0,i=0,r=0;t>r;r++)e+=this._getHeightOfLine(this.ctx,r);return i=this._getHeightOfLine(this.ctx,r),{lineTop:e,offset:(this._fontSizeMult-this._fontSizeFraction)*i/(this.lineHeight*this._fontSizeMult)}},_createTextCharBg:function(i,r,n,s,o,a){return[' \n'].join("")},_createTextCharSpan:function(i,r,n,s,o){var a=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},r));return[' ',fabric.util.string.escapeXml(i),"\n"].join("")}})}(),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.clone;e.Textbox=e.util.createClass(e.IText,e.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:0,__cachedLines:null,initialize:function(t,i){this.ctx=e.util.createCanvasElement().getContext("2d"),this.callSuper("initialize",t,i),this.set({lockUniScaling:!1,lockScalingY:!0,lockScalingFlip:!0,hasBorders:!0}),this.setControlsVisibility(e.Textbox.getTextboxControlVisibility()),this._dimensionAffectingProps.width=!0},_initDimensions:function(t){this.__skipDimension||(t||(t=e.util.createCanvasElement().getContext("2d"),this._setTextStyles(t)),this.dynamicMinWidth=0,this._textLines=this._splitTextIntoLines(),this.dynamicMinWidth>this.width&&this._set("width",this.dynamicMinWidth),this._clearCache(),this.height=this._getTextHeight(t))},_generateStyleMap:function(){for(var t=0,e=0,i=0,r={},n=0;ns;s++)n+=this._getWidthOfChar(t,e[s],i,s+r);return n},_wrapLine:function(t,e,i){for(var r=0,n=[],s="",o=e.split(" "),a="",h=0,c=" ",l=0,u=0,f=0,d=!0,g=0;g=this.width&&!d&&(n.push(s),s="",r=l,d=!0),d||(s+=c),s+=a,u=this._measureText(t,c,i,h),h++,d=!1,l>f&&(f=l);return g&&n.push(s),f>this.dynamicMinWidth&&(this.dynamicMinWidth=f),n},_splitTextIntoLines:function(){var t=this.textAlign;this.ctx.save(),this._setTextStyles(this.ctx),this.textAlign="left";var e=this._wrapText(this.ctx,this.text);return this.textAlign=t,this.ctx.restore(),this._textLines=e,this._styleMap=this._generateStyleMap(),e},setOnGroup:function(t,e){"scaleX"===t&&(this.set("scaleX",Math.abs(1/e)),this.set("width",this.get("width")*e/("undefined"==typeof this.__oldScaleX?1:this.__oldScaleX)),this.__oldScaleX=e)},get2DCursorLocation:function(t){"undefined"==typeof t&&(t=this.selectionStart);for(var e=this._textLines.length,i=0,r=0;e>r;r++){var n=this._textLines[r],s=n.length;if(i+s>=t)return{lineIndex:r,charIndex:t-i};i+=s,("\n"===this.text[i]||" "===this.text[i])&&i++}return{lineIndex:e-1,charIndex:this._textLines[e-1].length}},_getCursorBoundariesOffsets:function(t,e){for(var i=0,r=0,n=this.get2DCursorLocation(),s=this._textLines[n.lineIndex].split(""),o=this._getLineLeftOffset(this._getLineWidth(this.ctx,n.lineIndex)),a=0;a=h.getMinWidth()?(h.set("width",c),!0):void 0},fabric.Group.prototype._refreshControlsVisibility=function(){if("undefined"!=typeof fabric.Textbox)for(var t=this._objects.length;t--;)if(this._objects[t]instanceof fabric.Textbox)return void this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility())};var e=fabric.util.object.clone;fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var t in this._styleMap)this._textLines[t]||delete this.styles[this._styleMap[t].line]},insertCharStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertCharStyleObject.apply(this,[t,e,i])},insertNewlineStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertNewlineStyleObject.apply(this,[t,e,i])},shiftLineStyles:function(t,i){var r=e(this.styles),n=this._styleMap[t];t=n.line;for(var s in this.styles){var o=parseInt(s,10);o>t&&(this.styles[o+i]=r[o],r[o-i]||delete this.styles[o])}},_getTextOnPreviousLine:function(t){for(var e=this._textLines[t-1];this._styleMap[t-2]&&this._styleMap[t-2].line===this._styleMap[t-1].line;)e=this._textLines[t-2]+e,t--;return e},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=this._styleMap[i.lineIndex],n=r.line,s=r.offset+i.charIndex;this._removeStyleObject(t,i,n,s)}})}(),function(){var t=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(e,i,r,n,s){n=t.call(this,e,i,r,n,s);for(var o=0,a=0,h=0;h=n));h++)("\n"===this.text[o+a]||" "===this.text[o+a])&&a++;return n-h+a}}(),function(){function request(t,e,i){var r=URL.parse(t);r.port||(r.port=0===r.protocol.indexOf("https:")?443:80);var n=0===r.protocol.indexOf("https:")?HTTPS:HTTP,s=n.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(t){var r="";e&&t.setEncoding(e),t.on("end",function(){i(r)}),t.on("data",function(e){200===t.statusCode&&(r+=e)})});s.on("error",function(t){fabric.log(t.errno===process.ECONNREFUSED?"ECONNREFUSED: connection refused to "+r.hostname+":"+r.port:t.message),i(null)}),s.end()}function requestFs(t,e){var i=require("fs");i.readFile(t,function(t,i){if(t)throw fabric.log(t),t;e(i)})}if("undefined"==typeof document||"undefined"==typeof window){var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(t,e,i){function r(r){r?(n.src=new Buffer(r,"binary"),n._src=t,e&&e.call(i,n)):(n=null,e&&e.call(i,null,!0))}var n=new Image;t&&(t instanceof Buffer||0===t.indexOf("data"))?(n.src=n._src=t,e&&e.call(i,n)):t&&0!==t.indexOf("http")?requestFs(t,r):t?request(t,"binary",r):e&&e.call(i,t)},fabric.loadSVGFromURL=function(t,e,i){t=t.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),0!==t.indexOf("http")?requestFs(t,function(t){fabric.loadSVGFromString(t.toString(),e,i)}):request(t,"",function(t){fabric.loadSVGFromString(t,e,i)})},fabric.loadSVGFromString=function(t,e,i){var r=(new DOMParser).parseFromString(t);fabric.parseSVGDocument(r.documentElement,function(t,i){e&&e(t,i)},i)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.Image.fromObject=function(t,e){fabric.util.loadImage(t.src,function(i){var r=new fabric.Image(i);r._initConfig(t),r._initFilters(t.filters,function(i){r.filters=i||[],r._initFilters(t.resizeFilters,function(t){r.resizeFilters=t||[],e&&e(r)})})})},fabric.createCanvasForNode=function(t,e,i,r){r=r||i;var n=fabric.document.createElement("canvas"),s=new Canvas(t||600,e||600,r);n.style={},n.width=s.width,n.height=s.height;var o=fabric.Canvas||fabric.StaticCanvas,a=new o(n,i);return a.contextContainer=s.getContext("2d"),a.nodeCanvas=s,a.Font=Canvas.Font,a},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){return this.nodeCanvas.createJPEGStream(t)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(t,e){return origSetWidth.call(this,t,e),this.nodeCanvas.width=t,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(t,e){return origSetHeight.call(this,t,e),this.nodeCanvas.height=t,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}}(); \ No newline at end of file +var fabric=fabric||{version:"1.6.1"};if(typeof exports!=="undefined"){exports.fabric=fabric}if(typeof document!=="undefined"&&typeof window!=="undefined"){fabric.document=document;fabric.window=window;window.fabric=fabric}else{fabric.document=require("jsdom").jsdom("");if(fabric.document.createWindow){fabric.window=fabric.document.createWindow()}else{fabric.window=fabric.document.parentWindow}}fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement;fabric.isLikelyNode=typeof Buffer!=="undefined"&&typeof window==="undefined";fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id"];fabric.DPI=96;fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)";fabric.fontPaths={};fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1;(function(){function _removeEventListener(eventName,handler){if(!this.__eventListeners[eventName]){return}var eventListener=this.__eventListeners[eventName];if(handler){eventListener[eventListener.indexOf(handler)]=false}else{fabric.util.array.fill(eventListener,false)}}function observe(eventName,handler){if(!this.__eventListeners){this.__eventListeners={}}if(arguments.length===1){for(var prop in eventName){this.on(prop,eventName[prop])}}else{if(!this.__eventListeners[eventName]){this.__eventListeners[eventName]=[]}this.__eventListeners[eventName].push(handler)}return this}function stopObserving(eventName,handler){if(!this.__eventListeners){return}if(arguments.length===0){for(eventName in this.__eventListeners){_removeEventListener.call(this,eventName)}}else if(arguments.length===1&&typeof arguments[0]==="object"){for(var prop in eventName){_removeEventListener.call(this,prop,eventName[prop])}}else{_removeEventListener.call(this,eventName,handler)}return this}function fire(eventName,options){if(!this.__eventListeners){return}var listenersForEvent=this.__eventListeners[eventName];if(!listenersForEvent){return}for(var i=0,len=listenersForEvent.length;i-1},complexity:function(){return this.getObjects().reduce(function(memo,current){memo+=current.complexity?current.complexity():0;return memo},0)}};(function(global){var sqrt=Math.sqrt,atan2=Math.atan2,pow=Math.pow,abs=Math.abs,PiBy180=Math.PI/180;fabric.util={removeFromArray:function(array,value){var idx=array.indexOf(value);if(idx!==-1){array.splice(idx,1)}return array},getRandomInt:function(min,max){return Math.floor(Math.random()*(max-min+1))+min},degreesToRadians:function(degrees){return degrees*PiBy180},radiansToDegrees:function(radians){return radians/PiBy180},rotatePoint:function(point,origin,radians){point.subtractEquals(origin);var v=fabric.util.rotateVector(point,radians);return new fabric.Point(v.x,v.y).addEquals(origin)},rotateVector:function(vector,radians){var sin=Math.sin(radians),cos=Math.cos(radians),rx=vector.x*cos-vector.y*sin,ry=vector.x*sin+vector.y*cos;return{x:rx,y:ry}},transformPoint:function(p,t,ignoreOffset){if(ignoreOffset){return new fabric.Point(t[0]*p.x+t[2]*p.y,t[1]*p.x+t[3]*p.y)}return new fabric.Point(t[0]*p.x+t[2]*p.y+t[4],t[1]*p.x+t[3]*p.y+t[5])},makeBoundingBoxFromPoints:function(points){var xPoints=[points[0].x,points[1].x,points[2].x,points[3].x],minX=fabric.util.array.min(xPoints),maxX=fabric.util.array.max(xPoints),width=Math.abs(minX-maxX),yPoints=[points[0].y,points[1].y,points[2].y,points[3].y],minY=fabric.util.array.min(yPoints),maxY=fabric.util.array.max(yPoints),height=Math.abs(minY-maxY);return{left:minX,top:minY,width:width,height:height}},invertTransform:function(t){var a=1/(t[0]*t[3]-t[1]*t[2]),r=[a*t[3],-a*t[1],-a*t[2],a*t[0]],o=fabric.util.transformPoint({x:t[4],y:t[5]},r,true);r[4]=-o.x;r[5]=-o.y;return r},toFixed:function(number,fractionDigits){return parseFloat(Number(number).toFixed(fractionDigits))},parseUnit:function(value,fontSize){var unit=/\D{0,2}$/.exec(value),number=parseFloat(value);if(!fontSize){fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}switch(unit[0]){case"mm":return number*fabric.DPI/25.4;case"cm":return number*fabric.DPI/2.54;case"in":return number*fabric.DPI;case"pt":return number*fabric.DPI/72;case"pc":return number*fabric.DPI/72*12;case"em":return number*fontSize;default:return number}},falseFunction:function(){return false},getKlass:function(type,namespace){type=fabric.util.string.camelize(type.charAt(0).toUpperCase()+type.slice(1));return fabric.util.resolveNamespace(namespace)[type]},resolveNamespace:function(namespace){if(!namespace){return fabric}var parts=namespace.split("."),len=parts.length,obj=global||fabric.window;for(var i=0;ix){x+=da[di++%dc];if(x>len){x=len}ctx[draw?"lineTo":"moveTo"](x,0);draw=!draw}ctx.restore()},createCanvasElement:function(canvasEl){canvasEl||(canvasEl=fabric.document.createElement("canvas"));if(!canvasEl.getContext&&typeof G_vmlCanvasManager!=="undefined"){G_vmlCanvasManager.initElement(canvasEl)}return canvasEl},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(klass){var proto=klass.prototype;for(var i=proto.stateProperties.length;i--;){var propName=proto.stateProperties[i],capitalizedPropName=propName.charAt(0).toUpperCase()+propName.slice(1),setterName="set"+capitalizedPropName,getterName="get"+capitalizedPropName;if(!proto[getterName]){proto[getterName]=function(property){return new Function('return this.get("'+property+'")')}(propName)}if(!proto[setterName]){proto[setterName]=function(property){return new Function("value",'return this.set("'+property+'", value)')}(propName)}}},clipContext:function(receiver,ctx){ctx.save();ctx.beginPath();receiver.clipTo(ctx);ctx.clip()},multiplyTransformMatrices:function(a,b,is2x2){return[a[0]*b[0]+a[2]*b[1],a[1]*b[0]+a[3]*b[1],a[0]*b[2]+a[2]*b[3],a[1]*b[2]+a[3]*b[3],is2x2?0:a[0]*b[4]+a[2]*b[5]+a[4],is2x2?0:a[1]*b[4]+a[3]*b[5]+a[5]]},qrDecompose:function(a){var angle=atan2(a[1],a[0]),denom=pow(a[0],2)+pow(a[1],2),scaleX=sqrt(denom),scaleY=(a[0]*a[3]-a[2]*a[1])/scaleX,skewX=atan2(a[0]*a[2]+a[1]*a[3],denom);return{angle:angle/PiBy180,scaleX:scaleX,scaleY:scaleY,skewX:skewX/PiBy180,skewY:0,translateX:a[4],translateY:a[5]}},customTransformMatrix:function(scaleX,scaleY,skewX){var skewMatrixX=[1,0,abs(Math.tan(skewX*PiBy180)),1],scaleMatrix=[abs(scaleX),0,0,abs(scaleY)];return fabric.util.multiplyTransformMatrices(scaleMatrix,skewMatrixX,true)},resetObjectTransform:function(target){target.scaleX=1;target.scaleY=1;target.skewX=0;target.skewY=0;target.flipX=false;target.flipY=false;target.setAngle(0)},getFunctionBody:function(fn){return(String(fn).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(ctx,x,y,tolerance){if(tolerance>0){if(x>tolerance){x-=tolerance}else{x=0}if(y>tolerance){y-=tolerance}else{y=0}}var _isTransparent=true,imageData=ctx.getImageData(x,y,tolerance*2||1,tolerance*2||1);for(var i=3,l=imageData.data.length;i0){dtheta-=2*PI}else if(sweep===1&&dtheta<0){dtheta+=2*PI}var segments=Math.ceil(Math.abs(dtheta/PI*2)),result=[],mDelta=dtheta/segments,mT=8/3*Math.sin(mDelta/4)*Math.sin(mDelta/4)/Math.sin(mDelta/2),th3=mTheta+mDelta;for(var i=0;i=ta){return tb-ta}else{return 2*Math.PI-(ta-tb)}}fabric.util.drawArc=function(ctx,fx,fy,coords){var rx=coords[0],ry=coords[1],rot=coords[2],large=coords[3],sweep=coords[4],tx=coords[5],ty=coords[6],segs=[[],[],[],[]],segsNorm=arcToSegments(tx-fx,ty-fy,rx,ry,large,sweep,rot);for(var i=0,len=segsNorm.length;i0){b=6*y0-12*y1+6*y2;a=-3*y0+9*y1-9*y2+3*y3;c=3*y1-3*y0}if(abs(a)<1e-12){if(abs(b)<1e-12){continue}t=-c/b;if(0>>0;if(len===0){return-1}var n=0;if(arguments.length>0){n=Number(arguments[1]);if(n!==n){n=0}else if(n!==0&&n!==Number.POSITIVE_INFINITY&&n!==Number.NEGATIVE_INFINITY){n=(n>0||-1)*Math.floor(Math.abs(n))}}if(n>=len){return-1}var k=n>=0?n:Math.max(len-Math.abs(n),0);for(;k>>0;i>>0;i>>0;i>>0;i>>0;i>>0,i=0,rv;if(arguments.length>1){rv=arguments[1]}else{do{if(i in this){rv=this[i++];break}if(++i>=len){throw new TypeError}}while(true)}for(;i=value2})}function min(array,byProperty){return find(array,byProperty,function(value1,value2){return value1/g,">")}fabric.util.string={camelize:camelize,capitalize:capitalize,escapeXml:escapeXml}})();(function(){var slice=Array.prototype.slice,apply=Function.prototype.apply,Dummy=function(){};if(!Function.prototype.bind){Function.prototype.bind=function(thisArg){var _this=this,args=slice.call(arguments,1),bound;if(args.length){bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,args.concat(slice.call(arguments)))}}else{bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,arguments)}}Dummy.prototype=this.prototype;bound.prototype=new Dummy;return bound}}})();(function(){var slice=Array.prototype.slice,emptyFunction=function(){},IS_DONTENUM_BUGGY=function(){for(var p in{toString:1}){if(p==="toString"){return false}}return true}(),addMethods=function(klass,source,parent){for(var property in source){if(property in klass.prototype&&typeof klass.prototype[property]==="function"&&(source[property]+"").indexOf("callSuper")>-1){klass.prototype[property]=function(property){return function(){var superclass=this.constructor.superclass;this.constructor.superclass=parent;var returnValue=source[property].apply(this,arguments);this.constructor.superclass=superclass;if(property!=="initialize"){return returnValue}}}(property)}else{klass.prototype[property]=source[property]}if(IS_DONTENUM_BUGGY){if(source.toString!==Object.prototype.toString){klass.prototype.toString=source.toString}if(source.valueOf!==Object.prototype.valueOf){klass.prototype.valueOf=source.valueOf}}}};function Subclass(){}function callSuper(methodName){var fn=this.constructor.superclass.prototype[methodName];return arguments.length>1?fn.apply(this,slice.call(arguments,1)):fn.call(this)}function createClass(){var parent=null,properties=slice.call(arguments,0);if(typeof properties[0]==="function"){parent=properties.shift()}function klass(){this.initialize.apply(this,arguments)}klass.superclass=parent;klass.subclasses=[];if(parent){Subclass.prototype=parent.prototype;klass.prototype=new Subclass;parent.subclasses.push(klass)}for(var i=0,length=properties.length;i-1?setOpacity(element,styles.match(/opacity:\s*(\d?\.?\d*)/)[1]):element}for(var property in styles){if(property==="opacity"){setOpacity(element,styles[property])}else{var normalizedProperty=property==="float"||property==="cssFloat"?typeof elementStyle.styleFloat==="undefined"?"cssFloat":"styleFloat":property;elementStyle[normalizedProperty]=styles[property]}}return element}var parseEl=fabric.document.createElement("div"),supportsOpacity=typeof parseEl.style.opacity==="string",supportsFilters=typeof parseEl.style.filter==="string",reOpacity=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,setOpacity=function(element){return element};if(supportsOpacity){setOpacity=function(element,value){element.style.opacity=value;return element}}else if(supportsFilters){setOpacity=function(element,value){var es=element.style;if(element.currentStyle&&!element.currentStyle.hasLayout){es.zoom=1}if(reOpacity.test(es.filter)){value=value>=.9999?"":"alpha(opacity="+value*100+")";es.filter=es.filter.replace(reOpacity,value)}else{es.filter+=" alpha(opacity="+value*100+")"}return element}}fabric.util.setStyle=setStyle})();(function(){var _slice=Array.prototype.slice;function getById(id){return typeof id==="string"?fabric.document.getElementById(id):id}var sliceCanConvertNodelists,toArray=function(arrayLike){return _slice.call(arrayLike,0)};try{sliceCanConvertNodelists=toArray(fabric.document.childNodes)instanceof Array}catch(err){}if(!sliceCanConvertNodelists){toArray=function(arrayLike){var arr=new Array(arrayLike.length),i=arrayLike.length;while(i--){arr[i]=arrayLike[i]}return arr}}function makeElement(tagName,attributes){var el=fabric.document.createElement(tagName);for(var prop in attributes){if(prop==="class"){el.className=attributes[prop]}else if(prop==="for"){el.htmlFor=attributes[prop]}else{el.setAttribute(prop,attributes[prop])}}return el}function addClass(element,className){if(element&&(" "+element.className+" ").indexOf(" "+className+" ")===-1){element.className+=(element.className?" ":"")+className}}function wrapElement(element,wrapper,attributes){if(typeof wrapper==="string"){wrapper=makeElement(wrapper,attributes)}if(element.parentNode){element.parentNode.replaceChild(wrapper,element)}wrapper.appendChild(element);return wrapper}function getScrollLeftTop(element){var left=0,top=0,docElement=fabric.document.documentElement,body=fabric.document.body||{scrollLeft:0,scrollTop:0};while(element&&(element.parentNode||element.host)){element=element.parentNode||element.host;if(element===fabric.document){left=body.scrollLeft||docElement.scrollLeft||0;top=body.scrollTop||docElement.scrollTop||0}else{left+=element.scrollLeft||0;top+=element.scrollTop||0}if(element.nodeType===1&&fabric.util.getElementStyle(element,"position")==="fixed"){break}}return{left:left,top:top}}function getElementOffset(element){var docElem,doc=element&&element.ownerDocument,box={left:0,top:0},offset={left:0,top:0},scrollLeftTop,offsetAttributes={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!doc){return offset}for(var attr in offsetAttributes){offset[offsetAttributes[attr]]+=parseInt(getElementStyle(element,attr),10)||0}docElem=doc.documentElement;if(typeof element.getBoundingClientRect!=="undefined"){box=element.getBoundingClientRect()}scrollLeftTop=getScrollLeftTop(element);return{left:box.left+scrollLeftTop.left-(docElem.clientLeft||0)+offset.left,top:box.top+scrollLeftTop.top-(docElem.clientTop||0)+offset.top}}var getElementStyle;if(fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle){getElementStyle=function(element,attr){var style=fabric.document.defaultView.getComputedStyle(element,null);return style?style[attr]:undefined}}else{getElementStyle=function(element,attr){var value=element.style[attr];if(!value&&element.currentStyle){value=element.currentStyle[attr]}return value}}(function(){var style=fabric.document.documentElement.style,selectProp="userSelect"in style?"userSelect":"MozUserSelect"in style?"MozUserSelect":"WebkitUserSelect"in style?"WebkitUserSelect":"KhtmlUserSelect"in style?"KhtmlUserSelect":"";function makeElementUnselectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=fabric.util.falseFunction}if(selectProp){element.style[selectProp]="none"}else if(typeof element.unselectable==="string"){element.unselectable="on"}return element}function makeElementSelectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=null}if(selectProp){element.style[selectProp]=""}else if(typeof element.unselectable==="string"){element.unselectable=""}return element}fabric.util.makeElementUnselectable=makeElementUnselectable;fabric.util.makeElementSelectable=makeElementSelectable})();(function(){function getScript(url,callback){var headEl=fabric.document.getElementsByTagName("head")[0],scriptEl=fabric.document.createElement("script"),loading=true;scriptEl.onload=scriptEl.onreadystatechange=function(e){if(loading){if(typeof this.readyState==="string"&&this.readyState!=="loaded"&&this.readyState!=="complete"){return}loading=false;callback(e||fabric.window.event);scriptEl=scriptEl.onload=scriptEl.onreadystatechange=null}};scriptEl.src=url;headEl.appendChild(scriptEl)}fabric.util.getScript=getScript})();fabric.util.getById=getById;fabric.util.toArray=toArray;fabric.util.makeElement=makeElement;fabric.util.addClass=addClass;fabric.util.wrapElement=wrapElement;fabric.util.getScrollLeftTop=getScrollLeftTop;fabric.util.getElementOffset=getElementOffset;fabric.util.getElementStyle=getElementStyle})();(function(){function addParamToUrl(url,param){return url+(/\?/.test(url)?"&":"?")+param}var makeXHR=function(){var factories=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}];for(var i=factories.length;i--;){try{var req=factories[i]();if(req){return factories[i]}}catch(err){}}}();function emptyFn(){}function request(url,options){options||(options={});var method=options.method?options.method.toUpperCase():"GET",onComplete=options.onComplete||function(){},xhr=makeXHR(),body;xhr.onreadystatechange=function(){if(xhr.readyState===4){onComplete(xhr);xhr.onreadystatechange=emptyFn}};if(method==="GET"){body=null; +if(typeof options.parameters==="string"){url=addParamToUrl(url,options.parameters)}}xhr.open(method,url,true);if(method==="POST"||method==="PUT"){xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")}xhr.send(body);return xhr}fabric.util.request=request})();fabric.log=function(){};fabric.warn=function(){};if(typeof console!=="undefined"){["log","warn"].forEach(function(methodName){if(typeof console[methodName]!=="undefined"&&typeof console[methodName].apply==="function"){fabric[methodName]=function(){return console[methodName].apply(console,arguments)}}})}(function(){function animate(options){requestAnimFrame(function(timestamp){options||(options={});var start=timestamp||+new Date,duration=options.duration||500,finish=start+duration,time,onChange=options.onChange||function(){},abort=options.abort||function(){return false},easing=options.easing||function(t,b,c,d){return-c*Math.cos(t/d*(Math.PI/2))+c+b},startValue="startValue"in options?options.startValue:0,endValue="endValue"in options?options.endValue:100,byValue=options.byValue||endValue-startValue;options.onStart&&options.onStart();(function tick(ticktime){time=ticktime||+new Date;var currentTime=time>finish?duration:time-start;if(abort()){options.onComplete&&options.onComplete();return}onChange(easing(currentTime,startValue,byValue,duration));if(time>finish){options.onComplete&&options.onComplete();return}requestAnimFrame(tick)})(start)})}var _requestAnimFrame=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(callback){fabric.window.setTimeout(callback,1e3/60)};function requestAnimFrame(){return _requestAnimFrame.apply(fabric.window,arguments)}fabric.util.animate=animate;fabric.util.requestAnimFrame=requestAnimFrame})();(function(){function normalize(a,c,p,s){if(a1){matrices.shift();combinedMatrix=fabric.util.multiplyTransformMatrices(combinedMatrix,matrices[0])}return combinedMatrix}}();function parseStyleString(style,oStyle){var attr,value;style.replace(/;\s*$/,"").split(";").forEach(function(chunk){var pair=chunk.split(":");attr=normalizeAttr(pair[0].trim().toLowerCase());value=normalizeValue(attr,pair[1].trim());oStyle[attr]=value})}function parseStyleObject(style,oStyle){var attr,value;for(var prop in style){if(typeof style[prop]==="undefined"){continue}attr=normalizeAttr(prop.toLowerCase());value=normalizeValue(attr,style[prop]);oStyle[attr]=value}}function getGlobalStylesForElement(element,svgUid){var styles={};for(var rule in fabric.cssRules[svgUid]){if(elementMatchesRule(element,rule.split(" "))){for(var property in fabric.cssRules[svgUid][rule]){styles[property]=fabric.cssRules[svgUid][rule][property]}}}return styles}function elementMatchesRule(element,selectors){var firstMatching,parentMatching=true;firstMatching=selectorMatches(element,selectors.pop());if(firstMatching&&selectors.length){parentMatching=doesSomeParentMatch(element,selectors)}return firstMatching&&parentMatching&&selectors.length===0}function doesSomeParentMatch(element,selectors){var selector,parentMatching=true;while(element.parentNode&&element.parentNode.nodeType===1&&selectors.length){if(parentMatching){selector=selectors.pop()}element=element.parentNode;parentMatching=selectorMatches(element,selector)}return selectors.length===0}function selectorMatches(element,selector){var nodeName=element.nodeName,classNames=element.getAttribute("class"),id=element.getAttribute("id"),matcher;matcher=new RegExp("^"+nodeName,"i");selector=selector.replace(matcher,"");if(id&&selector.length){matcher=new RegExp("#"+id+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}if(classNames&&selector.length){classNames=classNames.split(" ");for(var i=classNames.length;i--;){matcher=new RegExp("\\."+classNames[i]+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}}return selector.length===0}function elementById(doc,id){var el;doc.getElementById&&(el=doc.getElementById(id));if(el){return el}var node,i,nodelist=doc.getElementsByTagName("*");for(i=0;iscaleY?scaleY:scaleX}if(scaleX===1&&scaleY===1&&minX===0&&minY===0&&x===0&&y===0){return parsedDim}if(x||y){translateMatrix=" translate("+parseUnit(x)+" "+parseUnit(y)+") "}matrix=translateMatrix+" matrix("+scaleX+" 0"+" 0 "+scaleY+" "+minX*scaleX+" "+minY*scaleY+") ";if(element.tagName==="svg"){el=element.ownerDocument.createElement("g");while(element.firstChild!=null){el.appendChild(element.firstChild)}element.appendChild(el)}else{el=element;matrix=el.getAttribute("transform")+matrix}el.setAttribute("transform",matrix);return parsedDim}fabric.parseSVGDocument=function(){function hasAncestorWithNodeName(element,nodeName){while(element&&(element=element.parentNode)){if(nodeName.test(element.nodeName)&&!element.getAttribute("instantiated_by_use")){return true}}return false}return function(doc,callback,reviver){if(!doc){return}parseUseDirectives(doc);var startTime=new Date,svgUid=fabric.Object.__uid++,options=applyViewboxTransform(doc),descendants=fabric.util.toArray(doc.getElementsByTagName("*"));options.svgUid=svgUid;if(descendants.length===0&&fabric.isLikelyNode){descendants=doc.selectNodes('//*[name(.)!="svg"]');var arr=[];for(var i=0,len=descendants.length;i\n',' \n \n')}}var reFontDeclaration=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*"+"(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+fabric.reNum+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+fabric.reNum+"))?\\s+(.*)");extend(fabric,{parseFontDeclaration:function(value,oStyle){var match=value.match(reFontDeclaration);if(!match){return}var fontStyle=match[1],fontWeight=match[3],fontSize=match[4],lineHeight=match[5],fontFamily=match[6];if(fontStyle){oStyle.fontStyle=fontStyle}if(fontWeight){oStyle.fontWeight=isNaN(parseFloat(fontWeight))?fontWeight:parseFloat(fontWeight)}if(fontSize){oStyle.fontSize=parseUnit(fontSize)}if(fontFamily){oStyle.fontFamily=fontFamily}if(lineHeight){oStyle.lineHeight=lineHeight==="normal"?1:lineHeight}},getGradientDefs:function(doc){var linearGradientEls=doc.getElementsByTagName("linearGradient"),radialGradientEls=doc.getElementsByTagName("radialGradient"),el,i,j=0,id,xlink,elList=[],gradientDefs={},idsToXlinkMap={};elList.length=linearGradientEls.length+radialGradientEls.length;i=linearGradientEls.length;while(i--){elList[j++]=linearGradientEls[i]}i=radialGradientEls.length;while(i--){elList[j++]=radialGradientEls[i]}while(j--){el=elList[j];xlink=el.getAttribute("xlink:href");id=el.getAttribute("id");if(xlink){idsToXlinkMap[id]=xlink.substr(1)}gradientDefs[id]=el}for(id in idsToXlinkMap){var el2=gradientDefs[idsToXlinkMap[id]].cloneNode(true);el=gradientDefs[id];while(el2.firstChild){el.appendChild(el2.firstChild)}}return gradientDefs},parseAttributes:function(element,attributes,svgUid){if(!element){return}var value,parentAttributes={},fontSize;if(typeof svgUid==="undefined"){svgUid=element.getAttribute("svgUid")}if(element.parentNode&&reAllowedParents.test(element.parentNode.nodeName)){parentAttributes=fabric.parseAttributes(element.parentNode,attributes,svgUid)}fontSize=parentAttributes&&parentAttributes.fontSize||element.getAttribute("font-size")||fabric.Text.DEFAULT_SVG_FONT_SIZE;var ownAttributes=attributes.reduce(function(memo,attr){value=element.getAttribute(attr);if(value){attr=normalizeAttr(attr);value=normalizeValue(attr,value,parentAttributes,fontSize);memo[attr]=value}return memo},{});ownAttributes=extend(ownAttributes,extend(getGlobalStylesForElement(element,svgUid),fabric.parseStyleAttribute(element)));if(ownAttributes.font){fabric.parseFontDeclaration(ownAttributes.font,ownAttributes)}return _setStrokeFillOpacity(extend(parentAttributes,ownAttributes))},parseElements:function(elements,callback,options,reviver){new fabric.ElementsParser(elements,callback,options,reviver).parse()},parseStyleAttribute:function(element){var oStyle={},style=element.getAttribute("style");if(!style){return oStyle}if(typeof style==="string"){parseStyleString(style,oStyle)}else{parseStyleObject(style,oStyle)}return oStyle},parsePointsAttribute:function(points){if(!points){return null}points=points.replace(/,/g," ").trim();points=points.split(/\s+/);var parsedPoints=[],i,len;i=0;len=points.length;for(;i/i,""))}if(!xml||!xml.documentElement){return}fabric.parseSVGDocument(xml.documentElement,function(results,options){svgCache.set(url,{objects:fabric.util.array.invoke(results,"toObject"),options:options});callback(results,options)},reviver)}},loadSVGFromString:function(string,callback,reviver){string=string.trim();var doc;if(typeof DOMParser!=="undefined"){var parser=new DOMParser;if(parser&&parser.parseFromString){doc=parser.parseFromString(string,"text/xml")}}else if(fabric.window.ActiveXObject){doc=new ActiveXObject("Microsoft.XMLDOM");doc.async="false";doc.loadXML(string.replace(//i,""))}fabric.parseSVGDocument(doc.documentElement,function(results,options){callback(results,options)},reviver)},createSVGFontFacesMarkup:function(objects){var markup="",fontList={},obj,fontFamily,style,row,rowIndex,char,charIndex,fontPaths=fabric.fontPaths;for(var i=0,len=objects.length;i',"","\n"].join("")}return markup},createSVGRefElementsMarkup:function(canvas){var markup=[];_createSVGPattern(markup,canvas,"backgroundColor");_createSVGPattern(markup,canvas,"overlayColor");return markup.join("")}})})(typeof exports!=="undefined"?exports:this);fabric.ElementsParser=function(elements,callback,options,reviver){this.elements=elements;this.callback=callback;this.options=options;this.reviver=reviver;this.svgUid=options&&options.svgUid||0};fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length);this.numElements=this.elements.length;this.createObjects()};fabric.ElementsParser.prototype.createObjects=function(){for(var i=0,len=this.elements.length;ithat.x&&this.y>that.y},gte:function(that){return this.x>=that.x&&this.y>=that.y},lerp:function(that,t){return new Point(this.x+(that.x-this.x)*t,this.y+(that.y-this.y)*t)},distanceFrom:function(that){var dx=this.x-that.x,dy=this.y-that.y;return Math.sqrt(dx*dx+dy*dy)},midPointFrom:function(that){return new Point(this.x+(that.x-this.x)/2,this.y+(that.y-this.y)/2)},min:function(that){return new Point(Math.min(this.x,that.x),Math.min(this.y,that.y))},max:function(that){return new Point(Math.max(this.x,that.x),Math.max(this.y,that.y))},toString:function(){return this.x+","+this.y},setXY:function(x,y){this.x=x;this.y=y},setFromPoint:function(that){this.x=that.x;this.y=that.y},swap:function(that){var x=this.x,y=this.y;this.x=that.x;this.y=that.y;that.x=x;that.y=y}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Intersection){fabric.warn("fabric.Intersection is already defined");return}function Intersection(status){this.status=status;this.points=[]}fabric.Intersection=Intersection;fabric.Intersection.prototype={appendPoint:function(point){this.points.push(point)},appendPoints:function(points){this.points=this.points.concat(points)}};fabric.Intersection.intersectLineLine=function(a1,a2,b1,b2){var result,uaT=(b2.x-b1.x)*(a1.y-b1.y)-(b2.y-b1.y)*(a1.x-b1.x),ubT=(a2.x-a1.x)*(a1.y-b1.y)-(a2.y-a1.y)*(a1.x-b1.x),uB=(b2.y-b1.y)*(a2.x-a1.x)-(b2.x-b1.x)*(a2.y-a1.y);if(uB!==0){var ua=uaT/uB,ub=ubT/uB;if(0<=ua&&ua<=1&&0<=ub&&ub<=1){result=new Intersection("Intersection");result.points.push(new fabric.Point(a1.x+ua*(a2.x-a1.x),a1.y+ua*(a2.y-a1.y)))}else{result=new Intersection}}else{if(uaT===0||ubT===0){result=new Intersection("Coincident")}else{result=new Intersection("Parallel")}}return result};fabric.Intersection.intersectLinePolygon=function(a1,a2,points){var result=new Intersection,length=points.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonPolygon=function(points1,points2){var result=new Intersection,length=points1.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonRectangle=function(points,r1,r2){var min=r1.min(r2),max=r1.max(r2),topRight=new fabric.Point(max.x,min.y),bottomLeft=new fabric.Point(min.x,max.y),inter1=Intersection.intersectLinePolygon(min,topRight,points),inter2=Intersection.intersectLinePolygon(topRight,max,points),inter3=Intersection.intersectLinePolygon(max,bottomLeft,points),inter4=Intersection.intersectLinePolygon(bottomLeft,min,points),result=new Intersection;result.appendPoints(inter1.points);result.appendPoints(inter2.points);result.appendPoints(inter3.points);result.appendPoints(inter4.points);if(result.points.length>0){result.status="Intersection"}return result}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Color){fabric.warn("fabric.Color is already defined.");return}function Color(color){if(!color){this.setSource([0,0,0,1])}else{this._tryParsingColor(color)}}fabric.Color=Color;fabric.Color.prototype={_tryParsingColor:function(color){var source;if(color in Color.colorNameMap){color=Color.colorNameMap[color] +}if(color==="transparent"){this.setSource([255,255,255,0]);return}source=Color.sourceFromHex(color);if(!source){source=Color.sourceFromRgb(color)}if(!source){source=Color.sourceFromHsl(color)}if(source){this.setSource(source)}},_rgbToHsl:function(r,g,b){r/=255,g/=255,b/=255;var h,s,l,max=fabric.util.array.max([r,g,b]),min=fabric.util.array.min([r,g,b]);l=(max+min)/2;if(max===min){h=s=0}else{var d=max-min;s=l>.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g1){t-=1}if(t<1/6){return p+(q-p)*6*t}if(t<1/2){return q}if(t<2/3){return p+(q-p)*(2/3-t)*6}return p}fabric.Color.fromRgb=function(color){return Color.fromSource(Color.sourceFromRgb(color))};fabric.Color.sourceFromRgb=function(color){var match=color.match(Color.reRGBa);if(match){var r=parseInt(match[1],10)/(/%$/.test(match[1])?100:1)*(/%$/.test(match[1])?255:1),g=parseInt(match[2],10)/(/%$/.test(match[2])?100:1)*(/%$/.test(match[2])?255:1),b=parseInt(match[3],10)/(/%$/.test(match[3])?100:1)*(/%$/.test(match[3])?255:1);return[parseInt(r,10),parseInt(g,10),parseInt(b,10),match[4]?parseFloat(match[4]):1]}};fabric.Color.fromRgba=Color.fromRgb;fabric.Color.fromHsl=function(color){return Color.fromSource(Color.sourceFromHsl(color))};fabric.Color.sourceFromHsl=function(color){var match=color.match(Color.reHSLa);if(!match){return}var h=(parseFloat(match[1])%360+360)%360/360,s=parseFloat(match[2])/(/%$/.test(match[2])?100:1),l=parseFloat(match[3])/(/%$/.test(match[3])?100:1),r,g,b;if(s===0){r=g=b=l}else{var q=l<=.5?l*(s+1):l+s-l*s,p=l*2-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3)}return[Math.round(r*255),Math.round(g*255),Math.round(b*255),match[4]?parseFloat(match[4]):1]};fabric.Color.fromHsla=Color.fromHsl;fabric.Color.fromHex=function(color){return Color.fromSource(Color.sourceFromHex(color))};fabric.Color.sourceFromHex=function(color){if(color.match(Color.reHex)){var value=color.slice(color.indexOf("#")+1),isShortNotation=value.length===3,r=isShortNotation?value.charAt(0)+value.charAt(0):value.substring(0,2),g=isShortNotation?value.charAt(1)+value.charAt(1):value.substring(2,4),b=isShortNotation?value.charAt(2)+value.charAt(2):value.substring(4,6);return[parseInt(r,16),parseInt(g,16),parseInt(b,16),1]}};fabric.Color.fromSource=function(source){var oColor=new Color;oColor.setSource(source);return oColor}})(typeof exports!=="undefined"?exports:this);(function(){function getColorStop(el){var style=el.getAttribute("style"),offset=el.getAttribute("offset")||0,color,colorAlpha,opacity;offset=parseFloat(offset)/(/%$/.test(offset)?100:1);offset=offset<0?0:offset>1?1:offset;if(style){var keyValuePairs=style.split(/\s*;\s*/);if(keyValuePairs[keyValuePairs.length-1]===""){keyValuePairs.pop()}for(var i=keyValuePairs.length;i--;){var split=keyValuePairs[i].split(/\s*:\s*/),key=split[0].trim(),value=split[1].trim();if(key==="stop-color"){color=value}else if(key==="stop-opacity"){opacity=value}}}if(!color){color=el.getAttribute("stop-color")||"rgb(0,0,0)"}if(!opacity){opacity=el.getAttribute("stop-opacity")}color=new fabric.Color(color);colorAlpha=color.getAlpha();opacity=isNaN(parseFloat(opacity))?1:parseFloat(opacity);opacity*=colorAlpha;return{offset:offset,color:color.toRgb(),opacity:opacity}}function getLinearCoords(el){return{x1:el.getAttribute("x1")||0,y1:el.getAttribute("y1")||0,x2:el.getAttribute("x2")||"100%",y2:el.getAttribute("y2")||0}}function getRadialCoords(el){return{x1:el.getAttribute("fx")||el.getAttribute("cx")||"50%",y1:el.getAttribute("fy")||el.getAttribute("cy")||"50%",r1:0,x2:el.getAttribute("cx")||"50%",y2:el.getAttribute("cy")||"50%",r2:el.getAttribute("r")||"50%"}}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(options){options||(options={});var coords={};this.id=fabric.Object.__uid++;this.type=options.type||"linear";coords={x1:options.coords.x1||0,y1:options.coords.y1||0,x2:options.coords.x2||0,y2:options.coords.y2||0};if(this.type==="radial"){coords.r1=options.coords.r1||0;coords.r2=options.coords.r2||0}this.coords=coords;this.colorStops=options.colorStops.slice();if(options.gradientTransform){this.gradientTransform=options.gradientTransform}this.offsetX=options.offsetX||this.offsetX;this.offsetY=options.offsetY||this.offsetY},addColorStop:function(colorStop){for(var position in colorStop){var color=new fabric.Color(colorStop[position]);this.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform}},toSVG:function(object){var coords=fabric.util.object.clone(this.coords),markup,commonAttributes;this.colorStops.sort(function(a,b){return a.offset-b.offset});if(!(object.group&&object.group.type==="path-group")){for(var prop in coords){if(prop==="x1"||prop==="x2"||prop==="r2"){coords[prop]+=this.offsetX-object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=this.offsetY-object.height/2}}}commonAttributes='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"';if(this.gradientTransform){commonAttributes+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '}if(this.type==="linear"){markup=["\n']}else if(this.type==="radial"){markup=["\n']}for(var i=0;i\n')}markup.push(this.type==="linear"?"\n":"\n");return markup.join("")},toLive:function(ctx,object){var gradient,prop,coords=fabric.util.object.clone(this.coords);if(!this.type){return}if(object.group&&object.group.type==="path-group"){for(prop in coords){if(prop==="x1"||prop==="x2"){coords[prop]+=-this.offsetX+object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=-this.offsetY+object.height/2}}}if(this.type==="linear"){gradient=ctx.createLinearGradient(coords.x1,coords.y1,coords.x2,coords.y2)}else if(this.type==="radial"){gradient=ctx.createRadialGradient(coords.x1,coords.y1,coords.r1,coords.x2,coords.y2,coords.r2)}for(var i=0,len=this.colorStops.length;i\n'+'\n'+"\n"},toLive:function(ctx){var source=typeof this.source==="function"?this.source():this.source;if(!source){return""}if(typeof source.src!=="undefined"){if(!source.complete){return""}if(source.naturalWidth===0||source.naturalHeight===0){return""}}return ctx.createPattern(source,this.repeat)}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),toFixed=fabric.util.toFixed;if(fabric.Shadow){fabric.warn("fabric.Shadow is already defined.");return}fabric.Shadow=fabric.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:false,includeDefaultValues:true,initialize:function(options){if(typeof options==="string"){options=this._parseShadow(options)}for(var prop in options){this[prop]=options[prop]}this.id=fabric.Object.__uid++},_parseShadow:function(shadow){var shadowStr=shadow.trim(),offsetsAndBlur=fabric.Shadow.reOffsetsAndBlur.exec(shadowStr)||[],color=shadowStr.replace(fabric.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:color.trim(),offsetX:parseInt(offsetsAndBlur[1],10)||0,offsetY:parseInt(offsetsAndBlur[2],10)||0,blur:parseInt(offsetsAndBlur[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(object){var fBoxX=40,fBoxY=40,NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,offset=fabric.util.rotateVector({x:this.offsetX,y:this.offsetY},fabric.util.degreesToRadians(-object.angle)),BLUR_BOX=20;if(object.width&&object.height){fBoxX=toFixed((Math.abs(offset.x)+this.blur)/object.width,NUM_FRACTION_DIGITS)*100+BLUR_BOX;fBoxY=toFixed((Math.abs(offset.y)+this.blur)/object.height,NUM_FRACTION_DIGITS)*100+BLUR_BOX}if(object.flipX){offset.x*=-1}if(object.flipY){offset.y*=-1}return'\n"+' \n'+' \n'+' \n'+' \n'+" \n"+" \n"+' \n'+" \n"+"\n"},toObject:function(){if(this.includeDefaultValues){return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke}}var obj={},proto=fabric.Shadow.prototype;["color","blur","offsetX","offsetY","affectStroke"].forEach(function(prop){if(this[prop]!==proto[prop]){obj[prop]=this[prop]}},this);return obj}});fabric.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/})(typeof exports!=="undefined"?exports:this);(function(){"use strict";if(fabric.StaticCanvas){fabric.warn("fabric.StaticCanvas is already defined.");return}var extend=fabric.util.object.extend,getElementOffset=fabric.util.getElementOffset,removeFromArray=fabric.util.removeFromArray,toFixed=fabric.util.toFixed,CANVAS_INIT_ERROR=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(el,options){options||(options={});this._initStatic(el,options)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:true,stateful:true,renderOnAddRemove:true,clipTo:null,controlsAboveOverlay:false,allowTouchScrolling:false,imageSmoothingEnabled:true,preserveObjectStacking:false,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},enableRetinaScaling:true,_initStatic:function(el,options){this._objects=[];this._createLowerCanvas(el);this._initOptions(options);this._setImageSmoothing();if(!this.interactive){this._initRetinaScaling()}if(options.overlayImage){this.setOverlayImage(options.overlayImage,this.renderAll.bind(this))}if(options.backgroundImage){this.setBackgroundImage(options.backgroundImage,this.renderAll.bind(this))}if(options.backgroundColor){this.setBackgroundColor(options.backgroundColor,this.renderAll.bind(this))}if(options.overlayColor){this.setOverlayColor(options.overlayColor,this.renderAll.bind(this))}this.calcOffset()},_isRetinaScaling:function(){return fabric.devicePixelRatio!==1&&this.enableRetinaScaling},_initRetinaScaling:function(){if(!this._isRetinaScaling()){return}this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio);this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio);this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio)},calcOffset:function(){this._offset=getElementOffset(this.lowerCanvasEl);return this},setOverlayImage:function(image,callback,options){return this.__setBgOverlayImage("overlayImage",image,callback,options)},setBackgroundImage:function(image,callback,options){return this.__setBgOverlayImage("backgroundImage",image,callback,options)},setOverlayColor:function(overlayColor,callback){return this.__setBgOverlayColor("overlayColor",overlayColor,callback)},setBackgroundColor:function(backgroundColor,callback){return this.__setBgOverlayColor("backgroundColor",backgroundColor,callback)},_setImageSmoothing:function(){var ctx=this.getContext();ctx.imageSmoothingEnabled=ctx.imageSmoothingEnabled||ctx.webkitImageSmoothingEnabled||ctx.mozImageSmoothingEnabled||ctx.msImageSmoothingEnabled||ctx.oImageSmoothingEnabled;ctx.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(property,image,callback,options){if(typeof image==="string"){fabric.util.loadImage(image,function(img){this[property]=new fabric.Image(img,options);callback&&callback(img)},this,options&&options.crossOrigin)}else{options&&image.setOptions(options);this[property]=image;callback&&callback(image)}return this},__setBgOverlayColor:function(property,color,callback){if(color&&color.source){var _this=this;fabric.util.loadImage(color.source,function(img){_this[property]=new fabric.Pattern({source:img,repeat:color.repeat,offsetX:color.offsetX,offsetY:color.offsetY});callback&&callback()})}else{this[property]=color;callback&&callback()}return this},_createCanvasElement:function(){var element=fabric.document.createElement("canvas");if(!element.style){element.style={}}if(!element){throw CANVAS_INIT_ERROR}this._initCanvasElement(element);return element},_initCanvasElement:function(element){fabric.util.createCanvasElement(element);if(typeof element.getContext==="undefined"){throw CANVAS_INIT_ERROR}},_initOptions:function(options){for(var prop in options){this[prop]=options[prop]}this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0;this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0;if(!this.lowerCanvasEl.style){return}this.lowerCanvasEl.width=this.width;this.lowerCanvasEl.height=this.height;this.lowerCanvasEl.style.width=this.width+"px";this.lowerCanvasEl.style.height=this.height+"px";this.viewportTransform=this.viewportTransform.slice()},_createLowerCanvas:function(canvasEl){this.lowerCanvasEl=fabric.util.getById(canvasEl)||this._createCanvasElement();this._initCanvasElement(this.lowerCanvasEl);fabric.util.addClass(this.lowerCanvasEl,"lower-canvas");if(this.interactive){this._applyCanvasStyle(this.lowerCanvasEl)}this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(value,options){return this.setDimensions({width:value},options)},setHeight:function(value,options){return this.setDimensions({height:value},options)},setDimensions:function(dimensions,options){var cssValue;options=options||{};for(var prop in dimensions){cssValue=dimensions[prop];if(!options.cssOnly){this._setBackstoreDimension(prop,dimensions[prop]);cssValue+="px"}if(!options.backstoreOnly){this._setCssDimension(prop,cssValue)}}this._initRetinaScaling();this._setImageSmoothing();this.calcOffset();if(!options.cssOnly){this.renderAll()}return this},_setBackstoreDimension:function(prop,value){this.lowerCanvasEl[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl[prop]=value}if(this.cacheCanvasEl){this.cacheCanvasEl[prop]=value}this[prop]=value;return this},_setCssDimension:function(prop,value){this.lowerCanvasEl.style[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl.style[prop]=value}if(this.wrapperEl){this.wrapperEl.style[prop]=value}return this},getZoom:function(){return Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(vpt){var activeGroup=this.getActiveGroup();this.viewportTransform=vpt;this.renderAll();for(var i=0,len=this._objects.length;i");return markup.join("")},_setSVGPreamble:function(markup,options){if(options.suppressPreamble){return}markup.push('\n','\n')},_setSVGHeader:function(markup,options){var width=options.width||this.width,height=options.height||this.height,vpt,viewBox='viewBox="0 0 '+this.width+" "+this.height+'" ',NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;if(options.viewBox){viewBox='viewBox="'+options.viewBox.x+" "+options.viewBox.y+" "+options.viewBox.width+" "+options.viewBox.height+'" '}else{if(this.svgViewportTransformation){vpt=this.viewportTransform;viewBox='viewBox="'+toFixed(-vpt[4]/vpt[0],NUM_FRACTION_DIGITS)+" "+toFixed(-vpt[5]/vpt[3],NUM_FRACTION_DIGITS)+" "+toFixed(this.width/vpt[0],NUM_FRACTION_DIGITS)+" "+toFixed(this.height/vpt[3],NUM_FRACTION_DIGITS)+'" '}}markup.push("\n',"Created with Fabric.js ",fabric.version,"\n","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"\n")},_setSVGObjects:function(markup,reviver){for(var i=0,objects=this.getObjects(),len=objects.length;i\n")}else if(this[property]&&property==="overlayColor"){markup.push('\n")}},sendToBack:function(object){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=objs.length;i--;){obj=objs[i];removeFromArray(this._objects,obj); +this._objects.unshift(obj)}}else{removeFromArray(this._objects,object);this._objects.unshift(object)}return this.renderAll&&this.renderAll()},bringToFront:function(object){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=0;i=0;--i){var isIntersecting=object.intersectsWithObject(this._objects[i])||object.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(object);if(isIntersecting){newIdx=i;break}}}else{newIdx=idx-1}return newIdx},bringForward:function(object,intersecting){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,idx,newIdx,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=objs.length;i--;){obj=objs[i];idx=this._objects.indexOf(obj);if(idx!==this._objects.length-1){newIdx=idx+1;removeFromArray(this._objects,obj);this._objects.splice(newIdx,0,obj)}}}else{idx=this._objects.indexOf(object);if(idx!==this._objects.length-1){newIdx=this._findNewUpperIndex(object,idx,intersecting);removeFromArray(this._objects,object);this._objects.splice(newIdx,0,object)}}this.renderAll&&this.renderAll();return this},_findNewUpperIndex:function(object,idx,intersecting){var newIdx;if(intersecting){newIdx=idx;for(var i=idx+1;i"}});extend(fabric.StaticCanvas.prototype,fabric.Observable);extend(fabric.StaticCanvas.prototype,fabric.Collection);extend(fabric.StaticCanvas.prototype,fabric.DataURLExporter);extend(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(methodName){var el=fabric.util.createCanvasElement();if(!el||!el.getContext){return null}var ctx=el.getContext("2d");if(!ctx){return null}switch(methodName){case"getImageData":return typeof ctx.getImageData!=="undefined";case"setLineDash":return typeof ctx.setLineDash!=="undefined";case"toDataURL":return typeof el.toDataURL!=="undefined";case"toDataURLWithQuality":try{el.toDataURL("image/jpeg",0);return true}catch(e){}return false;default:return null}}});fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject})();fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeDashArray:null,setShadow:function(options){this.shadow=new fabric.Shadow(options);return this},_setBrushStyles:function(){var ctx=this.canvas.contextTop;ctx.strokeStyle=this.color;ctx.lineWidth=this.width;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;if(this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")){ctx.setLineDash(this.strokeDashArray)}},_setShadow:function(){if(!this.shadow){return}var ctx=this.canvas.contextTop;ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur;ctx.shadowOffsetX=this.shadow.offsetX;ctx.shadowOffsetY=this.shadow.offsetY},_resetShadow:function(){var ctx=this.canvas.contextTop;ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0}});(function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(canvas){this.canvas=canvas;this._points=[]},onMouseDown:function(pointer){this._prepareForDrawing(pointer);this._captureDrawingPath(pointer);this._render()},onMouseMove:function(pointer){this._captureDrawingPath(pointer);this.canvas.clearContext(this.canvas.contextTop);this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(pointer){var p=new fabric.Point(pointer.x,pointer.y);this._reset();this._addPoint(p);this.canvas.contextTop.moveTo(p.x,p.y)},_addPoint:function(point){this._points.push(point)},_reset:function(){this._points.length=0;this._setBrushStyles();this._setShadow()},_captureDrawingPath:function(pointer){var pointerPoint=new fabric.Point(pointer.x,pointer.y);this._addPoint(pointerPoint)},_render:function(){var ctx=this.canvas.contextTop,v=this.canvas.viewportTransform,p1=this._points[0],p2=this._points[1];ctx.save();ctx.transform(v[0],v[1],v[2],v[3],v[4],v[5]);ctx.beginPath();if(this._points.length===2&&p1.x===p2.x&&p1.y===p2.y){p1.x-=.5;p2.x+=.5}ctx.moveTo(p1.x,p1.y);for(var i=1,len=this._points.length;i0?1:-1;if(by==="y"){skew=t.target.skewY;originA="top";originB="bottom";property="originY"}origins[-1]=originA;origins[1]=originB;t.target.flipX&&(flipSign*=-1);t.target.flipY&&(flipSign*=-1);if(skew===0){t.skewSign=-corner*mouseMove*flipSign;t[property]=origins[-mouseMove]}else{skew=skew>0?1:-1;t.skewSign=skew;t[property]=origins[skew*corner*flipSign]}},_skewObject:function(x,y,by){var t=this._currentTransform,target=t.target,skewed=false,lockSkewingX=target.get("lockSkewingX"),lockSkewingY=target.get("lockSkewingY");if(lockSkewingX&&by==="x"||lockSkewingY&&by==="y"){return false}var center=target.getCenterPoint(),actualMouseByCenter=target.toLocalPoint(new fabric.Point(x,y),"center","center")[by],lastMouseByCenter=target.toLocalPoint(new fabric.Point(t.lastX,t.lastY),"center","center")[by],actualMouseByOrigin,constraintPosition,dim=target._getTransformedDimensions();this._changeSkewTransformOrigin(actualMouseByCenter-lastMouseByCenter,t,by);actualMouseByOrigin=target.toLocalPoint(new fabric.Point(x,y),t.originX,t.originY)[by],constraintPosition=target.translateToOriginPoint(center,t.originX,t.originY);skewed=this._setObjectSkew(actualMouseByOrigin,t,by,dim);t.lastX=x;t.lastY=y;target.setPositionByOrigin(constraintPosition,t.originX,t.originY);return skewed},_setObjectSkew:function(localMouse,transform,by,_dim){var target=transform.target,newValue,skewed=false,skewSign=transform.skewSign,newDim,dimNoSkew,otherBy,_otherBy,_by,newDimMouse,skewX,skewY;if(by==="x"){otherBy="y";_otherBy="Y";_by="X";skewX=0;skewY=target.skewY}else{otherBy="x";_otherBy="X";_by="Y";skewX=target.skewX;skewY=0}dimNoSkew=target._getTransformedDimensions(skewX,skewY);newDimMouse=2*Math.abs(localMouse)-dimNoSkew[by];if(newDimMouse<=2){newValue=0}else{newValue=skewSign*Math.atan(newDimMouse/target["scale"+_by]/(dimNoSkew[otherBy]/target["scale"+_otherBy]));newValue=fabric.util.radiansToDegrees(newValue)}skewed=target["skew"+_by]!==newValue;target.set("skew"+_by,newValue);if(target["skew"+_otherBy]!==0){newDim=target._getTransformedDimensions();newValue=_dim[otherBy]/newDim[otherBy]*target["scale"+_otherBy];target.set("scale"+_otherBy,newValue)}return skewed},_scaleObject:function(x,y,by){var t=this._currentTransform,target=t.target,lockScalingX=target.get("lockScalingX"),lockScalingY=target.get("lockScalingY"),lockScalingFlip=target.get("lockScalingFlip");if(lockScalingX&&lockScalingY){return false}var constraintPosition=target.translateToOriginPoint(target.getCenterPoint(),t.originX,t.originY),localMouse=target.toLocalPoint(new fabric.Point(x,y),t.originX,t.originY),dim=target._getTransformedDimensions(),scaled=false;this._setLocalMouse(localMouse,t);scaled=this._setObjectScale(localMouse,t,lockScalingX,lockScalingY,by,lockScalingFlip,dim);target.setPositionByOrigin(constraintPosition,t.originX,t.originY);return scaled},_setObjectScale:function(localMouse,transform,lockScalingX,lockScalingY,by,lockScalingFlip,_dim){var target=transform.target,forbidScalingX=false,forbidScalingY=false,scaled=false,changeX,changeY,scaleX,scaleY;scaleX=localMouse.x*target.scaleX/_dim.x;scaleY=localMouse.y*target.scaleY/_dim.y;changeX=target.scaleX!==scaleX;changeY=target.scaleY!==scaleY;if(lockScalingFlip&&scaleX<=0&&scaleXtarget.padding){if(localMouse.x<0){localMouse.x+=target.padding}else{localMouse.x-=target.padding}}else{localMouse.x=0}if(abs(localMouse.y)>target.padding){if(localMouse.y<0){localMouse.y+=target.padding}else{localMouse.y-=target.padding}}else{localMouse.y=0}},_rotateObject:function(x,y){var t=this._currentTransform;if(t.target.get("lockRotation")){return false}var lastAngle=atan2(t.ey-t.top,t.ex-t.left),curAngle=atan2(y-t.top,x-t.left),angle=radiansToDegrees(curAngle-lastAngle+t.theta);if(angle<0){angle=360+angle}t.target.angle=angle%360;return true},setCursor:function(value){this.upperCanvasEl.style.cursor=value},_resetObjectTransform:function(target){target.scaleX=1;target.scaleY=1;target.skewX=0;target.skewY=0;target.setAngle(0)},_drawSelection:function(){var ctx=this.contextTop,groupSelector=this._groupSelector,left=groupSelector.left,top=groupSelector.top,aleft=abs(left),atop=abs(top);ctx.fillStyle=this.selectionColor;ctx.fillRect(groupSelector.ex-(left>0?0:-left),groupSelector.ey-(top>0?0:-top),aleft,atop);ctx.lineWidth=this.selectionLineWidth;ctx.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var px=groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),py=groupSelector.ey+STROKE_OFFSET-(top>0?0:atop);ctx.beginPath();fabric.util.drawDashedLine(ctx,px,py,px+aleft,py,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py+atop-1,px+aleft,py+atop-1,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py,px,py+atop,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px+aleft-1,py,px+aleft-1,py+atop,this.selectionDashArray);ctx.closePath();ctx.stroke()}else{ctx.strokeRect(groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),groupSelector.ey+STROKE_OFFSET-(top>0?0:atop),aleft,atop)}},_isLastRenderedObject:function(e){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e,true))},findTarget:function(e,skipGroup){if(this.skipTargetFind){return}if(this._isLastRenderedObject(e)){return this.lastRenderedObjectWithControlsAboveOverlay}var activeGroup=this.getActiveGroup();if(!skipGroup&&this._checkTarget(e,activeGroup,this.getPointer(e,true))){return activeGroup}var target=this._searchPossibleTargets(e,skipGroup);this._fireOverOutEvents(target,e);return target},_fireOverOutEvents:function(target,e){if(target){if(this._hoveredTarget!==target){if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget,e:e});this._hoveredTarget.fire("mouseout")}this.fire("mouse:over",{target:target,e:e});target.fire("mouseover");this._hoveredTarget=target}}else if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget,e:e});this._hoveredTarget.fire("mouseout");this._hoveredTarget=null}},_checkTarget:function(e,obj,pointer){if(obj&&obj.visible&&obj.evented&&this.containsPoint(e,obj)){if((this.perPixelTargetFind||obj.perPixelTargetFind)&&!obj.isEditing){var isTransparent=this.isTargetTransparent(obj,pointer.x,pointer.y);if(!isTransparent){return true}}else{return true}}},_searchPossibleTargets:function(e,skipGroup){var target,pointer=this.getPointer(e,true),i=this._objects.length;while(i--){if((!this._objects[i].group||skipGroup)&&this._checkTarget(e,this._objects[i],pointer)){this.relatedTarget=this._objects[i];target=this._objects[i];break}}return target},getPointer:function(e,ignoreZoom,upperCanvasEl){if(!upperCanvasEl){upperCanvasEl=this.upperCanvasEl}var pointer=getPointer(e),bounds=upperCanvasEl.getBoundingClientRect(),boundsWidth=bounds.width||0,boundsHeight=bounds.height||0,cssScale;if(!boundsWidth||!boundsHeight){if("top"in bounds&&"bottom"in bounds){boundsHeight=Math.abs(bounds.top-bounds.bottom)}if("right"in bounds&&"left"in bounds){boundsWidth=Math.abs(bounds.right-bounds.left)}}this.calcOffset();pointer.x=pointer.x-this._offset.left;pointer.y=pointer.y-this._offset.top;if(!ignoreZoom){pointer=fabric.util.transformPoint(pointer,fabric.util.invertTransform(this.viewportTransform))}if(boundsWidth===0||boundsHeight===0){cssScale={width:1,height:1}}else{cssScale={width:upperCanvasEl.width/boundsWidth,height:upperCanvasEl.height/boundsHeight}}return{x:pointer.x*cssScale.width,y:pointer.y*cssScale.height}},_createUpperCanvas:function(){var lowerCanvasClass=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement();fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+lowerCanvasClass);this.wrapperEl.appendChild(this.upperCanvasEl);this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl);this._applyCanvasStyle(this.upperCanvasEl);this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement();this.cacheCanvasEl.setAttribute("width",this.width);this.cacheCanvasEl.setAttribute("height",this.height);this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{"class":this.containerClass});fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+"px",height:this.getHeight()+"px",position:"relative"});fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(element){var width=this.getWidth()||element.width,height=this.getHeight()||element.height;fabric.util.setStyle(element,{position:"absolute",width:width+"px",height:height+"px",left:0,top:0});element.width=width;element.height=height;fabric.util.makeElementUnselectable(element)},_copyCanvasStyle:function(fromEl,toEl){toEl.style.cssText=fromEl.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(object){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=object;object.set("active",true)},setActiveObject:function(object,e){this._setActiveObject(object);this.renderAll();this.fire("object:selected",{target:object,e:e});object.fire("selected",{e:e});return this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=null},discardActiveObject:function(e){this._discardActiveObject();this.renderAll();this.fire("selection:cleared",{e:e});return this},_setActiveGroup:function(group){this._activeGroup=group;if(group){group.set("active",true)}},setActiveGroup:function(group,e){this._setActiveGroup(group);if(group){this.fire("object:selected",{target:group,e:e});group.fire("selected",{e:e})}return this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var g=this.getActiveGroup();if(g){g.destroy()}this.setActiveGroup(null)},discardActiveGroup:function(e){this._discardActiveGroup();this.fire("selection:cleared",{e:e});return this},deactivateAll:function(){var allObjects=this.getObjects(),i=0,len=allObjects.length;for(;i1){return}var groupSelector=this._groupSelector;if(groupSelector){pointer=this.getPointer(e,true);groupSelector.left=pointer.x-groupSelector.ex;groupSelector.top=pointer.y-groupSelector.ey;this.renderTop()}else if(!this._currentTransform){target=this.findTarget(e);if(!target||target&&!target.selectable){this.setCursor(this.defaultCursor)}else{this._setCursorFromEvent(e,target)}}else{this._transformObject(e)}this.fire("mouse:move",{target:target,e:e});target&&target.fire("mousemove",{e:e})},_transformObject:function(e){var pointer=this.getPointer(e),transform=this._currentTransform;transform.reset=false,transform.target.isMoving=true;this._beforeScaleTransform(e,transform);this._performTransformAction(e,transform,pointer);this.renderAll()},_performTransformAction:function(e,transform,pointer){var x=pointer.x,y=pointer.y,target=transform.target,action=transform.action,actionPerformed=false;if(action==="rotate"){(actionPerformed=this._rotateObject(x,y))&&this._fire("rotating",target,e)}else if(action==="scale"){(actionPerformed=this._onScale(e,transform,x,y))&&this._fire("scaling",target,e)}else if(action==="scaleX"){(actionPerformed=this._scaleObject(x,y,"x"))&&this._fire("scaling",target,e)}else if(action==="scaleY"){(actionPerformed=this._scaleObject(x,y,"y"))&&this._fire("scaling",target,e)}else if(action==="skewX"){(actionPerformed=this._skewObject(x,y,"x"))&&this._fire("skewing",target,e)}else if(action==="skewY"){(actionPerformed=this._skewObject(x,y,"y"))&&this._fire("skewing",target,e)}else{(actionPerformed=this._translateObject(x,y))&&this._fire("moving",target,e);this.setCursor(this.moveCursor)}transform.actionPerformed=actionPerformed},_fire:function(eventName,target,e){this.fire("object:"+eventName,{target:target,e:e});target.fire(eventName,{e:e})},_beforeScaleTransform:function(e,transform){if(transform.action==="scale"||transform.action==="scaleX"||transform.action==="scaleY"){var centerTransform=this._shouldCenterTransform(transform.target);if(centerTransform&&(transform.originX!=="center"||transform.originY!=="center")||!centerTransform&&transform.originX==="center"&&transform.originY==="center"){this._resetCurrentTransform();transform.reset=true}}},_onScale:function(e,transform,x,y){if((e.shiftKey||this.uniScaleTransform)&&!transform.target.get("lockUniScaling")){transform.currentAction="scale";return this._scaleObject(x,y)}else{if(!transform.reset&&transform.currentAction==="scale"){this._resetCurrentTransform()}transform.currentAction="scaleEqually";return this._scaleObject(x,y,"equally")}},_setCursorFromEvent:function(e,target){if(!target||!target.selectable){this.setCursor(this.defaultCursor);return false}else{var activeGroup=this.getActiveGroup(),corner=target._findTargetCorner&&(!activeGroup||!activeGroup.contains(target))&&target._findTargetCorner(this.getPointer(e,true));if(!corner){this.setCursor(target.hoverCursor||this.hoverCursor)}else{this._setCornerCursor(corner,target,e)}}return true},_setCornerCursor:function(corner,target,e){if(corner in cursorOffset){this.setCursor(this._getRotatedCornerCursor(corner,target,e))}else if(corner==="mtr"&&target.hasRotatingPoint){this.setCursor(this.rotationCursor)}else{this.setCursor(this.defaultCursor);return false}},_getRotatedCornerCursor:function(corner,target,e){var n=Math.round(target.getAngle()%360/45);if(n<0){n+=8}n+=cursorOffset[corner];if(e.shiftKey&&cursorOffset[corner]%2===0){n+=2}n%=8;return this.cursorMap[n]}})})();(function(){var min=Math.min,max=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(e,target){var activeObject=this.getActiveObject();return e.shiftKey&&target&&target.selectable&&(this.getActiveGroup()||activeObject&&activeObject!==target)&&this.selection},_handleGrouping:function(e,target){if(target===this.getActiveGroup()){target=this.findTarget(e,true);if(!target||target.isType("group")){return}}if(this.getActiveGroup()){this._updateActiveGroup(target,e)}else{this._createActiveGroup(target,e)}if(this._activeGroup){this._activeGroup.saveCoords()}},_updateActiveGroup:function(target,e){var activeGroup=this.getActiveGroup();if(activeGroup.contains(target)){activeGroup.removeWithUpdate(target);target.set("active",false);if(activeGroup.size()===1){this.discardActiveGroup(e);this.setActiveObject(activeGroup.item(0));return}}else{activeGroup.addWithUpdate(target)}this.fire("selection:created",{target:activeGroup,e:e});activeGroup.set("active",true)},_createActiveGroup:function(target,e){if(this._activeObject&&target!==this._activeObject){var group=this._createGroup(target);group.addWithUpdate();this.setActiveGroup(group);this._activeObject=null;this.fire("selection:created",{target:group,e:e})}target.set("active",true)},_createGroup:function(target){var objects=this.getObjects(),isActiveLower=objects.indexOf(this._activeObject)1){group=new fabric.Group(group.reverse(),{canvas:this});group.addWithUpdate();this.setActiveGroup(group,e);group.saveCoords();this.fire("selection:created",{target:group});this.renderAll()}},_collectObjects:function(){var group=[],currentObject,x1=this._groupSelector.ex,y1=this._groupSelector.ey,x2=x1+this._groupSelector.left,y2=y1+this._groupSelector.top,selectionX1Y1=new fabric.Point(min(x1,x2),min(y1,y2)),selectionX2Y2=new fabric.Point(max(x1,x2),max(y1,y2)),isClick=x1===x2&&y1===y2;for(var i=this._objects.length;i--;){currentObject=this._objects[i];if(!currentObject||!currentObject.selectable||!currentObject.visible){continue}if(currentObject.intersectsWithRect(selectionX1Y1,selectionX2Y2)||currentObject.isContainedWithinRect(selectionX1Y1,selectionX2Y2)||currentObject.containsPoint(selectionX1Y1)||currentObject.containsPoint(selectionX2Y2)){currentObject.set("active",true);group.push(currentObject);if(isClick){break}}}return group},_maybeGroupObjects:function(e){if(this.selection&&this._groupSelector){this._groupSelectedObjects(e)}var activeGroup=this.getActiveGroup();if(activeGroup){activeGroup.setObjectsCoords().setCoords();activeGroup.isMoving=false;this.setCursor(this.defaultCursor)}this._groupSelector=null;this._currentTransform=null}})})();fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(options){options||(options={});var format=options.format||"png",quality=options.quality||1,multiplier=options.multiplier||1,cropping={left:options.left,top:options.top,width:options.width,height:options.height};if(this._isRetinaScaling()){multiplier*=fabric.devicePixelRatio}if(multiplier!==1){return this.__toDataURLWithMultiplier(format,quality,cropping,multiplier)}else{return this.__toDataURL(format,quality,cropping)}},__toDataURL:function(format,quality,cropping){this.renderAll();var canvasEl=this.contextContainer.canvas,croppedCanvasEl=this.__getCroppedCanvas(canvasEl,cropping);if(format==="jpg"){format="jpeg"}var data=fabric.StaticCanvas.supports("toDataURLWithQuality")?(croppedCanvasEl||canvasEl).toDataURL("image/"+format,quality):(croppedCanvasEl||canvasEl).toDataURL("image/"+format);if(croppedCanvasEl){croppedCanvasEl=null}return data},__getCroppedCanvas:function(canvasEl,cropping){var croppedCanvasEl,croppedCtx,shouldCrop="left"in cropping||"top"in cropping||"width"in cropping||"height"in cropping;if(shouldCrop){croppedCanvasEl=fabric.util.createCanvasElement();croppedCtx=croppedCanvasEl.getContext("2d");croppedCanvasEl.width=cropping.width||this.width;croppedCanvasEl.height=cropping.height||this.height;croppedCtx.drawImage(canvasEl,-cropping.left||0,-cropping.top||0)}return croppedCanvasEl},__toDataURLWithMultiplier:function(format,quality,cropping,multiplier){var origWidth=this.getWidth(),origHeight=this.getHeight(),scaledWidth=origWidth*multiplier,scaledHeight=origHeight*multiplier,activeObject=this.getActiveObject(),activeGroup=this.getActiveGroup(),ctx=this.contextContainer;if(multiplier>1){this.setDimensions({width:scaledWidth,height:scaledHeight})}ctx.save();ctx.scale(multiplier/fabric.devicePixelRatio,multiplier/fabric.devicePixelRatio);if(cropping.left){cropping.left*=multiplier}if(cropping.top){cropping.top*=multiplier}if(cropping.width){cropping.width*=multiplier}else if(multiplier<1){cropping.width=scaledWidth}if(cropping.height){cropping.height*=multiplier}else if(multiplier<1){cropping.height=scaledHeight}if(activeGroup){this._tempRemoveBordersControlsFromGroup(activeGroup)}else if(activeObject&&this.deactivateAll){this.deactivateAll()}var data=this.__toDataURL(format,quality,cropping);this.width=origWidth;this.height=origHeight;this.setDimensions({width:origWidth,height:origHeight});if(activeGroup){this._restoreBordersControlsOnGroup(activeGroup)}else if(activeObject&&this.setActiveObject){this.setActiveObject(activeObject)}this.contextTop&&this.clearContext(this.contextTop);this.renderAll();return data},toDataURLWithMultiplier:function(format,multiplier,quality){return this.toDataURL({format:format,multiplier:multiplier,quality:quality})},_tempRemoveBordersControlsFromGroup:function(group){group.origHasControls=group.hasControls;group.origBorderColor=group.borderColor;group.hasControls=true;group.borderColor="rgba(0,0,0,0)";group.forEachObject(function(o){o.origBorderColor=o.borderColor;o.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(group){group.hideControls=group.origHideControls;group.borderColor=group.origBorderColor;group.forEachObject(function(o){o.borderColor=o.origBorderColor;delete o.origBorderColor})}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(json,callback,reviver){return this.loadFromJSON(json,callback,reviver)},loadFromJSON:function(json,callback,reviver){if(!json){return}var serialized=typeof json==="string"?JSON.parse(json):json;this.clear();var _this=this;this._enlivenObjects(serialized.objects,function(){_this._setBgOverlay(serialized,callback)},reviver);return this},_setBgOverlay:function(serialized,callback){var _this=this,loaded={backgroundColor:false,overlayColor:false,backgroundImage:false,overlayImage:false};if(!serialized.backgroundImage&&!serialized.overlayImage&&!serialized.background&&!serialized.overlay){callback&&callback();return}var cbIfLoaded=function(){if(loaded.backgroundImage&&loaded.overlayImage&&loaded.backgroundColor&&loaded.overlayColor){_this.renderAll();callback&&callback()}};this.__setBgOverlay("backgroundImage",serialized.backgroundImage,loaded,cbIfLoaded);this.__setBgOverlay("overlayImage",serialized.overlayImage,loaded,cbIfLoaded);this.__setBgOverlay("backgroundColor",serialized.background,loaded,cbIfLoaded);this.__setBgOverlay("overlayColor",serialized.overlay,loaded,cbIfLoaded);cbIfLoaded()},__setBgOverlay:function(property,value,loaded,callback){var _this=this;if(!value){loaded[property]=true;return}if(property==="backgroundImage"||property==="overlayImage"){fabric.Image.fromObject(value,function(img){_this[property]=img;loaded[property]=true;callback&&callback()})}else{this["set"+fabric.util.string.capitalize(property,true)](value,function(){loaded[property]=true;callback&&callback()})}},_enlivenObjects:function(objects,callback,reviver){var _this=this;if(!objects||objects.length===0){callback&&callback();return}var renderOnAddRemove=this.renderOnAddRemove;this.renderOnAddRemove=false;fabric.util.enlivenObjects(objects,function(enlivenedObjects){enlivenedObjects.forEach(function(obj,index){_this.insertAt(obj,index,true)});_this.renderOnAddRemove=renderOnAddRemove;callback&&callback()},null,reviver)},_toDataURL:function(format,callback){this.clone(function(clone){callback(clone.toDataURL(format))})},_toDataURLWithMultiplier:function(format,multiplier,callback){this.clone(function(clone){callback(clone.toDataURLWithMultiplier(format,multiplier))})},clone:function(callback,properties){var data=JSON.stringify(this.toJSON(properties));this.cloneWithoutData(function(clone){clone.loadFromJSON(data,function(){callback&&callback(clone)})})},cloneWithoutData:function(callback){var el=fabric.document.createElement("canvas");el.width=this.getWidth();el.height=this.getHeight();var clone=new fabric.Canvas(el);clone.clipTo=this.clipTo;if(this.backgroundImage){clone.setBackgroundImage(this.backgroundImage.src,function(){clone.renderAll();callback&&callback(clone)});clone.backgroundImageOpacity=this.backgroundImageOpacity;clone.backgroundImageStretch=this.backgroundImageStretch}else{callback&&callback(clone)}}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,toFixed=fabric.util.toFixed,capitalize=fabric.util.string.capitalize,degreesToRadians=fabric.util.degreesToRadians,supportsLineDash=fabric.StaticCanvas.supports("setLineDash");if(fabric.Object){return}fabric.Object=fabric.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:false,flipY:false,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:12,transparentCorners:true,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:false,centeredRotation:true,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:true,evented:true,visible:true,hasControls:true,hasBorders:true,hasRotatingPoint:true,rotatingPointOffset:40,perPixelTargetFind:false,includeDefaultValues:true,clipTo:null,lockMovementX:false,lockMovementY:false,lockRotation:false,lockScalingX:false,lockScalingY:false,lockUniScaling:false,lockSkewingX:false,lockSkewingY:false,lockScalingFlip:false,stateProperties:("top left width height scaleX scaleY flipX flipY originX originY transformMatrix "+"stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit "+"angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor "+"alignX alignY meetOrSlice skewX skewY").split(" "),initialize:function(options){if(options){this.setOptions(options)}},_initGradient:function(options){if(options.fill&&options.fill.colorStops&&!(options.fill instanceof fabric.Gradient)){this.set("fill",new fabric.Gradient(options.fill))}if(options.stroke&&options.stroke.colorStops&&!(options.stroke instanceof fabric.Gradient)){this.set("stroke",new fabric.Gradient(options.stroke))}},_initPattern:function(options){if(options.fill&&options.fill.source&&!(options.fill instanceof fabric.Pattern)){this.set("fill",new fabric.Pattern(options.fill))}if(options.stroke&&options.stroke.source&&!(options.stroke instanceof fabric.Pattern)){this.set("stroke",new fabric.Pattern(options.stroke))}},_initClipping:function(options){if(!options.clipTo||typeof options.clipTo!=="string"){return}var functionBody=fabric.util.getFunctionBody(options.clipTo);if(typeof functionBody!=="undefined"){this.clipTo=new Function("ctx",functionBody)}},setOptions:function(options){for(var prop in options){this.set(prop,options[prop])}this._initGradient(options);this._initPattern(options);this._initClipping(options)},transform:function(ctx,fromLeft){if(this.group&&this.canvas.preserveObjectStacking&&this.group===this.canvas._activeGroup){this.group.transform(ctx)}var center=fromLeft?this._getLeftTopCoords():this.getCenterPoint();ctx.translate(center.x,center.y);ctx.rotate(degreesToRadians(this.angle));ctx.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1));ctx.transform(1,0,Math.tan(degreesToRadians(this.skewX)),1,0,0);ctx.transform(1,Math.tan(degreesToRadians(this.skewY)),0,1,0,0)},toObject:function(propertiesToInclude){var NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,object={type:this.type,originX:this.originX,originY:this.originY,left:toFixed(this.left,NUM_FRACTION_DIGITS),top:toFixed(this.top,NUM_FRACTION_DIGITS),width:toFixed(this.width,NUM_FRACTION_DIGITS),height:toFixed(this.height,NUM_FRACTION_DIGITS),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:toFixed(this.strokeWidth,NUM_FRACTION_DIGITS),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:toFixed(this.strokeMiterLimit,NUM_FRACTION_DIGITS),scaleX:toFixed(this.scaleX,NUM_FRACTION_DIGITS),scaleY:toFixed(this.scaleY,NUM_FRACTION_DIGITS),angle:toFixed(this.getAngle(),NUM_FRACTION_DIGITS),flipX:this.flipX,flipY:this.flipY,opacity:toFixed(this.opacity,NUM_FRACTION_DIGITS),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():this.transformMatrix,skewX:toFixed(this.skewX,NUM_FRACTION_DIGITS),skewY:toFixed(this.skewY,NUM_FRACTION_DIGITS)};if(!this.includeDefaultValues){object=this._removeDefaultValues(object)}fabric.util.populateWithProperties(this,object,propertiesToInclude);return object},toDatalessObject:function(propertiesToInclude){return this.toObject(propertiesToInclude)},_removeDefaultValues:function(object){var prototype=fabric.util.getKlass(object.type).prototype,stateProperties=prototype.stateProperties;stateProperties.forEach(function(prop){if(object[prop]===prototype[prop]){delete object[prop]}var isArray=Object.prototype.toString.call(object[prop])==="[object Array]"&&Object.prototype.toString.call(prototype[prop])==="[object Array]";if(isArray&&object[prop].length===0&&prototype[prop].length===0){delete object[prop]}});return object},toString:function(){return"#"},get:function(property){return this[property]},_setObject:function(obj){for(var prop in obj){this._set(prop,obj[prop])}},set:function(key,value){if(typeof key==="object"){this._setObject(key)}else{if(typeof value==="function"&&key!=="clipTo"){this._set(key,value(this.get(key)))}else{this._set(key,value)}}return this},_set:function(key,value){var shouldConstrainValue=key==="scaleX"||key==="scaleY";if(shouldConstrainValue){value=this._constrainScale(value)}if(key==="scaleX"&&value<0){this.flipX=!this.flipX;value*=-1}else if(key==="scaleY"&&value<0){this.flipY=!this.flipY;value*=-1}else if(key==="width"||key==="height"){this.minScaleLimit=toFixed(Math.min(.1,1/Math.max(this.width,this.height)),2)}else if(key==="shadow"&&value&&!(value instanceof fabric.Shadow)){value=new fabric.Shadow(value)}this[key]=value;return this},setOnGroup:function(){},toggle:function(property){var value=this.get(property);if(typeof value==="boolean"){this.set(property,!value)}return this},setSourcePath:function(value){this.sourcePath=value;return this},getViewportTransform:function(){if(this.canvas&&this.canvas.viewportTransform){return this.canvas.viewportTransform}return[1,0,0,1,0,0]},render:function(ctx,noTransform){if(this.width===0&&this.height===0||!this.visible){return}ctx.save();this._setupCompositeOperation(ctx);if(!noTransform){this.transform(ctx)}this._setStrokeStyles(ctx);this._setFillStyles(ctx);if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}this._setOpacity(ctx);this._setShadow(ctx);this.clipTo&&fabric.util.clipContext(this,ctx);this._render(ctx,noTransform);this.clipTo&&ctx.restore();ctx.restore()},_setOpacity:function(ctx){if(this.group){this.group._setOpacity(ctx)}ctx.globalAlpha*=this.opacity},_setStrokeStyles:function(ctx){if(this.stroke){ctx.lineWidth=this.strokeWidth;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;ctx.miterLimit=this.strokeMiterLimit;ctx.strokeStyle=this.stroke.toLive?this.stroke.toLive(ctx,this):this.stroke}},_setFillStyles:function(ctx){if(this.fill){ctx.fillStyle=this.fill.toLive?this.fill.toLive(ctx,this):this.fill}},_renderControls:function(ctx,noTransform){if(!this.active||noTransform||this.group&&this.group!==this.canvas.getActiveGroup()){return}var vpt=this.getViewportTransform(),matrix=this.calcTransformMatrix(),options;matrix=fabric.util.multiplyTransformMatrices(vpt,matrix);options=fabric.util.qrDecompose(matrix);ctx.save();ctx.translate(options.translateX,options.translateY);if(this.group&&this.group===this.canvas.getActiveGroup()){ctx.rotate(degreesToRadians(options.angle));this.drawBordersInGroup(ctx,options)}else{ctx.rotate(degreesToRadians(this.angle));this.drawBorders(ctx)}this.drawControls(ctx);ctx.restore()},_setShadow:function(ctx){if(!this.shadow){return}var multX=this.canvas&&this.canvas.viewportTransform[0]||1,multY=this.canvas&&this.canvas.viewportTransform[3]||1;if(this.canvas&&this.canvas._isRetinaScaling()){multX*=fabric.devicePixelRatio;multY*=fabric.devicePixelRatio}ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur*(multX+multY)*(this.scaleX+this.scaleY)/4;ctx.shadowOffsetX=this.shadow.offsetX*multX*this.scaleX;ctx.shadowOffsetY=this.shadow.offsetY*multY*this.scaleY},_removeShadow:function(ctx){if(!this.shadow){return}ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0},_renderFill:function(ctx){if(!this.fill){return}ctx.save();if(this.fill.gradientTransform){var g=this.fill.gradientTransform;ctx.transform.apply(ctx,g)}if(this.fill.toLive){ctx.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0)}if(this.fillRule==="evenodd"){ctx.fill("evenodd")}else{ctx.fill()}ctx.restore()},_renderStroke:function(ctx){if(!this.stroke||this.strokeWidth===0){return}if(this.shadow&&!this.shadow.affectStroke){this._removeShadow(ctx)}ctx.save();if(this.strokeDashArray){if(1&this.strokeDashArray.length){this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray)}if(supportsLineDash){ctx.setLineDash(this.strokeDashArray);this._stroke&&this._stroke(ctx)}else{this._renderDashedStroke&&this._renderDashedStroke(ctx)}ctx.stroke()}else{if(this.stroke.gradientTransform){var g=this.stroke.gradientTransform;ctx.transform.apply(ctx,g)}this._stroke?this._stroke(ctx):ctx.stroke()}ctx.restore()},clone:function(callback,propertiesToInclude){if(this.constructor.fromObject){return this.constructor.fromObject(this.toObject(propertiesToInclude),callback)}return new fabric.Object(this.toObject(propertiesToInclude))},cloneAsImage:function(callback){var dataUrl=this.toDataURL();fabric.util.loadImage(dataUrl,function(img){if(callback){callback(new fabric.Image(img)) +}});return this},toDataURL:function(options){options||(options={});var el=fabric.util.createCanvasElement(),boundingRect=this.getBoundingRect();el.width=boundingRect.width;el.height=boundingRect.height;fabric.util.wrapElement(el,"div");var canvas=new fabric.StaticCanvas(el);if(options.format==="jpg"){options.format="jpeg"}if(options.format==="jpeg"){canvas.backgroundColor="#fff"}var origParams={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",false);this.setPositionByOrigin(new fabric.Point(el.width/2,el.height/2),"center","center");var originalCanvas=this.canvas;canvas.add(this);var data=canvas.toDataURL(options);this.set(origParams).setCoords();this.canvas=originalCanvas;canvas.dispose();canvas=null;return data},isType:function(type){return this.type===type},complexity:function(){return 0},toJSON:function(propertiesToInclude){return this.toObject(propertiesToInclude)},setGradient:function(property,options){options||(options={});var gradient={colorStops:[]};gradient.type=options.type||(options.r1||options.r2?"radial":"linear");gradient.coords={x1:options.x1,y1:options.y1,x2:options.x2,y2:options.y2};if(options.r1||options.r2){gradient.coords.r1=options.r1;gradient.coords.r2=options.r2}options.gradientTransform&&(gradient.gradientTransform=options.gradientTransform);for(var position in options.colorStops){var color=new fabric.Color(options.colorStops[position]);gradient.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this.set(property,fabric.Gradient.forObject(this,gradient))},setPatternFill:function(options){return this.set("fill",new fabric.Pattern(options))},setShadow:function(options){return this.set("shadow",options?new fabric.Shadow(options):null)},setColor:function(color){this.set("fill",color);return this},setAngle:function(angle){var shouldCenterOrigin=(this.originX!=="center"||this.originY!=="center")&&this.centeredRotation;if(shouldCenterOrigin){this._setOriginToCenter()}this.set("angle",angle);if(shouldCenterOrigin){this._resetOrigin()}return this},centerH:function(){this.canvas.centerObjectH(this);return this},centerV:function(){this.canvas.centerObjectV(this);return this},center:function(){this.canvas.centerObject(this);return this},remove:function(){this.canvas.remove(this);return this},getLocalPointer:function(e,pointer){pointer=pointer||this.canvas.getPointer(e);var pClicked=new fabric.Point(pointer.x,pointer.y),objectLeftTop=this._getLeftTopCoords();if(this.angle){pClicked=fabric.util.rotatePoint(pClicked,objectLeftTop,fabric.util.degreesToRadians(-this.angle))}return{x:pClicked.x-objectLeftTop.x,y:pClicked.y-objectLeftTop.y}},_setupCompositeOperation:function(ctx){if(this.globalCompositeOperation){ctx.globalCompositeOperation=this.globalCompositeOperation}}});fabric.util.createAccessors(fabric.Object);fabric.Object.prototype.rotate=fabric.Object.prototype.setAngle;extend(fabric.Object.prototype,fabric.Observable);fabric.Object.NUM_FRACTION_DIGITS=2;fabric.Object.__uid=0})(typeof exports!=="undefined"?exports:this);(function(){var degreesToRadians=fabric.util.degreesToRadians,originXOffset={left:-.5,center:0,right:.5},originYOffset={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(point,fromOriginX,fromOriginY,toOriginX,toOriginY){var x=point.x,y=point.y,offsetX=originXOffset[toOriginX]-originXOffset[fromOriginX],offsetY=originYOffset[toOriginY]-originYOffset[fromOriginY],dim;if(offsetX||offsetY){dim=this._getTransformedDimensions();x=point.x+offsetX*dim.x;y=point.y+offsetY*dim.y}return new fabric.Point(x,y)},translateToCenterPoint:function(point,originX,originY){var p=this.translateToGivenOrigin(point,originX,originY,"center","center");if(this.angle){return fabric.util.rotatePoint(p,point,degreesToRadians(this.angle))}return p},translateToOriginPoint:function(center,originX,originY){var p=this.translateToGivenOrigin(center,"center","center",originX,originY);if(this.angle){return fabric.util.rotatePoint(p,center,degreesToRadians(this.angle))}return p},getCenterPoint:function(){var leftTop=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(leftTop,this.originX,this.originY)},getPointByOrigin:function(originX,originY){var center=this.getCenterPoint();return this.translateToOriginPoint(center,originX,originY)},toLocalPoint:function(point,originX,originY){var center=this.getCenterPoint(),p,p2;if(originX&&originY){p=this.translateToGivenOrigin(center,"center","center",originX,originY)}else{p=new fabric.Point(this.left,this.top)}p2=new fabric.Point(point.x,point.y);if(this.angle){p2=fabric.util.rotatePoint(p2,center,-degreesToRadians(this.angle))}return p2.subtractEquals(p)},setPositionByOrigin:function(pos,originX,originY){var center=this.translateToCenterPoint(pos,originX,originY),position=this.translateToOriginPoint(center,this.originX,this.originY);this.set("left",position.x);this.set("top",position.y)},adjustPosition:function(to){var angle=degreesToRadians(this.angle),hypotFull=this.getWidth(),xFull=Math.cos(angle)*hypotFull,yFull=Math.sin(angle)*hypotFull;this.left+=xFull*(originXOffset[to]-originXOffset[this.originX]);this.top+=yFull*(originXOffset[to]-originXOffset[this.originX]);this.setCoords();this.originX=to},_setOriginToCenter:function(){this._originalOriginX=this.originX;this._originalOriginY=this.originY;var center=this.getCenterPoint();this.originX="center";this.originY="center";this.left=center.x;this.top=center.y},_resetOrigin:function(){var originPoint=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX;this.originY=this._originalOriginY;this.left=originPoint.x;this.top=originPoint.y;this._originalOriginX=null;this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")}})})();(function(){function getCoords(oCoords){return[new fabric.Point(oCoords.tl.x,oCoords.tl.y),new fabric.Point(oCoords.tr.x,oCoords.tr.y),new fabric.Point(oCoords.br.x,oCoords.br.y),new fabric.Point(oCoords.bl.x,oCoords.bl.y)]}var degreesToRadians=fabric.util.degreesToRadians,multiplyMatrices=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(pointTL,pointBR){var oCoords=getCoords(this.oCoords),intersection=fabric.Intersection.intersectPolygonRectangle(oCoords,pointTL,pointBR);return intersection.status==="Intersection"},intersectsWithObject:function(other){var intersection=fabric.Intersection.intersectPolygonPolygon(getCoords(this.oCoords),getCoords(other.oCoords));return intersection.status==="Intersection"},isContainedWithinObject:function(other){var boundingRect=other.getBoundingRect(),point1=new fabric.Point(boundingRect.left,boundingRect.top),point2=new fabric.Point(boundingRect.left+boundingRect.width,boundingRect.top+boundingRect.height);return this.isContainedWithinRect(point1,point2)},isContainedWithinRect:function(pointTL,pointBR){var boundingRect=this.getBoundingRect();return boundingRect.left>=pointTL.x&&boundingRect.left+boundingRect.width<=pointBR.x&&boundingRect.top>=pointTL.y&&boundingRect.top+boundingRect.height<=pointBR.y},containsPoint:function(point){var lines=this._getImageLines(this.oCoords),xPoints=this._findCrossPoints(point,lines);return xPoints!==0&&xPoints%2===1},_getImageLines:function(oCoords){return{topline:{o:oCoords.tl,d:oCoords.tr},rightline:{o:oCoords.tr,d:oCoords.br},bottomline:{o:oCoords.br,d:oCoords.bl},leftline:{o:oCoords.bl,d:oCoords.tl}}},_findCrossPoints:function(point,oCoords){var b1,b2,a1,a2,xi,yi,xcount=0,iLine;for(var lineKey in oCoords){iLine=oCoords[lineKey];if(iLine.o.y=point.y&&iLine.d.y>=point.y){continue}if(iLine.o.x===iLine.d.x&&iLine.o.x>=point.x){xi=iLine.o.x;yi=point.y}else{b1=0;b2=(iLine.d.y-iLine.o.y)/(iLine.d.x-iLine.o.x);a1=point.y-b1*point.x;a2=iLine.o.y-b2*iLine.o.x;xi=-(a1-a2)/(b1-b2);yi=a1+b1*xi}if(xi>=point.x){xcount+=1}if(xcount===2){break}}return xcount},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();return fabric.util.makeBoundingBoxFromPoints([this.oCoords.tl,this.oCoords.tr,this.oCoords.br,this.oCoords.bl])},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(value){if(Math.abs(value)0?Math.atan(currentHeight/currentWidth):0,_hypotenuse=currentWidth/Math.cos(_angle)/2,offsetX=Math.cos(_angle+theta)*_hypotenuse,offsetY=Math.sin(_angle+theta)*_hypotenuse,coords=fabric.util.transformPoint(this.getCenterPoint(),vpt),tl=new fabric.Point(coords.x-offsetX,coords.y-offsetY),tr=new fabric.Point(tl.x+currentWidth*cosTh,tl.y+currentWidth*sinTh),bl=new fabric.Point(tl.x-currentHeight*sinTh,tl.y+currentHeight*cosTh),br=new fabric.Point(coords.x+offsetX,coords.y+offsetY),ml=new fabric.Point((tl.x+bl.x)/2,(tl.y+bl.y)/2),mt=new fabric.Point((tr.x+tl.x)/2,(tr.y+tl.y)/2),mr=new fabric.Point((br.x+tr.x)/2,(br.y+tr.y)/2),mb=new fabric.Point((br.x+bl.x)/2,(br.y+bl.y)/2),mtr=new fabric.Point(mt.x+sinTh*this.rotatingPointOffset,mt.y-cosTh*this.rotatingPointOffset);this.oCoords={tl:tl,tr:tr,br:br,bl:bl,ml:ml,mt:mt,mr:mr,mb:mb,mtr:mtr};this._setCornerCoords&&this._setCornerCoords();return this},_calcRotateMatrix:function(){if(this.angle){var theta=degreesToRadians(this.angle),cos=Math.cos(theta),sin=Math.sin(theta);return[cos,sin,-sin,cos,0,0]}return[1,0,0,1,0,0]},calcTransformMatrix:function(){var center=this.getCenterPoint(),translateMatrix=[1,0,0,1,center.x,center.y],rotateMatrix=this._calcRotateMatrix(),dimensionMatrix=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,true),matrix=this.group?this.group.calcTransformMatrix():[1,0,0,1,0,0];matrix=multiplyMatrices(matrix,translateMatrix);matrix=multiplyMatrices(matrix,rotateMatrix);matrix=multiplyMatrices(matrix,dimensionMatrix);return matrix},_calcDimensionsTransformMatrix:function(skewX,skewY,flipping){var skewMatrixX=[1,0,Math.tan(degreesToRadians(skewX)),1],skewMatrixY=[1,Math.tan(degreesToRadians(skewY)),0,1],scaleX=this.scaleX*(flipping&&this.flipX?-1:1),scaleY=this.scaleY*(flipping&&this.flipY?-1:1),scaleMatrix=[scaleX,0,0,scaleY],m=multiplyMatrices(scaleMatrix,skewMatrixX,true);return multiplyMatrices(m,skewMatrixY,true)}})})();fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){if(this.group){fabric.StaticCanvas.prototype.sendToBack.call(this.group,this)}else{this.canvas.sendToBack(this)}return this},bringToFront:function(){if(this.group){fabric.StaticCanvas.prototype.bringToFront.call(this.group,this)}else{this.canvas.bringToFront(this)}return this},sendBackwards:function(intersecting){if(this.group){fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,intersecting)}else{this.canvas.sendBackwards(this,intersecting)}return this},bringForward:function(intersecting){if(this.group){fabric.StaticCanvas.prototype.bringForward.call(this.group,this,intersecting)}else{this.canvas.bringForward(this,intersecting)}return this},moveTo:function(index){if(this.group){fabric.StaticCanvas.prototype.moveTo.call(this.group,this,index)}else{this.canvas.moveTo(this,index)}return this}});fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(skipShadow){var fill=this.fill?this.fill.toLive?"url(#SVGID_"+this.fill.id+")":this.fill:"none",fillRule=this.fillRule,stroke=this.stroke?this.stroke.toLive?"url(#SVGID_"+this.stroke.id+")":this.stroke:"none",strokeWidth=this.strokeWidth?this.strokeWidth:"0",strokeDashArray=this.strokeDashArray?this.strokeDashArray.join(" "):"none",strokeLineCap=this.strokeLineCap?this.strokeLineCap:"butt",strokeLineJoin=this.strokeLineJoin?this.strokeLineJoin:"miter",strokeMiterLimit=this.strokeMiterLimit?this.strokeMiterLimit:"4",opacity=typeof this.opacity!=="undefined"?this.opacity:"1",visibility=this.visible?"":" visibility: hidden;",filter=skipShadow?"":this.getSvgFilter();return["stroke: ",stroke,"; ","stroke-width: ",strokeWidth,"; ","stroke-dasharray: ",strokeDashArray,"; ","stroke-linecap: ",strokeLineCap,"; ","stroke-linejoin: ",strokeLineJoin,"; ","stroke-miterlimit: ",strokeMiterLimit,"; ","fill: ",fill,"; ","fill-rule: ",fillRule,"; ","opacity: ",opacity,";",filter,visibility].join("")},getSvgFilter:function(){return this.shadow?"filter: url(#SVGID_"+this.shadow.id+");":""},getSvgTransform:function(){if(this.group&&this.group.type==="path-group"){return""}var toFixed=fabric.util.toFixed,angle=this.getAngle(),skewX=this.getSkewX()%360,skewY=this.getSkewY()%360,center=this.getCenterPoint(),NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,translatePart=this.type==="path-group"?"":"translate("+toFixed(center.x,NUM_FRACTION_DIGITS)+" "+toFixed(center.y,NUM_FRACTION_DIGITS)+")",anglePart=angle!==0?" rotate("+toFixed(angle,NUM_FRACTION_DIGITS)+")":"",scalePart=this.scaleX===1&&this.scaleY===1?"":" scale("+toFixed(this.scaleX,NUM_FRACTION_DIGITS)+" "+toFixed(this.scaleY,NUM_FRACTION_DIGITS)+")",skewXPart=skewX!==0?" skewX("+toFixed(skewX,NUM_FRACTION_DIGITS)+")":"",skewYPart=skewY!==0?" skewY("+toFixed(skewY,NUM_FRACTION_DIGITS)+")":"",addTranslateX=this.type==="path-group"?this.width:0,flipXPart=this.flipX?" matrix(-1 0 0 1 "+addTranslateX+" 0) ":"",addTranslateY=this.type==="path-group"?this.height:0,flipYPart=this.flipY?" matrix(1 0 0 -1 0 "+addTranslateY+")":"";return[translatePart,anglePart,scalePart,flipXPart,flipYPart,skewXPart,skewYPart].join("")},getSvgTransformMatrix:function(){return this.transformMatrix?" matrix("+this.transformMatrix.join(" ")+") ":""},_createBaseSVGMarkup:function(){var markup=[];if(this.fill&&this.fill.toLive){markup.push(this.fill.toSVG(this,false))}if(this.stroke&&this.stroke.toLive){markup.push(this.stroke.toSVG(this,false))}if(this.shadow){markup.push(this.shadow.toSVG(this))}return markup}});fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(prop){return this.get(prop)!==this.originalState[prop]},this)},saveState:function(options){this.stateProperties.forEach(function(prop){this.originalState[prop]=this.get(prop)},this);if(options&&options.stateProperties){options.stateProperties.forEach(function(prop){this.originalState[prop]=this.get(prop)},this)}return this},setupState:function(){this.originalState={};this.saveState();return this}});(function(){var degreesToRadians=fabric.util.degreesToRadians,isVML=function(){return typeof G_vmlCanvasManager!=="undefined"};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(pointer){if(!this.hasControls||!this.active){return false}var ex=pointer.x,ey=pointer.y,xPoints,lines;this.__corner=0;for(var i in this.oCoords){if(!this.isControlVisible(i)){continue}if(i==="mtr"&&!this.hasRotatingPoint){continue}if(this.get("lockUniScaling")&&(i==="mt"||i==="mr"||i==="mb"||i==="ml")){continue}lines=this._getImageLines(this.oCoords[i].corner);xPoints=this._findCrossPoints({x:ex,y:ey},lines);if(xPoints!==0&&xPoints%2===1){this.__corner=i;return i}}return false},_setCornerCoords:function(){var coords=this.oCoords,newTheta=degreesToRadians(45-this.angle),cornerHypotenuse=this.cornerSize*.707106,cosHalfOffset=cornerHypotenuse*Math.cos(newTheta),sinHalfOffset=cornerHypotenuse*Math.sin(newTheta),x,y;for(var point in coords){x=coords[point].x;y=coords[point].y;coords[point].corner={tl:{x:x-sinHalfOffset,y:y-cosHalfOffset},tr:{x:x+cosHalfOffset,y:y-sinHalfOffset},bl:{x:x-cosHalfOffset,y:y+sinHalfOffset},br:{x:x+sinHalfOffset,y:y+cosHalfOffset}}}},_getNonTransformedDimensions:function(){var strokeWidth=this.strokeWidth,w=this.width,h=this.height,addStrokeToW=true,addStrokeToH=true;if(this.type==="line"&&this.strokeLineCap==="butt"){addStrokeToH=w;addStrokeToW=h}if(addStrokeToH){h+=h<0?-strokeWidth:strokeWidth}if(addStrokeToW){w+=w<0?-strokeWidth:strokeWidth}return{x:w,y:h}},_getTransformedDimensions:function(skewX,skewY){if(typeof skewX==="undefined"){skewX=this.skewX}if(typeof skewY==="undefined"){skewY=this.skewY}var dimensions=this._getNonTransformedDimensions(),dimX=dimensions.x/2,dimY=dimensions.y/2,points=[{x:-dimX,y:-dimY},{x:dimX,y:-dimY},{x:-dimX,y:dimY},{x:dimX,y:dimY}],i,transformMatrix=this._calcDimensionsTransformMatrix(skewX,skewY,false),bbox;for(i=0;i\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Line.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" "));fabric.Line.fromElement=function(element,options){var parsedAttributes=fabric.parseAttributes(element,fabric.Line.ATTRIBUTE_NAMES),points=[parsedAttributes.x1||0,parsedAttributes.y1||0,parsedAttributes.x2||0,parsedAttributes.y2||0];return new fabric.Line(points,extend(parsedAttributes,options))};fabric.Line.fromObject=function(object){var points=[object.x1,object.y1,object.x2,object.y2];return new fabric.Line(points,object)};function makeEdgeToOriginGetter(propertyNames,originValues){var origin=propertyNames.origin,axis1=propertyNames.axis1,axis2=propertyNames.axis2,dimension=propertyNames.dimension,nearest=originValues.nearest,center=originValues.center,farthest=originValues.farthest;return function(){switch(this.get(origin)){case nearest:return Math.min(this.get(axis1),this.get(axis2));case center:return Math.min(this.get(axis1),this.get(axis2))+.5*this.get(dimension);case farthest:return Math.max(this.get(axis1),this.get(axis2))}}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),pi=Math.PI,extend=fabric.util.object.extend;if(fabric.Circle){fabric.warn("fabric.Circle is already defined.");return}fabric.Circle=fabric.util.createClass(fabric.Object,{type:"circle",radius:0,startAngle:0,endAngle:pi*2,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("radius",options.radius||0);this.startAngle=options.startAngle||this.startAngle;this.endAngle=options.endAngle||this.endAngle},_set:function(key,value){this.callSuper("_set",key,value);if(key==="radius"){this.setRadius(value)}return this},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0,angle=(this.endAngle-this.startAngle)%(2*pi);if(angle===0){if(this.group&&this.group.type==="path-group"){x=this.left+this.radius;y=this.top+this.radius}markup.push("\n')}else{var startX=Math.cos(this.startAngle)*this.radius,startY=Math.sin(this.startAngle)*this.radius,endX=Math.cos(this.endAngle)*this.radius,endY=Math.sin(this.endAngle)*this.radius,largeFlag=angle>pi?"1":"0";markup.push('\n')}return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.arc(noTransform?this.left+this.radius:0,noTransform?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,false);this._renderFill(ctx);this._renderStroke(ctx)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(value){this.radius=value;return this.set("width",value*2).set("height",value*2)},complexity:function(){return 1}});fabric.Circle.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy r".split(" "));fabric.Circle.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Circle.ATTRIBUTE_NAMES);if(!isValidRadius(parsedAttributes)){throw new Error("value of `r` attribute is required and can not be negative")}parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var obj=new fabric.Circle(extend(parsedAttributes,options));obj.left-=obj.radius;obj.top-=obj.radius;return obj};function isValidRadius(attributes){return"radius"in attributes&&attributes.radius>=0}fabric.Circle.fromObject=function(object){return new fabric.Circle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Triangle){fabric.warn("fabric.Triangle is already defined");return}fabric.Triangle=fabric.util.createClass(fabric.Object,{type:"triangle",initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("width",options.width||100).set("height",options.height||100)},_render:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();ctx.moveTo(-widthBy2,heightBy2);ctx.lineTo(0,-heightBy2);ctx.lineTo(widthBy2,heightBy2);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();fabric.util.drawDashedLine(ctx,-widthBy2,heightBy2,0,-heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,0,-heightBy2,widthBy2,heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,widthBy2,heightBy2,-widthBy2,heightBy2,this.strokeDashArray);ctx.closePath()},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),widthBy2=this.width/2,heightBy2=this.height/2,points=[-widthBy2+" "+heightBy2,"0 "+-heightBy2,widthBy2+" "+heightBy2].join(",");markup.push("');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Triangle.fromObject=function(object){return new fabric.Triangle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),piBy2=Math.PI*2,extend=fabric.util.object.extend;if(fabric.Ellipse){fabric.warn("fabric.Ellipse is already defined."); +return}fabric.Ellipse=fabric.util.createClass(fabric.Object,{type:"ellipse",rx:0,ry:0,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("rx",options.rx||0);this.set("ry",options.ry||0)},_set:function(key,value){this.callSuper("_set",key,value);switch(key){case"rx":this.rx=value;this.set("width",value*2);break;case"ry":this.ry=value;this.set("height",value*2);break}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0;if(this.group&&this.group.type==="path-group"){x=this.left+this.rx;y=this.top+this.ry}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.save();ctx.transform(1,0,0,this.ry/this.rx,0,0);ctx.arc(noTransform?this.left+this.rx:0,noTransform?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,piBy2,false);ctx.restore();this._renderFill(ctx);this._renderStroke(ctx)},complexity:function(){return 1}});fabric.Ellipse.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" "));fabric.Ellipse.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Ellipse.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var ellipse=new fabric.Ellipse(extend(parsedAttributes,options));ellipse.top-=ellipse.ry;ellipse.left-=ellipse.rx;return ellipse};fabric.Ellipse.fromObject=function(object){return new fabric.Ellipse(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;if(fabric.Rect){fabric.warn("fabric.Rect is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("rx","ry","x","y");fabric.Rect=fabric.util.createClass(fabric.Object,{stateProperties:stateProperties,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(options){options=options||{};this.callSuper("initialize",options);this._initRxRy()},_initRxRy:function(){if(this.rx&&!this.ry){this.ry=this.rx}else if(this.ry&&!this.rx){this.rx=this.ry}},_render:function(ctx,noTransform){if(this.width===1&&this.height===1){ctx.fillRect(-.5,-.5,1,1);return}var rx=this.rx?Math.min(this.rx,this.width/2):0,ry=this.ry?Math.min(this.ry,this.height/2):0,w=this.width,h=this.height,x=noTransform?this.left:-this.width/2,y=noTransform?this.top:-this.height/2,isRounded=rx!==0||ry!==0,k=1-.5522847498;ctx.beginPath();ctx.moveTo(x+rx,y);ctx.lineTo(x+w-rx,y);isRounded&&ctx.bezierCurveTo(x+w-k*rx,y,x+w,y+k*ry,x+w,y+ry);ctx.lineTo(x+w,y+h-ry);isRounded&&ctx.bezierCurveTo(x+w,y+h-k*ry,x+w-k*rx,y+h,x+w-rx,y+h);ctx.lineTo(x+rx,y+h);isRounded&&ctx.bezierCurveTo(x+k*rx,y+h,x,y+h-k*ry,x,y+h-ry);ctx.lineTo(x,y+ry);isRounded&&ctx.bezierCurveTo(x,y+k*ry,x+k*rx,y,x+rx,y);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var x=-this.width/2,y=-this.height/2,w=this.width,h=this.height;ctx.beginPath();fabric.util.drawDashedLine(ctx,x,y,x+w,y,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y,x+w,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y+h,x,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x,y+h,x,y,this.strokeDashArray);ctx.closePath()},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx")||0,ry:this.get("ry")||0});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=this.left,y=this.top;if(!(this.group&&this.group.type==="path-group")){x=-this.width/2;y=-this.height/2}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Rect.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" "));fabric.Rect.fromElement=function(element,options){if(!element){return null}options=options||{};var parsedAttributes=fabric.parseAttributes(element,fabric.Rect.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var rect=new fabric.Rect(extend(options?fabric.util.object.clone(options):{},parsedAttributes));rect.visible=rect.width>0&&rect.height>0;return rect};fabric.Rect.fromObject=function(object){return new fabric.Rect(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Polyline){fabric.warn("fabric.Polyline is already defined");return}fabric.Polyline=fabric.util.createClass(fabric.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(points,options){return fabric.Polygon.prototype.initialize.call(this,points,options)},_calcDimensions:function(){return fabric.Polygon.prototype._calcDimensions.call(this)},_applyPointOffset:function(){return fabric.Polygon.prototype._applyPointOffset.call(this)},toObject:function(propertiesToInclude){return fabric.Polygon.prototype.toObject.call(this,propertiesToInclude)},toSVG:function(reviver){return fabric.Polygon.prototype.toSVG.call(this,reviver)},_render:function(ctx,noTransform){if(!fabric.Polygon.prototype.commonRender.call(this,ctx,noTransform)){return}this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var p1,p2;ctx.beginPath();for(var i=0,len=this.points.length;i\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){if(!this.commonRender(ctx,noTransform)){return}this._renderFill(ctx);if(this.stroke||this.strokeDashArray){ctx.closePath();this._renderStroke(ctx)}},commonRender:function(ctx,noTransform){var point,len=this.points.length;if(!len||isNaN(this.points[len-1].y)){return false}noTransform||ctx.translate(-this.pathOffset.x,-this.pathOffset.y);ctx.beginPath();ctx.moveTo(this.points[0].x,this.points[0].y);for(var i=0;i"},toObject:function(propertiesToInclude){var o=extend(this.callSuper("toObject",propertiesToInclude),{path:this.path.map(function(item){return item.slice()}),pathOffset:this.pathOffset});if(this.sourcePath){o.sourcePath=this.sourcePath}if(this.transformMatrix){o.transformMatrix=this.transformMatrix}return o},toDatalessObject:function(propertiesToInclude){var o=this.toObject(propertiesToInclude);if(this.sourcePath){o.path=this.sourcePath}delete o.sourcePath;return o},toSVG:function(reviver){var chunks=[],markup=this._createBaseSVGMarkup(),addTransform="";for(var i=0,len=this.path.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return this.path.length},_parsePath:function(){var result=[],coords=[],currentPath,parsed,re=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,match,coordsStr;for(var i=0,coordsParsed,len=this.path.length;icommandLength){for(var k=1,klen=coordsParsed.length;k\n");for(var i=0,len=objects.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},toString:function(){return"#"},isSameColor:function(){var firstPathFill=this.getObjects()[0].get("fill")||"";if(typeof firstPathFill!=="string"){return false}firstPathFill=firstPathFill.toLowerCase();return this.getObjects().every(function(path){var pathFill=path.get("fill")||"";return typeof pathFill==="string"&&pathFill.toLowerCase()===firstPathFill})},complexity:function(){return this.paths.reduce(function(total,path){return total+(path&&path.complexity?path.complexity():0)},0)},getObjects:function(){return this.paths}});fabric.PathGroup.fromObject=function(object,callback){if(typeof object.paths==="string"){fabric.loadSVGFromURL(object.paths,function(elements){var pathUrl=object.paths;delete object.paths;var pathGroup=fabric.util.groupSVGElements(elements,object,pathUrl);callback(pathGroup)})}else{fabric.util.enlivenObjects(object.paths,function(enlivenedObjects){delete object.paths;callback(new fabric.PathGroup(enlivenedObjects,object))})}};fabric.PathGroup.async=true})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,min=fabric.util.array.min,max=fabric.util.array.max,invoke=fabric.util.array.invoke;if(fabric.Group){return}var _lockProperties={lockMovementX:true,lockMovementY:true,lockRotation:true,lockScalingX:true,lockScalingY:true,lockUniScaling:true};fabric.Group=fabric.util.createClass(fabric.Object,fabric.Collection,{type:"group",strokeWidth:0,initialize:function(objects,options,isAlreadyGrouped){options=options||{};this._objects=[];isAlreadyGrouped&&this.callSuper("initialize",options);this._objects=objects||[];for(var i=this._objects.length;i--;){this._objects[i].group=this}this.originalState={};if(options.originX){this.originX=options.originX}if(options.originY){this.originY=options.originY}if(isAlreadyGrouped){this._updateObjectsCoords(true)}else{this._calcBounds();this._updateObjectsCoords();this.callSuper("initialize",options)}this.setCoords();this.saveCoords()},_updateObjectsCoords:function(skipCoordsChange){for(var i=this._objects.length;i--;){this._updateObjectCoords(this._objects[i],skipCoordsChange)}},_updateObjectCoords:function(object,skipCoordsChange){object.__origHasControls=object.hasControls;object.hasControls=false;if(skipCoordsChange){return}var objectLeft=object.getLeft(),objectTop=object.getTop(),center=this.getCenterPoint();object.set({originalLeft:objectLeft,originalTop:objectTop,left:objectLeft-center.x,top:objectTop-center.y});object.setCoords()},toString:function(){return"#"},addWithUpdate:function(object){this._restoreObjectsState();fabric.util.resetObjectTransform(this);if(object){this._objects.push(object);object.group=this;object._set("canvas",this.canvas)}this.forEachObject(this._setObjectActive,this);this._calcBounds();this._updateObjectsCoords();return this},_setObjectActive:function(object){object.set("active",true);object.group=this},removeWithUpdate:function(object){this._restoreObjectsState();fabric.util.resetObjectTransform(this);this.forEachObject(this._setObjectActive,this);this.remove(object);this._calcBounds();this._updateObjectsCoords();return this},_onObjectAdded:function(object){object.group=this;object._set("canvas",this.canvas)},_onObjectRemoved:function(object){delete object.group;object.set("active",false)},delegatedProperties:{fill:true,stroke:true,strokeWidth:true,fontFamily:true,fontWeight:true,fontSize:true,fontStyle:true,lineHeight:true,textDecoration:true,textAlign:true,backgroundColor:true},_set:function(key,value){var i=this._objects.length;if(this.delegatedProperties[key]||key==="canvas"){while(i--){this._objects[i].set(key,value)}}else{while(i--){this._objects[i].setOnGroup(key,value)}}this.callSuper("_set",key,value)},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{objects:invoke(this._objects,"toObject",propertiesToInclude)})},render:function(ctx){if(!this.visible){return}ctx.save();if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}this.transform(ctx);this._setShadow(ctx);this.clipTo&&fabric.util.clipContext(this,ctx);for(var i=0,len=this._objects.length;i\n');for(var i=0,len=this._objects.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},get:function(prop){if(prop in _lockProperties){if(this[prop]){return this[prop]}else{for(var i=0,len=this._objects.length;i0){object.resizeFilters=this.resizeFilters.map(function(filterObj){return filterObj&&filterObj.toObject()})}if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=-this.width/2,y=-this.height/2,preserveAspectRatio="none";if(this.group&&this.group.type==="path-group"){x=this.left;y=this.top}if(this.alignX!=="none"&&this.alignY!=="none"){preserveAspectRatio="x"+this.alignX+"Y"+this.alignY+" "+this.meetOrSlice}markup.push('\n','\n");if(this.stroke||this.strokeDashArray){var origFill=this.fill;this.fill=null;markup.push("\n');this.fill=origFill}markup.push("\n");return reviver?reviver(markup.join("")):markup.join("")},getSrc:function(){if(this.getElement()){return this.getElement().src||this.getElement()._src}},setSrc:function(src,callback,options){fabric.util.loadImage(src,function(img){return this.setElement(img,callback,options)},this,options&&options.crossOrigin)},toString:function(){return'#'},clone:function(callback,propertiesToInclude){this.constructor.fromObject(this.toObject(propertiesToInclude),callback)},applyFilters:function(callback,filters,imgElement,forResizing){filters=filters||this.filters;imgElement=imgElement||this._originalElement;if(!imgElement){return}var imgEl=imgElement,canvasEl=fabric.util.createCanvasElement(),replacement=fabric.util.createImage(),_this=this;canvasEl.width=imgEl.width;canvasEl.height=imgEl.height;canvasEl.getContext("2d").drawImage(imgEl,0,0,imgEl.width,imgEl.height);if(filters.length===0){this._element=imgElement;callback&&callback();return canvasEl}filters.forEach(function(filter){filter&&filter.applyTo(canvasEl,filter.scaleX||_this.scaleX,filter.scaleY||_this.scaleY);if(!forResizing&&filter&&filter.type==="Resize"){_this.width*=filter.scaleX;_this.height*=filter.scaleY}});replacement.width=canvasEl.width;replacement.height=canvasEl.height;if(fabric.isLikelyNode){replacement.src=canvasEl.toBuffer(undefined,fabric.Image.pngCompression);_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback()}else{replacement.onload=function(){_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback();replacement.onload=canvasEl=imgEl=null};replacement.src=canvasEl.toDataURL("image/png")}return canvasEl},_render:function(ctx,noTransform){var x,y,imageMargins=this._findMargins(),elementToDraw;x=noTransform?this.left:-this.width/2;y=noTransform?this.top:-this.height/2;if(this.meetOrSlice==="slice"){ctx.beginPath();ctx.rect(x,y,this.width,this.height);ctx.clip()}if(this.isMoving===false&&this.resizeFilters.length&&this._needsResize()){this._lastScaleX=this.scaleX;this._lastScaleY=this.scaleY;elementToDraw=this.applyFilters(null,this.resizeFilters,this._filteredEl||this._originalElement,true)}else{elementToDraw=this._element}elementToDraw&&ctx.drawImage(elementToDraw,x+imageMargins.marginX,y+imageMargins.marginY,imageMargins.width,imageMargins.height);this._renderStroke(ctx)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_findMargins:function(){var width=this.width,height=this.height,scales,scale,marginX=0,marginY=0;if(this.alignX!=="none"||this.alignY!=="none"){scales=[this.width/this._element.width,this.height/this._element.height];scale=this.meetOrSlice==="meet"?Math.min.apply(null,scales):Math.max.apply(null,scales);width=this._element.width*scale;height=this._element.height*scale;if(this.alignX==="Mid"){marginX=(this.width-width)/2}if(this.alignX==="Max"){marginX=this.width-width}if(this.alignY==="Mid"){marginY=(this.height-height)/2}if(this.alignY==="Max"){marginY=this.height-height}}return{width:width,height:height,marginX:marginX,marginY:marginY}},_resetWidthHeight:function(){var element=this.getElement();this.set("width",element.width);this.set("height",element.height)},_initElement:function(element,options){this.setElement(fabric.util.getById(element),null,options);fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(options){options||(options={});this.setOptions(options);this._setWidthHeight(options);if(this._element&&this.crossOrigin){this._element.crossOrigin=this.crossOrigin}},_initFilters:function(filters,callback){if(filters&&filters.length){fabric.util.enlivenObjects(filters,function(enlivenedObjects){callback&&callback(enlivenedObjects)},"fabric.Image.filters")}else{callback&&callback()}},_setWidthHeight:function(options){this.width="width"in options?options.width:this.getElement()?this.getElement().width||0:0;this.height="height"in options?options.height:this.getElement()?this.getElement().height||0:0},complexity:function(){return 1}});fabric.Image.CSS_CANVAS="canvas-img";fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc;fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){fabric.Image.prototype._initFilters.call(object,object.filters,function(filters){object.filters=filters||[];fabric.Image.prototype._initFilters.call(object,object.resizeFilters,function(resizeFilters){object.resizeFilters=resizeFilters||[];var instance=new fabric.Image(img,object);callback&&callback(instance)})})},null,object.crossOrigin)};fabric.Image.fromURL=function(url,callback,imgOptions){fabric.util.loadImage(url,function(img){callback&&callback(new fabric.Image(img,imgOptions))},null,imgOptions&&imgOptions.crossOrigin)};fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".split(" "));fabric.Image.fromElement=function(element,callback,options){var parsedAttributes=fabric.parseAttributes(element,fabric.Image.ATTRIBUTE_NAMES),preserveAR;if(parsedAttributes.preserveAspectRatio){preserveAR=fabric.util.parsePreserveAspectRatioAttribute(parsedAttributes.preserveAspectRatio);extend(parsedAttributes,preserveAR)}fabric.Image.fromURL(parsedAttributes["xlink:href"],callback,extend(options?fabric.util.object.clone(options):{},parsedAttributes))};fabric.Image.async=true;fabric.Image.pngCompression=1})(typeof exports!=="undefined"?exports:this);fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var angle=this.getAngle()%360;if(angle>0){return Math.round((angle-1)/90)*90}return Math.round(angle/90)*90},straighten:function(){this.setAngle(this._getAngleValueForStraighten());return this},fxStraighten:function(callbacks){callbacks=callbacks||{};var empty=function(){},onComplete=callbacks.onComplete||empty,onChange=callbacks.onChange||empty,_this=this;fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(value){_this.setAngle(value);onChange()},onComplete:function(){_this.setCoords();onComplete()},onStart:function(){_this.set("active",false)}});return this}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(object){object.straighten();this.renderAll();return this},fxStraightenObject:function(object){object.fxStraighten({onChange:this.renderAll.bind(this)});return this}});fabric.Image.filters=fabric.Image.filters||{};fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(options){if(options){this.setOptions(options)}},setOptions:function(options){for(var prop in options){this[prop]=options[prop]}},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.Brightness=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"Brightness",initialize:function(options){options=options||{};this.brightness=options.brightness||0},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,brightness=this.brightness;for(var i=0,len=data.length;ish||scx<0||scx>sw){continue}srcOff=(scy*sw+scx)*4;wt=weights[cy*side+cx];r+=src[srcOff]*wt;g+=src[srcOff+1]*wt;b+=src[srcOff+2]*wt;a+=src[srcOff+3]*wt}}dst[dstOff]=r;dst[dstOff+1]=g;dst[dstOff+2]=b;dst[dstOff+3]=a+alphaFac*(255-a)}}context.putImageData(output,0,0)},toObject:function(){return extend(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}});fabric.Image.filters.Convolute.fromObject=function(object){return new fabric.Image.filters.Convolute(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.GradientTransparency=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(options){options=options||{};this.threshold=options.threshold||100},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,threshold=this.threshold,total=data.length;for(var i=0,len=data.length;i-1?options.channel:0},applyTo:function(canvasEl){if(!this.mask){return}var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,maskEl=this.mask.getElement(),maskCanvasEl=fabric.util.createCanvasElement(),channel=this.channel,i,iLen=imageData.width*imageData.height*4;maskCanvasEl.width=canvasEl.width;maskCanvasEl.height=canvasEl.height;maskCanvasEl.getContext("2d").drawImage(maskEl,0,0,canvasEl.width,canvasEl.height);var maskImageData=maskCanvasEl.getContext("2d").getImageData(0,0,canvasEl.width,canvasEl.height),maskData=maskImageData.data;for(i=0;ilimit&&g>limit&&b>limit&&abs(r-g)width){multW=2;signW=-1}if(newHeight>height){multH=2;signH=-1}imageData=context.getImageData(0,0,width,height);canvasEl.width=max(newWidth,width);canvasEl.height=max(newHeight,height);context.putImageData(imageData,0,0);while(!doneW||!doneH){width=stepW;height=stepH;if(newWidth*signWlobes){return 0}x*=Math.PI;if(abs(x)<1e-16){return 1}var xx=x/lobes;return sin(x)*sin(xx)/x/xx}}function process(u){var v,i,weight,idx,a,red,green,blue,alpha,fX,fY;center.x=(u+.5)*ratioX;icenter.x=floor(center.x);for(v=0;v=oW){continue}fX=floor(1e3*abs(i-center.x));if(!cacheLanc[fX]){cacheLanc[fX]={}}for(var j=icenter.y-range2Y;j<=icenter.y+range2Y;j++){if(j<0||j>=oH){continue}fY=floor(1e3*abs(j-center.y));if(!cacheLanc[fX][fY]){cacheLanc[fX][fY]=lanczos(sqrt(pow(fX*rcpRatioX,2)+pow(fY*rcpRatioY,2))/1e3)}weight=cacheLanc[fX][fY];if(weight>0){idx=(j*oW+i)*4;a+=weight;red+=weight*srcData[idx];green+=weight*srcData[idx+1];blue+=weight*srcData[idx+2];alpha+=weight*srcData[idx+3]}}}idx=(v*dW+u)*4;destData[idx]=red/a;destData[idx+1]=green/a;destData[idx+2]=blue/a;destData[idx+3]=alpha/a}if(++u1&&w<-1){continue}weight=2*w*w*w-3*w*w+1;if(weight>0){dx=4*(xx+yy*oW);gxA+=weight*data[dx+3];weightsAlpha+=weight;if(data[dx+3]<255){weight=weight*data[dx+3]/250}gxR+=weight*data[dx];gxG+=weight*data[dx+1];gxB+=weight*data[dx+2];weights+=weight}}}data2[x2]=gxR/weights;data2[x2+1]=gxG/weights;data2[x2+2]=gxB/weights;data2[x2+3]=gxA/weightsAlpha}}return img2},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}});fabric.Image.filters.Resize.fromObject=function(object){return new fabric.Image.filters.Resize(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,clone=fabric.util.object.clone,toFixed=fabric.util.toFixed,supportsLineDash=fabric.StaticCanvas.supports("setLineDash"),NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;if(fabric.Text){fabric.warn("fabric.Text is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("fontFamily","fontWeight","fontSize","text","textDecoration","textAlign","fontStyle","lineHeight","textBackgroundColor");fabric.Text=fabric.util.createClass(fabric.Object,{_dimensionAffectingProps:{fontSize:true,fontWeight:true,fontFamily:true,fontStyle:true,lineHeight:true,stroke:true,strokeWidth:true,text:true,textAlign:true},_reNewline:/\r?\n/,_reSpacesAndTabs:/[ \t\r]+/g,type:"text",fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",textDecoration:"",textAlign:"left",fontStyle:"",lineHeight:1.16,textBackgroundColor:"",stateProperties:stateProperties,stroke:null,shadow:null,_fontSizeFraction:.25,_fontSizeMult:1.13,initialize:function(text,options){options=options||{};this.text=text;this.__skipDimension=true;this.setOptions(options);this.__skipDimension=false;this._initDimensions()},_initDimensions:function(ctx){if(this.__skipDimension){return}if(!ctx){ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx)}this._textLines=this._splitTextIntoLines();this._clearCache();this._cacheLinesWidth=this.textAlign!=="justify";this.width=this._getTextWidth(ctx);this._cacheLinesWidth=true;this.height=this._getTextHeight(ctx)},toString:function(){return"#'},_render:function(ctx){this.clipTo&&fabric.util.clipContext(this,ctx);this._setOpacity(ctx);this._setShadow(ctx);this._setupCompositeOperation(ctx);this._renderTextBackground(ctx);this._setStrokeStyles(ctx);this._setFillStyles(ctx);this._renderText(ctx);this._renderTextDecoration(ctx);this.clipTo&&ctx.restore()},_renderText:function(ctx){this._translateForTextAlign(ctx);this._renderTextFill(ctx);this._renderTextStroke(ctx);this._translateForTextAlign(ctx,true)},_translateForTextAlign:function(ctx,back){if(this.textAlign!=="left"&&this.textAlign!=="justify"){var sign=back?-1:1;ctx.translate(this.textAlign==="center"?sign*this.width/2:sign*this.width,0)}},_setTextStyles:function(ctx){ctx.textBaseline="alphabetic";if(!this.skipTextAlign){ctx.textAlign=this.textAlign}ctx.font=this._getFontDeclaration()},_getTextHeight:function(){return this._textLines.length*this._getHeightOfLine()},_getTextWidth:function(ctx){var maxWidth=this._getLineWidth(ctx,0);for(var i=1,len=this._textLines.length;imaxWidth){maxWidth=currentLineWidth}}return maxWidth},_renderChars:function(method,ctx,chars,left,top){var shortM=method.slice(0,-4);if(this[shortM].toLive){var offsetX=-this.width/2+this[shortM].offsetX||0,offsetY=-this.height/2+this[shortM].offsetY||0;ctx.save();ctx.translate(offsetX,offsetY);left-=offsetX;top-=offsetY}ctx[method](chars,left,top);this[shortM].toLive&&ctx.restore()},_renderTextLine:function(method,ctx,line,left,top,lineIndex){top-=this.fontSize*this._fontSizeFraction;var lineWidth=this._getLineWidth(ctx,lineIndex);if(this.textAlign!=="justify"||this.width0?widthDiff/numSpaces:0,leftOffset=0,word; +for(var i=0,len=words.length;i1){width=this.width}else{width=ctx.measureText(line).width}}else{width=ctx.measureText(line).width}this._cacheLinesWidth&&(this.__lineWidths[lineIndex]=width);return width},_renderTextDecoration:function(ctx){if(!this.textDecoration){return}var halfOfVerticalBox=this.height/2,_this=this,offsets=[];function renderLinesAtOffset(offsets){var i,lineHeight=0,len,j,oLen,lineWidth,lineLeftOffset,heightOfLine;for(i=0,len=_this._textLines.length;i-1){offsets.push(.85)}if(this.textDecoration.indexOf("line-through")>-1){offsets.push(.43)}if(this.textDecoration.indexOf("overline")>-1){offsets.push(-.12)}if(offsets.length>0){renderLinesAtOffset(offsets)}},_getFontDeclaration:function(){return[fabric.isLikelyNode?this.fontWeight:this.fontStyle,fabric.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",fabric.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(ctx,noTransform){if(!this.visible){return}ctx.save();this._setTextStyles(ctx);if(this._shouldClearCache()){this._initDimensions(ctx)}if(!noTransform){this.transform(ctx)}if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}if(this.group&&this.group.type==="path-group"){ctx.translate(this.left,this.top)}this._render(ctx);ctx.restore()},_splitTextIntoLines:function(){return this.text.split(this._reNewline)},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),offsets=this._getSVGLeftTopOffsets(this.ctx),textAndBg=this._getSVGTextAndBg(offsets.textTop,offsets.textLeft);this._wrapSVGTextAndBg(markup,textAndBg);return reviver?reviver(markup.join("")):markup.join("")},_getSVGLeftTopOffsets:function(ctx){var lineTop=this._getHeightOfLine(ctx,0),textLeft=-this.width/2,textTop=0;return{textLeft:textLeft+(this.group&&this.group.type==="path-group"?this.left:0),textTop:textTop+(this.group&&this.group.type==="path-group"?-this.top:0),lineTop:lineTop}},_wrapSVGTextAndBg:function(markup,textAndBg){var noShadow=true,filter=this.getSvgFilter(),style=filter===""?"":' style="'+filter+'"';markup.push(' \n",textAndBg.textBgRects.join("")," \n',textAndBg.textSpans.join("")," \n"," \n")},_getSVGTextAndBg:function(textTopOffset,textLeftOffset){var textSpans=[],textBgRects=[],height=0;this._setSVGBg(textBgRects);for(var i=0,len=this._textLines.length;i",fabric.util.string.escapeXml(this._textLines[i]),"\n")},_setSVGTextLineJustifed:function(i,textSpans,yPos,textLeftOffset){var ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx);var line=this._textLines[i],words=line.split(/\s+/),wordsWidth=this._getWidthOfWords(ctx,line),widthDiff=this.width-wordsWidth,numSpaces=words.length-1,spaceWidth=numSpaces>0?widthDiff/numSpaces:0,word,attributes=this._getFillAttributes(this.fill),len;textLeftOffset+=this._getLineLeftOffset(this._getLineWidth(ctx,i));for(i=0,len=words.length;i",fabric.util.string.escapeXml(word),"\n");textLeftOffset+=this._getWidthOfWords(ctx,word)+spaceWidth}},_setSVGTextLineBg:function(textBgRects,i,textLeftOffset,textTopOffset,height){textBgRects.push(" \n')},_setSVGBg:function(textBgRects){if(this.backgroundColor){textBgRects.push(" \n')}},_getFillAttributes:function(value){var fillColor=value&&typeof value==="string"?new fabric.Color(value):"";if(!fillColor||!fillColor.getSource()||fillColor.getAlpha()===1){return'fill="'+value+'"'}return'opacity="'+fillColor.getAlpha()+'" fill="'+fillColor.setAlpha(1).toRgb()+'"'},_set:function(key,value){this.callSuper("_set",key,value);if(key in this._dimensionAffectingProps){this._initDimensions();this.setCoords()}},complexity:function(){return 1}});fabric.Text.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" "));fabric.Text.DEFAULT_SVG_FONT_SIZE=16;fabric.Text.fromElement=function(element,options){if(!element){return null}var parsedAttributes=fabric.parseAttributes(element,fabric.Text.ATTRIBUTE_NAMES);options=fabric.util.object.extend(options?fabric.util.object.clone(options):{},parsedAttributes);options.top=options.top||0;options.left=options.left||0;if("dx"in parsedAttributes){options.left+=parsedAttributes.dx}if("dy"in parsedAttributes){options.top+=parsedAttributes.dy}if(!("fontSize"in options)){options.fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}if(!options.originX){options.originX="left"}var textContent="";if(!("textContent"in element)){if("firstChild"in element&&element.firstChild!==null){if("data"in element.firstChild&&element.firstChild.data!==null){textContent=element.firstChild.data}}}else{textContent=element.textContent}textContent=textContent.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var text=new fabric.Text(textContent,options),offX=0;if(text.originX==="left"){offX=text.getWidth()/2}if(text.originX==="right"){offX=-text.getWidth()/2}text.set({left:text.getLeft()+offX,top:text.getTop()-text.getHeight()/2+text.fontSize*(.18+text._fontSizeFraction)});return text};fabric.Text.fromObject=function(object){return new fabric.Text(object.text,clone(object))};fabric.util.createAccessors(fabric.Text)})(typeof exports!=="undefined"?exports:this);(function(){var clone=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:false,editable:true,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:true,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:false,_charWidthsCache:{},__widthOfSpace:[],initialize:function(text,options){this.styles=options?options.styles||{}:{};this.callSuper("initialize",text,options);this.initBehavior()},_clearCache:function(){this.callSuper("_clearCache");this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles){return true}var obj=this.styles;for(var p1 in obj){for(var p2 in obj[p1]){for(var p3 in obj[p1][p2]){return false}}}return true},setSelectionStart:function(index){index=Math.max(index,0);if(this.selectionStart!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionStart=index}this._updateTextarea()},setSelectionEnd:function(index){index=Math.min(index,this.text.length);if(this.selectionEnd!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionEnd=index}this._updateTextarea()},getSelectionStyles:function(startIndex,endIndex){if(arguments.length===2){var styles=[];for(var i=startIndex;i=start.charIndex&&(i!==endLine||jstartLine&&i0||this.skipFillStrokeCheck)){this.callSuper("_renderChars",method,ctx,line,left,top)}},_renderChar:function(method,ctx,lineIndex,i,_char,left,top,lineHeight){var charWidth,charHeight,shouldFill,shouldStroke,decl=this._getStyleDeclaration(lineIndex,i),offset,textDecoration;if(decl){charHeight=this._getHeightOfChar(ctx,_char,lineIndex,i);shouldStroke=decl.stroke;shouldFill=decl.fill;textDecoration=decl.textDecoration}else{charHeight=this.fontSize}shouldStroke=(shouldStroke||this.stroke)&&method==="strokeText";shouldFill=(shouldFill||this.fill)&&method==="fillText";decl&&ctx.save();charWidth=this._applyCharStylesGetWidth(ctx,_char,lineIndex,i,decl||{});textDecoration=textDecoration||this.textDecoration;if(decl&&decl.textBackgroundColor){this._removeShadow(ctx)}shouldFill&&ctx.fillText(_char,left,top);shouldStroke&&ctx.strokeText(_char,left,top);if(textDecoration||textDecoration!==""){offset=this._fontSizeFraction*lineHeight/this.lineHeight;this._renderCharDecoration(ctx,textDecoration,left,top,offset,charWidth,charHeight)}decl&&ctx.restore();ctx.translate(charWidth,0)},_hasStyleChanged:function(prevStyle,thisStyle){return prevStyle.fill!==thisStyle.fill||prevStyle.fontSize!==thisStyle.fontSize||prevStyle.textBackgroundColor!==thisStyle.textBackgroundColor||prevStyle.textDecoration!==thisStyle.textDecoration||prevStyle.fontFamily!==thisStyle.fontFamily||prevStyle.fontWeight!==thisStyle.fontWeight||prevStyle.fontStyle!==thisStyle.fontStyle||prevStyle.stroke!==thisStyle.stroke||prevStyle.strokeWidth!==thisStyle.strokeWidth},_renderCharDecoration:function(ctx,textDecoration,left,top,offset,charWidth,charHeight){if(!textDecoration){return}var decorationWeight=charHeight/15,positions={underline:top+charHeight/10,"line-through":top-charHeight*(this._fontSizeFraction+this._fontSizeMult-1)+decorationWeight,overline:top-(this._fontSizeMult-this._fontSizeFraction)*charHeight},decorations=["underline","line-through","overline"],i,decoration;for(i=0;i-1){ctx.fillRect(left,positions[decoration],charWidth,decorationWeight)}}},_renderTextLine:function(method,ctx,line,left,top,lineIndex){if(!this.isEmptyStyles()){top+=this.fontSize*(this._fontSizeFraction+.03)}this.callSuper("_renderTextLine",method,ctx,line,left,top,lineIndex)},_renderTextDecoration:function(ctx){if(this.isEmptyStyles()){return this.callSuper("_renderTextDecoration",ctx)}},_renderTextLinesBackground:function(ctx){this.callSuper("_renderTextLinesBackground",ctx);var lineTopOffset=0,heightOfLine,lineWidth,lineLeftOffset,leftOffset=this._getLeftOffset(),topOffset=this._getTopOffset(),line,_char,style;for(var i=0,len=this._textLines.length;imaxHeight){maxHeight=currentCharHeight}}this.__lineHeights[lineIndex]=maxHeight*this.lineHeight*this._fontSizeMult;return this.__lineHeights[lineIndex]},_getTextHeight:function(ctx){var height=0;for(var i=0,len=this._textLines.length;i-1){offset++;index--}return startFrom-offset},findWordBoundaryRight:function(startFrom){var offset=0,index=startFrom;if(this._reSpace.test(this.text.charAt(index))){while(this._reSpace.test(this.text.charAt(index))){offset++;index++}}while(/\S/.test(this.text.charAt(index))&&index-1){offset++; +index--}return startFrom-offset},findLineBoundaryRight:function(startFrom){var offset=0,index=startFrom;while(!/\n/.test(this.text.charAt(index))&&index0&&index=_this.__selectionStartOnMouseDown){_this.setSelectionStart(_this.__selectionStartOnMouseDown);_this.setSelectionEnd(newSelectionStart)}else{_this.setSelectionStart(newSelectionStart);_this.setSelectionEnd(_this.__selectionStartOnMouseDown)}})},_setEditingProps:function(){this.hoverCursor="text";if(this.canvas){this.canvas.defaultCursor=this.canvas.moveCursor="text"}this.borderColor=this.editingBorderColor;this.hasControls=this.selectable=false;this.lockMovementX=this.lockMovementY=true},_updateTextarea:function(){if(!this.hiddenTextarea||this.inCompositionMode){return}this.hiddenTextarea.value=this.text;this.hiddenTextarea.selectionStart=this.selectionStart;this.hiddenTextarea.selectionEnd=this.selectionEnd;if(this.selectionStart===this.selectionEnd){var p=this._calcTextareaPosition();this.hiddenTextarea.style.left=p.x+"px";this.hiddenTextarea.style.top=p.y+"px"}},_calcTextareaPosition:function(){var chars=this.text.split(""),boundaries=this._getCursorBoundaries(chars,"cursor"),cursorLocation=this.get2DCursorLocation(),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex,charHeight=this.getCurrentCharFontSize(lineIndex,charIndex),leftOffset=lineIndex===0&&charIndex===0?this._getLineLeftOffset(this._getLineWidth(this.ctx,lineIndex)):boundaries.leftOffset,m=this.calcTransformMatrix(),p={x:boundaries.left+leftOffset,y:boundaries.top+boundaries.topOffset+charHeight};this.hiddenTextarea.style.fontSize=charHeight+"px";return fabric.util.transformPoint(p,m)},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){if(!this._savedProps){return}this.hoverCursor=this._savedProps.overCursor;this.hasControls=this._savedProps.hasControls;this.borderColor=this._savedProps.borderColor;this.lockMovementX=this._savedProps.lockMovementX;this.lockMovementY=this._savedProps.lockMovementY;if(this.canvas){this.canvas.defaultCursor=this._savedProps.defaultCursor;this.canvas.moveCursor=this._savedProps.moveCursor}},exitEditing:function(){this.selected=false;this.isEditing=false;this.selectable=true;this.selectionEnd=this.selectionStart;this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);this.hiddenTextarea=null;this.abortCursorAnimation();this._restoreEditingProps();this._currentCursorOpacity=0;this.fire("editing:exited");this.canvas&&this.canvas.fire("text:editing:exited",{target:this});return this},_removeExtraneousStyles:function(){for(var prop in this.styles){if(!this._textLines[prop]){delete this.styles[prop]}}},_removeCharsFromTo:function(start,end){while(end!==start){this._removeSingleCharAndStyle(start+1);end--}this.setSelectionStart(start)},_removeSingleCharAndStyle:function(index){var isBeginningOfLine=this.text[index-1]==="\n",indexStyle=isBeginningOfLine?index:index-1;this.removeStyleObject(isBeginningOfLine,indexStyle);this.text=this.text.slice(0,index-1)+this.text.slice(index);this._textLines=this._splitTextIntoLines()},insertChars:function(_chars,useCopiedStyle){var style;if(this.selectionEnd-this.selectionStart>1){this._removeCharsFromTo(this.selectionStart,this.selectionEnd);this.setSelectionEnd(this.selectionStart)}if(!useCopiedStyle&&this.isEmptyStyles()){this.insertChar(_chars,false);return}for(var i=0,len=_chars.length;i=charIndex){newLineStyles[parseInt(index,10)-charIndex]=this.styles[lineIndex][index];delete this.styles[lineIndex][index]}}this.styles[lineIndex+1]=newLineStyles}this._forceClearCache=true},insertCharStyleObject:function(lineIndex,charIndex,style){var currentLineStyles=this.styles[lineIndex],currentLineStylesCloned=clone(currentLineStyles);if(charIndex===0&&!style){charIndex=1}for(var index in currentLineStylesCloned){var numericIndex=parseInt(index,10);if(numericIndex>=charIndex){currentLineStyles[numericIndex+1]=currentLineStylesCloned[numericIndex];if(!currentLineStylesCloned[numericIndex-1]){delete currentLineStyles[numericIndex]}}}this.styles[lineIndex][charIndex]=style||clone(currentLineStyles[charIndex-1]);this._forceClearCache=true},insertStyleObjects:function(_chars,isEndOfLine,styleObject){var cursorLocation=this.get2DCursorLocation(),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;if(!this._getLineStyle(lineIndex)){this._setLineStyle(lineIndex,{})}if(_chars==="\n"){this.insertNewlineStyleObject(lineIndex,charIndex,isEndOfLine)}else{this.insertCharStyleObject(lineIndex,charIndex,styleObject)}},shiftLineStyles:function(lineIndex,offset){var clonedStyles=clone(this.styles);for(var line in this.styles){var numericLine=parseInt(line,10);if(numericLine>lineIndex){this.styles[numericLine+offset]=clonedStyles[numericLine];if(!clonedStyles[numericLine-offset]){delete this.styles[numericLine]}}}},removeStyleObject:function(isBeginningOfLine,index){var cursorLocation=this.get2DCursorLocation(index),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;this._removeStyleObject(isBeginningOfLine,cursorLocation,lineIndex,charIndex)},_getTextOnPreviousLine:function(lIndex){return this._textLines[lIndex-1]},_removeStyleObject:function(isBeginningOfLine,cursorLocation,lineIndex,charIndex){if(isBeginningOfLine){var textOnPreviousLine=this._getTextOnPreviousLine(cursorLocation.lineIndex),newCharIndexOnPrevLine=textOnPreviousLine?textOnPreviousLine.length:0;if(!this.styles[lineIndex-1]){this.styles[lineIndex-1]={}}for(charIndex in this.styles[lineIndex]){this.styles[lineIndex-1][parseInt(charIndex,10)+newCharIndexOnPrevLine]=this.styles[lineIndex][charIndex]}this.shiftLineStyles(cursorLocation.lineIndex,-1)}else{var currentLineStyles=this.styles[lineIndex];if(currentLineStyles){delete currentLineStyles[charIndex]}var currentLineStylesCloned=clone(currentLineStyles);for(var i in currentLineStylesCloned){var numericIndex=parseInt(i,10);if(numericIndex>=charIndex&&numericIndex!==0){currentLineStyles[numericIndex-1]=currentLineStylesCloned[numericIndex];delete currentLineStyles[numericIndex]}}}},insertNewline:function(){this.insertChars("\n")}})})();fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date;this.__lastLastClickTime=+new Date;this.__lastPointer={};this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(options){this.__newClickTime=+new Date;var newPointer=this.canvas.getPointer(options.e);if(this.isTripleClick(newPointer)){this.fire("tripleclick",options);this._stopEvent(options.e)}else if(this.isDoubleClick(newPointer)){this.fire("dblclick",options);this._stopEvent(options.e)}this.__lastLastClickTime=this.__lastClickTime;this.__lastClickTime=this.__newClickTime;this.__lastPointer=newPointer;this.__lastIsEditing=this.isEditing;this.__lastSelected=this.selected},isDoubleClick:function(newPointer){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===newPointer.x&&this.__lastPointer.y===newPointer.y&&this.__lastIsEditing},isTripleClick:function(newPointer){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===newPointer.x&&this.__lastPointer.y===newPointer.y},_stopEvent:function(e){e.preventDefault&&e.preventDefault();e.stopPropagation&&e.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler();this.initMousedownHandler();this.initMouseupHandler();this.initClicks()},initClicks:function(){this.on("dblclick",function(options){this.selectWord(this.getSelectionStartFromPointer(options.e))});this.on("tripleclick",function(options){this.selectLine(this.getSelectionStartFromPointer(options.e))})},initMousedownHandler:function(){this.on("mousedown",function(options){if(!this.editable){return}var pointer=this.canvas.getPointer(options.e);this.__mousedownX=pointer.x;this.__mousedownY=pointer.y;this.__isMousedown=true;if(this.hiddenTextarea&&this.canvas){this.canvas.wrapperEl.appendChild(this.hiddenTextarea)}if(this.selected){this.setCursorByClick(options.e)}if(this.isEditing){this.__selectionStartOnMouseDown=this.selectionStart;this.initDelayedCursor(true)}})},_isObjectMoved:function(e){var pointer=this.canvas.getPointer(e);return this.__mousedownX!==pointer.x||this.__mousedownY!==pointer.y},initMouseupHandler:function(){this.on("mouseup",function(options){this.__isMousedown=false;if(!this.editable||this._isObjectMoved(options.e)){return}if(this.__lastSelected&&!this.__corner){this.enterEditing(options.e);this.initDelayedCursor(true)}this.selected=true})},setCursorByClick:function(e){var newSelectionStart=this.getSelectionStartFromPointer(e);if(e.shiftKey){if(newSelectionStartdistanceBtwLastCharAndCursor?0:1,newSelectionStart=index+offset;if(this.flipX){newSelectionStart=jlen-newSelectionStart}if(newSelectionStart>this.text.length){newSelectionStart=this.text.length}return newSelectionStart}});fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(e){var p;if(e&&this.canvas){p=this.canvas.getPointer(e)}else{this.oCoords||this.setCoords();p=this.oCoords.tl}this.hiddenTextarea=fabric.document.createElement("textarea");this.hiddenTextarea.setAttribute("autocapitalize","off");this.hiddenTextarea.style.cssText="position: absolute; top: "+p.y+"px; left: "+p.x+"px; opacity: 0;"+" width: 0px; height: 0px; z-index: -999;";if(this.canvas){this.canvas.lowerCanvasEl.parentNode.appendChild(this.hiddenTextarea)}else{fabric.document.body.appendChild(this.hiddenTextarea)}fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this));fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this));fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this));fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this));fabric.util.addListener(this.hiddenTextarea,"cut",this.cut.bind(this));fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this));fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this));fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this));fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this));if(!this._clickHandlerInitialized&&this.canvas){fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this));this._clickHandlerInitialized=true}},_keysMap:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",67:"copy",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(e){if(!this.isEditing){return}if(e.keyCode in this._keysMap){this[this._keysMap[e.keyCode]](e)}else{return}e.stopImmediatePropagation();e.preventDefault();this.canvas&&this.canvas.renderAll()},onKeyUp:function(e){if(!this.isEditing||this._copyDone){this._copyDone=false;return}if(e.keyCode in this._ctrlKeysMap&&(e.ctrlKey||e.metaKey)){this[this._ctrlKeysMap[e.keyCode]](e)}else{return}e.stopImmediatePropagation();e.preventDefault();this.canvas&&this.canvas.renderAll()},onInput:function(e){if(!this.isEditing||this.inCompositionMode){return}var offset=this.selectionStart||0,offsetEnd=this.selectionEnd||0,textLength=this.text.length,newTextLength=this.hiddenTextarea.value.length,diff,charsToInsert,start;if(newTextLength>textLength){start=this._selectionDirection==="left"?offsetEnd:offset;diff=newTextLength-textLength;charsToInsert=this.hiddenTextarea.value.slice(start,start+diff)}else{diff=newTextLength-textLength+offsetEnd-offset;charsToInsert=this.hiddenTextarea.value.slice(offset,offset+diff)}this.insertChars(charsToInsert);e.stopPropagation()},onCompositionStart:function(){this.inCompositionMode=true;this.prevCompositionLength=0;this.compositionStart=this.selectionStart},onCompositionEnd:function(){this.inCompositionMode=false},onCompositionUpdate:function(e){var data=e.data;this.selectionStart=this.compositionStart;this.selectionEnd=this.selectionEnd===this.selectionStart?this.compositionStart+this.prevCompositionLength:this.selectionEnd;this.insertChars(data,false);this.prevCompositionLength=data.length},forwardDelete:function(e){if(this.selectionStart===this.selectionEnd){if(this.selectionStart===this.text.length){return}this.moveCursorRight(e)}this.removeChars(e)},copy:function(e){if(this.selectionStart===this.selectionEnd){return}var selectedText=this.getSelectedText(),clipboardData=this._getClipboardData(e);if(clipboardData){clipboardData.setData("text",selectedText)}fabric.copiedText=selectedText;fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd);e.stopImmediatePropagation();e.preventDefault();this._copyDone=true},paste:function(e){var copiedText=null,clipboardData=this._getClipboardData(e),useCopiedStyle=true;if(clipboardData){copiedText=clipboardData.getData("text").replace(/\r/g,"");if(!fabric.copiedTextStyle||fabric.copiedText!==copiedText){useCopiedStyle=false}}else{copiedText=fabric.copiedText}if(copiedText){this.insertChars(copiedText,useCopiedStyle)}e.stopImmediatePropagation();e.preventDefault()},cut:function(e){if(this.selectionStart===this.selectionEnd){return}this.copy(e);this.removeChars(e)},_getClipboardData:function(e){return e&&e.clipboardData||fabric.window.clipboardData},getDownCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,cursorLocation=this.get2DCursorLocation(selectionProp),_char,lineLeftOffset,lineIndex=cursorLocation.lineIndex,textOnSameLineBeforeCursor=this._textLines[lineIndex].slice(0,cursorLocation.charIndex),textOnSameLineAfterCursor=this._textLines[lineIndex].slice(cursorLocation.charIndex),textOnNextLine=this._textLines[lineIndex+1]||"";if(lineIndex===this._textLines.length-1||e.metaKey||e.keyCode===34){return this.text.length-selectionProp}var widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,lineIndex);lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor);var widthOfCharsOnSameLineBeforeCursor=lineLeftOffset;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnNextLine-widthOfChar,rightEdge=widthOfCharsOnNextLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnNextLine=offsetFromRightEdgethis.text.length){this.setSelectionEnd(this.text.length)}},getUpCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,cursorLocation=this.get2DCursorLocation(selectionProp),lineIndex=cursorLocation.lineIndex;if(lineIndex===0||e.metaKey||e.keyCode===33){return selectionProp}var textOnSameLineBeforeCursor=this._textLines[lineIndex].slice(0,cursorLocation.charIndex),textOnPreviousLine=this._textLines[lineIndex-1]||"",_char,widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,cursorLocation.lineIndex),lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor),widthOfCharsOnSameLineBeforeCursor=lineLeftOffset;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnPreviousLine-widthOfChar,rightEdge=widthOfCharsOnPreviousLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnPrevLine=offsetFromRightEdge=this.text.length&&this.selectionEnd>=this.text.length){return}this.abortCursorAnimation();this._currentCursorOpacity=1;if(e.shiftKey){this.moveCursorRightWithShift(e)}else{this.moveCursorRightWithoutShift(e)}this.initDelayedCursor()},moveCursorRightWithShift:function(e){if(this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd){this._moveRight(e,"selectionStart")}else{this._selectionDirection="right";this._moveRight(e,"selectionEnd")}},moveCursorRightWithoutShift:function(e){this._selectionDirection="right";if(this.selectionStart===this.selectionEnd){this._moveRight(e,"selectionStart");this.setSelectionEnd(this.selectionStart)}else{this.setSelectionEnd(this.selectionEnd+this.getNumNewLinesInSelectedText());this.setSelectionStart(this.selectionEnd)}},removeChars:function(e){if(this.selectionStart===this.selectionEnd){this._removeCharsNearCursor(e)}else{this._removeCharsFromTo(this.selectionStart,this.selectionEnd)}this.setSelectionEnd(this.selectionStart);this._removeExtraneousStyles();this.canvas&&this.canvas.renderAll();this.setCoords();this.fire("changed");this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(e){if(this.selectionStart===0){return}if(e.metaKey){var leftLineBoundary=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftLineBoundary,this.selectionStart);this.setSelectionStart(leftLineBoundary)}else if(e.altKey){var leftWordBoundary=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftWordBoundary,this.selectionStart);this.setSelectionStart(leftWordBoundary)}else{this._removeSingleCharAndStyle(this.selectionStart);this.setSelectionStart(this.selectionStart-1)}}});(function(){var toFixed=fabric.util.toFixed,NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(lineIndex,textSpans,height,textLeftOffset,textTopOffset,textBgRects){if(!this._getLineStyle(lineIndex)){fabric.Text.prototype._setSVGTextLineText.call(this,lineIndex,textSpans,height,textLeftOffset,textTopOffset)}else{this._setSVGTextLineChars(lineIndex,textSpans,height,textLeftOffset,textBgRects)}},_setSVGTextLineChars:function(lineIndex,textSpans,height,textLeftOffset,textBgRects){var chars=this._textLines[lineIndex],charOffset=0,lineLeftOffset=this._getLineLeftOffset(this._getLineWidth(this.ctx,lineIndex))-this.width/2,lineOffset=this._getSVGLineTopOffset(lineIndex),heightOfLine=this._getHeightOfLine(this.ctx,lineIndex);for(var i=0,len=chars.length;i\n'].join("")},_createTextCharSpan:function(_char,styleDecl,lineLeftOffset,lineTopOffset,charOffset){var fillStyles=this.getSvgStyles.call(fabric.util.object.extend({visible:true,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},styleDecl));return[' ',fabric.util.string.escapeXml(_char),"\n"].join("")}})})();(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),clone=fabric.util.object.clone;fabric.Textbox=fabric.util.createClass(fabric.IText,fabric.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:0,__cachedLines:null,initialize:function(text,options){this.ctx=fabric.util.createCanvasElement().getContext("2d");this.callSuper("initialize",text,options);this.set({lockUniScaling:false,lockScalingY:true,lockScalingFlip:true,hasBorders:true});this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());this._dimensionAffectingProps.width=true},_initDimensions:function(ctx){if(this.__skipDimension){return}if(!ctx){ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx)}this.dynamicMinWidth=0;this._textLines=this._splitTextIntoLines();if(this.dynamicMinWidth>this.width){this._set("width",this.dynamicMinWidth)}this._clearCache();this.height=this._getTextHeight(ctx)},_generateStyleMap:function(){var realLineCount=0,realLineCharCount=0,charCount=0,map={};for(var i=0;i=this.width&&!lineJustStarted){lines.push(line);line="";lineWidth=wordWidth;lineJustStarted=true}if(!lineJustStarted){line+=infix}line+=word;infixWidth=this._measureText(ctx,infix,lineIndex,offset);offset++;lineJustStarted=false;if(wordWidth>largestWordWidth){largestWordWidth=wordWidth}}i&&lines.push(line);if(largestWordWidth>this.dynamicMinWidth){this.dynamicMinWidth=largestWordWidth}return lines},_splitTextIntoLines:function(){var originalAlign=this.textAlign;this.ctx.save();this._setTextStyles(this.ctx);this.textAlign="left";var lines=this._wrapText(this.ctx,this.text);this.textAlign=originalAlign;this.ctx.restore();this._textLines=lines;this._styleMap=this._generateStyleMap();return lines},setOnGroup:function(key,value){if(key==="scaleX"){this.set("scaleX",Math.abs(1/value));this.set("width",this.get("width")*value/(typeof this.__oldScaleX==="undefined"?1:this.__oldScaleX));this.__oldScaleX=value}},get2DCursorLocation:function(selectionStart){if(typeof selectionStart==="undefined"){selectionStart=this.selectionStart}var numLines=this._textLines.length,removed=0;for(var i=0;i=t.getMinWidth()){t.set("width",w);return true}}else{return setObjectScaleOverridden.call(fabric.Canvas.prototype,localMouse,transform,lockScalingX,lockScalingY,by,lockScalingFlip,_dim)}};fabric.Group.prototype._refreshControlsVisibility=function(){if(typeof fabric.Textbox==="undefined"){return}for(var i=this._objects.length;i--;){if(this._objects[i]instanceof fabric.Textbox){this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());return}}};var clone=fabric.util.object.clone;fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var prop in this._styleMap){if(!this._textLines[prop]){delete this.styles[this._styleMap[prop].line]}}},insertCharStyleObject:function(lineIndex,charIndex,style){var map=this._styleMap[lineIndex];lineIndex=map.line;charIndex=map.offset+charIndex;fabric.IText.prototype.insertCharStyleObject.apply(this,[lineIndex,charIndex,style])},insertNewlineStyleObject:function(lineIndex,charIndex,isEndOfLine){var map=this._styleMap[lineIndex];lineIndex=map.line;charIndex=map.offset+charIndex;fabric.IText.prototype.insertNewlineStyleObject.apply(this,[lineIndex,charIndex,isEndOfLine])},shiftLineStyles:function(lineIndex,offset){var clonedStyles=clone(this.styles),map=this._styleMap[lineIndex];lineIndex=map.line;for(var line in this.styles){var numericLine=parseInt(line,10);if(numericLine>lineIndex){this.styles[numericLine+offset]=clonedStyles[numericLine];if(!clonedStyles[numericLine-offset]){delete this.styles[numericLine]}}}},_getTextOnPreviousLine:function(lIndex){var textOnPreviousLine=this._textLines[lIndex-1];while(this._styleMap[lIndex-2]&&this._styleMap[lIndex-2].line===this._styleMap[lIndex-1].line){textOnPreviousLine=this._textLines[lIndex-2]+textOnPreviousLine;lIndex--}return textOnPreviousLine},removeStyleObject:function(isBeginningOfLine,index){var cursorLocation=this.get2DCursorLocation(index),map=this._styleMap[cursorLocation.lineIndex],lineIndex=map.line,charIndex=map.offset+cursorLocation.charIndex;this._removeStyleObject(isBeginningOfLine,cursorLocation,lineIndex,charIndex)}})})();(function(){var override=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(mouseOffset,prevWidth,width,index,jlen){index=override.call(this,mouseOffset,prevWidth,width,index,jlen);var tmp=0,removed=0;for(var i=0;i=index){break}if(this.text[tmp+removed]==="\n"||this.text[tmp+removed]===" "){removed++}}return index-i+removed}})();(function(){if(typeof document!=="undefined"&&typeof window!=="undefined"){return}var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;function request(url,encoding,callback){var oURL=URL.parse(url);if(!oURL.port){oURL.port=oURL.protocol.indexOf("https:")===0?443:80}var reqHandler=oURL.protocol.indexOf("https:")===0?HTTPS:HTTP,req=reqHandler.request({hostname:oURL.hostname,port:oURL.port,path:oURL.path,method:"GET"},function(response){var body="";if(encoding){response.setEncoding(encoding)}response.on("end",function(){callback(body)});response.on("data",function(chunk){if(response.statusCode===200){body+=chunk}})});req.on("error",function(err){if(err.errno===process.ECONNREFUSED){fabric.log("ECONNREFUSED: connection refused to "+oURL.hostname+":"+oURL.port)}else{fabric.log(err.message)}callback(null)});req.end()}function requestFs(path,callback){var fs=require("fs");fs.readFile(path,function(err,data){if(err){fabric.log(err);throw err}else{callback(data)}})}fabric.util.loadImage=function(url,callback,context){function createImageAndCallBack(data){if(data){img.src=new Buffer(data,"binary");img._src=url;callback&&callback.call(context,img)}else{img=null;callback&&callback.call(context,null,true)}}var img=new Image;if(url&&(url instanceof Buffer||url.indexOf("data")===0)){img.src=img._src=url;callback&&callback.call(context,img)}else if(url&&url.indexOf("http")!==0){requestFs(url,createImageAndCallBack)}else if(url){request(url,"binary",createImageAndCallBack)}else{callback&&callback.call(context,url)}};fabric.loadSVGFromURL=function(url,callback,reviver){url=url.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim();if(url.indexOf("http")!==0){requestFs(url,function(body){fabric.loadSVGFromString(body.toString(),callback,reviver)})}else{request(url,"",function(body){fabric.loadSVGFromString(body,callback,reviver)})}};fabric.loadSVGFromString=function(string,callback,reviver){var doc=(new DOMParser).parseFromString(string);fabric.parseSVGDocument(doc.documentElement,function(results,options){callback&&callback(results,options)},reviver)};fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body);callback&&callback()})};fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){var oImg=new fabric.Image(img);oImg._initConfig(object);oImg._initFilters(object.filters,function(filters){oImg.filters=filters||[];oImg._initFilters(object.resizeFilters,function(resizeFilters){oImg.resizeFilters=resizeFilters||[];callback&&callback(oImg)})})})};fabric.createCanvasForNode=function(width,height,options,nodeCanvasOptions){nodeCanvasOptions=nodeCanvasOptions||options;var canvasEl=fabric.document.createElement("canvas"),nodeCanvas=new Canvas(width||600,height||600,nodeCanvasOptions);canvasEl.style={};canvasEl.width=nodeCanvas.width;canvasEl.height=nodeCanvas.height;var FabricCanvas=fabric.Canvas||fabric.StaticCanvas,fabricCanvas=new FabricCanvas(canvasEl,options);fabricCanvas.contextContainer=nodeCanvas.getContext("2d");fabricCanvas.nodeCanvas=nodeCanvas;fabricCanvas.Font=Canvas.Font;return fabricCanvas};fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()};fabric.StaticCanvas.prototype.createJPEGStream=function(opts){return this.nodeCanvas.createJPEGStream(opts)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(width,options){origSetWidth.call(this,width,options);this.nodeCanvas.width=width;return this};if(fabric.Canvas){fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth}var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(height,options){origSetHeight.call(this,height,options);this.nodeCanvas.height=height;return this};if(fabric.Canvas){fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight}})(); \ No newline at end of file diff --git a/dist/fabric.min.js.gz b/dist/fabric.min.js.gz index 4f04c7112bca2b9b62f63f34ddb89c4d71ff82a1..7fe29032a87b58cf6bfb22bb0af849f23e35abe6 100644 GIT binary patch literal 75936 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 literal 64874 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"); - if (fabric.document.createWindow) { - fabric.window = fabric.document.createWindow(); - } else { - fabric.window = fabric.document.parentWindow; - } -} - -fabric.isTouchSupported = "ontouchstart" in fabric.document.documentElement; - -fabric.isLikelyNode = typeof Buffer !== "undefined" && typeof window === "undefined"; - -fabric.SHARED_ATTRIBUTES = [ "display", "transform", "fill", "fill-opacity", "fill-rule", "opacity", "stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "id" ]; - -fabric.DPI = 96; - -fabric.reNum = "(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)"; - -fabric.fontPaths = {}; - -fabric.devicePixelRatio = fabric.window.devicePixelRatio || fabric.window.webkitDevicePixelRatio || fabric.window.mozDevicePixelRatio || 1; - -(function() { - function _removeEventListener(eventName, handler) { - if (!this.__eventListeners[eventName]) { - return; - } - var eventListener = this.__eventListeners[eventName]; - if (handler) { - eventListener[eventListener.indexOf(handler)] = false; - } else { - fabric.util.array.fill(eventListener, false); - } - } - function observe(eventName, handler) { - if (!this.__eventListeners) { - this.__eventListeners = {}; - } - if (arguments.length === 1) { - for (var prop in eventName) { - this.on(prop, eventName[prop]); - } - } else { - if (!this.__eventListeners[eventName]) { - this.__eventListeners[eventName] = []; - } - this.__eventListeners[eventName].push(handler); - } - return this; - } - function stopObserving(eventName, handler) { - if (!this.__eventListeners) { - return; - } - if (arguments.length === 0) { - for (eventName in this.__eventListeners) { - _removeEventListener.call(this, eventName); - } - } else if (arguments.length === 1 && typeof arguments[0] === "object") { - for (var prop in eventName) { - _removeEventListener.call(this, prop, eventName[prop]); - } - } else { - _removeEventListener.call(this, eventName, handler); - } - return this; - } - function fire(eventName, options) { - if (!this.__eventListeners) { - return; - } - var listenersForEvent = this.__eventListeners[eventName]; - if (!listenersForEvent) { - return; - } - for (var i = 0, len = listenersForEvent.length; i < len; i++) { - listenersForEvent[i] && listenersForEvent[i].call(this, options || {}); - } - this.__eventListeners[eventName] = listenersForEvent.filter(function(value) { - return value !== false; - }); - return this; - } - fabric.Observable = { - observe: observe, - stopObserving: stopObserving, - fire: fire, - on: observe, - off: stopObserving, - trigger: fire - }; -})(); - -fabric.Collection = { - add: function() { - this._objects.push.apply(this._objects, arguments); - for (var i = 0, length = arguments.length; i < length; i++) { - this._onObjectAdded(arguments[i]); - } - this.renderOnAddRemove && this.renderAll(); - return this; - }, - insertAt: function(object, index, nonSplicing) { - var objects = this.getObjects(); - if (nonSplicing) { - objects[index] = object; - } else { - objects.splice(index, 0, object); - } - this._onObjectAdded(object); - this.renderOnAddRemove && this.renderAll(); - return this; - }, - remove: function() { - var objects = this.getObjects(), index; - for (var i = 0, length = arguments.length; i < length; i++) { - index = objects.indexOf(arguments[i]); - if (index !== -1) { - objects.splice(index, 1); - this._onObjectRemoved(arguments[i]); - } - } - this.renderOnAddRemove && this.renderAll(); - return this; - }, - forEachObject: function(callback, context) { - var objects = this.getObjects(), i = objects.length; - while (i--) { - callback.call(context, objects[i], i, objects); - } - return this; - }, - getObjects: function(type) { - if (typeof type === "undefined") { - return this._objects; - } - return this._objects.filter(function(o) { - return o.type === type; - }); - }, - item: function(index) { - return this.getObjects()[index]; - }, - isEmpty: function() { - return this.getObjects().length === 0; - }, - size: function() { - return this.getObjects().length; - }, - contains: function(object) { - return this.getObjects().indexOf(object) > -1; - }, - complexity: function() { - return this.getObjects().reduce(function(memo, current) { - memo += current.complexity ? current.complexity() : 0; - return memo; - }, 0); - } -}; - -(function(global) { - var sqrt = Math.sqrt, atan2 = Math.atan2, pow = Math.pow, abs = Math.abs, PiBy180 = Math.PI / 180; - fabric.util = { - removeFromArray: function(array, value) { - var idx = array.indexOf(value); - if (idx !== -1) { - array.splice(idx, 1); - } - return array; - }, - getRandomInt: function(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - }, - degreesToRadians: function(degrees) { - return degrees * PiBy180; - }, - radiansToDegrees: function(radians) { - return radians / PiBy180; - }, - rotatePoint: function(point, origin, radians) { - point.subtractEquals(origin); - var v = fabric.util.rotateVector(point, radians); - return new fabric.Point(v.x, v.y).addEquals(origin); - }, - rotateVector: function(vector, radians) { - var sin = Math.sin(radians), cos = Math.cos(radians), rx = vector.x * cos - vector.y * sin, ry = vector.x * sin + vector.y * cos; - return { - x: rx, - y: ry - }; - }, - transformPoint: function(p, t, ignoreOffset) { - if (ignoreOffset) { - return new fabric.Point(t[0] * p.x + t[2] * p.y, t[1] * p.x + t[3] * p.y); - } - return new fabric.Point(t[0] * p.x + t[2] * p.y + t[4], t[1] * p.x + t[3] * p.y + t[5]); - }, - makeBoundingBoxFromPoints: function(points) { - var xPoints = [ points[0].x, points[1].x, points[2].x, points[3].x ], minX = fabric.util.array.min(xPoints), maxX = fabric.util.array.max(xPoints), width = Math.abs(minX - maxX), yPoints = [ points[0].y, points[1].y, points[2].y, points[3].y ], minY = fabric.util.array.min(yPoints), maxY = fabric.util.array.max(yPoints), height = Math.abs(minY - maxY); - return { - left: minX, - top: minY, - width: width, - height: height - }; - }, - invertTransform: function(t) { - var a = 1 / (t[0] * t[3] - t[1] * t[2]), r = [ a * t[3], -a * t[1], -a * t[2], a * t[0] ], o = fabric.util.transformPoint({ - x: t[4], - y: t[5] - }, r, true); - r[4] = -o.x; - r[5] = -o.y; - return r; - }, - toFixed: function(number, fractionDigits) { - return parseFloat(Number(number).toFixed(fractionDigits)); - }, - parseUnit: function(value, fontSize) { - var unit = /\D{0,2}$/.exec(value), number = parseFloat(value); - if (!fontSize) { - fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; - } - switch (unit[0]) { - case "mm": - return number * fabric.DPI / 25.4; - - case "cm": - return number * fabric.DPI / 2.54; - - case "in": - return number * fabric.DPI; - - case "pt": - return number * fabric.DPI / 72; - - case "pc": - return number * fabric.DPI / 72 * 12; - - case "em": - return number * fontSize; - - default: - return number; - } - }, - falseFunction: function() { - return false; - }, - getKlass: function(type, namespace) { - type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1)); - return fabric.util.resolveNamespace(namespace)[type]; - }, - resolveNamespace: function(namespace) { - if (!namespace) { - return fabric; - } - var parts = namespace.split("."), len = parts.length, obj = global || fabric.window; - for (var i = 0; i < len; ++i) { - obj = obj[parts[i]]; - } - return obj; - }, - loadImage: function(url, callback, context, crossOrigin) { - if (!url) { - callback && callback.call(context, url); - return; - } - var img = fabric.util.createImage(); - img.onload = function() { - callback && callback.call(context, img); - img = img.onload = img.onerror = null; - }; - img.onerror = function() { - fabric.log("Error loading " + img.src); - callback && callback.call(context, null, true); - img = img.onload = img.onerror = null; - }; - if (url.indexOf("data") !== 0 && crossOrigin) { - img.crossOrigin = crossOrigin; - } - img.src = url; - }, - enlivenObjects: function(objects, callback, namespace, reviver) { - objects = objects || []; - function onLoaded() { - if (++numLoadedObjects === numTotalObjects) { - callback && callback(enlivenedObjects); - } - } - var enlivenedObjects = [], numLoadedObjects = 0, numTotalObjects = objects.length; - if (!numTotalObjects) { - callback && callback(enlivenedObjects); - return; - } - objects.forEach(function(o, index) { - if (!o || !o.type) { - onLoaded(); - return; - } - var klass = fabric.util.getKlass(o.type, namespace); - if (klass.async) { - klass.fromObject(o, function(obj, error) { - if (!error) { - enlivenedObjects[index] = obj; - reviver && reviver(o, enlivenedObjects[index]); - } - onLoaded(); - }); - } else { - enlivenedObjects[index] = klass.fromObject(o); - reviver && reviver(o, enlivenedObjects[index]); - onLoaded(); - } - }); - }, - groupSVGElements: function(elements, options, path) { - var object; - object = new fabric.PathGroup(elements, options); - if (typeof path !== "undefined") { - object.setSourcePath(path); - } - return object; - }, - populateWithProperties: function(source, destination, properties) { - if (properties && Object.prototype.toString.call(properties) === "[object Array]") { - for (var i = 0, len = properties.length; i < len; i++) { - if (properties[i] in source) { - destination[properties[i]] = source[properties[i]]; - } - } - } - }, - drawDashedLine: function(ctx, x, y, x2, y2, da) { - var dx = x2 - x, dy = y2 - y, len = sqrt(dx * dx + dy * dy), rot = atan2(dy, dx), dc = da.length, di = 0, draw = true; - ctx.save(); - ctx.translate(x, y); - ctx.moveTo(0, 0); - ctx.rotate(rot); - x = 0; - while (len > x) { - x += da[di++ % dc]; - if (x > len) { - x = len; - } - ctx[draw ? "lineTo" : "moveTo"](x, 0); - draw = !draw; - } - ctx.restore(); - }, - createCanvasElement: function(canvasEl) { - canvasEl || (canvasEl = fabric.document.createElement("canvas")); - if (!canvasEl.getContext && typeof G_vmlCanvasManager !== "undefined") { - G_vmlCanvasManager.initElement(canvasEl); - } - return canvasEl; - }, - createImage: function() { - return fabric.isLikelyNode ? new (require("canvas").Image)() : fabric.document.createElement("img"); - }, - createAccessors: function(klass) { - var proto = klass.prototype; - for (var i = proto.stateProperties.length; i--; ) { - var propName = proto.stateProperties[i], capitalizedPropName = propName.charAt(0).toUpperCase() + propName.slice(1), setterName = "set" + capitalizedPropName, getterName = "get" + capitalizedPropName; - if (!proto[getterName]) { - proto[getterName] = function(property) { - return new Function('return this.get("' + property + '")'); - }(propName); - } - if (!proto[setterName]) { - proto[setterName] = function(property) { - return new Function("value", 'return this.set("' + property + '", value)'); - }(propName); - } - } - }, - clipContext: function(receiver, ctx) { - ctx.save(); - ctx.beginPath(); - receiver.clipTo(ctx); - ctx.clip(); - }, - multiplyTransformMatrices: function(a, b, is2x2) { - return [ a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4], is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5] ]; - }, - qrDecompose: function(a) { - var angle = atan2(a[1], a[0]), denom = pow(a[0], 2) + pow(a[1], 2), scaleX = sqrt(denom), scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX, skewX = atan2(a[0] * a[2] + a[1] * a[3], denom); - return { - angle: angle / PiBy180, - scaleX: scaleX, - scaleY: scaleY, - skewX: skewX / PiBy180, - skewY: 0, - translateX: a[4], - translateY: a[5] - }; - }, - customTransformMatrix: function(scaleX, scaleY, skewX) { - var skewMatrixX = [ 1, 0, abs(Math.tan(skewX * PiBy180)), 1 ], scaleMatrix = [ abs(scaleX), 0, 0, abs(scaleY) ]; - return fabric.util.multiplyTransformMatrices(scaleMatrix, skewMatrixX, true); - }, - resetObjectTransform: function(target) { - target.scaleX = 1; - target.scaleY = 1; - target.skewX = 0; - target.skewY = 0; - target.flipX = false; - target.flipY = false; - target.setAngle(0); - }, - getFunctionBody: function(fn) { - return (String(fn).match(/function[^{]*\{([\s\S]*)\}/) || {})[1]; - }, - isTransparent: function(ctx, x, y, tolerance) { - if (tolerance > 0) { - if (x > tolerance) { - x -= tolerance; - } else { - x = 0; - } - if (y > tolerance) { - y -= tolerance; - } else { - y = 0; - } - } - var _isTransparent = true, imageData = ctx.getImageData(x, y, tolerance * 2 || 1, tolerance * 2 || 1); - for (var i = 3, l = imageData.data.length; i < l; i += 4) { - var temp = imageData.data[i]; - _isTransparent = temp <= 0; - if (_isTransparent === false) { - break; - } - } - imageData = null; - return _isTransparent; - }, - parsePreserveAspectRatioAttribute: function(attribute) { - var meetOrSlice = "meet", alignX = "Mid", alignY = "Mid", aspectRatioAttrs = attribute.split(" "), align; - if (aspectRatioAttrs && aspectRatioAttrs.length) { - meetOrSlice = aspectRatioAttrs.pop(); - if (meetOrSlice !== "meet" && meetOrSlice !== "slice") { - align = meetOrSlice; - meetOrSlice = "meet"; - } else if (aspectRatioAttrs.length) { - align = aspectRatioAttrs.pop(); - } - } - alignX = align !== "none" ? align.slice(1, 4) : "none"; - alignY = align !== "none" ? align.slice(5, 8) : "none"; - return { - meetOrSlice: meetOrSlice, - alignX: alignX, - alignY: alignY - }; - } - }; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - var arcToSegmentsCache = {}, segmentToBezierCache = {}, boundsOfCurveCache = {}, _join = Array.prototype.join; - function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) { - var argsString = _join.call(arguments); - if (arcToSegmentsCache[argsString]) { - return arcToSegmentsCache[argsString]; - } - var PI = Math.PI, th = rotateX * PI / 180, sinTh = Math.sin(th), cosTh = Math.cos(th), fromX = 0, fromY = 0; - rx = Math.abs(rx); - ry = Math.abs(ry); - var px = -cosTh * toX * .5 - sinTh * toY * .5, py = -cosTh * toY * .5 + sinTh * toX * .5, rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px, pl = rx2 * ry2 - rx2 * py2 - ry2 * px2, root = 0; - if (pl < 0) { - var s = Math.sqrt(1 - pl / (rx2 * ry2)); - rx *= s; - ry *= s; - } else { - root = (large === sweep ? -1 : 1) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2)); - } - var cx = root * rx * py / ry, cy = -root * ry * px / rx, cx1 = cosTh * cx - sinTh * cy + toX * .5, cy1 = sinTh * cx + cosTh * cy + toY * .5, mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry), dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry); - if (sweep === 0 && dtheta > 0) { - dtheta -= 2 * PI; - } else if (sweep === 1 && dtheta < 0) { - dtheta += 2 * PI; - } - var segments = Math.ceil(Math.abs(dtheta / PI * 2)), result = [], mDelta = dtheta / segments, mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2), th3 = mTheta + mDelta; - for (var i = 0; i < segments; i++) { - result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY); - fromX = result[i][4]; - fromY = result[i][5]; - mTheta = th3; - th3 += mDelta; - } - arcToSegmentsCache[argsString] = result; - return result; - } - function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) { - var argsString2 = _join.call(arguments); - if (segmentToBezierCache[argsString2]) { - return segmentToBezierCache[argsString2]; - } - var costh2 = Math.cos(th2), sinth2 = Math.sin(th2), costh3 = Math.cos(th3), sinth3 = Math.sin(th3), toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1, toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1, cp1X = fromX + mT * (-cosTh * rx * sinth2 - sinTh * ry * costh2), cp1Y = fromY + mT * (-sinTh * rx * sinth2 + cosTh * ry * costh2), cp2X = toX + mT * (cosTh * rx * sinth3 + sinTh * ry * costh3), cp2Y = toY + mT * (sinTh * rx * sinth3 - cosTh * ry * costh3); - segmentToBezierCache[argsString2] = [ cp1X, cp1Y, cp2X, cp2Y, toX, toY ]; - return segmentToBezierCache[argsString2]; - } - function calcVectorAngle(ux, uy, vx, vy) { - var ta = Math.atan2(uy, ux), tb = Math.atan2(vy, vx); - if (tb >= ta) { - return tb - ta; - } else { - return 2 * Math.PI - (ta - tb); - } - } - fabric.util.drawArc = function(ctx, fx, fy, coords) { - var rx = coords[0], ry = coords[1], rot = coords[2], large = coords[3], sweep = coords[4], tx = coords[5], ty = coords[6], segs = [ [], [], [], [] ], segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); - for (var i = 0, len = segsNorm.length; i < len; i++) { - segs[i][0] = segsNorm[i][0] + fx; - segs[i][1] = segsNorm[i][1] + fy; - segs[i][2] = segsNorm[i][2] + fx; - segs[i][3] = segsNorm[i][3] + fy; - segs[i][4] = segsNorm[i][4] + fx; - segs[i][5] = segsNorm[i][5] + fy; - ctx.bezierCurveTo.apply(ctx, segs[i]); - } - }; - fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) { - var fromX = 0, fromY = 0, bound = [], bounds = [], segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot), boundCopy = [ [], [] ]; - for (var i = 0, len = segs.length; i < len; i++) { - bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]); - boundCopy[0].x = bound[0].x + fx; - boundCopy[0].y = bound[0].y + fy; - boundCopy[1].x = bound[1].x + fx; - boundCopy[1].y = bound[1].y + fy; - bounds.push(boundCopy[0]); - bounds.push(boundCopy[1]); - fromX = segs[i][4]; - fromY = segs[i][5]; - } - return bounds; - }; - function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) { - var argsString = _join.call(arguments); - if (boundsOfCurveCache[argsString]) { - return boundsOfCurveCache[argsString]; - } - var sqrt = Math.sqrt, min = Math.min, max = Math.max, abs = Math.abs, tvalues = [], bounds = [ [], [] ], a, b, c, t, t1, t2, b2ac, sqrtb2ac; - b = 6 * x0 - 12 * x1 + 6 * x2; - a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; - c = 3 * x1 - 3 * x0; - for (var i = 0; i < 2; ++i) { - if (i > 0) { - b = 6 * y0 - 12 * y1 + 6 * y2; - a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; - c = 3 * y1 - 3 * y0; - } - if (abs(a) < 1e-12) { - if (abs(b) < 1e-12) { - continue; - } - t = -c / b; - if (0 < t && t < 1) { - tvalues.push(t); - } - continue; - } - b2ac = b * b - 4 * c * a; - if (b2ac < 0) { - continue; - } - sqrtb2ac = sqrt(b2ac); - t1 = (-b + sqrtb2ac) / (2 * a); - if (0 < t1 && t1 < 1) { - tvalues.push(t1); - } - t2 = (-b - sqrtb2ac) / (2 * a); - if (0 < t2 && t2 < 1) { - tvalues.push(t2); - } - } - var x, y, j = tvalues.length, jlen = j, mt; - while (j--) { - t = tvalues[j]; - mt = 1 - t; - x = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; - bounds[0][j] = x; - y = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; - bounds[1][j] = y; - } - bounds[0][jlen] = x0; - bounds[1][jlen] = y0; - bounds[0][jlen + 1] = x3; - bounds[1][jlen + 1] = y3; - var result = [ { - x: min.apply(null, bounds[0]), - y: min.apply(null, bounds[1]) - }, { - x: max.apply(null, bounds[0]), - y: max.apply(null, bounds[1]) - } ]; - boundsOfCurveCache[argsString] = result; - return result; - } - fabric.util.getBoundsOfCurve = getBoundsOfCurve; -})(); - -(function() { - var slice = Array.prototype.slice; - if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function(searchElement) { - if (this === void 0 || this === null) { - throw new TypeError(); - } - var t = Object(this), len = t.length >>> 0; - if (len === 0) { - return -1; - } - var n = 0; - if (arguments.length > 0) { - n = Number(arguments[1]); - if (n !== n) { - n = 0; - } else if (n !== 0 && n !== Number.POSITIVE_INFINITY && n !== Number.NEGATIVE_INFINITY) { - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - } - if (n >= len) { - return -1; - } - var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); - for (;k < len; k++) { - if (k in t && t[k] === searchElement) { - return k; - } - } - return -1; - }; - } - if (!Array.prototype.forEach) { - Array.prototype.forEach = function(fn, context) { - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this) { - fn.call(context, this[i], i, this); - } - } - }; - } - if (!Array.prototype.map) { - Array.prototype.map = function(fn, context) { - var result = []; - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this) { - result[i] = fn.call(context, this[i], i, this); - } - } - return result; - }; - } - if (!Array.prototype.every) { - Array.prototype.every = function(fn, context) { - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this && !fn.call(context, this[i], i, this)) { - return false; - } - } - return true; - }; - } - if (!Array.prototype.some) { - Array.prototype.some = function(fn, context) { - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this && fn.call(context, this[i], i, this)) { - return true; - } - } - return false; - }; - } - if (!Array.prototype.filter) { - Array.prototype.filter = function(fn, context) { - var result = [], val; - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this) { - val = this[i]; - if (fn.call(context, val, i, this)) { - result.push(val); - } - } - } - return result; - }; - } - if (!Array.prototype.reduce) { - Array.prototype.reduce = function(fn) { - var len = this.length >>> 0, i = 0, rv; - if (arguments.length > 1) { - rv = arguments[1]; - } else { - do { - if (i in this) { - rv = this[i++]; - break; - } - if (++i >= len) { - throw new TypeError(); - } - } while (true); - } - for (;i < len; i++) { - if (i in this) { - rv = fn.call(null, rv, this[i], i, this); - } - } - return rv; - }; - } - function invoke(array, method) { - var args = slice.call(arguments, 2), result = []; - for (var i = 0, len = array.length; i < len; i++) { - result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]); - } - return result; - } - function max(array, byProperty) { - return find(array, byProperty, function(value1, value2) { - return value1 >= value2; - }); - } - function min(array, byProperty) { - return find(array, byProperty, function(value1, value2) { - return value1 < value2; - }); - } - function fill(array, value) { - var k = array.length; - while (k--) { - array[k] = value; - } - return array; - } - function find(array, byProperty, condition) { - if (!array || array.length === 0) { - return; - } - var i = array.length - 1, result = byProperty ? array[i][byProperty] : array[i]; - if (byProperty) { - while (i--) { - if (condition(array[i][byProperty], result)) { - result = array[i][byProperty]; - } - } - } else { - while (i--) { - if (condition(array[i], result)) { - result = array[i]; - } - } - } - return result; - } - fabric.util.array = { - fill: fill, - invoke: invoke, - min: min, - max: max - }; -})(); - -(function() { - function extend(destination, source) { - for (var property in source) { - destination[property] = source[property]; - } - return destination; - } - function clone(object) { - return extend({}, object); - } - fabric.util.object = { - extend: extend, - clone: clone - }; -})(); - -(function() { - if (!String.prototype.trim) { - String.prototype.trim = function() { - return this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""); - }; - } - function camelize(string) { - return string.replace(/-+(.)?/g, function(match, character) { - return character ? character.toUpperCase() : ""; - }); - } - function capitalize(string, firstLetterOnly) { - return string.charAt(0).toUpperCase() + (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()); - } - function escapeXml(string) { - return string.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(//g, ">"); - } - fabric.util.string = { - camelize: camelize, - capitalize: capitalize, - escapeXml: escapeXml - }; -})(); - -(function() { - var slice = Array.prototype.slice, apply = Function.prototype.apply, Dummy = function() {}; - if (!Function.prototype.bind) { - Function.prototype.bind = function(thisArg) { - var _this = this, args = slice.call(arguments, 1), bound; - if (args.length) { - bound = function() { - return apply.call(_this, this instanceof Dummy ? this : thisArg, args.concat(slice.call(arguments))); - }; - } else { - bound = function() { - return apply.call(_this, this instanceof Dummy ? this : thisArg, arguments); - }; - } - Dummy.prototype = this.prototype; - bound.prototype = new Dummy(); - return bound; - }; - } -})(); - -(function() { - var slice = Array.prototype.slice, emptyFunction = function() {}, IS_DONTENUM_BUGGY = function() { - for (var p in { - toString: 1 - }) { - if (p === "toString") { - return false; - } - } - return true; - }(), addMethods = function(klass, source, parent) { - for (var property in source) { - if (property in klass.prototype && typeof klass.prototype[property] === "function" && (source[property] + "").indexOf("callSuper") > -1) { - klass.prototype[property] = function(property) { - return function() { - var superclass = this.constructor.superclass; - this.constructor.superclass = parent; - var returnValue = source[property].apply(this, arguments); - this.constructor.superclass = superclass; - if (property !== "initialize") { - return returnValue; - } - }; - }(property); - } else { - klass.prototype[property] = source[property]; - } - if (IS_DONTENUM_BUGGY) { - if (source.toString !== Object.prototype.toString) { - klass.prototype.toString = source.toString; - } - if (source.valueOf !== Object.prototype.valueOf) { - klass.prototype.valueOf = source.valueOf; - } - } - } - }; - function Subclass() {} - function callSuper(methodName) { - var fn = this.constructor.superclass.prototype[methodName]; - return arguments.length > 1 ? fn.apply(this, slice.call(arguments, 1)) : fn.call(this); - } - function createClass() { - var parent = null, properties = slice.call(arguments, 0); - if (typeof properties[0] === "function") { - parent = properties.shift(); - } - function klass() { - this.initialize.apply(this, arguments); - } - klass.superclass = parent; - klass.subclasses = []; - if (parent) { - Subclass.prototype = parent.prototype; - klass.prototype = new Subclass(); - parent.subclasses.push(klass); - } - for (var i = 0, length = properties.length; i < length; i++) { - addMethods(klass, properties[i], parent); - } - if (!klass.prototype.initialize) { - klass.prototype.initialize = emptyFunction; - } - klass.prototype.constructor = klass; - klass.prototype.callSuper = callSuper; - return klass; - } - fabric.util.createClass = createClass; -})(); - -(function() { - var unknown = "unknown"; - function areHostMethods(object) { - var methodNames = Array.prototype.slice.call(arguments, 1), t, i, len = methodNames.length; - for (i = 0; i < len; i++) { - t = typeof object[methodNames[i]]; - if (!/^(?:function|object|unknown)$/.test(t)) { - return false; - } - } - return true; - } - var getElement, setElement, getUniqueId = function() { - var uid = 0; - return function(element) { - return element.__uniqueID || (element.__uniqueID = "uniqueID__" + uid++); - }; - }(); - (function() { - var elements = {}; - getElement = function(uid) { - return elements[uid]; - }; - setElement = function(uid, element) { - elements[uid] = element; - }; - })(); - function createListener(uid, handler) { - return { - handler: handler, - wrappedHandler: createWrappedHandler(uid, handler) - }; - } - function createWrappedHandler(uid, handler) { - return function(e) { - handler.call(getElement(uid), e || fabric.window.event); - }; - } - function createDispatcher(uid, eventName) { - return function(e) { - if (handlers[uid] && handlers[uid][eventName]) { - var handlersForEvent = handlers[uid][eventName]; - for (var i = 0, len = handlersForEvent.length; i < len; i++) { - handlersForEvent[i].call(this, e || fabric.window.event); - } - } - }; - } - var shouldUseAddListenerRemoveListener = areHostMethods(fabric.document.documentElement, "addEventListener", "removeEventListener") && areHostMethods(fabric.window, "addEventListener", "removeEventListener"), shouldUseAttachEventDetachEvent = areHostMethods(fabric.document.documentElement, "attachEvent", "detachEvent") && areHostMethods(fabric.window, "attachEvent", "detachEvent"), listeners = {}, handlers = {}, addListener, removeListener; - if (shouldUseAddListenerRemoveListener) { - addListener = function(element, eventName, handler) { - element.addEventListener(eventName, handler, false); - }; - removeListener = function(element, eventName, handler) { - element.removeEventListener(eventName, handler, false); - }; - } else if (shouldUseAttachEventDetachEvent) { - addListener = function(element, eventName, handler) { - var uid = getUniqueId(element); - setElement(uid, element); - if (!listeners[uid]) { - listeners[uid] = {}; - } - if (!listeners[uid][eventName]) { - listeners[uid][eventName] = []; - } - var listener = createListener(uid, handler); - listeners[uid][eventName].push(listener); - element.attachEvent("on" + eventName, listener.wrappedHandler); - }; - removeListener = function(element, eventName, handler) { - var uid = getUniqueId(element), listener; - if (listeners[uid] && listeners[uid][eventName]) { - for (var i = 0, len = listeners[uid][eventName].length; i < len; i++) { - listener = listeners[uid][eventName][i]; - if (listener && listener.handler === handler) { - element.detachEvent("on" + eventName, listener.wrappedHandler); - listeners[uid][eventName][i] = null; - } - } - } - }; - } else { - addListener = function(element, eventName, handler) { - var uid = getUniqueId(element); - if (!handlers[uid]) { - handlers[uid] = {}; - } - if (!handlers[uid][eventName]) { - handlers[uid][eventName] = []; - var existingHandler = element["on" + eventName]; - if (existingHandler) { - handlers[uid][eventName].push(existingHandler); - } - element["on" + eventName] = createDispatcher(uid, eventName); - } - handlers[uid][eventName].push(handler); - }; - removeListener = function(element, eventName, handler) { - var uid = getUniqueId(element); - if (handlers[uid] && handlers[uid][eventName]) { - var handlersForEvent = handlers[uid][eventName]; - for (var i = 0, len = handlersForEvent.length; i < len; i++) { - if (handlersForEvent[i] === handler) { - handlersForEvent.splice(i, 1); - } - } - } - }; - } - fabric.util.addListener = addListener; - fabric.util.removeListener = removeListener; - function getPointer(event) { - event || (event = fabric.window.event); - var element = event.target || (typeof event.srcElement !== unknown ? event.srcElement : null), scroll = fabric.util.getScrollLeftTop(element); - return { - x: pointerX(event) + scroll.left, - y: pointerY(event) + scroll.top - }; - } - var pointerX = function(event) { - return typeof event.clientX !== unknown ? event.clientX : 0; - }, pointerY = function(event) { - return typeof event.clientY !== unknown ? event.clientY : 0; - }; - function _getPointer(event, pageProp, clientProp) { - var touchProp = event.type === "touchend" ? "changedTouches" : "touches"; - return event[touchProp] && event[touchProp][0] ? event[touchProp][0][pageProp] - (event[touchProp][0][pageProp] - event[touchProp][0][clientProp]) || event[clientProp] : event[clientProp]; - } - if (fabric.isTouchSupported) { - pointerX = function(event) { - return _getPointer(event, "pageX", "clientX"); - }; - pointerY = function(event) { - return _getPointer(event, "pageY", "clientY"); - }; - } - fabric.util.getPointer = getPointer; - fabric.util.object.extend(fabric.util, fabric.Observable); -})(); - -(function() { - function setStyle(element, styles) { - var elementStyle = element.style; - if (!elementStyle) { - return element; - } - if (typeof styles === "string") { - element.style.cssText += ";" + styles; - return styles.indexOf("opacity") > -1 ? setOpacity(element, styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; - } - for (var property in styles) { - if (property === "opacity") { - setOpacity(element, styles[property]); - } else { - var normalizedProperty = property === "float" || property === "cssFloat" ? typeof elementStyle.styleFloat === "undefined" ? "cssFloat" : "styleFloat" : property; - elementStyle[normalizedProperty] = styles[property]; - } - } - return element; - } - var parseEl = fabric.document.createElement("div"), supportsOpacity = typeof parseEl.style.opacity === "string", supportsFilters = typeof parseEl.style.filter === "string", reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/, setOpacity = function(element) { - return element; - }; - if (supportsOpacity) { - setOpacity = function(element, value) { - element.style.opacity = value; - return element; - }; - } else if (supportsFilters) { - setOpacity = function(element, value) { - var es = element.style; - if (element.currentStyle && !element.currentStyle.hasLayout) { - es.zoom = 1; - } - if (reOpacity.test(es.filter)) { - value = value >= .9999 ? "" : "alpha(opacity=" + value * 100 + ")"; - es.filter = es.filter.replace(reOpacity, value); - } else { - es.filter += " alpha(opacity=" + value * 100 + ")"; - } - return element; - }; - } - fabric.util.setStyle = setStyle; -})(); - -(function() { - var _slice = Array.prototype.slice; - function getById(id) { - return typeof id === "string" ? fabric.document.getElementById(id) : id; - } - var sliceCanConvertNodelists, toArray = function(arrayLike) { - return _slice.call(arrayLike, 0); - }; - try { - sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array; - } catch (err) {} - if (!sliceCanConvertNodelists) { - toArray = function(arrayLike) { - var arr = new Array(arrayLike.length), i = arrayLike.length; - while (i--) { - arr[i] = arrayLike[i]; - } - return arr; - }; - } - function makeElement(tagName, attributes) { - var el = fabric.document.createElement(tagName); - for (var prop in attributes) { - if (prop === "class") { - el.className = attributes[prop]; - } else if (prop === "for") { - el.htmlFor = attributes[prop]; - } else { - el.setAttribute(prop, attributes[prop]); - } - } - return el; - } - function addClass(element, className) { - if (element && (" " + element.className + " ").indexOf(" " + className + " ") === -1) { - element.className += (element.className ? " " : "") + className; - } - } - function wrapElement(element, wrapper, attributes) { - if (typeof wrapper === "string") { - wrapper = makeElement(wrapper, attributes); - } - if (element.parentNode) { - element.parentNode.replaceChild(wrapper, element); - } - wrapper.appendChild(element); - return wrapper; - } - function getScrollLeftTop(element) { - var left = 0, top = 0, docElement = fabric.document.documentElement, body = fabric.document.body || { - scrollLeft: 0, - scrollTop: 0 - }; - while (element && (element.parentNode || element.host)) { - element = element.parentNode || element.host; - if (element === fabric.document) { - left = body.scrollLeft || docElement.scrollLeft || 0; - top = body.scrollTop || docElement.scrollTop || 0; - } else { - left += element.scrollLeft || 0; - top += element.scrollTop || 0; - } - if (element.nodeType === 1 && fabric.util.getElementStyle(element, "position") === "fixed") { - break; - } - } - return { - left: left, - top: top - }; - } - function getElementOffset(element) { - var docElem, doc = element && element.ownerDocument, box = { - left: 0, - top: 0 - }, offset = { - left: 0, - top: 0 - }, scrollLeftTop, offsetAttributes = { - borderLeftWidth: "left", - borderTopWidth: "top", - paddingLeft: "left", - paddingTop: "top" - }; - if (!doc) { - return offset; - } - for (var attr in offsetAttributes) { - offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0; - } - docElem = doc.documentElement; - if (typeof element.getBoundingClientRect !== "undefined") { - box = element.getBoundingClientRect(); - } - scrollLeftTop = getScrollLeftTop(element); - return { - left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left, - top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top - }; - } - var getElementStyle; - if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) { - getElementStyle = function(element, attr) { - var style = fabric.document.defaultView.getComputedStyle(element, null); - return style ? style[attr] : undefined; - }; - } else { - getElementStyle = function(element, attr) { - var value = element.style[attr]; - if (!value && element.currentStyle) { - value = element.currentStyle[attr]; - } - return value; - }; - } - (function() { - var style = fabric.document.documentElement.style, selectProp = "userSelect" in style ? "userSelect" : "MozUserSelect" in style ? "MozUserSelect" : "WebkitUserSelect" in style ? "WebkitUserSelect" : "KhtmlUserSelect" in style ? "KhtmlUserSelect" : ""; - function makeElementUnselectable(element) { - if (typeof element.onselectstart !== "undefined") { - element.onselectstart = fabric.util.falseFunction; - } - if (selectProp) { - element.style[selectProp] = "none"; - } else if (typeof element.unselectable === "string") { - element.unselectable = "on"; - } - return element; - } - function makeElementSelectable(element) { - if (typeof element.onselectstart !== "undefined") { - element.onselectstart = null; - } - if (selectProp) { - element.style[selectProp] = ""; - } else if (typeof element.unselectable === "string") { - element.unselectable = ""; - } - return element; - } - fabric.util.makeElementUnselectable = makeElementUnselectable; - fabric.util.makeElementSelectable = makeElementSelectable; - })(); - (function() { - function getScript(url, callback) { - var headEl = fabric.document.getElementsByTagName("head")[0], scriptEl = fabric.document.createElement("script"), loading = true; - scriptEl.onload = scriptEl.onreadystatechange = function(e) { - if (loading) { - if (typeof this.readyState === "string" && this.readyState !== "loaded" && this.readyState !== "complete") { - return; - } - loading = false; - callback(e || fabric.window.event); - scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null; - } - }; - scriptEl.src = url; - headEl.appendChild(scriptEl); - } - fabric.util.getScript = getScript; - })(); - fabric.util.getById = getById; - fabric.util.toArray = toArray; - fabric.util.makeElement = makeElement; - fabric.util.addClass = addClass; - fabric.util.wrapElement = wrapElement; - fabric.util.getScrollLeftTop = getScrollLeftTop; - fabric.util.getElementOffset = getElementOffset; - fabric.util.getElementStyle = getElementStyle; -})(); - -(function() { - function addParamToUrl(url, param) { - return url + (/\?/.test(url) ? "&" : "?") + param; - } - var makeXHR = function() { - var factories = [ function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }, function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }, function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }, function() { - return new XMLHttpRequest(); - } ]; - for (var i = factories.length; i--; ) { - try { - var req = factories[i](); - if (req) { - return factories[i]; - } - } catch (err) {} - } - }(); - function emptyFn() {} - function request(url, options) { - options || (options = {}); - var method = options.method ? options.method.toUpperCase() : "GET", onComplete = options.onComplete || function() {}, xhr = makeXHR(), body; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - onComplete(xhr); - xhr.onreadystatechange = emptyFn; - } - }; - if (method === "GET") { - body = null; - if (typeof options.parameters === "string") { - url = addParamToUrl(url, options.parameters); - } - } - xhr.open(method, url, true); - if (method === "POST" || method === "PUT") { - xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); - } - xhr.send(body); - return xhr; - } - fabric.util.request = request; -})(); - -fabric.log = function() {}; - -fabric.warn = function() {}; - -if (typeof console !== "undefined") { - [ "log", "warn" ].forEach(function(methodName) { - if (typeof console[methodName] !== "undefined" && typeof console[methodName].apply === "function") { - fabric[methodName] = function() { - return console[methodName].apply(console, arguments); - }; - } - }); -} - -(function() { - function animate(options) { - requestAnimFrame(function(timestamp) { - options || (options = {}); - var start = timestamp || +new Date(), duration = options.duration || 500, finish = start + duration, time, onChange = options.onChange || function() {}, abort = options.abort || function() { - return false; - }, easing = options.easing || function(t, b, c, d) { - return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; - }, startValue = "startValue" in options ? options.startValue : 0, endValue = "endValue" in options ? options.endValue : 100, byValue = options.byValue || endValue - startValue; - options.onStart && options.onStart(); - (function tick(ticktime) { - time = ticktime || +new Date(); - var currentTime = time > finish ? duration : time - start; - if (abort()) { - options.onComplete && options.onComplete(); - return; - } - onChange(easing(currentTime, startValue, byValue, duration)); - if (time > finish) { - options.onComplete && options.onComplete(); - return; - } - requestAnimFrame(tick); - })(start); - }); - } - var _requestAnimFrame = fabric.window.requestAnimationFrame || fabric.window.webkitRequestAnimationFrame || fabric.window.mozRequestAnimationFrame || fabric.window.oRequestAnimationFrame || fabric.window.msRequestAnimationFrame || function(callback) { - fabric.window.setTimeout(callback, 1e3 / 60); - }; - function requestAnimFrame() { - return _requestAnimFrame.apply(fabric.window, arguments); - } - fabric.util.animate = animate; - fabric.util.requestAnimFrame = requestAnimFrame; -})(); - -(function() { - function normalize(a, c, p, s) { - if (a < Math.abs(c)) { - a = c; - s = p / 4; - } else { - if (c === 0 && a === 0) { - s = p / (2 * Math.PI) * Math.asin(1); - } else { - s = p / (2 * Math.PI) * Math.asin(c / a); - } - } - return { - a: a, - c: c, - p: p, - s: s - }; - } - function elastic(opts, t, d) { - return opts.a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p); - } - function easeOutCubic(t, b, c, d) { - return c * ((t = t / d - 1) * t * t + 1) + b; - } - function easeInOutCubic(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t + b; - } - return c / 2 * ((t -= 2) * t * t + 2) + b; - } - function easeInQuart(t, b, c, d) { - return c * (t /= d) * t * t * t + b; - } - function easeOutQuart(t, b, c, d) { - return -c * ((t = t / d - 1) * t * t * t - 1) + b; - } - function easeInOutQuart(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t * t + b; - } - return -c / 2 * ((t -= 2) * t * t * t - 2) + b; - } - function easeInQuint(t, b, c, d) { - return c * (t /= d) * t * t * t * t + b; - } - function easeOutQuint(t, b, c, d) { - return c * ((t = t / d - 1) * t * t * t * t + 1) + b; - } - function easeInOutQuint(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t * t * t + b; - } - return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; - } - function easeInSine(t, b, c, d) { - return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; - } - function easeOutSine(t, b, c, d) { - return c * Math.sin(t / d * (Math.PI / 2)) + b; - } - function easeInOutSine(t, b, c, d) { - return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; - } - function easeInExpo(t, b, c, d) { - return t === 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; - } - function easeOutExpo(t, b, c, d) { - return t === d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; - } - function easeInOutExpo(t, b, c, d) { - if (t === 0) { - return b; - } - if (t === d) { - return b + c; - } - t /= d / 2; - if (t < 1) { - return c / 2 * Math.pow(2, 10 * (t - 1)) + b; - } - return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; - } - function easeInCirc(t, b, c, d) { - return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; - } - function easeOutCirc(t, b, c, d) { - return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; - } - function easeInOutCirc(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; - } - return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; - } - function easeInElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d; - if (t === 1) { - return b + c; - } - if (!p) { - p = d * .3; - } - var opts = normalize(a, c, p, s); - return -elastic(opts, t, d) + b; - } - function easeOutElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d; - if (t === 1) { - return b + c; - } - if (!p) { - p = d * .3; - } - var opts = normalize(a, c, p, s); - return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p) + opts.c + b; - } - function easeInOutElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d / 2; - if (t === 2) { - return b + c; - } - if (!p) { - p = d * (.3 * 1.5); - } - var opts = normalize(a, c, p, s); - if (t < 1) { - return -.5 * elastic(opts, t, d) + b; - } - return opts.a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p) * .5 + opts.c + b; - } - function easeInBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - return c * (t /= d) * t * ((s + 1) * t - s) + b; - } - function easeOutBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; - } - function easeInOutBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - t /= d / 2; - if (t < 1) { - return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b; - } - return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b; - } - function easeInBounce(t, b, c, d) { - return c - easeOutBounce(d - t, 0, c, d) + b; - } - function easeOutBounce(t, b, c, d) { - if ((t /= d) < 1 / 2.75) { - return c * (7.5625 * t * t) + b; - } else if (t < 2 / 2.75) { - return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b; - } else if (t < 2.5 / 2.75) { - return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b; - } else { - return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b; - } - } - function easeInOutBounce(t, b, c, d) { - if (t < d / 2) { - return easeInBounce(t * 2, 0, c, d) * .5 + b; - } - return easeOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b; - } - fabric.util.ease = { - easeInQuad: function(t, b, c, d) { - return c * (t /= d) * t + b; - }, - easeOutQuad: function(t, b, c, d) { - return -c * (t /= d) * (t - 2) + b; - }, - easeInOutQuad: function(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t + b; - } - return -c / 2 * (--t * (t - 2) - 1) + b; - }, - easeInCubic: function(t, b, c, d) { - return c * (t /= d) * t * t + b; - }, - easeOutCubic: easeOutCubic, - easeInOutCubic: easeInOutCubic, - easeInQuart: easeInQuart, - easeOutQuart: easeOutQuart, - easeInOutQuart: easeInOutQuart, - easeInQuint: easeInQuint, - easeOutQuint: easeOutQuint, - easeInOutQuint: easeInOutQuint, - easeInSine: easeInSine, - easeOutSine: easeOutSine, - easeInOutSine: easeInOutSine, - easeInExpo: easeInExpo, - easeOutExpo: easeOutExpo, - easeInOutExpo: easeInOutExpo, - easeInCirc: easeInCirc, - easeOutCirc: easeOutCirc, - easeInOutCirc: easeInOutCirc, - easeInElastic: easeInElastic, - easeOutElastic: easeOutElastic, - easeInOutElastic: easeInOutElastic, - easeInBack: easeInBack, - easeOutBack: easeOutBack, - easeInOutBack: easeInOutBack, - easeInBounce: easeInBounce, - easeOutBounce: easeOutBounce, - easeInOutBounce: easeInOutBounce - }; -})(); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, capitalize = fabric.util.string.capitalize, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, parseUnit = fabric.util.parseUnit, multiplyTransformMatrices = fabric.util.multiplyTransformMatrices, reAllowedSVGTagNames = /^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i, reViewBoxTagNames = /^(symbol|image|marker|pattern|view|svg)$/i, reNotAllowedAncestors = /^(?:pattern|defs|symbol|metadata)$/i, reAllowedParents = /^(symbol|g|a|svg)$/i, attributesMap = { - cx: "left", - x: "left", - r: "radius", - cy: "top", - y: "top", - display: "visible", - visibility: "visible", - transform: "transformMatrix", - "fill-opacity": "fillOpacity", - "fill-rule": "fillRule", - "font-family": "fontFamily", - "font-size": "fontSize", - "font-style": "fontStyle", - "font-weight": "fontWeight", - "stroke-dasharray": "strokeDashArray", - "stroke-linecap": "strokeLineCap", - "stroke-linejoin": "strokeLineJoin", - "stroke-miterlimit": "strokeMiterLimit", - "stroke-opacity": "strokeOpacity", - "stroke-width": "strokeWidth", - "text-decoration": "textDecoration", - "text-anchor": "originX" - }, colorAttributes = { - stroke: "strokeOpacity", - fill: "fillOpacity" - }; - fabric.cssRules = {}; - fabric.gradientDefs = {}; - function normalizeAttr(attr) { - if (attr in attributesMap) { - return attributesMap[attr]; - } - return attr; - } - function normalizeValue(attr, value, parentAttributes, fontSize) { - var isArray = Object.prototype.toString.call(value) === "[object Array]", parsed; - if ((attr === "fill" || attr === "stroke") && value === "none") { - value = ""; - } else if (attr === "strokeDashArray") { - value = value.replace(/,/g, " ").split(/\s+/).map(function(n) { - return parseFloat(n); - }); - } else if (attr === "transformMatrix") { - if (parentAttributes && parentAttributes.transformMatrix) { - value = multiplyTransformMatrices(parentAttributes.transformMatrix, fabric.parseTransformAttribute(value)); - } else { - value = fabric.parseTransformAttribute(value); - } - } else if (attr === "visible") { - value = value === "none" || value === "hidden" ? false : true; - if (parentAttributes && parentAttributes.visible === false) { - value = false; - } - } else if (attr === "originX") { - value = value === "start" ? "left" : value === "end" ? "right" : "center"; - } else { - parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize); - } - return !isArray && isNaN(parsed) ? value : parsed; - } - function _setStrokeFillOpacity(attributes) { - for (var attr in colorAttributes) { - if (typeof attributes[colorAttributes[attr]] === "undefined" || attributes[attr] === "") { - continue; - } - if (typeof attributes[attr] === "undefined") { - if (!fabric.Object.prototype[attr]) { - continue; - } - attributes[attr] = fabric.Object.prototype[attr]; - } - if (attributes[attr].indexOf("url(") === 0) { - continue; - } - var color = new fabric.Color(attributes[attr]); - attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba(); - } - return attributes; - } - fabric.parseTransformAttribute = function() { - function rotateMatrix(matrix, args) { - var angle = args[0], x = args.length === 3 ? args[1] : 0, y = args.length === 3 ? args[2] : 0; - matrix[0] = Math.cos(angle); - matrix[1] = Math.sin(angle); - matrix[2] = -Math.sin(angle); - matrix[3] = Math.cos(angle); - matrix[4] = x - (matrix[0] * x + matrix[2] * y); - matrix[5] = y - (matrix[1] * x + matrix[3] * y); - } - function scaleMatrix(matrix, args) { - var multiplierX = args[0], multiplierY = args.length === 2 ? args[1] : args[0]; - matrix[0] = multiplierX; - matrix[3] = multiplierY; - } - function skewXMatrix(matrix, args) { - matrix[2] = Math.tan(fabric.util.degreesToRadians(args[0])); - } - function skewYMatrix(matrix, args) { - matrix[1] = Math.tan(fabric.util.degreesToRadians(args[0])); - } - function translateMatrix(matrix, args) { - matrix[4] = args[0]; - if (args.length === 2) { - matrix[5] = args[1]; - } - } - var iMatrix = [ 1, 0, 0, 1, 0, 0 ], number = fabric.reNum, commaWsp = "(?:\\s+,?\\s*|,\\s*)", skewX = "(?:(skewX)\\s*\\(\\s*(" + number + ")\\s*\\))", skewY = "(?:(skewY)\\s*\\(\\s*(" + number + ")\\s*\\))", rotate = "(?:(rotate)\\s*\\(\\s*(" + number + ")(?:" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + "))?\\s*\\))", scale = "(?:(scale)\\s*\\(\\s*(" + number + ")(?:" + commaWsp + "(" + number + "))?\\s*\\))", translate = "(?:(translate)\\s*\\(\\s*(" + number + ")(?:" + commaWsp + "(" + number + "))?\\s*\\))", matrix = "(?:(matrix)\\s*\\(\\s*" + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + "\\s*\\))", transform = "(?:" + matrix + "|" + translate + "|" + scale + "|" + rotate + "|" + skewX + "|" + skewY + ")", transforms = "(?:" + transform + "(?:" + commaWsp + "*" + transform + ")*" + ")", transformList = "^\\s*(?:" + transforms + "?)\\s*$", reTransformList = new RegExp(transformList), reTransform = new RegExp(transform, "g"); - return function(attributeValue) { - var matrix = iMatrix.concat(), matrices = []; - if (!attributeValue || attributeValue && !reTransformList.test(attributeValue)) { - return matrix; - } - attributeValue.replace(reTransform, function(match) { - var m = new RegExp(transform).exec(match).filter(function(match) { - return match !== "" && match != null; - }), operation = m[1], args = m.slice(2).map(parseFloat); - switch (operation) { - case "translate": - translateMatrix(matrix, args); - break; - - case "rotate": - args[0] = fabric.util.degreesToRadians(args[0]); - rotateMatrix(matrix, args); - break; - - case "scale": - scaleMatrix(matrix, args); - break; - - case "skewX": - skewXMatrix(matrix, args); - break; - - case "skewY": - skewYMatrix(matrix, args); - break; - - case "matrix": - matrix = args; - break; - } - matrices.push(matrix.concat()); - matrix = iMatrix.concat(); - }); - var combinedMatrix = matrices[0]; - while (matrices.length > 1) { - matrices.shift(); - combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]); - } - return combinedMatrix; - }; - }(); - function parseStyleString(style, oStyle) { - var attr, value; - style.replace(/;\s*$/, "").split(";").forEach(function(chunk) { - var pair = chunk.split(":"); - attr = normalizeAttr(pair[0].trim().toLowerCase()); - value = normalizeValue(attr, pair[1].trim()); - oStyle[attr] = value; - }); - } - function parseStyleObject(style, oStyle) { - var attr, value; - for (var prop in style) { - if (typeof style[prop] === "undefined") { - continue; - } - attr = normalizeAttr(prop.toLowerCase()); - value = normalizeValue(attr, style[prop]); - oStyle[attr] = value; - } - } - function getGlobalStylesForElement(element, svgUid) { - var styles = {}; - for (var rule in fabric.cssRules[svgUid]) { - if (elementMatchesRule(element, rule.split(" "))) { - for (var property in fabric.cssRules[svgUid][rule]) { - styles[property] = fabric.cssRules[svgUid][rule][property]; - } - } - } - return styles; - } - function elementMatchesRule(element, selectors) { - var firstMatching, parentMatching = true; - firstMatching = selectorMatches(element, selectors.pop()); - if (firstMatching && selectors.length) { - parentMatching = doesSomeParentMatch(element, selectors); - } - return firstMatching && parentMatching && selectors.length === 0; - } - function doesSomeParentMatch(element, selectors) { - var selector, parentMatching = true; - while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) { - if (parentMatching) { - selector = selectors.pop(); - } - element = element.parentNode; - parentMatching = selectorMatches(element, selector); - } - return selectors.length === 0; - } - function selectorMatches(element, selector) { - var nodeName = element.nodeName, classNames = element.getAttribute("class"), id = element.getAttribute("id"), matcher; - matcher = new RegExp("^" + nodeName, "i"); - selector = selector.replace(matcher, ""); - if (id && selector.length) { - matcher = new RegExp("#" + id + "(?![a-zA-Z\\-]+)", "i"); - selector = selector.replace(matcher, ""); - } - if (classNames && selector.length) { - classNames = classNames.split(" "); - for (var i = classNames.length; i--; ) { - matcher = new RegExp("\\." + classNames[i] + "(?![a-zA-Z\\-]+)", "i"); - selector = selector.replace(matcher, ""); - } - } - return selector.length === 0; - } - function elementById(doc, id) { - var el; - doc.getElementById && (el = doc.getElementById(id)); - if (el) { - return el; - } - var node, i, nodelist = doc.getElementsByTagName("*"); - for (i = 0; i < nodelist.length; i++) { - node = nodelist[i]; - if (id === node.getAttribute("id")) { - return node; - } - } - } - function parseUseDirectives(doc) { - var nodelist = doc.getElementsByTagName("use"), i = 0; - while (nodelist.length && i < nodelist.length) { - var el = nodelist[i], xlink = el.getAttribute("xlink:href").substr(1), x = el.getAttribute("x") || 0, y = el.getAttribute("y") || 0, el2 = elementById(doc, xlink).cloneNode(true), currentTrans = (el2.getAttribute("transform") || "") + " translate(" + x + ", " + y + ")", parentNode, oldLength = nodelist.length, attr, j, attrs, l; - applyViewboxTransform(el2); - if (/^svg$/i.test(el2.nodeName)) { - var el3 = el2.ownerDocument.createElement("g"); - for (j = 0, attrs = el2.attributes, l = attrs.length; j < l; j++) { - attr = attrs.item(j); - el3.setAttribute(attr.nodeName, attr.nodeValue); - } - while (el2.firstChild != null) { - el3.appendChild(el2.firstChild); - } - el2 = el3; - } - for (j = 0, attrs = el.attributes, l = attrs.length; j < l; j++) { - attr = attrs.item(j); - if (attr.nodeName === "x" || attr.nodeName === "y" || attr.nodeName === "xlink:href") { - continue; - } - if (attr.nodeName === "transform") { - currentTrans = attr.nodeValue + " " + currentTrans; - } else { - el2.setAttribute(attr.nodeName, attr.nodeValue); - } - } - el2.setAttribute("transform", currentTrans); - el2.setAttribute("instantiated_by_use", "1"); - el2.removeAttribute("id"); - parentNode = el.parentNode; - parentNode.replaceChild(el2, el); - if (nodelist.length === oldLength) { - i++; - } - } - } - var reViewBoxAttrValue = new RegExp("^" + "\\s*(" + fabric.reNum + "+)\\s*,?" + "\\s*(" + fabric.reNum + "+)\\s*,?" + "\\s*(" + fabric.reNum + "+)\\s*,?" + "\\s*(" + fabric.reNum + "+)\\s*" + "$"); - function applyViewboxTransform(element) { - var viewBoxAttr = element.getAttribute("viewBox"), scaleX = 1, scaleY = 1, minX = 0, minY = 0, viewBoxWidth, viewBoxHeight, matrix, el, widthAttr = element.getAttribute("width"), heightAttr = element.getAttribute("height"), x = element.getAttribute("x") || 0, y = element.getAttribute("y") || 0, preserveAspectRatio = element.getAttribute("preserveAspectRatio") || "", missingViewBox = !viewBoxAttr || !reViewBoxTagNames.test(element.tagName) || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue)), missingDimAttr = !widthAttr || !heightAttr || widthAttr === "100%" || heightAttr === "100%", toBeParsed = missingViewBox && missingDimAttr, parsedDim = {}, translateMatrix = ""; - parsedDim.width = 0; - parsedDim.height = 0; - parsedDim.toBeParsed = toBeParsed; - if (toBeParsed) { - return parsedDim; - } - if (missingViewBox) { - parsedDim.width = parseUnit(widthAttr); - parsedDim.height = parseUnit(heightAttr); - return parsedDim; - } - minX = -parseFloat(viewBoxAttr[1]), minY = -parseFloat(viewBoxAttr[2]), viewBoxWidth = parseFloat(viewBoxAttr[3]), - viewBoxHeight = parseFloat(viewBoxAttr[4]); - if (!missingDimAttr) { - parsedDim.width = parseUnit(widthAttr); - parsedDim.height = parseUnit(heightAttr); - scaleX = parsedDim.width / viewBoxWidth; - scaleY = parsedDim.height / viewBoxHeight; - } else { - parsedDim.width = viewBoxWidth; - parsedDim.height = viewBoxHeight; - } - preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio); - if (preserveAspectRatio.alignX !== "none") { - scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX; - } - if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) { - return parsedDim; - } - if (x || y) { - translateMatrix = " translate(" + parseUnit(x) + " " + parseUnit(y) + ") "; - } - matrix = translateMatrix + " matrix(" + scaleX + " 0" + " 0 " + scaleY + " " + minX * scaleX + " " + minY * scaleY + ") "; - if (element.tagName === "svg") { - el = element.ownerDocument.createElement("g"); - while (element.firstChild != null) { - el.appendChild(element.firstChild); - } - element.appendChild(el); - } else { - el = element; - matrix = el.getAttribute("transform") + matrix; - } - el.setAttribute("transform", matrix); - return parsedDim; - } - fabric.parseSVGDocument = function() { - function hasAncestorWithNodeName(element, nodeName) { - while (element && (element = element.parentNode)) { - if (nodeName.test(element.nodeName) && !element.getAttribute("instantiated_by_use")) { - return true; - } - } - return false; - } - return function(doc, callback, reviver) { - if (!doc) { - return; - } - parseUseDirectives(doc); - var startTime = new Date(), svgUid = fabric.Object.__uid++, options = applyViewboxTransform(doc), descendants = fabric.util.toArray(doc.getElementsByTagName("*")); - options.svgUid = svgUid; - if (descendants.length === 0 && fabric.isLikelyNode) { - descendants = doc.selectNodes('//*[name(.)!="svg"]'); - var arr = []; - for (var i = 0, len = descendants.length; i < len; i++) { - arr[i] = descendants[i]; - } - descendants = arr; - } - var elements = descendants.filter(function(el) { - applyViewboxTransform(el); - return reAllowedSVGTagNames.test(el.tagName) && !hasAncestorWithNodeName(el, reNotAllowedAncestors); - }); - if (!elements || elements && !elements.length) { - callback && callback([], {}); - return; - } - fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc); - fabric.cssRules[svgUid] = fabric.getCSSRules(doc); - fabric.parseElements(elements, function(instances) { - fabric.documentParsingTime = new Date() - startTime; - if (callback) { - callback(instances, options); - } - }, clone(options), reviver); - }; - }(); - var svgCache = { - has: function(name, callback) { - callback(false); - }, - get: function() {}, - set: function() {} - }; - function _enlivenCachedObject(cachedObject) { - var objects = cachedObject.objects, options = cachedObject.options; - objects = objects.map(function(o) { - return fabric[capitalize(o.type)].fromObject(o); - }); - return { - objects: objects, - options: options - }; - } - function _createSVGPattern(markup, canvas, property) { - if (canvas[property] && canvas[property].toSVG) { - markup.push(' \n', ' \n \n'); - } - } - var reFontDeclaration = new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*" + "(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(" + fabric.reNum + "(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|" + fabric.reNum + "))?\\s+(.*)"); - extend(fabric, { - parseFontDeclaration: function(value, oStyle) { - var match = value.match(reFontDeclaration); - if (!match) { - return; - } - var fontStyle = match[1], fontWeight = match[3], fontSize = match[4], lineHeight = match[5], fontFamily = match[6]; - if (fontStyle) { - oStyle.fontStyle = fontStyle; - } - if (fontWeight) { - oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight); - } - if (fontSize) { - oStyle.fontSize = parseUnit(fontSize); - } - if (fontFamily) { - oStyle.fontFamily = fontFamily; - } - if (lineHeight) { - oStyle.lineHeight = lineHeight === "normal" ? 1 : lineHeight; - } - }, - getGradientDefs: function(doc) { - var linearGradientEls = doc.getElementsByTagName("linearGradient"), radialGradientEls = doc.getElementsByTagName("radialGradient"), el, i, j = 0, id, xlink, elList = [], gradientDefs = {}, idsToXlinkMap = {}; - elList.length = linearGradientEls.length + radialGradientEls.length; - i = linearGradientEls.length; - while (i--) { - elList[j++] = linearGradientEls[i]; - } - i = radialGradientEls.length; - while (i--) { - elList[j++] = radialGradientEls[i]; - } - while (j--) { - el = elList[j]; - xlink = el.getAttribute("xlink:href"); - id = el.getAttribute("id"); - if (xlink) { - idsToXlinkMap[id] = xlink.substr(1); - } - gradientDefs[id] = el; - } - for (id in idsToXlinkMap) { - var el2 = gradientDefs[idsToXlinkMap[id]].cloneNode(true); - el = gradientDefs[id]; - while (el2.firstChild) { - el.appendChild(el2.firstChild); - } - } - return gradientDefs; - }, - parseAttributes: function(element, attributes, svgUid) { - if (!element) { - return; - } - var value, parentAttributes = {}, fontSize; - if (typeof svgUid === "undefined") { - svgUid = element.getAttribute("svgUid"); - } - if (element.parentNode && reAllowedParents.test(element.parentNode.nodeName)) { - parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid); - } - fontSize = parentAttributes && parentAttributes.fontSize || element.getAttribute("font-size") || fabric.Text.DEFAULT_SVG_FONT_SIZE; - var ownAttributes = attributes.reduce(function(memo, attr) { - value = element.getAttribute(attr); - if (value) { - attr = normalizeAttr(attr); - value = normalizeValue(attr, value, parentAttributes, fontSize); - memo[attr] = value; - } - return memo; - }, {}); - ownAttributes = extend(ownAttributes, extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element))); - if (ownAttributes.font) { - fabric.parseFontDeclaration(ownAttributes.font, ownAttributes); - } - return _setStrokeFillOpacity(extend(parentAttributes, ownAttributes)); - }, - parseElements: function(elements, callback, options, reviver) { - new fabric.ElementsParser(elements, callback, options, reviver).parse(); - }, - parseStyleAttribute: function(element) { - var oStyle = {}, style = element.getAttribute("style"); - if (!style) { - return oStyle; - } - if (typeof style === "string") { - parseStyleString(style, oStyle); - } else { - parseStyleObject(style, oStyle); - } - return oStyle; - }, - parsePointsAttribute: function(points) { - if (!points) { - return null; - } - points = points.replace(/,/g, " ").trim(); - points = points.split(/\s+/); - var parsedPoints = [], i, len; - i = 0; - len = points.length; - for (;i < len; i += 2) { - parsedPoints.push({ - x: parseFloat(points[i]), - y: parseFloat(points[i + 1]) - }); - } - return parsedPoints; - }, - getCSSRules: function(doc) { - var styles = doc.getElementsByTagName("style"), allRules = {}, rules; - for (var i = 0, len = styles.length; i < len; i++) { - var styleContents = styles[i].textContent || styles[i].text; - styleContents = styleContents.replace(/\/\*[\s\S]*?\*\//g, ""); - if (styleContents.trim() === "") { - continue; - } - rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g); - rules = rules.map(function(rule) { - return rule.trim(); - }); - rules.forEach(function(rule) { - var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/), ruleObj = {}, declaration = match[2].trim(), propertyValuePairs = declaration.replace(/;$/, "").split(/\s*;\s*/); - for (var i = 0, len = propertyValuePairs.length; i < len; i++) { - var pair = propertyValuePairs[i].split(/\s*:\s*/), property = normalizeAttr(pair[0]), value = normalizeValue(property, pair[1], pair[0]); - ruleObj[property] = value; - } - rule = match[1]; - rule.split(",").forEach(function(_rule) { - _rule = _rule.replace(/^svg/i, "").trim(); - if (_rule === "") { - return; - } - allRules[_rule] = fabric.util.object.clone(ruleObj); - }); - }); - } - return allRules; - }, - loadSVGFromURL: function(url, callback, reviver) { - url = url.replace(/^\n\s*/, "").trim(); - svgCache.has(url, function(hasUrl) { - if (hasUrl) { - svgCache.get(url, function(value) { - var enlivedRecord = _enlivenCachedObject(value); - callback(enlivedRecord.objects, enlivedRecord.options); - }); - } else { - new fabric.util.request(url, { - method: "get", - onComplete: onComplete - }); - } - }); - function onComplete(r) { - var xml = r.responseXML; - if (xml && !xml.documentElement && fabric.window.ActiveXObject && r.responseText) { - xml = new ActiveXObject("Microsoft.XMLDOM"); - xml.async = "false"; - xml.loadXML(r.responseText.replace(//i, "")); - } - if (!xml || !xml.documentElement) { - return; - } - fabric.parseSVGDocument(xml.documentElement, function(results, options) { - svgCache.set(url, { - objects: fabric.util.array.invoke(results, "toObject"), - options: options - }); - callback(results, options); - }, reviver); - } - }, - loadSVGFromString: function(string, callback, reviver) { - string = string.trim(); - var doc; - if (typeof DOMParser !== "undefined") { - var parser = new DOMParser(); - if (parser && parser.parseFromString) { - doc = parser.parseFromString(string, "text/xml"); - } - } else if (fabric.window.ActiveXObject) { - doc = new ActiveXObject("Microsoft.XMLDOM"); - doc.async = "false"; - doc.loadXML(string.replace(//i, "")); - } - fabric.parseSVGDocument(doc.documentElement, function(results, options) { - callback(results, options); - }, reviver); - }, - createSVGFontFacesMarkup: function(objects) { - var markup = "", fontList = {}, obj, fontFamily, style, row, rowIndex, char, charIndex, fontPaths = fabric.fontPaths; - for (var i = 0, len = objects.length; i < len; i++) { - obj = objects[i]; - fontFamily = obj.fontFamily; - if (obj.type.indexOf("text") === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) { - continue; - } - fontList[fontFamily] = true; - if (!obj.styles) { - continue; - } - style = obj.styles; - for (rowIndex in style) { - char = style[rowIndex]; - for (charIndex in row) { - char = row[charIndex]; - fontFamily = char.fontFamily; - if (!fontList[fontFamily] && fontPaths[fontFamily]) { - fontList[fontFamily] = true; - } - } - } - } - for (var j in fontList) { - markup += [ " @font-face {\n", " font-family: '", j, "';\n", " src: url('", fontPaths[j], "');\n", " }\n" ].join(""); - } - if (markup) { - markup = [ ' \n" ].join(""); - } - return markup; - }, - createSVGRefElementsMarkup: function(canvas) { - var markup = []; - _createSVGPattern(markup, canvas, "backgroundColor"); - _createSVGPattern(markup, canvas, "overlayColor"); - return markup.join(""); - } - }); -})(typeof exports !== "undefined" ? exports : this); - -fabric.ElementsParser = function(elements, callback, options, reviver) { - this.elements = elements; - this.callback = callback; - this.options = options; - this.reviver = reviver; - this.svgUid = options && options.svgUid || 0; -}; - -fabric.ElementsParser.prototype.parse = function() { - this.instances = new Array(this.elements.length); - this.numElements = this.elements.length; - this.createObjects(); -}; - -fabric.ElementsParser.prototype.createObjects = function() { - for (var i = 0, len = this.elements.length; i < len; i++) { - this.elements[i].setAttribute("svgUid", this.svgUid); - (function(_this, i) { - setTimeout(function() { - _this.createObject(_this.elements[i], i); - }, 0); - })(this, i); - } -}; - -fabric.ElementsParser.prototype.createObject = function(el, index) { - var klass = fabric[fabric.util.string.capitalize(el.tagName)]; - if (klass && klass.fromElement) { - try { - this._createObject(klass, el, index); - } catch (err) { - fabric.log(err); - } - } else { - this.checkIfDone(); - } -}; - -fabric.ElementsParser.prototype._createObject = function(klass, el, index) { - if (klass.async) { - klass.fromElement(el, this.createCallback(index, el), this.options); - } else { - var obj = klass.fromElement(el, this.options); - this.resolveGradient(obj, "fill"); - this.resolveGradient(obj, "stroke"); - this.reviver && this.reviver(el, obj); - this.instances[index] = obj; - this.checkIfDone(); - } -}; - -fabric.ElementsParser.prototype.createCallback = function(index, el) { - var _this = this; - return function(obj) { - _this.resolveGradient(obj, "fill"); - _this.resolveGradient(obj, "stroke"); - _this.reviver && _this.reviver(el, obj); - _this.instances[index] = obj; - _this.checkIfDone(); - }; -}; - -fabric.ElementsParser.prototype.resolveGradient = function(obj, property) { - var instanceFillValue = obj.get(property); - if (!/^url\(/.test(instanceFillValue)) { - return; - } - var gradientId = instanceFillValue.slice(5, instanceFillValue.length - 1); - if (fabric.gradientDefs[this.svgUid][gradientId]) { - obj.set(property, fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][gradientId], obj)); - } -}; - -fabric.ElementsParser.prototype.checkIfDone = function() { - if (--this.numElements === 0) { - this.instances = this.instances.filter(function(el) { - return el != null; - }); - this.callback(this.instances); - } -}; - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Point) { - fabric.warn("fabric.Point is already defined"); - return; - } - fabric.Point = Point; - function Point(x, y) { - this.x = x; - this.y = y; - } - Point.prototype = { - constructor: Point, - add: function(that) { - return new Point(this.x + that.x, this.y + that.y); - }, - addEquals: function(that) { - this.x += that.x; - this.y += that.y; - return this; - }, - scalarAdd: function(scalar) { - return new Point(this.x + scalar, this.y + scalar); - }, - scalarAddEquals: function(scalar) { - this.x += scalar; - this.y += scalar; - return this; - }, - subtract: function(that) { - return new Point(this.x - that.x, this.y - that.y); - }, - subtractEquals: function(that) { - this.x -= that.x; - this.y -= that.y; - return this; - }, - scalarSubtract: function(scalar) { - return new Point(this.x - scalar, this.y - scalar); - }, - scalarSubtractEquals: function(scalar) { - this.x -= scalar; - this.y -= scalar; - return this; - }, - multiply: function(scalar) { - return new Point(this.x * scalar, this.y * scalar); - }, - multiplyEquals: function(scalar) { - this.x *= scalar; - this.y *= scalar; - return this; - }, - divide: function(scalar) { - return new Point(this.x / scalar, this.y / scalar); - }, - divideEquals: function(scalar) { - this.x /= scalar; - this.y /= scalar; - return this; - }, - eq: function(that) { - return this.x === that.x && this.y === that.y; - }, - lt: function(that) { - return this.x < that.x && this.y < that.y; - }, - lte: function(that) { - return this.x <= that.x && this.y <= that.y; - }, - gt: function(that) { - return this.x > that.x && this.y > that.y; - }, - gte: function(that) { - return this.x >= that.x && this.y >= that.y; - }, - lerp: function(that, t) { - return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t); - }, - distanceFrom: function(that) { - var dx = this.x - that.x, dy = this.y - that.y; - return Math.sqrt(dx * dx + dy * dy); - }, - midPointFrom: function(that) { - return new Point(this.x + (that.x - this.x) / 2, this.y + (that.y - this.y) / 2); - }, - min: function(that) { - return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y)); - }, - max: function(that) { - return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y)); - }, - toString: function() { - return this.x + "," + this.y; - }, - setXY: function(x, y) { - this.x = x; - this.y = y; - }, - setFromPoint: function(that) { - this.x = that.x; - this.y = that.y; - }, - swap: function(that) { - var x = this.x, y = this.y; - this.x = that.x; - this.y = that.y; - that.x = x; - that.y = y; - } - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Intersection) { - fabric.warn("fabric.Intersection is already defined"); - return; - } - function Intersection(status) { - this.status = status; - this.points = []; - } - fabric.Intersection = Intersection; - fabric.Intersection.prototype = { - appendPoint: function(point) { - this.points.push(point); - }, - appendPoints: function(points) { - this.points = this.points.concat(points); - } - }; - fabric.Intersection.intersectLineLine = function(a1, a2, b1, b2) { - var result, uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x), ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x), uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y); - if (uB !== 0) { - var ua = uaT / uB, ub = ubT / uB; - if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { - result = new Intersection("Intersection"); - result.points.push(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y))); - } else { - result = new Intersection(); - } - } else { - if (uaT === 0 || ubT === 0) { - result = new Intersection("Coincident"); - } else { - result = new Intersection("Parallel"); - } - } - return result; - }; - fabric.Intersection.intersectLinePolygon = function(a1, a2, points) { - var result = new Intersection(), length = points.length; - for (var i = 0; i < length; i++) { - var b1 = points[i], b2 = points[(i + 1) % length], inter = Intersection.intersectLineLine(a1, a2, b1, b2); - result.appendPoints(inter.points); - } - if (result.points.length > 0) { - result.status = "Intersection"; - } - return result; - }; - fabric.Intersection.intersectPolygonPolygon = function(points1, points2) { - var result = new Intersection(), length = points1.length; - for (var i = 0; i < length; i++) { - var a1 = points1[i], a2 = points1[(i + 1) % length], inter = Intersection.intersectLinePolygon(a1, a2, points2); - result.appendPoints(inter.points); - } - if (result.points.length > 0) { - result.status = "Intersection"; - } - return result; - }; - fabric.Intersection.intersectPolygonRectangle = function(points, r1, r2) { - var min = r1.min(r2), max = r1.max(r2), topRight = new fabric.Point(max.x, min.y), bottomLeft = new fabric.Point(min.x, max.y), inter1 = Intersection.intersectLinePolygon(min, topRight, points), inter2 = Intersection.intersectLinePolygon(topRight, max, points), inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points), inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points), result = new Intersection(); - result.appendPoints(inter1.points); - result.appendPoints(inter2.points); - result.appendPoints(inter3.points); - result.appendPoints(inter4.points); - if (result.points.length > 0) { - result.status = "Intersection"; - } - return result; - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Color) { - fabric.warn("fabric.Color is already defined."); - return; - } - function Color(color) { - if (!color) { - this.setSource([ 0, 0, 0, 1 ]); - } else { - this._tryParsingColor(color); - } - } - fabric.Color = Color; - fabric.Color.prototype = { - _tryParsingColor: function(color) { - var source; - if (color in Color.colorNameMap) { - color = Color.colorNameMap[color]; - } - if (color === "transparent") { - this.setSource([ 255, 255, 255, 0 ]); - return; - } - source = Color.sourceFromHex(color); - if (!source) { - source = Color.sourceFromRgb(color); - } - if (!source) { - source = Color.sourceFromHsl(color); - } - if (source) { - this.setSource(source); - } - }, - _rgbToHsl: function(r, g, b) { - r /= 255, g /= 255, b /= 255; - var h, s, l, max = fabric.util.array.max([ r, g, b ]), min = fabric.util.array.min([ r, g, b ]); - l = (max + min) / 2; - if (max === min) { - h = s = 0; - } else { - var d = max - min; - s = l > .5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - - case g: - h = (b - r) / d + 2; - break; - - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - return [ Math.round(h * 360), Math.round(s * 100), Math.round(l * 100) ]; - }, - getSource: function() { - return this._source; - }, - setSource: function(source) { - this._source = source; - }, - toRgb: function() { - var source = this.getSource(); - return "rgb(" + source[0] + "," + source[1] + "," + source[2] + ")"; - }, - toRgba: function() { - var source = this.getSource(); - return "rgba(" + source[0] + "," + source[1] + "," + source[2] + "," + source[3] + ")"; - }, - toHsl: function() { - var source = this.getSource(), hsl = this._rgbToHsl(source[0], source[1], source[2]); - return "hsl(" + hsl[0] + "," + hsl[1] + "%," + hsl[2] + "%)"; - }, - toHsla: function() { - var source = this.getSource(), hsl = this._rgbToHsl(source[0], source[1], source[2]); - return "hsla(" + hsl[0] + "," + hsl[1] + "%," + hsl[2] + "%," + source[3] + ")"; - }, - toHex: function() { - var source = this.getSource(), r, g, b; - r = source[0].toString(16); - r = r.length === 1 ? "0" + r : r; - g = source[1].toString(16); - g = g.length === 1 ? "0" + g : g; - b = source[2].toString(16); - b = b.length === 1 ? "0" + b : b; - return r.toUpperCase() + g.toUpperCase() + b.toUpperCase(); - }, - getAlpha: function() { - return this.getSource()[3]; - }, - setAlpha: function(alpha) { - var source = this.getSource(); - source[3] = alpha; - this.setSource(source); - return this; - }, - toGrayscale: function() { - var source = this.getSource(), average = parseInt((source[0] * .3 + source[1] * .59 + source[2] * .11).toFixed(0), 10), currentAlpha = source[3]; - this.setSource([ average, average, average, currentAlpha ]); - return this; - }, - toBlackWhite: function(threshold) { - var source = this.getSource(), average = (source[0] * .3 + source[1] * .59 + source[2] * .11).toFixed(0), currentAlpha = source[3]; - threshold = threshold || 127; - average = Number(average) < Number(threshold) ? 0 : 255; - this.setSource([ average, average, average, currentAlpha ]); - return this; - }, - overlayWith: function(otherColor) { - if (!(otherColor instanceof Color)) { - otherColor = new Color(otherColor); - } - var result = [], alpha = this.getAlpha(), otherAlpha = .5, source = this.getSource(), otherSource = otherColor.getSource(); - for (var i = 0; i < 3; i++) { - result.push(Math.round(source[i] * (1 - otherAlpha) + otherSource[i] * otherAlpha)); - } - result[3] = alpha; - this.setSource(result); - return this; - } - }; - fabric.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/; - fabric.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/; - fabric.Color.reHex = /^#?([0-9a-f]{6}|[0-9a-f]{3})$/i; - fabric.Color.colorNameMap = { - aqua: "#00FFFF", - black: "#000000", - blue: "#0000FF", - fuchsia: "#FF00FF", - gray: "#808080", - green: "#008000", - lime: "#00FF00", - maroon: "#800000", - navy: "#000080", - olive: "#808000", - orange: "#FFA500", - purple: "#800080", - red: "#FF0000", - silver: "#C0C0C0", - teal: "#008080", - white: "#FFFFFF", - yellow: "#FFFF00" - }; - function hue2rgb(p, q, t) { - if (t < 0) { - t += 1; - } - if (t > 1) { - t -= 1; - } - if (t < 1 / 6) { - return p + (q - p) * 6 * t; - } - if (t < 1 / 2) { - return q; - } - if (t < 2 / 3) { - return p + (q - p) * (2 / 3 - t) * 6; - } - return p; - } - fabric.Color.fromRgb = function(color) { - return Color.fromSource(Color.sourceFromRgb(color)); - }; - fabric.Color.sourceFromRgb = function(color) { - var match = color.match(Color.reRGBa); - if (match) { - var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1), g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1), b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1); - return [ parseInt(r, 10), parseInt(g, 10), parseInt(b, 10), match[4] ? parseFloat(match[4]) : 1 ]; - } - }; - fabric.Color.fromRgba = Color.fromRgb; - fabric.Color.fromHsl = function(color) { - return Color.fromSource(Color.sourceFromHsl(color)); - }; - fabric.Color.sourceFromHsl = function(color) { - var match = color.match(Color.reHSLa); - if (!match) { - return; - } - var h = (parseFloat(match[1]) % 360 + 360) % 360 / 360, s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1), l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1), r, g, b; - if (s === 0) { - r = g = b = l; - } else { - var q = l <= .5 ? l * (s + 1) : l + s - l * s, p = l * 2 - q; - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - return [ Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), match[4] ? parseFloat(match[4]) : 1 ]; - }; - fabric.Color.fromHsla = Color.fromHsl; - fabric.Color.fromHex = function(color) { - return Color.fromSource(Color.sourceFromHex(color)); - }; - fabric.Color.sourceFromHex = function(color) { - if (color.match(Color.reHex)) { - var value = color.slice(color.indexOf("#") + 1), isShortNotation = value.length === 3, r = isShortNotation ? value.charAt(0) + value.charAt(0) : value.substring(0, 2), g = isShortNotation ? value.charAt(1) + value.charAt(1) : value.substring(2, 4), b = isShortNotation ? value.charAt(2) + value.charAt(2) : value.substring(4, 6); - return [ parseInt(r, 16), parseInt(g, 16), parseInt(b, 16), 1 ]; - } - }; - fabric.Color.fromSource = function(source) { - var oColor = new Color(); - oColor.setSource(source); - return oColor; - }; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - function getColorStop(el) { - var style = el.getAttribute("style"), offset = el.getAttribute("offset") || 0, color, colorAlpha, opacity; - offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1); - offset = offset < 0 ? 0 : offset > 1 ? 1 : offset; - if (style) { - var keyValuePairs = style.split(/\s*;\s*/); - if (keyValuePairs[keyValuePairs.length - 1] === "") { - keyValuePairs.pop(); - } - for (var i = keyValuePairs.length; i--; ) { - var split = keyValuePairs[i].split(/\s*:\s*/), key = split[0].trim(), value = split[1].trim(); - if (key === "stop-color") { - color = value; - } else if (key === "stop-opacity") { - opacity = value; - } - } - } - if (!color) { - color = el.getAttribute("stop-color") || "rgb(0,0,0)"; - } - if (!opacity) { - opacity = el.getAttribute("stop-opacity"); - } - color = new fabric.Color(color); - colorAlpha = color.getAlpha(); - opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity); - opacity *= colorAlpha; - return { - offset: offset, - color: color.toRgb(), - opacity: opacity - }; - } - function getLinearCoords(el) { - return { - x1: el.getAttribute("x1") || 0, - y1: el.getAttribute("y1") || 0, - x2: el.getAttribute("x2") || "100%", - y2: el.getAttribute("y2") || 0 - }; - } - function getRadialCoords(el) { - return { - x1: el.getAttribute("fx") || el.getAttribute("cx") || "50%", - y1: el.getAttribute("fy") || el.getAttribute("cy") || "50%", - r1: 0, - x2: el.getAttribute("cx") || "50%", - y2: el.getAttribute("cy") || "50%", - r2: el.getAttribute("r") || "50%" - }; - } - fabric.Gradient = fabric.util.createClass({ - offsetX: 0, - offsetY: 0, - initialize: function(options) { - options || (options = {}); - var coords = {}; - this.id = fabric.Object.__uid++; - this.type = options.type || "linear"; - coords = { - x1: options.coords.x1 || 0, - y1: options.coords.y1 || 0, - x2: options.coords.x2 || 0, - y2: options.coords.y2 || 0 - }; - if (this.type === "radial") { - coords.r1 = options.coords.r1 || 0; - coords.r2 = options.coords.r2 || 0; - } - this.coords = coords; - this.colorStops = options.colorStops.slice(); - if (options.gradientTransform) { - this.gradientTransform = options.gradientTransform; - } - this.offsetX = options.offsetX || this.offsetX; - this.offsetY = options.offsetY || this.offsetY; - }, - addColorStop: function(colorStop) { - for (var position in colorStop) { - var color = new fabric.Color(colorStop[position]); - this.colorStops.push({ - offset: position, - color: color.toRgb(), - opacity: color.getAlpha() - }); - } - return this; - }, - toObject: function() { - return { - type: this.type, - coords: this.coords, - colorStops: this.colorStops, - offsetX: this.offsetX, - offsetY: this.offsetY, - gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform - }; - }, - toSVG: function(object) { - var coords = fabric.util.object.clone(this.coords), markup, commonAttributes; - this.colorStops.sort(function(a, b) { - return a.offset - b.offset; - }); - if (!(object.group && object.group.type === "path-group")) { - for (var prop in coords) { - if (prop === "x1" || prop === "x2" || prop === "r2") { - coords[prop] += this.offsetX - object.width / 2; - } else if (prop === "y1" || prop === "y2") { - coords[prop] += this.offsetY - object.height / 2; - } - } - } - commonAttributes = 'id="SVGID_' + this.id + '" gradientUnits="userSpaceOnUse"'; - if (this.gradientTransform) { - commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(" ") + ')" '; - } - if (this.type === "linear") { - markup = [ "\n' ]; - } else if (this.type === "radial") { - markup = [ "\n' ]; - } - for (var i = 0; i < this.colorStops.length; i++) { - markup.push("\n'); - } - markup.push(this.type === "linear" ? "\n" : "\n"); - return markup.join(""); - }, - toLive: function(ctx, object) { - var gradient, prop, coords = fabric.util.object.clone(this.coords); - if (!this.type) { - return; - } - if (object.group && object.group.type === "path-group") { - for (prop in coords) { - if (prop === "x1" || prop === "x2") { - coords[prop] += -this.offsetX + object.width / 2; - } else if (prop === "y1" || prop === "y2") { - coords[prop] += -this.offsetY + object.height / 2; - } - } - } - if (this.type === "linear") { - gradient = ctx.createLinearGradient(coords.x1, coords.y1, coords.x2, coords.y2); - } else if (this.type === "radial") { - gradient = ctx.createRadialGradient(coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2); - } - for (var i = 0, len = this.colorStops.length; i < len; i++) { - var color = this.colorStops[i].color, opacity = this.colorStops[i].opacity, offset = this.colorStops[i].offset; - if (typeof opacity !== "undefined") { - color = new fabric.Color(color).setAlpha(opacity).toRgba(); - } - gradient.addColorStop(parseFloat(offset), color); - } - return gradient; - } - }); - fabric.util.object.extend(fabric.Gradient, { - fromElement: function(el, instance) { - var colorStopEls = el.getElementsByTagName("stop"), type = el.nodeName === "linearGradient" ? "linear" : "radial", gradientUnits = el.getAttribute("gradientUnits") || "objectBoundingBox", gradientTransform = el.getAttribute("gradientTransform"), colorStops = [], coords = {}, ellipseMatrix; - if (type === "linear") { - coords = getLinearCoords(el); - } else if (type === "radial") { - coords = getRadialCoords(el); - } - for (var i = colorStopEls.length; i--; ) { - colorStops.push(getColorStop(colorStopEls[i])); - } - ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits); - var gradient = new fabric.Gradient({ - type: type, - coords: coords, - colorStops: colorStops, - offsetX: -instance.left, - offsetY: -instance.top - }); - if (gradientTransform || ellipseMatrix !== "") { - gradient.gradientTransform = fabric.parseTransformAttribute((gradientTransform || "") + ellipseMatrix); - } - return gradient; - }, - forObject: function(obj, options) { - options || (options = {}); - _convertPercentUnitsToValues(obj, options.coords, "userSpaceOnUse"); - return new fabric.Gradient(options); - } - }); - function _convertPercentUnitsToValues(object, options, gradientUnits) { - var propValue, addFactor = 0, multFactor = 1, ellipseMatrix = ""; - for (var prop in options) { - propValue = parseFloat(options[prop], 10); - if (typeof options[prop] === "string" && /^\d+%$/.test(options[prop])) { - multFactor = .01; - } else { - multFactor = 1; - } - if (prop === "x1" || prop === "x2" || prop === "r2") { - multFactor *= gradientUnits === "objectBoundingBox" ? object.width : 1; - addFactor = gradientUnits === "objectBoundingBox" ? object.left || 0 : 0; - } else if (prop === "y1" || prop === "y2") { - multFactor *= gradientUnits === "objectBoundingBox" ? object.height : 1; - addFactor = gradientUnits === "objectBoundingBox" ? object.top || 0 : 0; - } - options[prop] = propValue * multFactor + addFactor; - } - if (object.type === "ellipse" && options.r2 !== null && gradientUnits === "objectBoundingBox" && object.rx !== object.ry) { - var scaleFactor = object.ry / object.rx; - ellipseMatrix = " scale(1, " + scaleFactor + ")"; - if (options.y1) { - options.y1 /= scaleFactor; - } - if (options.y2) { - options.y2 /= scaleFactor; - } - } - return ellipseMatrix; - } -})(); - -fabric.Pattern = fabric.util.createClass({ - repeat: "repeat", - offsetX: 0, - offsetY: 0, - initialize: function(options) { - options || (options = {}); - this.id = fabric.Object.__uid++; - if (options.source) { - if (typeof options.source === "string") { - if (typeof fabric.util.getFunctionBody(options.source) !== "undefined") { - this.source = new Function(fabric.util.getFunctionBody(options.source)); - } else { - var _this = this; - this.source = fabric.util.createImage(); - fabric.util.loadImage(options.source, function(img) { - _this.source = img; - }); - } - } else { - this.source = options.source; - } - } - if (options.repeat) { - this.repeat = options.repeat; - } - if (options.offsetX) { - this.offsetX = options.offsetX; - } - if (options.offsetY) { - this.offsetY = options.offsetY; - } - }, - toObject: function() { - var source; - if (typeof this.source === "function") { - source = String(this.source); - } else if (typeof this.source.src === "string") { - source = this.source.src; - } else if (typeof this.source === "object" && this.source.toDataURL) { - source = this.source.toDataURL(); - } - return { - source: source, - repeat: this.repeat, - offsetX: this.offsetX, - offsetY: this.offsetY - }; - }, - toSVG: function(object) { - var patternSource = typeof this.source === "function" ? this.source() : this.source, patternWidth = patternSource.width / object.getWidth(), patternHeight = patternSource.height / object.getHeight(), patternOffsetX = this.offsetX / object.getWidth(), patternOffsetY = this.offsetY / object.getHeight(), patternImgSrc = ""; - if (this.repeat === "repeat-x" || this.repeat === "no-repeat") { - patternHeight = 1; - } - if (this.repeat === "repeat-y" || this.repeat === "no-repeat") { - patternWidth = 1; - } - if (patternSource.src) { - patternImgSrc = patternSource.src; - } else if (patternSource.toDataURL) { - patternImgSrc = patternSource.toDataURL(); - } - return '\n' + '\n' + "\n"; - }, - toLive: function(ctx) { - var source = typeof this.source === "function" ? this.source() : this.source; - if (!source) { - return ""; - } - if (typeof source.src !== "undefined") { - if (!source.complete) { - return ""; - } - if (source.naturalWidth === 0 || source.naturalHeight === 0) { - return ""; - } - } - return ctx.createPattern(source, this.repeat); - } -}); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), toFixed = fabric.util.toFixed; - if (fabric.Shadow) { - fabric.warn("fabric.Shadow is already defined."); - return; - } - fabric.Shadow = fabric.util.createClass({ - color: "rgb(0,0,0)", - blur: 0, - offsetX: 0, - offsetY: 0, - affectStroke: false, - includeDefaultValues: true, - initialize: function(options) { - if (typeof options === "string") { - options = this._parseShadow(options); - } - for (var prop in options) { - this[prop] = options[prop]; - } - this.id = fabric.Object.__uid++; - }, - _parseShadow: function(shadow) { - var shadowStr = shadow.trim(), offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [], color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, "") || "rgb(0,0,0)"; - return { - color: color.trim(), - offsetX: parseInt(offsetsAndBlur[1], 10) || 0, - offsetY: parseInt(offsetsAndBlur[2], 10) || 0, - blur: parseInt(offsetsAndBlur[3], 10) || 0 - }; - }, - toString: function() { - return [ this.offsetX, this.offsetY, this.blur, this.color ].join("px "); - }, - toSVG: function(object) { - var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, offset = fabric.util.rotateVector({ - x: this.offsetX, - y: this.offsetY - }, fabric.util.degreesToRadians(-object.angle)), BLUR_BOX = 20; - if (object.width && object.height) { - fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; - fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; - } - if (object.flipX) { - offset.x *= -1; - } - if (object.flipY) { - offset.y *= -1; - } - return '\n" + ' \n' + ' \n' + ' \n' + ' \n' + " \n" + " \n" + ' \n' + " \n" + "\n"; - }, - toObject: function() { - if (this.includeDefaultValues) { - return { - color: this.color, - blur: this.blur, - offsetX: this.offsetX, - offsetY: this.offsetY, - affectStroke: this.affectStroke - }; - } - var obj = {}, proto = fabric.Shadow.prototype; - [ "color", "blur", "offsetX", "offsetY", "affectStroke" ].forEach(function(prop) { - if (this[prop] !== proto[prop]) { - obj[prop] = this[prop]; - } - }, this); - return obj; - } - }); - fabric.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - "use strict"; - if (fabric.StaticCanvas) { - fabric.warn("fabric.StaticCanvas is already defined."); - return; - } - var extend = fabric.util.object.extend, getElementOffset = fabric.util.getElementOffset, removeFromArray = fabric.util.removeFromArray, toFixed = fabric.util.toFixed, CANVAS_INIT_ERROR = new Error("Could not initialize `canvas` element"); - fabric.StaticCanvas = fabric.util.createClass({ - initialize: function(el, options) { - options || (options = {}); - this._initStatic(el, options); - }, - backgroundColor: "", - backgroundImage: null, - overlayColor: "", - overlayImage: null, - includeDefaultValues: true, - stateful: true, - renderOnAddRemove: true, - clipTo: null, - controlsAboveOverlay: false, - allowTouchScrolling: false, - imageSmoothingEnabled: true, - preserveObjectStacking: false, - viewportTransform: [ 1, 0, 0, 1, 0, 0 ], - onBeforeScaleRotate: function() {}, - enableRetinaScaling: true, - _initStatic: function(el, options) { - this._objects = []; - this._createLowerCanvas(el); - this._initOptions(options); - this._setImageSmoothing(); - if (!this.interactive) { - this._initRetinaScaling(); - } - if (options.overlayImage) { - this.setOverlayImage(options.overlayImage, this.renderAll.bind(this)); - } - if (options.backgroundImage) { - this.setBackgroundImage(options.backgroundImage, this.renderAll.bind(this)); - } - if (options.backgroundColor) { - this.setBackgroundColor(options.backgroundColor, this.renderAll.bind(this)); - } - if (options.overlayColor) { - this.setOverlayColor(options.overlayColor, this.renderAll.bind(this)); - } - this.calcOffset(); - }, - _isRetinaScaling: function() { - return fabric.devicePixelRatio !== 1 && this.enableRetinaScaling; - }, - _initRetinaScaling: function() { - if (!this._isRetinaScaling()) { - return; - } - this.lowerCanvasEl.setAttribute("width", this.width * fabric.devicePixelRatio); - this.lowerCanvasEl.setAttribute("height", this.height * fabric.devicePixelRatio); - this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio); - }, - calcOffset: function() { - this._offset = getElementOffset(this.lowerCanvasEl); - return this; - }, - setOverlayImage: function(image, callback, options) { - return this.__setBgOverlayImage("overlayImage", image, callback, options); - }, - setBackgroundImage: function(image, callback, options) { - return this.__setBgOverlayImage("backgroundImage", image, callback, options); - }, - setOverlayColor: function(overlayColor, callback) { - return this.__setBgOverlayColor("overlayColor", overlayColor, callback); - }, - setBackgroundColor: function(backgroundColor, callback) { - return this.__setBgOverlayColor("backgroundColor", backgroundColor, callback); - }, - _setImageSmoothing: function() { - var ctx = this.getContext(); - ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled; - ctx.imageSmoothingEnabled = this.imageSmoothingEnabled; - }, - __setBgOverlayImage: function(property, image, callback, options) { - if (typeof image === "string") { - fabric.util.loadImage(image, function(img) { - this[property] = new fabric.Image(img, options); - callback && callback(img); - }, this, options && options.crossOrigin); - } else { - options && image.setOptions(options); - this[property] = image; - callback && callback(image); - } - return this; - }, - __setBgOverlayColor: function(property, color, callback) { - if (color && color.source) { - var _this = this; - fabric.util.loadImage(color.source, function(img) { - _this[property] = new fabric.Pattern({ - source: img, - repeat: color.repeat, - offsetX: color.offsetX, - offsetY: color.offsetY - }); - callback && callback(); - }); - } else { - this[property] = color; - callback && callback(); - } - return this; - }, - _createCanvasElement: function() { - var element = fabric.document.createElement("canvas"); - if (!element.style) { - element.style = {}; - } - if (!element) { - throw CANVAS_INIT_ERROR; - } - this._initCanvasElement(element); - return element; - }, - _initCanvasElement: function(element) { - fabric.util.createCanvasElement(element); - if (typeof element.getContext === "undefined") { - throw CANVAS_INIT_ERROR; - } - }, - _initOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - this.width = this.width || parseInt(this.lowerCanvasEl.width, 10) || 0; - this.height = this.height || parseInt(this.lowerCanvasEl.height, 10) || 0; - if (!this.lowerCanvasEl.style) { - return; - } - this.lowerCanvasEl.width = this.width; - this.lowerCanvasEl.height = this.height; - this.lowerCanvasEl.style.width = this.width + "px"; - this.lowerCanvasEl.style.height = this.height + "px"; - this.viewportTransform = this.viewportTransform.slice(); - }, - _createLowerCanvas: function(canvasEl) { - this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(); - this._initCanvasElement(this.lowerCanvasEl); - fabric.util.addClass(this.lowerCanvasEl, "lower-canvas"); - if (this.interactive) { - this._applyCanvasStyle(this.lowerCanvasEl); - } - this.contextContainer = this.lowerCanvasEl.getContext("2d"); - }, - getWidth: function() { - return this.width; - }, - getHeight: function() { - return this.height; - }, - setWidth: function(value, options) { - return this.setDimensions({ - width: value - }, options); - }, - setHeight: function(value, options) { - return this.setDimensions({ - height: value - }, options); - }, - setDimensions: function(dimensions, options) { - var cssValue; - options = options || {}; - for (var prop in dimensions) { - cssValue = dimensions[prop]; - if (!options.cssOnly) { - this._setBackstoreDimension(prop, dimensions[prop]); - cssValue += "px"; - } - if (!options.backstoreOnly) { - this._setCssDimension(prop, cssValue); - } - } - this._initRetinaScaling(); - this._setImageSmoothing(); - this.calcOffset(); - if (!options.cssOnly) { - this.renderAll(); - } - return this; - }, - _setBackstoreDimension: function(prop, value) { - this.lowerCanvasEl[prop] = value; - if (this.upperCanvasEl) { - this.upperCanvasEl[prop] = value; - } - if (this.cacheCanvasEl) { - this.cacheCanvasEl[prop] = value; - } - this[prop] = value; - return this; - }, - _setCssDimension: function(prop, value) { - this.lowerCanvasEl.style[prop] = value; - if (this.upperCanvasEl) { - this.upperCanvasEl.style[prop] = value; - } - if (this.wrapperEl) { - this.wrapperEl.style[prop] = value; - } - return this; - }, - getZoom: function() { - return Math.sqrt(this.viewportTransform[0] * this.viewportTransform[3]); - }, - setViewportTransform: function(vpt) { - var activeGroup = this.getActiveGroup(); - this.viewportTransform = vpt; - this.renderAll(); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].setCoords(); - } - if (activeGroup) { - activeGroup.setCoords(); - } - return this; - }, - zoomToPoint: function(point, value) { - var before = point; - point = fabric.util.transformPoint(point, fabric.util.invertTransform(this.viewportTransform)); - this.viewportTransform[0] = value; - this.viewportTransform[3] = value; - var after = fabric.util.transformPoint(point, this.viewportTransform); - this.viewportTransform[4] += before.x - after.x; - this.viewportTransform[5] += before.y - after.y; - this.renderAll(); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].setCoords(); - } - return this; - }, - setZoom: function(value) { - this.zoomToPoint(new fabric.Point(0, 0), value); - return this; - }, - absolutePan: function(point) { - this.viewportTransform[4] = -point.x; - this.viewportTransform[5] = -point.y; - this.renderAll(); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].setCoords(); - } - return this; - }, - relativePan: function(point) { - return this.absolutePan(new fabric.Point(-point.x - this.viewportTransform[4], -point.y - this.viewportTransform[5])); - }, - getElement: function() { - return this.lowerCanvasEl; - }, - getActiveObject: function() { - return null; - }, - getActiveGroup: function() { - return null; - }, - _onObjectAdded: function(obj) { - this.stateful && obj.setupState(); - obj._set("canvas", this); - obj.setCoords(); - this.fire("object:added", { - target: obj - }); - obj.fire("added"); - }, - _onObjectRemoved: function(obj) { - if (this.getActiveObject() === obj) { - this.fire("before:selection:cleared", { - target: obj - }); - this._discardActiveObject(); - this.fire("selection:cleared"); - } - this.fire("object:removed", { - target: obj - }); - obj.fire("removed"); - }, - clearContext: function(ctx) { - ctx.clearRect(0, 0, this.width, this.height); - return this; - }, - getContext: function() { - return this.contextContainer; - }, - clear: function() { - this._objects.length = 0; - if (this.discardActiveGroup) { - this.discardActiveGroup(); - } - if (this.discardActiveObject) { - this.discardActiveObject(); - } - this.clearContext(this.contextContainer); - if (this.contextTop) { - this.clearContext(this.contextTop); - } - this.fire("canvas:cleared"); - this.renderAll(); - return this; - }, - _chooseObjectsToRender: function() { - var activeGroup = this.getActiveGroup(), object, objsToRender = [], activeGroupObjects = []; - if (activeGroup && !this.preserveObjectStacking) { - for (var i = 0, length = this._objects.length; i < length; i++) { - object = this._objects[i]; - if (!activeGroup.contains(object)) { - objsToRender.push(object); - } else { - activeGroupObjects.push(object); - } - } - activeGroup._set("_objects", activeGroupObjects); - } else { - objsToRender = this._objects; - } - return objsToRender; - }, - renderAll: function() { - var canvasToDrawOn = this.contextContainer, objsToRender; - if (this.contextTop && this.selection && !this._groupSelector && !this.isDrawingMode) { - this.clearContext(this.contextTop); - } - this.clearContext(canvasToDrawOn); - this.fire("before:render"); - if (this.clipTo) { - fabric.util.clipContext(this, canvasToDrawOn); - } - this._renderBackground(canvasToDrawOn); - canvasToDrawOn.save(); - objsToRender = this._chooseObjectsToRender(); - canvasToDrawOn.transform.apply(canvasToDrawOn, this.viewportTransform); - this._renderObjects(canvasToDrawOn, objsToRender); - this.preserveObjectStacking || this._renderObjects(canvasToDrawOn, [ this.getActiveGroup() ]); - canvasToDrawOn.restore(); - if (!this.controlsAboveOverlay && this.interactive) { - this.drawControls(canvasToDrawOn); - } - if (this.clipTo) { - canvasToDrawOn.restore(); - } - this._renderOverlay(canvasToDrawOn); - if (this.controlsAboveOverlay && this.interactive) { - this.drawControls(canvasToDrawOn); - } - this.fire("after:render"); - return this; - }, - _renderObjects: function(ctx, objects) { - for (var i = 0, length = objects.length; i < length; ++i) { - objects[i] && objects[i].render(ctx); - } - }, - _renderBackgroundOrOverlay: function(ctx, property) { - var object = this[property + "Color"]; - if (object) { - ctx.fillStyle = object.toLive ? object.toLive(ctx) : object; - ctx.fillRect(object.offsetX || 0, object.offsetY || 0, this.width, this.height); - } - object = this[property + "Image"]; - if (object) { - object.render(ctx); - } - }, - _renderBackground: function(ctx) { - this._renderBackgroundOrOverlay(ctx, "background"); - }, - _renderOverlay: function(ctx) { - this._renderBackgroundOrOverlay(ctx, "overlay"); - }, - renderTop: function() { - var ctx = this.contextTop || this.contextContainer; - this.clearContext(ctx); - if (this.selection && this._groupSelector) { - this._drawSelection(); - } - this.fire("after:render"); - return this; - }, - getCenter: function() { - return { - top: this.getHeight() / 2, - left: this.getWidth() / 2 - }; - }, - centerObjectH: function(object) { - this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y)); - this.renderAll(); - return this; - }, - centerObjectV: function(object) { - this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top)); - this.renderAll(); - return this; - }, - centerObject: function(object) { - var center = this.getCenter(); - this._centerObject(object, new fabric.Point(center.left, center.top)); - this.renderAll(); - return this; - }, - _centerObject: function(object, center) { - object.setPositionByOrigin(center, "center", "center"); - return this; - }, - toDatalessJSON: function(propertiesToInclude) { - return this.toDatalessObject(propertiesToInclude); - }, - toObject: function(propertiesToInclude) { - return this._toObjectMethod("toObject", propertiesToInclude); - }, - toDatalessObject: function(propertiesToInclude) { - return this._toObjectMethod("toDatalessObject", propertiesToInclude); - }, - _toObjectMethod: function(methodName, propertiesToInclude) { - var data = { - objects: this._toObjects(methodName, propertiesToInclude) - }; - extend(data, this.__serializeBgOverlay()); - fabric.util.populateWithProperties(this, data, propertiesToInclude); - return data; - }, - _toObjects: function(methodName, propertiesToInclude) { - return this.getObjects().map(function(instance) { - return this._toObject(instance, methodName, propertiesToInclude); - }, this); - }, - _toObject: function(instance, methodName, propertiesToInclude) { - var originalValue; - if (!this.includeDefaultValues) { - originalValue = instance.includeDefaultValues; - instance.includeDefaultValues = false; - } - var originalProperties = this._realizeGroupTransformOnObject(instance), object = instance[methodName](propertiesToInclude); - if (!this.includeDefaultValues) { - instance.includeDefaultValues = originalValue; - } - this._unwindGroupTransformOnObject(instance, originalProperties); - return object; - }, - _realizeGroupTransformOnObject: function(instance) { - var layoutProps = [ "angle", "flipX", "flipY", "height", "left", "scaleX", "scaleY", "top", "width" ]; - if (instance.group && instance.group === this.getActiveGroup()) { - var originalValues = {}; - layoutProps.forEach(function(prop) { - originalValues[prop] = instance[prop]; - }); - this.getActiveGroup().realizeTransform(instance); - return originalValues; - } else { - return null; - } - }, - _unwindGroupTransformOnObject: function(instance, originalValues) { - if (originalValues) { - instance.set(originalValues); - } - }, - __serializeBgOverlay: function() { - var data = { - background: this.backgroundColor && this.backgroundColor.toObject ? this.backgroundColor.toObject() : this.backgroundColor - }; - if (this.overlayColor) { - data.overlay = this.overlayColor.toObject ? this.overlayColor.toObject() : this.overlayColor; - } - if (this.backgroundImage) { - data.backgroundImage = this.backgroundImage.toObject(); - } - if (this.overlayImage) { - data.overlayImage = this.overlayImage.toObject(); - } - return data; - }, - svgViewportTransformation: true, - toSVG: function(options, reviver) { - options || (options = {}); - var markup = []; - this._setSVGPreamble(markup, options); - this._setSVGHeader(markup, options); - this._setSVGBgOverlayColor(markup, "backgroundColor"); - this._setSVGBgOverlayImage(markup, "backgroundImage"); - this._setSVGObjects(markup, reviver); - this._setSVGBgOverlayColor(markup, "overlayColor"); - this._setSVGBgOverlayImage(markup, "overlayImage"); - markup.push(""); - return markup.join(""); - }, - _setSVGPreamble: function(markup, options) { - if (options.suppressPreamble) { - return; - } - markup.push('\n', '\n'); - }, - _setSVGHeader: function(markup, options) { - var width = options.width || this.width, height = options.height || this.height, vpt, viewBox = 'viewBox="0 0 ' + this.width + " " + this.height + '" ', NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - if (options.viewBox) { - viewBox = 'viewBox="' + options.viewBox.x + " " + options.viewBox.y + " " + options.viewBox.width + " " + options.viewBox.height + '" '; - } else { - if (this.svgViewportTransformation) { - vpt = this.viewportTransform; - viewBox = 'viewBox="' + toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + " " + toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + " " + toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + " " + toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '" '; - } - } - markup.push("\n', "Created with Fabric.js ", fabric.version, "\n", "", fabric.createSVGFontFacesMarkup(this.getObjects()), fabric.createSVGRefElementsMarkup(this), "\n"); - }, - _setSVGObjects: function(markup, reviver) { - for (var i = 0, objects = this.getObjects(), len = objects.length; i < len; i++) { - var instance = objects[i], originalProperties = this._realizeGroupTransformOnObject(instance); - markup.push(instance.toSVG(reviver)); - this._unwindGroupTransformOnObject(instance, originalProperties); - } - }, - _setSVGBgOverlayImage: function(markup, property) { - if (this[property] && this[property].toSVG) { - markup.push(this[property].toSVG()); - } - }, - _setSVGBgOverlayColor: function(markup, property) { - if (this[property] && this[property].source) { - markup.push('\n"); - } else if (this[property] && property === "overlayColor") { - markup.push('\n"); - } - }, - sendToBack: function(object) { - removeFromArray(this._objects, object); - this._objects.unshift(object); - return this.renderAll && this.renderAll(); - }, - bringToFront: function(object) { - removeFromArray(this._objects, object); - this._objects.push(object); - return this.renderAll && this.renderAll(); - }, - sendBackwards: function(object, intersecting) { - var idx = this._objects.indexOf(object); - if (idx !== 0) { - var newIdx = this._findNewLowerIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - this.renderAll && this.renderAll(); - } - return this; - }, - _findNewLowerIndex: function(object, idx, intersecting) { - var newIdx; - if (intersecting) { - newIdx = idx; - for (var i = idx - 1; i >= 0; --i) { - var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object); - if (isIntersecting) { - newIdx = i; - break; - } - } - } else { - newIdx = idx - 1; - } - return newIdx; - }, - bringForward: function(object, intersecting) { - var idx = this._objects.indexOf(object); - if (idx !== this._objects.length - 1) { - var newIdx = this._findNewUpperIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - this.renderAll && this.renderAll(); - } - return this; - }, - _findNewUpperIndex: function(object, idx, intersecting) { - var newIdx; - if (intersecting) { - newIdx = idx; - for (var i = idx + 1; i < this._objects.length; ++i) { - var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object); - if (isIntersecting) { - newIdx = i; - break; - } - } - } else { - newIdx = idx + 1; - } - return newIdx; - }, - moveTo: function(object, index) { - removeFromArray(this._objects, object); - this._objects.splice(index, 0, object); - return this.renderAll && this.renderAll(); - }, - dispose: function() { - this.clear(); - return this; - }, - toString: function() { - return "#"; - } - }); - extend(fabric.StaticCanvas.prototype, fabric.Observable); - extend(fabric.StaticCanvas.prototype, fabric.Collection); - extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter); - extend(fabric.StaticCanvas, { - EMPTY_JSON: '{"objects": [], "background": "white"}', - supports: function(methodName) { - var el = fabric.util.createCanvasElement(); - if (!el || !el.getContext) { - return null; - } - var ctx = el.getContext("2d"); - if (!ctx) { - return null; - } - switch (methodName) { - case "getImageData": - return typeof ctx.getImageData !== "undefined"; - - case "setLineDash": - return typeof ctx.setLineDash !== "undefined"; - - case "toDataURL": - return typeof el.toDataURL !== "undefined"; - - case "toDataURLWithQuality": - try { - el.toDataURL("image/jpeg", 0); - return true; - } catch (e) {} - return false; - - default: - return null; - } - } - }); - fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject; -})(); - -fabric.BaseBrush = fabric.util.createClass({ - color: "rgb(0, 0, 0)", - width: 1, - shadow: null, - strokeLineCap: "round", - strokeLineJoin: "round", - strokeDashArray: null, - setShadow: function(options) { - this.shadow = new fabric.Shadow(options); - return this; - }, - _setBrushStyles: function() { - var ctx = this.canvas.contextTop; - ctx.strokeStyle = this.color; - ctx.lineWidth = this.width; - ctx.lineCap = this.strokeLineCap; - ctx.lineJoin = this.strokeLineJoin; - if (this.strokeDashArray && fabric.StaticCanvas.supports("setLineDash")) { - ctx.setLineDash(this.strokeDashArray); - } - }, - _setShadow: function() { - if (!this.shadow) { - return; - } - var ctx = this.canvas.contextTop; - ctx.shadowColor = this.shadow.color; - ctx.shadowBlur = this.shadow.blur; - ctx.shadowOffsetX = this.shadow.offsetX; - ctx.shadowOffsetY = this.shadow.offsetY; - }, - _resetShadow: function() { - var ctx = this.canvas.contextTop; - ctx.shadowColor = ""; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - } -}); - -(function() { - fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, { - initialize: function(canvas) { - this.canvas = canvas; - this._points = []; - }, - onMouseDown: function(pointer) { - this._prepareForDrawing(pointer); - this._captureDrawingPath(pointer); - this._render(); - }, - onMouseMove: function(pointer) { - this._captureDrawingPath(pointer); - this.canvas.clearContext(this.canvas.contextTop); - this._render(); - }, - onMouseUp: function() { - this._finalizeAndAddPath(); - }, - _prepareForDrawing: function(pointer) { - var p = new fabric.Point(pointer.x, pointer.y); - this._reset(); - this._addPoint(p); - this.canvas.contextTop.moveTo(p.x, p.y); - }, - _addPoint: function(point) { - this._points.push(point); - }, - _reset: function() { - this._points.length = 0; - this._setBrushStyles(); - this._setShadow(); - }, - _captureDrawingPath: function(pointer) { - var pointerPoint = new fabric.Point(pointer.x, pointer.y); - this._addPoint(pointerPoint); - }, - _render: function() { - var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform, p1 = this._points[0], p2 = this._points[1]; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - ctx.beginPath(); - if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) { - p1.x -= .5; - p2.x += .5; - } - ctx.moveTo(p1.x, p1.y); - for (var i = 1, len = this._points.length; i < len; i++) { - var midPoint = p1.midPointFrom(p2); - ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y); - p1 = this._points[i]; - p2 = this._points[i + 1]; - } - ctx.lineTo(p1.x, p1.y); - ctx.stroke(); - ctx.restore(); - }, - convertPointsToSVGPath: function(points) { - var path = [], p1 = new fabric.Point(points[0].x, points[0].y), p2 = new fabric.Point(points[1].x, points[1].y); - path.push("M ", points[0].x, " ", points[0].y, " "); - for (var i = 1, len = points.length; i < len; i++) { - var midPoint = p1.midPointFrom(p2); - path.push("Q ", p1.x, " ", p1.y, " ", midPoint.x, " ", midPoint.y, " "); - p1 = new fabric.Point(points[i].x, points[i].y); - if (i + 1 < points.length) { - p2 = new fabric.Point(points[i + 1].x, points[i + 1].y); - } - } - path.push("L ", p1.x, " ", p1.y, " "); - return path; - }, - createPath: function(pathData) { - var path = new fabric.Path(pathData, { - fill: null, - stroke: this.color, - strokeWidth: this.width, - strokeLineCap: this.strokeLineCap, - strokeLineJoin: this.strokeLineJoin, - strokeDashArray: this.strokeDashArray, - originX: "center", - originY: "center" - }); - if (this.shadow) { - this.shadow.affectStroke = true; - path.setShadow(this.shadow); - } - return path; - }, - _finalizeAndAddPath: function() { - var ctx = this.canvas.contextTop; - ctx.closePath(); - var pathData = this.convertPointsToSVGPath(this._points).join(""); - if (pathData === "M 0 0 Q 0 0 0 0 L 0 0") { - this.canvas.renderAll(); - return; - } - var path = this.createPath(pathData); - this.canvas.add(path); - path.setCoords(); - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderAll(); - this.canvas.fire("path:created", { - path: path - }); - } - }); -})(); - -fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, { - width: 10, - initialize: function(canvas) { - this.canvas = canvas; - this.points = []; - }, - drawDot: function(pointer) { - var point = this.addPoint(pointer), ctx = this.canvas.contextTop, v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - ctx.fillStyle = point.fill; - ctx.beginPath(); - ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); - ctx.closePath(); - ctx.fill(); - ctx.restore(); - }, - onMouseDown: function(pointer) { - this.points.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - this.drawDot(pointer); - }, - onMouseMove: function(pointer) { - this.drawDot(pointer); - }, - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; - this.canvas.renderOnAddRemove = false; - var circles = []; - for (var i = 0, len = this.points.length; i < len; i++) { - var point = this.points[i], circle = new fabric.Circle({ - radius: point.radius, - left: point.x, - top: point.y, - originX: "center", - originY: "center", - fill: point.fill - }); - this.shadow && circle.setShadow(this.shadow); - circles.push(circle); - } - var group = new fabric.Group(circles, { - originX: "center", - originY: "center" - }); - group.canvas = this.canvas; - this.canvas.add(group); - this.canvas.fire("path:created", { - path: group - }); - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); - }, - addPoint: function(pointer) { - var pointerPoint = new fabric.Point(pointer.x, pointer.y), circleRadius = fabric.util.getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2, circleColor = new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0, 100) / 100).toRgba(); - pointerPoint.radius = circleRadius; - pointerPoint.fill = circleColor; - this.points.push(pointerPoint); - return pointerPoint; - } -}); - -fabric.SprayBrush = fabric.util.createClass(fabric.BaseBrush, { - width: 10, - density: 20, - dotWidth: 1, - dotWidthVariance: 1, - randomOpacity: false, - optimizeOverlapping: true, - initialize: function(canvas) { - this.canvas = canvas; - this.sprayChunks = []; - }, - onMouseDown: function(pointer) { - this.sprayChunks.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - this.addSprayChunk(pointer); - this.render(); - }, - onMouseMove: function(pointer) { - this.addSprayChunk(pointer); - this.render(); - }, - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; - this.canvas.renderOnAddRemove = false; - var rects = []; - for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { - var sprayChunk = this.sprayChunks[i]; - for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) { - var rect = new fabric.Rect({ - width: sprayChunk[j].width, - height: sprayChunk[j].width, - left: sprayChunk[j].x + 1, - top: sprayChunk[j].y + 1, - originX: "center", - originY: "center", - fill: this.color - }); - this.shadow && rect.setShadow(this.shadow); - rects.push(rect); - } - } - if (this.optimizeOverlapping) { - rects = this._getOptimizedRects(rects); - } - var group = new fabric.Group(rects, { - originX: "center", - originY: "center" - }); - group.canvas = this.canvas; - this.canvas.add(group); - this.canvas.fire("path:created", { - path: group - }); - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); - }, - _getOptimizedRects: function(rects) { - var uniqueRects = {}, key; - for (var i = 0, len = rects.length; i < len; i++) { - key = rects[i].left + "" + rects[i].top; - if (!uniqueRects[key]) { - uniqueRects[key] = rects[i]; - } - } - var uniqueRectsArray = []; - for (key in uniqueRects) { - uniqueRectsArray.push(uniqueRects[key]); - } - return uniqueRectsArray; - }, - render: function() { - var ctx = this.canvas.contextTop; - ctx.fillStyle = this.color; - var v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - for (var i = 0, len = this.sprayChunkPoints.length; i < len; i++) { - var point = this.sprayChunkPoints[i]; - if (typeof point.opacity !== "undefined") { - ctx.globalAlpha = point.opacity; - } - ctx.fillRect(point.x, point.y, point.width, point.width); - } - ctx.restore(); - }, - addSprayChunk: function(pointer) { - this.sprayChunkPoints = []; - var x, y, width, radius = this.width / 2; - for (var i = 0; i < this.density; i++) { - x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius); - y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius); - if (this.dotWidthVariance) { - width = fabric.util.getRandomInt(Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance); - } else { - width = this.dotWidth; - } - var point = new fabric.Point(x, y); - point.width = width; - if (this.randomOpacity) { - point.opacity = fabric.util.getRandomInt(0, 100) / 100; - } - this.sprayChunkPoints.push(point); - } - this.sprayChunks.push(this.sprayChunkPoints); - } -}); - -fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { - getPatternSrc: function() { - var dotWidth = 20, dotDistance = 5, patternCanvas = fabric.document.createElement("canvas"), patternCtx = patternCanvas.getContext("2d"); - patternCanvas.width = patternCanvas.height = dotWidth + dotDistance; - patternCtx.fillStyle = this.color; - patternCtx.beginPath(); - patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); - patternCtx.closePath(); - patternCtx.fill(); - return patternCanvas; - }, - getPatternSrcFunction: function() { - return String(this.getPatternSrc).replace("this.color", '"' + this.color + '"'); - }, - getPattern: function() { - return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), "repeat"); - }, - _setBrushStyles: function() { - this.callSuper("_setBrushStyles"); - this.canvas.contextTop.strokeStyle = this.getPattern(); - }, - createPath: function(pathData) { - var path = this.callSuper("createPath", pathData); - path.stroke = new fabric.Pattern({ - source: this.source || this.getPatternSrcFunction() - }); - return path; - } -}); - -(function() { - var getPointer = fabric.util.getPointer, degreesToRadians = fabric.util.degreesToRadians, radiansToDegrees = fabric.util.radiansToDegrees, atan2 = Math.atan2, abs = Math.abs, STROKE_OFFSET = .5; - fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, { - initialize: function(el, options) { - options || (options = {}); - this._initStatic(el, options); - this._initInteractive(); - this._createCacheCanvas(); - }, - uniScaleTransform: false, - centeredScaling: false, - centeredRotation: false, - interactive: true, - selection: true, - selectionColor: "rgba(100, 100, 255, 0.3)", - selectionDashArray: [], - selectionBorderColor: "rgba(255, 255, 255, 0.3)", - selectionLineWidth: 1, - hoverCursor: "move", - moveCursor: "move", - defaultCursor: "default", - freeDrawingCursor: "crosshair", - rotationCursor: "crosshair", - containerClass: "canvas-container", - perPixelTargetFind: false, - targetFindTolerance: 0, - skipTargetFind: false, - isDrawingMode: false, - _initInteractive: function() { - this._currentTransform = null; - this._groupSelector = null; - this._initWrapperElement(); - this._createUpperCanvas(); - this._initEventListeners(); - this._initRetinaScaling(); - this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this); - this.calcOffset(); - }, - _resetCurrentTransform: function() { - var t = this._currentTransform; - t.target.set({ - scaleX: t.original.scaleX, - scaleY: t.original.scaleY, - skewX: t.original.skewX, - skewY: t.original.skewY, - left: t.original.left, - top: t.original.top - }); - if (this._shouldCenterTransform(t.target)) { - if (t.action === "rotate") { - this._setOriginToCenter(t.target); - } else { - if (t.originX !== "center") { - if (t.originX === "right") { - t.mouseXSign = -1; - } else { - t.mouseXSign = 1; - } - } - if (t.originY !== "center") { - if (t.originY === "bottom") { - t.mouseYSign = -1; - } else { - t.mouseYSign = 1; - } - } - t.originX = "center"; - t.originY = "center"; - } - } else { - t.originX = t.original.originX; - t.originY = t.original.originY; - } - }, - containsPoint: function(e, target) { - var pointer = this.getPointer(e, true), xy = this._normalizePointer(target, pointer); - return target.containsPoint(xy) || target._findTargetCorner(pointer); - }, - _normalizePointer: function(object, pointer) { - var activeGroup = this.getActiveGroup(), isObjectInGroup = activeGroup && object.type !== "group" && activeGroup.contains(object), lt, m; - if (isObjectInGroup) { - m = fabric.util.multiplyTransformMatrices(this.viewportTransform, activeGroup.calcTransformMatrix()); - m = fabric.util.invertTransform(m); - pointer = fabric.util.transformPoint(pointer, m, false); - lt = fabric.util.transformPoint(activeGroup.getCenterPoint(), m, false); - pointer.x -= lt.x; - pointer.y -= lt.y; - } - return { - x: pointer.x, - y: pointer.y - }; - }, - isTargetTransparent: function(target, x, y) { - var hasBorders = target.hasBorders, transparentCorners = target.transparentCorners; - target.hasBorders = target.transparentCorners = false; - target.render(this.contextCache); - target._renderControls(this.contextCache); - target.hasBorders = hasBorders; - target.transparentCorners = transparentCorners; - var isTransparent = fabric.util.isTransparent(this.contextCache, x, y, this.targetFindTolerance); - this.clearContext(this.contextCache); - return isTransparent; - }, - _shouldClearSelection: function(e, target) { - var activeGroup = this.getActiveGroup(), activeObject = this.getActiveObject(); - return !target || target && activeGroup && !activeGroup.contains(target) && activeGroup !== target && !e.shiftKey || target && !target.evented || target && !target.selectable && activeObject && activeObject !== target; - }, - _shouldCenterTransform: function(target) { - if (!target) { - return; - } - var t = this._currentTransform, centerTransform; - if (t.action === "scale" || t.action === "scaleX" || t.action === "scaleY") { - centerTransform = this.centeredScaling || target.centeredScaling; - } else if (t.action === "rotate") { - centerTransform = this.centeredRotation || target.centeredRotation; - } - return centerTransform ? !t.altKey : t.altKey; - }, - _getOriginFromCorner: function(target, corner) { - var origin = { - x: target.originX, - y: target.originY - }; - if (corner === "ml" || corner === "tl" || corner === "bl") { - origin.x = "right"; - } else if (corner === "mr" || corner === "tr" || corner === "br") { - origin.x = "left"; - } - if (corner === "tl" || corner === "mt" || corner === "tr") { - origin.y = "bottom"; - } else if (corner === "bl" || corner === "mb" || corner === "br") { - origin.y = "top"; - } - return origin; - }, - _getActionFromCorner: function(target, corner, e) { - if (!corner) { - return "drag"; - } - switch (corner) { - case "mtr": - return "rotate"; - - case "ml": - case "mr": - return e.shiftKey ? "skewY" : "scaleX"; - - case "mt": - case "mb": - return e.shiftKey ? "skewX" : "scaleY"; - - default: - return "scale"; - } - }, - _setupCurrentTransform: function(e, target) { - if (!target) { - return; - } - var pointer = this.getPointer(e), corner = target._findTargetCorner(this.getPointer(e, true)), action = this._getActionFromCorner(target, corner, e), origin = this._getOriginFromCorner(target, corner); - this._currentTransform = { - target: target, - action: action, - corner: corner, - scaleX: target.scaleX, - scaleY: target.scaleY, - skewX: target.skewX, - skewY: target.skewY, - offsetX: pointer.x - target.left, - offsetY: pointer.y - target.top, - originX: origin.x, - originY: origin.y, - ex: pointer.x, - ey: pointer.y, - lastX: pointer.x, - lastY: pointer.y, - left: target.left, - top: target.top, - theta: degreesToRadians(target.angle), - width: target.width * target.scaleX, - mouseXSign: 1, - mouseYSign: 1, - shiftKey: e.shiftKey, - altKey: e.altKey - }; - this._currentTransform.original = { - left: target.left, - top: target.top, - scaleX: target.scaleX, - scaleY: target.scaleY, - skewX: target.skewX, - skewY: target.skewY, - originX: origin.x, - originY: origin.y - }; - this._resetCurrentTransform(); - }, - _translateObject: function(x, y) { - var transform = this._currentTransform, target = transform.target, newLeft = x - transform.offsetX, newTop = y - transform.offsetY, moveX = !target.get("lockMovementX") && target.left !== newLeft, moveY = !target.get("lockMovementY") && target.top !== newTop; - moveX && target.set("left", newLeft); - moveY && target.set("top", newTop); - return moveX || moveY; - }, - _changeSkewTransformOrigin: function(mouseMove, t, by) { - var property = "originX", origins = { - 0: "center" - }, skew = t.target.skewX, originA = "left", originB = "right", corner = t.corner === "mt" || t.corner === "ml" ? 1 : -1, flipSign = 1; - mouseMove = mouseMove > 0 ? 1 : -1; - if (by === "y") { - skew = t.target.skewY; - originA = "top"; - originB = "bottom"; - property = "originY"; - } - origins[-1] = originA; - origins[1] = originB; - t.target.flipX && (flipSign *= -1); - t.target.flipY && (flipSign *= -1); - if (skew === 0) { - t.skewSign = -corner * mouseMove * flipSign; - t[property] = origins[-mouseMove]; - } else { - skew = skew > 0 ? 1 : -1; - t.skewSign = skew; - t[property] = origins[skew * corner * flipSign]; - } - }, - _skewObject: function(x, y, by) { - var t = this._currentTransform, target = t.target, skewed = false, lockSkewingX = target.get("lockSkewingX"), lockSkewingY = target.get("lockSkewingY"); - if (lockSkewingX && by === "x" || lockSkewingY && by === "y") { - return false; - } - var center = target.getCenterPoint(), actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), "center", "center")[by], lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), "center", "center")[by], actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions(); - this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by); - actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by], - constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY); - skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim); - t.lastX = x; - t.lastY = y; - target.setPositionByOrigin(constraintPosition, t.originX, t.originY); - return skewed; - }, - _setObjectSkew: function(localMouse, transform, by, _dim) { - var target = transform.target, newValue, skewed = false, skewSign = transform.skewSign, newDim, dimNoSkew, otherBy, _otherBy, _by, newDimMouse, skewX, skewY; - if (by === "x") { - otherBy = "y"; - _otherBy = "Y"; - _by = "X"; - skewX = 0; - skewY = target.skewY; - } else { - otherBy = "x"; - _otherBy = "X"; - _by = "Y"; - skewX = target.skewX; - skewY = 0; - } - dimNoSkew = target._getTransformedDimensions(skewX, skewY); - newDimMouse = 2 * Math.abs(localMouse) - dimNoSkew[by]; - if (newDimMouse <= 2) { - newValue = 0; - } else { - newValue = skewSign * Math.atan(newDimMouse / target["scale" + _by] / (dimNoSkew[otherBy] / target["scale" + _otherBy])); - newValue = fabric.util.radiansToDegrees(newValue); - } - skewed = target["skew" + _by] !== newValue; - target.set("skew" + _by, newValue); - if (target["skew" + _otherBy] !== 0) { - newDim = target._getTransformedDimensions(); - newValue = _dim[otherBy] / newDim[otherBy] * target["scale" + _otherBy]; - target.set("scale" + _otherBy, newValue); - } - return skewed; - }, - _scaleObject: function(x, y, by) { - var t = this._currentTransform, target = t.target, lockScalingX = target.get("lockScalingX"), lockScalingY = target.get("lockScalingY"), lockScalingFlip = target.get("lockScalingFlip"); - if (lockScalingX && lockScalingY) { - return false; - } - var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY), localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY), dim = target._getTransformedDimensions(), scaled = false; - this._setLocalMouse(localMouse, t); - scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim); - target.setPositionByOrigin(constraintPosition, t.originX, t.originY); - return scaled; - }, - _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) { - var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false, changeX, changeY, scaleX, scaleY; - scaleX = localMouse.x * target.scaleX / _dim.x; - scaleY = localMouse.y * target.scaleY / _dim.y; - changeX = target.scaleX !== scaleX; - changeY = target.scaleY !== scaleY; - if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) { - forbidScalingX = true; - } - if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) { - forbidScalingY = true; - } - if (by === "equally" && !lockScalingX && !lockScalingY) { - forbidScalingX || forbidScalingY || (scaled = this._scaleObjectEqually(localMouse, target, transform, _dim)); - } else if (!by) { - forbidScalingX || lockScalingX || target.set("scaleX", scaleX) && (scaled = scaled || changeX); - forbidScalingY || lockScalingY || target.set("scaleY", scaleY) && (scaled = scaled || changeY); - } else if (by === "x" && !target.get("lockUniScaling")) { - forbidScalingX || lockScalingX || target.set("scaleX", scaleX) && (scaled = scaled || changeX); - } else if (by === "y" && !target.get("lockUniScaling")) { - forbidScalingY || lockScalingY || target.set("scaleY", scaleY) && (scaled = scaled || changeY); - } - transform.newScaleX = scaleX; - transform.newScaleY = scaleY; - forbidScalingX || forbidScalingY || this._flipObject(transform, by); - return scaled; - }, - _scaleObjectEqually: function(localMouse, target, transform, _dim) { - var dist = localMouse.y + localMouse.x, lastDist = _dim.y * transform.original.scaleY / target.scaleY + _dim.x * transform.original.scaleX / target.scaleX, scaled; - transform.newScaleX = transform.original.scaleX * dist / lastDist; - transform.newScaleY = transform.original.scaleY * dist / lastDist; - scaled = transform.newScaleX !== target.scaleX || transform.newScaleY !== target.scaleY; - target.set("scaleX", transform.newScaleX); - target.set("scaleY", transform.newScaleY); - return scaled; - }, - _flipObject: function(transform, by) { - if (transform.newScaleX < 0 && by !== "y") { - if (transform.originX === "left") { - transform.originX = "right"; - } else if (transform.originX === "right") { - transform.originX = "left"; - } - } - if (transform.newScaleY < 0 && by !== "x") { - if (transform.originY === "top") { - transform.originY = "bottom"; - } else if (transform.originY === "bottom") { - transform.originY = "top"; - } - } - }, - _setLocalMouse: function(localMouse, t) { - var target = t.target; - if (t.originX === "right") { - localMouse.x *= -1; - } else if (t.originX === "center") { - localMouse.x *= t.mouseXSign * 2; - if (localMouse.x < 0) { - t.mouseXSign = -t.mouseXSign; - } - } - if (t.originY === "bottom") { - localMouse.y *= -1; - } else if (t.originY === "center") { - localMouse.y *= t.mouseYSign * 2; - if (localMouse.y < 0) { - t.mouseYSign = -t.mouseYSign; - } - } - if (abs(localMouse.x) > target.padding) { - if (localMouse.x < 0) { - localMouse.x += target.padding; - } else { - localMouse.x -= target.padding; - } - } else { - localMouse.x = 0; - } - if (abs(localMouse.y) > target.padding) { - if (localMouse.y < 0) { - localMouse.y += target.padding; - } else { - localMouse.y -= target.padding; - } - } else { - localMouse.y = 0; - } - }, - _rotateObject: function(x, y) { - var t = this._currentTransform; - if (t.target.get("lockRotation")) { - return false; - } - var lastAngle = atan2(t.ey - t.top, t.ex - t.left), curAngle = atan2(y - t.top, x - t.left), angle = radiansToDegrees(curAngle - lastAngle + t.theta); - if (angle < 0) { - angle = 360 + angle; - } - t.target.angle = angle % 360; - return true; - }, - setCursor: function(value) { - this.upperCanvasEl.style.cursor = value; - }, - _resetObjectTransform: function(target) { - target.scaleX = 1; - target.scaleY = 1; - target.skewX = 0; - target.skewY = 0; - target.setAngle(0); - }, - _drawSelection: function() { - var ctx = this.contextTop, groupSelector = this._groupSelector, left = groupSelector.left, top = groupSelector.top, aleft = abs(left), atop = abs(top); - ctx.fillStyle = this.selectionColor; - ctx.fillRect(groupSelector.ex - (left > 0 ? 0 : -left), groupSelector.ey - (top > 0 ? 0 : -top), aleft, atop); - ctx.lineWidth = this.selectionLineWidth; - ctx.strokeStyle = this.selectionBorderColor; - if (this.selectionDashArray.length > 1) { - var px = groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), py = groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop); - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray); - fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray); - fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray); - fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray); - ctx.closePath(); - ctx.stroke(); - } else { - ctx.strokeRect(groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop), aleft, atop); - } - }, - _isLastRenderedObject: function(e) { - return this.controlsAboveOverlay && this.lastRenderedObjectWithControlsAboveOverlay && this.lastRenderedObjectWithControlsAboveOverlay.visible && this.containsPoint(e, this.lastRenderedObjectWithControlsAboveOverlay) && this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e, true)); - }, - findTarget: function(e, skipGroup) { - if (this.skipTargetFind) { - return; - } - if (this._isLastRenderedObject(e)) { - return this.lastRenderedObjectWithControlsAboveOverlay; - } - var activeGroup = this.getActiveGroup(); - if (activeGroup && !skipGroup && this.containsPoint(e, activeGroup)) { - return activeGroup; - } - var target = this._searchPossibleTargets(e, skipGroup); - this._fireOverOutEvents(target, e); - return target; - }, - _fireOverOutEvents: function(target, e) { - if (target) { - if (this._hoveredTarget !== target) { - if (this._hoveredTarget) { - this.fire("mouse:out", { - target: this._hoveredTarget, - e: e - }); - this._hoveredTarget.fire("mouseout"); - } - this.fire("mouse:over", { - target: target, - e: e - }); - target.fire("mouseover"); - this._hoveredTarget = target; - } - } else if (this._hoveredTarget) { - this.fire("mouse:out", { - target: this._hoveredTarget, - e: e - }); - this._hoveredTarget.fire("mouseout"); - this._hoveredTarget = null; - } - }, - _checkTarget: function(e, obj, pointer) { - if (obj && obj.visible && obj.evented && this.containsPoint(e, obj)) { - if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { - var isTransparent = this.isTargetTransparent(obj, pointer.x, pointer.y); - if (!isTransparent) { - return true; - } - } else { - return true; - } - } - }, - _searchPossibleTargets: function(e, skipGroup) { - var target, pointer = this.getPointer(e, true), i = this._objects.length; - while (i--) { - if ((!this._objects[i].group || skipGroup) && this._checkTarget(e, this._objects[i], pointer)) { - this.relatedTarget = this._objects[i]; - target = this._objects[i]; - break; - } - } - return target; - }, - getPointer: function(e, ignoreZoom, upperCanvasEl) { - if (!upperCanvasEl) { - upperCanvasEl = this.upperCanvasEl; - } - var pointer = getPointer(e), bounds = upperCanvasEl.getBoundingClientRect(), boundsWidth = bounds.width || 0, boundsHeight = bounds.height || 0, cssScale; - if (!boundsWidth || !boundsHeight) { - if ("top" in bounds && "bottom" in bounds) { - boundsHeight = Math.abs(bounds.top - bounds.bottom); - } - if ("right" in bounds && "left" in bounds) { - boundsWidth = Math.abs(bounds.right - bounds.left); - } - } - this.calcOffset(); - pointer.x = pointer.x - this._offset.left; - pointer.y = pointer.y - this._offset.top; - if (!ignoreZoom) { - pointer = fabric.util.transformPoint(pointer, fabric.util.invertTransform(this.viewportTransform)); - } - if (boundsWidth === 0 || boundsHeight === 0) { - cssScale = { - width: 1, - height: 1 - }; - } else { - cssScale = { - width: upperCanvasEl.width / boundsWidth, - height: upperCanvasEl.height / boundsHeight - }; - } - return { - x: pointer.x * cssScale.width, - y: pointer.y * cssScale.height - }; - }, - _createUpperCanvas: function() { - var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ""); - this.upperCanvasEl = this._createCanvasElement(); - fabric.util.addClass(this.upperCanvasEl, "upper-canvas " + lowerCanvasClass); - this.wrapperEl.appendChild(this.upperCanvasEl); - this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl); - this._applyCanvasStyle(this.upperCanvasEl); - this.contextTop = this.upperCanvasEl.getContext("2d"); - }, - _createCacheCanvas: function() { - this.cacheCanvasEl = this._createCanvasElement(); - this.cacheCanvasEl.setAttribute("width", this.width); - this.cacheCanvasEl.setAttribute("height", this.height); - this.contextCache = this.cacheCanvasEl.getContext("2d"); - }, - _initWrapperElement: function() { - this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, "div", { - "class": this.containerClass - }); - fabric.util.setStyle(this.wrapperEl, { - width: this.getWidth() + "px", - height: this.getHeight() + "px", - position: "relative" - }); - fabric.util.makeElementUnselectable(this.wrapperEl); - }, - _applyCanvasStyle: function(element) { - var width = this.getWidth() || element.width, height = this.getHeight() || element.height; - fabric.util.setStyle(element, { - position: "absolute", - width: width + "px", - height: height + "px", - left: 0, - top: 0 - }); - element.width = width; - element.height = height; - fabric.util.makeElementUnselectable(element); - }, - _copyCanvasStyle: function(fromEl, toEl) { - toEl.style.cssText = fromEl.style.cssText; - }, - getSelectionContext: function() { - return this.contextTop; - }, - getSelectionElement: function() { - return this.upperCanvasEl; - }, - _setActiveObject: function(object) { - if (this._activeObject) { - this._activeObject.set("active", false); - } - this._activeObject = object; - object.set("active", true); - }, - setActiveObject: function(object, e) { - this._setActiveObject(object); - this.renderAll(); - this.fire("object:selected", { - target: object, - e: e - }); - object.fire("selected", { - e: e - }); - return this; - }, - getActiveObject: function() { - return this._activeObject; - }, - _discardActiveObject: function() { - if (this._activeObject) { - this._activeObject.set("active", false); - } - this._activeObject = null; - }, - discardActiveObject: function(e) { - this._discardActiveObject(); - this.renderAll(); - this.fire("selection:cleared", { - e: e - }); - return this; - }, - _setActiveGroup: function(group) { - this._activeGroup = group; - if (group) { - group.set("active", true); - } - }, - setActiveGroup: function(group, e) { - this._setActiveGroup(group); - if (group) { - this.fire("object:selected", { - target: group, - e: e - }); - group.fire("selected", { - e: e - }); - } - return this; - }, - getActiveGroup: function() { - return this._activeGroup; - }, - _discardActiveGroup: function() { - var g = this.getActiveGroup(); - if (g) { - g.destroy(); - } - this.setActiveGroup(null); - }, - discardActiveGroup: function(e) { - this._discardActiveGroup(); - this.fire("selection:cleared", { - e: e - }); - return this; - }, - deactivateAll: function() { - var allObjects = this.getObjects(), i = 0, len = allObjects.length; - for (;i < len; i++) { - allObjects[i].set("active", false); - } - this._discardActiveGroup(); - this._discardActiveObject(); - return this; - }, - deactivateAllWithDispatch: function(e) { - var activeObject = this.getActiveGroup() || this.getActiveObject(); - if (activeObject) { - this.fire("before:selection:cleared", { - target: activeObject, - e: e - }); - } - this.deactivateAll(); - if (activeObject) { - this.fire("selection:cleared", { - e: e - }); - } - return this; - }, - dispose: function() { - this.callSuper("dispose"); - var wrapper = this.wrapperEl; - this.removeListeners(); - wrapper.removeChild(this.upperCanvasEl); - wrapper.removeChild(this.lowerCanvasEl); - delete this.upperCanvasEl; - if (wrapper.parentNode) { - wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl); - } - delete this.wrapperEl; - return this; - }, - drawControls: function(ctx) { - var activeGroup = this.getActiveGroup(); - if (activeGroup) { - activeGroup._renderControls(ctx); - } else { - this._drawObjectsControls(ctx); - } - }, - _drawObjectsControls: function(ctx) { - for (var i = 0, len = this._objects.length; i < len; ++i) { - if (!this._objects[i] || !this._objects[i].active) { - continue; - } - this._objects[i]._renderControls(ctx); - this.lastRenderedObjectWithControlsAboveOverlay = this._objects[i]; - } - } - }); - for (var prop in fabric.StaticCanvas) { - if (prop !== "prototype") { - fabric.Canvas[prop] = fabric.StaticCanvas[prop]; - } - } - if (fabric.isTouchSupported) { - fabric.Canvas.prototype._setCursorFromEvent = function() {}; - } - fabric.Element = fabric.Canvas; -})(); - -(function() { - var cursorOffset = { - mt: 0, - tr: 1, - mr: 2, - br: 3, - mb: 4, - bl: 5, - ml: 6, - tl: 7 - }, addListener = fabric.util.addListener, removeListener = fabric.util.removeListener; - fabric.util.object.extend(fabric.Canvas.prototype, { - cursorMap: [ "n-resize", "ne-resize", "e-resize", "se-resize", "s-resize", "sw-resize", "w-resize", "nw-resize" ], - _initEventListeners: function() { - this._bindEvents(); - addListener(fabric.window, "resize", this._onResize); - addListener(this.upperCanvasEl, "mousedown", this._onMouseDown); - addListener(this.upperCanvasEl, "mousemove", this._onMouseMove); - addListener(this.upperCanvasEl, "mousewheel", this._onMouseWheel); - addListener(this.upperCanvasEl, "touchstart", this._onMouseDown); - addListener(this.upperCanvasEl, "touchmove", this._onMouseMove); - if (typeof eventjs !== "undefined" && "add" in eventjs) { - eventjs.add(this.upperCanvasEl, "gesture", this._onGesture); - eventjs.add(this.upperCanvasEl, "drag", this._onDrag); - eventjs.add(this.upperCanvasEl, "orientation", this._onOrientationChange); - eventjs.add(this.upperCanvasEl, "shake", this._onShake); - eventjs.add(this.upperCanvasEl, "longpress", this._onLongPress); - } - }, - _bindEvents: function() { - this._onMouseDown = this._onMouseDown.bind(this); - this._onMouseMove = this._onMouseMove.bind(this); - this._onMouseUp = this._onMouseUp.bind(this); - this._onResize = this._onResize.bind(this); - this._onGesture = this._onGesture.bind(this); - this._onDrag = this._onDrag.bind(this); - this._onShake = this._onShake.bind(this); - this._onLongPress = this._onLongPress.bind(this); - this._onOrientationChange = this._onOrientationChange.bind(this); - this._onMouseWheel = this._onMouseWheel.bind(this); - }, - removeListeners: function() { - removeListener(fabric.window, "resize", this._onResize); - removeListener(this.upperCanvasEl, "mousedown", this._onMouseDown); - removeListener(this.upperCanvasEl, "mousemove", this._onMouseMove); - removeListener(this.upperCanvasEl, "mousewheel", this._onMouseWheel); - removeListener(this.upperCanvasEl, "touchstart", this._onMouseDown); - removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove); - if (typeof eventjs !== "undefined" && "remove" in eventjs) { - eventjs.remove(this.upperCanvasEl, "gesture", this._onGesture); - eventjs.remove(this.upperCanvasEl, "drag", this._onDrag); - eventjs.remove(this.upperCanvasEl, "orientation", this._onOrientationChange); - eventjs.remove(this.upperCanvasEl, "shake", this._onShake); - eventjs.remove(this.upperCanvasEl, "longpress", this._onLongPress); - } - }, - _onGesture: function(e, self) { - this.__onTransformGesture && this.__onTransformGesture(e, self); - }, - _onDrag: function(e, self) { - this.__onDrag && this.__onDrag(e, self); - }, - _onMouseWheel: function(e, self) { - this.__onMouseWheel && this.__onMouseWheel(e, self); - }, - _onOrientationChange: function(e, self) { - this.__onOrientationChange && this.__onOrientationChange(e, self); - }, - _onShake: function(e, self) { - this.__onShake && this.__onShake(e, self); - }, - _onLongPress: function(e, self) { - this.__onLongPress && this.__onLongPress(e, self); - }, - _onMouseDown: function(e) { - this.__onMouseDown(e); - addListener(fabric.document, "touchend", this._onMouseUp); - addListener(fabric.document, "touchmove", this._onMouseMove); - removeListener(this.upperCanvasEl, "mousemove", this._onMouseMove); - removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove); - if (e.type === "touchstart") { - removeListener(this.upperCanvasEl, "mousedown", this._onMouseDown); - } else { - addListener(fabric.document, "mouseup", this._onMouseUp); - addListener(fabric.document, "mousemove", this._onMouseMove); - } - }, - _onMouseUp: function(e) { - this.__onMouseUp(e); - removeListener(fabric.document, "mouseup", this._onMouseUp); - removeListener(fabric.document, "touchend", this._onMouseUp); - removeListener(fabric.document, "mousemove", this._onMouseMove); - removeListener(fabric.document, "touchmove", this._onMouseMove); - addListener(this.upperCanvasEl, "mousemove", this._onMouseMove); - addListener(this.upperCanvasEl, "touchmove", this._onMouseMove); - if (e.type === "touchend") { - var _this = this; - setTimeout(function() { - addListener(_this.upperCanvasEl, "mousedown", _this._onMouseDown); - }, 400); - } - }, - _onMouseMove: function(e) { - !this.allowTouchScrolling && e.preventDefault && e.preventDefault(); - this.__onMouseMove(e); - }, - _onResize: function() { - this.calcOffset(); - }, - _shouldRender: function(target, pointer) { - var activeObject = this.getActiveGroup() || this.getActiveObject(); - return !!(target && (target.isMoving || target !== activeObject) || !target && !!activeObject || !target && !activeObject && !this._groupSelector || pointer && this._previousPointer && this.selection && (pointer.x !== this._previousPointer.x || pointer.y !== this._previousPointer.y)); - }, - __onMouseUp: function(e) { - var target; - if (this.isDrawingMode && this._isCurrentlyDrawing) { - this._onMouseUpInDrawingMode(e); - return; - } - if (this._currentTransform) { - this._finalizeCurrentTransform(); - target = this._currentTransform.target; - } else { - target = this.findTarget(e, true); - } - var shouldRender = this._shouldRender(target, this.getPointer(e)); - this._maybeGroupObjects(e); - if (target) { - target.isMoving = false; - } - shouldRender && this.renderAll(); - this._handleCursorAndEvent(e, target); - }, - _handleCursorAndEvent: function(e, target) { - this._setCursorFromEvent(e, target); - var _this = this; - setTimeout(function() { - _this._setCursorFromEvent(e, target); - }, 50); - this.fire("mouse:up", { - target: target, - e: e - }); - target && target.fire("mouseup", { - e: e - }); - }, - _finalizeCurrentTransform: function() { - var transform = this._currentTransform, target = transform.target; - if (target._scaling) { - target._scaling = false; - } - target.setCoords(); - this._restoreOriginXY(target); - if (transform.actionPerformed || this.stateful && target.hasStateChanged()) { - this.fire("object:modified", { - target: target - }); - target.fire("modified"); - } - }, - _restoreOriginXY: function(target) { - if (this._previousOriginX && this._previousOriginY) { - var originPoint = target.translateToOriginPoint(target.getCenterPoint(), this._previousOriginX, this._previousOriginY); - target.originX = this._previousOriginX; - target.originY = this._previousOriginY; - target.left = originPoint.x; - target.top = originPoint.y; - this._previousOriginX = null; - this._previousOriginY = null; - } - }, - _onMouseDownInDrawingMode: function(e) { - this._isCurrentlyDrawing = true; - this.discardActiveObject(e).renderAll(); - if (this.clipTo) { - fabric.util.clipContext(this, this.contextTop); - } - var ivt = fabric.util.invertTransform(this.viewportTransform), pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); - this.freeDrawingBrush.onMouseDown(pointer); - this.fire("mouse:down", { - e: e - }); - var target = this.findTarget(e); - if (typeof target !== "undefined") { - target.fire("mousedown", { - e: e, - target: target - }); - } - }, - _onMouseMoveInDrawingMode: function(e) { - if (this._isCurrentlyDrawing) { - var ivt = fabric.util.invertTransform(this.viewportTransform), pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); - this.freeDrawingBrush.onMouseMove(pointer); - } - this.setCursor(this.freeDrawingCursor); - this.fire("mouse:move", { - e: e - }); - var target = this.findTarget(e); - if (typeof target !== "undefined") { - target.fire("mousemove", { - e: e, - target: target - }); - } - }, - _onMouseUpInDrawingMode: function(e) { - this._isCurrentlyDrawing = false; - if (this.clipTo) { - this.contextTop.restore(); - } - this.freeDrawingBrush.onMouseUp(); - this.fire("mouse:up", { - e: e - }); - var target = this.findTarget(e); - if (typeof target !== "undefined") { - target.fire("mouseup", { - e: e, - target: target - }); - } - }, - __onMouseDown: function(e) { - var isLeftClick = "which" in e ? e.which === 1 : e.button === 0; - if (!isLeftClick && !fabric.isTouchSupported) { - return; - } - if (this.isDrawingMode) { - this._onMouseDownInDrawingMode(e); - return; - } - if (this._currentTransform) { - return; - } - var target = this.findTarget(e), pointer = this.getPointer(e, true); - this._previousPointer = pointer; - var shouldRender = this._shouldRender(target, pointer), shouldGroup = this._shouldGroup(e, target); - if (this._shouldClearSelection(e, target)) { - this._clearSelection(e, target, pointer); - } else if (shouldGroup) { - this._handleGrouping(e, target); - target = this.getActiveGroup(); - } - if (target && target.selectable && (target.__corner || !shouldGroup)) { - this._beforeTransform(e, target); - this._setupCurrentTransform(e, target); - } - shouldRender && this.renderAll(); - this.fire("mouse:down", { - target: target, - e: e - }); - target && target.fire("mousedown", { - e: e - }); - }, - _beforeTransform: function(e, target) { - this.stateful && target.saveState(); - if (target._findTargetCorner(this.getPointer(e))) { - this.onBeforeScaleRotate(target); - } - if (target !== this.getActiveGroup() && target !== this.getActiveObject()) { - this.deactivateAll(); - this.setActiveObject(target, e); - } - }, - _clearSelection: function(e, target, pointer) { - this.deactivateAllWithDispatch(e); - if (target && target.selectable) { - this.setActiveObject(target, e); - } else if (this.selection) { - this._groupSelector = { - ex: pointer.x, - ey: pointer.y, - top: 0, - left: 0 - }; - } - }, - _setOriginToCenter: function(target) { - this._previousOriginX = this._currentTransform.target.originX; - this._previousOriginY = this._currentTransform.target.originY; - var center = target.getCenterPoint(); - target.originX = "center"; - target.originY = "center"; - target.left = center.x; - target.top = center.y; - this._currentTransform.left = target.left; - this._currentTransform.top = target.top; - }, - _setCenterToOrigin: function(target) { - var originPoint = target.translateToOriginPoint(target.getCenterPoint(), this._previousOriginX, this._previousOriginY); - target.originX = this._previousOriginX; - target.originY = this._previousOriginY; - target.left = originPoint.x; - target.top = originPoint.y; - this._previousOriginX = null; - this._previousOriginY = null; - }, - __onMouseMove: function(e) { - var target, pointer; - if (this.isDrawingMode) { - this._onMouseMoveInDrawingMode(e); - return; - } - if (typeof e.touches !== "undefined" && e.touches.length > 1) { - return; - } - var groupSelector = this._groupSelector; - if (groupSelector) { - pointer = this.getPointer(e, true); - groupSelector.left = pointer.x - groupSelector.ex; - groupSelector.top = pointer.y - groupSelector.ey; - this.renderTop(); - } else if (!this._currentTransform) { - target = this.findTarget(e); - if (!target || target && !target.selectable) { - this.setCursor(this.defaultCursor); - } else { - this._setCursorFromEvent(e, target); - } - } else { - this._transformObject(e); - } - this.fire("mouse:move", { - target: target, - e: e - }); - target && target.fire("mousemove", { - e: e - }); - }, - _transformObject: function(e) { - var pointer = this.getPointer(e), transform = this._currentTransform; - transform.reset = false, transform.target.isMoving = true; - this._beforeScaleTransform(e, transform); - this._performTransformAction(e, transform, pointer); - this.renderAll(); - }, - _performTransformAction: function(e, transform, pointer) { - var x = pointer.x, y = pointer.y, target = transform.target, action = transform.action, actionPerformed = false; - if (action === "rotate") { - (actionPerformed = this._rotateObject(x, y)) && this._fire("rotating", target, e); - } else if (action === "scale") { - (actionPerformed = this._onScale(e, transform, x, y)) && this._fire("scaling", target, e); - } else if (action === "scaleX") { - (actionPerformed = this._scaleObject(x, y, "x")) && this._fire("scaling", target, e); - } else if (action === "scaleY") { - (actionPerformed = this._scaleObject(x, y, "y")) && this._fire("scaling", target, e); - } else if (action === "skewX") { - (actionPerformed = this._skewObject(x, y, "x")) && this._fire("skewing", target, e); - } else if (action === "skewY") { - (actionPerformed = this._skewObject(x, y, "y")) && this._fire("skewing", target, e); - } else { - (actionPerformed = this._translateObject(x, y)) && this._fire("moving", target, e); - this.setCursor(this.moveCursor); - } - transform.actionPerformed = actionPerformed; - }, - _fire: function(eventName, target, e) { - this.fire("object:" + eventName, { - target: target, - e: e - }); - target.fire(eventName, { - e: e - }); - }, - _beforeScaleTransform: function(e, transform) { - if (transform.action === "scale" || transform.action === "scaleX" || transform.action === "scaleY") { - var centerTransform = this._shouldCenterTransform(transform.target); - if (centerTransform && (transform.originX !== "center" || transform.originY !== "center") || !centerTransform && transform.originX === "center" && transform.originY === "center") { - this._resetCurrentTransform(); - transform.reset = true; - } - } - }, - _onScale: function(e, transform, x, y) { - if ((e.shiftKey || this.uniScaleTransform) && !transform.target.get("lockUniScaling")) { - transform.currentAction = "scale"; - return this._scaleObject(x, y); - } else { - if (!transform.reset && transform.currentAction === "scale") { - this._resetCurrentTransform(); - } - transform.currentAction = "scaleEqually"; - return this._scaleObject(x, y, "equally"); - } - }, - _setCursorFromEvent: function(e, target) { - if (!target || !target.selectable) { - this.setCursor(this.defaultCursor); - return false; - } else { - var activeGroup = this.getActiveGroup(), corner = target._findTargetCorner && (!activeGroup || !activeGroup.contains(target)) && target._findTargetCorner(this.getPointer(e, true)); - if (!corner) { - this.setCursor(target.hoverCursor || this.hoverCursor); - } else { - this._setCornerCursor(corner, target, e); - } - } - return true; - }, - _setCornerCursor: function(corner, target, e) { - if (corner in cursorOffset) { - this.setCursor(this._getRotatedCornerCursor(corner, target, e)); - } else if (corner === "mtr" && target.hasRotatingPoint) { - this.setCursor(this.rotationCursor); - } else { - this.setCursor(this.defaultCursor); - return false; - } - }, - _getRotatedCornerCursor: function(corner, target, e) { - var n = Math.round(target.getAngle() % 360 / 45); - if (n < 0) { - n += 8; - } - n += cursorOffset[corner]; - if (e.shiftKey && cursorOffset[corner] % 2 === 0) { - n += 2; - } - n %= 8; - return this.cursorMap[n]; - } - }); -})(); - -(function() { - var min = Math.min, max = Math.max; - fabric.util.object.extend(fabric.Canvas.prototype, { - _shouldGroup: function(e, target) { - var activeObject = this.getActiveObject(); - return e.shiftKey && target && target.selectable && (this.getActiveGroup() || activeObject && activeObject !== target) && this.selection; - }, - _handleGrouping: function(e, target) { - if (target === this.getActiveGroup()) { - target = this.findTarget(e, true); - if (!target || target.isType("group")) { - return; - } - } - if (this.getActiveGroup()) { - this._updateActiveGroup(target, e); - } else { - this._createActiveGroup(target, e); - } - if (this._activeGroup) { - this._activeGroup.saveCoords(); - } - }, - _updateActiveGroup: function(target, e) { - var activeGroup = this.getActiveGroup(); - if (activeGroup.contains(target)) { - activeGroup.removeWithUpdate(target); - target.set("active", false); - if (activeGroup.size() === 1) { - this.discardActiveGroup(e); - this.setActiveObject(activeGroup.item(0)); - return; - } - } else { - activeGroup.addWithUpdate(target); - } - this.fire("selection:created", { - target: activeGroup, - e: e - }); - activeGroup.set("active", true); - }, - _createActiveGroup: function(target, e) { - if (this._activeObject && target !== this._activeObject) { - var group = this._createGroup(target); - group.addWithUpdate(); - this.setActiveGroup(group); - this._activeObject = null; - this.fire("selection:created", { - target: group, - e: e - }); - } - target.set("active", true); - }, - _createGroup: function(target) { - var objects = this.getObjects(), isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target), groupObjects = isActiveLower ? [ this._activeObject, target ] : [ target, this._activeObject ]; - return new fabric.Group(groupObjects, { - canvas: this - }); - }, - _groupSelectedObjects: function(e) { - var group = this._collectObjects(); - if (group.length === 1) { - this.setActiveObject(group[0], e); - } else if (group.length > 1) { - group = new fabric.Group(group.reverse(), { - canvas: this - }); - group.addWithUpdate(); - this.setActiveGroup(group, e); - group.saveCoords(); - this.fire("selection:created", { - target: group - }); - this.renderAll(); - } - }, - _collectObjects: function() { - var group = [], currentObject, x1 = this._groupSelector.ex, y1 = this._groupSelector.ey, x2 = x1 + this._groupSelector.left, y2 = y1 + this._groupSelector.top, selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)), selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)), isClick = x1 === x2 && y1 === y2; - for (var i = this._objects.length; i--; ) { - currentObject = this._objects[i]; - if (!currentObject || !currentObject.selectable || !currentObject.visible) { - continue; - } - if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) || currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || currentObject.containsPoint(selectionX1Y1) || currentObject.containsPoint(selectionX2Y2)) { - currentObject.set("active", true); - group.push(currentObject); - if (isClick) { - break; - } - } - } - return group; - }, - _maybeGroupObjects: function(e) { - if (this.selection && this._groupSelector) { - this._groupSelectedObjects(e); - } - var activeGroup = this.getActiveGroup(); - if (activeGroup) { - activeGroup.setObjectsCoords().setCoords(); - activeGroup.isMoving = false; - this.setCursor(this.defaultCursor); - } - this._groupSelector = null; - this._currentTransform = null; - } - }); -})(); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, { - toDataURL: function(options) { - options || (options = {}); - var format = options.format || "png", quality = options.quality || 1, multiplier = options.multiplier || 1, cropping = { - left: options.left, - top: options.top, - width: options.width, - height: options.height - }; - if (this._isRetinaScaling()) { - multiplier *= fabric.devicePixelRatio; - } - if (multiplier !== 1) { - return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier); - } else { - return this.__toDataURL(format, quality, cropping); - } - }, - __toDataURL: function(format, quality, cropping) { - this.renderAll(); - var canvasEl = this.contextContainer.canvas, croppedCanvasEl = this.__getCroppedCanvas(canvasEl, cropping); - if (format === "jpg") { - format = "jpeg"; - } - var data = fabric.StaticCanvas.supports("toDataURLWithQuality") ? (croppedCanvasEl || canvasEl).toDataURL("image/" + format, quality) : (croppedCanvasEl || canvasEl).toDataURL("image/" + format); - if (croppedCanvasEl) { - croppedCanvasEl = null; - } - return data; - }, - __getCroppedCanvas: function(canvasEl, cropping) { - var croppedCanvasEl, croppedCtx, shouldCrop = "left" in cropping || "top" in cropping || "width" in cropping || "height" in cropping; - if (shouldCrop) { - croppedCanvasEl = fabric.util.createCanvasElement(); - croppedCtx = croppedCanvasEl.getContext("2d"); - croppedCanvasEl.width = cropping.width || this.width; - croppedCanvasEl.height = cropping.height || this.height; - croppedCtx.drawImage(canvasEl, -cropping.left || 0, -cropping.top || 0); - } - return croppedCanvasEl; - }, - __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { - var origWidth = this.getWidth(), origHeight = this.getHeight(), scaledWidth = origWidth * multiplier, scaledHeight = origHeight * multiplier, activeObject = this.getActiveObject(), activeGroup = this.getActiveGroup(), ctx = this.contextContainer; - if (multiplier > 1) { - this.setDimensions({ - width: scaledWidth, - height: scaledHeight - }); - } - ctx.save(); - ctx.scale(multiplier / fabric.devicePixelRatio, multiplier / fabric.devicePixelRatio); - if (cropping.left) { - cropping.left *= multiplier; - } - if (cropping.top) { - cropping.top *= multiplier; - } - if (cropping.width) { - cropping.width *= multiplier; - } else if (multiplier < 1) { - cropping.width = scaledWidth; - } - if (cropping.height) { - cropping.height *= multiplier; - } else if (multiplier < 1) { - cropping.height = scaledHeight; - } - if (activeGroup) { - this._tempRemoveBordersControlsFromGroup(activeGroup); - } else if (activeObject && this.deactivateAll) { - this.deactivateAll(); - } - var data = this.__toDataURL(format, quality, cropping); - this.width = origWidth; - this.height = origHeight; - this.setDimensions({ - width: origWidth, - height: origHeight - }); - if (activeGroup) { - this._restoreBordersControlsOnGroup(activeGroup); - } else if (activeObject && this.setActiveObject) { - this.setActiveObject(activeObject); - } - this.contextTop && this.clearContext(this.contextTop); - this.renderAll(); - return data; - }, - toDataURLWithMultiplier: function(format, multiplier, quality) { - return this.toDataURL({ - format: format, - multiplier: multiplier, - quality: quality - }); - }, - _tempRemoveBordersControlsFromGroup: function(group) { - group.origHasControls = group.hasControls; - group.origBorderColor = group.borderColor; - group.hasControls = true; - group.borderColor = "rgba(0,0,0,0)"; - group.forEachObject(function(o) { - o.origBorderColor = o.borderColor; - o.borderColor = "rgba(0,0,0,0)"; - }); - }, - _restoreBordersControlsOnGroup: function(group) { - group.hideControls = group.origHideControls; - group.borderColor = group.origBorderColor; - group.forEachObject(function(o) { - o.borderColor = o.origBorderColor; - delete o.origBorderColor; - }); - } -}); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, { - loadFromDatalessJSON: function(json, callback, reviver) { - return this.loadFromJSON(json, callback, reviver); - }, - loadFromJSON: function(json, callback, reviver) { - if (!json) { - return; - } - var serialized = typeof json === "string" ? JSON.parse(json) : json; - this.clear(); - var _this = this; - this._enlivenObjects(serialized.objects, function() { - _this._setBgOverlay(serialized, callback); - }, reviver); - return this; - }, - _setBgOverlay: function(serialized, callback) { - var _this = this, loaded = { - backgroundColor: false, - overlayColor: false, - backgroundImage: false, - overlayImage: false - }; - if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) { - callback && callback(); - return; - } - var cbIfLoaded = function() { - if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { - _this.renderAll(); - callback && callback(); - } - }; - this.__setBgOverlay("backgroundImage", serialized.backgroundImage, loaded, cbIfLoaded); - this.__setBgOverlay("overlayImage", serialized.overlayImage, loaded, cbIfLoaded); - this.__setBgOverlay("backgroundColor", serialized.background, loaded, cbIfLoaded); - this.__setBgOverlay("overlayColor", serialized.overlay, loaded, cbIfLoaded); - cbIfLoaded(); - }, - __setBgOverlay: function(property, value, loaded, callback) { - var _this = this; - if (!value) { - loaded[property] = true; - return; - } - if (property === "backgroundImage" || property === "overlayImage") { - fabric.Image.fromObject(value, function(img) { - _this[property] = img; - loaded[property] = true; - callback && callback(); - }); - } else { - this["set" + fabric.util.string.capitalize(property, true)](value, function() { - loaded[property] = true; - callback && callback(); - }); - } - }, - _enlivenObjects: function(objects, callback, reviver) { - var _this = this; - if (!objects || objects.length === 0) { - callback && callback(); - return; - } - var renderOnAddRemove = this.renderOnAddRemove; - this.renderOnAddRemove = false; - fabric.util.enlivenObjects(objects, function(enlivenedObjects) { - enlivenedObjects.forEach(function(obj, index) { - _this.insertAt(obj, index, true); - }); - _this.renderOnAddRemove = renderOnAddRemove; - callback && callback(); - }, null, reviver); - }, - _toDataURL: function(format, callback) { - this.clone(function(clone) { - callback(clone.toDataURL(format)); - }); - }, - _toDataURLWithMultiplier: function(format, multiplier, callback) { - this.clone(function(clone) { - callback(clone.toDataURLWithMultiplier(format, multiplier)); - }); - }, - clone: function(callback, properties) { - var data = JSON.stringify(this.toJSON(properties)); - this.cloneWithoutData(function(clone) { - clone.loadFromJSON(data, function() { - callback && callback(clone); - }); - }); - }, - cloneWithoutData: function(callback) { - var el = fabric.document.createElement("canvas"); - el.width = this.getWidth(); - el.height = this.getHeight(); - var clone = new fabric.Canvas(el); - clone.clipTo = this.clipTo; - if (this.backgroundImage) { - clone.setBackgroundImage(this.backgroundImage.src, function() { - clone.renderAll(); - callback && callback(clone); - }); - clone.backgroundImageOpacity = this.backgroundImageOpacity; - clone.backgroundImageStretch = this.backgroundImageStretch; - } else { - callback && callback(clone); - } - } -}); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, toFixed = fabric.util.toFixed, capitalize = fabric.util.string.capitalize, degreesToRadians = fabric.util.degreesToRadians, supportsLineDash = fabric.StaticCanvas.supports("setLineDash"); - if (fabric.Object) { - return; - } - fabric.Object = fabric.util.createClass({ - type: "object", - originX: "left", - originY: "top", - top: 0, - left: 0, - width: 0, - height: 0, - scaleX: 1, - scaleY: 1, - flipX: false, - flipY: false, - opacity: 1, - angle: 0, - skewX: 0, - skewY: 0, - cornerSize: 12, - transparentCorners: true, - hoverCursor: null, - padding: 0, - borderColor: "rgba(102,153,255,0.75)", - cornerColor: "rgba(102,153,255,0.5)", - centeredScaling: false, - centeredRotation: true, - fill: "rgb(0,0,0)", - fillRule: "nonzero", - globalCompositeOperation: "source-over", - backgroundColor: "", - stroke: null, - strokeWidth: 1, - strokeDashArray: null, - strokeLineCap: "butt", - strokeLineJoin: "miter", - strokeMiterLimit: 10, - shadow: null, - borderOpacityWhenMoving: .4, - borderScaleFactor: 1, - transformMatrix: null, - minScaleLimit: .01, - selectable: true, - evented: true, - visible: true, - hasControls: true, - hasBorders: true, - hasRotatingPoint: true, - rotatingPointOffset: 40, - perPixelTargetFind: false, - includeDefaultValues: true, - clipTo: null, - lockMovementX: false, - lockMovementY: false, - lockRotation: false, - lockScalingX: false, - lockScalingY: false, - lockUniScaling: false, - lockSkewingX: false, - lockSkewingY: false, - lockScalingFlip: false, - stateProperties: ("top left width height scaleX scaleY flipX flipY originX originY transformMatrix " + "stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit " + "angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor " + "alignX alignY meetOrSlice skewX skewY").split(" "), - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - _initGradient: function(options) { - if (options.fill && options.fill.colorStops && !(options.fill instanceof fabric.Gradient)) { - this.set("fill", new fabric.Gradient(options.fill)); - } - if (options.stroke && options.stroke.colorStops && !(options.stroke instanceof fabric.Gradient)) { - this.set("stroke", new fabric.Gradient(options.stroke)); - } - }, - _initPattern: function(options) { - if (options.fill && options.fill.source && !(options.fill instanceof fabric.Pattern)) { - this.set("fill", new fabric.Pattern(options.fill)); - } - if (options.stroke && options.stroke.source && !(options.stroke instanceof fabric.Pattern)) { - this.set("stroke", new fabric.Pattern(options.stroke)); - } - }, - _initClipping: function(options) { - if (!options.clipTo || typeof options.clipTo !== "string") { - return; - } - var functionBody = fabric.util.getFunctionBody(options.clipTo); - if (typeof functionBody !== "undefined") { - this.clipTo = new Function("ctx", functionBody); - } - }, - setOptions: function(options) { - for (var prop in options) { - this.set(prop, options[prop]); - } - this._initGradient(options); - this._initPattern(options); - this._initClipping(options); - }, - transform: function(ctx, fromLeft) { - if (this.group && this.canvas.preserveObjectStacking && this.group === this.canvas._activeGroup) { - this.group.transform(ctx); - } - var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint(); - ctx.translate(center.x, center.y); - ctx.rotate(degreesToRadians(this.angle)); - ctx.scale(this.scaleX * (this.flipX ? -1 : 1), this.scaleY * (this.flipY ? -1 : 1)); - ctx.transform(1, 0, Math.tan(degreesToRadians(this.skewX)), 1, 0, 0); - ctx.transform(1, Math.tan(degreesToRadians(this.skewY)), 0, 1, 0, 0); - }, - toObject: function(propertiesToInclude) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, object = { - type: this.type, - originX: this.originX, - originY: this.originY, - left: toFixed(this.left, NUM_FRACTION_DIGITS), - top: toFixed(this.top, NUM_FRACTION_DIGITS), - width: toFixed(this.width, NUM_FRACTION_DIGITS), - height: toFixed(this.height, NUM_FRACTION_DIGITS), - fill: this.fill && this.fill.toObject ? this.fill.toObject() : this.fill, - stroke: this.stroke && this.stroke.toObject ? this.stroke.toObject() : this.stroke, - strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS), - strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray, - strokeLineCap: this.strokeLineCap, - strokeLineJoin: this.strokeLineJoin, - strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS), - scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS), - scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS), - angle: toFixed(this.getAngle(), NUM_FRACTION_DIGITS), - flipX: this.flipX, - flipY: this.flipY, - opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS), - shadow: this.shadow && this.shadow.toObject ? this.shadow.toObject() : this.shadow, - visible: this.visible, - clipTo: this.clipTo && String(this.clipTo), - backgroundColor: this.backgroundColor, - fillRule: this.fillRule, - globalCompositeOperation: this.globalCompositeOperation, - transformMatrix: this.transformMatrix ? this.transformMatrix.concat() : this.transformMatrix, - skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS), - skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS) - }; - if (!this.includeDefaultValues) { - object = this._removeDefaultValues(object); - } - fabric.util.populateWithProperties(this, object, propertiesToInclude); - return object; - }, - toDatalessObject: function(propertiesToInclude) { - return this.toObject(propertiesToInclude); - }, - _removeDefaultValues: function(object) { - var prototype = fabric.util.getKlass(object.type).prototype, stateProperties = prototype.stateProperties; - stateProperties.forEach(function(prop) { - if (object[prop] === prototype[prop]) { - delete object[prop]; - } - var isArray = Object.prototype.toString.call(object[prop]) === "[object Array]" && Object.prototype.toString.call(prototype[prop]) === "[object Array]"; - if (isArray && object[prop].length === 0 && prototype[prop].length === 0) { - delete object[prop]; - } - }); - return object; - }, - toString: function() { - return "#"; - }, - get: function(property) { - return this[property]; - }, - _setObject: function(obj) { - for (var prop in obj) { - this._set(prop, obj[prop]); - } - }, - set: function(key, value) { - if (typeof key === "object") { - this._setObject(key); - } else { - if (typeof value === "function" && key !== "clipTo") { - this._set(key, value(this.get(key))); - } else { - this._set(key, value); - } - } - return this; - }, - _set: function(key, value) { - var shouldConstrainValue = key === "scaleX" || key === "scaleY"; - if (shouldConstrainValue) { - value = this._constrainScale(value); - } - if (key === "scaleX" && value < 0) { - this.flipX = !this.flipX; - value *= -1; - } else if (key === "scaleY" && value < 0) { - this.flipY = !this.flipY; - value *= -1; - } else if (key === "width" || key === "height") { - this.minScaleLimit = toFixed(Math.min(.1, 1 / Math.max(this.width, this.height)), 2); - } else if (key === "shadow" && value && !(value instanceof fabric.Shadow)) { - value = new fabric.Shadow(value); - } - this[key] = value; - return this; - }, - setOnGroup: function() {}, - toggle: function(property) { - var value = this.get(property); - if (typeof value === "boolean") { - this.set(property, !value); - } - return this; - }, - setSourcePath: function(value) { - this.sourcePath = value; - return this; - }, - getViewportTransform: function() { - if (this.canvas && this.canvas.viewportTransform) { - return this.canvas.viewportTransform; - } - return [ 1, 0, 0, 1, 0, 0 ]; - }, - render: function(ctx, noTransform) { - if (this.width === 0 && this.height === 0 || !this.visible) { - return; - } - ctx.save(); - this._setupCompositeOperation(ctx); - if (!noTransform) { - this.transform(ctx); - } - this._setStrokeStyles(ctx); - this._setFillStyles(ctx); - if (this.transformMatrix) { - ctx.transform.apply(ctx, this.transformMatrix); - } - this._setOpacity(ctx); - this._setShadow(ctx); - this.clipTo && fabric.util.clipContext(this, ctx); - this._render(ctx, noTransform); - this.clipTo && ctx.restore(); - ctx.restore(); - }, - _setOpacity: function(ctx) { - if (this.group) { - this.group._setOpacity(ctx); - } - ctx.globalAlpha *= this.opacity; - }, - _setStrokeStyles: function(ctx) { - if (this.stroke) { - ctx.lineWidth = this.strokeWidth; - ctx.lineCap = this.strokeLineCap; - ctx.lineJoin = this.strokeLineJoin; - ctx.miterLimit = this.strokeMiterLimit; - ctx.strokeStyle = this.stroke.toLive ? this.stroke.toLive(ctx, this) : this.stroke; - } - }, - _setFillStyles: function(ctx) { - if (this.fill) { - ctx.fillStyle = this.fill.toLive ? this.fill.toLive(ctx, this) : this.fill; - } - }, - _renderControls: function(ctx, noTransform) { - if (!this.active || noTransform || this.group && this.group !== this.canvas.getActiveGroup()) { - return; - } - var vpt = this.getViewportTransform(), matrix = this.calcTransformMatrix(), options; - matrix = fabric.util.multiplyTransformMatrices(vpt, matrix); - options = fabric.util.qrDecompose(matrix); - ctx.save(); - ctx.translate(options.translateX, options.translateY); - if (this.group && this.group === this.canvas.getActiveGroup()) { - ctx.rotate(degreesToRadians(options.angle)); - this.drawBordersInGroup(ctx, options); - } else { - ctx.rotate(degreesToRadians(this.angle)); - this.drawBorders(ctx); - } - this.drawControls(ctx); - ctx.restore(); - }, - _setShadow: function(ctx) { - if (!this.shadow) { - return; - } - var multX = this.canvas && this.canvas.viewportTransform[0] || 1, multY = this.canvas && this.canvas.viewportTransform[3] || 1; - if (this.canvas && this.canvas._isRetinaScaling()) { - multX *= fabric.devicePixelRatio; - multY *= fabric.devicePixelRatio; - } - ctx.shadowColor = this.shadow.color; - ctx.shadowBlur = this.shadow.blur * (multX + multY) * (this.scaleX + this.scaleY) / 4; - ctx.shadowOffsetX = this.shadow.offsetX * multX * this.scaleX; - ctx.shadowOffsetY = this.shadow.offsetY * multY * this.scaleY; - }, - _removeShadow: function(ctx) { - if (!this.shadow) { - return; - } - ctx.shadowColor = ""; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - }, - _renderFill: function(ctx) { - if (!this.fill) { - return; - } - ctx.save(); - if (this.fill.gradientTransform) { - var g = this.fill.gradientTransform; - ctx.transform.apply(ctx, g); - } - if (this.fill.toLive) { - ctx.translate(-this.width / 2 + this.fill.offsetX || 0, -this.height / 2 + this.fill.offsetY || 0); - } - if (this.fillRule === "evenodd") { - ctx.fill("evenodd"); - } else { - ctx.fill(); - } - ctx.restore(); - }, - _renderStroke: function(ctx) { - if (!this.stroke || this.strokeWidth === 0) { - return; - } - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - ctx.save(); - if (this.strokeDashArray) { - if (1 & this.strokeDashArray.length) { - this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray); - } - if (supportsLineDash) { - ctx.setLineDash(this.strokeDashArray); - this._stroke && this._stroke(ctx); - } else { - this._renderDashedStroke && this._renderDashedStroke(ctx); - } - ctx.stroke(); - } else { - if (this.stroke.gradientTransform) { - var g = this.stroke.gradientTransform; - ctx.transform.apply(ctx, g); - } - this._stroke ? this._stroke(ctx) : ctx.stroke(); - } - ctx.restore(); - }, - clone: function(callback, propertiesToInclude) { - if (this.constructor.fromObject) { - return this.constructor.fromObject(this.toObject(propertiesToInclude), callback); - } - return new fabric.Object(this.toObject(propertiesToInclude)); - }, - cloneAsImage: function(callback) { - var dataUrl = this.toDataURL(); - fabric.util.loadImage(dataUrl, function(img) { - if (callback) { - callback(new fabric.Image(img)); - } - }); - return this; - }, - toDataURL: function(options) { - options || (options = {}); - var el = fabric.util.createCanvasElement(), boundingRect = this.getBoundingRect(); - el.width = boundingRect.width; - el.height = boundingRect.height; - fabric.util.wrapElement(el, "div"); - var canvas = new fabric.StaticCanvas(el); - if (options.format === "jpg") { - options.format = "jpeg"; - } - if (options.format === "jpeg") { - canvas.backgroundColor = "#fff"; - } - var origParams = { - active: this.get("active"), - left: this.getLeft(), - top: this.getTop() - }; - this.set("active", false); - this.setPositionByOrigin(new fabric.Point(el.width / 2, el.height / 2), "center", "center"); - var originalCanvas = this.canvas; - canvas.add(this); - var data = canvas.toDataURL(options); - this.set(origParams).setCoords(); - this.canvas = originalCanvas; - canvas.dispose(); - canvas = null; - return data; - }, - isType: function(type) { - return this.type === type; - }, - complexity: function() { - return 0; - }, - toJSON: function(propertiesToInclude) { - return this.toObject(propertiesToInclude); - }, - setGradient: function(property, options) { - options || (options = {}); - var gradient = { - colorStops: [] - }; - gradient.type = options.type || (options.r1 || options.r2 ? "radial" : "linear"); - gradient.coords = { - x1: options.x1, - y1: options.y1, - x2: options.x2, - y2: options.y2 - }; - if (options.r1 || options.r2) { - gradient.coords.r1 = options.r1; - gradient.coords.r2 = options.r2; - } - options.gradientTransform && (gradient.gradientTransform = options.gradientTransform); - for (var position in options.colorStops) { - var color = new fabric.Color(options.colorStops[position]); - gradient.colorStops.push({ - offset: position, - color: color.toRgb(), - opacity: color.getAlpha() - }); - } - return this.set(property, fabric.Gradient.forObject(this, gradient)); - }, - setPatternFill: function(options) { - return this.set("fill", new fabric.Pattern(options)); - }, - setShadow: function(options) { - return this.set("shadow", options ? new fabric.Shadow(options) : null); - }, - setColor: function(color) { - this.set("fill", color); - return this; - }, - setAngle: function(angle) { - var shouldCenterOrigin = (this.originX !== "center" || this.originY !== "center") && this.centeredRotation; - if (shouldCenterOrigin) { - this._setOriginToCenter(); - } - this.set("angle", angle); - if (shouldCenterOrigin) { - this._resetOrigin(); - } - return this; - }, - centerH: function() { - this.canvas.centerObjectH(this); - return this; - }, - centerV: function() { - this.canvas.centerObjectV(this); - return this; - }, - center: function() { - this.canvas.centerObject(this); - return this; - }, - remove: function() { - this.canvas.remove(this); - return this; - }, - getLocalPointer: function(e, pointer) { - pointer = pointer || this.canvas.getPointer(e); - var pClicked = new fabric.Point(pointer.x, pointer.y), objectLeftTop = this._getLeftTopCoords(); - if (this.angle) { - pClicked = fabric.util.rotatePoint(pClicked, objectLeftTop, fabric.util.degreesToRadians(-this.angle)); - } - return { - x: pClicked.x - objectLeftTop.x, - y: pClicked.y - objectLeftTop.y - }; - }, - _setupCompositeOperation: function(ctx) { - if (this.globalCompositeOperation) { - ctx.globalCompositeOperation = this.globalCompositeOperation; - } - } - }); - fabric.util.createAccessors(fabric.Object); - fabric.Object.prototype.rotate = fabric.Object.prototype.setAngle; - extend(fabric.Object.prototype, fabric.Observable); - fabric.Object.NUM_FRACTION_DIGITS = 2; - fabric.Object.__uid = 0; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - var degreesToRadians = fabric.util.degreesToRadians, originXOffset = { - left: -.5, - center: 0, - right: .5 - }, originYOffset = { - top: -.5, - center: 0, - bottom: .5 - }; - fabric.util.object.extend(fabric.Object.prototype, { - translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) { - var x = point.x, y = point.y, offsetX = originXOffset[toOriginX] - originXOffset[fromOriginX], offsetY = originYOffset[toOriginY] - originYOffset[fromOriginY], dim; - if (offsetX || offsetY) { - dim = this._getTransformedDimensions(); - x = point.x + offsetX * dim.x; - y = point.y + offsetY * dim.y; - } - return new fabric.Point(x, y); - }, - translateToCenterPoint: function(point, originX, originY) { - var p = this.translateToGivenOrigin(point, originX, originY, "center", "center"); - if (this.angle) { - return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle)); - } - return p; - }, - translateToOriginPoint: function(center, originX, originY) { - var p = this.translateToGivenOrigin(center, "center", "center", originX, originY); - if (this.angle) { - return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle)); - } - return p; - }, - getCenterPoint: function() { - var leftTop = new fabric.Point(this.left, this.top); - return this.translateToCenterPoint(leftTop, this.originX, this.originY); - }, - getPointByOrigin: function(originX, originY) { - var center = this.getCenterPoint(); - return this.translateToOriginPoint(center, originX, originY); - }, - toLocalPoint: function(point, originX, originY) { - var center = this.getCenterPoint(), p, p2; - if (originX && originY) { - p = this.translateToGivenOrigin(center, "center", "center", originX, originY); - } else { - p = new fabric.Point(this.left, this.top); - } - p2 = new fabric.Point(point.x, point.y); - if (this.angle) { - p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle)); - } - return p2.subtractEquals(p); - }, - setPositionByOrigin: function(pos, originX, originY) { - var center = this.translateToCenterPoint(pos, originX, originY), position = this.translateToOriginPoint(center, this.originX, this.originY); - this.set("left", position.x); - this.set("top", position.y); - }, - adjustPosition: function(to) { - var angle = degreesToRadians(this.angle), hypotFull = this.getWidth(), xFull = Math.cos(angle) * hypotFull, yFull = Math.sin(angle) * hypotFull; - this.left += xFull * (originXOffset[to] - originXOffset[this.originX]); - this.top += yFull * (originXOffset[to] - originXOffset[this.originX]); - this.setCoords(); - this.originX = to; - }, - _setOriginToCenter: function() { - this._originalOriginX = this.originX; - this._originalOriginY = this.originY; - var center = this.getCenterPoint(); - this.originX = "center"; - this.originY = "center"; - this.left = center.x; - this.top = center.y; - }, - _resetOrigin: function() { - var originPoint = this.translateToOriginPoint(this.getCenterPoint(), this._originalOriginX, this._originalOriginY); - this.originX = this._originalOriginX; - this.originY = this._originalOriginY; - this.left = originPoint.x; - this.top = originPoint.y; - this._originalOriginX = null; - this._originalOriginY = null; - }, - _getLeftTopCoords: function() { - return this.translateToOriginPoint(this.getCenterPoint(), "left", "top"); - } - }); -})(); - -(function() { - function getCoords(oCoords) { - return [ new fabric.Point(oCoords.tl.x, oCoords.tl.y), new fabric.Point(oCoords.tr.x, oCoords.tr.y), new fabric.Point(oCoords.br.x, oCoords.br.y), new fabric.Point(oCoords.bl.x, oCoords.bl.y) ]; - } - var degreesToRadians = fabric.util.degreesToRadians, multiplyMatrices = fabric.util.multiplyTransformMatrices; - fabric.util.object.extend(fabric.Object.prototype, { - oCoords: null, - intersectsWithRect: function(pointTL, pointBR) { - var oCoords = getCoords(this.oCoords), intersection = fabric.Intersection.intersectPolygonRectangle(oCoords, pointTL, pointBR); - return intersection.status === "Intersection"; - }, - intersectsWithObject: function(other) { - var intersection = fabric.Intersection.intersectPolygonPolygon(getCoords(this.oCoords), getCoords(other.oCoords)); - return intersection.status === "Intersection"; - }, - isContainedWithinObject: function(other) { - var boundingRect = other.getBoundingRect(), point1 = new fabric.Point(boundingRect.left, boundingRect.top), point2 = new fabric.Point(boundingRect.left + boundingRect.width, boundingRect.top + boundingRect.height); - return this.isContainedWithinRect(point1, point2); - }, - isContainedWithinRect: function(pointTL, pointBR) { - var boundingRect = this.getBoundingRect(); - return boundingRect.left >= pointTL.x && boundingRect.left + boundingRect.width <= pointBR.x && boundingRect.top >= pointTL.y && boundingRect.top + boundingRect.height <= pointBR.y; - }, - containsPoint: function(point) { - var lines = this._getImageLines(this.oCoords), xPoints = this._findCrossPoints(point, lines); - return xPoints !== 0 && xPoints % 2 === 1; - }, - _getImageLines: function(oCoords) { - return { - topline: { - o: oCoords.tl, - d: oCoords.tr - }, - rightline: { - o: oCoords.tr, - d: oCoords.br - }, - bottomline: { - o: oCoords.br, - d: oCoords.bl - }, - leftline: { - o: oCoords.bl, - d: oCoords.tl - } - }; - }, - _findCrossPoints: function(point, oCoords) { - var b1, b2, a1, a2, xi, yi, xcount = 0, iLine; - for (var lineKey in oCoords) { - iLine = oCoords[lineKey]; - if (iLine.o.y < point.y && iLine.d.y < point.y) { - continue; - } - if (iLine.o.y >= point.y && iLine.d.y >= point.y) { - continue; - } - if (iLine.o.x === iLine.d.x && iLine.o.x >= point.x) { - xi = iLine.o.x; - yi = point.y; - } else { - b1 = 0; - b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x); - a1 = point.y - b1 * point.x; - a2 = iLine.o.y - b2 * iLine.o.x; - xi = -(a1 - a2) / (b1 - b2); - yi = a1 + b1 * xi; - } - if (xi >= point.x) { - xcount += 1; - } - if (xcount === 2) { - break; - } - } - return xcount; - }, - getBoundingRectWidth: function() { - return this.getBoundingRect().width; - }, - getBoundingRectHeight: function() { - return this.getBoundingRect().height; - }, - getBoundingRect: function() { - this.oCoords || this.setCoords(); - return fabric.util.makeBoundingBoxFromPoints([ this.oCoords.tl, this.oCoords.tr, this.oCoords.br, this.oCoords.bl ]); - }, - getWidth: function() { - return this._getTransformedDimensions().x; - }, - getHeight: function() { - return this._getTransformedDimensions().y; - }, - _constrainScale: function(value) { - if (Math.abs(value) < this.minScaleLimit) { - if (value < 0) { - return -this.minScaleLimit; - } else { - return this.minScaleLimit; - } - } - return value; - }, - scale: function(value) { - value = this._constrainScale(value); - if (value < 0) { - this.flipX = !this.flipX; - this.flipY = !this.flipY; - value *= -1; - } - this.scaleX = value; - this.scaleY = value; - this.setCoords(); - return this; - }, - scaleToWidth: function(value) { - var boundingRectFactor = this.getBoundingRect().width / this.getWidth(); - return this.scale(value / this.width / boundingRectFactor); - }, - scaleToHeight: function(value) { - var boundingRectFactor = this.getBoundingRect().height / this.getHeight(); - return this.scale(value / this.height / boundingRectFactor); - }, - setCoords: function() { - var theta = degreesToRadians(this.angle), vpt = this.getViewportTransform(), dim = this._calculateCurrentDimensions(), currentWidth = dim.x, currentHeight = dim.y; - if (currentWidth < 0) { - currentWidth = Math.abs(currentWidth); - } - var sinTh = Math.sin(theta), cosTh = Math.cos(theta), _angle = currentWidth > 0 ? Math.atan(currentHeight / currentWidth) : 0, _hypotenuse = currentWidth / Math.cos(_angle) / 2, offsetX = Math.cos(_angle + theta) * _hypotenuse, offsetY = Math.sin(_angle + theta) * _hypotenuse, coords = fabric.util.transformPoint(this.getCenterPoint(), vpt), tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY), tr = new fabric.Point(tl.x + currentWidth * cosTh, tl.y + currentWidth * sinTh), bl = new fabric.Point(tl.x - currentHeight * sinTh, tl.y + currentHeight * cosTh), br = new fabric.Point(coords.x + offsetX, coords.y + offsetY), ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2), mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2), mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2), mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2), mtr = new fabric.Point(mt.x + sinTh * this.rotatingPointOffset, mt.y - cosTh * this.rotatingPointOffset); - this.oCoords = { - tl: tl, - tr: tr, - br: br, - bl: bl, - ml: ml, - mt: mt, - mr: mr, - mb: mb, - mtr: mtr - }; - this._setCornerCoords && this._setCornerCoords(); - return this; - }, - _calcRotateMatrix: function() { - if (this.angle) { - var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta); - return [ cos, sin, -sin, cos, 0, 0 ]; - } - return [ 1, 0, 0, 1, 0, 0 ]; - }, - calcTransformMatrix: function() { - var center = this.getCenterPoint(), translateMatrix = [ 1, 0, 0, 1, center.x, center.y ], rotateMatrix = this._calcRotateMatrix(), dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true), matrix = this.group ? this.group.calcTransformMatrix() : [ 1, 0, 0, 1, 0, 0 ]; - matrix = multiplyMatrices(matrix, translateMatrix); - matrix = multiplyMatrices(matrix, rotateMatrix); - matrix = multiplyMatrices(matrix, dimensionMatrix); - return matrix; - }, - _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) { - var skewMatrixX = [ 1, 0, Math.tan(degreesToRadians(skewX)), 1 ], skewMatrixY = [ 1, Math.tan(degreesToRadians(skewY)), 0, 1 ], scaleX = this.scaleX * (flipping && this.flipX ? -1 : 1), scaleY = this.scaleY * (flipping && this.flipY ? -1 : 1), scaleMatrix = [ scaleX, 0, 0, scaleY ], m = multiplyMatrices(scaleMatrix, skewMatrixX, true); - return multiplyMatrices(m, skewMatrixY, true); - } - }); -})(); - -fabric.util.object.extend(fabric.Object.prototype, { - sendToBack: function() { - if (this.group) { - fabric.StaticCanvas.prototype.sendToBack.call(this.group, this); - } else { - this.canvas.sendToBack(this); - } - return this; - }, - bringToFront: function() { - if (this.group) { - fabric.StaticCanvas.prototype.bringToFront.call(this.group, this); - } else { - this.canvas.bringToFront(this); - } - return this; - }, - sendBackwards: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting); - } else { - this.canvas.sendBackwards(this, intersecting); - } - return this; - }, - bringForward: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting); - } else { - this.canvas.bringForward(this, intersecting); - } - return this; - }, - moveTo: function(index) { - if (this.group) { - fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index); - } else { - this.canvas.moveTo(this, index); - } - return this; - } -}); - -fabric.util.object.extend(fabric.Object.prototype, { - getSvgStyles: function(skipShadow) { - var fill = this.fill ? this.fill.toLive ? "url(#SVGID_" + this.fill.id + ")" : this.fill : "none", fillRule = this.fillRule, stroke = this.stroke ? this.stroke.toLive ? "url(#SVGID_" + this.stroke.id + ")" : this.stroke : "none", strokeWidth = this.strokeWidth ? this.strokeWidth : "0", strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(" ") : "none", strokeLineCap = this.strokeLineCap ? this.strokeLineCap : "butt", strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : "miter", strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : "4", opacity = typeof this.opacity !== "undefined" ? this.opacity : "1", visibility = this.visible ? "" : " visibility: hidden;", filter = skipShadow ? "" : this.getSvgFilter(); - return [ "stroke: ", stroke, "; ", "stroke-width: ", strokeWidth, "; ", "stroke-dasharray: ", strokeDashArray, "; ", "stroke-linecap: ", strokeLineCap, "; ", "stroke-linejoin: ", strokeLineJoin, "; ", "stroke-miterlimit: ", strokeMiterLimit, "; ", "fill: ", fill, "; ", "fill-rule: ", fillRule, "; ", "opacity: ", opacity, ";", filter, visibility ].join(""); - }, - getSvgFilter: function() { - return this.shadow ? "filter: url(#SVGID_" + this.shadow.id + ");" : ""; - }, - getSvgTransform: function() { - if (this.group && this.group.type === "path-group") { - return ""; - } - var toFixed = fabric.util.toFixed, angle = this.getAngle(), skewX = this.getSkewX() % 360, skewY = this.getSkewY() % 360, center = this.getCenterPoint(), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, translatePart = this.type === "path-group" ? "" : "translate(" + toFixed(center.x, NUM_FRACTION_DIGITS) + " " + toFixed(center.y, NUM_FRACTION_DIGITS) + ")", anglePart = angle !== 0 ? " rotate(" + toFixed(angle, NUM_FRACTION_DIGITS) + ")" : "", scalePart = this.scaleX === 1 && this.scaleY === 1 ? "" : " scale(" + toFixed(this.scaleX, NUM_FRACTION_DIGITS) + " " + toFixed(this.scaleY, NUM_FRACTION_DIGITS) + ")", skewXPart = skewX !== 0 ? " skewX(" + toFixed(skewX, NUM_FRACTION_DIGITS) + ")" : "", skewYPart = skewY !== 0 ? " skewY(" + toFixed(skewY, NUM_FRACTION_DIGITS) + ")" : "", addTranslateX = this.type === "path-group" ? this.width : 0, flipXPart = this.flipX ? " matrix(-1 0 0 1 " + addTranslateX + " 0) " : "", addTranslateY = this.type === "path-group" ? this.height : 0, flipYPart = this.flipY ? " matrix(1 0 0 -1 0 " + addTranslateY + ")" : ""; - return [ translatePart, anglePart, scalePart, flipXPart, flipYPart, skewXPart, skewYPart ].join(""); - }, - getSvgTransformMatrix: function() { - return this.transformMatrix ? " matrix(" + this.transformMatrix.join(" ") + ") " : ""; - }, - _createBaseSVGMarkup: function() { - var markup = []; - if (this.fill && this.fill.toLive) { - markup.push(this.fill.toSVG(this, false)); - } - if (this.stroke && this.stroke.toLive) { - markup.push(this.stroke.toSVG(this, false)); - } - if (this.shadow) { - markup.push(this.shadow.toSVG(this)); - } - return markup; - } -}); - -fabric.util.object.extend(fabric.Object.prototype, { - hasStateChanged: function() { - return this.stateProperties.some(function(prop) { - return this.get(prop) !== this.originalState[prop]; - }, this); - }, - saveState: function(options) { - this.stateProperties.forEach(function(prop) { - this.originalState[prop] = this.get(prop); - }, this); - if (options && options.stateProperties) { - options.stateProperties.forEach(function(prop) { - this.originalState[prop] = this.get(prop); - }, this); - } - return this; - }, - setupState: function() { - this.originalState = {}; - this.saveState(); - return this; - } -}); - -(function() { - var degreesToRadians = fabric.util.degreesToRadians, isVML = function() { - return typeof G_vmlCanvasManager !== "undefined"; - }; - fabric.util.object.extend(fabric.Object.prototype, { - _controlsVisibility: null, - _findTargetCorner: function(pointer) { - if (!this.hasControls || !this.active) { - return false; - } - var ex = pointer.x, ey = pointer.y, xPoints, lines; - this.__corner = 0; - for (var i in this.oCoords) { - if (!this.isControlVisible(i)) { - continue; - } - if (i === "mtr" && !this.hasRotatingPoint) { - continue; - } - if (this.get("lockUniScaling") && (i === "mt" || i === "mr" || i === "mb" || i === "ml")) { - continue; - } - lines = this._getImageLines(this.oCoords[i].corner); - xPoints = this._findCrossPoints({ - x: ex, - y: ey - }, lines); - if (xPoints !== 0 && xPoints % 2 === 1) { - this.__corner = i; - return i; - } - } - return false; - }, - _setCornerCoords: function() { - var coords = this.oCoords, newTheta = degreesToRadians(45 - this.angle), cornerHypotenuse = this.cornerSize * .707106, cosHalfOffset = cornerHypotenuse * Math.cos(newTheta), sinHalfOffset = cornerHypotenuse * Math.sin(newTheta), x, y; - for (var point in coords) { - x = coords[point].x; - y = coords[point].y; - coords[point].corner = { - tl: { - x: x - sinHalfOffset, - y: y - cosHalfOffset - }, - tr: { - x: x + cosHalfOffset, - y: y - sinHalfOffset - }, - bl: { - x: x - cosHalfOffset, - y: y + sinHalfOffset - }, - br: { - x: x + sinHalfOffset, - y: y + cosHalfOffset - } - }; - } - }, - _getNonTransformedDimensions: function() { - var strokeWidth = this.strokeWidth, w = this.width, h = this.height, addStrokeToW = true, addStrokeToH = true; - if (this.type === "line" && this.strokeLineCap === "butt") { - addStrokeToH = w; - addStrokeToW = h; - } - if (addStrokeToH) { - h += h < 0 ? -strokeWidth : strokeWidth; - } - if (addStrokeToW) { - w += w < 0 ? -strokeWidth : strokeWidth; - } - return { - x: w, - y: h - }; - }, - _getTransformedDimensions: function(skewX, skewY) { - if (typeof skewX === "undefined") { - skewX = this.skewX; - } - if (typeof skewY === "undefined") { - skewY = this.skewY; - } - var dimensions = this._getNonTransformedDimensions(), dimX = dimensions.x / 2, dimY = dimensions.y / 2, points = [ { - x: -dimX, - y: -dimY - }, { - x: dimX, - y: -dimY - }, { - x: -dimX, - y: dimY - }, { - x: dimX, - y: dimY - } ], i, transformMatrix = this._calcDimensionsTransformMatrix(skewX, skewY, false), bbox; - for (i = 0; i < points.length; i++) { - points[i] = fabric.util.transformPoint(points[i], transformMatrix); - } - bbox = fabric.util.makeBoundingBoxFromPoints(points); - return { - x: bbox.width, - y: bbox.height - }; - }, - _calculateCurrentDimensions: function() { - var vpt = this.getViewportTransform(), dim = this._getTransformedDimensions(), w = dim.x, h = dim.y; - w += 2 * this.padding; - h += 2 * this.padding; - return fabric.util.transformPoint(new fabric.Point(w, h), vpt, true); - }, - drawBorders: function(ctx) { - if (!this.hasBorders) { - return this; - } - var wh = this._calculateCurrentDimensions(), strokeWidth = 1 / this.borderScaleFactor, width = wh.x + strokeWidth, height = wh.y + strokeWidth; - ctx.save(); - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - ctx.strokeStyle = this.borderColor; - ctx.lineWidth = strokeWidth; - ctx.strokeRect(-width / 2, -height / 2, width, height); - if (this.hasRotatingPoint && this.isControlVisible("mtr") && !this.get("lockRotation") && this.hasControls) { - var rotateHeight = -height / 2; - ctx.beginPath(); - ctx.moveTo(0, rotateHeight); - ctx.lineTo(0, rotateHeight - this.rotatingPointOffset); - ctx.closePath(); - ctx.stroke(); - } - ctx.restore(); - return this; - }, - drawBordersInGroup: function(ctx, options) { - if (!this.hasBorders) { - return this; - } - var p = this._getNonTransformedDimensions(), matrix = fabric.util.customTransformMatrix(options.scaleX, options.scaleY, options.skewX), wh = fabric.util.transformPoint(p, matrix), strokeWidth = 1 / this.borderScaleFactor, width = wh.x + strokeWidth + 2 * this.padding, height = wh.y + strokeWidth + 2 * this.padding; - ctx.save(); - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - ctx.strokeStyle = this.borderColor; - ctx.lineWidth = strokeWidth; - ctx.strokeRect(-width / 2, -height / 2, width, height); - ctx.restore(); - return this; - }, - drawControls: function(ctx) { - if (!this.hasControls) { - return this; - } - var wh = this._calculateCurrentDimensions(), width = wh.x, height = wh.y, scaleOffset = this.cornerSize, left = -(width + scaleOffset) / 2, top = -(height + scaleOffset) / 2, methodName = this.transparentCorners ? "strokeRect" : "fillRect"; - ctx.save(); - ctx.lineWidth = 1; - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - ctx.strokeStyle = ctx.fillStyle = this.cornerColor; - this._drawControl("tl", ctx, methodName, left, top); - this._drawControl("tr", ctx, methodName, left + width, top); - this._drawControl("bl", ctx, methodName, left, top + height); - this._drawControl("br", ctx, methodName, left + width, top + height); - if (!this.get("lockUniScaling")) { - this._drawControl("mt", ctx, methodName, left + width / 2, top); - this._drawControl("mb", ctx, methodName, left + width / 2, top + height); - this._drawControl("mr", ctx, methodName, left + width, top + height / 2); - this._drawControl("ml", ctx, methodName, left, top + height / 2); - } - if (this.hasRotatingPoint) { - this._drawControl("mtr", ctx, methodName, left + width / 2, top - this.rotatingPointOffset); - } - ctx.restore(); - return this; - }, - _drawControl: function(control, ctx, methodName, left, top) { - if (!this.isControlVisible(control)) { - return; - } - var size = this.cornerSize; - isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size); - ctx[methodName](left, top, size, size); - }, - isControlVisible: function(controlName) { - return this._getControlsVisibility()[controlName]; - }, - setControlVisible: function(controlName, visible) { - this._getControlsVisibility()[controlName] = visible; - return this; - }, - setControlsVisibility: function(options) { - options || (options = {}); - for (var p in options) { - this.setControlVisible(p, options[p]); - } - return this; - }, - _getControlsVisibility: function() { - if (!this._controlsVisibility) { - this._controlsVisibility = { - tl: true, - tr: true, - br: true, - bl: true, - ml: true, - mt: true, - mr: true, - mb: true, - mtr: true - }; - } - return this._controlsVisibility; - } - }); -})(); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, { - FX_DURATION: 500, - fxCenterObjectH: function(object, callbacks) { - callbacks = callbacks || {}; - var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; - fabric.util.animate({ - startValue: object.get("left"), - endValue: this.getCenter().left, - duration: this.FX_DURATION, - onChange: function(value) { - object.set("left", value); - _this.renderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - return this; - }, - fxCenterObjectV: function(object, callbacks) { - callbacks = callbacks || {}; - var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; - fabric.util.animate({ - startValue: object.get("top"), - endValue: this.getCenter().top, - duration: this.FX_DURATION, - onChange: function(value) { - object.set("top", value); - _this.renderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - return this; - }, - fxRemove: function(object, callbacks) { - callbacks = callbacks || {}; - var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; - fabric.util.animate({ - startValue: object.get("opacity"), - endValue: 0, - duration: this.FX_DURATION, - onStart: function() { - object.set("active", false); - }, - onChange: function(value) { - object.set("opacity", value); - _this.renderAll(); - onChange(); - }, - onComplete: function() { - _this.remove(object); - onComplete(); - } - }); - return this; - } -}); - -fabric.util.object.extend(fabric.Object.prototype, { - animate: function() { - if (arguments[0] && typeof arguments[0] === "object") { - var propsToAnimate = [], prop, skipCallbacks; - for (prop in arguments[0]) { - propsToAnimate.push(prop); - } - for (var i = 0, len = propsToAnimate.length; i < len; i++) { - prop = propsToAnimate[i]; - skipCallbacks = i !== len - 1; - this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks); - } - } else { - this._animate.apply(this, arguments); - } - return this; - }, - _animate: function(property, to, options, skipCallbacks) { - var _this = this, propPair; - to = to.toString(); - if (!options) { - options = {}; - } else { - options = fabric.util.object.clone(options); - } - if (~property.indexOf(".")) { - propPair = property.split("."); - } - var currentValue = propPair ? this.get(propPair[0])[propPair[1]] : this.get(property); - if (!("from" in options)) { - options.from = currentValue; - } - if (~to.indexOf("=")) { - to = currentValue + parseFloat(to.replace("=", "")); - } else { - to = parseFloat(to); - } - fabric.util.animate({ - startValue: options.from, - endValue: to, - byValue: options.by, - easing: options.easing, - duration: options.duration, - abort: options.abort && function() { - return options.abort.call(_this); - }, - onChange: function(value) { - if (propPair) { - _this[propPair[0]][propPair[1]] = value; - } else { - _this.set(property, value); - } - if (skipCallbacks) { - return; - } - options.onChange && options.onChange(); - }, - onComplete: function() { - if (skipCallbacks) { - return; - } - _this.setCoords(); - options.onComplete && options.onComplete(); - } - }); - } -}); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, coordProps = { - x1: 1, - x2: 1, - y1: 1, - y2: 1 - }, supportsLineDash = fabric.StaticCanvas.supports("setLineDash"); - if (fabric.Line) { - fabric.warn("fabric.Line is already defined"); - return; - } - fabric.Line = fabric.util.createClass(fabric.Object, { - type: "line", - x1: 0, - y1: 0, - x2: 0, - y2: 0, - initialize: function(points, options) { - options = options || {}; - if (!points) { - points = [ 0, 0, 0, 0 ]; - } - this.callSuper("initialize", options); - this.set("x1", points[0]); - this.set("y1", points[1]); - this.set("x2", points[2]); - this.set("y2", points[3]); - this._setWidthHeight(options); - }, - _setWidthHeight: function(options) { - options || (options = {}); - this.width = Math.abs(this.x2 - this.x1); - this.height = Math.abs(this.y2 - this.y1); - this.left = "left" in options ? options.left : this._getLeftToOriginX(); - this.top = "top" in options ? options.top : this._getTopToOriginY(); - }, - _set: function(key, value) { - this.callSuper("_set", key, value); - if (typeof coordProps[key] !== "undefined") { - this._setWidthHeight(); - } - return this; - }, - _getLeftToOriginX: makeEdgeToOriginGetter({ - origin: "originX", - axis1: "x1", - axis2: "x2", - dimension: "width" - }, { - nearest: "left", - center: "center", - farthest: "right" - }), - _getTopToOriginY: makeEdgeToOriginGetter({ - origin: "originY", - axis1: "y1", - axis2: "y2", - dimension: "height" - }, { - nearest: "top", - center: "center", - farthest: "bottom" - }), - _render: function(ctx, noTransform) { - ctx.beginPath(); - if (noTransform) { - var cp = this.getCenterPoint(); - ctx.translate(cp.x - this.strokeWidth / 2, cp.y - this.strokeWidth / 2); - } - if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) { - var p = this.calcLinePoints(); - ctx.moveTo(p.x1, p.y1); - ctx.lineTo(p.x2, p.y2); - } - ctx.lineWidth = this.strokeWidth; - var origStrokeStyle = ctx.strokeStyle; - ctx.strokeStyle = this.stroke || ctx.fillStyle; - this.stroke && this._renderStroke(ctx); - ctx.strokeStyle = origStrokeStyle; - }, - _renderDashedStroke: function(ctx) { - var p = this.calcLinePoints(); - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray); - ctx.closePath(); - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), this.calcLinePoints()); - }, - calcLinePoints: function() { - var xMult = this.x1 <= this.x2 ? -1 : 1, yMult = this.y1 <= this.y2 ? -1 : 1, x1 = xMult * this.width * .5, y1 = yMult * this.height * .5, x2 = xMult * this.width * -.5, y2 = yMult * this.height * -.5; - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2 - }; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), p = { - x1: this.x1, - x2: this.x2, - y1: this.y1, - y2: this.y2 - }; - if (!(this.group && this.group.type === "path-group")) { - p = this.calcLinePoints(); - } - markup.push("\n'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - complexity: function() { - return 1; - } - }); - fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")); - fabric.Line.fromElement = function(element, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), points = [ parsedAttributes.x1 || 0, parsedAttributes.y1 || 0, parsedAttributes.x2 || 0, parsedAttributes.y2 || 0 ]; - return new fabric.Line(points, extend(parsedAttributes, options)); - }; - fabric.Line.fromObject = function(object) { - var points = [ object.x1, object.y1, object.x2, object.y2 ]; - return new fabric.Line(points, object); - }; - function makeEdgeToOriginGetter(propertyNames, originValues) { - var origin = propertyNames.origin, axis1 = propertyNames.axis1, axis2 = propertyNames.axis2, dimension = propertyNames.dimension, nearest = originValues.nearest, center = originValues.center, farthest = originValues.farthest; - return function() { - switch (this.get(origin)) { - case nearest: - return Math.min(this.get(axis1), this.get(axis2)); - - case center: - return Math.min(this.get(axis1), this.get(axis2)) + .5 * this.get(dimension); - - case farthest: - return Math.max(this.get(axis1), this.get(axis2)); - } - }; - } -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), pi = Math.PI, extend = fabric.util.object.extend; - if (fabric.Circle) { - fabric.warn("fabric.Circle is already defined."); - return; - } - fabric.Circle = fabric.util.createClass(fabric.Object, { - type: "circle", - radius: 0, - startAngle: 0, - endAngle: pi * 2, - initialize: function(options) { - options = options || {}; - this.callSuper("initialize", options); - this.set("radius", options.radius || 0); - this.startAngle = options.startAngle || this.startAngle; - this.endAngle = options.endAngle || this.endAngle; - }, - _set: function(key, value) { - this.callSuper("_set", key, value); - if (key === "radius") { - this.setRadius(value); - } - return this; - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), { - radius: this.get("radius"), - startAngle: this.startAngle, - endAngle: this.endAngle - }); - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = 0, y = 0, angle = (this.endAngle - this.startAngle) % (2 * pi); - if (angle === 0) { - if (this.group && this.group.type === "path-group") { - x = this.left + this.radius; - y = this.top + this.radius; - } - markup.push("\n'); - } else { - var startX = Math.cos(this.startAngle) * this.radius, startY = Math.sin(this.startAngle) * this.radius, endX = Math.cos(this.endAngle) * this.radius, endY = Math.sin(this.endAngle) * this.radius, largeFlag = angle > pi ? "1" : "0"; - markup.push('\n'); - } - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - _render: function(ctx, noTransform) { - ctx.beginPath(); - ctx.arc(noTransform ? this.left + this.radius : 0, noTransform ? this.top + this.radius : 0, this.radius, this.startAngle, this.endAngle, false); - this._renderFill(ctx); - this._renderStroke(ctx); - }, - getRadiusX: function() { - return this.get("radius") * this.get("scaleX"); - }, - getRadiusY: function() { - return this.get("radius") * this.get("scaleY"); - }, - setRadius: function(value) { - this.radius = value; - return this.set("width", value * 2).set("height", value * 2); - }, - complexity: function() { - return 1; - } - }); - fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")); - fabric.Circle.fromElement = function(element, options) { - options || (options = {}); - var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); - if (!isValidRadius(parsedAttributes)) { - throw new Error("value of `r` attribute is required and can not be negative"); - } - parsedAttributes.left = parsedAttributes.left || 0; - parsedAttributes.top = parsedAttributes.top || 0; - var obj = new fabric.Circle(extend(parsedAttributes, options)); - obj.left -= obj.radius; - obj.top -= obj.radius; - return obj; - }; - function isValidRadius(attributes) { - return "radius" in attributes && attributes.radius >= 0; - } - fabric.Circle.fromObject = function(object) { - return new fabric.Circle(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Triangle) { - fabric.warn("fabric.Triangle is already defined"); - return; - } - fabric.Triangle = fabric.util.createClass(fabric.Object, { - type: "triangle", - initialize: function(options) { - options = options || {}; - this.callSuper("initialize", options); - this.set("width", options.width || 100).set("height", options.height || 100); - }, - _render: function(ctx) { - var widthBy2 = this.width / 2, heightBy2 = this.height / 2; - ctx.beginPath(); - ctx.moveTo(-widthBy2, heightBy2); - ctx.lineTo(0, -heightBy2); - ctx.lineTo(widthBy2, heightBy2); - ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); - }, - _renderDashedStroke: function(ctx) { - var widthBy2 = this.width / 2, heightBy2 = this.height / 2; - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray); - ctx.closePath(); - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), widthBy2 = this.width / 2, heightBy2 = this.height / 2, points = [ -widthBy2 + " " + heightBy2, "0 " + -heightBy2, widthBy2 + " " + heightBy2 ].join(","); - markup.push("'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - complexity: function() { - return 1; - } - }); - fabric.Triangle.fromObject = function(object) { - return new fabric.Triangle(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), piBy2 = Math.PI * 2, extend = fabric.util.object.extend; - if (fabric.Ellipse) { - fabric.warn("fabric.Ellipse is already defined."); - return; - } - fabric.Ellipse = fabric.util.createClass(fabric.Object, { - type: "ellipse", - rx: 0, - ry: 0, - initialize: function(options) { - options = options || {}; - this.callSuper("initialize", options); - this.set("rx", options.rx || 0); - this.set("ry", options.ry || 0); - }, - _set: function(key, value) { - this.callSuper("_set", key, value); - switch (key) { - case "rx": - this.rx = value; - this.set("width", value * 2); - break; - - case "ry": - this.ry = value; - this.set("height", value * 2); - break; - } - return this; - }, - getRx: function() { - return this.get("rx") * this.get("scaleX"); - }, - getRy: function() { - return this.get("ry") * this.get("scaleY"); - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), { - rx: this.get("rx"), - ry: this.get("ry") - }); - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = 0, y = 0; - if (this.group && this.group.type === "path-group") { - x = this.left + this.rx; - y = this.top + this.ry; - } - markup.push("\n'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - _render: function(ctx, noTransform) { - ctx.beginPath(); - ctx.save(); - ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0); - ctx.arc(noTransform ? this.left + this.rx : 0, noTransform ? (this.top + this.ry) * this.rx / this.ry : 0, this.rx, 0, piBy2, false); - ctx.restore(); - this._renderFill(ctx); - this._renderStroke(ctx); - }, - complexity: function() { - return 1; - } - }); - fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")); - fabric.Ellipse.fromElement = function(element, options) { - options || (options = {}); - var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); - parsedAttributes.left = parsedAttributes.left || 0; - parsedAttributes.top = parsedAttributes.top || 0; - var ellipse = new fabric.Ellipse(extend(parsedAttributes, options)); - ellipse.top -= ellipse.ry; - ellipse.left -= ellipse.rx; - return ellipse; - }; - fabric.Ellipse.fromObject = function(object) { - return new fabric.Ellipse(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - if (fabric.Rect) { - fabric.warn("fabric.Rect is already defined"); - return; - } - var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push("rx", "ry", "x", "y"); - fabric.Rect = fabric.util.createClass(fabric.Object, { - stateProperties: stateProperties, - type: "rect", - rx: 0, - ry: 0, - strokeDashArray: null, - initialize: function(options) { - options = options || {}; - this.callSuper("initialize", options); - this._initRxRy(); - }, - _initRxRy: function() { - if (this.rx && !this.ry) { - this.ry = this.rx; - } else if (this.ry && !this.rx) { - this.rx = this.ry; - } - }, - _render: function(ctx, noTransform) { - if (this.width === 1 && this.height === 1) { - ctx.fillRect(-.5, -.5, 1, 1); - return; - } - var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0, ry = this.ry ? Math.min(this.ry, this.height / 2) : 0, w = this.width, h = this.height, x = noTransform ? this.left : -this.width / 2, y = noTransform ? this.top : -this.height / 2, isRounded = rx !== 0 || ry !== 0, k = 1 - .5522847498; - ctx.beginPath(); - ctx.moveTo(x + rx, y); - ctx.lineTo(x + w - rx, y); - isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry); - ctx.lineTo(x + w, y + h - ry); - isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h); - ctx.lineTo(x + rx, y + h); - isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry); - ctx.lineTo(x, y + ry); - isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y); - ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); - }, - _renderDashedStroke: function(ctx) { - var x = -this.width / 2, y = -this.height / 2, w = this.width, h = this.height; - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray); - ctx.closePath(); - }, - toObject: function(propertiesToInclude) { - var object = extend(this.callSuper("toObject", propertiesToInclude), { - rx: this.get("rx") || 0, - ry: this.get("ry") || 0 - }); - if (!this.includeDefaultValues) { - this._removeDefaultValues(object); - } - return object; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = this.left, y = this.top; - if (!(this.group && this.group.type === "path-group")) { - x = -this.width / 2; - y = -this.height / 2; - } - markup.push("\n'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - complexity: function() { - return 1; - } - }); - fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")); - fabric.Rect.fromElement = function(element, options) { - if (!element) { - return null; - } - options = options || {}; - var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES); - parsedAttributes.left = parsedAttributes.left || 0; - parsedAttributes.top = parsedAttributes.top || 0; - var rect = new fabric.Rect(extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes)); - rect.visible = rect.width > 0 && rect.height > 0; - return rect; - }; - fabric.Rect.fromObject = function(object) { - return new fabric.Rect(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Polyline) { - fabric.warn("fabric.Polyline is already defined"); - return; - } - fabric.Polyline = fabric.util.createClass(fabric.Object, { - type: "polyline", - points: null, - minX: 0, - minY: 0, - initialize: function(points, options) { - return fabric.Polygon.prototype.initialize.call(this, points, options); - }, - _calcDimensions: function() { - return fabric.Polygon.prototype._calcDimensions.call(this); - }, - _applyPointOffset: function() { - return fabric.Polygon.prototype._applyPointOffset.call(this); - }, - toObject: function(propertiesToInclude) { - return fabric.Polygon.prototype.toObject.call(this, propertiesToInclude); - }, - toSVG: function(reviver) { - return fabric.Polygon.prototype.toSVG.call(this, reviver); - }, - _render: function(ctx, noTransform) { - if (!fabric.Polygon.prototype.commonRender.call(this, ctx, noTransform)) { - return; - } - this._renderFill(ctx); - this._renderStroke(ctx); - }, - _renderDashedStroke: function(ctx) { - var p1, p2; - ctx.beginPath(); - for (var i = 0, len = this.points.length; i < len; i++) { - p1 = this.points[i]; - p2 = this.points[i + 1] || p1; - fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray); - } - }, - complexity: function() { - return this.get("points").length; - } - }); - fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - fabric.Polyline.fromElement = function(element, options) { - if (!element) { - return null; - } - options || (options = {}); - var points = fabric.parsePointsAttribute(element.getAttribute("points")), parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES); - return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options)); - }; - fabric.Polyline.fromObject = function(object) { - var points = object.points; - return new fabric.Polyline(points, object, true); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, min = fabric.util.array.min, max = fabric.util.array.max, toFixed = fabric.util.toFixed; - if (fabric.Polygon) { - fabric.warn("fabric.Polygon is already defined"); - return; - } - fabric.Polygon = fabric.util.createClass(fabric.Object, { - type: "polygon", - points: null, - minX: 0, - minY: 0, - initialize: function(points, options) { - options = options || {}; - this.points = points || []; - this.callSuper("initialize", options); - this._calcDimensions(); - if (!("top" in options)) { - this.top = this.minY; - } - if (!("left" in options)) { - this.left = this.minX; - } - this.pathOffset = { - x: this.minX + this.width / 2, - y: this.minY + this.height / 2 - }; - }, - _calcDimensions: function() { - var points = this.points, minX = min(points, "x"), minY = min(points, "y"), maxX = max(points, "x"), maxY = max(points, "y"); - this.width = maxX - minX || 0; - this.height = maxY - minY || 0; - this.minX = minX || 0, this.minY = minY || 0; - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), { - points: this.points.concat() - }); - }, - toSVG: function(reviver) { - var points = [], addTransform, markup = this._createBaseSVGMarkup(); - for (var i = 0, len = this.points.length; i < len; i++) { - points.push(toFixed(this.points[i].x, 2), ",", toFixed(this.points[i].y, 2), " "); - } - if (!(this.group && this.group.type === "path-group")) { - addTransform = " translate(" + -this.pathOffset.x + ", " + -this.pathOffset.y + ") "; - } - markup.push("<", this.type, " ", 'points="', points.join(""), '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), addTransform, " ", this.getSvgTransformMatrix(), '"/>\n'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - _render: function(ctx, noTransform) { - if (!this.commonRender(ctx, noTransform)) { - return; - } - this._renderFill(ctx); - if (this.stroke || this.strokeDashArray) { - ctx.closePath(); - this._renderStroke(ctx); - } - }, - commonRender: function(ctx, noTransform) { - var point, len = this.points.length; - if (!len || isNaN(this.points[len - 1].y)) { - return false; - } - noTransform || ctx.translate(-this.pathOffset.x, -this.pathOffset.y); - ctx.beginPath(); - ctx.moveTo(this.points[0].x, this.points[0].y); - for (var i = 0; i < len; i++) { - point = this.points[i]; - ctx.lineTo(point.x, point.y); - } - return true; - }, - _renderDashedStroke: function(ctx) { - fabric.Polyline.prototype._renderDashedStroke.call(this, ctx); - ctx.closePath(); - }, - complexity: function() { - return this.points.length; - } - }); - fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - fabric.Polygon.fromElement = function(element, options) { - if (!element) { - return null; - } - options || (options = {}); - var points = fabric.parsePointsAttribute(element.getAttribute("points")), parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES); - return new fabric.Polygon(points, extend(parsedAttributes, options)); - }; - fabric.Polygon.fromObject = function(object) { - return new fabric.Polygon(object.points, object, true); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), min = fabric.util.array.min, max = fabric.util.array.max, extend = fabric.util.object.extend, _toString = Object.prototype.toString, drawArc = fabric.util.drawArc, commandLengths = { - m: 2, - l: 2, - h: 1, - v: 1, - c: 6, - s: 4, - q: 4, - t: 2, - a: 7 - }, repeatedCommands = { - m: "l", - M: "L" - }; - if (fabric.Path) { - fabric.warn("fabric.Path is already defined"); - return; - } - fabric.Path = fabric.util.createClass(fabric.Object, { - type: "path", - path: null, - minX: 0, - minY: 0, - initialize: function(path, options) { - options = options || {}; - this.setOptions(options); - if (!path) { - path = []; - } - var fromArray = _toString.call(path) === "[object Array]"; - this.path = fromArray ? path : path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi); - if (!this.path) { - return; - } - if (!fromArray) { - this.path = this._parsePath(); - } - this._setPositionDimensions(options); - if (options.sourcePath) { - this.setSourcePath(options.sourcePath); - } - }, - _setPositionDimensions: function(options) { - var calcDim = this._parseDimensions(); - this.minX = calcDim.left; - this.minY = calcDim.top; - this.width = calcDim.width; - this.height = calcDim.height; - if (typeof options.left === "undefined") { - this.left = calcDim.left + (this.originX === "center" ? this.width / 2 : this.originX === "right" ? this.width : 0); - } - if (typeof options.top === "undefined") { - this.top = calcDim.top + (this.originY === "center" ? this.height / 2 : this.originY === "bottom" ? this.height : 0); - } - this.pathOffset = this.pathOffset || { - x: this.minX + this.width / 2, - y: this.minY + this.height / 2 - }; - }, - _render: function(ctx) { - var current, previous = null, subpathStartX = 0, subpathStartY = 0, x = 0, y = 0, controlX = 0, controlY = 0, tempX, tempY, l = -this.pathOffset.x, t = -this.pathOffset.y; - if (this.group && this.group.type === "path-group") { - l = 0; - t = 0; - } - ctx.beginPath(); - for (var i = 0, len = this.path.length; i < len; ++i) { - current = this.path[i]; - switch (current[0]) { - case "l": - x += current[1]; - y += current[2]; - ctx.lineTo(x + l, y + t); - break; - - case "L": - x = current[1]; - y = current[2]; - ctx.lineTo(x + l, y + t); - break; - - case "h": - x += current[1]; - ctx.lineTo(x + l, y + t); - break; - - case "H": - x = current[1]; - ctx.lineTo(x + l, y + t); - break; - - case "v": - y += current[1]; - ctx.lineTo(x + l, y + t); - break; - - case "V": - y = current[1]; - ctx.lineTo(x + l, y + t); - break; - - case "m": - x += current[1]; - y += current[2]; - subpathStartX = x; - subpathStartY = y; - ctx.moveTo(x + l, y + t); - break; - - case "M": - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - ctx.moveTo(x + l, y + t); - break; - - case "c": - tempX = x + current[5]; - tempY = y + current[6]; - controlX = x + current[3]; - controlY = y + current[4]; - ctx.bezierCurveTo(x + current[1] + l, y + current[2] + t, controlX + l, controlY + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - break; - - case "C": - x = current[5]; - y = current[6]; - controlX = current[3]; - controlY = current[4]; - ctx.bezierCurveTo(current[1] + l, current[2] + t, controlX + l, controlY + t, x + l, y + t); - break; - - case "s": - tempX = x + current[3]; - tempY = y + current[4]; - if (previous[0].match(/[CcSs]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - ctx.bezierCurveTo(controlX + l, controlY + t, x + current[1] + l, y + current[2] + t, tempX + l, tempY + t); - controlX = x + current[1]; - controlY = y + current[2]; - x = tempX; - y = tempY; - break; - - case "S": - tempX = current[3]; - tempY = current[4]; - if (previous[0].match(/[CcSs]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - ctx.bezierCurveTo(controlX + l, controlY + t, current[1] + l, current[2] + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - controlX = current[1]; - controlY = current[2]; - break; - - case "q": - tempX = x + current[3]; - tempY = y + current[4]; - controlX = x + current[1]; - controlY = y + current[2]; - ctx.quadraticCurveTo(controlX + l, controlY + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - break; - - case "Q": - tempX = current[3]; - tempY = current[4]; - ctx.quadraticCurveTo(current[1] + l, current[2] + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - controlX = current[1]; - controlY = current[2]; - break; - - case "t": - tempX = x + current[1]; - tempY = y + current[2]; - if (previous[0].match(/[QqTt]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - ctx.quadraticCurveTo(controlX + l, controlY + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - break; - - case "T": - tempX = current[1]; - tempY = current[2]; - if (previous[0].match(/[QqTt]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - ctx.quadraticCurveTo(controlX + l, controlY + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - break; - - case "a": - drawArc(ctx, x + l, y + t, [ current[1], current[2], current[3], current[4], current[5], current[6] + x + l, current[7] + y + t ]); - x += current[6]; - y += current[7]; - break; - - case "A": - drawArc(ctx, x + l, y + t, [ current[1], current[2], current[3], current[4], current[5], current[6] + l, current[7] + t ]); - x = current[6]; - y = current[7]; - break; - - case "z": - case "Z": - x = subpathStartX; - y = subpathStartY; - ctx.closePath(); - break; - } - previous = current; - } - this._renderFill(ctx); - this._renderStroke(ctx); - }, - toString: function() { - return "#"; - }, - toObject: function(propertiesToInclude) { - var o = extend(this.callSuper("toObject", propertiesToInclude), { - path: this.path.map(function(item) { - return item.slice(); - }), - pathOffset: this.pathOffset - }); - if (this.sourcePath) { - o.sourcePath = this.sourcePath; - } - if (this.transformMatrix) { - o.transformMatrix = this.transformMatrix; - } - return o; - }, - toDatalessObject: function(propertiesToInclude) { - var o = this.toObject(propertiesToInclude); - if (this.sourcePath) { - o.path = this.sourcePath; - } - delete o.sourcePath; - return o; - }, - toSVG: function(reviver) { - var chunks = [], markup = this._createBaseSVGMarkup(), addTransform = ""; - for (var i = 0, len = this.path.length; i < len; i++) { - chunks.push(this.path[i].join(" ")); - } - var path = chunks.join(" "); - if (!(this.group && this.group.type === "path-group")) { - addTransform = " translate(" + -this.pathOffset.x + ", " + -this.pathOffset.y + ") "; - } - markup.push("\n"); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - complexity: function() { - return this.path.length; - }, - _parsePath: function() { - var result = [], coords = [], currentPath, parsed, re = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi, match, coordsStr; - for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) { - currentPath = this.path[i]; - coordsStr = currentPath.slice(1).trim(); - coords.length = 0; - while (match = re.exec(coordsStr)) { - coords.push(match[0]); - } - coordsParsed = [ currentPath.charAt(0) ]; - for (var j = 0, jlen = coords.length; j < jlen; j++) { - parsed = parseFloat(coords[j]); - if (!isNaN(parsed)) { - coordsParsed.push(parsed); - } - } - var command = coordsParsed[0], commandLength = commandLengths[command.toLowerCase()], repeatedCommand = repeatedCommands[command] || command; - if (coordsParsed.length - 1 > commandLength) { - for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) { - result.push([ command ].concat(coordsParsed.slice(k, k + commandLength))); - command = repeatedCommand; - } - } else { - result.push(coordsParsed); - } - } - return result; - }, - _parseDimensions: function() { - var aX = [], aY = [], current, previous = null, subpathStartX = 0, subpathStartY = 0, x = 0, y = 0, controlX = 0, controlY = 0, tempX, tempY, bounds; - for (var i = 0, len = this.path.length; i < len; ++i) { - current = this.path[i]; - switch (current[0]) { - case "l": - x += current[1]; - y += current[2]; - bounds = []; - break; - - case "L": - x = current[1]; - y = current[2]; - bounds = []; - break; - - case "h": - x += current[1]; - bounds = []; - break; - - case "H": - x = current[1]; - bounds = []; - break; - - case "v": - y += current[1]; - bounds = []; - break; - - case "V": - y = current[1]; - bounds = []; - break; - - case "m": - x += current[1]; - y += current[2]; - subpathStartX = x; - subpathStartY = y; - bounds = []; - break; - - case "M": - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - bounds = []; - break; - - case "c": - tempX = x + current[5]; - tempY = y + current[6]; - controlX = x + current[3]; - controlY = y + current[4]; - bounds = fabric.util.getBoundsOfCurve(x, y, x + current[1], y + current[2], controlX, controlY, tempX, tempY); - x = tempX; - y = tempY; - break; - - case "C": - x = current[5]; - y = current[6]; - controlX = current[3]; - controlY = current[4]; - bounds = fabric.util.getBoundsOfCurve(x, y, current[1], current[2], controlX, controlY, x, y); - break; - - case "s": - tempX = x + current[3]; - tempY = y + current[4]; - if (previous[0].match(/[CcSs]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, x + current[1], y + current[2], tempX, tempY); - controlX = x + current[1]; - controlY = y + current[2]; - x = tempX; - y = tempY; - break; - - case "S": - tempX = current[3]; - tempY = current[4]; - if (previous[0].match(/[CcSs]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, current[1], current[2], tempX, tempY); - x = tempX; - y = tempY; - controlX = current[1]; - controlY = current[2]; - break; - - case "q": - tempX = x + current[3]; - tempY = y + current[4]; - controlX = x + current[1]; - controlY = y + current[2]; - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, tempX, tempY); - x = tempX; - y = tempY; - break; - - case "Q": - controlX = current[1]; - controlY = current[2]; - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, current[3], current[4]); - x = current[3]; - y = current[4]; - break; - - case "t": - tempX = x + current[1]; - tempY = y + current[2]; - if (previous[0].match(/[QqTt]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, tempX, tempY); - x = tempX; - y = tempY; - break; - - case "T": - tempX = current[1]; - tempY = current[2]; - if (previous[0].match(/[QqTt]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, tempX, tempY); - x = tempX; - y = tempY; - break; - - case "a": - bounds = fabric.util.getBoundsOfArc(x, y, current[1], current[2], current[3], current[4], current[5], current[6] + x, current[7] + y); - x += current[6]; - y += current[7]; - break; - - case "A": - bounds = fabric.util.getBoundsOfArc(x, y, current[1], current[2], current[3], current[4], current[5], current[6], current[7]); - x = current[6]; - y = current[7]; - break; - - case "z": - case "Z": - x = subpathStartX; - y = subpathStartY; - break; - } - previous = current; - bounds.forEach(function(point) { - aX.push(point.x); - aY.push(point.y); - }); - aX.push(x); - aY.push(y); - } - var minX = min(aX) || 0, minY = min(aY) || 0, maxX = max(aX) || 0, maxY = max(aY) || 0, deltaX = maxX - minX, deltaY = maxY - minY, o = { - left: minX, - top: minY, - width: deltaX, - height: deltaY - }; - return o; - } - }); - fabric.Path.fromObject = function(object, callback) { - if (typeof object.path === "string") { - fabric.loadSVGFromURL(object.path, function(elements) { - var path = elements[0], pathUrl = object.path; - delete object.path; - fabric.util.object.extend(path, object); - path.setSourcePath(pathUrl); - callback(path); - }); - } else { - callback(new fabric.Path(object.path, object)); - } - }; - fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat([ "d" ]); - fabric.Path.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); - callback && callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); - }; - fabric.Path.async = true; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, invoke = fabric.util.array.invoke, parentToObject = fabric.Object.prototype.toObject; - if (fabric.PathGroup) { - fabric.warn("fabric.PathGroup is already defined"); - return; - } - fabric.PathGroup = fabric.util.createClass(fabric.Path, { - type: "path-group", - fill: "", - initialize: function(paths, options) { - options = options || {}; - this.paths = paths || []; - for (var i = this.paths.length; i--; ) { - this.paths[i].group = this; - } - if (options.toBeParsed) { - this.parseDimensionsFromPaths(options); - delete options.toBeParsed; - } - this.setOptions(options); - this.setCoords(); - if (options.sourcePath) { - this.setSourcePath(options.sourcePath); - } - }, - parseDimensionsFromPaths: function(options) { - var points, p, xC = [], yC = [], path, height, width, m; - for (var j = this.paths.length; j--; ) { - path = this.paths[j]; - height = path.height + path.strokeWidth; - width = path.width + path.strokeWidth; - points = [ { - x: path.left, - y: path.top - }, { - x: path.left + width, - y: path.top - }, { - x: path.left, - y: path.top + height - }, { - x: path.left + width, - y: path.top + height - } ]; - m = this.paths[j].transformMatrix; - for (var i = 0; i < points.length; i++) { - p = points[i]; - if (m) { - p = fabric.util.transformPoint(p, m, false); - } - xC.push(p.x); - yC.push(p.y); - } - } - options.width = Math.max.apply(null, xC); - options.height = Math.max.apply(null, yC); - }, - render: function(ctx) { - if (!this.visible) { - return; - } - ctx.save(); - if (this.transformMatrix) { - ctx.transform.apply(ctx, this.transformMatrix); - } - this.transform(ctx); - this._setShadow(ctx); - this.clipTo && fabric.util.clipContext(this, ctx); - ctx.translate(-this.width / 2, -this.height / 2); - for (var i = 0, l = this.paths.length; i < l; ++i) { - this.paths[i].render(ctx, true); - } - this.clipTo && ctx.restore(); - ctx.restore(); - }, - _set: function(prop, value) { - if (prop === "fill" && value && this.isSameColor()) { - var i = this.paths.length; - while (i--) { - this.paths[i]._set(prop, value); - } - } - return this.callSuper("_set", prop, value); - }, - toObject: function(propertiesToInclude) { - var o = extend(parentToObject.call(this, propertiesToInclude), { - paths: invoke(this.getObjects(), "toObject", propertiesToInclude) - }); - if (this.sourcePath) { - o.sourcePath = this.sourcePath; - } - return o; - }, - toDatalessObject: function(propertiesToInclude) { - var o = this.toObject(propertiesToInclude); - if (this.sourcePath) { - o.paths = this.sourcePath; - } - return o; - }, - toSVG: function(reviver) { - var objects = this.getObjects(), p = this.getPointByOrigin("left", "top"), translatePart = "translate(" + p.x + " " + p.y + ")", markup = this._createBaseSVGMarkup(); - markup.push("\n"); - for (var i = 0, len = objects.length; i < len; i++) { - markup.push(" ", objects[i].toSVG(reviver)); - } - markup.push("\n"); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - toString: function() { - return "#"; - }, - isSameColor: function() { - var firstPathFill = this.getObjects()[0].get("fill") || ""; - if (typeof firstPathFill !== "string") { - return false; - } - firstPathFill = firstPathFill.toLowerCase(); - return this.getObjects().every(function(path) { - var pathFill = path.get("fill") || ""; - return typeof pathFill === "string" && pathFill.toLowerCase() === firstPathFill; - }); - }, - complexity: function() { - return this.paths.reduce(function(total, path) { - return total + (path && path.complexity ? path.complexity() : 0); - }, 0); - }, - getObjects: function() { - return this.paths; - } - }); - fabric.PathGroup.fromObject = function(object, callback) { - if (typeof object.paths === "string") { - fabric.loadSVGFromURL(object.paths, function(elements) { - var pathUrl = object.paths; - delete object.paths; - var pathGroup = fabric.util.groupSVGElements(elements, object, pathUrl); - callback(pathGroup); - }); - } else { - fabric.util.enlivenObjects(object.paths, function(enlivenedObjects) { - delete object.paths; - callback(new fabric.PathGroup(enlivenedObjects, object)); - }); - } - }; - fabric.PathGroup.async = true; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, min = fabric.util.array.min, max = fabric.util.array.max, invoke = fabric.util.array.invoke; - if (fabric.Group) { - return; - } - var _lockProperties = { - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - lockUniScaling: true - }; - fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, { - type: "group", - strokeWidth: 0, - initialize: function(objects, options, isAlreadyGrouped) { - options = options || {}; - this._objects = []; - isAlreadyGrouped && this.callSuper("initialize", options); - this._objects = objects || []; - for (var i = this._objects.length; i--; ) { - this._objects[i].group = this; - } - this.originalState = {}; - if (options.originX) { - this.originX = options.originX; - } - if (options.originY) { - this.originY = options.originY; - } - if (isAlreadyGrouped) { - this._updateObjectsCoords(true); - } else { - this._calcBounds(); - this._updateObjectsCoords(); - this.callSuper("initialize", options); - } - this.setCoords(); - this.saveCoords(); - }, - _updateObjectsCoords: function(skipCoordsChange) { - for (var i = this._objects.length; i--; ) { - this._updateObjectCoords(this._objects[i], skipCoordsChange); - } - }, - _updateObjectCoords: function(object, skipCoordsChange) { - object.__origHasControls = object.hasControls; - object.hasControls = false; - if (skipCoordsChange) { - return; - } - var objectLeft = object.getLeft(), objectTop = object.getTop(), center = this.getCenterPoint(); - object.set({ - originalLeft: objectLeft, - originalTop: objectTop, - left: objectLeft - center.x, - top: objectTop - center.y - }); - object.setCoords(); - }, - toString: function() { - return "#"; - }, - addWithUpdate: function(object) { - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - if (object) { - this._objects.push(object); - object.group = this; - object._set("canvas", this.canvas); - } - this.forEachObject(this._setObjectActive, this); - this._calcBounds(); - this._updateObjectsCoords(); - return this; - }, - _setObjectActive: function(object) { - object.set("active", true); - object.group = this; - }, - removeWithUpdate: function(object) { - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - this.forEachObject(this._setObjectActive, this); - this.remove(object); - this._calcBounds(); - this._updateObjectsCoords(); - return this; - }, - _onObjectAdded: function(object) { - object.group = this; - object._set("canvas", this.canvas); - }, - _onObjectRemoved: function(object) { - delete object.group; - object.set("active", false); - }, - delegatedProperties: { - fill: true, - stroke: true, - strokeWidth: true, - fontFamily: true, - fontWeight: true, - fontSize: true, - fontStyle: true, - lineHeight: true, - textDecoration: true, - textAlign: true, - backgroundColor: true - }, - _set: function(key, value) { - var i = this._objects.length; - if (this.delegatedProperties[key] || key === "canvas") { - while (i--) { - this._objects[i].set(key, value); - } - } else { - while (i--) { - this._objects[i].setOnGroup(key, value); - } - } - this.callSuper("_set", key, value); - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), { - objects: invoke(this._objects, "toObject", propertiesToInclude) - }); - }, - render: function(ctx) { - if (!this.visible) { - return; - } - ctx.save(); - if (this.transformMatrix) { - ctx.transform.apply(ctx, this.transformMatrix); - } - this.transform(ctx); - this._setShadow(ctx); - this.clipTo && fabric.util.clipContext(this, ctx); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._renderObject(this._objects[i], ctx); - } - this.clipTo && ctx.restore(); - ctx.restore(); - }, - _renderControls: function(ctx, noTransform) { - this.callSuper("_renderControls", ctx, noTransform); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i]._renderControls(ctx); - } - }, - _renderObject: function(object, ctx) { - if (!object.visible) { - return; - } - var originalHasRotatingPoint = object.hasRotatingPoint; - object.hasRotatingPoint = false; - object.render(ctx); - object.hasRotatingPoint = originalHasRotatingPoint; - }, - _restoreObjectsState: function() { - this._objects.forEach(this._restoreObjectState, this); - return this; - }, - realizeTransform: function(object) { - var matrix = object.calcTransformMatrix(), options = fabric.util.qrDecompose(matrix), center = new fabric.Point(options.translateX, options.translateY); - object.scaleX = options.scaleX; - object.scaleY = options.scaleY; - object.skewX = options.skewX; - object.skewY = options.skewY; - object.angle = options.angle; - object.flipX = false; - object.flipY = false; - object.setPositionByOrigin(center, "center", "center"); - return object; - }, - _restoreObjectState: function(object) { - this.realizeTransform(object); - object.setCoords(); - object.hasControls = object.__origHasControls; - delete object.__origHasControls; - object.set("active", false); - delete object.group; - return this; - }, - destroy: function() { - return this._restoreObjectsState(); - }, - saveCoords: function() { - this._originalLeft = this.get("left"); - this._originalTop = this.get("top"); - return this; - }, - hasMoved: function() { - return this._originalLeft !== this.get("left") || this._originalTop !== this.get("top"); - }, - setObjectsCoords: function() { - this.forEachObject(function(object) { - object.setCoords(); - }); - return this; - }, - _calcBounds: function(onlyWidthHeight) { - var aX = [], aY = [], o, prop, props = [ "tr", "br", "bl", "tl" ], i = 0, iLen = this._objects.length, j, jLen = props.length; - for (;i < iLen; ++i) { - o = this._objects[i]; - o.setCoords(); - for (j = 0; j < jLen; j++) { - prop = props[j]; - aX.push(o.oCoords[prop].x); - aY.push(o.oCoords[prop].y); - } - } - this.set(this._getBounds(aX, aY, onlyWidthHeight)); - }, - _getBounds: function(aX, aY, onlyWidthHeight) { - var ivt = fabric.util.invertTransform(this.getViewportTransform()), minXY = fabric.util.transformPoint(new fabric.Point(min(aX), min(aY)), ivt), maxXY = fabric.util.transformPoint(new fabric.Point(max(aX), max(aY)), ivt), obj = { - width: maxXY.x - minXY.x || 0, - height: maxXY.y - minXY.y || 0 - }; - if (!onlyWidthHeight) { - obj.left = minXY.x || 0; - obj.top = minXY.y || 0; - if (this.originX === "center") { - obj.left += obj.width / 2; - } - if (this.originX === "right") { - obj.left += obj.width; - } - if (this.originY === "center") { - obj.top += obj.height / 2; - } - if (this.originY === "bottom") { - obj.top += obj.height; - } - } - return obj; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(); - markup.push('\n'); - for (var i = 0, len = this._objects.length; i < len; i++) { - markup.push(" ", this._objects[i].toSVG(reviver)); - } - markup.push("\n"); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - get: function(prop) { - if (prop in _lockProperties) { - if (this[prop]) { - return this[prop]; - } else { - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i][prop]) { - return true; - } - } - return false; - } - } else { - if (prop in this.delegatedProperties) { - return this._objects[0] && this._objects[0].get(prop); - } - return this[prop]; - } - } - }); - fabric.Group.fromObject = function(object, callback) { - fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) { - delete object.objects; - callback && callback(new fabric.Group(enlivenedObjects, object, true)); - }); - }; - fabric.Group.async = true; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var extend = fabric.util.object.extend; - if (!global.fabric) { - global.fabric = {}; - } - if (global.fabric.Image) { - fabric.warn("fabric.Image is already defined."); - return; - } - fabric.Image = fabric.util.createClass(fabric.Object, { - type: "image", - crossOrigin: "", - alignX: "none", - alignY: "none", - meetOrSlice: "meet", - strokeWidth: 0, - _lastScaleX: 1, - _lastScaleY: 1, - initialize: function(element, options) { - options || (options = {}); - this.filters = []; - this.resizeFilters = []; - this.callSuper("initialize", options); - this._initElement(element, options); - }, - getElement: function() { - return this._element; - }, - setElement: function(element, callback, options) { - this._element = element; - this._originalElement = element; - this._initConfig(options); - if (this.filters.length !== 0) { - this.applyFilters(callback); - } else if (callback) { - callback(); - } - return this; - }, - setCrossOrigin: function(value) { - this.crossOrigin = value; - this._element.crossOrigin = value; - return this; - }, - getOriginalSize: function() { - var element = this.getElement(); - return { - width: element.width, - height: element.height - }; - }, - _stroke: function(ctx) { - ctx.save(); - this._setStrokeStyles(ctx); - ctx.beginPath(); - ctx.strokeRect(-this.width / 2, -this.height / 2, this.width, this.height); - ctx.closePath(); - ctx.restore(); - }, - _renderDashedStroke: function(ctx) { - var x = -this.width / 2, y = -this.height / 2, w = this.width, h = this.height; - ctx.save(); - this._setStrokeStyles(ctx); - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray); - ctx.closePath(); - ctx.restore(); - }, - toObject: function(propertiesToInclude) { - var filters = [], element = this._originalElement; - this.filters.forEach(function(filterObj) { - if (filterObj) { - filters.push(filterObj.toObject()); - } - }); - var object = extend(this.callSuper("toObject", propertiesToInclude), { - src: element ? element.src || element._src : "", - filters: filters, - crossOrigin: this.crossOrigin, - alignX: this.alignX, - alignY: this.alignY, - meetOrSlice: this.meetOrSlice - }); - if (this.resizeFilters.length > 0) { - object.resizeFilters = this.resizeFilters.map(function(filterObj) { - return filterObj && filterObj.toObject(); - }); - } - if (!this.includeDefaultValues) { - this._removeDefaultValues(object); - } - return object; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, preserveAspectRatio = "none"; - if (this.group && this.group.type === "path-group") { - x = this.left; - y = this.top; - } - if (this.alignX !== "none" && this.alignY !== "none") { - preserveAspectRatio = "x" + this.alignX + "Y" + this.alignY + " " + this.meetOrSlice; - } - markup.push('\n', '\n"); - if (this.stroke || this.strokeDashArray) { - var origFill = this.fill; - this.fill = null; - markup.push("\n'); - this.fill = origFill; - } - markup.push("\n"); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - getSrc: function() { - if (this.getElement()) { - return this.getElement().src || this.getElement()._src; - } - }, - setSrc: function(src, callback, options) { - fabric.util.loadImage(src, function(img) { - return this.setElement(img, callback, options); - }, this, options && options.crossOrigin); - }, - toString: function() { - return '#'; - }, - clone: function(callback, propertiesToInclude) { - this.constructor.fromObject(this.toObject(propertiesToInclude), callback); - }, - applyFilters: function(callback, filters, imgElement, forResizing) { - filters = filters || this.filters; - imgElement = imgElement || this._originalElement; - if (!imgElement) { - return; - } - var imgEl = imgElement, canvasEl = fabric.util.createCanvasElement(), replacement = fabric.util.createImage(), _this = this; - canvasEl.width = imgEl.width; - canvasEl.height = imgEl.height; - canvasEl.getContext("2d").drawImage(imgEl, 0, 0, imgEl.width, imgEl.height); - if (filters.length === 0) { - this._element = imgElement; - callback && callback(); - return canvasEl; - } - filters.forEach(function(filter) { - filter && filter.applyTo(canvasEl, filter.scaleX || _this.scaleX, filter.scaleY || _this.scaleY); - if (!forResizing && filter && filter.type === "Resize") { - _this.width *= filter.scaleX; - _this.height *= filter.scaleY; - } - }); - replacement.width = canvasEl.width; - replacement.height = canvasEl.height; - if (fabric.isLikelyNode) { - replacement.src = canvasEl.toBuffer(undefined, fabric.Image.pngCompression); - _this._element = replacement; - !forResizing && (_this._filteredEl = replacement); - callback && callback(); - } else { - replacement.onload = function() { - _this._element = replacement; - !forResizing && (_this._filteredEl = replacement); - callback && callback(); - replacement.onload = canvasEl = imgEl = null; - }; - replacement.src = canvasEl.toDataURL("image/png"); - } - return canvasEl; - }, - _render: function(ctx, noTransform) { - var x, y, imageMargins = this._findMargins(), elementToDraw; - x = noTransform ? this.left : -this.width / 2; - y = noTransform ? this.top : -this.height / 2; - if (this.meetOrSlice === "slice") { - ctx.beginPath(); - ctx.rect(x, y, this.width, this.height); - ctx.clip(); - } - if (this.isMoving === false && this.resizeFilters.length && this._needsResize()) { - this._lastScaleX = this.scaleX; - this._lastScaleY = this.scaleY; - elementToDraw = this.applyFilters(null, this.resizeFilters, this._filteredEl || this._originalElement, true); - } else { - elementToDraw = this._element; - } - elementToDraw && ctx.drawImage(elementToDraw, x + imageMargins.marginX, y + imageMargins.marginY, imageMargins.width, imageMargins.height); - this._renderStroke(ctx); - }, - _needsResize: function() { - return this.scaleX !== this._lastScaleX || this.scaleY !== this._lastScaleY; - }, - _findMargins: function() { - var width = this.width, height = this.height, scales, scale, marginX = 0, marginY = 0; - if (this.alignX !== "none" || this.alignY !== "none") { - scales = [ this.width / this._element.width, this.height / this._element.height ]; - scale = this.meetOrSlice === "meet" ? Math.min.apply(null, scales) : Math.max.apply(null, scales); - width = this._element.width * scale; - height = this._element.height * scale; - if (this.alignX === "Mid") { - marginX = (this.width - width) / 2; - } - if (this.alignX === "Max") { - marginX = this.width - width; - } - if (this.alignY === "Mid") { - marginY = (this.height - height) / 2; - } - if (this.alignY === "Max") { - marginY = this.height - height; - } - } - return { - width: width, - height: height, - marginX: marginX, - marginY: marginY - }; - }, - _resetWidthHeight: function() { - var element = this.getElement(); - this.set("width", element.width); - this.set("height", element.height); - }, - _initElement: function(element, options) { - this.setElement(fabric.util.getById(element), null, options); - fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS); - }, - _initConfig: function(options) { - options || (options = {}); - this.setOptions(options); - this._setWidthHeight(options); - if (this._element && this.crossOrigin) { - this._element.crossOrigin = this.crossOrigin; - } - }, - _initFilters: function(filters, callback) { - if (filters && filters.length) { - fabric.util.enlivenObjects(filters, function(enlivenedObjects) { - callback && callback(enlivenedObjects); - }, "fabric.Image.filters"); - } else { - callback && callback(); - } - }, - _setWidthHeight: function(options) { - this.width = "width" in options ? options.width : this.getElement() ? this.getElement().width || 0 : 0; - this.height = "height" in options ? options.height : this.getElement() ? this.getElement().height || 0 : 0; - }, - complexity: function() { - return 1; - } - }); - fabric.Image.CSS_CANVAS = "canvas-img"; - fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc; - fabric.Image.fromObject = function(object, callback) { - fabric.util.loadImage(object.src, function(img) { - fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) { - object.filters = filters || []; - fabric.Image.prototype._initFilters.call(object, object.resizeFilters, function(resizeFilters) { - object.resizeFilters = resizeFilters || []; - var instance = new fabric.Image(img, object); - callback && callback(instance); - }); - }); - }, null, object.crossOrigin); - }; - fabric.Image.fromURL = function(url, callback, imgOptions) { - fabric.util.loadImage(url, function(img) { - callback && callback(new fabric.Image(img, imgOptions)); - }, null, imgOptions && imgOptions.crossOrigin); - }; - fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".split(" ")); - fabric.Image.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES), preserveAR; - if (parsedAttributes.preserveAspectRatio) { - preserveAR = fabric.util.parsePreserveAspectRatioAttribute(parsedAttributes.preserveAspectRatio); - extend(parsedAttributes, preserveAR); - } - fabric.Image.fromURL(parsedAttributes["xlink:href"], callback, extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes)); - }; - fabric.Image.async = true; - fabric.Image.pngCompression = 1; -})(typeof exports !== "undefined" ? exports : this); - -fabric.util.object.extend(fabric.Object.prototype, { - _getAngleValueForStraighten: function() { - var angle = this.getAngle() % 360; - if (angle > 0) { - return Math.round((angle - 1) / 90) * 90; - } - return Math.round(angle / 90) * 90; - }, - straighten: function() { - this.setAngle(this._getAngleValueForStraighten()); - return this; - }, - fxStraighten: function(callbacks) { - callbacks = callbacks || {}; - var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; - fabric.util.animate({ - startValue: this.get("angle"), - endValue: this._getAngleValueForStraighten(), - duration: this.FX_DURATION, - onChange: function(value) { - _this.setAngle(value); - onChange(); - }, - onComplete: function() { - _this.setCoords(); - onComplete(); - }, - onStart: function() { - _this.set("active", false); - } - }); - return this; - } -}); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, { - straightenObject: function(object) { - object.straighten(); - this.renderAll(); - return this; - }, - fxStraightenObject: function(object) { - object.fxStraighten({ - onChange: this.renderAll.bind(this) - }); - return this; - } -}); - -fabric.Image.filters = fabric.Image.filters || {}; - -fabric.Image.filters.BaseFilter = fabric.util.createClass({ - type: "BaseFilter", - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - setOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - }, - toObject: function() { - return { - type: this.type - }; - }, - toJSON: function() { - return this.toObject(); - } -}); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Brightness = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Brightness", - initialize: function(options) { - options = options || {}; - this.brightness = options.brightness || 0; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, brightness = this.brightness; - for (var i = 0, len = data.length; i < len; i += 4) { - data[i] += brightness; - data[i + 1] += brightness; - data[i + 2] += brightness; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - brightness: this.brightness - }); - } - }); - fabric.Image.filters.Brightness.fromObject = function(object) { - return new fabric.Image.filters.Brightness(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Convolute = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Convolute", - initialize: function(options) { - options = options || {}; - this.opaque = options.opaque; - this.matrix = options.matrix || [ 0, 0, 0, 0, 1, 0, 0, 0, 0 ]; - }, - applyTo: function(canvasEl) { - var weights = this.matrix, context = canvasEl.getContext("2d"), pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height), side = Math.round(Math.sqrt(weights.length)), halfSide = Math.floor(side / 2), src = pixels.data, sw = pixels.width, sh = pixels.height, output = context.createImageData(sw, sh), dst = output.data, alphaFac = this.opaque ? 1 : 0, r, g, b, a, dstOff, scx, scy, srcOff, wt; - for (var y = 0; y < sh; y++) { - for (var x = 0; x < sw; x++) { - dstOff = (y * sw + x) * 4; - r = 0; - g = 0; - b = 0; - a = 0; - for (var cy = 0; cy < side; cy++) { - for (var cx = 0; cx < side; cx++) { - scy = y + cy - halfSide; - scx = x + cx - halfSide; - if (scy < 0 || scy > sh || scx < 0 || scx > sw) { - continue; - } - srcOff = (scy * sw + scx) * 4; - wt = weights[cy * side + cx]; - r += src[srcOff] * wt; - g += src[srcOff + 1] * wt; - b += src[srcOff + 2] * wt; - a += src[srcOff + 3] * wt; - } - } - dst[dstOff] = r; - dst[dstOff + 1] = g; - dst[dstOff + 2] = b; - dst[dstOff + 3] = a + alphaFac * (255 - a); - } - } - context.putImageData(output, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - opaque: this.opaque, - matrix: this.matrix - }); - } - }); - fabric.Image.filters.Convolute.fromObject = function(object) { - return new fabric.Image.filters.Convolute(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.GradientTransparency = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "GradientTransparency", - initialize: function(options) { - options = options || {}; - this.threshold = options.threshold || 100; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, threshold = this.threshold, total = data.length; - for (var i = 0, len = data.length; i < len; i += 4) { - data[i + 3] = threshold + 255 * (total - i) / total; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - threshold: this.threshold - }); - } - }); - fabric.Image.filters.GradientTransparency.fromObject = function(object) { - return new fabric.Image.filters.GradientTransparency(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Grayscale = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Grayscale", - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, len = imageData.width * imageData.height * 4, index = 0, average; - while (index < len) { - average = (data[index] + data[index + 1] + data[index + 2]) / 3; - data[index] = average; - data[index + 1] = average; - data[index + 2] = average; - index += 4; - } - context.putImageData(imageData, 0, 0); - } - }); - fabric.Image.filters.Grayscale.fromObject = function() { - return new fabric.Image.filters.Grayscale(); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Invert = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Invert", - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i; - for (i = 0; i < iLen; i += 4) { - data[i] = 255 - data[i]; - data[i + 1] = 255 - data[i + 1]; - data[i + 2] = 255 - data[i + 2]; - } - context.putImageData(imageData, 0, 0); - } - }); - fabric.Image.filters.Invert.fromObject = function() { - return new fabric.Image.filters.Invert(); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Mask = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Mask", - initialize: function(options) { - options = options || {}; - this.mask = options.mask; - this.channel = [ 0, 1, 2, 3 ].indexOf(options.channel) > -1 ? options.channel : 0; - }, - applyTo: function(canvasEl) { - if (!this.mask) { - return; - } - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, maskEl = this.mask.getElement(), maskCanvasEl = fabric.util.createCanvasElement(), channel = this.channel, i, iLen = imageData.width * imageData.height * 4; - maskCanvasEl.width = canvasEl.width; - maskCanvasEl.height = canvasEl.height; - maskCanvasEl.getContext("2d").drawImage(maskEl, 0, 0, canvasEl.width, canvasEl.height); - var maskImageData = maskCanvasEl.getContext("2d").getImageData(0, 0, canvasEl.width, canvasEl.height), maskData = maskImageData.data; - for (i = 0; i < iLen; i += 4) { - data[i + 3] = maskData[i + channel]; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - mask: this.mask.toObject(), - channel: this.channel - }); - } - }); - fabric.Image.filters.Mask.fromObject = function(object, callback) { - fabric.util.loadImage(object.mask.src, function(img) { - object.mask = new fabric.Image(img, object.mask); - callback && callback(new fabric.Image.filters.Mask(object)); - }); - }; - fabric.Image.filters.Mask.async = true; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Noise = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Noise", - initialize: function(options) { - options = options || {}; - this.noise = options.noise || 0; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, noise = this.noise, rand; - for (var i = 0, len = data.length; i < len; i += 4) { - rand = (.5 - Math.random()) * noise; - data[i] += rand; - data[i + 1] += rand; - data[i + 2] += rand; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - noise: this.noise - }); - } - }); - fabric.Image.filters.Noise.fromObject = function(object) { - return new fabric.Image.filters.Noise(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Pixelate = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Pixelate", - initialize: function(options) { - options = options || {}; - this.blocksize = options.blocksize || 4; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = imageData.height, jLen = imageData.width, index, i, j, r, g, b, a; - for (i = 0; i < iLen; i += this.blocksize) { - for (j = 0; j < jLen; j += this.blocksize) { - index = i * 4 * jLen + j * 4; - r = data[index]; - g = data[index + 1]; - b = data[index + 2]; - a = data[index + 3]; - for (var _i = i, _ilen = i + this.blocksize; _i < _ilen; _i++) { - for (var _j = j, _jlen = j + this.blocksize; _j < _jlen; _j++) { - index = _i * 4 * jLen + _j * 4; - data[index] = r; - data[index + 1] = g; - data[index + 2] = b; - data[index + 3] = a; - } - } - } - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - blocksize: this.blocksize - }); - } - }); - fabric.Image.filters.Pixelate.fromObject = function(object) { - return new fabric.Image.filters.Pixelate(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.RemoveWhite = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "RemoveWhite", - initialize: function(options) { - options = options || {}; - this.threshold = options.threshold || 30; - this.distance = options.distance || 20; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, threshold = this.threshold, distance = this.distance, limit = 255 - threshold, abs = Math.abs, r, g, b; - for (var i = 0, len = data.length; i < len; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - if (r > limit && g > limit && b > limit && abs(r - g) < distance && abs(r - b) < distance && abs(g - b) < distance) { - data[i + 3] = 0; - } - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - threshold: this.threshold, - distance: this.distance - }); - } - }); - fabric.Image.filters.RemoveWhite.fromObject = function(object) { - return new fabric.Image.filters.RemoveWhite(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Sepia = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Sepia", - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, avg; - for (i = 0; i < iLen; i += 4) { - avg = .3 * data[i] + .59 * data[i + 1] + .11 * data[i + 2]; - data[i] = avg + 100; - data[i + 1] = avg + 50; - data[i + 2] = avg + 255; - } - context.putImageData(imageData, 0, 0); - } - }); - fabric.Image.filters.Sepia.fromObject = function() { - return new fabric.Image.filters.Sepia(); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Sepia2 = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Sepia2", - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, r, g, b; - for (i = 0; i < iLen; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - data[i] = (r * .393 + g * .769 + b * .189) / 1.351; - data[i + 1] = (r * .349 + g * .686 + b * .168) / 1.203; - data[i + 2] = (r * .272 + g * .534 + b * .131) / 2.14; - } - context.putImageData(imageData, 0, 0); - } - }); - fabric.Image.filters.Sepia2.fromObject = function() { - return new fabric.Image.filters.Sepia2(); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Tint = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Tint", - initialize: function(options) { - options = options || {}; - this.color = options.color || "#000000"; - this.opacity = typeof options.opacity !== "undefined" ? options.opacity : new fabric.Color(this.color).getAlpha(); - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, tintR, tintG, tintB, r, g, b, alpha1, source; - source = new fabric.Color(this.color).getSource(); - tintR = source[0] * this.opacity; - tintG = source[1] * this.opacity; - tintB = source[2] * this.opacity; - alpha1 = 1 - this.opacity; - for (i = 0; i < iLen; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - data[i] = tintR + r * alpha1; - data[i + 1] = tintG + g * alpha1; - data[i + 2] = tintB + b * alpha1; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - color: this.color, - opacity: this.opacity - }); - } - }); - fabric.Image.filters.Tint.fromObject = function(object) { - return new fabric.Image.filters.Tint(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Multiply = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Multiply", - initialize: function(options) { - options = options || {}; - this.color = options.color || "#000000"; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, source; - source = new fabric.Color(this.color).getSource(); - for (i = 0; i < iLen; i += 4) { - data[i] *= source[0] / 255; - data[i + 1] *= source[1] / 255; - data[i + 2] *= source[2] / 255; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - color: this.color - }); - } - }); - fabric.Image.filters.Multiply.fromObject = function(object) { - return new fabric.Image.filters.Multiply(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric; - fabric.Image.filters.Blend = fabric.util.createClass({ - type: "Blend", - initialize: function(options) { - options = options || {}; - this.color = options.color || "#000"; - this.image = options.image || false; - this.mode = options.mode || "multiply"; - this.alpha = options.alpha || 1; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, tr, tg, tb, r, g, b, _r, _g, _b, source, isImage = false; - if (this.image) { - isImage = true; - var _el = fabric.util.createCanvasElement(); - _el.width = this.image.width; - _el.height = this.image.height; - var tmpCanvas = new fabric.StaticCanvas(_el); - tmpCanvas.add(this.image); - var context2 = tmpCanvas.getContext("2d"); - source = context2.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height).data; - } else { - source = new fabric.Color(this.color).getSource(); - tr = source[0] * this.alpha; - tg = source[1] * this.alpha; - tb = source[2] * this.alpha; - } - for (var i = 0, len = data.length; i < len; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - if (isImage) { - tr = source[i] * this.alpha; - tg = source[i + 1] * this.alpha; - tb = source[i + 2] * this.alpha; - } - switch (this.mode) { - case "multiply": - data[i] = r * tr / 255; - data[i + 1] = g * tg / 255; - data[i + 2] = b * tb / 255; - break; - - case "screen": - data[i] = 1 - (1 - r) * (1 - tr); - data[i + 1] = 1 - (1 - g) * (1 - tg); - data[i + 2] = 1 - (1 - b) * (1 - tb); - break; - - case "add": - data[i] = Math.min(255, r + tr); - data[i + 1] = Math.min(255, g + tg); - data[i + 2] = Math.min(255, b + tb); - break; - - case "diff": - case "difference": - data[i] = Math.abs(r - tr); - data[i + 1] = Math.abs(g - tg); - data[i + 2] = Math.abs(b - tb); - break; - - case "subtract": - _r = r - tr; - _g = g - tg; - _b = b - tb; - data[i] = _r < 0 ? 0 : _r; - data[i + 1] = _g < 0 ? 0 : _g; - data[i + 2] = _b < 0 ? 0 : _b; - break; - - case "darken": - data[i] = Math.min(r, tr); - data[i + 1] = Math.min(g, tg); - data[i + 2] = Math.min(b, tb); - break; - - case "lighten": - data[i] = Math.max(r, tr); - data[i + 1] = Math.max(g, tg); - data[i + 2] = Math.max(b, tb); - break; - } - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return { - color: this.color, - image: this.image, - mode: this.mode, - alpha: this.alpha - }; - } - }); - fabric.Image.filters.Blend.fromObject = function(object) { - return new fabric.Image.filters.Blend(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), pow = Math.pow, floor = Math.floor, sqrt = Math.sqrt, abs = Math.abs, max = Math.max, round = Math.round, sin = Math.sin, ceil = Math.ceil; - fabric.Image.filters.Resize = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Resize", - resizeType: "hermite", - scaleX: 0, - scaleY: 0, - lanczosLobes: 3, - applyTo: function(canvasEl, scaleX, scaleY) { - this.rcpScaleX = 1 / scaleX; - this.rcpScaleY = 1 / scaleY; - var oW = canvasEl.width, oH = canvasEl.height, dW = round(oW * scaleX), dH = round(oH * scaleY), imageData; - if (this.resizeType === "sliceHack") { - imageData = this.sliceByTwo(canvasEl, oW, oH, dW, dH); - } - if (this.resizeType === "hermite") { - imageData = this.hermiteFastResize(canvasEl, oW, oH, dW, dH); - } - if (this.resizeType === "bilinear") { - imageData = this.bilinearFiltering(canvasEl, oW, oH, dW, dH); - } - if (this.resizeType === "lanczos") { - imageData = this.lanczosResize(canvasEl, oW, oH, dW, dH); - } - canvasEl.width = dW; - canvasEl.height = dH; - canvasEl.getContext("2d").putImageData(imageData, 0, 0); - }, - sliceByTwo: function(canvasEl, width, height, newWidth, newHeight) { - var context = canvasEl.getContext("2d"), imageData, multW = .5, multH = .5, signW = 1, signH = 1, doneW = false, doneH = false, stepW = width, stepH = height, tmpCanvas = fabric.util.createCanvasElement(), tmpCtx = tmpCanvas.getContext("2d"); - newWidth = floor(newWidth); - newHeight = floor(newHeight); - tmpCanvas.width = max(newWidth, width); - tmpCanvas.height = max(newHeight, height); - if (newWidth > width) { - multW = 2; - signW = -1; - } - if (newHeight > height) { - multH = 2; - signH = -1; - } - imageData = context.getImageData(0, 0, width, height); - canvasEl.width = max(newWidth, width); - canvasEl.height = max(newHeight, height); - context.putImageData(imageData, 0, 0); - while (!doneW || !doneH) { - width = stepW; - height = stepH; - if (newWidth * signW < floor(stepW * multW * signW)) { - stepW = floor(stepW * multW); - } else { - stepW = newWidth; - doneW = true; - } - if (newHeight * signH < floor(stepH * multH * signH)) { - stepH = floor(stepH * multH); - } else { - stepH = newHeight; - doneH = true; - } - imageData = context.getImageData(0, 0, width, height); - tmpCtx.putImageData(imageData, 0, 0); - context.clearRect(0, 0, stepW, stepH); - context.drawImage(tmpCanvas, 0, 0, width, height, 0, 0, stepW, stepH); - } - return context.getImageData(0, 0, newWidth, newHeight); - }, - lanczosResize: function(canvasEl, oW, oH, dW, dH) { - function lanczosCreate(lobes) { - return function(x) { - if (x > lobes) { - return 0; - } - x *= Math.PI; - if (abs(x) < 1e-16) { - return 1; - } - var xx = x / lobes; - return sin(x) * sin(xx) / x / xx; - }; - } - function process(u) { - var v, i, weight, idx, a, red, green, blue, alpha, fX, fY; - center.x = (u + .5) * ratioX; - icenter.x = floor(center.x); - for (v = 0; v < dH; v++) { - center.y = (v + .5) * ratioY; - icenter.y = floor(center.y); - a = 0, red = 0, green = 0, blue = 0, alpha = 0; - for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { - if (i < 0 || i >= oW) { - continue; - } - fX = floor(1e3 * abs(i - center.x)); - if (!cacheLanc[fX]) { - cacheLanc[fX] = {}; - } - for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) { - if (j < 0 || j >= oH) { - continue; - } - fY = floor(1e3 * abs(j - center.y)); - if (!cacheLanc[fX][fY]) { - cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1e3); - } - weight = cacheLanc[fX][fY]; - if (weight > 0) { - idx = (j * oW + i) * 4; - a += weight; - red += weight * srcData[idx]; - green += weight * srcData[idx + 1]; - blue += weight * srcData[idx + 2]; - alpha += weight * srcData[idx + 3]; - } - } - } - idx = (v * dW + u) * 4; - destData[idx] = red / a; - destData[idx + 1] = green / a; - destData[idx + 2] = blue / a; - destData[idx + 3] = alpha / a; - } - if (++u < dW) { - return process(u); - } else { - return destImg; - } - } - var context = canvasEl.getContext("2d"), srcImg = context.getImageData(0, 0, oW, oH), destImg = context.getImageData(0, 0, dW, dH), srcData = srcImg.data, destData = destImg.data, lanczos = lanczosCreate(this.lanczosLobes), ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY, range2X = ceil(ratioX * this.lanczosLobes / 2), range2Y = ceil(ratioY * this.lanczosLobes / 2), cacheLanc = {}, center = {}, icenter = {}; - return process(0); - }, - bilinearFiltering: function(canvasEl, w, h, w2, h2) { - var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl, color, offset = 0, origPix, ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, context = canvasEl.getContext("2d"), w4 = 4 * (w - 1), img = context.getImageData(0, 0, w, h), pixels = img.data, destImage = context.getImageData(0, 0, w2, h2), destPixels = destImage.data; - for (i = 0; i < h2; i++) { - for (j = 0; j < w2; j++) { - x = floor(ratioX * j); - y = floor(ratioY * i); - xDiff = ratioX * j - x; - yDiff = ratioY * i - y; - origPix = 4 * (y * w + x); - for (chnl = 0; chnl < 4; chnl++) { - a = pixels[origPix + chnl]; - b = pixels[origPix + 4 + chnl]; - c = pixels[origPix + w4 + chnl]; - d = pixels[origPix + w4 + 4 + chnl]; - color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + c * yDiff * (1 - xDiff) + d * xDiff * yDiff; - destPixels[offset++] = color; - } - } - } - return destImage; - }, - hermiteFastResize: function(canvasEl, oW, oH, dW, dH) { - var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY, ratioWHalf = ceil(ratioW / 2), ratioHHalf = ceil(ratioH / 2), context = canvasEl.getContext("2d"), img = context.getImageData(0, 0, oW, oH), data = img.data, img2 = context.getImageData(0, 0, dW, dH), data2 = img2.data; - for (var j = 0; j < dH; j++) { - for (var i = 0; i < dW; i++) { - var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0, gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + .5) * ratioH; - for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) { - var dy = abs(centerY - (yy + .5)) / ratioHHalf, centerX = (i + .5) * ratioW, w0 = dy * dy; - for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) { - var dx = abs(centerX - (xx + .5)) / ratioWHalf, w = sqrt(w0 + dx * dx); - if (w > 1 && w < -1) { - continue; - } - weight = 2 * w * w * w - 3 * w * w + 1; - if (weight > 0) { - dx = 4 * (xx + yy * oW); - gxA += weight * data[dx + 3]; - weightsAlpha += weight; - if (data[dx + 3] < 255) { - weight = weight * data[dx + 3] / 250; - } - gxR += weight * data[dx]; - gxG += weight * data[dx + 1]; - gxB += weight * data[dx + 2]; - weights += weight; - } - } - } - data2[x2] = gxR / weights; - data2[x2 + 1] = gxG / weights; - data2[x2 + 2] = gxB / weights; - data2[x2 + 3] = gxA / weightsAlpha; - } - } - return img2; - }, - toObject: function() { - return { - type: this.type, - scaleX: this.scaleX, - scaleY: this.scaleY, - resizeType: this.resizeType, - lanczosLobes: this.lanczosLobes - }; - } - }); - fabric.Image.filters.Resize.fromObject = function(object) { - return new fabric.Image.filters.Resize(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, supportsLineDash = fabric.StaticCanvas.supports("setLineDash"), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - if (fabric.Text) { - fabric.warn("fabric.Text is already defined"); - return; - } - var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push("fontFamily", "fontWeight", "fontSize", "text", "textDecoration", "textAlign", "fontStyle", "lineHeight", "textBackgroundColor"); - fabric.Text = fabric.util.createClass(fabric.Object, { - _dimensionAffectingProps: { - fontSize: true, - fontWeight: true, - fontFamily: true, - fontStyle: true, - lineHeight: true, - stroke: true, - strokeWidth: true, - text: true, - textAlign: true - }, - _reNewline: /\r?\n/, - _reSpacesAndTabs: /[ \t\r]+/g, - type: "text", - fontSize: 40, - fontWeight: "normal", - fontFamily: "Times New Roman", - textDecoration: "", - textAlign: "left", - fontStyle: "", - lineHeight: 1.16, - textBackgroundColor: "", - stateProperties: stateProperties, - stroke: null, - shadow: null, - _fontSizeFraction: .25, - _fontSizeMult: 1.13, - initialize: function(text, options) { - options = options || {}; - this.text = text; - this.__skipDimension = true; - this.setOptions(options); - this.__skipDimension = false; - this._initDimensions(); - }, - _initDimensions: function(ctx) { - if (this.__skipDimension) { - return; - } - if (!ctx) { - ctx = fabric.util.createCanvasElement().getContext("2d"); - this._setTextStyles(ctx); - } - this._textLines = this._splitTextIntoLines(); - this._clearCache(); - this._cacheLinesWidth = this.textAlign !== "justify"; - this.width = this._getTextWidth(ctx); - this._cacheLinesWidth = true; - this.height = this._getTextHeight(ctx); - }, - toString: function() { - return "#'; - }, - _render: function(ctx) { - this.clipTo && fabric.util.clipContext(this, ctx); - this._setOpacity(ctx); - this._setShadow(ctx); - this._setupCompositeOperation(ctx); - this._renderTextBackground(ctx); - this._setStrokeStyles(ctx); - this._setFillStyles(ctx); - this._renderText(ctx); - this._renderTextDecoration(ctx); - this.clipTo && ctx.restore(); - }, - _renderText: function(ctx) { - this._translateForTextAlign(ctx); - this._renderTextFill(ctx); - this._renderTextStroke(ctx); - this._translateForTextAlign(ctx, true); - }, - _translateForTextAlign: function(ctx, back) { - if (this.textAlign !== "left" && this.textAlign !== "justify") { - var sign = back ? -1 : 1; - ctx.translate(this.textAlign === "center" ? sign * this.width / 2 : sign * this.width, 0); - } - }, - _setTextStyles: function(ctx) { - ctx.textBaseline = "alphabetic"; - if (!this.skipTextAlign) { - ctx.textAlign = this.textAlign; - } - ctx.font = this._getFontDeclaration(); - }, - _getTextHeight: function() { - return this._textLines.length * this._getHeightOfLine(); - }, - _getTextWidth: function(ctx) { - var maxWidth = this._getLineWidth(ctx, 0); - for (var i = 1, len = this._textLines.length; i < len; i++) { - var currentLineWidth = this._getLineWidth(ctx, i); - if (currentLineWidth > maxWidth) { - maxWidth = currentLineWidth; - } - } - return maxWidth; - }, - _renderChars: function(method, ctx, chars, left, top) { - var shortM = method.slice(0, -4); - if (this[shortM].toLive) { - var offsetX = -this.width / 2 + this[shortM].offsetX || 0, offsetY = -this.height / 2 + this[shortM].offsetY || 0; - ctx.save(); - ctx.translate(offsetX, offsetY); - left -= offsetX; - top -= offsetY; - } - ctx[method](chars, left, top); - this[shortM].toLive && ctx.restore(); - }, - _renderTextLine: function(method, ctx, line, left, top, lineIndex) { - top -= this.fontSize * this._fontSizeFraction; - var lineWidth = this._getLineWidth(ctx, lineIndex); - if (this.textAlign !== "justify" || this.width < lineWidth) { - this._renderChars(method, ctx, line, left, top, lineIndex); - return; - } - var words = line.split(/\s+/), charOffset = 0, wordsWidth = this._getWidthOfWords(ctx, line, lineIndex, 0), widthDiff = this.width - wordsWidth, numSpaces = words.length - 1, spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0, leftOffset = 0, word; - for (var i = 0, len = words.length; i < len; i++) { - while (line[charOffset] === " " && charOffset < line.length) { - charOffset++; - } - word = words[i]; - this._renderChars(method, ctx, word, left + leftOffset, top, lineIndex, charOffset); - leftOffset += this._getWidthOfWords(ctx, word, lineIndex, charOffset) + spaceWidth; - charOffset += word.length; - } - }, - _getWidthOfWords: function(ctx, line) { - return ctx.measureText(line.replace(/\s+/g, "")).width; - }, - _getLeftOffset: function() { - return -this.width / 2; - }, - _getTopOffset: function() { - return -this.height / 2; - }, - isEmptyStyles: function() { - return true; - }, - _renderTextFill: function(ctx) { - if (!this.fill && this.isEmptyStyles()) { - return; - } - var lineHeights = 0; - for (var i = 0, len = this._textLines.length; i < len; i++) { - var heightOfLine = this._getHeightOfLine(ctx, i), maxHeight = heightOfLine / this.lineHeight; - this._renderTextLine("fillText", ctx, this._textLines[i], this._getLeftOffset(), this._getTopOffset() + lineHeights + maxHeight, i); - lineHeights += heightOfLine; - } - }, - _renderTextStroke: function(ctx) { - if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) { - return; - } - var lineHeights = 0; - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - ctx.save(); - if (this.strokeDashArray) { - if (1 & this.strokeDashArray.length) { - this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray); - } - supportsLineDash && ctx.setLineDash(this.strokeDashArray); - } - ctx.beginPath(); - for (var i = 0, len = this._textLines.length; i < len; i++) { - var heightOfLine = this._getHeightOfLine(ctx, i), maxHeight = heightOfLine / this.lineHeight; - this._renderTextLine("strokeText", ctx, this._textLines[i], this._getLeftOffset(), this._getTopOffset() + lineHeights + maxHeight, i); - lineHeights += heightOfLine; - } - ctx.closePath(); - ctx.restore(); - }, - _getHeightOfLine: function() { - return this.fontSize * this._fontSizeMult * this.lineHeight; - }, - _renderTextBackground: function(ctx) { - this._renderTextBoxBackground(ctx); - this._renderTextLinesBackground(ctx); - }, - _renderTextBoxBackground: function(ctx) { - if (!this.backgroundColor) { - return; - } - ctx.fillStyle = this.backgroundColor; - ctx.fillRect(this._getLeftOffset(), this._getTopOffset(), this.width, this.height); - this._removeShadow(ctx); - }, - _renderTextLinesBackground: function(ctx) { - if (!this.textBackgroundColor) { - return; - } - var lineTopOffset = 0, heightOfLine, lineWidth, lineLeftOffset; - ctx.fillStyle = this.textBackgroundColor; - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this._getHeightOfLine(ctx, i); - if (this._textLines[i] !== "") { - lineWidth = this.textAlign === "justify" ? this.width : this._getLineWidth(ctx, i); - lineLeftOffset = this._getLineLeftOffset(lineWidth); - ctx.fillRect(this._getLeftOffset() + lineLeftOffset, this._getTopOffset() + lineTopOffset, lineWidth, heightOfLine / this.lineHeight); - } - lineTopOffset += heightOfLine; - } - this._removeShadow(ctx); - }, - _getLineLeftOffset: function(lineWidth) { - if (this.textAlign === "center") { - return (this.width - lineWidth) / 2; - } - if (this.textAlign === "right") { - return this.width - lineWidth; - } - return 0; - }, - _clearCache: function() { - this.__lineWidths = []; - this.__lineHeights = []; - }, - _shouldClearCache: function() { - var shouldClear = false; - if (this._forceClearCache) { - this._forceClearCache = false; - return true; - } - for (var prop in this._dimensionAffectingProps) { - if (this["__" + prop] !== this[prop]) { - this["__" + prop] = this[prop]; - shouldClear = true; - } - } - return shouldClear; - }, - _getLineWidth: function(ctx, lineIndex) { - if (this.__lineWidths[lineIndex]) { - return this.__lineWidths[lineIndex]; - } - var width, wordCount, line = this._textLines[lineIndex]; - if (line === "") { - width = 0; - } else if (this.textAlign === "justify" && this._cacheLinesWidth) { - wordCount = line.split(/\s+/); - if (wordCount.length > 1) { - width = this.width; - } else { - width = ctx.measureText(line).width; - } - } else { - width = ctx.measureText(line).width; - } - this._cacheLinesWidth && (this.__lineWidths[lineIndex] = width); - return width; - }, - _renderTextDecoration: function(ctx) { - if (!this.textDecoration) { - return; - } - var halfOfVerticalBox = this.height / 2, _this = this, offsets = []; - function renderLinesAtOffset(offsets) { - var i, lineHeight = 0, len, j, oLen, lineWidth, lineLeftOffset, heightOfLine; - for (i = 0, len = _this._textLines.length; i < len; i++) { - lineWidth = _this._getLineWidth(ctx, i), lineLeftOffset = _this._getLineLeftOffset(lineWidth), - heightOfLine = _this._getHeightOfLine(ctx, i); - for (j = 0, oLen = offsets.length; j < oLen; j++) { - ctx.fillRect(_this._getLeftOffset() + lineLeftOffset, lineHeight + (_this._fontSizeMult - 1 + offsets[j]) * _this.fontSize - halfOfVerticalBox, lineWidth, _this.fontSize / 15); - } - lineHeight += heightOfLine; - } - } - if (this.textDecoration.indexOf("underline") > -1) { - offsets.push(.85); - } - if (this.textDecoration.indexOf("line-through") > -1) { - offsets.push(.43); - } - if (this.textDecoration.indexOf("overline") > -1) { - offsets.push(-.12); - } - if (offsets.length > 0) { - renderLinesAtOffset(offsets); - } - }, - _getFontDeclaration: function() { - return [ fabric.isLikelyNode ? this.fontWeight : this.fontStyle, fabric.isLikelyNode ? this.fontStyle : this.fontWeight, this.fontSize + "px", fabric.isLikelyNode ? '"' + this.fontFamily + '"' : this.fontFamily ].join(" "); - }, - render: function(ctx, noTransform) { - if (!this.visible) { - return; - } - ctx.save(); - this._setTextStyles(ctx); - if (this._shouldClearCache()) { - this._initDimensions(ctx); - } - if (!noTransform) { - this.transform(ctx); - } - if (this.transformMatrix) { - ctx.transform.apply(ctx, this.transformMatrix); - } - if (this.group && this.group.type === "path-group") { - ctx.translate(this.left, this.top); - } - this._render(ctx); - ctx.restore(); - }, - _splitTextIntoLines: function() { - return this.text.split(this._reNewline); - }, - toObject: function(propertiesToInclude) { - var object = extend(this.callSuper("toObject", propertiesToInclude), { - text: this.text, - fontSize: this.fontSize, - fontWeight: this.fontWeight, - fontFamily: this.fontFamily, - fontStyle: this.fontStyle, - lineHeight: this.lineHeight, - textDecoration: this.textDecoration, - textAlign: this.textAlign, - textBackgroundColor: this.textBackgroundColor - }); - if (!this.includeDefaultValues) { - this._removeDefaultValues(object); - } - return object; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), offsets = this._getSVGLeftTopOffsets(this.ctx), textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft); - this._wrapSVGTextAndBg(markup, textAndBg); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - _getSVGLeftTopOffsets: function(ctx) { - var lineTop = this._getHeightOfLine(ctx, 0), textLeft = -this.width / 2, textTop = 0; - return { - textLeft: textLeft + (this.group && this.group.type === "path-group" ? this.left : 0), - textTop: textTop + (this.group && this.group.type === "path-group" ? -this.top : 0), - lineTop: lineTop - }; - }, - _wrapSVGTextAndBg: function(markup, textAndBg) { - var noShadow = true, filter = this.getSvgFilter(), style = filter === "" ? "" : ' style="' + filter + '"'; - markup.push(' \n", textAndBg.textBgRects.join(""), " \n', textAndBg.textSpans.join(""), " \n", " \n"); - }, - _getSVGTextAndBg: function(textTopOffset, textLeftOffset) { - var textSpans = [], textBgRects = [], height = 0; - this._setSVGBg(textBgRects); - for (var i = 0, len = this._textLines.length; i < len; i++) { - if (this.textBackgroundColor) { - this._setSVGTextLineBg(textBgRects, i, textLeftOffset, textTopOffset, height); - } - this._setSVGTextLineText(i, textSpans, height, textLeftOffset, textTopOffset, textBgRects); - height += this._getHeightOfLine(this.ctx, i); - } - return { - textSpans: textSpans, - textBgRects: textBgRects - }; - }, - _setSVGTextLineText: function(i, textSpans, height, textLeftOffset, textTopOffset) { - var yPos = this.fontSize * (this._fontSizeMult - this._fontSizeFraction) - textTopOffset + height - this.height / 2; - if (this.textAlign === "justify") { - this._setSVGTextLineJustifed(i, textSpans, yPos, textLeftOffset); - return; - } - textSpans.push(' ", fabric.util.string.escapeXml(this._textLines[i]), "\n"); - }, - _setSVGTextLineJustifed: function(i, textSpans, yPos, textLeftOffset) { - var ctx = fabric.util.createCanvasElement().getContext("2d"); - this._setTextStyles(ctx); - var line = this._textLines[i], words = line.split(/\s+/), wordsWidth = this._getWidthOfWords(ctx, line), widthDiff = this.width - wordsWidth, numSpaces = words.length - 1, spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0, word, attributes = this._getFillAttributes(this.fill), len; - textLeftOffset += this._getLineLeftOffset(this._getLineWidth(ctx, i)); - for (i = 0, len = words.length; i < len; i++) { - word = words[i]; - textSpans.push(' ", fabric.util.string.escapeXml(word), "\n"); - textLeftOffset += this._getWidthOfWords(ctx, word) + spaceWidth; - } - }, - _setSVGTextLineBg: function(textBgRects, i, textLeftOffset, textTopOffset, height) { - textBgRects.push(" \n'); - }, - _setSVGBg: function(textBgRects) { - if (this.backgroundColor) { - textBgRects.push(" \n'); - } - }, - _getFillAttributes: function(value) { - var fillColor = value && typeof value === "string" ? new fabric.Color(value) : ""; - if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) { - return 'fill="' + value + '"'; - } - return 'opacity="' + fillColor.getAlpha() + '" fill="' + fillColor.setAlpha(1).toRgb() + '"'; - }, - _set: function(key, value) { - this.callSuper("_set", key, value); - if (key in this._dimensionAffectingProps) { - this._initDimensions(); - this.setCoords(); - } - }, - complexity: function() { - return 1; - } - }); - fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")); - fabric.Text.DEFAULT_SVG_FONT_SIZE = 16; - fabric.Text.fromElement = function(element, options) { - if (!element) { - return null; - } - var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES); - options = fabric.util.object.extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes); - options.top = options.top || 0; - options.left = options.left || 0; - if ("dx" in parsedAttributes) { - options.left += parsedAttributes.dx; - } - if ("dy" in parsedAttributes) { - options.top += parsedAttributes.dy; - } - if (!("fontSize" in options)) { - options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; - } - if (!options.originX) { - options.originX = "left"; - } - var textContent = ""; - if (!("textContent" in element)) { - if ("firstChild" in element && element.firstChild !== null) { - if ("data" in element.firstChild && element.firstChild.data !== null) { - textContent = element.firstChild.data; - } - } - } else { - textContent = element.textContent; - } - textContent = textContent.replace(/^\s+|\s+$|\n+/g, "").replace(/\s+/g, " "); - var text = new fabric.Text(textContent, options), offX = 0; - if (text.originX === "left") { - offX = text.getWidth() / 2; - } - if (text.originX === "right") { - offX = -text.getWidth() / 2; - } - text.set({ - left: text.getLeft() + offX, - top: text.getTop() - text.getHeight() / 2 + text.fontSize * (.18 + text._fontSizeFraction) - }); - return text; - }; - fabric.Text.fromObject = function(object) { - return new fabric.Text(object.text, clone(object)); - }; - fabric.util.createAccessors(fabric.Text); -})(typeof exports !== "undefined" ? exports : this); - -(function() { - var clone = fabric.util.object.clone; - fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, { - type: "i-text", - selectionStart: 0, - selectionEnd: 0, - selectionColor: "rgba(17,119,255,0.3)", - isEditing: false, - editable: true, - editingBorderColor: "rgba(102,153,255,0.25)", - cursorWidth: 2, - cursorColor: "#333", - cursorDelay: 1e3, - cursorDuration: 600, - styles: null, - caching: true, - _reSpace: /\s|\n/, - _currentCursorOpacity: 0, - _selectionDirection: null, - _abortCursorAnimation: false, - _charWidthsCache: {}, - __widthOfSpace: [], - initialize: function(text, options) { - this.styles = options ? options.styles || {} : {}; - this.callSuper("initialize", text, options); - this.initBehavior(); - }, - _clearCache: function() { - this.callSuper("_clearCache"); - this.__widthOfSpace = []; - }, - isEmptyStyles: function() { - if (!this.styles) { - return true; - } - var obj = this.styles; - for (var p1 in obj) { - for (var p2 in obj[p1]) { - for (var p3 in obj[p1][p2]) { - return false; - } - } - } - return true; - }, - setSelectionStart: function(index) { - index = Math.max(index, 0); - if (this.selectionStart !== index) { - this.fire("selection:changed"); - this.canvas && this.canvas.fire("text:selection:changed", { - target: this - }); - this.selectionStart = index; - } - this._updateTextarea(); - }, - setSelectionEnd: function(index) { - index = Math.min(index, this.text.length); - if (this.selectionEnd !== index) { - this.fire("selection:changed"); - this.canvas && this.canvas.fire("text:selection:changed", { - target: this - }); - this.selectionEnd = index; - } - this._updateTextarea(); - }, - getSelectionStyles: function(startIndex, endIndex) { - if (arguments.length === 2) { - var styles = []; - for (var i = startIndex; i < endIndex; i++) { - styles.push(this.getSelectionStyles(i)); - } - return styles; - } - var loc = this.get2DCursorLocation(startIndex), style = this._getStyleDeclaration(loc.lineIndex, loc.charIndex); - return style || {}; - }, - setSelectionStyles: function(styles) { - if (this.selectionStart === this.selectionEnd) { - this._extendStyles(this.selectionStart, styles); - } else { - for (var i = this.selectionStart; i < this.selectionEnd; i++) { - this._extendStyles(i, styles); - } - } - this._forceClearCache = true; - return this; - }, - _extendStyles: function(index, styles) { - var loc = this.get2DCursorLocation(index); - if (!this._getLineStyle(loc.lineIndex)) { - this._setLineStyle(loc.lineIndex, {}); - } - if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) { - this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {}); - } - fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles); - }, - _render: function(ctx) { - this.callSuper("_render", ctx); - this.ctx = ctx; - this.isEditing && this.renderCursorOrSelection(); - }, - renderCursorOrSelection: function() { - if (!this.active) { - return; - } - var chars = this.text.split(""), boundaries, ctx; - if (this.canvas.contextTop) { - ctx = this.canvas.contextTop; - ctx.save(); - ctx.transform.apply(ctx, this.canvas.viewportTransform); - this.transform(ctx); - this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix); - } else { - ctx = this.ctx; - ctx.save(); - } - if (this.selectionStart === this.selectionEnd) { - boundaries = this._getCursorBoundaries(chars, "cursor"); - this.renderCursor(boundaries, ctx); - } else { - boundaries = this._getCursorBoundaries(chars, "selection"); - this.renderSelection(chars, boundaries, ctx); - } - ctx.restore(); - }, - get2DCursorLocation: function(selectionStart) { - if (typeof selectionStart === "undefined") { - selectionStart = this.selectionStart; - } - var len = this._textLines.length; - for (var i = 0; i < len; i++) { - if (selectionStart <= this._textLines[i].length) { - return { - lineIndex: i, - charIndex: selectionStart - }; - } - selectionStart -= this._textLines[i].length + 1; - } - return { - lineIndex: i - 1, - charIndex: this._textLines[i - 1].length < selectionStart ? this._textLines[i - 1].length : selectionStart - }; - }, - getCurrentCharStyle: function(lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1); - return { - fontSize: style && style.fontSize || this.fontSize, - fill: style && style.fill || this.fill, - textBackgroundColor: style && style.textBackgroundColor || this.textBackgroundColor, - textDecoration: style && style.textDecoration || this.textDecoration, - fontFamily: style && style.fontFamily || this.fontFamily, - fontWeight: style && style.fontWeight || this.fontWeight, - fontStyle: style && style.fontStyle || this.fontStyle, - stroke: style && style.stroke || this.stroke, - strokeWidth: style && style.strokeWidth || this.strokeWidth - }; - }, - getCurrentCharFontSize: function(lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1); - return style && style.fontSize ? style.fontSize : this.fontSize; - }, - getCurrentCharColor: function(lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1); - return style && style.fill ? style.fill : this.cursorColor; - }, - _getCursorBoundaries: function(chars, typeOfBoundaries) { - var left = Math.round(this._getLeftOffset()), top = this._getTopOffset(), offsets = this._getCursorBoundariesOffsets(chars, typeOfBoundaries); - return { - left: left, - top: top, - leftOffset: offsets.left + offsets.lineLeft, - topOffset: offsets.top - }; - }, - _getCursorBoundariesOffsets: function(chars, typeOfBoundaries) { - var lineLeftOffset = 0, lineIndex = 0, charIndex = 0, topOffset = 0, leftOffset = 0; - for (var i = 0; i < this.selectionStart; i++) { - if (chars[i] === "\n") { - leftOffset = 0; - topOffset += this._getHeightOfLine(this.ctx, lineIndex); - lineIndex++; - charIndex = 0; - } else { - leftOffset += this._getWidthOfChar(this.ctx, chars[i], lineIndex, charIndex); - charIndex++; - } - lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)); - } - if (typeOfBoundaries === "cursor") { - topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, lineIndex) / this.lineHeight - this.getCurrentCharFontSize(lineIndex, charIndex) * (1 - this._fontSizeFraction); - } - return { - top: topOffset, - left: leftOffset, - lineLeft: lineLeftOffset - }; - }, - renderCursor: function(boundaries, ctx) { - var cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = lineIndex === 0 && charIndex === 0 ? this._getLineLeftOffset(this._getLineWidth(ctx, lineIndex)) : boundaries.leftOffset; - ctx.fillStyle = this.getCurrentCharColor(lineIndex, charIndex); - ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity; - ctx.fillRect(boundaries.left + leftOffset, boundaries.top + boundaries.topOffset, this.cursorWidth / this.scaleX, charHeight); - }, - renderSelection: function(chars, boundaries, ctx) { - ctx.fillStyle = this.selectionColor; - var start = this.get2DCursorLocation(this.selectionStart), end = this.get2DCursorLocation(this.selectionEnd), startLine = start.lineIndex, endLine = end.lineIndex; - for (var i = startLine; i <= endLine; i++) { - var lineOffset = this._getLineLeftOffset(this._getLineWidth(ctx, i)) || 0, lineHeight = this._getHeightOfLine(this.ctx, i), boxWidth = 0, line = this._textLines[i]; - if (i === startLine) { - for (var j = 0, len = line.length; j < len; j++) { - if (j >= start.charIndex && (i !== endLine || j < end.charIndex)) { - boxWidth += this._getWidthOfChar(ctx, line[j], i, j); - } - if (j < start.charIndex) { - lineOffset += this._getWidthOfChar(ctx, line[j], i, j); - } - } - } else if (i > startLine && i < endLine) { - boxWidth += this._getLineWidth(ctx, i) || 5; - } else if (i === endLine) { - for (var j2 = 0, j2len = end.charIndex; j2 < j2len; j2++) { - boxWidth += this._getWidthOfChar(ctx, line[j2], i, j2); - } - } - ctx.fillRect(boundaries.left + lineOffset, boundaries.top + boundaries.topOffset, boxWidth, lineHeight); - boundaries.topOffset += lineHeight; - } - }, - _renderChars: function(method, ctx, line, left, top, lineIndex, charOffset) { - if (this.isEmptyStyles()) { - return this._renderCharsFast(method, ctx, line, left, top); - } - charOffset = charOffset || 0; - this.skipTextAlign = true; - left -= this.textAlign === "center" ? this.width / 2 : this.textAlign === "right" ? this.width : 0; - var lineHeight = this._getHeightOfLine(ctx, lineIndex), lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(ctx, lineIndex)), prevStyle, thisStyle, charsToRender = ""; - left += lineLeftOffset || 0; - ctx.save(); - top -= lineHeight / this.lineHeight * this._fontSizeFraction; - for (var i = charOffset, len = line.length + charOffset; i <= len; i++) { - prevStyle = prevStyle || this.getCurrentCharStyle(lineIndex, i); - thisStyle = this.getCurrentCharStyle(lineIndex, i + 1); - if (this._hasStyleChanged(prevStyle, thisStyle) || i === len) { - this._renderChar(method, ctx, lineIndex, i - 1, charsToRender, left, top, lineHeight); - charsToRender = ""; - prevStyle = thisStyle; - } - charsToRender += line[i - charOffset]; - } - ctx.restore(); - }, - _renderCharsFast: function(method, ctx, line, left, top) { - this.skipTextAlign = false; - if (method === "fillText" && this.fill) { - this.callSuper("_renderChars", method, ctx, line, left, top); - } - if (method === "strokeText" && (this.stroke && this.strokeWidth > 0 || this.skipFillStrokeCheck)) { - this.callSuper("_renderChars", method, ctx, line, left, top); - } - }, - _renderChar: function(method, ctx, lineIndex, i, _char, left, top, lineHeight) { - var charWidth, charHeight, shouldFill, shouldStroke, decl = this._getStyleDeclaration(lineIndex, i), offset, textDecoration; - if (decl) { - charHeight = this._getHeightOfChar(ctx, _char, lineIndex, i); - shouldStroke = decl.stroke; - shouldFill = decl.fill; - textDecoration = decl.textDecoration; - } else { - charHeight = this.fontSize; - } - shouldStroke = (shouldStroke || this.stroke) && method === "strokeText"; - shouldFill = (shouldFill || this.fill) && method === "fillText"; - decl && ctx.save(); - charWidth = this._applyCharStylesGetWidth(ctx, _char, lineIndex, i, decl || {}); - textDecoration = textDecoration || this.textDecoration; - if (decl && decl.textBackgroundColor) { - this._removeShadow(ctx); - } - shouldFill && ctx.fillText(_char, left, top); - shouldStroke && ctx.strokeText(_char, left, top); - if (textDecoration || textDecoration !== "") { - offset = this._fontSizeFraction * lineHeight / this.lineHeight; - this._renderCharDecoration(ctx, textDecoration, left, top, offset, charWidth, charHeight); - } - decl && ctx.restore(); - ctx.translate(charWidth, 0); - }, - _hasStyleChanged: function(prevStyle, thisStyle) { - return prevStyle.fill !== thisStyle.fill || prevStyle.fontSize !== thisStyle.fontSize || prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || prevStyle.textDecoration !== thisStyle.textDecoration || prevStyle.fontFamily !== thisStyle.fontFamily || prevStyle.fontWeight !== thisStyle.fontWeight || prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth; - }, - _renderCharDecoration: function(ctx, textDecoration, left, top, offset, charWidth, charHeight) { - if (!textDecoration) { - return; - } - var decorationWeight = charHeight / 15, positions = { - underline: top + charHeight / 10, - "line-through": top - charHeight * (this._fontSizeFraction + this._fontSizeMult - 1) + decorationWeight, - overline: top - (this._fontSizeMult - this._fontSizeFraction) * charHeight - }, decorations = [ "underline", "line-through", "overline" ], i, decoration; - for (i = 0; i < decorations.length; i++) { - decoration = decorations[i]; - if (textDecoration.indexOf(decoration) > -1) { - ctx.fillRect(left, positions[decoration], charWidth, decorationWeight); - } - } - }, - _renderTextLine: function(method, ctx, line, left, top, lineIndex) { - if (!this.isEmptyStyles()) { - top += this.fontSize * (this._fontSizeFraction + .03); - } - this.callSuper("_renderTextLine", method, ctx, line, left, top, lineIndex); - }, - _renderTextDecoration: function(ctx) { - if (this.isEmptyStyles()) { - return this.callSuper("_renderTextDecoration", ctx); - } - }, - _renderTextLinesBackground: function(ctx) { - this.callSuper("_renderTextLinesBackground", ctx); - var lineTopOffset = 0, heightOfLine, lineWidth, lineLeftOffset, leftOffset = this._getLeftOffset(), topOffset = this._getTopOffset(), line, _char, style; - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this._getHeightOfLine(ctx, i); - line = this._textLines[i]; - if (line === "" || !this.styles || !this._getLineStyle(i)) { - lineTopOffset += heightOfLine; - continue; - } - lineWidth = this._getLineWidth(ctx, i); - lineLeftOffset = this._getLineLeftOffset(lineWidth); - for (var j = 0, jlen = line.length; j < jlen; j++) { - style = this._getStyleDeclaration(i, j); - if (!style || !style.textBackgroundColor) { - continue; - } - _char = line[j]; - ctx.fillStyle = style.textBackgroundColor; - ctx.fillRect(leftOffset + lineLeftOffset + this._getWidthOfCharsAt(ctx, i, j), topOffset + lineTopOffset, this._getWidthOfChar(ctx, _char, i, j) + 1, heightOfLine / this.lineHeight); - } - lineTopOffset += heightOfLine; - } - }, - _getCacheProp: function(_char, styleDeclaration) { - return _char + styleDeclaration.fontFamily + styleDeclaration.fontSize + styleDeclaration.fontWeight + styleDeclaration.fontStyle + styleDeclaration.shadow; - }, - _applyCharStylesGetWidth: function(ctx, _char, lineIndex, charIndex, decl) { - var charDecl = this._getStyleDeclaration(lineIndex, charIndex), styleDeclaration = decl && clone(decl) || clone(charDecl), width; - this._applyFontStyles(styleDeclaration); - var cacheProp = this._getCacheProp(_char, styleDeclaration); - if (!charDecl && this._charWidthsCache[cacheProp] && this.caching) { - return this._charWidthsCache[cacheProp]; - } - if (typeof styleDeclaration.shadow === "string") { - styleDeclaration.shadow = new fabric.Shadow(styleDeclaration.shadow); - } - var fill = styleDeclaration.fill || this.fill; - ctx.fillStyle = fill.toLive ? fill.toLive(ctx, this) : fill; - if (styleDeclaration.stroke) { - ctx.strokeStyle = styleDeclaration.stroke && styleDeclaration.stroke.toLive ? styleDeclaration.stroke.toLive(ctx, this) : styleDeclaration.stroke; - } - ctx.lineWidth = styleDeclaration.strokeWidth || this.strokeWidth; - ctx.font = this._getFontDeclaration.call(styleDeclaration); - if (styleDeclaration.shadow) { - styleDeclaration.scaleX = this.scaleX; - styleDeclaration.scaleY = this.scaleY; - styleDeclaration.canvas = this.canvas; - this._setShadow.call(styleDeclaration, ctx); - } - if (!this.caching || !this._charWidthsCache[cacheProp]) { - width = ctx.measureText(_char).width; - this.caching && (this._charWidthsCache[cacheProp] = width); - } - return this._charWidthsCache[cacheProp]; - }, - _applyFontStyles: function(styleDeclaration) { - if (!styleDeclaration.fontFamily) { - styleDeclaration.fontFamily = this.fontFamily; - } - if (!styleDeclaration.fontSize) { - styleDeclaration.fontSize = this.fontSize; - } - if (!styleDeclaration.fontWeight) { - styleDeclaration.fontWeight = this.fontWeight; - } - if (!styleDeclaration.fontStyle) { - styleDeclaration.fontStyle = this.fontStyle; - } - }, - _getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) { - if (returnCloneOrEmpty) { - return this.styles[lineIndex] && this.styles[lineIndex][charIndex] ? clone(this.styles[lineIndex][charIndex]) : {}; - } - return this.styles[lineIndex] && this.styles[lineIndex][charIndex] ? this.styles[lineIndex][charIndex] : null; - }, - _setStyleDeclaration: function(lineIndex, charIndex, style) { - this.styles[lineIndex][charIndex] = style; - }, - _deleteStyleDeclaration: function(lineIndex, charIndex) { - delete this.styles[lineIndex][charIndex]; - }, - _getLineStyle: function(lineIndex) { - return this.styles[lineIndex]; - }, - _setLineStyle: function(lineIndex, style) { - this.styles[lineIndex] = style; - }, - _deleteLineStyle: function(lineIndex) { - delete this.styles[lineIndex]; - }, - _getWidthOfChar: function(ctx, _char, lineIndex, charIndex) { - if (this.textAlign === "justify" && this._reSpacesAndTabs.test(_char)) { - return this._getWidthOfSpace(ctx, lineIndex); - } - var styleDeclaration = this._getStyleDeclaration(lineIndex, charIndex, true); - this._applyFontStyles(styleDeclaration); - var cacheProp = this._getCacheProp(_char, styleDeclaration); - if (this._charWidthsCache[cacheProp] && this.caching) { - return this._charWidthsCache[cacheProp]; - } else if (ctx) { - ctx.save(); - var width = this._applyCharStylesGetWidth(ctx, _char, lineIndex, charIndex); - ctx.restore(); - return width; - } - }, - _getHeightOfChar: function(ctx, lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex); - return style && style.fontSize ? style.fontSize : this.fontSize; - }, - _getWidthOfCharsAt: function(ctx, lineIndex, charIndex) { - var width = 0, i, _char; - for (i = 0; i < charIndex; i++) { - _char = this._textLines[lineIndex][i]; - width += this._getWidthOfChar(ctx, _char, lineIndex, i); - } - return width; - }, - _getLineWidth: function(ctx, lineIndex) { - if (this.__lineWidths[lineIndex]) { - return this.__lineWidths[lineIndex]; - } - this.__lineWidths[lineIndex] = this._getWidthOfCharsAt(ctx, lineIndex, this._textLines[lineIndex].length); - return this.__lineWidths[lineIndex]; - }, - _getWidthOfSpace: function(ctx, lineIndex) { - if (this.__widthOfSpace[lineIndex]) { - return this.__widthOfSpace[lineIndex]; - } - var line = this._textLines[lineIndex], wordsWidth = this._getWidthOfWords(ctx, line, lineIndex, 0), widthDiff = this.width - wordsWidth, numSpaces = line.length - line.replace(this._reSpacesAndTabs, "").length, width = widthDiff / numSpaces; - this.__widthOfSpace[lineIndex] = width; - return width; - }, - _getWidthOfWords: function(ctx, line, lineIndex, charOffset) { - var width = 0; - for (var charIndex = 0; charIndex < line.length; charIndex++) { - var _char = line[charIndex]; - if (!_char.match(/\s/)) { - width += this._getWidthOfChar(ctx, _char, lineIndex, charIndex + charOffset); - } - } - return width; - }, - _getHeightOfLine: function(ctx, lineIndex) { - if (this.__lineHeights[lineIndex]) { - return this.__lineHeights[lineIndex]; - } - var line = this._textLines[lineIndex], maxHeight = this._getHeightOfChar(ctx, lineIndex, 0); - for (var i = 1, len = line.length; i < len; i++) { - var currentCharHeight = this._getHeightOfChar(ctx, lineIndex, i); - if (currentCharHeight > maxHeight) { - maxHeight = currentCharHeight; - } - } - this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult; - return this.__lineHeights[lineIndex]; - }, - _getTextHeight: function(ctx) { - var height = 0; - for (var i = 0, len = this._textLines.length; i < len; i++) { - height += this._getHeightOfLine(ctx, i); - } - return height; - }, - toObject: function(propertiesToInclude) { - var clonedStyles = {}, i, j, row; - for (i in this.styles) { - row = this.styles[i]; - clonedStyles[i] = {}; - for (j in row) { - clonedStyles[i][j] = clone(row[j]); - } - } - return fabric.util.object.extend(this.callSuper("toObject", propertiesToInclude), { - styles: clonedStyles - }); - } - }); - fabric.IText.fromObject = function(object) { - return new fabric.IText(object.text, clone(object)); - }; -})(); - -(function() { - var clone = fabric.util.object.clone; - fabric.util.object.extend(fabric.IText.prototype, { - initBehavior: function() { - this.initAddedHandler(); - this.initRemovedHandler(); - this.initCursorSelectionHandlers(); - this.initDoubleClickSimulation(); - }, - initSelectedHandler: function() { - this.on("selected", function() { - var _this = this; - setTimeout(function() { - _this.selected = true; - }, 100); - }); - }, - initAddedHandler: function() { - var _this = this; - this.on("added", function() { - if (this.canvas && !this.canvas._hasITextHandlers) { - this.canvas._hasITextHandlers = true; - this._initCanvasHandlers(); - } - if (_this.canvas) { - _this.canvas._iTextInstances = _this.canvas._iTextInstances || []; - _this.canvas._iTextInstances.push(_this); - } - }); - }, - initRemovedHandler: function() { - var _this = this; - this.on("removed", function() { - if (_this.canvas) { - _this.canvas._iTextInstances = _this.canvas._iTextInstances || []; - fabric.util.removeFromArray(_this.canvas._iTextInstances, _this); - } - }); - }, - _initCanvasHandlers: function() { - var _this = this; - this.canvas.on("selection:cleared", function() { - fabric.IText.prototype.exitEditingOnOthers(_this.canvas); - }); - this.canvas.on("mouse:up", function() { - if (_this.canvas._iTextInstances) { - _this.canvas._iTextInstances.forEach(function(obj) { - obj.__isMousedown = false; - }); - } - }); - this.canvas.on("object:selected", function() { - fabric.IText.prototype.exitEditingOnOthers(_this.canvas); - }); - }, - _tick: function() { - this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, "_onTickComplete"); - }, - _animateCursor: function(obj, targetOpacity, duration, completeMethod) { - var tickState; - tickState = { - isAborted: false, - abort: function() { - this.isAborted = true; - } - }; - obj.animate("_currentCursorOpacity", targetOpacity, { - duration: duration, - onComplete: function() { - if (!tickState.isAborted) { - obj[completeMethod](); - } - }, - onChange: function() { - if (obj.canvas) { - obj.canvas.clearContext(obj.canvas.contextTop || obj.ctx); - obj.renderCursorOrSelection(); - } - }, - abort: function() { - return tickState.isAborted; - } - }); - return tickState; - }, - _onTickComplete: function() { - var _this = this; - if (this._cursorTimeout1) { - clearTimeout(this._cursorTimeout1); - } - this._cursorTimeout1 = setTimeout(function() { - _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, "_tick"); - }, 100); - }, - initDelayedCursor: function(restart) { - var _this = this, delay = restart ? 0 : this.cursorDelay; - this._currentTickState && this._currentTickState.abort(); - this._currentTickCompleteState && this._currentTickCompleteState.abort(); - clearTimeout(this._cursorTimeout1); - this._currentCursorOpacity = 1; - if (this.canvas) { - this.canvas.clearContext(this.canvas.contextTop || this.ctx); - this.renderCursorOrSelection(); - } - if (this._cursorTimeout2) { - clearTimeout(this._cursorTimeout2); - } - this._cursorTimeout2 = setTimeout(function() { - _this._tick(); - }, delay); - }, - abortCursorAnimation: function() { - this._currentTickState && this._currentTickState.abort(); - this._currentTickCompleteState && this._currentTickCompleteState.abort(); - clearTimeout(this._cursorTimeout1); - clearTimeout(this._cursorTimeout2); - this._currentCursorOpacity = 0; - this.canvas && this.canvas.clearContext(this.canvas.contextTop || this.ctx); - }, - selectAll: function() { - this.setSelectionStart(0); - this.setSelectionEnd(this.text.length); - }, - getSelectedText: function() { - return this.text.slice(this.selectionStart, this.selectionEnd); - }, - findWordBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - if (this._reSpace.test(this.text.charAt(index))) { - while (this._reSpace.test(this.text.charAt(index))) { - offset++; - index--; - } - } - while (/\S/.test(this.text.charAt(index)) && index > -1) { - offset++; - index--; - } - return startFrom - offset; - }, - findWordBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - if (this._reSpace.test(this.text.charAt(index))) { - while (this._reSpace.test(this.text.charAt(index))) { - offset++; - index++; - } - } - while (/\S/.test(this.text.charAt(index)) && index < this.text.length) { - offset++; - index++; - } - return startFrom + offset; - }, - findLineBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - while (!/\n/.test(this.text.charAt(index)) && index > -1) { - offset++; - index--; - } - return startFrom - offset; - }, - findLineBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - while (!/\n/.test(this.text.charAt(index)) && index < this.text.length) { - offset++; - index++; - } - return startFrom + offset; - }, - getNumNewLinesInSelectedText: function() { - var selectedText = this.getSelectedText(), numNewLines = 0; - for (var i = 0, len = selectedText.length; i < len; i++) { - if (selectedText[i] === "\n") { - numNewLines++; - } - } - return numNewLines; - }, - searchWordBoundary: function(selectionStart, direction) { - var index = this._reSpace.test(this.text.charAt(selectionStart)) ? selectionStart - 1 : selectionStart, _char = this.text.charAt(index), reNonWord = /[ \n\.,;!\?\-]/; - while (!reNonWord.test(_char) && index > 0 && index < this.text.length) { - index += direction; - _char = this.text.charAt(index); - } - if (reNonWord.test(_char) && _char !== "\n") { - index += direction === 1 ? 0 : 1; - } - return index; - }, - selectWord: function(selectionStart) { - var newSelectionStart = this.searchWordBoundary(selectionStart, -1), newSelectionEnd = this.searchWordBoundary(selectionStart, 1); - this.setSelectionStart(newSelectionStart); - this.setSelectionEnd(newSelectionEnd); - }, - selectLine: function(selectionStart) { - var newSelectionStart = this.findLineBoundaryLeft(selectionStart), newSelectionEnd = this.findLineBoundaryRight(selectionStart); - this.setSelectionStart(newSelectionStart); - this.setSelectionEnd(newSelectionEnd); - }, - enterEditing: function(e) { - if (this.isEditing || !this.editable) { - return; - } - if (this.canvas) { - this.exitEditingOnOthers(this.canvas); - } - this.isEditing = true; - this.initHiddenTextarea(e); - this.hiddenTextarea.focus(); - this._updateTextarea(); - this._saveEditingProps(); - this._setEditingProps(); - this._tick(); - this.fire("editing:entered"); - if (!this.canvas) { - return this; - } - this.canvas.renderAll(); - this.canvas.fire("text:editing:entered", { - target: this - }); - this.initMouseMoveHandler(); - return this; - }, - exitEditingOnOthers: function(canvas) { - if (canvas._iTextInstances) { - canvas._iTextInstances.forEach(function(obj) { - obj.selected = false; - if (obj.isEditing) { - obj.exitEditing(); - } - }); - } - }, - initMouseMoveHandler: function() { - var _this = this; - this.canvas.on("mouse:move", function(options) { - if (!_this.__isMousedown || !_this.isEditing) { - return; - } - var newSelectionStart = _this.getSelectionStartFromPointer(options.e); - if (newSelectionStart >= _this.__selectionStartOnMouseDown) { - _this.setSelectionStart(_this.__selectionStartOnMouseDown); - _this.setSelectionEnd(newSelectionStart); - } else { - _this.setSelectionStart(newSelectionStart); - _this.setSelectionEnd(_this.__selectionStartOnMouseDown); - } - }); - }, - _setEditingProps: function() { - this.hoverCursor = "text"; - if (this.canvas) { - this.canvas.defaultCursor = this.canvas.moveCursor = "text"; - } - this.borderColor = this.editingBorderColor; - this.hasControls = this.selectable = false; - this.lockMovementX = this.lockMovementY = true; - }, - _updateTextarea: function() { - if (!this.hiddenTextarea || this.inCompositionMode) { - return; - } - this.hiddenTextarea.value = this.text; - this.hiddenTextarea.selectionStart = this.selectionStart; - this.hiddenTextarea.selectionEnd = this.selectionEnd; - if (this.selectionStart === this.selectionEnd) { - var p = this._calcTextareaPosition(); - this.hiddenTextarea.style.left = p.x + "px"; - this.hiddenTextarea.style.top = p.y + "px"; - } - }, - _calcTextareaPosition: function() { - var chars = this.text.split(""), boundaries = this._getCursorBoundaries(chars, "cursor"), cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = lineIndex === 0 && charIndex === 0 ? this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) : boundaries.leftOffset, m = this.calcTransformMatrix(), p = { - x: boundaries.left + leftOffset, - y: boundaries.top + boundaries.topOffset + charHeight - }; - this.hiddenTextarea.style.fontSize = charHeight + "px"; - return fabric.util.transformPoint(p, m); - }, - _saveEditingProps: function() { - this._savedProps = { - hasControls: this.hasControls, - borderColor: this.borderColor, - lockMovementX: this.lockMovementX, - lockMovementY: this.lockMovementY, - hoverCursor: this.hoverCursor, - defaultCursor: this.canvas && this.canvas.defaultCursor, - moveCursor: this.canvas && this.canvas.moveCursor - }; - }, - _restoreEditingProps: function() { - if (!this._savedProps) { - return; - } - this.hoverCursor = this._savedProps.overCursor; - this.hasControls = this._savedProps.hasControls; - this.borderColor = this._savedProps.borderColor; - this.lockMovementX = this._savedProps.lockMovementX; - this.lockMovementY = this._savedProps.lockMovementY; - if (this.canvas) { - this.canvas.defaultCursor = this._savedProps.defaultCursor; - this.canvas.moveCursor = this._savedProps.moveCursor; - } - }, - exitEditing: function() { - this.selected = false; - this.isEditing = false; - this.selectable = true; - this.selectionEnd = this.selectionStart; - this.hiddenTextarea && this.canvas && this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea); - this.hiddenTextarea = null; - this.abortCursorAnimation(); - this._restoreEditingProps(); - this._currentCursorOpacity = 0; - this.fire("editing:exited"); - this.canvas && this.canvas.fire("text:editing:exited", { - target: this - }); - return this; - }, - _removeExtraneousStyles: function() { - for (var prop in this.styles) { - if (!this._textLines[prop]) { - delete this.styles[prop]; - } - } - }, - _removeCharsFromTo: function(start, end) { - while (end !== start) { - this._removeSingleCharAndStyle(start + 1); - end--; - } - this.setSelectionStart(start); - }, - _removeSingleCharAndStyle: function(index) { - var isBeginningOfLine = this.text[index - 1] === "\n", indexStyle = isBeginningOfLine ? index : index - 1; - this.removeStyleObject(isBeginningOfLine, indexStyle); - this.text = this.text.slice(0, index - 1) + this.text.slice(index); - this._textLines = this._splitTextIntoLines(); - }, - insertChars: function(_chars, useCopiedStyle) { - var style; - if (this.selectionEnd - this.selectionStart > 1) { - this._removeCharsFromTo(this.selectionStart, this.selectionEnd); - this.setSelectionEnd(this.selectionStart); - } - if (!useCopiedStyle && this.isEmptyStyles()) { - this.insertChar(_chars, false); - return; - } - for (var i = 0, len = _chars.length; i < len; i++) { - if (useCopiedStyle) { - style = fabric.copiedTextStyle[i]; - } - this.insertChar(_chars[i], i < len - 1, style); - } - }, - insertChar: function(_char, skipUpdate, styleObject) { - var isEndOfLine = this.text[this.selectionStart] === "\n"; - this.text = this.text.slice(0, this.selectionStart) + _char + this.text.slice(this.selectionEnd); - this._textLines = this._splitTextIntoLines(); - this.insertStyleObjects(_char, isEndOfLine, styleObject); - this.selectionStart += _char.length; - this.selectionEnd = this.selectionStart; - if (skipUpdate) { - return; - } - this._updateTextarea(); - this.canvas && this.canvas.renderAll(); - this.setCoords(); - this.fire("changed"); - this.canvas && this.canvas.fire("text:changed", { - target: this - }); - }, - insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) { - this.shiftLineStyles(lineIndex, +1); - if (!this.styles[lineIndex + 1]) { - this.styles[lineIndex + 1] = {}; - } - var currentCharStyle = {}, newLineStyles = {}; - if (this.styles[lineIndex] && this.styles[lineIndex][charIndex - 1]) { - currentCharStyle = this.styles[lineIndex][charIndex - 1]; - } - if (isEndOfLine) { - newLineStyles[0] = clone(currentCharStyle); - this.styles[lineIndex + 1] = newLineStyles; - } else { - for (var index in this.styles[lineIndex]) { - if (parseInt(index, 10) >= charIndex) { - newLineStyles[parseInt(index, 10) - charIndex] = this.styles[lineIndex][index]; - delete this.styles[lineIndex][index]; - } - } - this.styles[lineIndex + 1] = newLineStyles; - } - this._forceClearCache = true; - }, - insertCharStyleObject: function(lineIndex, charIndex, style) { - var currentLineStyles = this.styles[lineIndex], currentLineStylesCloned = clone(currentLineStyles); - if (charIndex === 0 && !style) { - charIndex = 1; - } - for (var index in currentLineStylesCloned) { - var numericIndex = parseInt(index, 10); - if (numericIndex >= charIndex) { - currentLineStyles[numericIndex + 1] = currentLineStylesCloned[numericIndex]; - if (!currentLineStylesCloned[numericIndex - 1]) { - delete currentLineStyles[numericIndex]; - } - } - } - this.styles[lineIndex][charIndex] = style || clone(currentLineStyles[charIndex - 1]); - this._forceClearCache = true; - }, - insertStyleObjects: function(_chars, isEndOfLine, styleObject) { - var cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex; - if (!this._getLineStyle(lineIndex)) { - this._setLineStyle(lineIndex, {}); - } - if (_chars === "\n") { - this.insertNewlineStyleObject(lineIndex, charIndex, isEndOfLine); - } else { - this.insertCharStyleObject(lineIndex, charIndex, styleObject); - } - }, - shiftLineStyles: function(lineIndex, offset) { - var clonedStyles = clone(this.styles); - for (var line in this.styles) { - var numericLine = parseInt(line, 10); - if (numericLine > lineIndex) { - this.styles[numericLine + offset] = clonedStyles[numericLine]; - if (!clonedStyles[numericLine - offset]) { - delete this.styles[numericLine]; - } - } - } - }, - removeStyleObject: function(isBeginningOfLine, index) { - var cursorLocation = this.get2DCursorLocation(index), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex; - this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex); - }, - _getTextOnPreviousLine: function(lIndex) { - return this._textLines[lIndex - 1]; - }, - _removeStyleObject: function(isBeginningOfLine, cursorLocation, lineIndex, charIndex) { - if (isBeginningOfLine) { - var textOnPreviousLine = this._getTextOnPreviousLine(cursorLocation.lineIndex), newCharIndexOnPrevLine = textOnPreviousLine ? textOnPreviousLine.length : 0; - if (!this.styles[lineIndex - 1]) { - this.styles[lineIndex - 1] = {}; - } - for (charIndex in this.styles[lineIndex]) { - this.styles[lineIndex - 1][parseInt(charIndex, 10) + newCharIndexOnPrevLine] = this.styles[lineIndex][charIndex]; - } - this.shiftLineStyles(cursorLocation.lineIndex, -1); - } else { - var currentLineStyles = this.styles[lineIndex]; - if (currentLineStyles) { - delete currentLineStyles[charIndex]; - } - var currentLineStylesCloned = clone(currentLineStyles); - for (var i in currentLineStylesCloned) { - var numericIndex = parseInt(i, 10); - if (numericIndex >= charIndex && numericIndex !== 0) { - currentLineStyles[numericIndex - 1] = currentLineStylesCloned[numericIndex]; - delete currentLineStyles[numericIndex]; - } - } - } - }, - insertNewline: function() { - this.insertChars("\n"); - } - }); -})(); - -fabric.util.object.extend(fabric.IText.prototype, { - initDoubleClickSimulation: function() { - this.__lastClickTime = +new Date(); - this.__lastLastClickTime = +new Date(); - this.__lastPointer = {}; - this.on("mousedown", this.onMouseDown.bind(this)); - }, - onMouseDown: function(options) { - this.__newClickTime = +new Date(); - var newPointer = this.canvas.getPointer(options.e); - if (this.isTripleClick(newPointer)) { - this.fire("tripleclick", options); - this._stopEvent(options.e); - } else if (this.isDoubleClick(newPointer)) { - this.fire("dblclick", options); - this._stopEvent(options.e); - } - this.__lastLastClickTime = this.__lastClickTime; - this.__lastClickTime = this.__newClickTime; - this.__lastPointer = newPointer; - this.__lastIsEditing = this.isEditing; - this.__lastSelected = this.selected; - }, - isDoubleClick: function(newPointer) { - return this.__newClickTime - this.__lastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y && this.__lastIsEditing; - }, - isTripleClick: function(newPointer) { - return this.__newClickTime - this.__lastClickTime < 500 && this.__lastClickTime - this.__lastLastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y; - }, - _stopEvent: function(e) { - e.preventDefault && e.preventDefault(); - e.stopPropagation && e.stopPropagation(); - }, - initCursorSelectionHandlers: function() { - this.initSelectedHandler(); - this.initMousedownHandler(); - this.initMouseupHandler(); - this.initClicks(); - }, - initClicks: function() { - this.on("dblclick", function(options) { - this.selectWord(this.getSelectionStartFromPointer(options.e)); - }); - this.on("tripleclick", function(options) { - this.selectLine(this.getSelectionStartFromPointer(options.e)); - }); - }, - initMousedownHandler: function() { - this.on("mousedown", function(options) { - if (!this.editable) { - return; - } - var pointer = this.canvas.getPointer(options.e); - this.__mousedownX = pointer.x; - this.__mousedownY = pointer.y; - this.__isMousedown = true; - if (this.hiddenTextarea && this.canvas) { - this.canvas.wrapperEl.appendChild(this.hiddenTextarea); - } - if (this.selected) { - this.setCursorByClick(options.e); - } - if (this.isEditing) { - this.__selectionStartOnMouseDown = this.selectionStart; - this.initDelayedCursor(true); - } - }); - }, - _isObjectMoved: function(e) { - var pointer = this.canvas.getPointer(e); - return this.__mousedownX !== pointer.x || this.__mousedownY !== pointer.y; - }, - initMouseupHandler: function() { - this.on("mouseup", function(options) { - this.__isMousedown = false; - if (!this.editable || this._isObjectMoved(options.e)) { - return; - } - if (this.__lastSelected && !this.__corner) { - this.enterEditing(options.e); - this.initDelayedCursor(true); - } - this.selected = true; - }); - }, - setCursorByClick: function(e) { - var newSelectionStart = this.getSelectionStartFromPointer(e); - if (e.shiftKey) { - if (newSelectionStart < this.selectionStart) { - this.setSelectionEnd(this.selectionStart); - this.setSelectionStart(newSelectionStart); - } else { - this.setSelectionEnd(newSelectionStart); - } - } else { - this.setSelectionStart(newSelectionStart); - this.setSelectionEnd(newSelectionStart); - } - }, - getSelectionStartFromPointer: function(e) { - var mouseOffset = this.getLocalPointer(e), prevWidth = 0, width = 0, height = 0, charIndex = 0, newSelectionStart, line; - for (var i = 0, len = this._textLines.length; i < len; i++) { - line = this._textLines[i]; - height += this._getHeightOfLine(this.ctx, i) * this.scaleY; - var widthOfLine = this._getLineWidth(this.ctx, i), lineLeftOffset = this._getLineLeftOffset(widthOfLine); - width = lineLeftOffset * this.scaleX; - for (var j = 0, jlen = line.length; j < jlen; j++) { - prevWidth = width; - width += this._getWidthOfChar(this.ctx, line[j], i, this.flipX ? jlen - j : j) * this.scaleX; - if (height <= mouseOffset.y || width <= mouseOffset.x) { - charIndex++; - continue; - } - return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex + i, jlen); - } - if (mouseOffset.y < height) { - return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex + i - 1, jlen); - } - } - if (typeof newSelectionStart === "undefined") { - return this.text.length; - } - }, - _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) { - var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth, distanceBtwNextCharAndCursor = width - mouseOffset.x, offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ? 0 : 1, newSelectionStart = index + offset; - if (this.flipX) { - newSelectionStart = jlen - newSelectionStart; - } - if (newSelectionStart > this.text.length) { - newSelectionStart = this.text.length; - } - return newSelectionStart; - } -}); - -fabric.util.object.extend(fabric.IText.prototype, { - initHiddenTextarea: function(e) { - var p; - if (e && this.canvas) { - p = this.canvas.getPointer(e); - } else { - this.oCoords || this.setCoords(); - p = this.oCoords.tl; - } - this.hiddenTextarea = fabric.document.createElement("textarea"); - this.hiddenTextarea.setAttribute("autocapitalize", "off"); - this.hiddenTextarea.style.cssText = "position: absolute; top: " + p.y + "px; left: " + p.x + "px; opacity: 0;" + " width: 0px; height: 0px; z-index: -999;"; - if (this.canvas) { - this.canvas.lowerCanvasEl.parentNode.appendChild(this.hiddenTextarea); - } else { - fabric.document.body.appendChild(this.hiddenTextarea); - } - fabric.util.addListener(this.hiddenTextarea, "keydown", this.onKeyDown.bind(this)); - fabric.util.addListener(this.hiddenTextarea, "keyup", this.onKeyUp.bind(this)); - fabric.util.addListener(this.hiddenTextarea, "input", this.onInput.bind(this)); - fabric.util.addListener(this.hiddenTextarea, "copy", this.copy.bind(this)); - fabric.util.addListener(this.hiddenTextarea, "cut", this.cut.bind(this)); - fabric.util.addListener(this.hiddenTextarea, "paste", this.paste.bind(this)); - fabric.util.addListener(this.hiddenTextarea, "compositionstart", this.onCompositionStart.bind(this)); - fabric.util.addListener(this.hiddenTextarea, "compositionupdate", this.onCompositionUpdate.bind(this)); - fabric.util.addListener(this.hiddenTextarea, "compositionend", this.onCompositionEnd.bind(this)); - if (!this._clickHandlerInitialized && this.canvas) { - fabric.util.addListener(this.canvas.upperCanvasEl, "click", this.onClick.bind(this)); - this._clickHandlerInitialized = true; - } - }, - _keysMap: { - 8: "removeChars", - 9: "exitEditing", - 27: "exitEditing", - 13: "insertNewline", - 33: "moveCursorUp", - 34: "moveCursorDown", - 35: "moveCursorRight", - 36: "moveCursorLeft", - 37: "moveCursorLeft", - 38: "moveCursorUp", - 39: "moveCursorRight", - 40: "moveCursorDown", - 46: "forwardDelete" - }, - _ctrlKeysMap: { - 65: "selectAll", - 67: "copy", - 88: "cut" - }, - onClick: function() { - this.hiddenTextarea && this.hiddenTextarea.focus(); - }, - onKeyDown: function(e) { - if (!this.isEditing) { - return; - } - if (e.keyCode in this._keysMap) { - this[this._keysMap[e.keyCode]](e); - } else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - this.canvas && this.canvas.renderAll(); - }, - onKeyUp: function(e) { - if (!this.isEditing || this._copyDone) { - this._copyDone = false; - return; - } - if (e.keyCode in this._ctrlKeysMap && (e.ctrlKey || e.metaKey)) { - this[this._ctrlKeysMap[e.keyCode]](e); - } else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - this.canvas && this.canvas.renderAll(); - }, - onInput: function(e) { - if (!this.isEditing || this.inCompositionMode) { - return; - } - var offset = this.selectionStart || 0, offsetEnd = this.selectionEnd || 0, textLength = this.text.length, newTextLength = this.hiddenTextarea.value.length, diff, charsToInsert, start; - if (newTextLength > textLength) { - start = this._selectionDirection === "left" ? offsetEnd : offset; - diff = newTextLength - textLength; - charsToInsert = this.hiddenTextarea.value.slice(start, start + diff); - } else { - diff = newTextLength - textLength + offsetEnd - offset; - charsToInsert = this.hiddenTextarea.value.slice(offset, offset + diff); - } - this.insertChars(charsToInsert); - e.stopPropagation(); - }, - onCompositionStart: function() { - this.inCompositionMode = true; - this.prevCompositionLength = 0; - this.compositionStart = this.selectionStart; - }, - onCompositionEnd: function() { - this.inCompositionMode = false; - }, - onCompositionUpdate: function(e) { - var data = e.data; - this.selectionStart = this.compositionStart; - this.selectionEnd = this.selectionEnd === this.selectionStart ? this.compositionStart + this.prevCompositionLength : this.selectionEnd; - this.insertChars(data, false); - this.prevCompositionLength = data.length; - }, - forwardDelete: function(e) { - if (this.selectionStart === this.selectionEnd) { - if (this.selectionStart === this.text.length) { - return; - } - this.moveCursorRight(e); - } - this.removeChars(e); - }, - copy: function(e) { - if (this.selectionStart === this.selectionEnd) { - return; - } - var selectedText = this.getSelectedText(), clipboardData = this._getClipboardData(e); - if (clipboardData) { - clipboardData.setData("text", selectedText); - } - fabric.copiedText = selectedText; - fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd); - e.stopImmediatePropagation(); - e.preventDefault(); - this._copyDone = true; - }, - paste: function(e) { - var copiedText = null, clipboardData = this._getClipboardData(e), useCopiedStyle = true; - if (clipboardData) { - copiedText = clipboardData.getData("text").replace(/\r/g, ""); - if (!fabric.copiedTextStyle || fabric.copiedText !== copiedText) { - useCopiedStyle = false; - } - } else { - copiedText = fabric.copiedText; - } - if (copiedText) { - this.insertChars(copiedText, useCopiedStyle); - } - e.stopImmediatePropagation(); - e.preventDefault(); - }, - cut: function(e) { - if (this.selectionStart === this.selectionEnd) { - return; - } - this.copy(e); - this.removeChars(e); - }, - _getClipboardData: function(e) { - return e && e.clipboardData || fabric.window.clipboardData; - }, - getDownCursorOffset: function(e, isRight) { - var selectionProp = isRight ? this.selectionEnd : this.selectionStart, cursorLocation = this.get2DCursorLocation(selectionProp), _char, lineLeftOffset, lineIndex = cursorLocation.lineIndex, textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex), textOnSameLineAfterCursor = this._textLines[lineIndex].slice(cursorLocation.charIndex), textOnNextLine = this._textLines[lineIndex + 1] || ""; - if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { - return this.text.length - selectionProp; - } - var widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, lineIndex); - lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor); - var widthOfCharsOnSameLineBeforeCursor = lineLeftOffset; - for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { - _char = textOnSameLineBeforeCursor[i]; - widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); - } - var indexOnNextLine = this._getIndexOnNextLine(cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor); - return textOnSameLineAfterCursor.length + 1 + indexOnNextLine; - }, - _getIndexOnNextLine: function(cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor) { - var lineIndex = cursorLocation.lineIndex + 1, widthOfNextLine = this._getLineWidth(this.ctx, lineIndex), lineLeftOffset = this._getLineLeftOffset(widthOfNextLine), widthOfCharsOnNextLine = lineLeftOffset, indexOnNextLine = 0, foundMatch; - for (var j = 0, jlen = textOnNextLine.length; j < jlen; j++) { - var _char = textOnNextLine[j], widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); - widthOfCharsOnNextLine += widthOfChar; - if (widthOfCharsOnNextLine > widthOfCharsOnSameLineBeforeCursor) { - foundMatch = true; - var leftEdge = widthOfCharsOnNextLine - widthOfChar, rightEdge = widthOfCharsOnNextLine, offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); - indexOnNextLine = offsetFromRightEdge < offsetFromLeftEdge ? j + 1 : j; - break; - } - } - if (!foundMatch) { - indexOnNextLine = textOnNextLine.length; - } - return indexOnNextLine; - }, - moveCursorDown: function(e) { - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - var offset = this.getDownCursorOffset(e, this._selectionDirection === "right"); - if (e.shiftKey) { - this.moveCursorDownWithShift(offset); - } else { - this.moveCursorDownWithoutShift(offset); - } - this.initDelayedCursor(); - }, - moveCursorDownWithoutShift: function(offset) { - this._selectionDirection = "right"; - this.setSelectionStart(this.selectionStart + offset); - this.setSelectionEnd(this.selectionStart); - }, - swapSelectionPoints: function() { - var swapSel = this.selectionEnd; - this.setSelectionEnd(this.selectionStart); - this.setSelectionStart(swapSel); - }, - moveCursorDownWithShift: function(offset) { - if (this.selectionEnd === this.selectionStart) { - this._selectionDirection = "right"; - } - if (this._selectionDirection === "right") { - this.setSelectionEnd(this.selectionEnd + offset); - } else { - this.setSelectionStart(this.selectionStart + offset); - } - if (this.selectionEnd < this.selectionStart && this._selectionDirection === "left") { - this.swapSelectionPoints(); - this._selectionDirection = "right"; - } - if (this.selectionEnd > this.text.length) { - this.setSelectionEnd(this.text.length); - } - }, - getUpCursorOffset: function(e, isRight) { - var selectionProp = isRight ? this.selectionEnd : this.selectionStart, cursorLocation = this.get2DCursorLocation(selectionProp), lineIndex = cursorLocation.lineIndex; - if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { - return selectionProp; - } - var textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex), textOnPreviousLine = this._textLines[lineIndex - 1] || "", _char, widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, cursorLocation.lineIndex), lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor), widthOfCharsOnSameLineBeforeCursor = lineLeftOffset; - for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { - _char = textOnSameLineBeforeCursor[i]; - widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); - } - var indexOnPrevLine = this._getIndexOnPrevLine(cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor); - return textOnPreviousLine.length - indexOnPrevLine + textOnSameLineBeforeCursor.length; - }, - _getIndexOnPrevLine: function(cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor) { - var lineIndex = cursorLocation.lineIndex - 1, widthOfPreviousLine = this._getLineWidth(this.ctx, lineIndex), lineLeftOffset = this._getLineLeftOffset(widthOfPreviousLine), widthOfCharsOnPreviousLine = lineLeftOffset, indexOnPrevLine = 0, foundMatch; - for (var j = 0, jlen = textOnPreviousLine.length; j < jlen; j++) { - var _char = textOnPreviousLine[j], widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); - widthOfCharsOnPreviousLine += widthOfChar; - if (widthOfCharsOnPreviousLine > widthOfCharsOnSameLineBeforeCursor) { - foundMatch = true; - var leftEdge = widthOfCharsOnPreviousLine - widthOfChar, rightEdge = widthOfCharsOnPreviousLine, offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); - indexOnPrevLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1; - break; - } - } - if (!foundMatch) { - indexOnPrevLine = textOnPreviousLine.length - 1; - } - return indexOnPrevLine; - }, - moveCursorUp: function(e) { - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - var offset = this.getUpCursorOffset(e, this._selectionDirection === "right"); - if (e.shiftKey) { - this.moveCursorUpWithShift(offset); - } else { - this.moveCursorUpWithoutShift(offset); - } - this.initDelayedCursor(); - }, - moveCursorUpWithShift: function(offset) { - if (this.selectionEnd === this.selectionStart) { - this._selectionDirection = "left"; - } - if (this._selectionDirection === "right") { - this.setSelectionEnd(this.selectionEnd - offset); - } else { - this.setSelectionStart(this.selectionStart - offset); - } - if (this.selectionEnd < this.selectionStart && this._selectionDirection === "right") { - this.swapSelectionPoints(); - this._selectionDirection = "left"; - } - }, - moveCursorUpWithoutShift: function(offset) { - if (this.selectionStart === this.selectionEnd) { - this.setSelectionStart(this.selectionStart - offset); - } - this.setSelectionEnd(this.selectionStart); - this._selectionDirection = "left"; - }, - moveCursorLeft: function(e) { - if (this.selectionStart === 0 && this.selectionEnd === 0) { - return; - } - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - if (e.shiftKey) { - this.moveCursorLeftWithShift(e); - } else { - this.moveCursorLeftWithoutShift(e); - } - this.initDelayedCursor(); - }, - _move: function(e, prop, direction) { - var propMethod = prop === "selectionStart" ? "setSelectionStart" : "setSelectionEnd"; - if (e.altKey) { - this[propMethod](this["findWordBoundary" + direction](this[prop])); - } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) { - this[propMethod](this["findLineBoundary" + direction](this[prop])); - } else { - this[propMethod](this[prop] + (direction === "Left" ? -1 : 1)); - } - }, - _moveLeft: function(e, prop) { - this._move(e, prop, "Left"); - }, - _moveRight: function(e, prop) { - this._move(e, prop, "Right"); - }, - moveCursorLeftWithoutShift: function(e) { - this._selectionDirection = "left"; - if (this.selectionEnd === this.selectionStart) { - this._moveLeft(e, "selectionStart"); - } - this.setSelectionEnd(this.selectionStart); - }, - moveCursorLeftWithShift: function(e) { - if (this._selectionDirection === "right" && this.selectionStart !== this.selectionEnd) { - this._moveLeft(e, "selectionEnd"); - } else { - this._selectionDirection = "left"; - this._moveLeft(e, "selectionStart"); - } - }, - moveCursorRight: function(e) { - if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) { - return; - } - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - if (e.shiftKey) { - this.moveCursorRightWithShift(e); - } else { - this.moveCursorRightWithoutShift(e); - } - this.initDelayedCursor(); - }, - moveCursorRightWithShift: function(e) { - if (this._selectionDirection === "left" && this.selectionStart !== this.selectionEnd) { - this._moveRight(e, "selectionStart"); - } else { - this._selectionDirection = "right"; - this._moveRight(e, "selectionEnd"); - } - }, - moveCursorRightWithoutShift: function(e) { - this._selectionDirection = "right"; - if (this.selectionStart === this.selectionEnd) { - this._moveRight(e, "selectionStart"); - this.setSelectionEnd(this.selectionStart); - } else { - this.setSelectionEnd(this.selectionEnd + this.getNumNewLinesInSelectedText()); - this.setSelectionStart(this.selectionEnd); - } - }, - removeChars: function(e) { - if (this.selectionStart === this.selectionEnd) { - this._removeCharsNearCursor(e); - } else { - this._removeCharsFromTo(this.selectionStart, this.selectionEnd); - } - this.setSelectionEnd(this.selectionStart); - this._removeExtraneousStyles(); - this.canvas && this.canvas.renderAll(); - this.setCoords(); - this.fire("changed"); - this.canvas && this.canvas.fire("text:changed", { - target: this - }); - }, - _removeCharsNearCursor: function(e) { - if (this.selectionStart === 0) { - return; - } - if (e.metaKey) { - var leftLineBoundary = this.findLineBoundaryLeft(this.selectionStart); - this._removeCharsFromTo(leftLineBoundary, this.selectionStart); - this.setSelectionStart(leftLineBoundary); - } else if (e.altKey) { - var leftWordBoundary = this.findWordBoundaryLeft(this.selectionStart); - this._removeCharsFromTo(leftWordBoundary, this.selectionStart); - this.setSelectionStart(leftWordBoundary); - } else { - this._removeSingleCharAndStyle(this.selectionStart); - this.setSelectionStart(this.selectionStart - 1); - } - } -}); - -(function() { - var toFixed = fabric.util.toFixed, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - fabric.util.object.extend(fabric.IText.prototype, { - _setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) { - if (!this._getLineStyle(lineIndex)) { - fabric.Text.prototype._setSVGTextLineText.call(this, lineIndex, textSpans, height, textLeftOffset, textTopOffset); - } else { - this._setSVGTextLineChars(lineIndex, textSpans, height, textLeftOffset, textBgRects); - } - }, - _setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) { - var chars = this._textLines[lineIndex], charOffset = 0, lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) - this.width / 2, lineOffset = this._getSVGLineTopOffset(lineIndex), heightOfLine = this._getHeightOfLine(this.ctx, lineIndex); - for (var i = 0, len = chars.length; i < len; i++) { - var styleDecl = this._getStyleDeclaration(lineIndex, i) || {}; - textSpans.push(this._createTextCharSpan(chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset)); - var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i); - if (styleDecl.textBackgroundColor) { - textBgRects.push(this._createTextCharBg(styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset)); - } - charOffset += charWidth; - } - }, - _getSVGLineTopOffset: function(lineIndex) { - var lineTopOffset = 0, lastHeight = 0; - for (var j = 0; j < lineIndex; j++) { - lineTopOffset += this._getHeightOfLine(this.ctx, j); - } - lastHeight = this._getHeightOfLine(this.ctx, j); - return { - lineTop: lineTopOffset, - offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult) - }; - }, - _createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) { - return [ ' \n' ].join(""); - }, - _createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) { - var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({ - visible: true, - fill: this.fill, - stroke: this.stroke, - type: "text", - getSvgFilter: fabric.Object.prototype.getSvgFilter - }, styleDecl)); - return [ ' ', fabric.util.string.escapeXml(_char), "\n" ].join(""); - } - }); -})(); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), clone = fabric.util.object.clone; - fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, { - type: "textbox", - minWidth: 20, - dynamicMinWidth: 0, - __cachedLines: null, - initialize: function(text, options) { - this.ctx = fabric.util.createCanvasElement().getContext("2d"); - this.callSuper("initialize", text, options); - this.set({ - lockUniScaling: false, - lockScalingY: true, - lockScalingFlip: true, - hasBorders: true - }); - this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility()); - this._dimensionAffectingProps.width = true; - }, - _initDimensions: function(ctx) { - if (this.__skipDimension) { - return; - } - if (!ctx) { - ctx = fabric.util.createCanvasElement().getContext("2d"); - this._setTextStyles(ctx); - } - this.dynamicMinWidth = 0; - this._textLines = this._splitTextIntoLines(); - if (this.dynamicMinWidth > this.width) { - this._set("width", this.dynamicMinWidth); - } - this._clearCache(); - this.height = this._getTextHeight(ctx); - }, - _generateStyleMap: function() { - var realLineCount = 0, realLineCharCount = 0, charCount = 0, map = {}; - for (var i = 0; i < this._textLines.length; i++) { - if (this.text[charCount] === "\n") { - realLineCharCount = 0; - charCount++; - realLineCount++; - } else if (this.text[charCount] === " ") { - realLineCharCount++; - charCount++; - } - map[i] = { - line: realLineCount, - offset: realLineCharCount - }; - charCount += this._textLines[i].length; - realLineCharCount += this._textLines[i].length; - } - return map; - }, - _getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) { - if (this._styleMap) { - var map = this._styleMap[lineIndex]; - if (!map) { - return returnCloneOrEmpty ? {} : null; - } - lineIndex = map.line; - charIndex = map.offset + charIndex; - } - return this.callSuper("_getStyleDeclaration", lineIndex, charIndex, returnCloneOrEmpty); - }, - _setStyleDeclaration: function(lineIndex, charIndex, style) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - this.styles[lineIndex][charIndex] = style; - }, - _deleteStyleDeclaration: function(lineIndex, charIndex) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - delete this.styles[lineIndex][charIndex]; - }, - _getLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - return this.styles[map.line]; - }, - _setLineStyle: function(lineIndex, style) { - var map = this._styleMap[lineIndex]; - this.styles[map.line] = style; - }, - _deleteLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - delete this.styles[map.line]; - }, - _wrapText: function(ctx, text) { - var lines = text.split(this._reNewline), wrapped = [], i; - for (i = 0; i < lines.length; i++) { - wrapped = wrapped.concat(this._wrapLine(ctx, lines[i], i)); - } - return wrapped; - }, - _measureText: function(ctx, text, lineIndex, charOffset) { - var width = 0; - charOffset = charOffset || 0; - for (var i = 0, len = text.length; i < len; i++) { - width += this._getWidthOfChar(ctx, text[i], lineIndex, i + charOffset); - } - return width; - }, - _wrapLine: function(ctx, text, lineIndex) { - var lineWidth = 0, lines = [], line = "", words = text.split(" "), word = "", offset = 0, infix = " ", wordWidth = 0, infixWidth = 0, largestWordWidth = 0, lineJustStarted = true; - for (var i = 0; i < words.length; i++) { - word = words[i]; - wordWidth = this._measureText(ctx, word, lineIndex, offset); - offset += word.length; - lineWidth += infixWidth + wordWidth; - if (lineWidth >= this.width && !lineJustStarted) { - lines.push(line); - line = ""; - lineWidth = wordWidth; - lineJustStarted = true; - } - if (!lineJustStarted) { - line += infix; - } - line += word; - infixWidth = this._measureText(ctx, infix, lineIndex, offset); - offset++; - lineJustStarted = false; - if (wordWidth > largestWordWidth) { - largestWordWidth = wordWidth; - } - } - i && lines.push(line); - if (largestWordWidth > this.dynamicMinWidth) { - this.dynamicMinWidth = largestWordWidth; - } - return lines; - }, - _splitTextIntoLines: function() { - var originalAlign = this.textAlign; - this.ctx.save(); - this._setTextStyles(this.ctx); - this.textAlign = "left"; - var lines = this._wrapText(this.ctx, this.text); - this.textAlign = originalAlign; - this.ctx.restore(); - this._textLines = lines; - this._styleMap = this._generateStyleMap(); - return lines; - }, - setOnGroup: function(key, value) { - if (key === "scaleX") { - this.set("scaleX", Math.abs(1 / value)); - this.set("width", this.get("width") * value / (typeof this.__oldScaleX === "undefined" ? 1 : this.__oldScaleX)); - this.__oldScaleX = value; - } - }, - get2DCursorLocation: function(selectionStart) { - if (typeof selectionStart === "undefined") { - selectionStart = this.selectionStart; - } - var numLines = this._textLines.length, removed = 0; - for (var i = 0; i < numLines; i++) { - var line = this._textLines[i], lineLen = line.length; - if (selectionStart <= removed + lineLen) { - return { - lineIndex: i, - charIndex: selectionStart - removed - }; - } - removed += lineLen; - if (this.text[removed] === "\n" || this.text[removed] === " ") { - removed++; - } - } - return { - lineIndex: numLines - 1, - charIndex: this._textLines[numLines - 1].length - }; - }, - _getCursorBoundariesOffsets: function(chars, typeOfBoundaries) { - var topOffset = 0, leftOffset = 0, cursorLocation = this.get2DCursorLocation(), lineChars = this._textLines[cursorLocation.lineIndex].split(""), lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, cursorLocation.lineIndex)); - for (var i = 0; i < cursorLocation.charIndex; i++) { - leftOffset += this._getWidthOfChar(this.ctx, lineChars[i], cursorLocation.lineIndex, i); - } - for (i = 0; i < cursorLocation.lineIndex; i++) { - topOffset += this._getHeightOfLine(this.ctx, i); - } - if (typeOfBoundaries === "cursor") { - topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, cursorLocation.lineIndex) / this.lineHeight - this.getCurrentCharFontSize(cursorLocation.lineIndex, cursorLocation.charIndex) * (1 - this._fontSizeFraction); - } - return { - top: topOffset, - left: leftOffset, - lineLeft: lineLeftOffset - }; - }, - getMinWidth: function() { - return Math.max(this.minWidth, this.dynamicMinWidth); - }, - toObject: function(propertiesToInclude) { - return fabric.util.object.extend(this.callSuper("toObject", propertiesToInclude), { - minWidth: this.minWidth - }); - } - }); - fabric.Textbox.fromObject = function(object) { - return new fabric.Textbox(object.text, clone(object)); - }; - fabric.Textbox.getTextboxControlVisibility = function() { - return { - tl: false, - tr: false, - br: false, - bl: false, - ml: true, - mt: false, - mr: true, - mb: false, - mtr: true - }; - }; - fabric.Textbox.instances = []; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - var setObjectScaleOverridden = fabric.Canvas.prototype._setObjectScale; - fabric.Canvas.prototype._setObjectScale = function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) { - var t = transform.target; - if (t instanceof fabric.Textbox) { - var w = t.width * (localMouse.x / transform.scaleX / (t.width + t.strokeWidth)); - if (w >= t.getMinWidth()) { - t.set("width", w); - return true; - } - } else { - return setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim); - } - }; - fabric.Group.prototype._refreshControlsVisibility = function() { - if (typeof fabric.Textbox === "undefined") { - return; - } - for (var i = this._objects.length; i--; ) { - if (this._objects[i] instanceof fabric.Textbox) { - this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility()); - return; - } - } - }; - var clone = fabric.util.object.clone; - fabric.util.object.extend(fabric.Textbox.prototype, { - _removeExtraneousStyles: function() { - for (var prop in this._styleMap) { - if (!this._textLines[prop]) { - delete this.styles[this._styleMap[prop].line]; - } - } - }, - insertCharStyleObject: function(lineIndex, charIndex, style) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - fabric.IText.prototype.insertCharStyleObject.apply(this, [ lineIndex, charIndex, style ]); - }, - insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - fabric.IText.prototype.insertNewlineStyleObject.apply(this, [ lineIndex, charIndex, isEndOfLine ]); - }, - shiftLineStyles: function(lineIndex, offset) { - var clonedStyles = clone(this.styles), map = this._styleMap[lineIndex]; - lineIndex = map.line; - for (var line in this.styles) { - var numericLine = parseInt(line, 10); - if (numericLine > lineIndex) { - this.styles[numericLine + offset] = clonedStyles[numericLine]; - if (!clonedStyles[numericLine - offset]) { - delete this.styles[numericLine]; - } - } - } - }, - _getTextOnPreviousLine: function(lIndex) { - var textOnPreviousLine = this._textLines[lIndex - 1]; - while (this._styleMap[lIndex - 2] && this._styleMap[lIndex - 2].line === this._styleMap[lIndex - 1].line) { - textOnPreviousLine = this._textLines[lIndex - 2] + textOnPreviousLine; - lIndex--; - } - return textOnPreviousLine; - }, - removeStyleObject: function(isBeginningOfLine, index) { - var cursorLocation = this.get2DCursorLocation(index), map = this._styleMap[cursorLocation.lineIndex], lineIndex = map.line, charIndex = map.offset + cursorLocation.charIndex; - this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex); - } - }); -})(); - -(function() { - var override = fabric.IText.prototype._getNewSelectionStartFromOffset; - fabric.IText.prototype._getNewSelectionStartFromOffset = function(mouseOffset, prevWidth, width, index, jlen) { - index = override.call(this, mouseOffset, prevWidth, width, index, jlen); - var tmp = 0, removed = 0; - for (var i = 0; i < this._textLines.length; i++) { - tmp += this._textLines[i].length; - if (tmp + removed >= index) { - break; - } - if (this.text[tmp + removed] === "\n" || this.text[tmp + removed] === " ") { - removed++; - } - } - return index - i + removed; - }; -})(); - -(function() { - if (typeof document !== "undefined" && typeof window !== "undefined") { - return; - } - var DOMParser = require("xmldom").DOMParser, URL = require("url"), HTTP = require("http"), HTTPS = require("https"), Canvas = require("canvas"), Image = require("canvas").Image; - function request(url, encoding, callback) { - var oURL = URL.parse(url); - if (!oURL.port) { - oURL.port = oURL.protocol.indexOf("https:") === 0 ? 443 : 80; - } - var reqHandler = oURL.protocol.indexOf("https:") === 0 ? HTTPS : HTTP, req = reqHandler.request({ - hostname: oURL.hostname, - port: oURL.port, - path: oURL.path, - method: "GET" - }, function(response) { - var body = ""; - if (encoding) { - response.setEncoding(encoding); - } - response.on("end", function() { - callback(body); - }); - response.on("data", function(chunk) { - if (response.statusCode === 200) { - body += chunk; - } - }); - }); - req.on("error", function(err) { - if (err.errno === process.ECONNREFUSED) { - fabric.log("ECONNREFUSED: connection refused to " + oURL.hostname + ":" + oURL.port); - } else { - fabric.log(err.message); - } - callback(null); - }); - req.end(); - } - function requestFs(path, callback) { - var fs = require("fs"); - fs.readFile(path, function(err, data) { - if (err) { - fabric.log(err); - throw err; - } else { - callback(data); - } - }); - } - fabric.util.loadImage = function(url, callback, context) { - function createImageAndCallBack(data) { - if (data) { - img.src = new Buffer(data, "binary"); - img._src = url; - callback && callback.call(context, img); - } else { - img = null; - callback && callback.call(context, null, true); - } - } - var img = new Image(); - if (url && (url instanceof Buffer || url.indexOf("data") === 0)) { - img.src = img._src = url; - callback && callback.call(context, img); - } else if (url && url.indexOf("http") !== 0) { - requestFs(url, createImageAndCallBack); - } else if (url) { - request(url, "binary", createImageAndCallBack); - } else { - callback && callback.call(context, url); - } - }; - fabric.loadSVGFromURL = function(url, callback, reviver) { - url = url.replace(/^\n\s*/, "").replace(/\?.*$/, "").trim(); - if (url.indexOf("http") !== 0) { - requestFs(url, function(body) { - fabric.loadSVGFromString(body.toString(), callback, reviver); - }); - } else { - request(url, "", function(body) { - fabric.loadSVGFromString(body, callback, reviver); - }); - } - }; - fabric.loadSVGFromString = function(string, callback, reviver) { - var doc = new DOMParser().parseFromString(string); - fabric.parseSVGDocument(doc.documentElement, function(results, options) { - callback && callback(results, options); - }, reviver); - }; - fabric.util.getScript = function(url, callback) { - request(url, "", function(body) { - eval(body); - callback && callback(); - }); - }; - fabric.Image.fromObject = function(object, callback) { - fabric.util.loadImage(object.src, function(img) { - var oImg = new fabric.Image(img); - oImg._initConfig(object); - oImg._initFilters(object.filters, function(filters) { - oImg.filters = filters || []; - oImg._initFilters(object.resizeFilters, function(resizeFilters) { - oImg.resizeFilters = resizeFilters || []; - callback && callback(oImg); - }); - }); - }); - }; - fabric.createCanvasForNode = function(width, height, options, nodeCanvasOptions) { - nodeCanvasOptions = nodeCanvasOptions || options; - var canvasEl = fabric.document.createElement("canvas"), nodeCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions); - canvasEl.style = {}; - canvasEl.width = nodeCanvas.width; - canvasEl.height = nodeCanvas.height; - var FabricCanvas = fabric.Canvas || fabric.StaticCanvas, fabricCanvas = new FabricCanvas(canvasEl, options); - fabricCanvas.contextContainer = nodeCanvas.getContext("2d"); - fabricCanvas.nodeCanvas = nodeCanvas; - fabricCanvas.Font = Canvas.Font; - return fabricCanvas; - }; - fabric.StaticCanvas.prototype.createPNGStream = function() { - return this.nodeCanvas.createPNGStream(); - }; - fabric.StaticCanvas.prototype.createJPEGStream = function(opts) { - return this.nodeCanvas.createJPEGStream(opts); - }; - var origSetWidth = fabric.StaticCanvas.prototype.setWidth; - fabric.StaticCanvas.prototype.setWidth = function(width, options) { - origSetWidth.call(this, width, options); - this.nodeCanvas.width = width; - return this; - }; - if (fabric.Canvas) { - fabric.Canvas.prototype.setWidth = fabric.StaticCanvas.prototype.setWidth; - } - var origSetHeight = fabric.StaticCanvas.prototype.setHeight; - fabric.StaticCanvas.prototype.setHeight = function(height, options) { - origSetHeight.call(this, height, options); - this.nodeCanvas.height = height; - return this; - }; - if (fabric.Canvas) { - fabric.Canvas.prototype.setHeight = fabric.StaticCanvas.prototype.setHeight; - } -})(); - -window.fabric = fabric; - -if (typeof define === "function" && define.amd) { - define([], function() { - return fabric; - }); -} \ No newline at end of file +var fabric=fabric||{version:"1.6.1"};if(typeof exports!=="undefined"){exports.fabric=fabric}if(typeof document!=="undefined"&&typeof window!=="undefined"){fabric.document=document;fabric.window=window;window.fabric=fabric}else{fabric.document=require("jsdom").jsdom("");if(fabric.document.createWindow){fabric.window=fabric.document.createWindow()}else{fabric.window=fabric.document.parentWindow}}fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement;fabric.isLikelyNode=typeof Buffer!=="undefined"&&typeof window==="undefined";fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id"];fabric.DPI=96;fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)";fabric.fontPaths={};fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1;(function(){function _removeEventListener(eventName,handler){if(!this.__eventListeners[eventName]){return}var eventListener=this.__eventListeners[eventName];if(handler){eventListener[eventListener.indexOf(handler)]=false}else{fabric.util.array.fill(eventListener,false)}}function observe(eventName,handler){if(!this.__eventListeners){this.__eventListeners={}}if(arguments.length===1){for(var prop in eventName){this.on(prop,eventName[prop])}}else{if(!this.__eventListeners[eventName]){this.__eventListeners[eventName]=[]}this.__eventListeners[eventName].push(handler)}return this}function stopObserving(eventName,handler){if(!this.__eventListeners){return}if(arguments.length===0){for(eventName in this.__eventListeners){_removeEventListener.call(this,eventName)}}else if(arguments.length===1&&typeof arguments[0]==="object"){for(var prop in eventName){_removeEventListener.call(this,prop,eventName[prop])}}else{_removeEventListener.call(this,eventName,handler)}return this}function fire(eventName,options){if(!this.__eventListeners){return}var listenersForEvent=this.__eventListeners[eventName];if(!listenersForEvent){return}for(var i=0,len=listenersForEvent.length;i-1},complexity:function(){return this.getObjects().reduce(function(memo,current){memo+=current.complexity?current.complexity():0;return memo},0)}};(function(global){var sqrt=Math.sqrt,atan2=Math.atan2,pow=Math.pow,abs=Math.abs,PiBy180=Math.PI/180;fabric.util={removeFromArray:function(array,value){var idx=array.indexOf(value);if(idx!==-1){array.splice(idx,1)}return array},getRandomInt:function(min,max){return Math.floor(Math.random()*(max-min+1))+min},degreesToRadians:function(degrees){return degrees*PiBy180},radiansToDegrees:function(radians){return radians/PiBy180},rotatePoint:function(point,origin,radians){point.subtractEquals(origin);var v=fabric.util.rotateVector(point,radians);return new fabric.Point(v.x,v.y).addEquals(origin)},rotateVector:function(vector,radians){var sin=Math.sin(radians),cos=Math.cos(radians),rx=vector.x*cos-vector.y*sin,ry=vector.x*sin+vector.y*cos;return{x:rx,y:ry}},transformPoint:function(p,t,ignoreOffset){if(ignoreOffset){return new fabric.Point(t[0]*p.x+t[2]*p.y,t[1]*p.x+t[3]*p.y)}return new fabric.Point(t[0]*p.x+t[2]*p.y+t[4],t[1]*p.x+t[3]*p.y+t[5])},makeBoundingBoxFromPoints:function(points){var xPoints=[points[0].x,points[1].x,points[2].x,points[3].x],minX=fabric.util.array.min(xPoints),maxX=fabric.util.array.max(xPoints),width=Math.abs(minX-maxX),yPoints=[points[0].y,points[1].y,points[2].y,points[3].y],minY=fabric.util.array.min(yPoints),maxY=fabric.util.array.max(yPoints),height=Math.abs(minY-maxY);return{left:minX,top:minY,width:width,height:height}},invertTransform:function(t){var a=1/(t[0]*t[3]-t[1]*t[2]),r=[a*t[3],-a*t[1],-a*t[2],a*t[0]],o=fabric.util.transformPoint({x:t[4],y:t[5]},r,true);r[4]=-o.x;r[5]=-o.y;return r},toFixed:function(number,fractionDigits){return parseFloat(Number(number).toFixed(fractionDigits))},parseUnit:function(value,fontSize){var unit=/\D{0,2}$/.exec(value),number=parseFloat(value);if(!fontSize){fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}switch(unit[0]){case"mm":return number*fabric.DPI/25.4;case"cm":return number*fabric.DPI/2.54;case"in":return number*fabric.DPI;case"pt":return number*fabric.DPI/72;case"pc":return number*fabric.DPI/72*12;case"em":return number*fontSize;default:return number}},falseFunction:function(){return false},getKlass:function(type,namespace){type=fabric.util.string.camelize(type.charAt(0).toUpperCase()+type.slice(1));return fabric.util.resolveNamespace(namespace)[type]},resolveNamespace:function(namespace){if(!namespace){return fabric}var parts=namespace.split("."),len=parts.length,obj=global||fabric.window;for(var i=0;ix){x+=da[di++%dc];if(x>len){x=len}ctx[draw?"lineTo":"moveTo"](x,0);draw=!draw}ctx.restore()},createCanvasElement:function(canvasEl){canvasEl||(canvasEl=fabric.document.createElement("canvas"));if(!canvasEl.getContext&&typeof G_vmlCanvasManager!=="undefined"){G_vmlCanvasManager.initElement(canvasEl)}return canvasEl},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(klass){var proto=klass.prototype;for(var i=proto.stateProperties.length;i--;){var propName=proto.stateProperties[i],capitalizedPropName=propName.charAt(0).toUpperCase()+propName.slice(1),setterName="set"+capitalizedPropName,getterName="get"+capitalizedPropName;if(!proto[getterName]){proto[getterName]=function(property){return new Function('return this.get("'+property+'")')}(propName)}if(!proto[setterName]){proto[setterName]=function(property){return new Function("value",'return this.set("'+property+'", value)')}(propName)}}},clipContext:function(receiver,ctx){ctx.save();ctx.beginPath();receiver.clipTo(ctx);ctx.clip()},multiplyTransformMatrices:function(a,b,is2x2){return[a[0]*b[0]+a[2]*b[1],a[1]*b[0]+a[3]*b[1],a[0]*b[2]+a[2]*b[3],a[1]*b[2]+a[3]*b[3],is2x2?0:a[0]*b[4]+a[2]*b[5]+a[4],is2x2?0:a[1]*b[4]+a[3]*b[5]+a[5]]},qrDecompose:function(a){var angle=atan2(a[1],a[0]),denom=pow(a[0],2)+pow(a[1],2),scaleX=sqrt(denom),scaleY=(a[0]*a[3]-a[2]*a[1])/scaleX,skewX=atan2(a[0]*a[2]+a[1]*a[3],denom);return{angle:angle/PiBy180,scaleX:scaleX,scaleY:scaleY,skewX:skewX/PiBy180,skewY:0,translateX:a[4],translateY:a[5]}},customTransformMatrix:function(scaleX,scaleY,skewX){var skewMatrixX=[1,0,abs(Math.tan(skewX*PiBy180)),1],scaleMatrix=[abs(scaleX),0,0,abs(scaleY)];return fabric.util.multiplyTransformMatrices(scaleMatrix,skewMatrixX,true)},resetObjectTransform:function(target){target.scaleX=1;target.scaleY=1;target.skewX=0;target.skewY=0;target.flipX=false;target.flipY=false;target.setAngle(0)},getFunctionBody:function(fn){return(String(fn).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(ctx,x,y,tolerance){if(tolerance>0){if(x>tolerance){x-=tolerance}else{x=0}if(y>tolerance){y-=tolerance}else{y=0}}var _isTransparent=true,imageData=ctx.getImageData(x,y,tolerance*2||1,tolerance*2||1);for(var i=3,l=imageData.data.length;i0){dtheta-=2*PI}else if(sweep===1&&dtheta<0){dtheta+=2*PI}var segments=Math.ceil(Math.abs(dtheta/PI*2)),result=[],mDelta=dtheta/segments,mT=8/3*Math.sin(mDelta/4)*Math.sin(mDelta/4)/Math.sin(mDelta/2),th3=mTheta+mDelta;for(var i=0;i=ta){return tb-ta}else{return 2*Math.PI-(ta-tb)}}fabric.util.drawArc=function(ctx,fx,fy,coords){var rx=coords[0],ry=coords[1],rot=coords[2],large=coords[3],sweep=coords[4],tx=coords[5],ty=coords[6],segs=[[],[],[],[]],segsNorm=arcToSegments(tx-fx,ty-fy,rx,ry,large,sweep,rot);for(var i=0,len=segsNorm.length;i0){b=6*y0-12*y1+6*y2;a=-3*y0+9*y1-9*y2+3*y3;c=3*y1-3*y0}if(abs(a)<1e-12){if(abs(b)<1e-12){continue}t=-c/b;if(0>>0;if(len===0){return-1}var n=0;if(arguments.length>0){n=Number(arguments[1]);if(n!==n){n=0}else if(n!==0&&n!==Number.POSITIVE_INFINITY&&n!==Number.NEGATIVE_INFINITY){n=(n>0||-1)*Math.floor(Math.abs(n))}}if(n>=len){return-1}var k=n>=0?n:Math.max(len-Math.abs(n),0);for(;k>>0;i>>0;i>>0;i>>0;i>>0;i>>0,i=0,rv;if(arguments.length>1){rv=arguments[1]}else{do{if(i in this){rv=this[i++];break}if(++i>=len){throw new TypeError}}while(true)}for(;i=value2})}function min(array,byProperty){return find(array,byProperty,function(value1,value2){return value1/g,">")}fabric.util.string={camelize:camelize,capitalize:capitalize,escapeXml:escapeXml}})();(function(){var slice=Array.prototype.slice,apply=Function.prototype.apply,Dummy=function(){};if(!Function.prototype.bind){Function.prototype.bind=function(thisArg){var _this=this,args=slice.call(arguments,1),bound;if(args.length){bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,args.concat(slice.call(arguments)))}}else{bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,arguments)}}Dummy.prototype=this.prototype;bound.prototype=new Dummy;return bound}}})();(function(){var slice=Array.prototype.slice,emptyFunction=function(){},IS_DONTENUM_BUGGY=function(){for(var p in{toString:1}){if(p==="toString"){return false}}return true}(),addMethods=function(klass,source,parent){for(var property in source){if(property in klass.prototype&&typeof klass.prototype[property]==="function"&&(source[property]+"").indexOf("callSuper")>-1){klass.prototype[property]=function(property){return function(){var superclass=this.constructor.superclass;this.constructor.superclass=parent;var returnValue=source[property].apply(this,arguments);this.constructor.superclass=superclass;if(property!=="initialize"){return returnValue}}}(property)}else{klass.prototype[property]=source[property]}if(IS_DONTENUM_BUGGY){if(source.toString!==Object.prototype.toString){klass.prototype.toString=source.toString}if(source.valueOf!==Object.prototype.valueOf){klass.prototype.valueOf=source.valueOf}}}};function Subclass(){}function callSuper(methodName){var fn=this.constructor.superclass.prototype[methodName];return arguments.length>1?fn.apply(this,slice.call(arguments,1)):fn.call(this)}function createClass(){var parent=null,properties=slice.call(arguments,0);if(typeof properties[0]==="function"){parent=properties.shift()}function klass(){this.initialize.apply(this,arguments)}klass.superclass=parent;klass.subclasses=[];if(parent){Subclass.prototype=parent.prototype;klass.prototype=new Subclass;parent.subclasses.push(klass)}for(var i=0,length=properties.length;i-1?setOpacity(element,styles.match(/opacity:\s*(\d?\.?\d*)/)[1]):element}for(var property in styles){if(property==="opacity"){setOpacity(element,styles[property])}else{var normalizedProperty=property==="float"||property==="cssFloat"?typeof elementStyle.styleFloat==="undefined"?"cssFloat":"styleFloat":property;elementStyle[normalizedProperty]=styles[property]}}return element}var parseEl=fabric.document.createElement("div"),supportsOpacity=typeof parseEl.style.opacity==="string",supportsFilters=typeof parseEl.style.filter==="string",reOpacity=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,setOpacity=function(element){return element};if(supportsOpacity){setOpacity=function(element,value){element.style.opacity=value;return element}}else if(supportsFilters){setOpacity=function(element,value){var es=element.style;if(element.currentStyle&&!element.currentStyle.hasLayout){es.zoom=1}if(reOpacity.test(es.filter)){value=value>=.9999?"":"alpha(opacity="+value*100+")";es.filter=es.filter.replace(reOpacity,value)}else{es.filter+=" alpha(opacity="+value*100+")"}return element}}fabric.util.setStyle=setStyle})();(function(){var _slice=Array.prototype.slice;function getById(id){return typeof id==="string"?fabric.document.getElementById(id):id}var sliceCanConvertNodelists,toArray=function(arrayLike){return _slice.call(arrayLike,0)};try{sliceCanConvertNodelists=toArray(fabric.document.childNodes)instanceof Array}catch(err){}if(!sliceCanConvertNodelists){toArray=function(arrayLike){var arr=new Array(arrayLike.length),i=arrayLike.length;while(i--){arr[i]=arrayLike[i]}return arr}}function makeElement(tagName,attributes){var el=fabric.document.createElement(tagName);for(var prop in attributes){if(prop==="class"){el.className=attributes[prop]}else if(prop==="for"){el.htmlFor=attributes[prop]}else{el.setAttribute(prop,attributes[prop])}}return el}function addClass(element,className){if(element&&(" "+element.className+" ").indexOf(" "+className+" ")===-1){element.className+=(element.className?" ":"")+className}}function wrapElement(element,wrapper,attributes){if(typeof wrapper==="string"){wrapper=makeElement(wrapper,attributes)}if(element.parentNode){element.parentNode.replaceChild(wrapper,element)}wrapper.appendChild(element);return wrapper}function getScrollLeftTop(element){var left=0,top=0,docElement=fabric.document.documentElement,body=fabric.document.body||{scrollLeft:0,scrollTop:0};while(element&&(element.parentNode||element.host)){element=element.parentNode||element.host;if(element===fabric.document){left=body.scrollLeft||docElement.scrollLeft||0;top=body.scrollTop||docElement.scrollTop||0}else{left+=element.scrollLeft||0;top+=element.scrollTop||0}if(element.nodeType===1&&fabric.util.getElementStyle(element,"position")==="fixed"){break}}return{left:left,top:top}}function getElementOffset(element){var docElem,doc=element&&element.ownerDocument,box={left:0,top:0},offset={left:0,top:0},scrollLeftTop,offsetAttributes={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!doc){return offset}for(var attr in offsetAttributes){offset[offsetAttributes[attr]]+=parseInt(getElementStyle(element,attr),10)||0}docElem=doc.documentElement;if(typeof element.getBoundingClientRect!=="undefined"){box=element.getBoundingClientRect()}scrollLeftTop=getScrollLeftTop(element);return{left:box.left+scrollLeftTop.left-(docElem.clientLeft||0)+offset.left,top:box.top+scrollLeftTop.top-(docElem.clientTop||0)+offset.top}}var getElementStyle;if(fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle){getElementStyle=function(element,attr){var style=fabric.document.defaultView.getComputedStyle(element,null);return style?style[attr]:undefined}}else{getElementStyle=function(element,attr){var value=element.style[attr];if(!value&&element.currentStyle){value=element.currentStyle[attr]}return value}}(function(){var style=fabric.document.documentElement.style,selectProp="userSelect"in style?"userSelect":"MozUserSelect"in style?"MozUserSelect":"WebkitUserSelect"in style?"WebkitUserSelect":"KhtmlUserSelect"in style?"KhtmlUserSelect":"";function makeElementUnselectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=fabric.util.falseFunction}if(selectProp){element.style[selectProp]="none"}else if(typeof element.unselectable==="string"){element.unselectable="on"}return element}function makeElementSelectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=null}if(selectProp){element.style[selectProp]=""}else if(typeof element.unselectable==="string"){element.unselectable=""}return element}fabric.util.makeElementUnselectable=makeElementUnselectable;fabric.util.makeElementSelectable=makeElementSelectable})();(function(){function getScript(url,callback){var headEl=fabric.document.getElementsByTagName("head")[0],scriptEl=fabric.document.createElement("script"),loading=true;scriptEl.onload=scriptEl.onreadystatechange=function(e){if(loading){if(typeof this.readyState==="string"&&this.readyState!=="loaded"&&this.readyState!=="complete"){return}loading=false;callback(e||fabric.window.event);scriptEl=scriptEl.onload=scriptEl.onreadystatechange=null}};scriptEl.src=url;headEl.appendChild(scriptEl)}fabric.util.getScript=getScript})();fabric.util.getById=getById;fabric.util.toArray=toArray;fabric.util.makeElement=makeElement;fabric.util.addClass=addClass;fabric.util.wrapElement=wrapElement;fabric.util.getScrollLeftTop=getScrollLeftTop;fabric.util.getElementOffset=getElementOffset;fabric.util.getElementStyle=getElementStyle})();(function(){function addParamToUrl(url,param){return url+(/\?/.test(url)?"&":"?")+param}var makeXHR=function(){var factories=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}];for(var i=factories.length;i--;){try{var req=factories[i]();if(req){return factories[i]}}catch(err){}}}();function emptyFn(){}function request(url,options){options||(options={});var method=options.method?options.method.toUpperCase():"GET",onComplete=options.onComplete||function(){},xhr=makeXHR(),body;xhr.onreadystatechange=function(){if(xhr.readyState===4){onComplete(xhr);xhr.onreadystatechange=emptyFn}};if(method==="GET"){body=null; +if(typeof options.parameters==="string"){url=addParamToUrl(url,options.parameters)}}xhr.open(method,url,true);if(method==="POST"||method==="PUT"){xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")}xhr.send(body);return xhr}fabric.util.request=request})();fabric.log=function(){};fabric.warn=function(){};if(typeof console!=="undefined"){["log","warn"].forEach(function(methodName){if(typeof console[methodName]!=="undefined"&&typeof console[methodName].apply==="function"){fabric[methodName]=function(){return console[methodName].apply(console,arguments)}}})}(function(){function animate(options){requestAnimFrame(function(timestamp){options||(options={});var start=timestamp||+new Date,duration=options.duration||500,finish=start+duration,time,onChange=options.onChange||function(){},abort=options.abort||function(){return false},easing=options.easing||function(t,b,c,d){return-c*Math.cos(t/d*(Math.PI/2))+c+b},startValue="startValue"in options?options.startValue:0,endValue="endValue"in options?options.endValue:100,byValue=options.byValue||endValue-startValue;options.onStart&&options.onStart();(function tick(ticktime){time=ticktime||+new Date;var currentTime=time>finish?duration:time-start;if(abort()){options.onComplete&&options.onComplete();return}onChange(easing(currentTime,startValue,byValue,duration));if(time>finish){options.onComplete&&options.onComplete();return}requestAnimFrame(tick)})(start)})}var _requestAnimFrame=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(callback){fabric.window.setTimeout(callback,1e3/60)};function requestAnimFrame(){return _requestAnimFrame.apply(fabric.window,arguments)}fabric.util.animate=animate;fabric.util.requestAnimFrame=requestAnimFrame})();(function(){function normalize(a,c,p,s){if(a1){matrices.shift();combinedMatrix=fabric.util.multiplyTransformMatrices(combinedMatrix,matrices[0])}return combinedMatrix}}();function parseStyleString(style,oStyle){var attr,value;style.replace(/;\s*$/,"").split(";").forEach(function(chunk){var pair=chunk.split(":");attr=normalizeAttr(pair[0].trim().toLowerCase());value=normalizeValue(attr,pair[1].trim());oStyle[attr]=value})}function parseStyleObject(style,oStyle){var attr,value;for(var prop in style){if(typeof style[prop]==="undefined"){continue}attr=normalizeAttr(prop.toLowerCase());value=normalizeValue(attr,style[prop]);oStyle[attr]=value}}function getGlobalStylesForElement(element,svgUid){var styles={};for(var rule in fabric.cssRules[svgUid]){if(elementMatchesRule(element,rule.split(" "))){for(var property in fabric.cssRules[svgUid][rule]){styles[property]=fabric.cssRules[svgUid][rule][property]}}}return styles}function elementMatchesRule(element,selectors){var firstMatching,parentMatching=true;firstMatching=selectorMatches(element,selectors.pop());if(firstMatching&&selectors.length){parentMatching=doesSomeParentMatch(element,selectors)}return firstMatching&&parentMatching&&selectors.length===0}function doesSomeParentMatch(element,selectors){var selector,parentMatching=true;while(element.parentNode&&element.parentNode.nodeType===1&&selectors.length){if(parentMatching){selector=selectors.pop()}element=element.parentNode;parentMatching=selectorMatches(element,selector)}return selectors.length===0}function selectorMatches(element,selector){var nodeName=element.nodeName,classNames=element.getAttribute("class"),id=element.getAttribute("id"),matcher;matcher=new RegExp("^"+nodeName,"i");selector=selector.replace(matcher,"");if(id&&selector.length){matcher=new RegExp("#"+id+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}if(classNames&&selector.length){classNames=classNames.split(" ");for(var i=classNames.length;i--;){matcher=new RegExp("\\."+classNames[i]+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}}return selector.length===0}function elementById(doc,id){var el;doc.getElementById&&(el=doc.getElementById(id));if(el){return el}var node,i,nodelist=doc.getElementsByTagName("*");for(i=0;iscaleY?scaleY:scaleX}if(scaleX===1&&scaleY===1&&minX===0&&minY===0&&x===0&&y===0){return parsedDim}if(x||y){translateMatrix=" translate("+parseUnit(x)+" "+parseUnit(y)+") "}matrix=translateMatrix+" matrix("+scaleX+" 0"+" 0 "+scaleY+" "+minX*scaleX+" "+minY*scaleY+") ";if(element.tagName==="svg"){el=element.ownerDocument.createElement("g");while(element.firstChild!=null){el.appendChild(element.firstChild)}element.appendChild(el)}else{el=element;matrix=el.getAttribute("transform")+matrix}el.setAttribute("transform",matrix);return parsedDim}fabric.parseSVGDocument=function(){function hasAncestorWithNodeName(element,nodeName){while(element&&(element=element.parentNode)){if(nodeName.test(element.nodeName)&&!element.getAttribute("instantiated_by_use")){return true}}return false}return function(doc,callback,reviver){if(!doc){return}parseUseDirectives(doc);var startTime=new Date,svgUid=fabric.Object.__uid++,options=applyViewboxTransform(doc),descendants=fabric.util.toArray(doc.getElementsByTagName("*"));options.svgUid=svgUid;if(descendants.length===0&&fabric.isLikelyNode){descendants=doc.selectNodes('//*[name(.)!="svg"]');var arr=[];for(var i=0,len=descendants.length;i\n',' \n \n')}}var reFontDeclaration=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*"+"(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+fabric.reNum+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+fabric.reNum+"))?\\s+(.*)");extend(fabric,{parseFontDeclaration:function(value,oStyle){var match=value.match(reFontDeclaration);if(!match){return}var fontStyle=match[1],fontWeight=match[3],fontSize=match[4],lineHeight=match[5],fontFamily=match[6];if(fontStyle){oStyle.fontStyle=fontStyle}if(fontWeight){oStyle.fontWeight=isNaN(parseFloat(fontWeight))?fontWeight:parseFloat(fontWeight)}if(fontSize){oStyle.fontSize=parseUnit(fontSize)}if(fontFamily){oStyle.fontFamily=fontFamily}if(lineHeight){oStyle.lineHeight=lineHeight==="normal"?1:lineHeight}},getGradientDefs:function(doc){var linearGradientEls=doc.getElementsByTagName("linearGradient"),radialGradientEls=doc.getElementsByTagName("radialGradient"),el,i,j=0,id,xlink,elList=[],gradientDefs={},idsToXlinkMap={};elList.length=linearGradientEls.length+radialGradientEls.length;i=linearGradientEls.length;while(i--){elList[j++]=linearGradientEls[i]}i=radialGradientEls.length;while(i--){elList[j++]=radialGradientEls[i]}while(j--){el=elList[j];xlink=el.getAttribute("xlink:href");id=el.getAttribute("id");if(xlink){idsToXlinkMap[id]=xlink.substr(1)}gradientDefs[id]=el}for(id in idsToXlinkMap){var el2=gradientDefs[idsToXlinkMap[id]].cloneNode(true);el=gradientDefs[id];while(el2.firstChild){el.appendChild(el2.firstChild)}}return gradientDefs},parseAttributes:function(element,attributes,svgUid){if(!element){return}var value,parentAttributes={},fontSize;if(typeof svgUid==="undefined"){svgUid=element.getAttribute("svgUid")}if(element.parentNode&&reAllowedParents.test(element.parentNode.nodeName)){parentAttributes=fabric.parseAttributes(element.parentNode,attributes,svgUid)}fontSize=parentAttributes&&parentAttributes.fontSize||element.getAttribute("font-size")||fabric.Text.DEFAULT_SVG_FONT_SIZE;var ownAttributes=attributes.reduce(function(memo,attr){value=element.getAttribute(attr);if(value){attr=normalizeAttr(attr);value=normalizeValue(attr,value,parentAttributes,fontSize);memo[attr]=value}return memo},{});ownAttributes=extend(ownAttributes,extend(getGlobalStylesForElement(element,svgUid),fabric.parseStyleAttribute(element)));if(ownAttributes.font){fabric.parseFontDeclaration(ownAttributes.font,ownAttributes)}return _setStrokeFillOpacity(extend(parentAttributes,ownAttributes))},parseElements:function(elements,callback,options,reviver){new fabric.ElementsParser(elements,callback,options,reviver).parse()},parseStyleAttribute:function(element){var oStyle={},style=element.getAttribute("style");if(!style){return oStyle}if(typeof style==="string"){parseStyleString(style,oStyle)}else{parseStyleObject(style,oStyle)}return oStyle},parsePointsAttribute:function(points){if(!points){return null}points=points.replace(/,/g," ").trim();points=points.split(/\s+/);var parsedPoints=[],i,len;i=0;len=points.length;for(;i/i,""))}if(!xml||!xml.documentElement){return}fabric.parseSVGDocument(xml.documentElement,function(results,options){svgCache.set(url,{objects:fabric.util.array.invoke(results,"toObject"),options:options});callback(results,options)},reviver)}},loadSVGFromString:function(string,callback,reviver){string=string.trim();var doc;if(typeof DOMParser!=="undefined"){var parser=new DOMParser;if(parser&&parser.parseFromString){doc=parser.parseFromString(string,"text/xml")}}else if(fabric.window.ActiveXObject){doc=new ActiveXObject("Microsoft.XMLDOM");doc.async="false";doc.loadXML(string.replace(//i,""))}fabric.parseSVGDocument(doc.documentElement,function(results,options){callback(results,options)},reviver)},createSVGFontFacesMarkup:function(objects){var markup="",fontList={},obj,fontFamily,style,row,rowIndex,char,charIndex,fontPaths=fabric.fontPaths;for(var i=0,len=objects.length;i',"","\n"].join("")}return markup},createSVGRefElementsMarkup:function(canvas){var markup=[];_createSVGPattern(markup,canvas,"backgroundColor");_createSVGPattern(markup,canvas,"overlayColor");return markup.join("")}})})(typeof exports!=="undefined"?exports:this);fabric.ElementsParser=function(elements,callback,options,reviver){this.elements=elements;this.callback=callback;this.options=options;this.reviver=reviver;this.svgUid=options&&options.svgUid||0};fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length);this.numElements=this.elements.length;this.createObjects()};fabric.ElementsParser.prototype.createObjects=function(){for(var i=0,len=this.elements.length;ithat.x&&this.y>that.y},gte:function(that){return this.x>=that.x&&this.y>=that.y},lerp:function(that,t){return new Point(this.x+(that.x-this.x)*t,this.y+(that.y-this.y)*t)},distanceFrom:function(that){var dx=this.x-that.x,dy=this.y-that.y;return Math.sqrt(dx*dx+dy*dy)},midPointFrom:function(that){return new Point(this.x+(that.x-this.x)/2,this.y+(that.y-this.y)/2)},min:function(that){return new Point(Math.min(this.x,that.x),Math.min(this.y,that.y))},max:function(that){return new Point(Math.max(this.x,that.x),Math.max(this.y,that.y))},toString:function(){return this.x+","+this.y},setXY:function(x,y){this.x=x;this.y=y},setFromPoint:function(that){this.x=that.x;this.y=that.y},swap:function(that){var x=this.x,y=this.y;this.x=that.x;this.y=that.y;that.x=x;that.y=y}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Intersection){fabric.warn("fabric.Intersection is already defined");return}function Intersection(status){this.status=status;this.points=[]}fabric.Intersection=Intersection;fabric.Intersection.prototype={appendPoint:function(point){this.points.push(point)},appendPoints:function(points){this.points=this.points.concat(points)}};fabric.Intersection.intersectLineLine=function(a1,a2,b1,b2){var result,uaT=(b2.x-b1.x)*(a1.y-b1.y)-(b2.y-b1.y)*(a1.x-b1.x),ubT=(a2.x-a1.x)*(a1.y-b1.y)-(a2.y-a1.y)*(a1.x-b1.x),uB=(b2.y-b1.y)*(a2.x-a1.x)-(b2.x-b1.x)*(a2.y-a1.y);if(uB!==0){var ua=uaT/uB,ub=ubT/uB;if(0<=ua&&ua<=1&&0<=ub&&ub<=1){result=new Intersection("Intersection");result.points.push(new fabric.Point(a1.x+ua*(a2.x-a1.x),a1.y+ua*(a2.y-a1.y)))}else{result=new Intersection}}else{if(uaT===0||ubT===0){result=new Intersection("Coincident")}else{result=new Intersection("Parallel")}}return result};fabric.Intersection.intersectLinePolygon=function(a1,a2,points){var result=new Intersection,length=points.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonPolygon=function(points1,points2){var result=new Intersection,length=points1.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonRectangle=function(points,r1,r2){var min=r1.min(r2),max=r1.max(r2),topRight=new fabric.Point(max.x,min.y),bottomLeft=new fabric.Point(min.x,max.y),inter1=Intersection.intersectLinePolygon(min,topRight,points),inter2=Intersection.intersectLinePolygon(topRight,max,points),inter3=Intersection.intersectLinePolygon(max,bottomLeft,points),inter4=Intersection.intersectLinePolygon(bottomLeft,min,points),result=new Intersection;result.appendPoints(inter1.points);result.appendPoints(inter2.points);result.appendPoints(inter3.points);result.appendPoints(inter4.points);if(result.points.length>0){result.status="Intersection"}return result}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Color){fabric.warn("fabric.Color is already defined.");return}function Color(color){if(!color){this.setSource([0,0,0,1])}else{this._tryParsingColor(color)}}fabric.Color=Color;fabric.Color.prototype={_tryParsingColor:function(color){var source;if(color in Color.colorNameMap){color=Color.colorNameMap[color] +}if(color==="transparent"){this.setSource([255,255,255,0]);return}source=Color.sourceFromHex(color);if(!source){source=Color.sourceFromRgb(color)}if(!source){source=Color.sourceFromHsl(color)}if(source){this.setSource(source)}},_rgbToHsl:function(r,g,b){r/=255,g/=255,b/=255;var h,s,l,max=fabric.util.array.max([r,g,b]),min=fabric.util.array.min([r,g,b]);l=(max+min)/2;if(max===min){h=s=0}else{var d=max-min;s=l>.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g1){t-=1}if(t<1/6){return p+(q-p)*6*t}if(t<1/2){return q}if(t<2/3){return p+(q-p)*(2/3-t)*6}return p}fabric.Color.fromRgb=function(color){return Color.fromSource(Color.sourceFromRgb(color))};fabric.Color.sourceFromRgb=function(color){var match=color.match(Color.reRGBa);if(match){var r=parseInt(match[1],10)/(/%$/.test(match[1])?100:1)*(/%$/.test(match[1])?255:1),g=parseInt(match[2],10)/(/%$/.test(match[2])?100:1)*(/%$/.test(match[2])?255:1),b=parseInt(match[3],10)/(/%$/.test(match[3])?100:1)*(/%$/.test(match[3])?255:1);return[parseInt(r,10),parseInt(g,10),parseInt(b,10),match[4]?parseFloat(match[4]):1]}};fabric.Color.fromRgba=Color.fromRgb;fabric.Color.fromHsl=function(color){return Color.fromSource(Color.sourceFromHsl(color))};fabric.Color.sourceFromHsl=function(color){var match=color.match(Color.reHSLa);if(!match){return}var h=(parseFloat(match[1])%360+360)%360/360,s=parseFloat(match[2])/(/%$/.test(match[2])?100:1),l=parseFloat(match[3])/(/%$/.test(match[3])?100:1),r,g,b;if(s===0){r=g=b=l}else{var q=l<=.5?l*(s+1):l+s-l*s,p=l*2-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3)}return[Math.round(r*255),Math.round(g*255),Math.round(b*255),match[4]?parseFloat(match[4]):1]};fabric.Color.fromHsla=Color.fromHsl;fabric.Color.fromHex=function(color){return Color.fromSource(Color.sourceFromHex(color))};fabric.Color.sourceFromHex=function(color){if(color.match(Color.reHex)){var value=color.slice(color.indexOf("#")+1),isShortNotation=value.length===3,r=isShortNotation?value.charAt(0)+value.charAt(0):value.substring(0,2),g=isShortNotation?value.charAt(1)+value.charAt(1):value.substring(2,4),b=isShortNotation?value.charAt(2)+value.charAt(2):value.substring(4,6);return[parseInt(r,16),parseInt(g,16),parseInt(b,16),1]}};fabric.Color.fromSource=function(source){var oColor=new Color;oColor.setSource(source);return oColor}})(typeof exports!=="undefined"?exports:this);(function(){function getColorStop(el){var style=el.getAttribute("style"),offset=el.getAttribute("offset")||0,color,colorAlpha,opacity;offset=parseFloat(offset)/(/%$/.test(offset)?100:1);offset=offset<0?0:offset>1?1:offset;if(style){var keyValuePairs=style.split(/\s*;\s*/);if(keyValuePairs[keyValuePairs.length-1]===""){keyValuePairs.pop()}for(var i=keyValuePairs.length;i--;){var split=keyValuePairs[i].split(/\s*:\s*/),key=split[0].trim(),value=split[1].trim();if(key==="stop-color"){color=value}else if(key==="stop-opacity"){opacity=value}}}if(!color){color=el.getAttribute("stop-color")||"rgb(0,0,0)"}if(!opacity){opacity=el.getAttribute("stop-opacity")}color=new fabric.Color(color);colorAlpha=color.getAlpha();opacity=isNaN(parseFloat(opacity))?1:parseFloat(opacity);opacity*=colorAlpha;return{offset:offset,color:color.toRgb(),opacity:opacity}}function getLinearCoords(el){return{x1:el.getAttribute("x1")||0,y1:el.getAttribute("y1")||0,x2:el.getAttribute("x2")||"100%",y2:el.getAttribute("y2")||0}}function getRadialCoords(el){return{x1:el.getAttribute("fx")||el.getAttribute("cx")||"50%",y1:el.getAttribute("fy")||el.getAttribute("cy")||"50%",r1:0,x2:el.getAttribute("cx")||"50%",y2:el.getAttribute("cy")||"50%",r2:el.getAttribute("r")||"50%"}}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(options){options||(options={});var coords={};this.id=fabric.Object.__uid++;this.type=options.type||"linear";coords={x1:options.coords.x1||0,y1:options.coords.y1||0,x2:options.coords.x2||0,y2:options.coords.y2||0};if(this.type==="radial"){coords.r1=options.coords.r1||0;coords.r2=options.coords.r2||0}this.coords=coords;this.colorStops=options.colorStops.slice();if(options.gradientTransform){this.gradientTransform=options.gradientTransform}this.offsetX=options.offsetX||this.offsetX;this.offsetY=options.offsetY||this.offsetY},addColorStop:function(colorStop){for(var position in colorStop){var color=new fabric.Color(colorStop[position]);this.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform}},toSVG:function(object){var coords=fabric.util.object.clone(this.coords),markup,commonAttributes;this.colorStops.sort(function(a,b){return a.offset-b.offset});if(!(object.group&&object.group.type==="path-group")){for(var prop in coords){if(prop==="x1"||prop==="x2"||prop==="r2"){coords[prop]+=this.offsetX-object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=this.offsetY-object.height/2}}}commonAttributes='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"';if(this.gradientTransform){commonAttributes+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '}if(this.type==="linear"){markup=["\n']}else if(this.type==="radial"){markup=["\n']}for(var i=0;i\n')}markup.push(this.type==="linear"?"\n":"\n");return markup.join("")},toLive:function(ctx,object){var gradient,prop,coords=fabric.util.object.clone(this.coords);if(!this.type){return}if(object.group&&object.group.type==="path-group"){for(prop in coords){if(prop==="x1"||prop==="x2"){coords[prop]+=-this.offsetX+object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=-this.offsetY+object.height/2}}}if(this.type==="linear"){gradient=ctx.createLinearGradient(coords.x1,coords.y1,coords.x2,coords.y2)}else if(this.type==="radial"){gradient=ctx.createRadialGradient(coords.x1,coords.y1,coords.r1,coords.x2,coords.y2,coords.r2)}for(var i=0,len=this.colorStops.length;i\n'+'\n'+"\n"},toLive:function(ctx){var source=typeof this.source==="function"?this.source():this.source;if(!source){return""}if(typeof source.src!=="undefined"){if(!source.complete){return""}if(source.naturalWidth===0||source.naturalHeight===0){return""}}return ctx.createPattern(source,this.repeat)}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),toFixed=fabric.util.toFixed;if(fabric.Shadow){fabric.warn("fabric.Shadow is already defined.");return}fabric.Shadow=fabric.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:false,includeDefaultValues:true,initialize:function(options){if(typeof options==="string"){options=this._parseShadow(options)}for(var prop in options){this[prop]=options[prop]}this.id=fabric.Object.__uid++},_parseShadow:function(shadow){var shadowStr=shadow.trim(),offsetsAndBlur=fabric.Shadow.reOffsetsAndBlur.exec(shadowStr)||[],color=shadowStr.replace(fabric.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:color.trim(),offsetX:parseInt(offsetsAndBlur[1],10)||0,offsetY:parseInt(offsetsAndBlur[2],10)||0,blur:parseInt(offsetsAndBlur[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(object){var fBoxX=40,fBoxY=40,NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,offset=fabric.util.rotateVector({x:this.offsetX,y:this.offsetY},fabric.util.degreesToRadians(-object.angle)),BLUR_BOX=20;if(object.width&&object.height){fBoxX=toFixed((Math.abs(offset.x)+this.blur)/object.width,NUM_FRACTION_DIGITS)*100+BLUR_BOX;fBoxY=toFixed((Math.abs(offset.y)+this.blur)/object.height,NUM_FRACTION_DIGITS)*100+BLUR_BOX}if(object.flipX){offset.x*=-1}if(object.flipY){offset.y*=-1}return'\n"+' \n'+' \n'+' \n'+' \n'+" \n"+" \n"+' \n'+" \n"+"\n"},toObject:function(){if(this.includeDefaultValues){return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke}}var obj={},proto=fabric.Shadow.prototype;["color","blur","offsetX","offsetY","affectStroke"].forEach(function(prop){if(this[prop]!==proto[prop]){obj[prop]=this[prop]}},this);return obj}});fabric.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/})(typeof exports!=="undefined"?exports:this);(function(){"use strict";if(fabric.StaticCanvas){fabric.warn("fabric.StaticCanvas is already defined.");return}var extend=fabric.util.object.extend,getElementOffset=fabric.util.getElementOffset,removeFromArray=fabric.util.removeFromArray,toFixed=fabric.util.toFixed,CANVAS_INIT_ERROR=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(el,options){options||(options={});this._initStatic(el,options)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:true,stateful:true,renderOnAddRemove:true,clipTo:null,controlsAboveOverlay:false,allowTouchScrolling:false,imageSmoothingEnabled:true,preserveObjectStacking:false,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},enableRetinaScaling:true,_initStatic:function(el,options){this._objects=[];this._createLowerCanvas(el);this._initOptions(options);this._setImageSmoothing();if(!this.interactive){this._initRetinaScaling()}if(options.overlayImage){this.setOverlayImage(options.overlayImage,this.renderAll.bind(this))}if(options.backgroundImage){this.setBackgroundImage(options.backgroundImage,this.renderAll.bind(this))}if(options.backgroundColor){this.setBackgroundColor(options.backgroundColor,this.renderAll.bind(this))}if(options.overlayColor){this.setOverlayColor(options.overlayColor,this.renderAll.bind(this))}this.calcOffset()},_isRetinaScaling:function(){return fabric.devicePixelRatio!==1&&this.enableRetinaScaling},_initRetinaScaling:function(){if(!this._isRetinaScaling()){return}this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio);this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio);this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio)},calcOffset:function(){this._offset=getElementOffset(this.lowerCanvasEl);return this},setOverlayImage:function(image,callback,options){return this.__setBgOverlayImage("overlayImage",image,callback,options)},setBackgroundImage:function(image,callback,options){return this.__setBgOverlayImage("backgroundImage",image,callback,options)},setOverlayColor:function(overlayColor,callback){return this.__setBgOverlayColor("overlayColor",overlayColor,callback)},setBackgroundColor:function(backgroundColor,callback){return this.__setBgOverlayColor("backgroundColor",backgroundColor,callback)},_setImageSmoothing:function(){var ctx=this.getContext();ctx.imageSmoothingEnabled=ctx.imageSmoothingEnabled||ctx.webkitImageSmoothingEnabled||ctx.mozImageSmoothingEnabled||ctx.msImageSmoothingEnabled||ctx.oImageSmoothingEnabled;ctx.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(property,image,callback,options){if(typeof image==="string"){fabric.util.loadImage(image,function(img){this[property]=new fabric.Image(img,options);callback&&callback(img)},this,options&&options.crossOrigin)}else{options&&image.setOptions(options);this[property]=image;callback&&callback(image)}return this},__setBgOverlayColor:function(property,color,callback){if(color&&color.source){var _this=this;fabric.util.loadImage(color.source,function(img){_this[property]=new fabric.Pattern({source:img,repeat:color.repeat,offsetX:color.offsetX,offsetY:color.offsetY});callback&&callback()})}else{this[property]=color;callback&&callback()}return this},_createCanvasElement:function(){var element=fabric.document.createElement("canvas");if(!element.style){element.style={}}if(!element){throw CANVAS_INIT_ERROR}this._initCanvasElement(element);return element},_initCanvasElement:function(element){fabric.util.createCanvasElement(element);if(typeof element.getContext==="undefined"){throw CANVAS_INIT_ERROR}},_initOptions:function(options){for(var prop in options){this[prop]=options[prop]}this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0;this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0;if(!this.lowerCanvasEl.style){return}this.lowerCanvasEl.width=this.width;this.lowerCanvasEl.height=this.height;this.lowerCanvasEl.style.width=this.width+"px";this.lowerCanvasEl.style.height=this.height+"px";this.viewportTransform=this.viewportTransform.slice()},_createLowerCanvas:function(canvasEl){this.lowerCanvasEl=fabric.util.getById(canvasEl)||this._createCanvasElement();this._initCanvasElement(this.lowerCanvasEl);fabric.util.addClass(this.lowerCanvasEl,"lower-canvas");if(this.interactive){this._applyCanvasStyle(this.lowerCanvasEl)}this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(value,options){return this.setDimensions({width:value},options)},setHeight:function(value,options){return this.setDimensions({height:value},options)},setDimensions:function(dimensions,options){var cssValue;options=options||{};for(var prop in dimensions){cssValue=dimensions[prop];if(!options.cssOnly){this._setBackstoreDimension(prop,dimensions[prop]);cssValue+="px"}if(!options.backstoreOnly){this._setCssDimension(prop,cssValue)}}this._initRetinaScaling();this._setImageSmoothing();this.calcOffset();if(!options.cssOnly){this.renderAll()}return this},_setBackstoreDimension:function(prop,value){this.lowerCanvasEl[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl[prop]=value}if(this.cacheCanvasEl){this.cacheCanvasEl[prop]=value}this[prop]=value;return this},_setCssDimension:function(prop,value){this.lowerCanvasEl.style[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl.style[prop]=value}if(this.wrapperEl){this.wrapperEl.style[prop]=value}return this},getZoom:function(){return Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(vpt){var activeGroup=this.getActiveGroup();this.viewportTransform=vpt;this.renderAll();for(var i=0,len=this._objects.length;i");return markup.join("")},_setSVGPreamble:function(markup,options){if(options.suppressPreamble){return}markup.push('\n','\n')},_setSVGHeader:function(markup,options){var width=options.width||this.width,height=options.height||this.height,vpt,viewBox='viewBox="0 0 '+this.width+" "+this.height+'" ',NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;if(options.viewBox){viewBox='viewBox="'+options.viewBox.x+" "+options.viewBox.y+" "+options.viewBox.width+" "+options.viewBox.height+'" '}else{if(this.svgViewportTransformation){vpt=this.viewportTransform;viewBox='viewBox="'+toFixed(-vpt[4]/vpt[0],NUM_FRACTION_DIGITS)+" "+toFixed(-vpt[5]/vpt[3],NUM_FRACTION_DIGITS)+" "+toFixed(this.width/vpt[0],NUM_FRACTION_DIGITS)+" "+toFixed(this.height/vpt[3],NUM_FRACTION_DIGITS)+'" '}}markup.push("\n',"Created with Fabric.js ",fabric.version,"\n","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"\n")},_setSVGObjects:function(markup,reviver){for(var i=0,objects=this.getObjects(),len=objects.length;i\n")}else if(this[property]&&property==="overlayColor"){markup.push('\n")}},sendToBack:function(object){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=objs.length;i--;){obj=objs[i];removeFromArray(this._objects,obj); +this._objects.unshift(obj)}}else{removeFromArray(this._objects,object);this._objects.unshift(object)}return this.renderAll&&this.renderAll()},bringToFront:function(object){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=0;i=0;--i){var isIntersecting=object.intersectsWithObject(this._objects[i])||object.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(object);if(isIntersecting){newIdx=i;break}}}else{newIdx=idx-1}return newIdx},bringForward:function(object,intersecting){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,idx,newIdx,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=objs.length;i--;){obj=objs[i];idx=this._objects.indexOf(obj);if(idx!==this._objects.length-1){newIdx=idx+1;removeFromArray(this._objects,obj);this._objects.splice(newIdx,0,obj)}}}else{idx=this._objects.indexOf(object);if(idx!==this._objects.length-1){newIdx=this._findNewUpperIndex(object,idx,intersecting);removeFromArray(this._objects,object);this._objects.splice(newIdx,0,object)}}this.renderAll&&this.renderAll();return this},_findNewUpperIndex:function(object,idx,intersecting){var newIdx;if(intersecting){newIdx=idx;for(var i=idx+1;i"}});extend(fabric.StaticCanvas.prototype,fabric.Observable);extend(fabric.StaticCanvas.prototype,fabric.Collection);extend(fabric.StaticCanvas.prototype,fabric.DataURLExporter);extend(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(methodName){var el=fabric.util.createCanvasElement();if(!el||!el.getContext){return null}var ctx=el.getContext("2d");if(!ctx){return null}switch(methodName){case"getImageData":return typeof ctx.getImageData!=="undefined";case"setLineDash":return typeof ctx.setLineDash!=="undefined";case"toDataURL":return typeof el.toDataURL!=="undefined";case"toDataURLWithQuality":try{el.toDataURL("image/jpeg",0);return true}catch(e){}return false;default:return null}}});fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject})();fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeDashArray:null,setShadow:function(options){this.shadow=new fabric.Shadow(options);return this},_setBrushStyles:function(){var ctx=this.canvas.contextTop;ctx.strokeStyle=this.color;ctx.lineWidth=this.width;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;if(this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")){ctx.setLineDash(this.strokeDashArray)}},_setShadow:function(){if(!this.shadow){return}var ctx=this.canvas.contextTop;ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur;ctx.shadowOffsetX=this.shadow.offsetX;ctx.shadowOffsetY=this.shadow.offsetY},_resetShadow:function(){var ctx=this.canvas.contextTop;ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0}});(function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(canvas){this.canvas=canvas;this._points=[]},onMouseDown:function(pointer){this._prepareForDrawing(pointer);this._captureDrawingPath(pointer);this._render()},onMouseMove:function(pointer){this._captureDrawingPath(pointer);this.canvas.clearContext(this.canvas.contextTop);this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(pointer){var p=new fabric.Point(pointer.x,pointer.y);this._reset();this._addPoint(p);this.canvas.contextTop.moveTo(p.x,p.y)},_addPoint:function(point){this._points.push(point)},_reset:function(){this._points.length=0;this._setBrushStyles();this._setShadow()},_captureDrawingPath:function(pointer){var pointerPoint=new fabric.Point(pointer.x,pointer.y);this._addPoint(pointerPoint)},_render:function(){var ctx=this.canvas.contextTop,v=this.canvas.viewportTransform,p1=this._points[0],p2=this._points[1];ctx.save();ctx.transform(v[0],v[1],v[2],v[3],v[4],v[5]);ctx.beginPath();if(this._points.length===2&&p1.x===p2.x&&p1.y===p2.y){p1.x-=.5;p2.x+=.5}ctx.moveTo(p1.x,p1.y);for(var i=1,len=this._points.length;i0?1:-1;if(by==="y"){skew=t.target.skewY;originA="top";originB="bottom";property="originY"}origins[-1]=originA;origins[1]=originB;t.target.flipX&&(flipSign*=-1);t.target.flipY&&(flipSign*=-1);if(skew===0){t.skewSign=-corner*mouseMove*flipSign;t[property]=origins[-mouseMove]}else{skew=skew>0?1:-1;t.skewSign=skew;t[property]=origins[skew*corner*flipSign]}},_skewObject:function(x,y,by){var t=this._currentTransform,target=t.target,skewed=false,lockSkewingX=target.get("lockSkewingX"),lockSkewingY=target.get("lockSkewingY");if(lockSkewingX&&by==="x"||lockSkewingY&&by==="y"){return false}var center=target.getCenterPoint(),actualMouseByCenter=target.toLocalPoint(new fabric.Point(x,y),"center","center")[by],lastMouseByCenter=target.toLocalPoint(new fabric.Point(t.lastX,t.lastY),"center","center")[by],actualMouseByOrigin,constraintPosition,dim=target._getTransformedDimensions();this._changeSkewTransformOrigin(actualMouseByCenter-lastMouseByCenter,t,by);actualMouseByOrigin=target.toLocalPoint(new fabric.Point(x,y),t.originX,t.originY)[by],constraintPosition=target.translateToOriginPoint(center,t.originX,t.originY);skewed=this._setObjectSkew(actualMouseByOrigin,t,by,dim);t.lastX=x;t.lastY=y;target.setPositionByOrigin(constraintPosition,t.originX,t.originY);return skewed},_setObjectSkew:function(localMouse,transform,by,_dim){var target=transform.target,newValue,skewed=false,skewSign=transform.skewSign,newDim,dimNoSkew,otherBy,_otherBy,_by,newDimMouse,skewX,skewY;if(by==="x"){otherBy="y";_otherBy="Y";_by="X";skewX=0;skewY=target.skewY}else{otherBy="x";_otherBy="X";_by="Y";skewX=target.skewX;skewY=0}dimNoSkew=target._getTransformedDimensions(skewX,skewY);newDimMouse=2*Math.abs(localMouse)-dimNoSkew[by];if(newDimMouse<=2){newValue=0}else{newValue=skewSign*Math.atan(newDimMouse/target["scale"+_by]/(dimNoSkew[otherBy]/target["scale"+_otherBy]));newValue=fabric.util.radiansToDegrees(newValue)}skewed=target["skew"+_by]!==newValue;target.set("skew"+_by,newValue);if(target["skew"+_otherBy]!==0){newDim=target._getTransformedDimensions();newValue=_dim[otherBy]/newDim[otherBy]*target["scale"+_otherBy];target.set("scale"+_otherBy,newValue)}return skewed},_scaleObject:function(x,y,by){var t=this._currentTransform,target=t.target,lockScalingX=target.get("lockScalingX"),lockScalingY=target.get("lockScalingY"),lockScalingFlip=target.get("lockScalingFlip");if(lockScalingX&&lockScalingY){return false}var constraintPosition=target.translateToOriginPoint(target.getCenterPoint(),t.originX,t.originY),localMouse=target.toLocalPoint(new fabric.Point(x,y),t.originX,t.originY),dim=target._getTransformedDimensions(),scaled=false;this._setLocalMouse(localMouse,t);scaled=this._setObjectScale(localMouse,t,lockScalingX,lockScalingY,by,lockScalingFlip,dim);target.setPositionByOrigin(constraintPosition,t.originX,t.originY);return scaled},_setObjectScale:function(localMouse,transform,lockScalingX,lockScalingY,by,lockScalingFlip,_dim){var target=transform.target,forbidScalingX=false,forbidScalingY=false,scaled=false,changeX,changeY,scaleX,scaleY;scaleX=localMouse.x*target.scaleX/_dim.x;scaleY=localMouse.y*target.scaleY/_dim.y;changeX=target.scaleX!==scaleX;changeY=target.scaleY!==scaleY;if(lockScalingFlip&&scaleX<=0&&scaleXtarget.padding){if(localMouse.x<0){localMouse.x+=target.padding}else{localMouse.x-=target.padding}}else{localMouse.x=0}if(abs(localMouse.y)>target.padding){if(localMouse.y<0){localMouse.y+=target.padding}else{localMouse.y-=target.padding}}else{localMouse.y=0}},_rotateObject:function(x,y){var t=this._currentTransform;if(t.target.get("lockRotation")){return false}var lastAngle=atan2(t.ey-t.top,t.ex-t.left),curAngle=atan2(y-t.top,x-t.left),angle=radiansToDegrees(curAngle-lastAngle+t.theta);if(angle<0){angle=360+angle}t.target.angle=angle%360;return true},setCursor:function(value){this.upperCanvasEl.style.cursor=value},_resetObjectTransform:function(target){target.scaleX=1;target.scaleY=1;target.skewX=0;target.skewY=0;target.setAngle(0)},_drawSelection:function(){var ctx=this.contextTop,groupSelector=this._groupSelector,left=groupSelector.left,top=groupSelector.top,aleft=abs(left),atop=abs(top);ctx.fillStyle=this.selectionColor;ctx.fillRect(groupSelector.ex-(left>0?0:-left),groupSelector.ey-(top>0?0:-top),aleft,atop);ctx.lineWidth=this.selectionLineWidth;ctx.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var px=groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),py=groupSelector.ey+STROKE_OFFSET-(top>0?0:atop);ctx.beginPath();fabric.util.drawDashedLine(ctx,px,py,px+aleft,py,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py+atop-1,px+aleft,py+atop-1,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py,px,py+atop,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px+aleft-1,py,px+aleft-1,py+atop,this.selectionDashArray);ctx.closePath();ctx.stroke()}else{ctx.strokeRect(groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),groupSelector.ey+STROKE_OFFSET-(top>0?0:atop),aleft,atop)}},_isLastRenderedObject:function(e){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e,true))},findTarget:function(e,skipGroup){if(this.skipTargetFind){return}if(this._isLastRenderedObject(e)){return this.lastRenderedObjectWithControlsAboveOverlay}var activeGroup=this.getActiveGroup();if(!skipGroup&&this._checkTarget(e,activeGroup,this.getPointer(e,true))){return activeGroup}var target=this._searchPossibleTargets(e,skipGroup);this._fireOverOutEvents(target,e);return target},_fireOverOutEvents:function(target,e){if(target){if(this._hoveredTarget!==target){if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget,e:e});this._hoveredTarget.fire("mouseout")}this.fire("mouse:over",{target:target,e:e});target.fire("mouseover");this._hoveredTarget=target}}else if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget,e:e});this._hoveredTarget.fire("mouseout");this._hoveredTarget=null}},_checkTarget:function(e,obj,pointer){if(obj&&obj.visible&&obj.evented&&this.containsPoint(e,obj)){if((this.perPixelTargetFind||obj.perPixelTargetFind)&&!obj.isEditing){var isTransparent=this.isTargetTransparent(obj,pointer.x,pointer.y);if(!isTransparent){return true}}else{return true}}},_searchPossibleTargets:function(e,skipGroup){var target,pointer=this.getPointer(e,true),i=this._objects.length;while(i--){if((!this._objects[i].group||skipGroup)&&this._checkTarget(e,this._objects[i],pointer)){this.relatedTarget=this._objects[i];target=this._objects[i];break}}return target},getPointer:function(e,ignoreZoom,upperCanvasEl){if(!upperCanvasEl){upperCanvasEl=this.upperCanvasEl}var pointer=getPointer(e),bounds=upperCanvasEl.getBoundingClientRect(),boundsWidth=bounds.width||0,boundsHeight=bounds.height||0,cssScale;if(!boundsWidth||!boundsHeight){if("top"in bounds&&"bottom"in bounds){boundsHeight=Math.abs(bounds.top-bounds.bottom)}if("right"in bounds&&"left"in bounds){boundsWidth=Math.abs(bounds.right-bounds.left)}}this.calcOffset();pointer.x=pointer.x-this._offset.left;pointer.y=pointer.y-this._offset.top;if(!ignoreZoom){pointer=fabric.util.transformPoint(pointer,fabric.util.invertTransform(this.viewportTransform))}if(boundsWidth===0||boundsHeight===0){cssScale={width:1,height:1}}else{cssScale={width:upperCanvasEl.width/boundsWidth,height:upperCanvasEl.height/boundsHeight}}return{x:pointer.x*cssScale.width,y:pointer.y*cssScale.height}},_createUpperCanvas:function(){var lowerCanvasClass=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement();fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+lowerCanvasClass);this.wrapperEl.appendChild(this.upperCanvasEl);this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl);this._applyCanvasStyle(this.upperCanvasEl);this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement();this.cacheCanvasEl.setAttribute("width",this.width);this.cacheCanvasEl.setAttribute("height",this.height);this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{"class":this.containerClass});fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+"px",height:this.getHeight()+"px",position:"relative"});fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(element){var width=this.getWidth()||element.width,height=this.getHeight()||element.height;fabric.util.setStyle(element,{position:"absolute",width:width+"px",height:height+"px",left:0,top:0});element.width=width;element.height=height;fabric.util.makeElementUnselectable(element)},_copyCanvasStyle:function(fromEl,toEl){toEl.style.cssText=fromEl.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(object){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=object;object.set("active",true)},setActiveObject:function(object,e){this._setActiveObject(object);this.renderAll();this.fire("object:selected",{target:object,e:e});object.fire("selected",{e:e});return this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=null},discardActiveObject:function(e){this._discardActiveObject();this.renderAll();this.fire("selection:cleared",{e:e});return this},_setActiveGroup:function(group){this._activeGroup=group;if(group){group.set("active",true)}},setActiveGroup:function(group,e){this._setActiveGroup(group);if(group){this.fire("object:selected",{target:group,e:e});group.fire("selected",{e:e})}return this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var g=this.getActiveGroup();if(g){g.destroy()}this.setActiveGroup(null)},discardActiveGroup:function(e){this._discardActiveGroup();this.fire("selection:cleared",{e:e});return this},deactivateAll:function(){var allObjects=this.getObjects(),i=0,len=allObjects.length;for(;i1){return}var groupSelector=this._groupSelector;if(groupSelector){pointer=this.getPointer(e,true);groupSelector.left=pointer.x-groupSelector.ex;groupSelector.top=pointer.y-groupSelector.ey;this.renderTop()}else if(!this._currentTransform){target=this.findTarget(e);if(!target||target&&!target.selectable){this.setCursor(this.defaultCursor)}else{this._setCursorFromEvent(e,target)}}else{this._transformObject(e)}this.fire("mouse:move",{target:target,e:e});target&&target.fire("mousemove",{e:e})},_transformObject:function(e){var pointer=this.getPointer(e),transform=this._currentTransform;transform.reset=false,transform.target.isMoving=true;this._beforeScaleTransform(e,transform);this._performTransformAction(e,transform,pointer);this.renderAll()},_performTransformAction:function(e,transform,pointer){var x=pointer.x,y=pointer.y,target=transform.target,action=transform.action,actionPerformed=false;if(action==="rotate"){(actionPerformed=this._rotateObject(x,y))&&this._fire("rotating",target,e)}else if(action==="scale"){(actionPerformed=this._onScale(e,transform,x,y))&&this._fire("scaling",target,e)}else if(action==="scaleX"){(actionPerformed=this._scaleObject(x,y,"x"))&&this._fire("scaling",target,e)}else if(action==="scaleY"){(actionPerformed=this._scaleObject(x,y,"y"))&&this._fire("scaling",target,e)}else if(action==="skewX"){(actionPerformed=this._skewObject(x,y,"x"))&&this._fire("skewing",target,e)}else if(action==="skewY"){(actionPerformed=this._skewObject(x,y,"y"))&&this._fire("skewing",target,e)}else{(actionPerformed=this._translateObject(x,y))&&this._fire("moving",target,e);this.setCursor(this.moveCursor)}transform.actionPerformed=actionPerformed},_fire:function(eventName,target,e){this.fire("object:"+eventName,{target:target,e:e});target.fire(eventName,{e:e})},_beforeScaleTransform:function(e,transform){if(transform.action==="scale"||transform.action==="scaleX"||transform.action==="scaleY"){var centerTransform=this._shouldCenterTransform(transform.target);if(centerTransform&&(transform.originX!=="center"||transform.originY!=="center")||!centerTransform&&transform.originX==="center"&&transform.originY==="center"){this._resetCurrentTransform();transform.reset=true}}},_onScale:function(e,transform,x,y){if((e.shiftKey||this.uniScaleTransform)&&!transform.target.get("lockUniScaling")){transform.currentAction="scale";return this._scaleObject(x,y)}else{if(!transform.reset&&transform.currentAction==="scale"){this._resetCurrentTransform()}transform.currentAction="scaleEqually";return this._scaleObject(x,y,"equally")}},_setCursorFromEvent:function(e,target){if(!target||!target.selectable){this.setCursor(this.defaultCursor);return false}else{var activeGroup=this.getActiveGroup(),corner=target._findTargetCorner&&(!activeGroup||!activeGroup.contains(target))&&target._findTargetCorner(this.getPointer(e,true));if(!corner){this.setCursor(target.hoverCursor||this.hoverCursor)}else{this._setCornerCursor(corner,target,e)}}return true},_setCornerCursor:function(corner,target,e){if(corner in cursorOffset){this.setCursor(this._getRotatedCornerCursor(corner,target,e))}else if(corner==="mtr"&&target.hasRotatingPoint){this.setCursor(this.rotationCursor)}else{this.setCursor(this.defaultCursor);return false}},_getRotatedCornerCursor:function(corner,target,e){var n=Math.round(target.getAngle()%360/45);if(n<0){n+=8}n+=cursorOffset[corner];if(e.shiftKey&&cursorOffset[corner]%2===0){n+=2}n%=8;return this.cursorMap[n]}})})();(function(){var min=Math.min,max=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(e,target){var activeObject=this.getActiveObject();return e.shiftKey&&target&&target.selectable&&(this.getActiveGroup()||activeObject&&activeObject!==target)&&this.selection},_handleGrouping:function(e,target){if(target===this.getActiveGroup()){target=this.findTarget(e,true);if(!target||target.isType("group")){return}}if(this.getActiveGroup()){this._updateActiveGroup(target,e)}else{this._createActiveGroup(target,e)}if(this._activeGroup){this._activeGroup.saveCoords()}},_updateActiveGroup:function(target,e){var activeGroup=this.getActiveGroup();if(activeGroup.contains(target)){activeGroup.removeWithUpdate(target);target.set("active",false);if(activeGroup.size()===1){this.discardActiveGroup(e);this.setActiveObject(activeGroup.item(0));return}}else{activeGroup.addWithUpdate(target)}this.fire("selection:created",{target:activeGroup,e:e});activeGroup.set("active",true)},_createActiveGroup:function(target,e){if(this._activeObject&&target!==this._activeObject){var group=this._createGroup(target);group.addWithUpdate();this.setActiveGroup(group);this._activeObject=null;this.fire("selection:created",{target:group,e:e})}target.set("active",true)},_createGroup:function(target){var objects=this.getObjects(),isActiveLower=objects.indexOf(this._activeObject)1){group=new fabric.Group(group.reverse(),{canvas:this});group.addWithUpdate();this.setActiveGroup(group,e);group.saveCoords();this.fire("selection:created",{target:group});this.renderAll()}},_collectObjects:function(){var group=[],currentObject,x1=this._groupSelector.ex,y1=this._groupSelector.ey,x2=x1+this._groupSelector.left,y2=y1+this._groupSelector.top,selectionX1Y1=new fabric.Point(min(x1,x2),min(y1,y2)),selectionX2Y2=new fabric.Point(max(x1,x2),max(y1,y2)),isClick=x1===x2&&y1===y2;for(var i=this._objects.length;i--;){currentObject=this._objects[i];if(!currentObject||!currentObject.selectable||!currentObject.visible){continue}if(currentObject.intersectsWithRect(selectionX1Y1,selectionX2Y2)||currentObject.isContainedWithinRect(selectionX1Y1,selectionX2Y2)||currentObject.containsPoint(selectionX1Y1)||currentObject.containsPoint(selectionX2Y2)){currentObject.set("active",true);group.push(currentObject);if(isClick){break}}}return group},_maybeGroupObjects:function(e){if(this.selection&&this._groupSelector){this._groupSelectedObjects(e)}var activeGroup=this.getActiveGroup();if(activeGroup){activeGroup.setObjectsCoords().setCoords();activeGroup.isMoving=false;this.setCursor(this.defaultCursor)}this._groupSelector=null;this._currentTransform=null}})})();fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(options){options||(options={});var format=options.format||"png",quality=options.quality||1,multiplier=options.multiplier||1,cropping={left:options.left,top:options.top,width:options.width,height:options.height};if(this._isRetinaScaling()){multiplier*=fabric.devicePixelRatio}if(multiplier!==1){return this.__toDataURLWithMultiplier(format,quality,cropping,multiplier)}else{return this.__toDataURL(format,quality,cropping)}},__toDataURL:function(format,quality,cropping){this.renderAll();var canvasEl=this.contextContainer.canvas,croppedCanvasEl=this.__getCroppedCanvas(canvasEl,cropping);if(format==="jpg"){format="jpeg"}var data=fabric.StaticCanvas.supports("toDataURLWithQuality")?(croppedCanvasEl||canvasEl).toDataURL("image/"+format,quality):(croppedCanvasEl||canvasEl).toDataURL("image/"+format);if(croppedCanvasEl){croppedCanvasEl=null}return data},__getCroppedCanvas:function(canvasEl,cropping){var croppedCanvasEl,croppedCtx,shouldCrop="left"in cropping||"top"in cropping||"width"in cropping||"height"in cropping;if(shouldCrop){croppedCanvasEl=fabric.util.createCanvasElement();croppedCtx=croppedCanvasEl.getContext("2d");croppedCanvasEl.width=cropping.width||this.width;croppedCanvasEl.height=cropping.height||this.height;croppedCtx.drawImage(canvasEl,-cropping.left||0,-cropping.top||0)}return croppedCanvasEl},__toDataURLWithMultiplier:function(format,quality,cropping,multiplier){var origWidth=this.getWidth(),origHeight=this.getHeight(),scaledWidth=origWidth*multiplier,scaledHeight=origHeight*multiplier,activeObject=this.getActiveObject(),activeGroup=this.getActiveGroup(),ctx=this.contextContainer;if(multiplier>1){this.setDimensions({width:scaledWidth,height:scaledHeight})}ctx.save();ctx.scale(multiplier/fabric.devicePixelRatio,multiplier/fabric.devicePixelRatio);if(cropping.left){cropping.left*=multiplier}if(cropping.top){cropping.top*=multiplier}if(cropping.width){cropping.width*=multiplier}else if(multiplier<1){cropping.width=scaledWidth}if(cropping.height){cropping.height*=multiplier}else if(multiplier<1){cropping.height=scaledHeight}if(activeGroup){this._tempRemoveBordersControlsFromGroup(activeGroup)}else if(activeObject&&this.deactivateAll){this.deactivateAll()}var data=this.__toDataURL(format,quality,cropping);this.width=origWidth;this.height=origHeight;this.setDimensions({width:origWidth,height:origHeight});if(activeGroup){this._restoreBordersControlsOnGroup(activeGroup)}else if(activeObject&&this.setActiveObject){this.setActiveObject(activeObject)}this.contextTop&&this.clearContext(this.contextTop);this.renderAll();return data},toDataURLWithMultiplier:function(format,multiplier,quality){return this.toDataURL({format:format,multiplier:multiplier,quality:quality})},_tempRemoveBordersControlsFromGroup:function(group){group.origHasControls=group.hasControls;group.origBorderColor=group.borderColor;group.hasControls=true;group.borderColor="rgba(0,0,0,0)";group.forEachObject(function(o){o.origBorderColor=o.borderColor;o.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(group){group.hideControls=group.origHideControls;group.borderColor=group.origBorderColor;group.forEachObject(function(o){o.borderColor=o.origBorderColor;delete o.origBorderColor})}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(json,callback,reviver){return this.loadFromJSON(json,callback,reviver)},loadFromJSON:function(json,callback,reviver){if(!json){return}var serialized=typeof json==="string"?JSON.parse(json):json;this.clear();var _this=this;this._enlivenObjects(serialized.objects,function(){_this._setBgOverlay(serialized,callback)},reviver);return this},_setBgOverlay:function(serialized,callback){var _this=this,loaded={backgroundColor:false,overlayColor:false,backgroundImage:false,overlayImage:false};if(!serialized.backgroundImage&&!serialized.overlayImage&&!serialized.background&&!serialized.overlay){callback&&callback();return}var cbIfLoaded=function(){if(loaded.backgroundImage&&loaded.overlayImage&&loaded.backgroundColor&&loaded.overlayColor){_this.renderAll();callback&&callback()}};this.__setBgOverlay("backgroundImage",serialized.backgroundImage,loaded,cbIfLoaded);this.__setBgOverlay("overlayImage",serialized.overlayImage,loaded,cbIfLoaded);this.__setBgOverlay("backgroundColor",serialized.background,loaded,cbIfLoaded);this.__setBgOverlay("overlayColor",serialized.overlay,loaded,cbIfLoaded);cbIfLoaded()},__setBgOverlay:function(property,value,loaded,callback){var _this=this;if(!value){loaded[property]=true;return}if(property==="backgroundImage"||property==="overlayImage"){fabric.Image.fromObject(value,function(img){_this[property]=img;loaded[property]=true;callback&&callback()})}else{this["set"+fabric.util.string.capitalize(property,true)](value,function(){loaded[property]=true;callback&&callback()})}},_enlivenObjects:function(objects,callback,reviver){var _this=this;if(!objects||objects.length===0){callback&&callback();return}var renderOnAddRemove=this.renderOnAddRemove;this.renderOnAddRemove=false;fabric.util.enlivenObjects(objects,function(enlivenedObjects){enlivenedObjects.forEach(function(obj,index){_this.insertAt(obj,index,true)});_this.renderOnAddRemove=renderOnAddRemove;callback&&callback()},null,reviver)},_toDataURL:function(format,callback){this.clone(function(clone){callback(clone.toDataURL(format))})},_toDataURLWithMultiplier:function(format,multiplier,callback){this.clone(function(clone){callback(clone.toDataURLWithMultiplier(format,multiplier))})},clone:function(callback,properties){var data=JSON.stringify(this.toJSON(properties));this.cloneWithoutData(function(clone){clone.loadFromJSON(data,function(){callback&&callback(clone)})})},cloneWithoutData:function(callback){var el=fabric.document.createElement("canvas");el.width=this.getWidth();el.height=this.getHeight();var clone=new fabric.Canvas(el);clone.clipTo=this.clipTo;if(this.backgroundImage){clone.setBackgroundImage(this.backgroundImage.src,function(){clone.renderAll();callback&&callback(clone)});clone.backgroundImageOpacity=this.backgroundImageOpacity;clone.backgroundImageStretch=this.backgroundImageStretch}else{callback&&callback(clone)}}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,toFixed=fabric.util.toFixed,capitalize=fabric.util.string.capitalize,degreesToRadians=fabric.util.degreesToRadians,supportsLineDash=fabric.StaticCanvas.supports("setLineDash");if(fabric.Object){return}fabric.Object=fabric.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:false,flipY:false,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:12,transparentCorners:true,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:false,centeredRotation:true,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:true,evented:true,visible:true,hasControls:true,hasBorders:true,hasRotatingPoint:true,rotatingPointOffset:40,perPixelTargetFind:false,includeDefaultValues:true,clipTo:null,lockMovementX:false,lockMovementY:false,lockRotation:false,lockScalingX:false,lockScalingY:false,lockUniScaling:false,lockSkewingX:false,lockSkewingY:false,lockScalingFlip:false,stateProperties:("top left width height scaleX scaleY flipX flipY originX originY transformMatrix "+"stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit "+"angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor "+"alignX alignY meetOrSlice skewX skewY").split(" "),initialize:function(options){if(options){this.setOptions(options)}},_initGradient:function(options){if(options.fill&&options.fill.colorStops&&!(options.fill instanceof fabric.Gradient)){this.set("fill",new fabric.Gradient(options.fill))}if(options.stroke&&options.stroke.colorStops&&!(options.stroke instanceof fabric.Gradient)){this.set("stroke",new fabric.Gradient(options.stroke))}},_initPattern:function(options){if(options.fill&&options.fill.source&&!(options.fill instanceof fabric.Pattern)){this.set("fill",new fabric.Pattern(options.fill))}if(options.stroke&&options.stroke.source&&!(options.stroke instanceof fabric.Pattern)){this.set("stroke",new fabric.Pattern(options.stroke))}},_initClipping:function(options){if(!options.clipTo||typeof options.clipTo!=="string"){return}var functionBody=fabric.util.getFunctionBody(options.clipTo);if(typeof functionBody!=="undefined"){this.clipTo=new Function("ctx",functionBody)}},setOptions:function(options){for(var prop in options){this.set(prop,options[prop])}this._initGradient(options);this._initPattern(options);this._initClipping(options)},transform:function(ctx,fromLeft){if(this.group&&this.canvas.preserveObjectStacking&&this.group===this.canvas._activeGroup){this.group.transform(ctx)}var center=fromLeft?this._getLeftTopCoords():this.getCenterPoint();ctx.translate(center.x,center.y);ctx.rotate(degreesToRadians(this.angle));ctx.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1));ctx.transform(1,0,Math.tan(degreesToRadians(this.skewX)),1,0,0);ctx.transform(1,Math.tan(degreesToRadians(this.skewY)),0,1,0,0)},toObject:function(propertiesToInclude){var NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,object={type:this.type,originX:this.originX,originY:this.originY,left:toFixed(this.left,NUM_FRACTION_DIGITS),top:toFixed(this.top,NUM_FRACTION_DIGITS),width:toFixed(this.width,NUM_FRACTION_DIGITS),height:toFixed(this.height,NUM_FRACTION_DIGITS),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:toFixed(this.strokeWidth,NUM_FRACTION_DIGITS),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:toFixed(this.strokeMiterLimit,NUM_FRACTION_DIGITS),scaleX:toFixed(this.scaleX,NUM_FRACTION_DIGITS),scaleY:toFixed(this.scaleY,NUM_FRACTION_DIGITS),angle:toFixed(this.getAngle(),NUM_FRACTION_DIGITS),flipX:this.flipX,flipY:this.flipY,opacity:toFixed(this.opacity,NUM_FRACTION_DIGITS),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():this.transformMatrix,skewX:toFixed(this.skewX,NUM_FRACTION_DIGITS),skewY:toFixed(this.skewY,NUM_FRACTION_DIGITS)};if(!this.includeDefaultValues){object=this._removeDefaultValues(object)}fabric.util.populateWithProperties(this,object,propertiesToInclude);return object},toDatalessObject:function(propertiesToInclude){return this.toObject(propertiesToInclude)},_removeDefaultValues:function(object){var prototype=fabric.util.getKlass(object.type).prototype,stateProperties=prototype.stateProperties;stateProperties.forEach(function(prop){if(object[prop]===prototype[prop]){delete object[prop]}var isArray=Object.prototype.toString.call(object[prop])==="[object Array]"&&Object.prototype.toString.call(prototype[prop])==="[object Array]";if(isArray&&object[prop].length===0&&prototype[prop].length===0){delete object[prop]}});return object},toString:function(){return"#"},get:function(property){return this[property]},_setObject:function(obj){for(var prop in obj){this._set(prop,obj[prop])}},set:function(key,value){if(typeof key==="object"){this._setObject(key)}else{if(typeof value==="function"&&key!=="clipTo"){this._set(key,value(this.get(key)))}else{this._set(key,value)}}return this},_set:function(key,value){var shouldConstrainValue=key==="scaleX"||key==="scaleY";if(shouldConstrainValue){value=this._constrainScale(value)}if(key==="scaleX"&&value<0){this.flipX=!this.flipX;value*=-1}else if(key==="scaleY"&&value<0){this.flipY=!this.flipY;value*=-1}else if(key==="width"||key==="height"){this.minScaleLimit=toFixed(Math.min(.1,1/Math.max(this.width,this.height)),2)}else if(key==="shadow"&&value&&!(value instanceof fabric.Shadow)){value=new fabric.Shadow(value)}this[key]=value;return this},setOnGroup:function(){},toggle:function(property){var value=this.get(property);if(typeof value==="boolean"){this.set(property,!value)}return this},setSourcePath:function(value){this.sourcePath=value;return this},getViewportTransform:function(){if(this.canvas&&this.canvas.viewportTransform){return this.canvas.viewportTransform}return[1,0,0,1,0,0]},render:function(ctx,noTransform){if(this.width===0&&this.height===0||!this.visible){return}ctx.save();this._setupCompositeOperation(ctx);if(!noTransform){this.transform(ctx)}this._setStrokeStyles(ctx);this._setFillStyles(ctx);if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}this._setOpacity(ctx);this._setShadow(ctx);this.clipTo&&fabric.util.clipContext(this,ctx);this._render(ctx,noTransform);this.clipTo&&ctx.restore();ctx.restore()},_setOpacity:function(ctx){if(this.group){this.group._setOpacity(ctx)}ctx.globalAlpha*=this.opacity},_setStrokeStyles:function(ctx){if(this.stroke){ctx.lineWidth=this.strokeWidth;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;ctx.miterLimit=this.strokeMiterLimit;ctx.strokeStyle=this.stroke.toLive?this.stroke.toLive(ctx,this):this.stroke}},_setFillStyles:function(ctx){if(this.fill){ctx.fillStyle=this.fill.toLive?this.fill.toLive(ctx,this):this.fill}},_renderControls:function(ctx,noTransform){if(!this.active||noTransform||this.group&&this.group!==this.canvas.getActiveGroup()){return}var vpt=this.getViewportTransform(),matrix=this.calcTransformMatrix(),options;matrix=fabric.util.multiplyTransformMatrices(vpt,matrix);options=fabric.util.qrDecompose(matrix);ctx.save();ctx.translate(options.translateX,options.translateY);if(this.group&&this.group===this.canvas.getActiveGroup()){ctx.rotate(degreesToRadians(options.angle));this.drawBordersInGroup(ctx,options)}else{ctx.rotate(degreesToRadians(this.angle));this.drawBorders(ctx)}this.drawControls(ctx);ctx.restore()},_setShadow:function(ctx){if(!this.shadow){return}var multX=this.canvas&&this.canvas.viewportTransform[0]||1,multY=this.canvas&&this.canvas.viewportTransform[3]||1;if(this.canvas&&this.canvas._isRetinaScaling()){multX*=fabric.devicePixelRatio;multY*=fabric.devicePixelRatio}ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur*(multX+multY)*(this.scaleX+this.scaleY)/4;ctx.shadowOffsetX=this.shadow.offsetX*multX*this.scaleX;ctx.shadowOffsetY=this.shadow.offsetY*multY*this.scaleY},_removeShadow:function(ctx){if(!this.shadow){return}ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0},_renderFill:function(ctx){if(!this.fill){return}ctx.save();if(this.fill.gradientTransform){var g=this.fill.gradientTransform;ctx.transform.apply(ctx,g)}if(this.fill.toLive){ctx.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0)}if(this.fillRule==="evenodd"){ctx.fill("evenodd")}else{ctx.fill()}ctx.restore()},_renderStroke:function(ctx){if(!this.stroke||this.strokeWidth===0){return}if(this.shadow&&!this.shadow.affectStroke){this._removeShadow(ctx)}ctx.save();if(this.strokeDashArray){if(1&this.strokeDashArray.length){this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray)}if(supportsLineDash){ctx.setLineDash(this.strokeDashArray);this._stroke&&this._stroke(ctx)}else{this._renderDashedStroke&&this._renderDashedStroke(ctx)}ctx.stroke()}else{if(this.stroke.gradientTransform){var g=this.stroke.gradientTransform;ctx.transform.apply(ctx,g)}this._stroke?this._stroke(ctx):ctx.stroke()}ctx.restore()},clone:function(callback,propertiesToInclude){if(this.constructor.fromObject){return this.constructor.fromObject(this.toObject(propertiesToInclude),callback)}return new fabric.Object(this.toObject(propertiesToInclude))},cloneAsImage:function(callback){var dataUrl=this.toDataURL();fabric.util.loadImage(dataUrl,function(img){if(callback){callback(new fabric.Image(img)) +}});return this},toDataURL:function(options){options||(options={});var el=fabric.util.createCanvasElement(),boundingRect=this.getBoundingRect();el.width=boundingRect.width;el.height=boundingRect.height;fabric.util.wrapElement(el,"div");var canvas=new fabric.StaticCanvas(el);if(options.format==="jpg"){options.format="jpeg"}if(options.format==="jpeg"){canvas.backgroundColor="#fff"}var origParams={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",false);this.setPositionByOrigin(new fabric.Point(el.width/2,el.height/2),"center","center");var originalCanvas=this.canvas;canvas.add(this);var data=canvas.toDataURL(options);this.set(origParams).setCoords();this.canvas=originalCanvas;canvas.dispose();canvas=null;return data},isType:function(type){return this.type===type},complexity:function(){return 0},toJSON:function(propertiesToInclude){return this.toObject(propertiesToInclude)},setGradient:function(property,options){options||(options={});var gradient={colorStops:[]};gradient.type=options.type||(options.r1||options.r2?"radial":"linear");gradient.coords={x1:options.x1,y1:options.y1,x2:options.x2,y2:options.y2};if(options.r1||options.r2){gradient.coords.r1=options.r1;gradient.coords.r2=options.r2}options.gradientTransform&&(gradient.gradientTransform=options.gradientTransform);for(var position in options.colorStops){var color=new fabric.Color(options.colorStops[position]);gradient.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this.set(property,fabric.Gradient.forObject(this,gradient))},setPatternFill:function(options){return this.set("fill",new fabric.Pattern(options))},setShadow:function(options){return this.set("shadow",options?new fabric.Shadow(options):null)},setColor:function(color){this.set("fill",color);return this},setAngle:function(angle){var shouldCenterOrigin=(this.originX!=="center"||this.originY!=="center")&&this.centeredRotation;if(shouldCenterOrigin){this._setOriginToCenter()}this.set("angle",angle);if(shouldCenterOrigin){this._resetOrigin()}return this},centerH:function(){this.canvas.centerObjectH(this);return this},centerV:function(){this.canvas.centerObjectV(this);return this},center:function(){this.canvas.centerObject(this);return this},remove:function(){this.canvas.remove(this);return this},getLocalPointer:function(e,pointer){pointer=pointer||this.canvas.getPointer(e);var pClicked=new fabric.Point(pointer.x,pointer.y),objectLeftTop=this._getLeftTopCoords();if(this.angle){pClicked=fabric.util.rotatePoint(pClicked,objectLeftTop,fabric.util.degreesToRadians(-this.angle))}return{x:pClicked.x-objectLeftTop.x,y:pClicked.y-objectLeftTop.y}},_setupCompositeOperation:function(ctx){if(this.globalCompositeOperation){ctx.globalCompositeOperation=this.globalCompositeOperation}}});fabric.util.createAccessors(fabric.Object);fabric.Object.prototype.rotate=fabric.Object.prototype.setAngle;extend(fabric.Object.prototype,fabric.Observable);fabric.Object.NUM_FRACTION_DIGITS=2;fabric.Object.__uid=0})(typeof exports!=="undefined"?exports:this);(function(){var degreesToRadians=fabric.util.degreesToRadians,originXOffset={left:-.5,center:0,right:.5},originYOffset={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(point,fromOriginX,fromOriginY,toOriginX,toOriginY){var x=point.x,y=point.y,offsetX=originXOffset[toOriginX]-originXOffset[fromOriginX],offsetY=originYOffset[toOriginY]-originYOffset[fromOriginY],dim;if(offsetX||offsetY){dim=this._getTransformedDimensions();x=point.x+offsetX*dim.x;y=point.y+offsetY*dim.y}return new fabric.Point(x,y)},translateToCenterPoint:function(point,originX,originY){var p=this.translateToGivenOrigin(point,originX,originY,"center","center");if(this.angle){return fabric.util.rotatePoint(p,point,degreesToRadians(this.angle))}return p},translateToOriginPoint:function(center,originX,originY){var p=this.translateToGivenOrigin(center,"center","center",originX,originY);if(this.angle){return fabric.util.rotatePoint(p,center,degreesToRadians(this.angle))}return p},getCenterPoint:function(){var leftTop=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(leftTop,this.originX,this.originY)},getPointByOrigin:function(originX,originY){var center=this.getCenterPoint();return this.translateToOriginPoint(center,originX,originY)},toLocalPoint:function(point,originX,originY){var center=this.getCenterPoint(),p,p2;if(originX&&originY){p=this.translateToGivenOrigin(center,"center","center",originX,originY)}else{p=new fabric.Point(this.left,this.top)}p2=new fabric.Point(point.x,point.y);if(this.angle){p2=fabric.util.rotatePoint(p2,center,-degreesToRadians(this.angle))}return p2.subtractEquals(p)},setPositionByOrigin:function(pos,originX,originY){var center=this.translateToCenterPoint(pos,originX,originY),position=this.translateToOriginPoint(center,this.originX,this.originY);this.set("left",position.x);this.set("top",position.y)},adjustPosition:function(to){var angle=degreesToRadians(this.angle),hypotFull=this.getWidth(),xFull=Math.cos(angle)*hypotFull,yFull=Math.sin(angle)*hypotFull;this.left+=xFull*(originXOffset[to]-originXOffset[this.originX]);this.top+=yFull*(originXOffset[to]-originXOffset[this.originX]);this.setCoords();this.originX=to},_setOriginToCenter:function(){this._originalOriginX=this.originX;this._originalOriginY=this.originY;var center=this.getCenterPoint();this.originX="center";this.originY="center";this.left=center.x;this.top=center.y},_resetOrigin:function(){var originPoint=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX;this.originY=this._originalOriginY;this.left=originPoint.x;this.top=originPoint.y;this._originalOriginX=null;this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")}})})();(function(){function getCoords(oCoords){return[new fabric.Point(oCoords.tl.x,oCoords.tl.y),new fabric.Point(oCoords.tr.x,oCoords.tr.y),new fabric.Point(oCoords.br.x,oCoords.br.y),new fabric.Point(oCoords.bl.x,oCoords.bl.y)]}var degreesToRadians=fabric.util.degreesToRadians,multiplyMatrices=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(pointTL,pointBR){var oCoords=getCoords(this.oCoords),intersection=fabric.Intersection.intersectPolygonRectangle(oCoords,pointTL,pointBR);return intersection.status==="Intersection"},intersectsWithObject:function(other){var intersection=fabric.Intersection.intersectPolygonPolygon(getCoords(this.oCoords),getCoords(other.oCoords));return intersection.status==="Intersection"},isContainedWithinObject:function(other){var boundingRect=other.getBoundingRect(),point1=new fabric.Point(boundingRect.left,boundingRect.top),point2=new fabric.Point(boundingRect.left+boundingRect.width,boundingRect.top+boundingRect.height);return this.isContainedWithinRect(point1,point2)},isContainedWithinRect:function(pointTL,pointBR){var boundingRect=this.getBoundingRect();return boundingRect.left>=pointTL.x&&boundingRect.left+boundingRect.width<=pointBR.x&&boundingRect.top>=pointTL.y&&boundingRect.top+boundingRect.height<=pointBR.y},containsPoint:function(point){var lines=this._getImageLines(this.oCoords),xPoints=this._findCrossPoints(point,lines);return xPoints!==0&&xPoints%2===1},_getImageLines:function(oCoords){return{topline:{o:oCoords.tl,d:oCoords.tr},rightline:{o:oCoords.tr,d:oCoords.br},bottomline:{o:oCoords.br,d:oCoords.bl},leftline:{o:oCoords.bl,d:oCoords.tl}}},_findCrossPoints:function(point,oCoords){var b1,b2,a1,a2,xi,yi,xcount=0,iLine;for(var lineKey in oCoords){iLine=oCoords[lineKey];if(iLine.o.y=point.y&&iLine.d.y>=point.y){continue}if(iLine.o.x===iLine.d.x&&iLine.o.x>=point.x){xi=iLine.o.x;yi=point.y}else{b1=0;b2=(iLine.d.y-iLine.o.y)/(iLine.d.x-iLine.o.x);a1=point.y-b1*point.x;a2=iLine.o.y-b2*iLine.o.x;xi=-(a1-a2)/(b1-b2);yi=a1+b1*xi}if(xi>=point.x){xcount+=1}if(xcount===2){break}}return xcount},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();return fabric.util.makeBoundingBoxFromPoints([this.oCoords.tl,this.oCoords.tr,this.oCoords.br,this.oCoords.bl])},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(value){if(Math.abs(value)0?Math.atan(currentHeight/currentWidth):0,_hypotenuse=currentWidth/Math.cos(_angle)/2,offsetX=Math.cos(_angle+theta)*_hypotenuse,offsetY=Math.sin(_angle+theta)*_hypotenuse,coords=fabric.util.transformPoint(this.getCenterPoint(),vpt),tl=new fabric.Point(coords.x-offsetX,coords.y-offsetY),tr=new fabric.Point(tl.x+currentWidth*cosTh,tl.y+currentWidth*sinTh),bl=new fabric.Point(tl.x-currentHeight*sinTh,tl.y+currentHeight*cosTh),br=new fabric.Point(coords.x+offsetX,coords.y+offsetY),ml=new fabric.Point((tl.x+bl.x)/2,(tl.y+bl.y)/2),mt=new fabric.Point((tr.x+tl.x)/2,(tr.y+tl.y)/2),mr=new fabric.Point((br.x+tr.x)/2,(br.y+tr.y)/2),mb=new fabric.Point((br.x+bl.x)/2,(br.y+bl.y)/2),mtr=new fabric.Point(mt.x+sinTh*this.rotatingPointOffset,mt.y-cosTh*this.rotatingPointOffset);this.oCoords={tl:tl,tr:tr,br:br,bl:bl,ml:ml,mt:mt,mr:mr,mb:mb,mtr:mtr};this._setCornerCoords&&this._setCornerCoords();return this},_calcRotateMatrix:function(){if(this.angle){var theta=degreesToRadians(this.angle),cos=Math.cos(theta),sin=Math.sin(theta);return[cos,sin,-sin,cos,0,0]}return[1,0,0,1,0,0]},calcTransformMatrix:function(){var center=this.getCenterPoint(),translateMatrix=[1,0,0,1,center.x,center.y],rotateMatrix=this._calcRotateMatrix(),dimensionMatrix=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,true),matrix=this.group?this.group.calcTransformMatrix():[1,0,0,1,0,0];matrix=multiplyMatrices(matrix,translateMatrix);matrix=multiplyMatrices(matrix,rotateMatrix);matrix=multiplyMatrices(matrix,dimensionMatrix);return matrix},_calcDimensionsTransformMatrix:function(skewX,skewY,flipping){var skewMatrixX=[1,0,Math.tan(degreesToRadians(skewX)),1],skewMatrixY=[1,Math.tan(degreesToRadians(skewY)),0,1],scaleX=this.scaleX*(flipping&&this.flipX?-1:1),scaleY=this.scaleY*(flipping&&this.flipY?-1:1),scaleMatrix=[scaleX,0,0,scaleY],m=multiplyMatrices(scaleMatrix,skewMatrixX,true);return multiplyMatrices(m,skewMatrixY,true)}})})();fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){if(this.group){fabric.StaticCanvas.prototype.sendToBack.call(this.group,this)}else{this.canvas.sendToBack(this)}return this},bringToFront:function(){if(this.group){fabric.StaticCanvas.prototype.bringToFront.call(this.group,this)}else{this.canvas.bringToFront(this)}return this},sendBackwards:function(intersecting){if(this.group){fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,intersecting)}else{this.canvas.sendBackwards(this,intersecting)}return this},bringForward:function(intersecting){if(this.group){fabric.StaticCanvas.prototype.bringForward.call(this.group,this,intersecting)}else{this.canvas.bringForward(this,intersecting)}return this},moveTo:function(index){if(this.group){fabric.StaticCanvas.prototype.moveTo.call(this.group,this,index)}else{this.canvas.moveTo(this,index)}return this}});fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(skipShadow){var fill=this.fill?this.fill.toLive?"url(#SVGID_"+this.fill.id+")":this.fill:"none",fillRule=this.fillRule,stroke=this.stroke?this.stroke.toLive?"url(#SVGID_"+this.stroke.id+")":this.stroke:"none",strokeWidth=this.strokeWidth?this.strokeWidth:"0",strokeDashArray=this.strokeDashArray?this.strokeDashArray.join(" "):"none",strokeLineCap=this.strokeLineCap?this.strokeLineCap:"butt",strokeLineJoin=this.strokeLineJoin?this.strokeLineJoin:"miter",strokeMiterLimit=this.strokeMiterLimit?this.strokeMiterLimit:"4",opacity=typeof this.opacity!=="undefined"?this.opacity:"1",visibility=this.visible?"":" visibility: hidden;",filter=skipShadow?"":this.getSvgFilter();return["stroke: ",stroke,"; ","stroke-width: ",strokeWidth,"; ","stroke-dasharray: ",strokeDashArray,"; ","stroke-linecap: ",strokeLineCap,"; ","stroke-linejoin: ",strokeLineJoin,"; ","stroke-miterlimit: ",strokeMiterLimit,"; ","fill: ",fill,"; ","fill-rule: ",fillRule,"; ","opacity: ",opacity,";",filter,visibility].join("")},getSvgFilter:function(){return this.shadow?"filter: url(#SVGID_"+this.shadow.id+");":""},getSvgTransform:function(){if(this.group&&this.group.type==="path-group"){return""}var toFixed=fabric.util.toFixed,angle=this.getAngle(),skewX=this.getSkewX()%360,skewY=this.getSkewY()%360,center=this.getCenterPoint(),NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,translatePart=this.type==="path-group"?"":"translate("+toFixed(center.x,NUM_FRACTION_DIGITS)+" "+toFixed(center.y,NUM_FRACTION_DIGITS)+")",anglePart=angle!==0?" rotate("+toFixed(angle,NUM_FRACTION_DIGITS)+")":"",scalePart=this.scaleX===1&&this.scaleY===1?"":" scale("+toFixed(this.scaleX,NUM_FRACTION_DIGITS)+" "+toFixed(this.scaleY,NUM_FRACTION_DIGITS)+")",skewXPart=skewX!==0?" skewX("+toFixed(skewX,NUM_FRACTION_DIGITS)+")":"",skewYPart=skewY!==0?" skewY("+toFixed(skewY,NUM_FRACTION_DIGITS)+")":"",addTranslateX=this.type==="path-group"?this.width:0,flipXPart=this.flipX?" matrix(-1 0 0 1 "+addTranslateX+" 0) ":"",addTranslateY=this.type==="path-group"?this.height:0,flipYPart=this.flipY?" matrix(1 0 0 -1 0 "+addTranslateY+")":"";return[translatePart,anglePart,scalePart,flipXPart,flipYPart,skewXPart,skewYPart].join("")},getSvgTransformMatrix:function(){return this.transformMatrix?" matrix("+this.transformMatrix.join(" ")+") ":""},_createBaseSVGMarkup:function(){var markup=[];if(this.fill&&this.fill.toLive){markup.push(this.fill.toSVG(this,false))}if(this.stroke&&this.stroke.toLive){markup.push(this.stroke.toSVG(this,false))}if(this.shadow){markup.push(this.shadow.toSVG(this))}return markup}});fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(prop){return this.get(prop)!==this.originalState[prop]},this)},saveState:function(options){this.stateProperties.forEach(function(prop){this.originalState[prop]=this.get(prop)},this);if(options&&options.stateProperties){options.stateProperties.forEach(function(prop){this.originalState[prop]=this.get(prop)},this)}return this},setupState:function(){this.originalState={};this.saveState();return this}});(function(){var degreesToRadians=fabric.util.degreesToRadians,isVML=function(){return typeof G_vmlCanvasManager!=="undefined"};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(pointer){if(!this.hasControls||!this.active){return false}var ex=pointer.x,ey=pointer.y,xPoints,lines;this.__corner=0;for(var i in this.oCoords){if(!this.isControlVisible(i)){continue}if(i==="mtr"&&!this.hasRotatingPoint){continue}if(this.get("lockUniScaling")&&(i==="mt"||i==="mr"||i==="mb"||i==="ml")){continue}lines=this._getImageLines(this.oCoords[i].corner);xPoints=this._findCrossPoints({x:ex,y:ey},lines);if(xPoints!==0&&xPoints%2===1){this.__corner=i;return i}}return false},_setCornerCoords:function(){var coords=this.oCoords,newTheta=degreesToRadians(45-this.angle),cornerHypotenuse=this.cornerSize*.707106,cosHalfOffset=cornerHypotenuse*Math.cos(newTheta),sinHalfOffset=cornerHypotenuse*Math.sin(newTheta),x,y;for(var point in coords){x=coords[point].x;y=coords[point].y;coords[point].corner={tl:{x:x-sinHalfOffset,y:y-cosHalfOffset},tr:{x:x+cosHalfOffset,y:y-sinHalfOffset},bl:{x:x-cosHalfOffset,y:y+sinHalfOffset},br:{x:x+sinHalfOffset,y:y+cosHalfOffset}}}},_getNonTransformedDimensions:function(){var strokeWidth=this.strokeWidth,w=this.width,h=this.height,addStrokeToW=true,addStrokeToH=true;if(this.type==="line"&&this.strokeLineCap==="butt"){addStrokeToH=w;addStrokeToW=h}if(addStrokeToH){h+=h<0?-strokeWidth:strokeWidth}if(addStrokeToW){w+=w<0?-strokeWidth:strokeWidth}return{x:w,y:h}},_getTransformedDimensions:function(skewX,skewY){if(typeof skewX==="undefined"){skewX=this.skewX}if(typeof skewY==="undefined"){skewY=this.skewY}var dimensions=this._getNonTransformedDimensions(),dimX=dimensions.x/2,dimY=dimensions.y/2,points=[{x:-dimX,y:-dimY},{x:dimX,y:-dimY},{x:-dimX,y:dimY},{x:dimX,y:dimY}],i,transformMatrix=this._calcDimensionsTransformMatrix(skewX,skewY,false),bbox;for(i=0;i\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Line.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" "));fabric.Line.fromElement=function(element,options){var parsedAttributes=fabric.parseAttributes(element,fabric.Line.ATTRIBUTE_NAMES),points=[parsedAttributes.x1||0,parsedAttributes.y1||0,parsedAttributes.x2||0,parsedAttributes.y2||0];return new fabric.Line(points,extend(parsedAttributes,options))};fabric.Line.fromObject=function(object){var points=[object.x1,object.y1,object.x2,object.y2];return new fabric.Line(points,object)};function makeEdgeToOriginGetter(propertyNames,originValues){var origin=propertyNames.origin,axis1=propertyNames.axis1,axis2=propertyNames.axis2,dimension=propertyNames.dimension,nearest=originValues.nearest,center=originValues.center,farthest=originValues.farthest;return function(){switch(this.get(origin)){case nearest:return Math.min(this.get(axis1),this.get(axis2));case center:return Math.min(this.get(axis1),this.get(axis2))+.5*this.get(dimension);case farthest:return Math.max(this.get(axis1),this.get(axis2))}}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),pi=Math.PI,extend=fabric.util.object.extend;if(fabric.Circle){fabric.warn("fabric.Circle is already defined.");return}fabric.Circle=fabric.util.createClass(fabric.Object,{type:"circle",radius:0,startAngle:0,endAngle:pi*2,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("radius",options.radius||0);this.startAngle=options.startAngle||this.startAngle;this.endAngle=options.endAngle||this.endAngle},_set:function(key,value){this.callSuper("_set",key,value);if(key==="radius"){this.setRadius(value)}return this},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0,angle=(this.endAngle-this.startAngle)%(2*pi);if(angle===0){if(this.group&&this.group.type==="path-group"){x=this.left+this.radius;y=this.top+this.radius}markup.push("\n')}else{var startX=Math.cos(this.startAngle)*this.radius,startY=Math.sin(this.startAngle)*this.radius,endX=Math.cos(this.endAngle)*this.radius,endY=Math.sin(this.endAngle)*this.radius,largeFlag=angle>pi?"1":"0";markup.push('\n')}return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.arc(noTransform?this.left+this.radius:0,noTransform?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,false);this._renderFill(ctx);this._renderStroke(ctx)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(value){this.radius=value;return this.set("width",value*2).set("height",value*2)},complexity:function(){return 1}});fabric.Circle.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy r".split(" "));fabric.Circle.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Circle.ATTRIBUTE_NAMES);if(!isValidRadius(parsedAttributes)){throw new Error("value of `r` attribute is required and can not be negative")}parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var obj=new fabric.Circle(extend(parsedAttributes,options));obj.left-=obj.radius;obj.top-=obj.radius;return obj};function isValidRadius(attributes){return"radius"in attributes&&attributes.radius>=0}fabric.Circle.fromObject=function(object){return new fabric.Circle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Triangle){fabric.warn("fabric.Triangle is already defined");return}fabric.Triangle=fabric.util.createClass(fabric.Object,{type:"triangle",initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("width",options.width||100).set("height",options.height||100)},_render:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();ctx.moveTo(-widthBy2,heightBy2);ctx.lineTo(0,-heightBy2);ctx.lineTo(widthBy2,heightBy2);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();fabric.util.drawDashedLine(ctx,-widthBy2,heightBy2,0,-heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,0,-heightBy2,widthBy2,heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,widthBy2,heightBy2,-widthBy2,heightBy2,this.strokeDashArray);ctx.closePath()},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),widthBy2=this.width/2,heightBy2=this.height/2,points=[-widthBy2+" "+heightBy2,"0 "+-heightBy2,widthBy2+" "+heightBy2].join(",");markup.push("');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Triangle.fromObject=function(object){return new fabric.Triangle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),piBy2=Math.PI*2,extend=fabric.util.object.extend;if(fabric.Ellipse){fabric.warn("fabric.Ellipse is already defined."); +return}fabric.Ellipse=fabric.util.createClass(fabric.Object,{type:"ellipse",rx:0,ry:0,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("rx",options.rx||0);this.set("ry",options.ry||0)},_set:function(key,value){this.callSuper("_set",key,value);switch(key){case"rx":this.rx=value;this.set("width",value*2);break;case"ry":this.ry=value;this.set("height",value*2);break}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0;if(this.group&&this.group.type==="path-group"){x=this.left+this.rx;y=this.top+this.ry}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.save();ctx.transform(1,0,0,this.ry/this.rx,0,0);ctx.arc(noTransform?this.left+this.rx:0,noTransform?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,piBy2,false);ctx.restore();this._renderFill(ctx);this._renderStroke(ctx)},complexity:function(){return 1}});fabric.Ellipse.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" "));fabric.Ellipse.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Ellipse.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var ellipse=new fabric.Ellipse(extend(parsedAttributes,options));ellipse.top-=ellipse.ry;ellipse.left-=ellipse.rx;return ellipse};fabric.Ellipse.fromObject=function(object){return new fabric.Ellipse(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;if(fabric.Rect){fabric.warn("fabric.Rect is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("rx","ry","x","y");fabric.Rect=fabric.util.createClass(fabric.Object,{stateProperties:stateProperties,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(options){options=options||{};this.callSuper("initialize",options);this._initRxRy()},_initRxRy:function(){if(this.rx&&!this.ry){this.ry=this.rx}else if(this.ry&&!this.rx){this.rx=this.ry}},_render:function(ctx,noTransform){if(this.width===1&&this.height===1){ctx.fillRect(-.5,-.5,1,1);return}var rx=this.rx?Math.min(this.rx,this.width/2):0,ry=this.ry?Math.min(this.ry,this.height/2):0,w=this.width,h=this.height,x=noTransform?this.left:-this.width/2,y=noTransform?this.top:-this.height/2,isRounded=rx!==0||ry!==0,k=1-.5522847498;ctx.beginPath();ctx.moveTo(x+rx,y);ctx.lineTo(x+w-rx,y);isRounded&&ctx.bezierCurveTo(x+w-k*rx,y,x+w,y+k*ry,x+w,y+ry);ctx.lineTo(x+w,y+h-ry);isRounded&&ctx.bezierCurveTo(x+w,y+h-k*ry,x+w-k*rx,y+h,x+w-rx,y+h);ctx.lineTo(x+rx,y+h);isRounded&&ctx.bezierCurveTo(x+k*rx,y+h,x,y+h-k*ry,x,y+h-ry);ctx.lineTo(x,y+ry);isRounded&&ctx.bezierCurveTo(x,y+k*ry,x+k*rx,y,x+rx,y);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var x=-this.width/2,y=-this.height/2,w=this.width,h=this.height;ctx.beginPath();fabric.util.drawDashedLine(ctx,x,y,x+w,y,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y,x+w,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y+h,x,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x,y+h,x,y,this.strokeDashArray);ctx.closePath()},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx")||0,ry:this.get("ry")||0});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=this.left,y=this.top;if(!(this.group&&this.group.type==="path-group")){x=-this.width/2;y=-this.height/2}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Rect.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" "));fabric.Rect.fromElement=function(element,options){if(!element){return null}options=options||{};var parsedAttributes=fabric.parseAttributes(element,fabric.Rect.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var rect=new fabric.Rect(extend(options?fabric.util.object.clone(options):{},parsedAttributes));rect.visible=rect.width>0&&rect.height>0;return rect};fabric.Rect.fromObject=function(object){return new fabric.Rect(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Polyline){fabric.warn("fabric.Polyline is already defined");return}fabric.Polyline=fabric.util.createClass(fabric.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(points,options){return fabric.Polygon.prototype.initialize.call(this,points,options)},_calcDimensions:function(){return fabric.Polygon.prototype._calcDimensions.call(this)},_applyPointOffset:function(){return fabric.Polygon.prototype._applyPointOffset.call(this)},toObject:function(propertiesToInclude){return fabric.Polygon.prototype.toObject.call(this,propertiesToInclude)},toSVG:function(reviver){return fabric.Polygon.prototype.toSVG.call(this,reviver)},_render:function(ctx,noTransform){if(!fabric.Polygon.prototype.commonRender.call(this,ctx,noTransform)){return}this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var p1,p2;ctx.beginPath();for(var i=0,len=this.points.length;i\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){if(!this.commonRender(ctx,noTransform)){return}this._renderFill(ctx);if(this.stroke||this.strokeDashArray){ctx.closePath();this._renderStroke(ctx)}},commonRender:function(ctx,noTransform){var point,len=this.points.length;if(!len||isNaN(this.points[len-1].y)){return false}noTransform||ctx.translate(-this.pathOffset.x,-this.pathOffset.y);ctx.beginPath();ctx.moveTo(this.points[0].x,this.points[0].y);for(var i=0;i"},toObject:function(propertiesToInclude){var o=extend(this.callSuper("toObject",propertiesToInclude),{path:this.path.map(function(item){return item.slice()}),pathOffset:this.pathOffset});if(this.sourcePath){o.sourcePath=this.sourcePath}if(this.transformMatrix){o.transformMatrix=this.transformMatrix}return o},toDatalessObject:function(propertiesToInclude){var o=this.toObject(propertiesToInclude);if(this.sourcePath){o.path=this.sourcePath}delete o.sourcePath;return o},toSVG:function(reviver){var chunks=[],markup=this._createBaseSVGMarkup(),addTransform="";for(var i=0,len=this.path.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return this.path.length},_parsePath:function(){var result=[],coords=[],currentPath,parsed,re=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,match,coordsStr;for(var i=0,coordsParsed,len=this.path.length;icommandLength){for(var k=1,klen=coordsParsed.length;k\n");for(var i=0,len=objects.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},toString:function(){return"#"},isSameColor:function(){var firstPathFill=this.getObjects()[0].get("fill")||"";if(typeof firstPathFill!=="string"){return false}firstPathFill=firstPathFill.toLowerCase();return this.getObjects().every(function(path){var pathFill=path.get("fill")||"";return typeof pathFill==="string"&&pathFill.toLowerCase()===firstPathFill})},complexity:function(){return this.paths.reduce(function(total,path){return total+(path&&path.complexity?path.complexity():0)},0)},getObjects:function(){return this.paths}});fabric.PathGroup.fromObject=function(object,callback){if(typeof object.paths==="string"){fabric.loadSVGFromURL(object.paths,function(elements){var pathUrl=object.paths;delete object.paths;var pathGroup=fabric.util.groupSVGElements(elements,object,pathUrl);callback(pathGroup)})}else{fabric.util.enlivenObjects(object.paths,function(enlivenedObjects){delete object.paths;callback(new fabric.PathGroup(enlivenedObjects,object))})}};fabric.PathGroup.async=true})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,min=fabric.util.array.min,max=fabric.util.array.max,invoke=fabric.util.array.invoke;if(fabric.Group){return}var _lockProperties={lockMovementX:true,lockMovementY:true,lockRotation:true,lockScalingX:true,lockScalingY:true,lockUniScaling:true};fabric.Group=fabric.util.createClass(fabric.Object,fabric.Collection,{type:"group",strokeWidth:0,initialize:function(objects,options,isAlreadyGrouped){options=options||{};this._objects=[];isAlreadyGrouped&&this.callSuper("initialize",options);this._objects=objects||[];for(var i=this._objects.length;i--;){this._objects[i].group=this}this.originalState={};if(options.originX){this.originX=options.originX}if(options.originY){this.originY=options.originY}if(isAlreadyGrouped){this._updateObjectsCoords(true)}else{this._calcBounds();this._updateObjectsCoords();this.callSuper("initialize",options)}this.setCoords();this.saveCoords()},_updateObjectsCoords:function(skipCoordsChange){for(var i=this._objects.length;i--;){this._updateObjectCoords(this._objects[i],skipCoordsChange)}},_updateObjectCoords:function(object,skipCoordsChange){object.__origHasControls=object.hasControls;object.hasControls=false;if(skipCoordsChange){return}var objectLeft=object.getLeft(),objectTop=object.getTop(),center=this.getCenterPoint();object.set({originalLeft:objectLeft,originalTop:objectTop,left:objectLeft-center.x,top:objectTop-center.y});object.setCoords()},toString:function(){return"#"},addWithUpdate:function(object){this._restoreObjectsState();fabric.util.resetObjectTransform(this);if(object){this._objects.push(object);object.group=this;object._set("canvas",this.canvas)}this.forEachObject(this._setObjectActive,this);this._calcBounds();this._updateObjectsCoords();return this},_setObjectActive:function(object){object.set("active",true);object.group=this},removeWithUpdate:function(object){this._restoreObjectsState();fabric.util.resetObjectTransform(this);this.forEachObject(this._setObjectActive,this);this.remove(object);this._calcBounds();this._updateObjectsCoords();return this},_onObjectAdded:function(object){object.group=this;object._set("canvas",this.canvas)},_onObjectRemoved:function(object){delete object.group;object.set("active",false)},delegatedProperties:{fill:true,stroke:true,strokeWidth:true,fontFamily:true,fontWeight:true,fontSize:true,fontStyle:true,lineHeight:true,textDecoration:true,textAlign:true,backgroundColor:true},_set:function(key,value){var i=this._objects.length;if(this.delegatedProperties[key]||key==="canvas"){while(i--){this._objects[i].set(key,value)}}else{while(i--){this._objects[i].setOnGroup(key,value)}}this.callSuper("_set",key,value)},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{objects:invoke(this._objects,"toObject",propertiesToInclude)})},render:function(ctx){if(!this.visible){return}ctx.save();if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}this.transform(ctx);this._setShadow(ctx);this.clipTo&&fabric.util.clipContext(this,ctx);for(var i=0,len=this._objects.length;i\n');for(var i=0,len=this._objects.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},get:function(prop){if(prop in _lockProperties){if(this[prop]){return this[prop]}else{for(var i=0,len=this._objects.length;i0){object.resizeFilters=this.resizeFilters.map(function(filterObj){return filterObj&&filterObj.toObject()})}if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=-this.width/2,y=-this.height/2,preserveAspectRatio="none";if(this.group&&this.group.type==="path-group"){x=this.left;y=this.top}if(this.alignX!=="none"&&this.alignY!=="none"){preserveAspectRatio="x"+this.alignX+"Y"+this.alignY+" "+this.meetOrSlice}markup.push('\n','\n");if(this.stroke||this.strokeDashArray){var origFill=this.fill;this.fill=null;markup.push("\n');this.fill=origFill}markup.push("\n");return reviver?reviver(markup.join("")):markup.join("")},getSrc:function(){if(this.getElement()){return this.getElement().src||this.getElement()._src}},setSrc:function(src,callback,options){fabric.util.loadImage(src,function(img){return this.setElement(img,callback,options)},this,options&&options.crossOrigin)},toString:function(){return'#'},clone:function(callback,propertiesToInclude){this.constructor.fromObject(this.toObject(propertiesToInclude),callback)},applyFilters:function(callback,filters,imgElement,forResizing){filters=filters||this.filters;imgElement=imgElement||this._originalElement;if(!imgElement){return}var imgEl=imgElement,canvasEl=fabric.util.createCanvasElement(),replacement=fabric.util.createImage(),_this=this;canvasEl.width=imgEl.width;canvasEl.height=imgEl.height;canvasEl.getContext("2d").drawImage(imgEl,0,0,imgEl.width,imgEl.height);if(filters.length===0){this._element=imgElement;callback&&callback();return canvasEl}filters.forEach(function(filter){filter&&filter.applyTo(canvasEl,filter.scaleX||_this.scaleX,filter.scaleY||_this.scaleY);if(!forResizing&&filter&&filter.type==="Resize"){_this.width*=filter.scaleX;_this.height*=filter.scaleY}});replacement.width=canvasEl.width;replacement.height=canvasEl.height;if(fabric.isLikelyNode){replacement.src=canvasEl.toBuffer(undefined,fabric.Image.pngCompression);_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback()}else{replacement.onload=function(){_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback();replacement.onload=canvasEl=imgEl=null};replacement.src=canvasEl.toDataURL("image/png")}return canvasEl},_render:function(ctx,noTransform){var x,y,imageMargins=this._findMargins(),elementToDraw;x=noTransform?this.left:-this.width/2;y=noTransform?this.top:-this.height/2;if(this.meetOrSlice==="slice"){ctx.beginPath();ctx.rect(x,y,this.width,this.height);ctx.clip()}if(this.isMoving===false&&this.resizeFilters.length&&this._needsResize()){this._lastScaleX=this.scaleX;this._lastScaleY=this.scaleY;elementToDraw=this.applyFilters(null,this.resizeFilters,this._filteredEl||this._originalElement,true)}else{elementToDraw=this._element}elementToDraw&&ctx.drawImage(elementToDraw,x+imageMargins.marginX,y+imageMargins.marginY,imageMargins.width,imageMargins.height);this._renderStroke(ctx)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_findMargins:function(){var width=this.width,height=this.height,scales,scale,marginX=0,marginY=0;if(this.alignX!=="none"||this.alignY!=="none"){scales=[this.width/this._element.width,this.height/this._element.height];scale=this.meetOrSlice==="meet"?Math.min.apply(null,scales):Math.max.apply(null,scales);width=this._element.width*scale;height=this._element.height*scale;if(this.alignX==="Mid"){marginX=(this.width-width)/2}if(this.alignX==="Max"){marginX=this.width-width}if(this.alignY==="Mid"){marginY=(this.height-height)/2}if(this.alignY==="Max"){marginY=this.height-height}}return{width:width,height:height,marginX:marginX,marginY:marginY}},_resetWidthHeight:function(){var element=this.getElement();this.set("width",element.width);this.set("height",element.height)},_initElement:function(element,options){this.setElement(fabric.util.getById(element),null,options);fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(options){options||(options={});this.setOptions(options);this._setWidthHeight(options);if(this._element&&this.crossOrigin){this._element.crossOrigin=this.crossOrigin}},_initFilters:function(filters,callback){if(filters&&filters.length){fabric.util.enlivenObjects(filters,function(enlivenedObjects){callback&&callback(enlivenedObjects)},"fabric.Image.filters")}else{callback&&callback()}},_setWidthHeight:function(options){this.width="width"in options?options.width:this.getElement()?this.getElement().width||0:0;this.height="height"in options?options.height:this.getElement()?this.getElement().height||0:0},complexity:function(){return 1}});fabric.Image.CSS_CANVAS="canvas-img";fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc;fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){fabric.Image.prototype._initFilters.call(object,object.filters,function(filters){object.filters=filters||[];fabric.Image.prototype._initFilters.call(object,object.resizeFilters,function(resizeFilters){object.resizeFilters=resizeFilters||[];var instance=new fabric.Image(img,object);callback&&callback(instance)})})},null,object.crossOrigin)};fabric.Image.fromURL=function(url,callback,imgOptions){fabric.util.loadImage(url,function(img){callback&&callback(new fabric.Image(img,imgOptions))},null,imgOptions&&imgOptions.crossOrigin)};fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".split(" "));fabric.Image.fromElement=function(element,callback,options){var parsedAttributes=fabric.parseAttributes(element,fabric.Image.ATTRIBUTE_NAMES),preserveAR;if(parsedAttributes.preserveAspectRatio){preserveAR=fabric.util.parsePreserveAspectRatioAttribute(parsedAttributes.preserveAspectRatio);extend(parsedAttributes,preserveAR)}fabric.Image.fromURL(parsedAttributes["xlink:href"],callback,extend(options?fabric.util.object.clone(options):{},parsedAttributes))};fabric.Image.async=true;fabric.Image.pngCompression=1})(typeof exports!=="undefined"?exports:this);fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var angle=this.getAngle()%360;if(angle>0){return Math.round((angle-1)/90)*90}return Math.round(angle/90)*90},straighten:function(){this.setAngle(this._getAngleValueForStraighten());return this},fxStraighten:function(callbacks){callbacks=callbacks||{};var empty=function(){},onComplete=callbacks.onComplete||empty,onChange=callbacks.onChange||empty,_this=this;fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(value){_this.setAngle(value);onChange()},onComplete:function(){_this.setCoords();onComplete()},onStart:function(){_this.set("active",false)}});return this}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(object){object.straighten();this.renderAll();return this},fxStraightenObject:function(object){object.fxStraighten({onChange:this.renderAll.bind(this)});return this}});fabric.Image.filters=fabric.Image.filters||{};fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(options){if(options){this.setOptions(options)}},setOptions:function(options){for(var prop in options){this[prop]=options[prop]}},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.Brightness=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"Brightness",initialize:function(options){options=options||{};this.brightness=options.brightness||0},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,brightness=this.brightness;for(var i=0,len=data.length;ish||scx<0||scx>sw){continue}srcOff=(scy*sw+scx)*4;wt=weights[cy*side+cx];r+=src[srcOff]*wt;g+=src[srcOff+1]*wt;b+=src[srcOff+2]*wt;a+=src[srcOff+3]*wt}}dst[dstOff]=r;dst[dstOff+1]=g;dst[dstOff+2]=b;dst[dstOff+3]=a+alphaFac*(255-a)}}context.putImageData(output,0,0)},toObject:function(){return extend(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}});fabric.Image.filters.Convolute.fromObject=function(object){return new fabric.Image.filters.Convolute(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.GradientTransparency=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(options){options=options||{};this.threshold=options.threshold||100},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,threshold=this.threshold,total=data.length;for(var i=0,len=data.length;i-1?options.channel:0},applyTo:function(canvasEl){if(!this.mask){return}var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,maskEl=this.mask.getElement(),maskCanvasEl=fabric.util.createCanvasElement(),channel=this.channel,i,iLen=imageData.width*imageData.height*4;maskCanvasEl.width=canvasEl.width;maskCanvasEl.height=canvasEl.height;maskCanvasEl.getContext("2d").drawImage(maskEl,0,0,canvasEl.width,canvasEl.height);var maskImageData=maskCanvasEl.getContext("2d").getImageData(0,0,canvasEl.width,canvasEl.height),maskData=maskImageData.data;for(i=0;ilimit&&g>limit&&b>limit&&abs(r-g)width){multW=2;signW=-1}if(newHeight>height){multH=2;signH=-1}imageData=context.getImageData(0,0,width,height);canvasEl.width=max(newWidth,width);canvasEl.height=max(newHeight,height);context.putImageData(imageData,0,0);while(!doneW||!doneH){width=stepW;height=stepH;if(newWidth*signWlobes){return 0}x*=Math.PI;if(abs(x)<1e-16){return 1}var xx=x/lobes;return sin(x)*sin(xx)/x/xx}}function process(u){var v,i,weight,idx,a,red,green,blue,alpha,fX,fY;center.x=(u+.5)*ratioX;icenter.x=floor(center.x);for(v=0;v=oW){continue}fX=floor(1e3*abs(i-center.x));if(!cacheLanc[fX]){cacheLanc[fX]={}}for(var j=icenter.y-range2Y;j<=icenter.y+range2Y;j++){if(j<0||j>=oH){continue}fY=floor(1e3*abs(j-center.y));if(!cacheLanc[fX][fY]){cacheLanc[fX][fY]=lanczos(sqrt(pow(fX*rcpRatioX,2)+pow(fY*rcpRatioY,2))/1e3)}weight=cacheLanc[fX][fY];if(weight>0){idx=(j*oW+i)*4;a+=weight;red+=weight*srcData[idx];green+=weight*srcData[idx+1];blue+=weight*srcData[idx+2];alpha+=weight*srcData[idx+3]}}}idx=(v*dW+u)*4;destData[idx]=red/a;destData[idx+1]=green/a;destData[idx+2]=blue/a;destData[idx+3]=alpha/a}if(++u1&&w<-1){continue}weight=2*w*w*w-3*w*w+1;if(weight>0){dx=4*(xx+yy*oW);gxA+=weight*data[dx+3];weightsAlpha+=weight;if(data[dx+3]<255){weight=weight*data[dx+3]/250}gxR+=weight*data[dx];gxG+=weight*data[dx+1];gxB+=weight*data[dx+2];weights+=weight}}}data2[x2]=gxR/weights;data2[x2+1]=gxG/weights;data2[x2+2]=gxB/weights;data2[x2+3]=gxA/weightsAlpha}}return img2},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}});fabric.Image.filters.Resize.fromObject=function(object){return new fabric.Image.filters.Resize(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,clone=fabric.util.object.clone,toFixed=fabric.util.toFixed,supportsLineDash=fabric.StaticCanvas.supports("setLineDash"),NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;if(fabric.Text){fabric.warn("fabric.Text is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("fontFamily","fontWeight","fontSize","text","textDecoration","textAlign","fontStyle","lineHeight","textBackgroundColor");fabric.Text=fabric.util.createClass(fabric.Object,{_dimensionAffectingProps:{fontSize:true,fontWeight:true,fontFamily:true,fontStyle:true,lineHeight:true,stroke:true,strokeWidth:true,text:true,textAlign:true},_reNewline:/\r?\n/,_reSpacesAndTabs:/[ \t\r]+/g,type:"text",fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",textDecoration:"",textAlign:"left",fontStyle:"",lineHeight:1.16,textBackgroundColor:"",stateProperties:stateProperties,stroke:null,shadow:null,_fontSizeFraction:.25,_fontSizeMult:1.13,initialize:function(text,options){options=options||{};this.text=text;this.__skipDimension=true;this.setOptions(options);this.__skipDimension=false;this._initDimensions()},_initDimensions:function(ctx){if(this.__skipDimension){return}if(!ctx){ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx)}this._textLines=this._splitTextIntoLines();this._clearCache();this._cacheLinesWidth=this.textAlign!=="justify";this.width=this._getTextWidth(ctx);this._cacheLinesWidth=true;this.height=this._getTextHeight(ctx)},toString:function(){return"#'},_render:function(ctx){this.clipTo&&fabric.util.clipContext(this,ctx);this._setOpacity(ctx);this._setShadow(ctx);this._setupCompositeOperation(ctx);this._renderTextBackground(ctx);this._setStrokeStyles(ctx);this._setFillStyles(ctx);this._renderText(ctx);this._renderTextDecoration(ctx);this.clipTo&&ctx.restore()},_renderText:function(ctx){this._translateForTextAlign(ctx);this._renderTextFill(ctx);this._renderTextStroke(ctx);this._translateForTextAlign(ctx,true)},_translateForTextAlign:function(ctx,back){if(this.textAlign!=="left"&&this.textAlign!=="justify"){var sign=back?-1:1;ctx.translate(this.textAlign==="center"?sign*this.width/2:sign*this.width,0)}},_setTextStyles:function(ctx){ctx.textBaseline="alphabetic";if(!this.skipTextAlign){ctx.textAlign=this.textAlign}ctx.font=this._getFontDeclaration()},_getTextHeight:function(){return this._textLines.length*this._getHeightOfLine()},_getTextWidth:function(ctx){var maxWidth=this._getLineWidth(ctx,0);for(var i=1,len=this._textLines.length;imaxWidth){maxWidth=currentLineWidth}}return maxWidth},_renderChars:function(method,ctx,chars,left,top){var shortM=method.slice(0,-4);if(this[shortM].toLive){var offsetX=-this.width/2+this[shortM].offsetX||0,offsetY=-this.height/2+this[shortM].offsetY||0;ctx.save();ctx.translate(offsetX,offsetY);left-=offsetX;top-=offsetY}ctx[method](chars,left,top);this[shortM].toLive&&ctx.restore()},_renderTextLine:function(method,ctx,line,left,top,lineIndex){top-=this.fontSize*this._fontSizeFraction;var lineWidth=this._getLineWidth(ctx,lineIndex);if(this.textAlign!=="justify"||this.width0?widthDiff/numSpaces:0,leftOffset=0,word; +for(var i=0,len=words.length;i1){width=this.width}else{width=ctx.measureText(line).width}}else{width=ctx.measureText(line).width}this._cacheLinesWidth&&(this.__lineWidths[lineIndex]=width);return width},_renderTextDecoration:function(ctx){if(!this.textDecoration){return}var halfOfVerticalBox=this.height/2,_this=this,offsets=[];function renderLinesAtOffset(offsets){var i,lineHeight=0,len,j,oLen,lineWidth,lineLeftOffset,heightOfLine;for(i=0,len=_this._textLines.length;i-1){offsets.push(.85)}if(this.textDecoration.indexOf("line-through")>-1){offsets.push(.43)}if(this.textDecoration.indexOf("overline")>-1){offsets.push(-.12)}if(offsets.length>0){renderLinesAtOffset(offsets)}},_getFontDeclaration:function(){return[fabric.isLikelyNode?this.fontWeight:this.fontStyle,fabric.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",fabric.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(ctx,noTransform){if(!this.visible){return}ctx.save();this._setTextStyles(ctx);if(this._shouldClearCache()){this._initDimensions(ctx)}if(!noTransform){this.transform(ctx)}if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}if(this.group&&this.group.type==="path-group"){ctx.translate(this.left,this.top)}this._render(ctx);ctx.restore()},_splitTextIntoLines:function(){return this.text.split(this._reNewline)},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),offsets=this._getSVGLeftTopOffsets(this.ctx),textAndBg=this._getSVGTextAndBg(offsets.textTop,offsets.textLeft);this._wrapSVGTextAndBg(markup,textAndBg);return reviver?reviver(markup.join("")):markup.join("")},_getSVGLeftTopOffsets:function(ctx){var lineTop=this._getHeightOfLine(ctx,0),textLeft=-this.width/2,textTop=0;return{textLeft:textLeft+(this.group&&this.group.type==="path-group"?this.left:0),textTop:textTop+(this.group&&this.group.type==="path-group"?-this.top:0),lineTop:lineTop}},_wrapSVGTextAndBg:function(markup,textAndBg){var noShadow=true,filter=this.getSvgFilter(),style=filter===""?"":' style="'+filter+'"';markup.push(' \n",textAndBg.textBgRects.join("")," \n',textAndBg.textSpans.join("")," \n"," \n")},_getSVGTextAndBg:function(textTopOffset,textLeftOffset){var textSpans=[],textBgRects=[],height=0;this._setSVGBg(textBgRects);for(var i=0,len=this._textLines.length;i",fabric.util.string.escapeXml(this._textLines[i]),"\n")},_setSVGTextLineJustifed:function(i,textSpans,yPos,textLeftOffset){var ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx);var line=this._textLines[i],words=line.split(/\s+/),wordsWidth=this._getWidthOfWords(ctx,line),widthDiff=this.width-wordsWidth,numSpaces=words.length-1,spaceWidth=numSpaces>0?widthDiff/numSpaces:0,word,attributes=this._getFillAttributes(this.fill),len;textLeftOffset+=this._getLineLeftOffset(this._getLineWidth(ctx,i));for(i=0,len=words.length;i",fabric.util.string.escapeXml(word),"\n");textLeftOffset+=this._getWidthOfWords(ctx,word)+spaceWidth}},_setSVGTextLineBg:function(textBgRects,i,textLeftOffset,textTopOffset,height){textBgRects.push(" \n')},_setSVGBg:function(textBgRects){if(this.backgroundColor){textBgRects.push(" \n')}},_getFillAttributes:function(value){var fillColor=value&&typeof value==="string"?new fabric.Color(value):"";if(!fillColor||!fillColor.getSource()||fillColor.getAlpha()===1){return'fill="'+value+'"'}return'opacity="'+fillColor.getAlpha()+'" fill="'+fillColor.setAlpha(1).toRgb()+'"'},_set:function(key,value){this.callSuper("_set",key,value);if(key in this._dimensionAffectingProps){this._initDimensions();this.setCoords()}},complexity:function(){return 1}});fabric.Text.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" "));fabric.Text.DEFAULT_SVG_FONT_SIZE=16;fabric.Text.fromElement=function(element,options){if(!element){return null}var parsedAttributes=fabric.parseAttributes(element,fabric.Text.ATTRIBUTE_NAMES);options=fabric.util.object.extend(options?fabric.util.object.clone(options):{},parsedAttributes);options.top=options.top||0;options.left=options.left||0;if("dx"in parsedAttributes){options.left+=parsedAttributes.dx}if("dy"in parsedAttributes){options.top+=parsedAttributes.dy}if(!("fontSize"in options)){options.fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}if(!options.originX){options.originX="left"}var textContent="";if(!("textContent"in element)){if("firstChild"in element&&element.firstChild!==null){if("data"in element.firstChild&&element.firstChild.data!==null){textContent=element.firstChild.data}}}else{textContent=element.textContent}textContent=textContent.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var text=new fabric.Text(textContent,options),offX=0;if(text.originX==="left"){offX=text.getWidth()/2}if(text.originX==="right"){offX=-text.getWidth()/2}text.set({left:text.getLeft()+offX,top:text.getTop()-text.getHeight()/2+text.fontSize*(.18+text._fontSizeFraction)});return text};fabric.Text.fromObject=function(object){return new fabric.Text(object.text,clone(object))};fabric.util.createAccessors(fabric.Text)})(typeof exports!=="undefined"?exports:this);(function(){var clone=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:false,editable:true,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:true,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:false,_charWidthsCache:{},__widthOfSpace:[],initialize:function(text,options){this.styles=options?options.styles||{}:{};this.callSuper("initialize",text,options);this.initBehavior()},_clearCache:function(){this.callSuper("_clearCache");this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles){return true}var obj=this.styles;for(var p1 in obj){for(var p2 in obj[p1]){for(var p3 in obj[p1][p2]){return false}}}return true},setSelectionStart:function(index){index=Math.max(index,0);if(this.selectionStart!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionStart=index}this._updateTextarea()},setSelectionEnd:function(index){index=Math.min(index,this.text.length);if(this.selectionEnd!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionEnd=index}this._updateTextarea()},getSelectionStyles:function(startIndex,endIndex){if(arguments.length===2){var styles=[];for(var i=startIndex;i=start.charIndex&&(i!==endLine||jstartLine&&i0||this.skipFillStrokeCheck)){this.callSuper("_renderChars",method,ctx,line,left,top)}},_renderChar:function(method,ctx,lineIndex,i,_char,left,top,lineHeight){var charWidth,charHeight,shouldFill,shouldStroke,decl=this._getStyleDeclaration(lineIndex,i),offset,textDecoration;if(decl){charHeight=this._getHeightOfChar(ctx,_char,lineIndex,i);shouldStroke=decl.stroke;shouldFill=decl.fill;textDecoration=decl.textDecoration}else{charHeight=this.fontSize}shouldStroke=(shouldStroke||this.stroke)&&method==="strokeText";shouldFill=(shouldFill||this.fill)&&method==="fillText";decl&&ctx.save();charWidth=this._applyCharStylesGetWidth(ctx,_char,lineIndex,i,decl||{});textDecoration=textDecoration||this.textDecoration;if(decl&&decl.textBackgroundColor){this._removeShadow(ctx)}shouldFill&&ctx.fillText(_char,left,top);shouldStroke&&ctx.strokeText(_char,left,top);if(textDecoration||textDecoration!==""){offset=this._fontSizeFraction*lineHeight/this.lineHeight;this._renderCharDecoration(ctx,textDecoration,left,top,offset,charWidth,charHeight)}decl&&ctx.restore();ctx.translate(charWidth,0)},_hasStyleChanged:function(prevStyle,thisStyle){return prevStyle.fill!==thisStyle.fill||prevStyle.fontSize!==thisStyle.fontSize||prevStyle.textBackgroundColor!==thisStyle.textBackgroundColor||prevStyle.textDecoration!==thisStyle.textDecoration||prevStyle.fontFamily!==thisStyle.fontFamily||prevStyle.fontWeight!==thisStyle.fontWeight||prevStyle.fontStyle!==thisStyle.fontStyle||prevStyle.stroke!==thisStyle.stroke||prevStyle.strokeWidth!==thisStyle.strokeWidth},_renderCharDecoration:function(ctx,textDecoration,left,top,offset,charWidth,charHeight){if(!textDecoration){return}var decorationWeight=charHeight/15,positions={underline:top+charHeight/10,"line-through":top-charHeight*(this._fontSizeFraction+this._fontSizeMult-1)+decorationWeight,overline:top-(this._fontSizeMult-this._fontSizeFraction)*charHeight},decorations=["underline","line-through","overline"],i,decoration;for(i=0;i-1){ctx.fillRect(left,positions[decoration],charWidth,decorationWeight)}}},_renderTextLine:function(method,ctx,line,left,top,lineIndex){if(!this.isEmptyStyles()){top+=this.fontSize*(this._fontSizeFraction+.03)}this.callSuper("_renderTextLine",method,ctx,line,left,top,lineIndex)},_renderTextDecoration:function(ctx){if(this.isEmptyStyles()){return this.callSuper("_renderTextDecoration",ctx)}},_renderTextLinesBackground:function(ctx){this.callSuper("_renderTextLinesBackground",ctx);var lineTopOffset=0,heightOfLine,lineWidth,lineLeftOffset,leftOffset=this._getLeftOffset(),topOffset=this._getTopOffset(),line,_char,style;for(var i=0,len=this._textLines.length;imaxHeight){maxHeight=currentCharHeight}}this.__lineHeights[lineIndex]=maxHeight*this.lineHeight*this._fontSizeMult;return this.__lineHeights[lineIndex]},_getTextHeight:function(ctx){var height=0;for(var i=0,len=this._textLines.length;i-1){offset++;index--}return startFrom-offset},findWordBoundaryRight:function(startFrom){var offset=0,index=startFrom;if(this._reSpace.test(this.text.charAt(index))){while(this._reSpace.test(this.text.charAt(index))){offset++;index++}}while(/\S/.test(this.text.charAt(index))&&index-1){offset++; +index--}return startFrom-offset},findLineBoundaryRight:function(startFrom){var offset=0,index=startFrom;while(!/\n/.test(this.text.charAt(index))&&index0&&index=_this.__selectionStartOnMouseDown){_this.setSelectionStart(_this.__selectionStartOnMouseDown);_this.setSelectionEnd(newSelectionStart)}else{_this.setSelectionStart(newSelectionStart);_this.setSelectionEnd(_this.__selectionStartOnMouseDown)}})},_setEditingProps:function(){this.hoverCursor="text";if(this.canvas){this.canvas.defaultCursor=this.canvas.moveCursor="text"}this.borderColor=this.editingBorderColor;this.hasControls=this.selectable=false;this.lockMovementX=this.lockMovementY=true},_updateTextarea:function(){if(!this.hiddenTextarea||this.inCompositionMode){return}this.hiddenTextarea.value=this.text;this.hiddenTextarea.selectionStart=this.selectionStart;this.hiddenTextarea.selectionEnd=this.selectionEnd;if(this.selectionStart===this.selectionEnd){var p=this._calcTextareaPosition();this.hiddenTextarea.style.left=p.x+"px";this.hiddenTextarea.style.top=p.y+"px"}},_calcTextareaPosition:function(){var chars=this.text.split(""),boundaries=this._getCursorBoundaries(chars,"cursor"),cursorLocation=this.get2DCursorLocation(),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex,charHeight=this.getCurrentCharFontSize(lineIndex,charIndex),leftOffset=lineIndex===0&&charIndex===0?this._getLineLeftOffset(this._getLineWidth(this.ctx,lineIndex)):boundaries.leftOffset,m=this.calcTransformMatrix(),p={x:boundaries.left+leftOffset,y:boundaries.top+boundaries.topOffset+charHeight};this.hiddenTextarea.style.fontSize=charHeight+"px";return fabric.util.transformPoint(p,m)},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){if(!this._savedProps){return}this.hoverCursor=this._savedProps.overCursor;this.hasControls=this._savedProps.hasControls;this.borderColor=this._savedProps.borderColor;this.lockMovementX=this._savedProps.lockMovementX;this.lockMovementY=this._savedProps.lockMovementY;if(this.canvas){this.canvas.defaultCursor=this._savedProps.defaultCursor;this.canvas.moveCursor=this._savedProps.moveCursor}},exitEditing:function(){this.selected=false;this.isEditing=false;this.selectable=true;this.selectionEnd=this.selectionStart;this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);this.hiddenTextarea=null;this.abortCursorAnimation();this._restoreEditingProps();this._currentCursorOpacity=0;this.fire("editing:exited");this.canvas&&this.canvas.fire("text:editing:exited",{target:this});return this},_removeExtraneousStyles:function(){for(var prop in this.styles){if(!this._textLines[prop]){delete this.styles[prop]}}},_removeCharsFromTo:function(start,end){while(end!==start){this._removeSingleCharAndStyle(start+1);end--}this.setSelectionStart(start)},_removeSingleCharAndStyle:function(index){var isBeginningOfLine=this.text[index-1]==="\n",indexStyle=isBeginningOfLine?index:index-1;this.removeStyleObject(isBeginningOfLine,indexStyle);this.text=this.text.slice(0,index-1)+this.text.slice(index);this._textLines=this._splitTextIntoLines()},insertChars:function(_chars,useCopiedStyle){var style;if(this.selectionEnd-this.selectionStart>1){this._removeCharsFromTo(this.selectionStart,this.selectionEnd);this.setSelectionEnd(this.selectionStart)}if(!useCopiedStyle&&this.isEmptyStyles()){this.insertChar(_chars,false);return}for(var i=0,len=_chars.length;i=charIndex){newLineStyles[parseInt(index,10)-charIndex]=this.styles[lineIndex][index];delete this.styles[lineIndex][index]}}this.styles[lineIndex+1]=newLineStyles}this._forceClearCache=true},insertCharStyleObject:function(lineIndex,charIndex,style){var currentLineStyles=this.styles[lineIndex],currentLineStylesCloned=clone(currentLineStyles);if(charIndex===0&&!style){charIndex=1}for(var index in currentLineStylesCloned){var numericIndex=parseInt(index,10);if(numericIndex>=charIndex){currentLineStyles[numericIndex+1]=currentLineStylesCloned[numericIndex];if(!currentLineStylesCloned[numericIndex-1]){delete currentLineStyles[numericIndex]}}}this.styles[lineIndex][charIndex]=style||clone(currentLineStyles[charIndex-1]);this._forceClearCache=true},insertStyleObjects:function(_chars,isEndOfLine,styleObject){var cursorLocation=this.get2DCursorLocation(),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;if(!this._getLineStyle(lineIndex)){this._setLineStyle(lineIndex,{})}if(_chars==="\n"){this.insertNewlineStyleObject(lineIndex,charIndex,isEndOfLine)}else{this.insertCharStyleObject(lineIndex,charIndex,styleObject)}},shiftLineStyles:function(lineIndex,offset){var clonedStyles=clone(this.styles);for(var line in this.styles){var numericLine=parseInt(line,10);if(numericLine>lineIndex){this.styles[numericLine+offset]=clonedStyles[numericLine];if(!clonedStyles[numericLine-offset]){delete this.styles[numericLine]}}}},removeStyleObject:function(isBeginningOfLine,index){var cursorLocation=this.get2DCursorLocation(index),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;this._removeStyleObject(isBeginningOfLine,cursorLocation,lineIndex,charIndex)},_getTextOnPreviousLine:function(lIndex){return this._textLines[lIndex-1]},_removeStyleObject:function(isBeginningOfLine,cursorLocation,lineIndex,charIndex){if(isBeginningOfLine){var textOnPreviousLine=this._getTextOnPreviousLine(cursorLocation.lineIndex),newCharIndexOnPrevLine=textOnPreviousLine?textOnPreviousLine.length:0;if(!this.styles[lineIndex-1]){this.styles[lineIndex-1]={}}for(charIndex in this.styles[lineIndex]){this.styles[lineIndex-1][parseInt(charIndex,10)+newCharIndexOnPrevLine]=this.styles[lineIndex][charIndex]}this.shiftLineStyles(cursorLocation.lineIndex,-1)}else{var currentLineStyles=this.styles[lineIndex];if(currentLineStyles){delete currentLineStyles[charIndex]}var currentLineStylesCloned=clone(currentLineStyles);for(var i in currentLineStylesCloned){var numericIndex=parseInt(i,10);if(numericIndex>=charIndex&&numericIndex!==0){currentLineStyles[numericIndex-1]=currentLineStylesCloned[numericIndex];delete currentLineStyles[numericIndex]}}}},insertNewline:function(){this.insertChars("\n")}})})();fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date;this.__lastLastClickTime=+new Date;this.__lastPointer={};this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(options){this.__newClickTime=+new Date;var newPointer=this.canvas.getPointer(options.e);if(this.isTripleClick(newPointer)){this.fire("tripleclick",options);this._stopEvent(options.e)}else if(this.isDoubleClick(newPointer)){this.fire("dblclick",options);this._stopEvent(options.e)}this.__lastLastClickTime=this.__lastClickTime;this.__lastClickTime=this.__newClickTime;this.__lastPointer=newPointer;this.__lastIsEditing=this.isEditing;this.__lastSelected=this.selected},isDoubleClick:function(newPointer){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===newPointer.x&&this.__lastPointer.y===newPointer.y&&this.__lastIsEditing},isTripleClick:function(newPointer){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===newPointer.x&&this.__lastPointer.y===newPointer.y},_stopEvent:function(e){e.preventDefault&&e.preventDefault();e.stopPropagation&&e.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler();this.initMousedownHandler();this.initMouseupHandler();this.initClicks()},initClicks:function(){this.on("dblclick",function(options){this.selectWord(this.getSelectionStartFromPointer(options.e))});this.on("tripleclick",function(options){this.selectLine(this.getSelectionStartFromPointer(options.e))})},initMousedownHandler:function(){this.on("mousedown",function(options){if(!this.editable){return}var pointer=this.canvas.getPointer(options.e);this.__mousedownX=pointer.x;this.__mousedownY=pointer.y;this.__isMousedown=true;if(this.hiddenTextarea&&this.canvas){this.canvas.wrapperEl.appendChild(this.hiddenTextarea)}if(this.selected){this.setCursorByClick(options.e)}if(this.isEditing){this.__selectionStartOnMouseDown=this.selectionStart;this.initDelayedCursor(true)}})},_isObjectMoved:function(e){var pointer=this.canvas.getPointer(e);return this.__mousedownX!==pointer.x||this.__mousedownY!==pointer.y},initMouseupHandler:function(){this.on("mouseup",function(options){this.__isMousedown=false;if(!this.editable||this._isObjectMoved(options.e)){return}if(this.__lastSelected&&!this.__corner){this.enterEditing(options.e);this.initDelayedCursor(true)}this.selected=true})},setCursorByClick:function(e){var newSelectionStart=this.getSelectionStartFromPointer(e);if(e.shiftKey){if(newSelectionStartdistanceBtwLastCharAndCursor?0:1,newSelectionStart=index+offset;if(this.flipX){newSelectionStart=jlen-newSelectionStart}if(newSelectionStart>this.text.length){newSelectionStart=this.text.length}return newSelectionStart}});fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(e){var p;if(e&&this.canvas){p=this.canvas.getPointer(e)}else{this.oCoords||this.setCoords();p=this.oCoords.tl}this.hiddenTextarea=fabric.document.createElement("textarea");this.hiddenTextarea.setAttribute("autocapitalize","off");this.hiddenTextarea.style.cssText="position: absolute; top: "+p.y+"px; left: "+p.x+"px; opacity: 0;"+" width: 0px; height: 0px; z-index: -999;";if(this.canvas){this.canvas.lowerCanvasEl.parentNode.appendChild(this.hiddenTextarea)}else{fabric.document.body.appendChild(this.hiddenTextarea)}fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this));fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this));fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this));fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this));fabric.util.addListener(this.hiddenTextarea,"cut",this.cut.bind(this));fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this));fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this));fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this));fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this));if(!this._clickHandlerInitialized&&this.canvas){fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this));this._clickHandlerInitialized=true}},_keysMap:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",67:"copy",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(e){if(!this.isEditing){return}if(e.keyCode in this._keysMap){this[this._keysMap[e.keyCode]](e)}else{return}e.stopImmediatePropagation();e.preventDefault();this.canvas&&this.canvas.renderAll()},onKeyUp:function(e){if(!this.isEditing||this._copyDone){this._copyDone=false;return}if(e.keyCode in this._ctrlKeysMap&&(e.ctrlKey||e.metaKey)){this[this._ctrlKeysMap[e.keyCode]](e)}else{return}e.stopImmediatePropagation();e.preventDefault();this.canvas&&this.canvas.renderAll()},onInput:function(e){if(!this.isEditing||this.inCompositionMode){return}var offset=this.selectionStart||0,offsetEnd=this.selectionEnd||0,textLength=this.text.length,newTextLength=this.hiddenTextarea.value.length,diff,charsToInsert,start;if(newTextLength>textLength){start=this._selectionDirection==="left"?offsetEnd:offset;diff=newTextLength-textLength;charsToInsert=this.hiddenTextarea.value.slice(start,start+diff)}else{diff=newTextLength-textLength+offsetEnd-offset;charsToInsert=this.hiddenTextarea.value.slice(offset,offset+diff)}this.insertChars(charsToInsert);e.stopPropagation()},onCompositionStart:function(){this.inCompositionMode=true;this.prevCompositionLength=0;this.compositionStart=this.selectionStart},onCompositionEnd:function(){this.inCompositionMode=false},onCompositionUpdate:function(e){var data=e.data;this.selectionStart=this.compositionStart;this.selectionEnd=this.selectionEnd===this.selectionStart?this.compositionStart+this.prevCompositionLength:this.selectionEnd;this.insertChars(data,false);this.prevCompositionLength=data.length},forwardDelete:function(e){if(this.selectionStart===this.selectionEnd){if(this.selectionStart===this.text.length){return}this.moveCursorRight(e)}this.removeChars(e)},copy:function(e){if(this.selectionStart===this.selectionEnd){return}var selectedText=this.getSelectedText(),clipboardData=this._getClipboardData(e);if(clipboardData){clipboardData.setData("text",selectedText)}fabric.copiedText=selectedText;fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd);e.stopImmediatePropagation();e.preventDefault();this._copyDone=true},paste:function(e){var copiedText=null,clipboardData=this._getClipboardData(e),useCopiedStyle=true;if(clipboardData){copiedText=clipboardData.getData("text").replace(/\r/g,"");if(!fabric.copiedTextStyle||fabric.copiedText!==copiedText){useCopiedStyle=false}}else{copiedText=fabric.copiedText}if(copiedText){this.insertChars(copiedText,useCopiedStyle)}e.stopImmediatePropagation();e.preventDefault()},cut:function(e){if(this.selectionStart===this.selectionEnd){return}this.copy(e);this.removeChars(e)},_getClipboardData:function(e){return e&&e.clipboardData||fabric.window.clipboardData},getDownCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,cursorLocation=this.get2DCursorLocation(selectionProp),_char,lineLeftOffset,lineIndex=cursorLocation.lineIndex,textOnSameLineBeforeCursor=this._textLines[lineIndex].slice(0,cursorLocation.charIndex),textOnSameLineAfterCursor=this._textLines[lineIndex].slice(cursorLocation.charIndex),textOnNextLine=this._textLines[lineIndex+1]||"";if(lineIndex===this._textLines.length-1||e.metaKey||e.keyCode===34){return this.text.length-selectionProp}var widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,lineIndex);lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor);var widthOfCharsOnSameLineBeforeCursor=lineLeftOffset;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnNextLine-widthOfChar,rightEdge=widthOfCharsOnNextLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnNextLine=offsetFromRightEdgethis.text.length){this.setSelectionEnd(this.text.length)}},getUpCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,cursorLocation=this.get2DCursorLocation(selectionProp),lineIndex=cursorLocation.lineIndex;if(lineIndex===0||e.metaKey||e.keyCode===33){return selectionProp}var textOnSameLineBeforeCursor=this._textLines[lineIndex].slice(0,cursorLocation.charIndex),textOnPreviousLine=this._textLines[lineIndex-1]||"",_char,widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,cursorLocation.lineIndex),lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor),widthOfCharsOnSameLineBeforeCursor=lineLeftOffset;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnPreviousLine-widthOfChar,rightEdge=widthOfCharsOnPreviousLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnPrevLine=offsetFromRightEdge=this.text.length&&this.selectionEnd>=this.text.length){return}this.abortCursorAnimation();this._currentCursorOpacity=1;if(e.shiftKey){this.moveCursorRightWithShift(e)}else{this.moveCursorRightWithoutShift(e)}this.initDelayedCursor()},moveCursorRightWithShift:function(e){if(this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd){this._moveRight(e,"selectionStart")}else{this._selectionDirection="right";this._moveRight(e,"selectionEnd")}},moveCursorRightWithoutShift:function(e){this._selectionDirection="right";if(this.selectionStart===this.selectionEnd){this._moveRight(e,"selectionStart");this.setSelectionEnd(this.selectionStart)}else{this.setSelectionEnd(this.selectionEnd+this.getNumNewLinesInSelectedText());this.setSelectionStart(this.selectionEnd)}},removeChars:function(e){if(this.selectionStart===this.selectionEnd){this._removeCharsNearCursor(e)}else{this._removeCharsFromTo(this.selectionStart,this.selectionEnd)}this.setSelectionEnd(this.selectionStart);this._removeExtraneousStyles();this.canvas&&this.canvas.renderAll();this.setCoords();this.fire("changed");this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(e){if(this.selectionStart===0){return}if(e.metaKey){var leftLineBoundary=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftLineBoundary,this.selectionStart);this.setSelectionStart(leftLineBoundary)}else if(e.altKey){var leftWordBoundary=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftWordBoundary,this.selectionStart);this.setSelectionStart(leftWordBoundary)}else{this._removeSingleCharAndStyle(this.selectionStart);this.setSelectionStart(this.selectionStart-1)}}});(function(){var toFixed=fabric.util.toFixed,NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(lineIndex,textSpans,height,textLeftOffset,textTopOffset,textBgRects){if(!this._getLineStyle(lineIndex)){fabric.Text.prototype._setSVGTextLineText.call(this,lineIndex,textSpans,height,textLeftOffset,textTopOffset)}else{this._setSVGTextLineChars(lineIndex,textSpans,height,textLeftOffset,textBgRects)}},_setSVGTextLineChars:function(lineIndex,textSpans,height,textLeftOffset,textBgRects){var chars=this._textLines[lineIndex],charOffset=0,lineLeftOffset=this._getLineLeftOffset(this._getLineWidth(this.ctx,lineIndex))-this.width/2,lineOffset=this._getSVGLineTopOffset(lineIndex),heightOfLine=this._getHeightOfLine(this.ctx,lineIndex);for(var i=0,len=chars.length;i\n'].join("")},_createTextCharSpan:function(_char,styleDecl,lineLeftOffset,lineTopOffset,charOffset){var fillStyles=this.getSvgStyles.call(fabric.util.object.extend({visible:true,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},styleDecl));return[' ',fabric.util.string.escapeXml(_char),"\n"].join("")}})})();(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),clone=fabric.util.object.clone;fabric.Textbox=fabric.util.createClass(fabric.IText,fabric.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:0,__cachedLines:null,initialize:function(text,options){this.ctx=fabric.util.createCanvasElement().getContext("2d");this.callSuper("initialize",text,options);this.set({lockUniScaling:false,lockScalingY:true,lockScalingFlip:true,hasBorders:true});this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());this._dimensionAffectingProps.width=true},_initDimensions:function(ctx){if(this.__skipDimension){return}if(!ctx){ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx)}this.dynamicMinWidth=0;this._textLines=this._splitTextIntoLines();if(this.dynamicMinWidth>this.width){this._set("width",this.dynamicMinWidth)}this._clearCache();this.height=this._getTextHeight(ctx)},_generateStyleMap:function(){var realLineCount=0,realLineCharCount=0,charCount=0,map={};for(var i=0;i=this.width&&!lineJustStarted){lines.push(line);line="";lineWidth=wordWidth;lineJustStarted=true}if(!lineJustStarted){line+=infix}line+=word;infixWidth=this._measureText(ctx,infix,lineIndex,offset);offset++;lineJustStarted=false;if(wordWidth>largestWordWidth){largestWordWidth=wordWidth}}i&&lines.push(line);if(largestWordWidth>this.dynamicMinWidth){this.dynamicMinWidth=largestWordWidth}return lines},_splitTextIntoLines:function(){var originalAlign=this.textAlign;this.ctx.save();this._setTextStyles(this.ctx);this.textAlign="left";var lines=this._wrapText(this.ctx,this.text);this.textAlign=originalAlign;this.ctx.restore();this._textLines=lines;this._styleMap=this._generateStyleMap();return lines},setOnGroup:function(key,value){if(key==="scaleX"){this.set("scaleX",Math.abs(1/value));this.set("width",this.get("width")*value/(typeof this.__oldScaleX==="undefined"?1:this.__oldScaleX));this.__oldScaleX=value}},get2DCursorLocation:function(selectionStart){if(typeof selectionStart==="undefined"){selectionStart=this.selectionStart}var numLines=this._textLines.length,removed=0;for(var i=0;i=t.getMinWidth()){t.set("width",w);return true}}else{return setObjectScaleOverridden.call(fabric.Canvas.prototype,localMouse,transform,lockScalingX,lockScalingY,by,lockScalingFlip,_dim)}};fabric.Group.prototype._refreshControlsVisibility=function(){if(typeof fabric.Textbox==="undefined"){return}for(var i=this._objects.length;i--;){if(this._objects[i]instanceof fabric.Textbox){this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());return}}};var clone=fabric.util.object.clone;fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var prop in this._styleMap){if(!this._textLines[prop]){delete this.styles[this._styleMap[prop].line]}}},insertCharStyleObject:function(lineIndex,charIndex,style){var map=this._styleMap[lineIndex];lineIndex=map.line;charIndex=map.offset+charIndex;fabric.IText.prototype.insertCharStyleObject.apply(this,[lineIndex,charIndex,style])},insertNewlineStyleObject:function(lineIndex,charIndex,isEndOfLine){var map=this._styleMap[lineIndex];lineIndex=map.line;charIndex=map.offset+charIndex;fabric.IText.prototype.insertNewlineStyleObject.apply(this,[lineIndex,charIndex,isEndOfLine])},shiftLineStyles:function(lineIndex,offset){var clonedStyles=clone(this.styles),map=this._styleMap[lineIndex];lineIndex=map.line;for(var line in this.styles){var numericLine=parseInt(line,10);if(numericLine>lineIndex){this.styles[numericLine+offset]=clonedStyles[numericLine];if(!clonedStyles[numericLine-offset]){delete this.styles[numericLine]}}}},_getTextOnPreviousLine:function(lIndex){var textOnPreviousLine=this._textLines[lIndex-1];while(this._styleMap[lIndex-2]&&this._styleMap[lIndex-2].line===this._styleMap[lIndex-1].line){textOnPreviousLine=this._textLines[lIndex-2]+textOnPreviousLine;lIndex--}return textOnPreviousLine},removeStyleObject:function(isBeginningOfLine,index){var cursorLocation=this.get2DCursorLocation(index),map=this._styleMap[cursorLocation.lineIndex],lineIndex=map.line,charIndex=map.offset+cursorLocation.charIndex;this._removeStyleObject(isBeginningOfLine,cursorLocation,lineIndex,charIndex)}})})();(function(){var override=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(mouseOffset,prevWidth,width,index,jlen){index=override.call(this,mouseOffset,prevWidth,width,index,jlen);var tmp=0,removed=0;for(var i=0;i=index){break}if(this.text[tmp+removed]==="\n"||this.text[tmp+removed]===" "){removed++}}return index-i+removed}})();(function(){if(typeof document!=="undefined"&&typeof window!=="undefined"){return}var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;function request(url,encoding,callback){var oURL=URL.parse(url);if(!oURL.port){oURL.port=oURL.protocol.indexOf("https:")===0?443:80}var reqHandler=oURL.protocol.indexOf("https:")===0?HTTPS:HTTP,req=reqHandler.request({hostname:oURL.hostname,port:oURL.port,path:oURL.path,method:"GET"},function(response){var body="";if(encoding){response.setEncoding(encoding)}response.on("end",function(){callback(body)});response.on("data",function(chunk){if(response.statusCode===200){body+=chunk}})});req.on("error",function(err){if(err.errno===process.ECONNREFUSED){fabric.log("ECONNREFUSED: connection refused to "+oURL.hostname+":"+oURL.port)}else{fabric.log(err.message)}callback(null)});req.end()}function requestFs(path,callback){var fs=require("fs");fs.readFile(path,function(err,data){if(err){fabric.log(err);throw err}else{callback(data)}})}fabric.util.loadImage=function(url,callback,context){function createImageAndCallBack(data){if(data){img.src=new Buffer(data,"binary");img._src=url;callback&&callback.call(context,img)}else{img=null;callback&&callback.call(context,null,true)}}var img=new Image;if(url&&(url instanceof Buffer||url.indexOf("data")===0)){img.src=img._src=url;callback&&callback.call(context,img)}else if(url&&url.indexOf("http")!==0){requestFs(url,createImageAndCallBack)}else if(url){request(url,"binary",createImageAndCallBack)}else{callback&&callback.call(context,url)}};fabric.loadSVGFromURL=function(url,callback,reviver){url=url.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim();if(url.indexOf("http")!==0){requestFs(url,function(body){fabric.loadSVGFromString(body.toString(),callback,reviver)})}else{request(url,"",function(body){fabric.loadSVGFromString(body,callback,reviver)})}};fabric.loadSVGFromString=function(string,callback,reviver){var doc=(new DOMParser).parseFromString(string);fabric.parseSVGDocument(doc.documentElement,function(results,options){callback&&callback(results,options)},reviver)};fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body);callback&&callback()})};fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){var oImg=new fabric.Image(img);oImg._initConfig(object);oImg._initFilters(object.filters,function(filters){oImg.filters=filters||[];oImg._initFilters(object.resizeFilters,function(resizeFilters){oImg.resizeFilters=resizeFilters||[];callback&&callback(oImg)})})})};fabric.createCanvasForNode=function(width,height,options,nodeCanvasOptions){nodeCanvasOptions=nodeCanvasOptions||options;var canvasEl=fabric.document.createElement("canvas"),nodeCanvas=new Canvas(width||600,height||600,nodeCanvasOptions);canvasEl.style={};canvasEl.width=nodeCanvas.width;canvasEl.height=nodeCanvas.height;var FabricCanvas=fabric.Canvas||fabric.StaticCanvas,fabricCanvas=new FabricCanvas(canvasEl,options);fabricCanvas.contextContainer=nodeCanvas.getContext("2d");fabricCanvas.nodeCanvas=nodeCanvas;fabricCanvas.Font=Canvas.Font;return fabricCanvas};fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()};fabric.StaticCanvas.prototype.createJPEGStream=function(opts){return this.nodeCanvas.createJPEGStream(opts)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(width,options){origSetWidth.call(this,width,options);this.nodeCanvas.width=width;return this};if(fabric.Canvas){fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth}var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(height,options){origSetHeight.call(this,height,options);this.nodeCanvas.height=height;return this};if(fabric.Canvas){fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight}})();window.fabric=fabric;if(typeof define==="function"&&define.amd){define([],function(){return fabric})} \ No newline at end of file diff --git a/package.json b/package.json index db645007..f8eaf7fe 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "fabric", "description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.", "homepage": "http://fabricjs.com/", - "version": "1.6.0", + "version": "1.6.1", "author": "Juriy Zaytsev ", "keywords": [ "canvas",