diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5a8353180..b136265d0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+**Version 1.7.10**
+
+- Fix: correct svg export for radial gradients [#3807](https://github.com/kangax/fabric.js/pull/3807)
+- Fix: Update fireout events to export the event object [#3853](https://github.com/kangax/fabric.js/pull/3853)
+- Fix: Improve callSuper to avoid infinite loops (not all of them) [#3844](https://github.com/kangax/fabric.js/pull/3844)
+- Fix: avoid selectionBackgroundColor leak on toDataUrl [#3862](https://github.com/kangax/fabric.js/pull/3862)
+- Fix: toDatelessObject for Group [#3863](https://github.com/kangax/fabric.js/pull/3863)
+- Improvement: better caching logic for groups [#3864](https://github.com/kangax/fabric.js/pull/3864)
+- Fix: correct svg gradient export for radial in polygons [#3866](https://github.com/kangax/fabric.js/pull/3866)
+- Fix: First draw could be empty for some objects [#3870](https://github.com/kangax/fabric.js/pull/3870)
+- Fix: Always send event data to object:selected [#3871](https://github.com/kangax/fabric.js/pull/3871)
+- Improvement: reduce angle calculation error [#3872](https://github.com/kangax/fabric.js/pull/3872)
+
**Version 1.7.9**
- Fix: Avoid textarea wrapping from chome v57+ [#3804](https://github.com/kangax/fabric.js/pull/3804)
diff --git a/HEADER.js b/HEADER.js
index 3d06b294a..33eb499c6 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.7.9" };
+var fabric = fabric || { version: "1.7.10" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
index 97897e2a1..cb7002c1c 100644
--- a/ISSUE_TEMPLATE.md
+++ b/ISSUE_TEMPLATE.md
@@ -25,7 +25,7 @@ Remove the template from below and provide thoughtful commentary *and code sampl
## Version
-1.7.8
+1.7.10
## Test Case
http://jsfiddle.net/fabricjs/Da7SP/
diff --git a/dist/fabric.js b/dist/fabric.js
index 13b54c472..2d9d9894f 100644
--- a/dist/fabric.js
+++ b/dist/fabric.js
@@ -1,7 +1,7 @@
/* 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.7.9" };
+var fabric = fabric || { version: "1.7.10" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
@@ -874,7 +874,7 @@ fabric.CommonMethods = {
object = new fabric.PathGroup(elements, options);
if (typeof path !== 'undefined') {
- object.setSourcePath(path);
+ object.sourcePath = path;
}
return object;
},
@@ -1920,10 +1920,27 @@ fabric.CommonMethods = {
function Subclass() { }
function callSuper(methodName) {
- var fn = this.constructor.superclass.prototype[methodName];
+ var parentMethod = null,
+ _this = this;
+
+ // climb prototype chain to find method not equal to callee's method
+ while (_this.constructor.superclass) {
+ var superClassMethod = _this.constructor.superclass.prototype[methodName];
+ if (_this[methodName] !== superClassMethod) {
+ parentMethod = superClassMethod;
+ break;
+ }
+ // eslint-disable-next-line
+ _this = _this.constructor.superclass.prototype;
+ }
+
+ if (!parentMethod) {
+ return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this);
+ }
+
return (arguments.length > 1)
- ? fn.apply(this, slice.call(arguments, 1))
- : fn.call(this);
+ ? parentMethod.apply(this, slice.call(arguments, 1))
+ : parentMethod.call(this);
}
/**
@@ -5376,6 +5393,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
}
/* _FROM_SVG_END_ */
+ var clone = fabric.util.object.clone;
+
/**
* Gradient class
* @class fabric.Gradient
@@ -5440,7 +5459,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
for (var position in colorStops) {
var color = new fabric.Color(colorStops[position]);
this.colorStops.push({
- offset: position,
+ offset: parseFloat(position),
color: color.toRgb(),
opacity: color.getAlpha()
});
@@ -5474,17 +5493,17 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
* @return {String} SVG representation of an gradient (linear/radial)
*/
toSVG: function(object) {
- var coords = fabric.util.object.clone(this.coords),
- markup, commonAttributes;
-
+ var coords = clone(this.coords, true),
+ markup, commonAttributes, colorStops = clone(this.colorStops, true),
+ needsSwap = coords.r1 > coords.r2;
// colorStops must be sorted ascending
- this.colorStops.sort(function(a, b) {
+ 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') {
+ if (prop === 'x1' || prop === 'x2') {
coords[prop] += this.offsetX - object.width / 2;
}
else if (prop === 'y1' || prop === 'y2') {
@@ -5510,24 +5529,46 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
];
}
else if (this.type === 'radial') {
+ // svg radial gradient has just 1 radius. the biggest.
markup = [
'\n'
];
}
- for (var i = 0; i < this.colorStops.length; i++) {
+ if (this.type === 'radial') {
+ if (needsSwap) {
+ // svg goes from internal to external radius. if radius are inverted, swap color stops.
+ colorStops = colorStops.concat();
+ colorStops.reverse();
+ for (var i = 0; i < colorStops.length; i++) {
+ colorStops[i].offset = 1 - colorStops[i].offset;
+ }
+ }
+ var minRadius = Math.min(coords.r1, coords.r2);
+ if (minRadius > 0) {
+ // i have to shift all colorStops and add new one in 0.
+ var maxRadius = Math.max(coords.r1, coords.r2),
+ percentageShift = minRadius / maxRadius;
+ for (var i = 0; i < colorStops.length; i++) {
+ colorStops[i].offset += percentageShift * (1 - colorStops[i].offset);
+ }
+ }
+ }
+
+ for (var i = 0; i < colorStops.length; i++) {
+ var colorStop = colorStops[i];
markup.push(
'\n'
);
}
@@ -5579,7 +5620,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
if (typeof opacity !== 'undefined') {
color = new fabric.Color(color).setAlpha(opacity).toRgba();
}
- gradient.addColorStop(parseFloat(offset), color);
+ gradient.addColorStop(offset, color);
}
return gradient;
@@ -9497,13 +9538,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
angle = radiansToDegrees(curAngle - lastAngle + t.theta),
hasRoated = true;
- // normalize angle to positive value
- if (angle < 0) {
- angle = 360 + angle;
- }
-
- angle %= 360;
-
if (t.target.snapAngle > 0) {
var snapAngle = t.target.snapAngle,
snapThreshold = t.target.snapThreshold || snapAngle,
@@ -9516,13 +9550,21 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {
angle = rightAngleLocked;
}
+ }
- if (t.target.angle === angle) {
- hasRoated = false;
- }
+ // normalize angle to positive value
+ if (angle < 0) {
+ angle = 360 + angle;
+ }
+ angle %= 360;
+
+ if (t.target.angle === angle) {
+ hasRoated = false;
+ }
+ else {
+ t.target.angle = angle;
}
- t.target.angle = angle;
return hasRoated;
},
@@ -9657,16 +9699,16 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
if (this._hoveredTarget !== target) {
if (this._hoveredTarget) {
this.fire('mouse:out', { target: this._hoveredTarget, e: e });
- this._hoveredTarget.fire('mouseout');
+ this._hoveredTarget.fire('mouseout', { e: e });
}
this.fire('mouse:over', { target: target, e: e });
- target.fire('mouseover');
+ target.fire('mouseover', { e: e });
this._hoveredTarget = target;
}
}
else if (this._hoveredTarget) {
this.fire('mouse:out', { target: this._hoveredTarget, e: e });
- this._hoveredTarget.fire('mouseout');
+ this._hoveredTarget.fire('mouseout', { e: e });
this._hoveredTarget = null;
}
},
@@ -11104,7 +11146,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
// remove group alltogether if after removal it only contains 1 object
this.discardActiveGroup(e);
// activate last remaining object
- this.setActiveObject(activeGroup.item(0));
+ this.setActiveObject(activeGroup.item(0), e);
return;
}
}
@@ -11125,7 +11167,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
var group = this._createGroup(target);
group.addWithUpdate();
- this.setActiveGroup(group);
+ this.setActiveGroup(group, e);
this._activeObject = null;
this.fire('selection:created', { target: group, e: e });
@@ -11170,7 +11212,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
group.addWithUpdate();
this.setActiveGroup(group, e);
group.saveCoords();
- this.fire('selection:created', { target: group });
+ this.fire('selection:created', { target: group, e: e });
this.renderAll();
}
},
@@ -12388,9 +12430,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* When set to `true`, object's cache will be rerendered next render call.
* since 1.7.0
* @type Boolean
- * @default false
+ * @default true
*/
- dirty: false,
+ dirty: true,
/**
* When set to `true`, force the object to have its own cache, even if it is inside a group
@@ -12435,7 +12477,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
}
if (this.objectCaching) {
this._createCacheCanvas();
- this.setupState({ propertySet: 'cacheProperties' });
}
},
@@ -12444,6 +12485,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* @private
*/
_createCacheCanvas: function() {
+ this._cacheProperties = {};
this._cacheCanvas = fabric.document.createElement('canvas');
this._cacheContext = this._cacheCanvas.getContext('2d');
this._updateCacheCanvas();
@@ -12750,7 +12792,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
ctx.transform.apply(ctx, this.transformMatrix);
}
this.clipTo && fabric.util.clipContext(this, ctx);
- if (this.objectCaching && (!this.group || this.needsItsOwnCache)) {
+ if (this.shouldCache()) {
if (!this._cacheCanvas) {
this._createCacheCanvas();
}
@@ -12772,6 +12814,28 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
},
/**
+ * Decide if the object should cache or not.
+ * objectCaching is a global flag, wins over everything
+ * needsItsOwnCache should be used when the object drawing method requires
+ * a cache step. None of the fabric classes requires it.
+ * Generally you do not cache objects in groups because the group outside is cached.
+ * @return {Boolean}
+ */
+ shouldCache: function() {
+ return this.objectCaching &&
+ (!this.group || this.needsItsOwnCache || !this.group.isCaching());
+ },
+
+ /**
+ * Check if this object or a child object will cast a shadow
+ * used by Group.shouldCache to know if child has a shadow recursively
+ * @return {Boolean}
+ */
+ willDrawShadow: function() {
+ return !!this.shadow;
+ },
+
+ /**
* Execute the drawing operation for an object on a specified context
* @param {CanvasRenderingContext2D} ctx Context to render on
* @param {Boolean} [noTransform] When true, context is not transformed
@@ -12892,11 +12956,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
/**
* Renders controls and borders for the object
* @param {CanvasRenderingContext2D} ctx Context to render on
- * @param {Boolean} [noTransform] When true, context is not transformed
*/
- _renderControls: function(ctx, noTransform) {
- if (!this.active || noTransform
- || (this.group && this.group !== this.canvas.getActiveGroup())) {
+ _renderControls: function(ctx) {
+ if (!this.active || (this.group && this.group !== this.canvas.getActiveGroup())) {
return;
}
@@ -13697,6 +13759,13 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
*/
_getLeftTopCoords: function() {
return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');
+ },
+
+ /**
+ * Callback; invoked right before object is about to go from active to inactive
+ */
+ onDeselect: function() {
+ /* NOOP */
}
});
@@ -14155,6 +14224,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
_calcRotateMatrix: function() {
if (this.angle) {
var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta);
+ // trying to keep rounding error small, ugly but it works.
+ if (cos === 6.123233995736766e-17 || cos === -1.8369701987210297e-16) {
+ cos = 0;
+ }
return [cos, sin, -sin, cos, 0, 0];
}
return fabric.iMatrix.concat();
@@ -14552,6 +14625,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
hasStateChanged: function(propertySet) {
propertySet = propertySet || originalSet;
propertySet = '_' + propertySet;
+ if (!Object.keys(this[propertySet]).length) {
+ return true;
+ }
return !_isEqual(this[propertySet], this, true);
},
@@ -14703,12 +14779,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* Draws a colored layer behind the object, inside its selection borders.
* Requires public options: padding, selectionBackgroundColor
* this function is called when the context is transformed
+ * has checks to be skipped when the object is on a staticCanvas
* @param {CanvasRenderingContext2D} ctx Context to draw on
* @return {fabric.Object} thisArg
* @chainable
*/
drawSelectionBackground: function(ctx) {
- if (!this.selectionBackgroundColor || this.group || !this.active) {
+ if (!this.selectionBackgroundColor || this.group || !this.active ||
+ (this.canvas && !this.canvas.interactive)) {
return this;
}
ctx.save();
@@ -16380,7 +16458,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
extend = fabric.util.object.extend,
min = fabric.util.array.min,
max = fabric.util.array.max,
- toFixed = fabric.util.toFixed;
+ toFixed = fabric.util.toFixed,
+ NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
if (fabric.Polyline) {
fabric.warn('fabric.Polyline is already defined');
@@ -16499,20 +16578,25 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* @return {String} svg representation of an instance
*/
toSVG: function(reviver) {
- var points = [], addTransform,
+ var points = [], diffX, diffY,
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) + ') ';
+ diffX = this.pathOffset.x;
+ diffY = this.pathOffset.y;
+ }
+
+ for (var i = 0, len = this.points.length; i < len; i++) {
+ points.push(
+ toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',',
+ toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '
+ );
}
markup.push(
'<', this.type, ' ', this.getSvgId(),
'points="', points.join(''),
'" style="', this.getSvgStyles(),
- '" transform="', this.getSvgTransform(), addTransform,
+ '" transform="', this.getSvgTransform(),
' ', this.getSvgTransformMatrix(),
'"/>\n'
);
@@ -16834,12 +16918,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
this._setPositionDimensions(options);
- if (options.sourcePath) {
- this.setSourcePath(options.sourcePath);
- }
if (this.objectCaching) {
this._createCacheCanvas();
- this.setupState({ propertySet: 'cacheProperties' });
}
},
@@ -17766,12 +17846,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
}
this.setOptions(options);
this.setCoords();
- if (options.sourcePath) {
- this.setSourcePath(options.sourcePath);
- }
if (this.objectCaching) {
this._createCacheCanvas();
- this.setupState({ propertySet: 'cacheProperties' });
}
},
@@ -17970,7 +18046,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
fabric.PathGroup.fromObject = function(object, callback) {
var originalPaths = object.paths;
delete object.paths;
- // remove this pattern from 2.0 accepts only object
if (typeof originalPaths === 'string') {
fabric.loadSVGFromURL(originalPaths, function (elements) {
var pathUrl = originalPaths;
@@ -18078,8 +18153,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
this._objects[i].group = this;
}
- this.originalState = { };
-
if (options.originX) {
this.originX = options.originX;
}
@@ -18271,6 +18344,24 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
},
/**
+ * Returns object representation of an instance, in dataless mode.
+ * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
+ * @return {Object} object representation of an instance
+ */
+ toDatalessObject: function(propertiesToInclude) {
+ var objsToObject = this.getObjects().map(function(obj) {
+ var originalDefaults = obj.includeDefaultValues;
+ obj.includeDefaultValues = obj.group.includeDefaultValues;
+ var _obj = obj.toDatalessObject(propertiesToInclude);
+ obj.includeDefaultValues = originalDefaults;
+ return _obj;
+ });
+ return extend(this.callSuper('toDatalessObject', propertiesToInclude), {
+ objects: objsToObject
+ });
+ },
+
+ /**
* Renders instance on a given context
* @param {CanvasRenderingContext2D} ctx context to render instance on
*/
@@ -18281,6 +18372,52 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
},
/**
+ * Decide if the object should cache or not.
+ * objectCaching is a global flag, wins over everything
+ * needsItsOwnCache should be used when the object drawing method requires
+ * a cache step. None of the fabric classes requires it.
+ * Generally you do not cache objects in groups because the group outside is cached.
+ * @return {Boolean}
+ */
+ shouldCache: function() {
+ var parentCache = this.objectCaching && (!this.group || this.needsItsOwnCache || !this.group.isCaching());
+ this.caching = parentCache;
+ if (parentCache) {
+ for (var i = 0, len = this._objects.length; i < len; i++) {
+ if (this._objects[i].willDrawShadow()) {
+ this.caching = false;
+ return false;
+ }
+ }
+ }
+ return parentCache;
+ },
+
+ /**
+ * Check if this object or a child object will cast a shadow
+ * @return {Boolean}
+ */
+ willDrawShadow: function() {
+ if (this.shadow) {
+ return true;
+ }
+ for (var i = 0, len = this._objects.length; i < len; i++) {
+ if (this._objects[i].willDrawShadow()) {
+ return true;
+ }
+ }
+ return false;
+ },
+
+ /**
+ * Check if this group or its parent group are caching, recursively up
+ * @return {Boolean}
+ */
+ isCaching: function() {
+ return this.caching || this.group && this.group.isCaching();
+ },
+
+ /**
* Execute the drawing operation for an object on a specified context
* @param {CanvasRenderingContext2D} ctx Context to render on
* @param {Boolean} [noTransform] When true, context is not transformed
@@ -21929,7 +22066,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
*/
_renderChars: function(method, ctx, chars, left, top) {
// remove Text word from method var
- var shortM = method.slice(0, -4), char, width;
+ var shortM = method.slice(0, -4), _char, width;
if (this[shortM].toLive) {
var offsetX = -this.width / 2 + this[shortM].offsetX || 0,
offsetY = -this.height / 2 + this[shortM].offsetY || 0;
@@ -21942,9 +22079,9 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
var additionalSpace = this._getWidthOfCharSpacing();
chars = chars.split('');
for (var i = 0, len = chars.length; i < len; i++) {
- char = chars[i];
- width = ctx.measureText(char).width + additionalSpace;
- ctx[method](char, left, top);
+ _char = chars[i];
+ width = ctx.measureText(_char).width + additionalSpace;
+ ctx[method](_char, left, top);
left += width > 0 ? width : 0;
}
}
@@ -23386,11 +23523,11 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
additionalSpace = this._getWidthOfCharSpacing();
chars = _char.split('');
charWidth = 0;
- for (var j = 0, len = chars.length, char; j < len; j++) {
- char = chars[j];
- shouldFill && ctx.fillText(char, left + charWidth, top);
- shouldStroke && ctx.strokeText(char, left + charWidth, top);
- _charWidth = ctx.measureText(char).width + additionalSpace;
+ for (var j = 0, len = chars.length, jChar; j < len; j++) {
+ jChar = chars[j];
+ shouldFill && ctx.fillText(jChar, left + charWidth, top);
+ shouldStroke && ctx.strokeText(jChar, left + charWidth, top);
+ _charWidth = ctx.measureText(jChar).width + additionalSpace;
charWidth += _charWidth > 0 ? _charWidth : 0;
}
}
@@ -23889,6 +24026,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
onDeselect: function() {
this.isEditing && this.exitEditing();
this.selected = false;
+ this.callSuper('onDeselect');
},
/**
diff --git a/dist/fabric.min.js b/dist/fabric.min.js
index 3e9096624..31b40e2fa 100644
--- a/dist/fabric.min.js
+++ b/dist/fabric.min.js
@@ -1,9 +1,9 @@
-var fabric=fabric||{version:"1.7.9"};"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(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E")),fabric.document.createWindow?fabric.window=fabric.document.createWindow():fabric.window=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.iMatrix=[1,0,0,1,0,0],fabric.charWidthsCache={},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;r-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},fabric.CommonMethods={_setOptions:function(t){for(var e in t)this.set(e,t[e])},_initGradient:function(t,e){!t||!t.colorStops||t instanceof fabric.Gradient||this.set(e,new fabric.Gradient(t))},_initPattern:function(t,e,i){!t||!t.source||t instanceof fabric.Pattern?i&&i():this.set(e,new fabric.Pattern(t,i))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var e=fabric.util.getFunctionBody(t.clipTo);"undefined"!=typeof e&&(this.clipTo=new Function("ctx",e))}},_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,e){this[t]=e},toggle:function(t){var e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this},get:function(t){return this[t]}},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 i!==-1&&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;var i,r=e.split("."),n=r.length,s=t||fabric.window;for(i=0;ir;)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){var e,i,r,n,s,o=t.prototype;for(e=o.stateProperties.length;e--;)i=o.stateProperties[e],r=i.charAt(0).toUpperCase()+i.slice(1),n="set"+r,s="get"+r,o[s]||(o[s]=function(t){return new Function('return this.get("'+t+'")')}(i)),o[n]||(o[n]=function(t){return new Function("value",'return this.set("'+t+'", value)')}(i))},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);var n,s,o=!0,a=t.getImageData(e,i,2*r||1,2*r||1),h=a.data.length;for(n=3;n0?D-=2*f:1===c&&D<0&&(D+=2*f);for(var E=Math.ceil(Math.abs(D/f*2)),I=[],L=D/E,F=8/3*Math.sin(L/4)*Math.sin(L/4)/Math.sin(L/2),B=A+L,R=0;R=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,b,m,y=Math.sqrt,_=Math.min,x=Math.max,C=Math.abs,S=[],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;O<2;++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),C(u)<1e-12){if(C(f)<1e-12)continue;g=-d/f,0=e})}function i(t,e){return n(t,e,function(t,e){return t>>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);n>>0;i>>0;r>>0;i>>0;i>>0;n>>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(;r/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;h-1?t.prototype[r]=function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);if(this.constructor.superclass=r,"initialize"!==t)return n}}(r):t.prototype[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;i-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&&(" "+t.className+" ").indexOf(" "+e+" ")===-1&&(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(c(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(t){}o||(h=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var c;c=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=c}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}function i(i,n){n||(n={});var s=n.method?n.method.toUpperCase():"GET",o=n.onComplete||function(){},a=r(),h=n.body||n.parameters;return a.onreadystatechange=function(){4===a.readyState&&(o(a),a.onreadystatechange=e)},"GET"===s&&(h=null,"string"==typeof n.parameters&&(i=t(i,n.parameters))),a.open(s,i,!0),"POST"!==s&&"PUT"!==s||a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.send(h),a}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(t){}}();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 i(u){r=u||+new Date;var d=r>o?s:r-n;return h()?void(t.onComplete&&t.onComplete()):(a(c(d,l,f,s)),r>o?void(t.onComplete&&t.onComplete()):void e(i))}(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){var r="rgba("+parseInt(t[0]+i*(e[0]-t[0]),10)+","+parseInt(t[1]+i*(e[1]-t[1]),10)+","+parseInt(t[2]+i*(e[2]-t[2]),10);return r+=","+(t&&e?parseFloat(t[3]+i*(e[3]-t[3])):1),r+=")"}function e(e,i,r,n){var s=new fabric.Color(e).getSource(),o=new fabric.Color(i).getSource();n=n||{},fabric.util.animate(fabric.util.object.extend(n,{duration:r||500,startValue:s,endValue:o,byValue:o,easing:function(e,i,r,s){var o=n.colorEasing?n.colorEasing(e,s):1-Math.cos(e/s*(Math.PI/2));return t(i,r,o)}}))}fabric.util.animateColor=e}(),function(){function t(t,e,i,r){return ta?a:o),1===o&&1===a&&0===h&&0===c&&0===f&&0===d)return _;if((f||d)&&(x=" translate("+y(f)+" "+y(d)+") "),r=x+" matrix("+o+" 0 0 "+a+" "+h*o+" "+c*a+") ","svg"===t.nodeName){for(n=t.ownerDocument.createElement("g");t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else n=t,r=n.getAttribute("transform")+r;return n.setAttribute("transform",r),
-_}function g(t,e){for(;t&&(t=t.parentNode);)if(t.nodeName&&e.test(t.nodeName.replace("svg:",""))&&!t.getAttribute("instantiated_by_use"))return!0;return!1}var p=t.fabric||(t.fabric={}),v=p.util.object.extend,b=p.util.object.clone,m=p.util.toFixed,y=p.util.parseUnit,_=p.util.multiplyTransformMatrices,x=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,C=/^(symbol|image|marker|pattern|view|svg)$/i,S=/^(?:pattern|defs|symbol|metadata|clipPath|mask)$/i,w=/^(symbol|g|a|svg)$/i,O={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",opacity:"opacity"},T={stroke:"strokeOpacity",fill:"fillOpacity"};p.cssRules={},p.gradientDefs={},p.parseTransformAttribute=function(){function t(t,e){var i=Math.cos(e[0]),r=Math.sin(e[0]),n=0,s=0;3===e.length&&(n=e[1],s=e[2]),t[0]=i,t[1]=r,t[2]=-r,t[3]=i,t[4]=n-(i*n-r*s),t[5]=s-(r*n+i*s)}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,i){t[i]=Math.tan(p.util.degreesToRadians(e[0]))}function r(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var n=[1,0,0,1,0,0],s=p.reNum,o="(?:\\s+,?\\s*|,\\s*)",a="(?:(skewX)\\s*\\(\\s*("+s+")\\s*\\))",h="(?:(skewY)\\s*\\(\\s*("+s+")\\s*\\))",c="(?:(rotate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+")"+o+"("+s+"))?\\s*\\))",l="(?:(scale)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))",u="(?:(translate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))",f="(?:(matrix)\\s*\\(\\s*("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")\\s*\\))",d="(?:"+f+"|"+u+"|"+l+"|"+c+"|"+a+"|"+h+")",g="(?:"+d+"(?:"+o+"*"+d+")*)",v="^\\s*(?:"+g+"?)\\s*$",b=new RegExp(v),m=new RegExp(d,"g");return function(s){var o=n.concat(),a=[];if(!s||s&&!b.test(s))return o;s.replace(m,function(s){var h=new RegExp(d).exec(s).filter(function(t){return!!t}),c=h[1],l=h.slice(2).map(parseFloat);switch(c){case"translate":r(o,l);break;case"rotate":l[0]=p.util.degreesToRadians(l[0]),t(o,l);break;case"scale":e(o,l);break;case"skewX":i(o,l,2);break;case"skewY":i(o,l,1);break;case"matrix":o=l}a.push(o.concat()),o=n.concat()});for(var h=a[0];a.length>1;)a.shift(),h=p.util.multiplyTransformMatrices(h,a[0]);return h}}();var j=new RegExp("^\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*$");p.parseSVGDocument=function(t,e,i,r){if(t){f(t);var n=p.Object.__uid++,s=d(t),o=p.util.toArray(t.getElementsByTagName("*"));if(s.crossOrigin=r&&r.crossOrigin,s.svgUid=n,0===o.length&&p.isLikelyNode){o=t.selectNodes('//*[name(.)!="svg"]');for(var a=[],h=0,c=o.length;h/i,""))),n&&n.documentElement||e&&e(null),p.parseSVGDocument(n.documentElement,function(t,i){e&&e(t,i)},i,r)}t=t.replace(/^\n\s*/,"").trim(),new p.util.request(t,{method:"get",onComplete:n})},loadSVGFromString:function(t,e,i,r){t=t.trim();var n;if("undefined"!=typeof DOMParser){var s=new DOMParser;s&&s.parseFromString&&(n=s.parseFromString(t,"text/xml"))}else p.window.ActiveXObject&&(n=new ActiveXObject("Microsoft.XMLDOM"),n.async="false",n.loadXML(t.replace(//i,"")));p.parseSVGDocument(n.documentElement,function(t,i){e(t,i)},i,r)}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r,n){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0,this.parsingOptions=n},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;tt.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,i){return"undefined"==typeof i&&(i=.5),i=Math.max(Math.min(1,i),0),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 this.lerp(t)},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){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new e(this.x,this.y)}}))}("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={constructor:e,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},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;0<=l&&l<=1&&0<=u&&u<=1?(o=new e("Intersection"),o.appendPoint(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,s,o,a=new e,h=r.length,c=0;c0&&(a.status="Intersection"),a},i.Intersection.intersectPolygonPolygon=function(t,i){for(var r=new e,n=t.length,s=0;s0&&(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 i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?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;t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t&&(i=[255,255,255,0]),i||(i=e.sourceFromHex(t)),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),i||(i=[0,0,0,1]),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+(e1?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)"Infinity"===e[a]?e[a]=1:"-Infinity"===e[a]&&(e[a]=0),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(t){var e={type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform};return fabric.util.populateWithProperties(this,e,t),e},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;s\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},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\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\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=fabric.util.transformPoint,s=fabric.util.invertTransform,o=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!1,_initStatic:function(t,e){var i=fabric.StaticCanvas.prototype.renderAll.bind(this);this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_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){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){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(t){var e=fabric.util.createCanvasElement(t);if(e.style||(e.style={}),!e)throw o;if("undefined"==typeof e.getContext)throw o;return e},_initOptions:function(t){this._setOptions(t),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(t),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 this.viewportTransform[0]},setViewportTransform:function(t){var e,i=this._activeGroup,r=!1,n=!0;this.viewportTransform=t;for(var s=0,o=this._objects.length;s"),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("