diff --git a/dist/fabric.js b/dist/fabric.js
index ece84aff..1528cbc5 100644
--- a/dist/fabric.js
+++ b/dist/fabric.js
@@ -1,7 +1,7 @@
-/* build: `node build.js modules=ALL exclude=gestures minifier=uglifyjs` */
+/* build: `node build.js modules=ALL exclude=gestures,json minifier=uglifyjs` */
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
-var fabric = fabric || { version: "1.6.0" };
+var fabric = fabric || { version: "1.6.0-rc.1" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
@@ -71,497 +71,6 @@ fabric.devicePixelRatio = fabric.window.devicePixelRatio ||
1;
-/*
- json2.js
- 2014-02-04
-
- Public Domain.
-
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
- See http://www.JSON.org/js.html
-
-
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
-
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
-
-
- This file creates a global JSON object containing two methods: stringify
- and parse.
-
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
-
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
-
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or ' '),
- it contains the characters used to indent at each level.
-
- This method produces a JSON text from a JavaScript value.
-
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
-
- For example, this would serialize Dates as ISO strings.
-
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
-
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
-
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
-
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
-
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
-
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
-
- Example:
-
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
-
-
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date ?
- 'Date(' + this[key] + ')' : value;
- });
- // text is '["Date(---current time---)"]'
-
-
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
-
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
-
- Example:
-
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
-
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
-
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
-
-
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
-*/
-
-/*jslint evil: true, regexp: true */
-
-/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-if (typeof JSON !== 'object') {
- JSON = {};
-}
-
-(function () {
- 'use strict';
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function () {
-
- return isFinite(this.valueOf())
- ? this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z'
- : null;
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function () {
- return this.valueOf();
- };
- }
-
- var cx,
- escapable,
- gap,
- indent,
- meta,
- rep;
-
-
- function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string'
- ? c
- : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' : '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
-// Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
-// What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
- return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
- case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
-// Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
-// Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
- v = partial.length === 0
- ? '[]'
- : gap
- ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
- : '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === 'string') {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
- v = partial.length === 0
- ? '{}'
- : gap
- ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
- : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- };
- JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
-// If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
- JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/
- .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
- .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function'
- ? walk({'': j}, '')
- : j;
- }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
-
-
(function() {
/**
@@ -573,12 +82,12 @@ if (typeof JSON !== 'object') {
if (!this.__eventListeners[eventName]) {
return;
}
-
+ var eventListener = this.__eventListeners[eventName];
if (handler) {
- fabric.util.removeFromArray(this.__eventListeners[eventName], handler);
+ eventListener[eventListener.indexOf(handler)] = false;
}
else {
- this.__eventListeners[eventName].length = 0;
+ fabric.util.array.fill(eventListener, false);
}
}
@@ -629,7 +138,9 @@ if (typeof JSON !== 'object') {
// remove all key/value pairs (event name -> event handler)
if (arguments.length === 0) {
- this.__eventListeners = { };
+ for (eventName in this.__eventListeners) {
+ _removeEventListener.call(this, eventName);
+ }
}
// one object with key/value pairs was passed
else if (arguments.length === 1 && typeof arguments[0] === 'object') {
@@ -664,9 +175,11 @@ if (typeof JSON !== 'object') {
}
for (var i = 0, len = listenersForEvent.length; i < len; i++) {
- // avoiding try/catch for perf. reasons
- listenersForEvent[i].call(this, options || { });
+ listenersForEvent[i] && listenersForEvent[i].call(this, options || { });
}
+ this.__eventListeners[eventName] = listenersForEvent.filter(function(value) {
+ return value !== false;
+ });
return this;
}
@@ -1956,6 +1469,17 @@ fabric.Collection = {
});
}
+ /**
+ * @private
+ */
+ function fill(array, value) {
+ var k = array.length;
+ while (k--) {
+ array[k] = value;
+ }
+ return array;
+ }
+
/**
* @private
*/
@@ -1987,6 +1511,7 @@ fabric.Collection = {
* @namespace fabric.util.array
*/
fabric.util.array = {
+ fill: fill,
invoke: invoke,
min: min,
max: max
@@ -3024,7 +2549,13 @@ if (typeof console !== 'undefined') {
s = p / 4;
}
else {
- s = p / (2 * Math.PI) * Math.asin(c / a);
+ //handle the 0/0 case:
+ 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 };
}
@@ -3518,11 +3049,11 @@ if (typeof console !== 'undefined') {
function _setStrokeFillOpacity(attributes) {
for (var attr in colorAttributes) {
- if (typeof attributes[colorAttributes[attr]] === 'undefined') {
+ if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') {
continue;
}
- if (!attributes[attr]) {
+ if (typeof attributes[attr] === 'undefined') {
if (!fabric.Object.prototype[attr]) {
continue;
}
@@ -6703,14 +6234,9 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */
_setImageSmoothing: function() {
var ctx = this.getContext();
- if (typeof ctx.imageSmoothingEnabled !== 'undefined') {
- ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;
- return;
- }
- ctx.webkitImageSmoothingEnabled = this.imageSmoothingEnabled;
- ctx.mozImageSmoothingEnabled = this.imageSmoothingEnabled;
- ctx.msImageSmoothingEnabled = this.imageSmoothingEnabled;
- ctx.oImageSmoothingEnabled = this.imageSmoothingEnabled;
+ ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled
+ || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;
+ ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;
},
/**
@@ -7181,7 +6707,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */
renderAll: function () {
var canvasToDrawOn = this.contextContainer, objsToRender;
- if (this.contextTop && this.selection && !this._groupSelector) {
+ if (this.contextTop && this.selection && !this._groupSelector && !this.isDrawingMode) {
this.clearContext(this.contextTop);
}
@@ -9103,16 +8629,19 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
* @private
* @param {Number} x pointer's x coordinate
* @param {Number} y pointer's y coordinate
+ * @return {Boolean} true if the translation occurred
*/
_translateObject: function (x, y) {
- var target = this._currentTransform.target;
+ 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;
- if (!target.get('lockMovementX')) {
- target.set('left', x - this._currentTransform.offsetX);
- }
- if (!target.get('lockMovementY')) {
- target.set('top', y - this._currentTransform.offsetY);
- }
+ moveX && target.set('left', newLeft);
+ moveY && target.set('top', newTop);
+ return moveX || moveY;
},
/**
@@ -9156,15 +8685,16 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
* @param {Number} x pointer's x coordinate
* @param {Number} y pointer's y coordinate
* @param {String} by Either 'x' or 'y'
+ * @return {Boolean} true if the skewing occurred
*/
_skewObject: function (x, y, by) {
var t = this._currentTransform,
- target = t.target,
+ target = t.target, skewed = false,
lockSkewingX = target.get('lockSkewingX'),
lockSkewingY = target.get('lockSkewingY');
if ((lockSkewingX && by === 'x') || (lockSkewingY && by === 'y')) {
- return;
+ return false;
}
// Get the constraint point
@@ -9178,15 +8708,21 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY);
// Actually skew the object
- this._setObjectSkew(actualMouseByOrigin, t, by, dim);
+ skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim);
t.lastX = x;
t.lastY = y;
// Make sure the constraints apply
target.setPositionByOrigin(constraintPosition, t.originX, t.originY);
+ return skewed;
},
+ /**
+ * Set object skew
+ * @private
+ * @return {Boolean} true if the skewing occurred
+ */
_setObjectSkew: function(localMouse, transform, by, _dim) {
- var target = transform.target, newValue,
+ var target = transform.target, newValue, skewed = false,
skewSign = transform.skewSign, newDim, dimNoSkew,
otherBy, _otherBy, _by, newDimMouse, skewX, skewY;
@@ -9215,12 +8751,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
(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;
},
/**
@@ -9230,6 +8768,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
* @param {Number} y pointer's y coordinate
* @param {String} by Either 'x' or 'y' - specifies dimension constraint by which to scale an object.
* When not provided, an object is scaled by both dimensions equally
+ * @return {Boolean} true if the scaling occurred
*/
_scaleObject: function (x, y, by) {
var t = this._currentTransform,
@@ -9239,74 +8778,83 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
lockScalingFlip = target.get('lockScalingFlip');
if (lockScalingX && lockScalingY) {
- return;
+ return false;
}
// Get the constraint point
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();
+ dim = target._getTransformedDimensions(), scaled = false;
this._setLocalMouse(localMouse, t);
// Actually scale the object
- this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim);
+ scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim);
// Make sure the constraints apply
target.setPositionByOrigin(constraintPosition, t.originX, t.originY);
+ return scaled;
},
/**
* @private
+ * @return {Boolean} true if the scaling occurred
*/
_setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {
- var target = transform.target, forbidScalingX = false, forbidScalingY = false;
+ var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false,
+ changeX, changeY, scaleX, scaleY;
- transform.newScaleX = localMouse.x * target.scaleX / _dim.x;
- transform.newScaleY = localMouse.y * target.scaleY / _dim.y;
+ scaleX = localMouse.x * target.scaleX / _dim.x;
+ scaleY = localMouse.y * target.scaleY / _dim.y;
+ changeX = target.scaleX !== scaleX;
+ changeY = target.scaleY !== scaleY;
- if (lockScalingFlip && transform.newScaleX <= 0 && transform.newScaleX < target.scaleX) {
+ if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) {
forbidScalingX = true;
}
- if (lockScalingFlip && transform.newScaleY <= 0 && transform.newScaleY < target.scaleY) {
+ if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) {
forbidScalingY = true;
}
if (by === 'equally' && !lockScalingX && !lockScalingY) {
- forbidScalingX || forbidScalingY || this._scaleObjectEqually(localMouse, target, transform, _dim);
+ forbidScalingX || forbidScalingY || (scaled = this._scaleObjectEqually(localMouse, target, transform, _dim));
}
else if (!by) {
- forbidScalingX || lockScalingX || target.set('scaleX', transform.newScaleX);
- forbidScalingY || lockScalingY || target.set('scaleY', transform.newScaleY);
+ 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', transform.newScaleX);
+ forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));
}
else if (by === 'y' && !target.get('lockUniScaling')) {
- forbidScalingY || lockScalingY || target.set('scaleY', transform.newScaleY);
+ forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));
}
-
+ transform.newScaleX = scaleX;
+ transform.newScaleY = scaleY;
forbidScalingX || forbidScalingY || this._flipObject(transform, by);
-
+ return scaled;
},
/**
* @private
+ * @return {Boolean} true if the scaling occurred
*/
_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;
+ _dim.x * transform.original.scaleX / target.scaleX,
+ scaled;
// We use transform.scaleX/Y instead of target.scaleX/Y
// because the object may have a min scale and we'll loose the proportions
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;
},
/**
@@ -9391,13 +8939,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
* @private
* @param {Number} x pointer's x coordinate
* @param {Number} y pointer's y coordinate
+ * @return {Boolean} true if the rotation occurred
*/
_rotateObject: function (x, y) {
var t = this._currentTransform;
if (t.target.get('lockRotation')) {
- return;
+ return false;
}
var lastAngle = atan2(t.ey - t.top, t.ex - t.left),
@@ -9410,6 +8959,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
}
t.target.angle = angle % 360;
+ return true;
},
/**
@@ -10243,14 +9793,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
}
target.setCoords();
+ this._restoreOriginXY(target);
- // only fire :modified event if target coordinates were changed during mousedown-mouseup
- if (this.stateful && target.hasStateChanged()) {
+ if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {
this.fire('object:modified', { target: target });
target.fire('modified');
}
-
- this._restoreOriginXY(target);
},
/**
@@ -10508,6 +10056,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
}
}
else {
+
this._transformObject(e);
}
@@ -10539,37 +10088,32 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
var x = pointer.x,
y = pointer.y,
target = transform.target,
- action = transform.action;
+ action = transform.action,
+ actionPerformed = false;
if (action === 'rotate') {
- this._rotateObject(x, y);
- this._fire('rotating', target, e);
+ (actionPerformed = this._rotateObject(x, y)) && this._fire('rotating', target, e);
}
else if (action === 'scale') {
- this._onScale(e, transform, x, y);
- this._fire('scaling', target, e);
+ (actionPerformed = this._onScale(e, transform, x, y)) && this._fire('scaling', target, e);
}
else if (action === 'scaleX') {
- this._scaleObject(x, y, 'x');
- this._fire('scaling', target, e);
+ (actionPerformed = this._scaleObject(x, y, 'x')) && this._fire('scaling', target, e);
}
else if (action === 'scaleY') {
- this._scaleObject(x, y, 'y');
- this._fire('scaling', target, e);
+ (actionPerformed = this._scaleObject(x, y, 'y')) && this._fire('scaling', target, e);
}
else if (action === 'skewX') {
- this._skewObject(x, y, 'x');
- this._fire('skewing', target, e);
+ (actionPerformed = this._skewObject(x, y, 'x')) && this._fire('skewing', target, e);
}
else if (action === 'skewY') {
- this._skewObject(x, y, 'y');
- this._fire('skewing', target, e);
+ (actionPerformed = this._skewObject(x, y, 'y')) && this._fire('skewing', target, e);
}
else {
- this._translateObject(x, y);
- this._fire('moving', target, e);
+ (actionPerformed = this._translateObject(x, y)) && this._fire('moving', target, e);
this.setCursor(this.moveCursor);
}
+ transform.actionPerformed = actionPerformed;
},
/**
@@ -10600,13 +10144,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
/**
* @private
+ * @return {Boolean} true if the scaling occurred
*/
_onScale: function(e, transform, x, y) {
// rotate object only if shift key is not pressed
// and if it is not a group we are transforming
if ((e.shiftKey || this.uniScaleTransform) && !transform.target.get('lockUniScaling')) {
transform.currentAction = 'scale';
- this._scaleObject(x, y);
+ return this._scaleObject(x, y);
}
else {
// Switch from a normal resize to proportional
@@ -10615,7 +10160,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
}
transform.currentAction = 'scaleEqually';
- this._scaleObject(x, y, 'equally');
+ return this._scaleObject(x, y, 'equally');
}
},
@@ -15701,8 +15246,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* @private
* @param {CanvasRenderingContext2D} ctx Context to render on
*/
- _render: function(ctx) {
- if (!fabric.Polygon.prototype.commonRender.call(this, ctx)) {
+ _render: function(ctx, noTransform) {
+ if (!fabric.Polygon.prototype.commonRender.call(this, ctx, noTransform)) {
return;
}
this._renderFill(ctx);
@@ -17998,14 +17543,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* @return {Object} Object representation of an instance
*/
toObject: function(propertiesToInclude) {
- var filters = [ ];
+ var filters = [ ], element = this._originalElement;
this.filters.forEach(function(filterObj) {
if (filterObj) {
filters.push(filterObj.toObject());
}
});
var object = extend(this.callSuper('toObject', propertiesToInclude), {
- src: this._originalElement.src || this._originalElement._src,
+ src: element ? element.src || element._src : '',
filters: filters,
crossOrigin: this.crossOrigin,
alignX: this.alignX,
@@ -24835,10 +24380,11 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
var w = t.width * ((localMouse.x / transform.scaleX) / (t.width + t.strokeWidth));
if (w >= t.getMinWidth()) {
t.set('width', w);
+ return true;
}
}
else {
- setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform,
+ return setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform,
lockScalingX, lockScalingY, by, lockScalingFlip, _dim);
}
};
diff --git a/dist/fabric.min.js b/dist/fabric.min.js
index 1d9a3e36..b749434a 100644
--- a/dist/fabric.min.js
+++ b/dist/fabric.min.js
@@ -1,11 +1,12 @@
-var fabric=fabric||{version:"1.6.0"};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;if(typeof JSON!=="object"){JSON={}}(function(){"use strict";function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var cx,escapable,gap,indent,meta,rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;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();if(typeof ctx.imageSmoothingEnabled!=="undefined"){ctx.imageSmoothingEnabled=this.imageSmoothingEnabled;return}ctx.webkitImageSmoothingEnabled=this.imageSmoothingEnabled;ctx.mozImageSmoothingEnabled=this.imageSmoothingEnabled;ctx.msImageSmoothingEnabled=this.imageSmoothingEnabled;ctx.oImageSmoothingEnabled=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){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"}});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,lockSkewingX=target.get("lockSkewingX"),lockSkewingY=target.get("lockSkewingY");if(lockSkewingX&&by==="x"||lockSkewingY&&by==="y"){return}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);this._setObjectSkew(actualMouseByOrigin,t,by,dim);t.lastX=x;t.lastY=y;target.setPositionByOrigin(constraintPosition,t.originX,t.originY)},_setObjectSkew:function(localMouse,transform,by,_dim){var target=transform.target,newValue,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)}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)}},_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}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();this._setLocalMouse(localMouse,t);this._setObjectScale(localMouse,t,lockScalingX,lockScalingY,by,lockScalingFlip,dim);target.setPositionByOrigin(constraintPosition,t.originX,t.originY)},_setObjectScale:function(localMouse,transform,lockScalingX,lockScalingY,by,lockScalingFlip,_dim){var target=transform.target,forbidScalingX=false,forbidScalingY=false;transform.newScaleX=localMouse.x*target.scaleX/_dim.x;transform.newScaleY=localMouse.y*target.scaleY/_dim.y;if(lockScalingFlip&&transform.newScaleX<=0&&transform.newScaleXtarget.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}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},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(;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;if(action==="rotate"){this._rotateObject(x,y);this._fire("rotating",target,e)}else if(action==="scale"){this._onScale(e,transform,x,y);this._fire("scaling",target,e)}else if(action==="scaleX"){this._scaleObject(x,y,"x");this._fire("scaling",target,e)}else if(action==="scaleY"){this._scaleObject(x,y,"y");this._fire("scaling",target,e)}else if(action==="skewX"){this._skewObject(x,y,"x");this._fire("skewing",target,e)}else if(action==="skewY"){this._skewObject(x,y,"y");this._fire("skewing",target,e)}else{this._translateObject(x,y);this._fire("moving",target,e);this.setCursor(this.moveCursor)}},_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";this._scaleObject(x,y)}else{if(!transform.reset&&transform.currentAction==="scale"){this._resetCurrentTransform()}transform.currentAction="scaleEqually";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){if(!fabric.Polygon.prototype.commonRender.call(this,ctx)){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)}}else{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
+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))&ⅈ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
diff --git a/dist/fabric.min.js.gz b/dist/fabric.min.js.gz
index f1b66aef..4f04c711 100644
Binary files a/dist/fabric.min.js.gz and b/dist/fabric.min.js.gz differ
diff --git a/dist/fabric.require.js b/dist/fabric.require.js
index f07e6a86..24244cf3 100644
--- a/dist/fabric.require.js
+++ b/dist/fabric.require.js
@@ -1,11 +1,11895 @@
-var fabric=fabric||{version:"1.6.0"};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;if(typeof JSON!=="object"){JSON={}}(function(){"use strict";function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var cx,escapable,gap,indent,meta,rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;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();if(typeof ctx.imageSmoothingEnabled!=="undefined"){ctx.imageSmoothingEnabled=this.imageSmoothingEnabled;return}ctx.webkitImageSmoothingEnabled=this.imageSmoothingEnabled;ctx.mozImageSmoothingEnabled=this.imageSmoothingEnabled;ctx.msImageSmoothingEnabled=this.imageSmoothingEnabled;ctx.oImageSmoothingEnabled=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){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"}});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,lockSkewingX=target.get("lockSkewingX"),lockSkewingY=target.get("lockSkewingY");if(lockSkewingX&&by==="x"||lockSkewingY&&by==="y"){return}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);this._setObjectSkew(actualMouseByOrigin,t,by,dim);t.lastX=x;t.lastY=y;target.setPositionByOrigin(constraintPosition,t.originX,t.originY)},_setObjectSkew:function(localMouse,transform,by,_dim){var target=transform.target,newValue,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)}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)}},_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}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();this._setLocalMouse(localMouse,t);this._setObjectScale(localMouse,t,lockScalingX,lockScalingY,by,lockScalingFlip,dim);target.setPositionByOrigin(constraintPosition,t.originX,t.originY)},_setObjectScale:function(localMouse,transform,lockScalingX,lockScalingY,by,lockScalingFlip,_dim){var target=transform.target,forbidScalingX=false,forbidScalingY=false;transform.newScaleX=localMouse.x*target.scaleX/_dim.x;transform.newScaleY=localMouse.y*target.scaleY/_dim.y;if(lockScalingFlip&&transform.newScaleX<=0&&transform.newScaleXtarget.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}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},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(;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;if(action==="rotate"){this._rotateObject(x,y);this._fire("rotating",target,e)}else if(action==="scale"){this._onScale(e,transform,x,y);this._fire("scaling",target,e)}else if(action==="scaleX"){this._scaleObject(x,y,"x");this._fire("scaling",target,e)}else if(action==="scaleY"){this._scaleObject(x,y,"y");this._fire("scaling",target,e)}else if(action==="skewX"){this._skewObject(x,y,"x");this._fire("skewing",target,e)}else if(action==="skewY"){this._skewObject(x,y,"y");this._fire("skewing",target,e)}else{this._translateObject(x,y);this._fire("moving",target,e);this.setCursor(this.moveCursor)}},_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";this._scaleObject(x,y)}else{if(!transform.reset&&transform.currentAction==="scale"){this._resetCurrentTransform()}transform.currentAction="scaleEqually";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){if(!fabric.Polygon.prototype.commonRender.call(this,ctx)){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)}}else{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
+var fabric = fabric || {
+ version: "1.6.0-rc.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 < 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