From 7feb320758fe434952fba2bdefc0a14213605a04 Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Fri, 26 Apr 2019 11:48:10 -0700 Subject: [PATCH] Update JS deps Resolves #4183 --- CHANGELOG-v3.md | 1 + lib/axios/axios.js | 2 +- lib/axios/axios.js.map | 2 +- lib/bootstrap/js/bootstrap.js | 2 +- lib/bootstrap/js/bootstrap.js.map | 2 +- lib/d3/d3.js | 2 +- lib/d3/d3.js.map | 2 +- .../element-resize-detector.js | 2 +- .../element-resize-detector.js.map | 2 +- lib/fabric/fabric.js | 2 +- lib/fabric/fabric.js.map | 2 +- lib/fileupload/jquery.fileupload.js | 2 +- lib/fileupload/jquery.fileupload.js.map | 2 +- lib/garnishjs/garnish.js | 2 +- lib/garnishjs/garnish.js.map | 2 +- lib/inputmask/jquery.inputmask.bundle.js | 2 +- lib/inputmask/jquery.inputmask.bundle.js.map | 2 +- lib/jquery/jquery.js | 2 +- lib/jquery/jquery.js.map | 2 +- lib/picturefill/picturefill.js | 2 +- lib/picturefill/picturefill.js.map | 2 +- lib/selectize/selectize.js | 2 +- lib/selectize/selectize.js.map | 2 +- lib/timepicker/jquery.timepicker.js | 2 +- lib/timepicker/jquery.timepicker.js.map | 2 +- lib/velocity/velocity.js | 2 +- lib/velocity/velocity.js.map | 2 +- lib/vue-autosuggest/vue-autosuggest.js | 2 +- lib/vue-autosuggest/vue-autosuggest.js.map | 2 +- lib/vue-router/vue-router.js | 2 +- lib/vue-router/vue-router.js.map | 2 +- lib/vue/vue.js | 2 +- lib/vue/vue.js.map | 2 +- lib/vue/vue.min.js | 2 +- lib/vue/vue.min.js.map | 2 +- lib/vuex/vuex.js | 2 +- lib/vuex/vuex.js.map | 2 +- lib/xregexp/xregexp-all.js | 2 +- lib/xregexp/xregexp-all.js.map | 2 +- lib/yii2-pjax/jquery.pjax.js | 2 +- lib/yii2-pjax/jquery.pjax.js.map | 2 +- package-lock.json | 121 ++++++++---------- package.json | 2 +- 43 files changed, 97 insertions(+), 107 deletions(-) diff --git a/CHANGELOG-v3.md b/CHANGELOG-v3.md index 02fa757de11..5c32eea213c 100644 --- a/CHANGELOG-v3.md +++ b/CHANGELOG-v3.md @@ -4,6 +4,7 @@ ### Changed - Craft now registers its project config event handlers before loading plugins. ([#3943](https://github.com/craftcms/cms/issues/3943)) +- The Control Panel now uses jQuery 3.4.0. ([#4183](https://github.com/craftcms/cms/issues/4183)) ### Fixed - Fixed an error where rebuilding the project config would not typecast the `propagateEntries` and `enableVersioning` section settings correctly. ([#3695](https://github.com/craftcms/cms/issues/3695)) diff --git a/lib/axios/axios.js b/lib/axios/axios.js index cc66c842970..275fdd72eb7 100644 --- a/lib/axios/axios.js +++ b/lib/axios/axios.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(n){var r={};function o(e){if(r[e])return r[e].exports;var t=r[e]={exports:{},id:e,loaded:!1};return n[e].call(t.exports,t,t.exports,o),t.loaded=!0,t.exports}return o.m=n,o.c=r,o.p="",o(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";var r=n(2),o=n(3),i=n(5),s=n(6);function a(e){var t=new i(e),n=o(i.prototype.request,t);return r.extend(n,i.prototype,t),r.extend(n,t),n}var u=a(s);u.Axios=i,u.create=function(e){return a(r.merge(s,e))},u.Cancel=n(23),u.CancelToken=n(24),u.isCancel=n(20),u.all=function(e){return Promise.all(e)},u.spread=n(25),e.exports=u,e.exports.default=u},function(e,t,n){"use strict";var o=n(3),r=n(4),i=Object.prototype.toString;function s(e){return"[object Array]"===i.call(e)}function a(e){return null!==e&&"object"==typeof e}function u(e){return"[object Function]"===i.call(e)}function c(e,t){if(null!=e)if("object"!=typeof e&&(e=[e]),s(e))for(var n=0,r=e.length;n>8-i%1*8)){if(255<(n=r.charCodeAt(i+=.75)))throw new a;t=t<<8|n}return o}},function(e,t,n){"use strict";var a=n(2);e.exports=a.isStandardBrowserEnv()?{write:function(e,t,n,r,o,i){var s=[];s.push(e+"="+encodeURIComponent(t)),a.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),a.isString(r)&&s.push("path="+r),a.isString(o)&&s.push("domain="+o),!0===i&&s.push("secure"),document.cookie=s.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}}},function(e,t,n){"use strict";var r=n(2);function o(){this.handlers=[]}o.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},o.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},o.prototype.forEach=function(t){r.forEach(this.handlers,function(e){null!==e&&t(e)})},e.exports=o},function(e,t,n){"use strict";var r=n(2),o=n(19),i=n(20),s=n(6),a=n(21),u=n(22);function c(e){e.cancelToken&&e.cancelToken.throwIfRequested()}e.exports=function(t){return c(t),t.baseURL&&!a(t.url)&&(t.url=u(t.baseURL,t.url)),t.headers=t.headers||{},t.data=o(t.data,t.headers,t.transformRequest),t.headers=r.merge(t.headers.common||{},t.headers[t.method]||{},t.headers||{}),r.forEach(["delete","get","head","post","put","patch","common"],function(e){delete t.headers[e]}),(t.adapter||s.adapter)(t).then(function(e){return c(t),e.data=o(e.data,e.headers,t.transformResponse),e},function(e){return i(e)||(c(t),e&&e.response&&(e.response.data=o(e.response.data,e.response.headers,t.transformResponse))),Promise.reject(e)})}},function(e,t,n){"use strict";var r=n(2);e.exports=function(t,n,e){return r.forEach(e,function(e){t=e(t,n)}),t}},function(e,t){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,n){"use strict";var r=n(23);function o(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new r(e),t(n.reason))})}o.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},o.source=function(){var t;return{token:new o(function(e){t=e}),cancel:t}},e.exports=o},function(e,t){"use strict";e.exports=function(t){return function(e){return t.apply(null,e)}}}])}); +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return o={},n.m=r=[function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";var r=n(2),o=n(3),i=n(5),s=n(6);function a(e){var t=new i(e),n=o(i.prototype.request,t);return r.extend(n,i.prototype,t),r.extend(n,t),n}var u=a(s);u.Axios=i,u.create=function(e){return a(r.merge(s,e))},u.Cancel=n(23),u.CancelToken=n(24),u.isCancel=n(20),u.all=function(e){return Promise.all(e)},u.spread=n(25),e.exports=u,e.exports.default=u},function(e,t,n){"use strict";var o=n(3),r=n(4),i=Object.prototype.toString;function s(e){return"[object Array]"===i.call(e)}function a(e){return null!==e&&"object"==typeof e}function u(e){return"[object Function]"===i.call(e)}function c(e,t){if(null!=e)if("object"!=typeof e&&(e=[e]),s(e))for(var n=0,r=e.length;n>8-i%1*8)){if(255<(n=r.charCodeAt(i+=.75)))throw new a;t=t<<8|n}return o}},function(e,t,n){"use strict";var a=n(2);e.exports=a.isStandardBrowserEnv()?{write:function(e,t,n,r,o,i){var s=[];s.push(e+"="+encodeURIComponent(t)),a.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),a.isString(r)&&s.push("path="+r),a.isString(o)&&s.push("domain="+o),!0===i&&s.push("secure"),document.cookie=s.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}}},function(e,t,n){"use strict";var r=n(2);function o(){this.handlers=[]}o.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},o.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},o.prototype.forEach=function(t){r.forEach(this.handlers,function(e){null!==e&&t(e)})},e.exports=o},function(e,t,n){"use strict";var r=n(2),o=n(19),i=n(20),s=n(6),a=n(21),u=n(22);function c(e){e.cancelToken&&e.cancelToken.throwIfRequested()}e.exports=function(t){return c(t),t.baseURL&&!a(t.url)&&(t.url=u(t.baseURL,t.url)),t.headers=t.headers||{},t.data=o(t.data,t.headers,t.transformRequest),t.headers=r.merge(t.headers.common||{},t.headers[t.method]||{},t.headers||{}),r.forEach(["delete","get","head","post","put","patch","common"],function(e){delete t.headers[e]}),(t.adapter||s.adapter)(t).then(function(e){return c(t),e.data=o(e.data,e.headers,t.transformResponse),e},function(e){return i(e)||(c(t),e&&e.response&&(e.response.data=o(e.response.data,e.response.headers,t.transformResponse))),Promise.reject(e)})}},function(e,t,n){"use strict";var r=n(2);e.exports=function(t,n,e){return r.forEach(e,function(e){t=e(t,n)}),t}},function(e,t){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,n){"use strict";var r=n(23);function o(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new r(e),t(n.reason))})}o.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},o.source=function(){var t;return{token:new o(function(e){t=e}),cancel:t}},e.exports=o},function(e,t){"use strict";e.exports=function(t){return function(e){return t.apply(null,e)}}}],n.c=o,n.p="",n(0);function n(e){if(o[e])return o[e].exports;var t=o[e]={exports:{},id:e,loaded:!1};return r[e].call(t.exports,t,t.exports,n),t.loaded=!0,t.exports}var r,o}); //# sourceMappingURL=axios.js.map diff --git a/lib/axios/axios.js.map b/lib/axios/axios.js.map index 709327b1277..8e477b47428 100644 --- a/lib/axios/axios.js.map +++ b/lib/axios/axios.js.map @@ -1 +1 @@ -{"version":3,"sources":["axios.js"],"names":["root","factory","exports","module","define","amd","this","modules","installedModules","__webpack_require__","moduleId","id","loaded","call","m","c","p","utils","bind","Axios","defaults","createInstance","defaultConfig","context","instance","prototype","request","extend","axios","create","instanceConfig","merge","Cancel","CancelToken","isCancel","all","promises","Promise","spread","default","isBuffer","toString","Object","isArray","val","isObject","isFunction","forEach","obj","fn","i","l","length","key","hasOwnProperty","isArrayBuffer","isFormData","FormData","isArrayBufferView","ArrayBuffer","isView","buffer","isString","isNumber","isUndefined","isDate","isFile","isBlob","isStream","pipe","isURLSearchParams","URLSearchParams","isStandardBrowserEnv","navigator","product","window","document","result","assignValue","arguments","a","b","thisArg","trim","str","replace","args","Array","apply","constructor","readFloatLE","slice","_isBuffer","InterceptorManager","dispatchRequest","interceptors","response","config","url","method","toLowerCase","chain","undefined","promise","resolve","interceptor","unshift","fulfilled","rejected","push","then","shift","data","normalizeHeaderName","DEFAULT_CONTENT_TYPE","Content-Type","setContentTypeIfUnset","headers","value","adapter","XMLHttpRequest","process","transformRequest","JSON","stringify","transformResponse","parse","e","timeout","xsrfCookieName","xsrfHeaderName","maxContentLength","validateStatus","status","common","Accept","normalizedName","name","toUpperCase","settle","buildURL","parseHeaders","isURLSameOrigin","createError","btoa","reject","requestData","requestHeaders","loadEvent","xDomain","XDomainRequest","onprogress","ontimeout","auth","username","password","Authorization","open","params","paramsSerializer","readyState","responseURL","indexOf","responseHeaders","getAllResponseHeaders","responseType","responseText","statusText","onerror","cookies","xsrfValue","withCredentials","read","setRequestHeader","onDownloadProgress","addEventListener","onUploadProgress","upload","cancelToken","cancel","abort","send","enhanceError","message","code","error","Error","encode","encodeURIComponent","serializedParams","parts","v","toISOString","join","ignoreDuplicateOf","parsed","split","line","substr","concat","originURL","msie","test","userAgent","urlParsingNode","createElement","resolveURL","href","setAttribute","protocol","host","search","hash","hostname","port","pathname","charAt","location","requestURL","E","input","block","charCode","String","output","idx","map","charCodeAt","write","expires","path","domain","secure","cookie","Date","toGMTString","match","RegExp","decodeURIComponent","remove","now","handlers","use","eject","h","transformData","isAbsoluteURL","combineURLs","throwIfCancellationRequested","throwIfRequested","baseURL","reason","fns","__CANCEL__","relativeURL","executor","TypeError","resolvePromise","token","source","callback","arr"],"mappings":"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","file":"axios.js","sourcesContent":["/* axios v0.17.1 | (c) 2017 by Matt Zabriskie */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"axios\"] = factory();\n\telse\n\t\troot[\"axios\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1);\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar bind = __webpack_require__(3);\n\tvar Axios = __webpack_require__(5);\n\tvar defaults = __webpack_require__(6);\n\t\n\t/**\n\t * Create an instance of Axios\n\t *\n\t * @param {Object} defaultConfig The default config for the instance\n\t * @return {Axios} A new instance of Axios\n\t */\n\tfunction createInstance(defaultConfig) {\n\t var context = new Axios(defaultConfig);\n\t var instance = bind(Axios.prototype.request, context);\n\t\n\t // Copy axios.prototype to instance\n\t utils.extend(instance, Axios.prototype, context);\n\t\n\t // Copy context to instance\n\t utils.extend(instance, context);\n\t\n\t return instance;\n\t}\n\t\n\t// Create the default instance to be exported\n\tvar axios = createInstance(defaults);\n\t\n\t// Expose Axios class to allow class inheritance\n\taxios.Axios = Axios;\n\t\n\t// Factory for creating new instances\n\taxios.create = function create(instanceConfig) {\n\t return createInstance(utils.merge(defaults, instanceConfig));\n\t};\n\t\n\t// Expose Cancel & CancelToken\n\taxios.Cancel = __webpack_require__(23);\n\taxios.CancelToken = __webpack_require__(24);\n\taxios.isCancel = __webpack_require__(20);\n\t\n\t// Expose all/spread\n\taxios.all = function all(promises) {\n\t return Promise.all(promises);\n\t};\n\taxios.spread = __webpack_require__(25);\n\t\n\tmodule.exports = axios;\n\t\n\t// Allow use of default import syntax in TypeScript\n\tmodule.exports.default = axios;\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar bind = __webpack_require__(3);\n\tvar isBuffer = __webpack_require__(4);\n\t\n\t/*global toString:true*/\n\t\n\t// utils is a library of generic helper functions non-specific to axios\n\t\n\tvar toString = Object.prototype.toString;\n\t\n\t/**\n\t * Determine if a value is an Array\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an Array, otherwise false\n\t */\n\tfunction isArray(val) {\n\t return toString.call(val) === '[object Array]';\n\t}\n\t\n\t/**\n\t * Determine if a value is an ArrayBuffer\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n\t */\n\tfunction isArrayBuffer(val) {\n\t return toString.call(val) === '[object ArrayBuffer]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a FormData\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an FormData, otherwise false\n\t */\n\tfunction isFormData(val) {\n\t return (typeof FormData !== 'undefined') && (val instanceof FormData);\n\t}\n\t\n\t/**\n\t * Determine if a value is a view on an ArrayBuffer\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n\t */\n\tfunction isArrayBufferView(val) {\n\t var result;\n\t if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n\t result = ArrayBuffer.isView(val);\n\t } else {\n\t result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Determine if a value is a String\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a String, otherwise false\n\t */\n\tfunction isString(val) {\n\t return typeof val === 'string';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Number\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Number, otherwise false\n\t */\n\tfunction isNumber(val) {\n\t return typeof val === 'number';\n\t}\n\t\n\t/**\n\t * Determine if a value is undefined\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if the value is undefined, otherwise false\n\t */\n\tfunction isUndefined(val) {\n\t return typeof val === 'undefined';\n\t}\n\t\n\t/**\n\t * Determine if a value is an Object\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an Object, otherwise false\n\t */\n\tfunction isObject(val) {\n\t return val !== null && typeof val === 'object';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Date\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Date, otherwise false\n\t */\n\tfunction isDate(val) {\n\t return toString.call(val) === '[object Date]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a File\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a File, otherwise false\n\t */\n\tfunction isFile(val) {\n\t return toString.call(val) === '[object File]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Blob\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Blob, otherwise false\n\t */\n\tfunction isBlob(val) {\n\t return toString.call(val) === '[object Blob]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Function\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Function, otherwise false\n\t */\n\tfunction isFunction(val) {\n\t return toString.call(val) === '[object Function]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Stream\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Stream, otherwise false\n\t */\n\tfunction isStream(val) {\n\t return isObject(val) && isFunction(val.pipe);\n\t}\n\t\n\t/**\n\t * Determine if a value is a URLSearchParams object\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n\t */\n\tfunction isURLSearchParams(val) {\n\t return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;\n\t}\n\t\n\t/**\n\t * Trim excess whitespace off the beginning and end of a string\n\t *\n\t * @param {String} str The String to trim\n\t * @returns {String} The String freed of excess whitespace\n\t */\n\tfunction trim(str) {\n\t return str.replace(/^\\s*/, '').replace(/\\s*$/, '');\n\t}\n\t\n\t/**\n\t * Determine if we're running in a standard browser environment\n\t *\n\t * This allows axios to run in a web worker, and react-native.\n\t * Both environments support XMLHttpRequest, but not fully standard globals.\n\t *\n\t * web workers:\n\t * typeof window -> undefined\n\t * typeof document -> undefined\n\t *\n\t * react-native:\n\t * navigator.product -> 'ReactNative'\n\t */\n\tfunction isStandardBrowserEnv() {\n\t if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {\n\t return false;\n\t }\n\t return (\n\t typeof window !== 'undefined' &&\n\t typeof document !== 'undefined'\n\t );\n\t}\n\t\n\t/**\n\t * Iterate over an Array or an Object invoking a function for each item.\n\t *\n\t * If `obj` is an Array callback will be called passing\n\t * the value, index, and complete array for each item.\n\t *\n\t * If 'obj' is an Object callback will be called passing\n\t * the value, key, and complete object for each property.\n\t *\n\t * @param {Object|Array} obj The object to iterate\n\t * @param {Function} fn The callback to invoke for each item\n\t */\n\tfunction forEach(obj, fn) {\n\t // Don't bother if no value provided\n\t if (obj === null || typeof obj === 'undefined') {\n\t return;\n\t }\n\t\n\t // Force an array if not already something iterable\n\t if (typeof obj !== 'object') {\n\t /*eslint no-param-reassign:0*/\n\t obj = [obj];\n\t }\n\t\n\t if (isArray(obj)) {\n\t // Iterate over array values\n\t for (var i = 0, l = obj.length; i < l; i++) {\n\t fn.call(null, obj[i], i, obj);\n\t }\n\t } else {\n\t // Iterate over object keys\n\t for (var key in obj) {\n\t if (Object.prototype.hasOwnProperty.call(obj, key)) {\n\t fn.call(null, obj[key], key, obj);\n\t }\n\t }\n\t }\n\t}\n\t\n\t/**\n\t * Accepts varargs expecting each argument to be an object, then\n\t * immutably merges the properties of each object and returns result.\n\t *\n\t * When multiple objects contain the same key the later object in\n\t * the arguments list will take precedence.\n\t *\n\t * Example:\n\t *\n\t * ```js\n\t * var result = merge({foo: 123}, {foo: 456});\n\t * console.log(result.foo); // outputs 456\n\t * ```\n\t *\n\t * @param {Object} obj1 Object to merge\n\t * @returns {Object} Result of all merge properties\n\t */\n\tfunction merge(/* obj1, obj2, obj3, ... */) {\n\t var result = {};\n\t function assignValue(val, key) {\n\t if (typeof result[key] === 'object' && typeof val === 'object') {\n\t result[key] = merge(result[key], val);\n\t } else {\n\t result[key] = val;\n\t }\n\t }\n\t\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t forEach(arguments[i], assignValue);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Extends object a by mutably adding to it the properties of object b.\n\t *\n\t * @param {Object} a The object to be extended\n\t * @param {Object} b The object to copy properties from\n\t * @param {Object} thisArg The object to bind function to\n\t * @return {Object} The resulting value of object a\n\t */\n\tfunction extend(a, b, thisArg) {\n\t forEach(b, function assignValue(val, key) {\n\t if (thisArg && typeof val === 'function') {\n\t a[key] = bind(val, thisArg);\n\t } else {\n\t a[key] = val;\n\t }\n\t });\n\t return a;\n\t}\n\t\n\tmodule.exports = {\n\t isArray: isArray,\n\t isArrayBuffer: isArrayBuffer,\n\t isBuffer: isBuffer,\n\t isFormData: isFormData,\n\t isArrayBufferView: isArrayBufferView,\n\t isString: isString,\n\t isNumber: isNumber,\n\t isObject: isObject,\n\t isUndefined: isUndefined,\n\t isDate: isDate,\n\t isFile: isFile,\n\t isBlob: isBlob,\n\t isFunction: isFunction,\n\t isStream: isStream,\n\t isURLSearchParams: isURLSearchParams,\n\t isStandardBrowserEnv: isStandardBrowserEnv,\n\t forEach: forEach,\n\t merge: merge,\n\t extend: extend,\n\t trim: trim\n\t};\n\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = function bind(fn, thisArg) {\n\t return function wrap() {\n\t var args = new Array(arguments.length);\n\t for (var i = 0; i < args.length; i++) {\n\t args[i] = arguments[i];\n\t }\n\t return fn.apply(thisArg, args);\n\t };\n\t};\n\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports) {\n\n\t/*!\n\t * Determine if an object is a Buffer\n\t *\n\t * @author Feross Aboukhadijeh \n\t * @license MIT\n\t */\n\t\n\t// The _isBuffer check is for Safari 5-7 support, because it's missing\n\t// Object.prototype.constructor. Remove this eventually\n\tmodule.exports = function (obj) {\n\t return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n\t}\n\t\n\tfunction isBuffer (obj) {\n\t return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n\t}\n\t\n\t// For Node v0.10 support. Remove this eventually.\n\tfunction isSlowBuffer (obj) {\n\t return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n\t}\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar defaults = __webpack_require__(6);\n\tvar utils = __webpack_require__(2);\n\tvar InterceptorManager = __webpack_require__(17);\n\tvar dispatchRequest = __webpack_require__(18);\n\t\n\t/**\n\t * Create a new instance of Axios\n\t *\n\t * @param {Object} instanceConfig The default config for the instance\n\t */\n\tfunction Axios(instanceConfig) {\n\t this.defaults = instanceConfig;\n\t this.interceptors = {\n\t request: new InterceptorManager(),\n\t response: new InterceptorManager()\n\t };\n\t}\n\t\n\t/**\n\t * Dispatch a request\n\t *\n\t * @param {Object} config The config specific for this request (merged with this.defaults)\n\t */\n\tAxios.prototype.request = function request(config) {\n\t /*eslint no-param-reassign:0*/\n\t // Allow for axios('example/url'[, config]) a la fetch API\n\t if (typeof config === 'string') {\n\t config = utils.merge({\n\t url: arguments[0]\n\t }, arguments[1]);\n\t }\n\t\n\t config = utils.merge(defaults, this.defaults, { method: 'get' }, config);\n\t config.method = config.method.toLowerCase();\n\t\n\t // Hook up interceptors middleware\n\t var chain = [dispatchRequest, undefined];\n\t var promise = Promise.resolve(config);\n\t\n\t this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n\t chain.unshift(interceptor.fulfilled, interceptor.rejected);\n\t });\n\t\n\t this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n\t chain.push(interceptor.fulfilled, interceptor.rejected);\n\t });\n\t\n\t while (chain.length) {\n\t promise = promise.then(chain.shift(), chain.shift());\n\t }\n\t\n\t return promise;\n\t};\n\t\n\t// Provide aliases for supported request methods\n\tutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n\t /*eslint func-names:0*/\n\t Axios.prototype[method] = function(url, config) {\n\t return this.request(utils.merge(config || {}, {\n\t method: method,\n\t url: url\n\t }));\n\t };\n\t});\n\t\n\tutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n\t /*eslint func-names:0*/\n\t Axios.prototype[method] = function(url, data, config) {\n\t return this.request(utils.merge(config || {}, {\n\t method: method,\n\t url: url,\n\t data: data\n\t }));\n\t };\n\t});\n\t\n\tmodule.exports = Axios;\n\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar normalizeHeaderName = __webpack_require__(7);\n\t\n\tvar DEFAULT_CONTENT_TYPE = {\n\t 'Content-Type': 'application/x-www-form-urlencoded'\n\t};\n\t\n\tfunction setContentTypeIfUnset(headers, value) {\n\t if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {\n\t headers['Content-Type'] = value;\n\t }\n\t}\n\t\n\tfunction getDefaultAdapter() {\n\t var adapter;\n\t if (typeof XMLHttpRequest !== 'undefined') {\n\t // For browsers use XHR adapter\n\t adapter = __webpack_require__(8);\n\t } else if (typeof process !== 'undefined') {\n\t // For node use HTTP adapter\n\t adapter = __webpack_require__(8);\n\t }\n\t return adapter;\n\t}\n\t\n\tvar defaults = {\n\t adapter: getDefaultAdapter(),\n\t\n\t transformRequest: [function transformRequest(data, headers) {\n\t normalizeHeaderName(headers, 'Content-Type');\n\t if (utils.isFormData(data) ||\n\t utils.isArrayBuffer(data) ||\n\t utils.isBuffer(data) ||\n\t utils.isStream(data) ||\n\t utils.isFile(data) ||\n\t utils.isBlob(data)\n\t ) {\n\t return data;\n\t }\n\t if (utils.isArrayBufferView(data)) {\n\t return data.buffer;\n\t }\n\t if (utils.isURLSearchParams(data)) {\n\t setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');\n\t return data.toString();\n\t }\n\t if (utils.isObject(data)) {\n\t setContentTypeIfUnset(headers, 'application/json;charset=utf-8');\n\t return JSON.stringify(data);\n\t }\n\t return data;\n\t }],\n\t\n\t transformResponse: [function transformResponse(data) {\n\t /*eslint no-param-reassign:0*/\n\t if (typeof data === 'string') {\n\t try {\n\t data = JSON.parse(data);\n\t } catch (e) { /* Ignore */ }\n\t }\n\t return data;\n\t }],\n\t\n\t timeout: 0,\n\t\n\t xsrfCookieName: 'XSRF-TOKEN',\n\t xsrfHeaderName: 'X-XSRF-TOKEN',\n\t\n\t maxContentLength: -1,\n\t\n\t validateStatus: function validateStatus(status) {\n\t return status >= 200 && status < 300;\n\t }\n\t};\n\t\n\tdefaults.headers = {\n\t common: {\n\t 'Accept': 'application/json, text/plain, */*'\n\t }\n\t};\n\t\n\tutils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {\n\t defaults.headers[method] = {};\n\t});\n\t\n\tutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n\t defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);\n\t});\n\t\n\tmodule.exports = defaults;\n\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tmodule.exports = function normalizeHeaderName(headers, normalizedName) {\n\t utils.forEach(headers, function processHeader(value, name) {\n\t if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {\n\t headers[normalizedName] = value;\n\t delete headers[name];\n\t }\n\t });\n\t};\n\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar settle = __webpack_require__(9);\n\tvar buildURL = __webpack_require__(12);\n\tvar parseHeaders = __webpack_require__(13);\n\tvar isURLSameOrigin = __webpack_require__(14);\n\tvar createError = __webpack_require__(10);\n\tvar btoa = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || __webpack_require__(15);\n\t\n\tmodule.exports = function xhrAdapter(config) {\n\t return new Promise(function dispatchXhrRequest(resolve, reject) {\n\t var requestData = config.data;\n\t var requestHeaders = config.headers;\n\t\n\t if (utils.isFormData(requestData)) {\n\t delete requestHeaders['Content-Type']; // Let the browser set it\n\t }\n\t\n\t var request = new XMLHttpRequest();\n\t var loadEvent = 'onreadystatechange';\n\t var xDomain = false;\n\t\n\t // For IE 8/9 CORS support\n\t // Only supports POST and GET calls and doesn't returns the response headers.\n\t // DON'T do this for testing b/c XMLHttpRequest is mocked, not XDomainRequest.\n\t if ((\"production\") !== 'test' &&\n\t typeof window !== 'undefined' &&\n\t window.XDomainRequest && !('withCredentials' in request) &&\n\t !isURLSameOrigin(config.url)) {\n\t request = new window.XDomainRequest();\n\t loadEvent = 'onload';\n\t xDomain = true;\n\t request.onprogress = function handleProgress() {};\n\t request.ontimeout = function handleTimeout() {};\n\t }\n\t\n\t // HTTP basic authentication\n\t if (config.auth) {\n\t var username = config.auth.username || '';\n\t var password = config.auth.password || '';\n\t requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);\n\t }\n\t\n\t request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);\n\t\n\t // Set the request timeout in MS\n\t request.timeout = config.timeout;\n\t\n\t // Listen for ready state\n\t request[loadEvent] = function handleLoad() {\n\t if (!request || (request.readyState !== 4 && !xDomain)) {\n\t return;\n\t }\n\t\n\t // The request errored out and we didn't get a response, this will be\n\t // handled by onerror instead\n\t // With one exception: request that using file: protocol, most browsers\n\t // will return status as 0 even though it's a successful request\n\t if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n\t return;\n\t }\n\t\n\t // Prepare the response\n\t var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;\n\t var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;\n\t var response = {\n\t data: responseData,\n\t // IE sends 1223 instead of 204 (https://github.com/axios/axios/issues/201)\n\t status: request.status === 1223 ? 204 : request.status,\n\t statusText: request.status === 1223 ? 'No Content' : request.statusText,\n\t headers: responseHeaders,\n\t config: config,\n\t request: request\n\t };\n\t\n\t settle(resolve, reject, response);\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Handle low level network errors\n\t request.onerror = function handleError() {\n\t // Real errors are hidden from us by the browser\n\t // onerror should only fire if it's a network error\n\t reject(createError('Network Error', config, null, request));\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Handle timeout\n\t request.ontimeout = function handleTimeout() {\n\t reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',\n\t request));\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Add xsrf header\n\t // This is only done if running in a standard browser environment.\n\t // Specifically not if we're in a web worker, or react-native.\n\t if (utils.isStandardBrowserEnv()) {\n\t var cookies = __webpack_require__(16);\n\t\n\t // Add xsrf header\n\t var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?\n\t cookies.read(config.xsrfCookieName) :\n\t undefined;\n\t\n\t if (xsrfValue) {\n\t requestHeaders[config.xsrfHeaderName] = xsrfValue;\n\t }\n\t }\n\t\n\t // Add headers to the request\n\t if ('setRequestHeader' in request) {\n\t utils.forEach(requestHeaders, function setRequestHeader(val, key) {\n\t if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {\n\t // Remove Content-Type if data is undefined\n\t delete requestHeaders[key];\n\t } else {\n\t // Otherwise add header to the request\n\t request.setRequestHeader(key, val);\n\t }\n\t });\n\t }\n\t\n\t // Add withCredentials to request if needed\n\t if (config.withCredentials) {\n\t request.withCredentials = true;\n\t }\n\t\n\t // Add responseType to request if needed\n\t if (config.responseType) {\n\t try {\n\t request.responseType = config.responseType;\n\t } catch (e) {\n\t // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.\n\t // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.\n\t if (config.responseType !== 'json') {\n\t throw e;\n\t }\n\t }\n\t }\n\t\n\t // Handle progress if needed\n\t if (typeof config.onDownloadProgress === 'function') {\n\t request.addEventListener('progress', config.onDownloadProgress);\n\t }\n\t\n\t // Not all browsers support upload events\n\t if (typeof config.onUploadProgress === 'function' && request.upload) {\n\t request.upload.addEventListener('progress', config.onUploadProgress);\n\t }\n\t\n\t if (config.cancelToken) {\n\t // Handle cancellation\n\t config.cancelToken.promise.then(function onCanceled(cancel) {\n\t if (!request) {\n\t return;\n\t }\n\t\n\t request.abort();\n\t reject(cancel);\n\t // Clean up request\n\t request = null;\n\t });\n\t }\n\t\n\t if (requestData === undefined) {\n\t requestData = null;\n\t }\n\t\n\t // Send the request\n\t request.send(requestData);\n\t });\n\t};\n\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar createError = __webpack_require__(10);\n\t\n\t/**\n\t * Resolve or reject a Promise based on response status.\n\t *\n\t * @param {Function} resolve A function that resolves the promise.\n\t * @param {Function} reject A function that rejects the promise.\n\t * @param {object} response The response.\n\t */\n\tmodule.exports = function settle(resolve, reject, response) {\n\t var validateStatus = response.config.validateStatus;\n\t // Note: status is not exposed by XDomainRequest\n\t if (!response.status || !validateStatus || validateStatus(response.status)) {\n\t resolve(response);\n\t } else {\n\t reject(createError(\n\t 'Request failed with status code ' + response.status,\n\t response.config,\n\t null,\n\t response.request,\n\t response\n\t ));\n\t }\n\t};\n\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar enhanceError = __webpack_require__(11);\n\t\n\t/**\n\t * Create an Error with the specified message, config, error code, request and response.\n\t *\n\t * @param {string} message The error message.\n\t * @param {Object} config The config.\n\t * @param {string} [code] The error code (for example, 'ECONNABORTED').\n\t * @param {Object} [request] The request.\n\t * @param {Object} [response] The response.\n\t * @returns {Error} The created error.\n\t */\n\tmodule.exports = function createError(message, config, code, request, response) {\n\t var error = new Error(message);\n\t return enhanceError(error, config, code, request, response);\n\t};\n\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Update an Error with the specified config, error code, and response.\n\t *\n\t * @param {Error} error The error to update.\n\t * @param {Object} config The config.\n\t * @param {string} [code] The error code (for example, 'ECONNABORTED').\n\t * @param {Object} [request] The request.\n\t * @param {Object} [response] The response.\n\t * @returns {Error} The error.\n\t */\n\tmodule.exports = function enhanceError(error, config, code, request, response) {\n\t error.config = config;\n\t if (code) {\n\t error.code = code;\n\t }\n\t error.request = request;\n\t error.response = response;\n\t return error;\n\t};\n\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tfunction encode(val) {\n\t return encodeURIComponent(val).\n\t replace(/%40/gi, '@').\n\t replace(/%3A/gi, ':').\n\t replace(/%24/g, '$').\n\t replace(/%2C/gi, ',').\n\t replace(/%20/g, '+').\n\t replace(/%5B/gi, '[').\n\t replace(/%5D/gi, ']');\n\t}\n\t\n\t/**\n\t * Build a URL by appending params to the end\n\t *\n\t * @param {string} url The base of the url (e.g., http://www.google.com)\n\t * @param {object} [params] The params to be appended\n\t * @returns {string} The formatted url\n\t */\n\tmodule.exports = function buildURL(url, params, paramsSerializer) {\n\t /*eslint no-param-reassign:0*/\n\t if (!params) {\n\t return url;\n\t }\n\t\n\t var serializedParams;\n\t if (paramsSerializer) {\n\t serializedParams = paramsSerializer(params);\n\t } else if (utils.isURLSearchParams(params)) {\n\t serializedParams = params.toString();\n\t } else {\n\t var parts = [];\n\t\n\t utils.forEach(params, function serialize(val, key) {\n\t if (val === null || typeof val === 'undefined') {\n\t return;\n\t }\n\t\n\t if (utils.isArray(val)) {\n\t key = key + '[]';\n\t }\n\t\n\t if (!utils.isArray(val)) {\n\t val = [val];\n\t }\n\t\n\t utils.forEach(val, function parseValue(v) {\n\t if (utils.isDate(v)) {\n\t v = v.toISOString();\n\t } else if (utils.isObject(v)) {\n\t v = JSON.stringify(v);\n\t }\n\t parts.push(encode(key) + '=' + encode(v));\n\t });\n\t });\n\t\n\t serializedParams = parts.join('&');\n\t }\n\t\n\t if (serializedParams) {\n\t url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n\t }\n\t\n\t return url;\n\t};\n\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\t// Headers whose duplicates are ignored by node\n\t// c.f. https://nodejs.org/api/http.html#http_message_headers\n\tvar ignoreDuplicateOf = [\n\t 'age', 'authorization', 'content-length', 'content-type', 'etag',\n\t 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n\t 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n\t 'referer', 'retry-after', 'user-agent'\n\t];\n\t\n\t/**\n\t * Parse headers into an object\n\t *\n\t * ```\n\t * Date: Wed, 27 Aug 2014 08:58:49 GMT\n\t * Content-Type: application/json\n\t * Connection: keep-alive\n\t * Transfer-Encoding: chunked\n\t * ```\n\t *\n\t * @param {String} headers Headers needing to be parsed\n\t * @returns {Object} Headers parsed into an object\n\t */\n\tmodule.exports = function parseHeaders(headers) {\n\t var parsed = {};\n\t var key;\n\t var val;\n\t var i;\n\t\n\t if (!headers) { return parsed; }\n\t\n\t utils.forEach(headers.split('\\n'), function parser(line) {\n\t i = line.indexOf(':');\n\t key = utils.trim(line.substr(0, i)).toLowerCase();\n\t val = utils.trim(line.substr(i + 1));\n\t\n\t if (key) {\n\t if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {\n\t return;\n\t }\n\t if (key === 'set-cookie') {\n\t parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);\n\t } else {\n\t parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n\t }\n\t }\n\t });\n\t\n\t return parsed;\n\t};\n\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tmodule.exports = (\n\t utils.isStandardBrowserEnv() ?\n\t\n\t // Standard browser envs have full support of the APIs needed to test\n\t // whether the request URL is of the same origin as current location.\n\t (function standardBrowserEnv() {\n\t var msie = /(msie|trident)/i.test(navigator.userAgent);\n\t var urlParsingNode = document.createElement('a');\n\t var originURL;\n\t\n\t /**\n\t * Parse a URL to discover it's components\n\t *\n\t * @param {String} url The URL to be parsed\n\t * @returns {Object}\n\t */\n\t function resolveURL(url) {\n\t var href = url;\n\t\n\t if (msie) {\n\t // IE needs attribute set twice to normalize properties\n\t urlParsingNode.setAttribute('href', href);\n\t href = urlParsingNode.href;\n\t }\n\t\n\t urlParsingNode.setAttribute('href', href);\n\t\n\t // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n\t return {\n\t href: urlParsingNode.href,\n\t protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n\t host: urlParsingNode.host,\n\t search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n\t hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n\t hostname: urlParsingNode.hostname,\n\t port: urlParsingNode.port,\n\t pathname: (urlParsingNode.pathname.charAt(0) === '/') ?\n\t urlParsingNode.pathname :\n\t '/' + urlParsingNode.pathname\n\t };\n\t }\n\t\n\t originURL = resolveURL(window.location.href);\n\t\n\t /**\n\t * Determine if a URL shares the same origin as the current location\n\t *\n\t * @param {String} requestURL The URL to test\n\t * @returns {boolean} True if URL shares the same origin, otherwise false\n\t */\n\t return function isURLSameOrigin(requestURL) {\n\t var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;\n\t return (parsed.protocol === originURL.protocol &&\n\t parsed.host === originURL.host);\n\t };\n\t })() :\n\t\n\t // Non standard browser envs (web workers, react-native) lack needed support.\n\t (function nonStandardBrowserEnv() {\n\t return function isURLSameOrigin() {\n\t return true;\n\t };\n\t })()\n\t);\n\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t// btoa polyfill for IE<10 courtesy https://github.com/davidchambers/Base64.js\n\t\n\tvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n\t\n\tfunction E() {\n\t this.message = 'String contains an invalid character';\n\t}\n\tE.prototype = new Error;\n\tE.prototype.code = 5;\n\tE.prototype.name = 'InvalidCharacterError';\n\t\n\tfunction btoa(input) {\n\t var str = String(input);\n\t var output = '';\n\t for (\n\t // initialize result and counter\n\t var block, charCode, idx = 0, map = chars;\n\t // if the next str index does not exist:\n\t // change the mapping table to \"=\"\n\t // check if d has no fractional digits\n\t str.charAt(idx | 0) || (map = '=', idx % 1);\n\t // \"8 - idx % 1 * 8\" generates the sequence 2, 4, 6, 8\n\t output += map.charAt(63 & block >> 8 - idx % 1 * 8)\n\t ) {\n\t charCode = str.charCodeAt(idx += 3 / 4);\n\t if (charCode > 0xFF) {\n\t throw new E();\n\t }\n\t block = block << 8 | charCode;\n\t }\n\t return output;\n\t}\n\t\n\tmodule.exports = btoa;\n\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tmodule.exports = (\n\t utils.isStandardBrowserEnv() ?\n\t\n\t // Standard browser envs support document.cookie\n\t (function standardBrowserEnv() {\n\t return {\n\t write: function write(name, value, expires, path, domain, secure) {\n\t var cookie = [];\n\t cookie.push(name + '=' + encodeURIComponent(value));\n\t\n\t if (utils.isNumber(expires)) {\n\t cookie.push('expires=' + new Date(expires).toGMTString());\n\t }\n\t\n\t if (utils.isString(path)) {\n\t cookie.push('path=' + path);\n\t }\n\t\n\t if (utils.isString(domain)) {\n\t cookie.push('domain=' + domain);\n\t }\n\t\n\t if (secure === true) {\n\t cookie.push('secure');\n\t }\n\t\n\t document.cookie = cookie.join('; ');\n\t },\n\t\n\t read: function read(name) {\n\t var match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n\t return (match ? decodeURIComponent(match[3]) : null);\n\t },\n\t\n\t remove: function remove(name) {\n\t this.write(name, '', Date.now() - 86400000);\n\t }\n\t };\n\t })() :\n\t\n\t // Non standard browser env (web workers, react-native) lack needed support.\n\t (function nonStandardBrowserEnv() {\n\t return {\n\t write: function write() {},\n\t read: function read() { return null; },\n\t remove: function remove() {}\n\t };\n\t })()\n\t);\n\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tfunction InterceptorManager() {\n\t this.handlers = [];\n\t}\n\t\n\t/**\n\t * Add a new interceptor to the stack\n\t *\n\t * @param {Function} fulfilled The function to handle `then` for a `Promise`\n\t * @param {Function} rejected The function to handle `reject` for a `Promise`\n\t *\n\t * @return {Number} An ID used to remove interceptor later\n\t */\n\tInterceptorManager.prototype.use = function use(fulfilled, rejected) {\n\t this.handlers.push({\n\t fulfilled: fulfilled,\n\t rejected: rejected\n\t });\n\t return this.handlers.length - 1;\n\t};\n\t\n\t/**\n\t * Remove an interceptor from the stack\n\t *\n\t * @param {Number} id The ID that was returned by `use`\n\t */\n\tInterceptorManager.prototype.eject = function eject(id) {\n\t if (this.handlers[id]) {\n\t this.handlers[id] = null;\n\t }\n\t};\n\t\n\t/**\n\t * Iterate over all the registered interceptors\n\t *\n\t * This method is particularly useful for skipping over any\n\t * interceptors that may have become `null` calling `eject`.\n\t *\n\t * @param {Function} fn The function to call for each interceptor\n\t */\n\tInterceptorManager.prototype.forEach = function forEach(fn) {\n\t utils.forEach(this.handlers, function forEachHandler(h) {\n\t if (h !== null) {\n\t fn(h);\n\t }\n\t });\n\t};\n\t\n\tmodule.exports = InterceptorManager;\n\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar transformData = __webpack_require__(19);\n\tvar isCancel = __webpack_require__(20);\n\tvar defaults = __webpack_require__(6);\n\tvar isAbsoluteURL = __webpack_require__(21);\n\tvar combineURLs = __webpack_require__(22);\n\t\n\t/**\n\t * Throws a `Cancel` if cancellation has been requested.\n\t */\n\tfunction throwIfCancellationRequested(config) {\n\t if (config.cancelToken) {\n\t config.cancelToken.throwIfRequested();\n\t }\n\t}\n\t\n\t/**\n\t * Dispatch a request to the server using the configured adapter.\n\t *\n\t * @param {object} config The config that is to be used for the request\n\t * @returns {Promise} The Promise to be fulfilled\n\t */\n\tmodule.exports = function dispatchRequest(config) {\n\t throwIfCancellationRequested(config);\n\t\n\t // Support baseURL config\n\t if (config.baseURL && !isAbsoluteURL(config.url)) {\n\t config.url = combineURLs(config.baseURL, config.url);\n\t }\n\t\n\t // Ensure headers exist\n\t config.headers = config.headers || {};\n\t\n\t // Transform request data\n\t config.data = transformData(\n\t config.data,\n\t config.headers,\n\t config.transformRequest\n\t );\n\t\n\t // Flatten headers\n\t config.headers = utils.merge(\n\t config.headers.common || {},\n\t config.headers[config.method] || {},\n\t config.headers || {}\n\t );\n\t\n\t utils.forEach(\n\t ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n\t function cleanHeaderConfig(method) {\n\t delete config.headers[method];\n\t }\n\t );\n\t\n\t var adapter = config.adapter || defaults.adapter;\n\t\n\t return adapter(config).then(function onAdapterResolution(response) {\n\t throwIfCancellationRequested(config);\n\t\n\t // Transform response data\n\t response.data = transformData(\n\t response.data,\n\t response.headers,\n\t config.transformResponse\n\t );\n\t\n\t return response;\n\t }, function onAdapterRejection(reason) {\n\t if (!isCancel(reason)) {\n\t throwIfCancellationRequested(config);\n\t\n\t // Transform response data\n\t if (reason && reason.response) {\n\t reason.response.data = transformData(\n\t reason.response.data,\n\t reason.response.headers,\n\t config.transformResponse\n\t );\n\t }\n\t }\n\t\n\t return Promise.reject(reason);\n\t });\n\t};\n\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\t/**\n\t * Transform the data for a request or a response\n\t *\n\t * @param {Object|String} data The data to be transformed\n\t * @param {Array} headers The headers for the request or response\n\t * @param {Array|Function} fns A single function or Array of functions\n\t * @returns {*} The resulting transformed data\n\t */\n\tmodule.exports = function transformData(data, headers, fns) {\n\t /*eslint no-param-reassign:0*/\n\t utils.forEach(fns, function transform(fn) {\n\t data = fn(data, headers);\n\t });\n\t\n\t return data;\n\t};\n\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = function isCancel(value) {\n\t return !!(value && value.__CANCEL__);\n\t};\n\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Determines whether the specified URL is absolute\n\t *\n\t * @param {string} url The URL to test\n\t * @returns {boolean} True if the specified URL is absolute, otherwise false\n\t */\n\tmodule.exports = function isAbsoluteURL(url) {\n\t // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n\t // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n\t // by any combination of letters, digits, plus, period, or hyphen.\n\t return /^([a-z][a-z\\d\\+\\-\\.]*:)?\\/\\//i.test(url);\n\t};\n\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Creates a new URL by combining the specified URLs\n\t *\n\t * @param {string} baseURL The base URL\n\t * @param {string} relativeURL The relative URL\n\t * @returns {string} The combined URL\n\t */\n\tmodule.exports = function combineURLs(baseURL, relativeURL) {\n\t return relativeURL\n\t ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n\t : baseURL;\n\t};\n\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * A `Cancel` is an object that is thrown when an operation is canceled.\n\t *\n\t * @class\n\t * @param {string=} message The message.\n\t */\n\tfunction Cancel(message) {\n\t this.message = message;\n\t}\n\t\n\tCancel.prototype.toString = function toString() {\n\t return 'Cancel' + (this.message ? ': ' + this.message : '');\n\t};\n\t\n\tCancel.prototype.__CANCEL__ = true;\n\t\n\tmodule.exports = Cancel;\n\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar Cancel = __webpack_require__(23);\n\t\n\t/**\n\t * A `CancelToken` is an object that can be used to request cancellation of an operation.\n\t *\n\t * @class\n\t * @param {Function} executor The executor function.\n\t */\n\tfunction CancelToken(executor) {\n\t if (typeof executor !== 'function') {\n\t throw new TypeError('executor must be a function.');\n\t }\n\t\n\t var resolvePromise;\n\t this.promise = new Promise(function promiseExecutor(resolve) {\n\t resolvePromise = resolve;\n\t });\n\t\n\t var token = this;\n\t executor(function cancel(message) {\n\t if (token.reason) {\n\t // Cancellation has already been requested\n\t return;\n\t }\n\t\n\t token.reason = new Cancel(message);\n\t resolvePromise(token.reason);\n\t });\n\t}\n\t\n\t/**\n\t * Throws a `Cancel` if cancellation has been requested.\n\t */\n\tCancelToken.prototype.throwIfRequested = function throwIfRequested() {\n\t if (this.reason) {\n\t throw this.reason;\n\t }\n\t};\n\t\n\t/**\n\t * Returns an object that contains a new `CancelToken` and a function that, when called,\n\t * cancels the `CancelToken`.\n\t */\n\tCancelToken.source = function source() {\n\t var cancel;\n\t var token = new CancelToken(function executor(c) {\n\t cancel = c;\n\t });\n\t return {\n\t token: token,\n\t cancel: cancel\n\t };\n\t};\n\t\n\tmodule.exports = CancelToken;\n\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Syntactic sugar for invoking a function and expanding an array for arguments.\n\t *\n\t * Common use case would be to use `Function.prototype.apply`.\n\t *\n\t * ```js\n\t * function f(x, y, z) {}\n\t * var args = [1, 2, 3];\n\t * f.apply(null, args);\n\t * ```\n\t *\n\t * With `spread` this example can be re-written.\n\t *\n\t * ```js\n\t * spread(function(x, y, z) {})([1, 2, 3]);\n\t * ```\n\t *\n\t * @param {Function} callback\n\t * @returns {Function}\n\t */\n\tmodule.exports = function spread(callback) {\n\t return function wrap(arr) {\n\t return callback.apply(null, arr);\n\t };\n\t};\n\n\n/***/ })\n/******/ ])\n});\n;\n//# sourceMappingURL=axios.map"]} \ No newline at end of file +{"version":3,"sources":["axios.js"],"names":["root","factory","exports","module","define","amd","this","installedModules","__webpack_require__","m","modules","utils","bind","Axios","defaults","createInstance","defaultConfig","context","instance","prototype","request","extend","axios","create","instanceConfig","merge","Cancel","CancelToken","isCancel","all","promises","Promise","spread","default","isBuffer","toString","Object","isArray","val","call","isObject","isFunction","forEach","obj","fn","i","l","length","key","hasOwnProperty","isArrayBuffer","isFormData","FormData","isArrayBufferView","ArrayBuffer","isView","buffer","isString","isNumber","isUndefined","isDate","isFile","isBlob","isStream","pipe","isURLSearchParams","URLSearchParams","isStandardBrowserEnv","navigator","product","window","document","result","assignValue","arguments","a","b","thisArg","trim","str","replace","args","Array","apply","constructor","readFloatLE","slice","isSlowBuffer","_isBuffer","InterceptorManager","dispatchRequest","interceptors","response","config","url","method","toLowerCase","chain","undefined","promise","resolve","interceptor","unshift","fulfilled","rejected","push","then","shift","data","normalizeHeaderName","DEFAULT_CONTENT_TYPE","Content-Type","setContentTypeIfUnset","headers","value","adapter","XMLHttpRequest","process","transformRequest","JSON","stringify","transformResponse","parse","e","timeout","xsrfCookieName","xsrfHeaderName","maxContentLength","validateStatus","status","common","Accept","normalizedName","name","toUpperCase","settle","buildURL","parseHeaders","isURLSameOrigin","createError","btoa","reject","requestData","requestHeaders","loadEvent","xDomain","XDomainRequest","onprogress","ontimeout","auth","username","password","Authorization","open","params","paramsSerializer","readyState","responseURL","indexOf","responseHeaders","getAllResponseHeaders","responseType","responseText","statusText","onerror","cookies","xsrfValue","withCredentials","read","setRequestHeader","onDownloadProgress","addEventListener","onUploadProgress","upload","cancelToken","cancel","abort","send","enhanceError","message","code","error","Error","encode","encodeURIComponent","serializedParams","parts","v","toISOString","join","ignoreDuplicateOf","parsed","split","line","substr","concat","originURL","msie","urlParsingNode","resolveURL","href","setAttribute","protocol","host","search","hash","hostname","port","pathname","charAt","test","userAgent","createElement","location","requestURL","E","input","block","charCode","String","output","idx","map","charCodeAt","write","expires","path","domain","secure","cookie","Date","toGMTString","match","RegExp","decodeURIComponent","remove","now","handlers","use","eject","id","h","transformData","isAbsoluteURL","combineURLs","throwIfCancellationRequested","throwIfRequested","baseURL","reason","fns","__CANCEL__","relativeURL","executor","TypeError","resolvePromise","token","source","c","callback","arr","p","moduleId","loaded"],"mappings":"CACA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,IACQ,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,GAAIH,GACe,iBAAZC,QACdA,QAAe,MAAID,IAEnBD,EAAY,MAAIC,IARlB,CASGK,KAAM,WACT,OAEcC,EAAmB,GA4BvBC,EAAoBC,EA9BJC,EA0ChB,CAEJ,SAAUP,EAAQD,EAASM,GAEhCL,EAAOD,QAAUM,EAAoB,IAIhC,SAAUL,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAC5BI,EAAOJ,EAAoB,GAC3BK,EAAQL,EAAoB,GAC5BM,EAAWN,EAAoB,GAQnC,SAASO,EAAeC,GACtB,IAAIC,EAAU,IAAIJ,EAAMG,GACpBE,EAAWN,EAAKC,EAAMM,UAAUC,QAASH,GAQ7C,OALAN,EAAMU,OAAOH,EAAUL,EAAMM,UAAWF,GAGxCN,EAAMU,OAAOH,EAAUD,GAEhBC,EAIT,IAAII,EAAQP,EAAeD,GAG3BQ,EAAMT,MAAQA,EAGdS,EAAMC,OAAS,SAAgBC,GAC7B,OAAOT,EAAeJ,EAAMc,MAAMX,EAAUU,KAI9CF,EAAMI,OAASlB,EAAoB,IACnCc,EAAMK,YAAcnB,EAAoB,IACxCc,EAAMM,SAAWpB,EAAoB,IAGrCc,EAAMO,IAAM,SAAaC,GACvB,OAAOC,QAAQF,IAAIC,IAErBR,EAAMU,OAASxB,EAAoB,IAEnCL,EAAOD,QAAUoB,EAGjBnB,EAAOD,QAAQ+B,QAAUX,GAKpB,SAAUnB,EAAQD,EAASM,GAEhC,aAEA,IAAII,EAAOJ,EAAoB,GAC3B0B,EAAW1B,EAAoB,GAM/B2B,EAAWC,OAAOjB,UAAUgB,SAQhC,SAASE,EAAQC,GACf,MAA8B,mBAAvBH,EAASI,KAAKD,GA2EvB,SAASE,EAASF,GAChB,OAAe,OAARA,GAA+B,iBAARA,EAuChC,SAASG,EAAWH,GAClB,MAA8B,sBAAvBH,EAASI,KAAKD,GAoEvB,SAASI,EAAQC,EAAKC,GAEpB,GAAID,MAAAA,EAUJ,GALmB,iBAARA,IAETA,EAAM,CAACA,IAGLN,EAAQM,GAEV,IAAK,IAAIE,EAAI,EAAGC,EAAIH,EAAII,OAAQF,EAAIC,EAAGD,IACrCD,EAAGL,KAAK,KAAMI,EAAIE,GAAIA,EAAGF,QAI3B,IAAK,IAAIK,KAAOL,EACVP,OAAOjB,UAAU8B,eAAeV,KAAKI,EAAKK,IAC5CJ,EAAGL,KAAK,KAAMI,EAAIK,GAAMA,EAAKL,GA0DrCxC,EAAOD,QAAU,CACfmC,QAASA,EACTa,cAhQF,SAAuBZ,GACrB,MAA8B,yBAAvBH,EAASI,KAAKD,IAgQrBJ,SAAUA,EACViB,WAxPF,SAAoBb,GAClB,MAA4B,oBAAbc,UAA8Bd,aAAec,UAwP5DC,kBA/OF,SAA2Bf,GAOzB,MAL4B,oBAAhBgB,aAAiCA,YAAkB,OACpDA,YAAYC,OAAOjB,GAEnB,GAAUA,EAAU,QAAMA,EAAIkB,kBAAkBF,aA2O3DG,SAhOF,SAAkBnB,GAChB,MAAsB,iBAARA,GAgOdoB,SAvNF,SAAkBpB,GAChB,MAAsB,iBAARA,GAuNdE,SAAUA,EACVmB,YA/MF,SAAqBrB,GACnB,YAAsB,IAARA,GA+MdsB,OA5LF,SAAgBtB,GACd,MAA8B,kBAAvBH,EAASI,KAAKD,IA4LrBuB,OAnLF,SAAgBvB,GACd,MAA8B,kBAAvBH,EAASI,KAAKD,IAmLrBwB,OA1KF,SAAgBxB,GACd,MAA8B,kBAAvBH,EAASI,KAAKD,IA0KrBG,WAAYA,EACZsB,SAxJF,SAAkBzB,GAChB,OAAOE,EAASF,IAAQG,EAAWH,EAAI0B,OAwJvCC,kBA/IF,SAA2B3B,GACzB,MAAkC,oBAApB4B,iBAAmC5B,aAAe4B,iBA+IhEC,qBArHF,WACE,OAAyB,oBAAdC,WAAmD,gBAAtBA,UAAUC,UAI9B,oBAAXC,QACa,oBAAbC,UAgHT7B,QAASA,EACTjB,MArDF,SAASA,IACP,IAAI+C,EAAS,GACb,SAASC,EAAYnC,EAAKU,GACG,iBAAhBwB,EAAOxB,IAAoC,iBAARV,EAC5CkC,EAAOxB,GAAOvB,EAAM+C,EAAOxB,GAAMV,GAEjCkC,EAAOxB,GAAOV,EAIlB,IAAK,IAAIO,EAAI,EAAGC,EAAI4B,UAAU3B,OAAQF,EAAIC,EAAGD,IAC3CH,EAAQgC,UAAU7B,GAAI4B,GAExB,OAAOD,GAyCPnD,OA9BF,SAAgBsD,EAAGC,EAAGC,GAQpB,OAPAnC,EAAQkC,EAAG,SAAqBtC,EAAKU,GAEjC2B,EAAE3B,GADA6B,GAA0B,mBAARvC,EACX1B,EAAK0B,EAAKuC,GAEVvC,IAGNqC,GAuBPG,KA1IF,SAAcC,GACZ,OAAOA,EAAIC,QAAQ,OAAQ,IAAIA,QAAQ,OAAQ,OA+I5C,SAAU7E,EAAQD,GAEvB,aAEAC,EAAOD,QAAU,SAAc0C,EAAIiC,GACjC,OAAO,WAEL,IADA,IAAII,EAAO,IAAIC,MAAMR,UAAU3B,QACtBF,EAAI,EAAGA,EAAIoC,EAAKlC,OAAQF,IAC/BoC,EAAKpC,GAAK6B,UAAU7B,GAEtB,OAAOD,EAAGuC,MAAMN,EAASI,MAOxB,SAAU9E,EAAQD,GAevB,SAASgC,EAAUS,GACjB,QAASA,EAAIyC,aAAmD,mBAA7BzC,EAAIyC,YAAYlD,UAA2BS,EAAIyC,YAAYlD,SAASS,GALzGxC,EAAOD,QAAU,SAAUyC,GACzB,OAAc,MAAPA,IAAgBT,EAASS,IAQlC,SAAuBA,GACrB,MAAkC,mBAApBA,EAAI0C,aAAmD,mBAAd1C,EAAI2C,OAAwBpD,EAASS,EAAI2C,MAAM,EAAG,IATjEC,CAAa5C,MAAUA,EAAI6C,aAehE,SAAUrF,EAAQD,EAASM,GAEhC,aAEA,IAAIM,EAAWN,EAAoB,GAC/BG,EAAQH,EAAoB,GAC5BiF,EAAqBjF,EAAoB,IACzCkF,EAAkBlF,EAAoB,IAO1C,SAASK,EAAMW,GACblB,KAAKQ,SAAWU,EAChBlB,KAAKqF,aAAe,CAClBvE,QAAS,IAAIqE,EACbG,SAAU,IAAIH,GASlB5E,EAAMM,UAAUC,QAAU,SAAiByE,GAGnB,iBAAXA,IACTA,EAASlF,EAAMc,MAAM,CACnBqE,IAAKpB,UAAU,IACdA,UAAU,MAGfmB,EAASlF,EAAMc,MAAMX,EAAUR,KAAKQ,SAAU,CAAEiF,OAAQ,OAASF,IAC1DE,OAASF,EAAOE,OAAOC,cAG9B,IAAIC,EAAQ,CAACP,OAAiBQ,GAC1BC,EAAUpE,QAAQqE,QAAQP,GAU9B,IARAvF,KAAKqF,aAAavE,QAAQsB,QAAQ,SAAoC2D,GACpEJ,EAAMK,QAAQD,EAAYE,UAAWF,EAAYG,YAGnDlG,KAAKqF,aAAaC,SAASlD,QAAQ,SAAkC2D,GACnEJ,EAAMQ,KAAKJ,EAAYE,UAAWF,EAAYG,YAGzCP,EAAMlD,QACXoD,EAAUA,EAAQO,KAAKT,EAAMU,QAASV,EAAMU,SAG9C,OAAOR,GAITxF,EAAM+B,QAAQ,CAAC,SAAU,MAAO,OAAQ,WAAY,SAA6BqD,GAE/ElF,EAAMM,UAAU4E,GAAU,SAASD,EAAKD,GACtC,OAAOvF,KAAKc,QAAQT,EAAMc,MAAMoE,GAAU,GAAI,CAC5CE,OAAQA,EACRD,IAAKA,QAKXnF,EAAM+B,QAAQ,CAAC,OAAQ,MAAO,SAAU,SAA+BqD,GAErElF,EAAMM,UAAU4E,GAAU,SAASD,EAAKc,EAAMf,GAC5C,OAAOvF,KAAKc,QAAQT,EAAMc,MAAMoE,GAAU,GAAI,CAC5CE,OAAQA,EACRD,IAAKA,EACLc,KAAMA,QAKZzG,EAAOD,QAAUW,GAKZ,SAAUV,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAC5BqG,EAAsBrG,EAAoB,GAE1CsG,EAAuB,CACzBC,eAAgB,qCAGlB,SAASC,EAAsBC,EAASC,IACjCvG,EAAMgD,YAAYsD,IAAYtG,EAAMgD,YAAYsD,EAAQ,mBAC3DA,EAAQ,gBAAkBC,GAgB9B,IAXMC,EAWFrG,EAAW,CACbqG,SAX8B,oBAAnBC,eAETD,EAAU3G,EAAoB,GACF,oBAAZ6G,UAEhBF,EAAU3G,EAAoB,IAEzB2G,GAMPG,iBAAkB,CAAC,SAA0BV,EAAMK,GAEjD,OADAJ,EAAoBI,EAAS,gBACzBtG,EAAMwC,WAAWyD,IACnBjG,EAAMuC,cAAc0D,IACpBjG,EAAMuB,SAAS0E,IACfjG,EAAMoD,SAAS6C,IACfjG,EAAMkD,OAAO+C,IACbjG,EAAMmD,OAAO8C,GAENA,EAELjG,EAAM0C,kBAAkBuD,GACnBA,EAAKpD,OAEV7C,EAAMsD,kBAAkB2C,IAC1BI,EAAsBC,EAAS,mDACxBL,EAAKzE,YAEVxB,EAAM6B,SAASoE,IACjBI,EAAsBC,EAAS,kCACxBM,KAAKC,UAAUZ,IAEjBA,IAGTa,kBAAmB,CAAC,SAA2Bb,GAE7C,GAAoB,iBAATA,EACT,IACEA,EAAOW,KAAKG,MAAMd,GAClB,MAAOe,IAEX,OAAOf,IAGTgB,QAAS,EAETC,eAAgB,aAChBC,eAAgB,eAEhBC,kBAAmB,EAEnBC,eAAgB,SAAwBC,GACtC,OAAiB,KAAVA,GAAiBA,EAAS,MAIrCnH,EAASmG,QAAU,CACjBiB,OAAQ,CACNC,OAAU,sCAIdxH,EAAM+B,QAAQ,CAAC,SAAU,MAAO,QAAS,SAA6BqD,GACpEjF,EAASmG,QAAQlB,GAAU,KAG7BpF,EAAM+B,QAAQ,CAAC,OAAQ,MAAO,SAAU,SAA+BqD,GACrEjF,EAASmG,QAAQlB,GAAUpF,EAAMc,MAAMqF,KAGzC3G,EAAOD,QAAUY,GAKZ,SAAUX,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAEhCL,EAAOD,QAAU,SAA6B+G,EAASmB,GACrDzH,EAAM+B,QAAQuE,EAAS,SAAuBC,EAAOmB,GAC/CA,IAASD,GAAkBC,EAAKC,gBAAkBF,EAAeE,gBACnErB,EAAQmB,GAAkBlB,SACnBD,EAAQoB,QAQhB,SAAUlI,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAC5B+H,EAAS/H,EAAoB,GAC7BgI,EAAWhI,EAAoB,IAC/BiI,EAAejI,EAAoB,IACnCkI,EAAkBlI,EAAoB,IACtCmI,EAAcnI,EAAoB,IAClCoI,EAA0B,oBAAXtE,QAA0BA,OAAOsE,MAAQtE,OAAOsE,KAAKhI,KAAK0D,SAAY9D,EAAoB,IAE7GL,EAAOD,QAAU,SAAoB2F,GACnC,OAAO,IAAI9D,QAAQ,SAA4BqE,EAASyC,GACtD,IAAIC,EAAcjD,EAAOe,KACrBmC,EAAiBlD,EAAOoB,QAExBtG,EAAMwC,WAAW2F,WACZC,EAAe,gBAGxB,IAAI3H,EAAU,IAAIgG,eACd4B,EAAY,qBACZC,GAAU,EAiBd,GAXsB,oBAAX3E,SACPA,OAAO4E,gBAAoB,oBAAqB9H,GAC/CsH,EAAgB7C,EAAOC,OAC1B1E,EAAU,IAAIkD,OAAO4E,eACrBF,EAAY,SACZC,GAAU,EACV7H,EAAQ+H,WAAa,aACrB/H,EAAQgI,UAAY,cAIlBvD,EAAOwD,KAAM,CACf,IAAIC,EAAWzD,EAAOwD,KAAKC,UAAY,GACnCC,EAAW1D,EAAOwD,KAAKE,UAAY,GACvCR,EAAeS,cAAgB,SAAWZ,EAAKU,EAAW,IAAMC,GA+DlE,GA5DAnI,EAAQqI,KAAK5D,EAAOE,OAAOuC,cAAeE,EAAS3C,EAAOC,IAAKD,EAAO6D,OAAQ7D,EAAO8D,mBAAmB,GAGxGvI,EAAQwG,QAAU/B,EAAO+B,QAGzBxG,EAAQ4H,GAAa,WACnB,GAAK5H,IAAmC,IAAvBA,EAAQwI,YAAqBX,KAQvB,IAAnB7H,EAAQ6G,QAAkB7G,EAAQyI,aAAwD,IAAzCzI,EAAQyI,YAAYC,QAAQ,UAAjF,CAKA,IAAIC,EAAkB,0BAA2B3I,EAAUqH,EAAarH,EAAQ4I,yBAA2B,KAEvGpE,EAAW,CACbgB,KAFkBf,EAAOoE,cAAwC,SAAxBpE,EAAOoE,aAAiD7I,EAAQwE,SAA/BxE,EAAQ8I,aAIlFjC,OAA2B,OAAnB7G,EAAQ6G,OAAkB,IAAM7G,EAAQ6G,OAChDkC,WAA+B,OAAnB/I,EAAQ6G,OAAkB,aAAe7G,EAAQ+I,WAC7DlD,QAAS8C,EACTlE,OAAQA,EACRzE,QAASA,GAGXmH,EAAOnC,EAASyC,EAAQjD,GAGxBxE,EAAU,OAIZA,EAAQgJ,QAAU,WAGhBvB,EAAOF,EAAY,gBAAiB9C,EAAQ,KAAMzE,IAGlDA,EAAU,MAIZA,EAAQgI,UAAY,WAClBP,EAAOF,EAAY,cAAgB9C,EAAO+B,QAAU,cAAe/B,EAAQ,eACzEzE,IAGFA,EAAU,MAMRT,EAAMwD,uBAAwB,CAChC,IAAIkG,EAAU7J,EAAoB,IAG9B8J,GAAazE,EAAO0E,iBAAmB7B,EAAgB7C,EAAOC,OAASD,EAAOgC,eAC9EwC,EAAQG,KAAK3E,EAAOgC,qBACpB3B,EAEAoE,IACFvB,EAAelD,EAAOiC,gBAAkBwC,GAuB5C,GAlBI,qBAAsBlJ,GACxBT,EAAM+B,QAAQqG,EAAgB,SAA0BzG,EAAKU,QAChC,IAAhB8F,GAAqD,iBAAtB9F,EAAIgD,qBAErC+C,EAAe/F,GAGtB5B,EAAQqJ,iBAAiBzH,EAAKV,KAMhCuD,EAAO0E,kBACTnJ,EAAQmJ,iBAAkB,GAIxB1E,EAAOoE,aACT,IACE7I,EAAQ6I,aAAepE,EAAOoE,aAC9B,MAAOtC,GAGP,GAA4B,SAAxB9B,EAAOoE,aACT,MAAMtC,EAM6B,mBAA9B9B,EAAO6E,oBAChBtJ,EAAQuJ,iBAAiB,WAAY9E,EAAO6E,oBAIP,mBAA5B7E,EAAO+E,kBAAmCxJ,EAAQyJ,QAC3DzJ,EAAQyJ,OAAOF,iBAAiB,WAAY9E,EAAO+E,kBAGjD/E,EAAOiF,aAETjF,EAAOiF,YAAY3E,QAAQO,KAAK,SAAoBqE,GAC7C3J,IAILA,EAAQ4J,QACRnC,EAAOkC,GAEP3J,EAAU,aAIM8E,IAAhB4C,IACFA,EAAc,MAIhB1H,EAAQ6J,KAAKnC,OAOZ,SAAU3I,EAAQD,EAASM,GAEhC,aAEA,IAAImI,EAAcnI,EAAoB,IAStCL,EAAOD,QAAU,SAAgBkG,EAASyC,EAAQjD,GAChD,IAAIoC,EAAiBpC,EAASC,OAAOmC,eAEhCpC,EAASqC,QAAWD,IAAkBA,EAAepC,EAASqC,QAGjEY,EAAOF,EACL,mCAAqC/C,EAASqC,OAC9CrC,EAASC,OACT,KACAD,EAASxE,QACTwE,IAPFQ,EAAQR,KAeP,SAAUzF,EAAQD,EAASM,GAEhC,aAEA,IAAI0K,EAAe1K,EAAoB,IAYvCL,EAAOD,QAAU,SAAqBiL,EAAStF,EAAQuF,EAAMhK,EAASwE,GACpE,IAAIyF,EAAQ,IAAIC,MAAMH,GACtB,OAAOD,EAAaG,EAAOxF,EAAQuF,EAAMhK,EAASwE,KAM/C,SAAUzF,EAAQD,GAEvB,aAYAC,EAAOD,QAAU,SAAsBmL,EAAOxF,EAAQuF,EAAMhK,EAASwE,GAOnE,OANAyF,EAAMxF,OAASA,EACXuF,IACFC,EAAMD,KAAOA,GAEfC,EAAMjK,QAAUA,EAChBiK,EAAMzF,SAAWA,EACVyF,IAMJ,SAAUlL,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAEhC,SAAS+K,EAAOjJ,GACd,OAAOkJ,mBAAmBlJ,GACxB0C,QAAQ,QAAS,KACjBA,QAAQ,QAAS,KACjBA,QAAQ,OAAQ,KAChBA,QAAQ,QAAS,KACjBA,QAAQ,OAAQ,KAChBA,QAAQ,QAAS,KACjBA,QAAQ,QAAS,KAUrB7E,EAAOD,QAAU,SAAkB4F,EAAK4D,EAAQC,GAE9C,IAAKD,EACH,OAAO5D,EAGT,IAAI2F,EACJ,GAAI9B,EACF8B,EAAmB9B,EAAiBD,QAC/B,GAAI/I,EAAMsD,kBAAkByF,GACjC+B,EAAmB/B,EAAOvH,eACrB,CACL,IAAIuJ,EAAQ,GAEZ/K,EAAM+B,QAAQgH,EAAQ,SAAmBpH,EAAKU,GACxCV,MAAAA,IAIA3B,EAAM0B,QAAQC,KAChBU,GAAY,MAGTrC,EAAM0B,QAAQC,KACjBA,EAAM,CAACA,IAGT3B,EAAM+B,QAAQJ,EAAK,SAAoBqJ,GACjChL,EAAMiD,OAAO+H,GACfA,EAAIA,EAAEC,cACGjL,EAAM6B,SAASmJ,KACxBA,EAAIpE,KAAKC,UAAUmE,IAErBD,EAAMjF,KAAK8E,EAAOvI,GAAO,IAAMuI,EAAOI,SAI1CF,EAAmBC,EAAMG,KAAK,KAOhC,OAJIJ,IACF3F,KAA8B,IAAtBA,EAAIgE,QAAQ,KAAc,IAAM,KAAO2B,GAG1C3F,IAMJ,SAAU3F,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAI5BsL,EAAoB,CACtB,MAAO,gBAAiB,iBAAkB,eAAgB,OAC1D,UAAW,OAAQ,OAAQ,oBAAqB,sBAChD,gBAAiB,WAAY,eAAgB,sBAC7C,UAAW,cAAe,cAgB5B3L,EAAOD,QAAU,SAAsB+G,GACrC,IACIjE,EACAV,EACAO,EAHAkJ,EAAS,GAKb,OAAK9E,GAELtG,EAAM+B,QAAQuE,EAAQ+E,MAAM,MAAO,SAAgBC,GAKjD,GAJApJ,EAAIoJ,EAAKnC,QAAQ,KACjB9G,EAAMrC,EAAMmE,KAAKmH,EAAKC,OAAO,EAAGrJ,IAAImD,cACpC1D,EAAM3B,EAAMmE,KAAKmH,EAAKC,OAAOrJ,EAAI,IAE7BG,EAAK,CACP,GAAI+I,EAAO/I,IAA0C,GAAlC8I,EAAkBhC,QAAQ9G,GAC3C,OAGA+I,EAAO/I,GADG,eAARA,GACa+I,EAAO/I,GAAO+I,EAAO/I,GAAO,IAAImJ,OAAO,CAAC7J,IAEzCyJ,EAAO/I,GAAO+I,EAAO/I,GAAO,KAAOV,EAAMA,KAKtDyJ,IAMJ,SAAU5L,EAAQD,EAASM,GAEhC,aAEA,IAUQ4L,EAFAC,EACAC,EATJ3L,EAAQH,EAAoB,GAkB5B,SAAS+L,EAAWzG,GAClB,IAAI0G,EAAO1G,EAWX,OATIuG,IAEFC,EAAeG,aAAa,OAAQD,GACpCA,EAAOF,EAAeE,MAGxBF,EAAeG,aAAa,OAAQD,GAG7B,CACLA,KAAMF,EAAeE,KACrBE,SAAUJ,EAAeI,SAAWJ,EAAeI,SAAS1H,QAAQ,KAAM,IAAM,GAChF2H,KAAML,EAAeK,KACrBC,OAAQN,EAAeM,OAASN,EAAeM,OAAO5H,QAAQ,MAAO,IAAM,GAC3E6H,KAAMP,EAAeO,KAAOP,EAAeO,KAAK7H,QAAQ,KAAM,IAAM,GACpE8H,SAAUR,EAAeQ,SACzBC,KAAMT,EAAeS,KACrBC,SAAiD,MAAtCV,EAAeU,SAASC,OAAO,GAChCX,EAAeU,SACf,IAAMV,EAAeU,UAtCvC7M,EAAOD,QACLS,EAAMwD,wBAKAkI,EAAO,kBAAkBa,KAAK9I,UAAU+I,WACxCb,EAAiB/H,SAAS6I,cAAc,KAmC5ChB,EAAYG,EAAWjI,OAAO+I,SAASb,MAQhC,SAAyBc,GAC9B,IAAIvB,EAAUpL,EAAM8C,SAAS6J,GAAef,EAAWe,GAAcA,EACrE,OAAQvB,EAAOW,WAAaN,EAAUM,UAChCX,EAAOY,OAASP,EAAUO,OAM3B,WACL,OAAO,IAQR,SAAUxM,EAAQD,GAEvB,aAMA,SAASqN,IACPjN,KAAK6K,QAAU,wCAEjBoC,EAAEpM,UAAY,IAAImK,OACNF,KAAO,EACnBmC,EAAEpM,UAAUkH,KAAO,wBAwBnBlI,EAAOD,QAtBP,SAAcsN,GAGZ,IAFA,IAIMC,EAAOC,EAJT3I,EAAM4I,OAAOH,GACbI,EAAS,GAGUC,EAAM,EAAGC,EAdtB,oEAkBR/I,EAAIkI,OAAa,EAANY,KAAaC,EAAM,IAAKD,EAAM,GAEzCD,GAAUE,EAAIb,OAAO,GAAKQ,GAAS,EAAII,EAAM,EAAI,GACjD,CAEA,GAAe,KADfH,EAAW3I,EAAIgJ,WAAWF,GAAO,MAE/B,MAAM,IAAIN,EAEZE,EAAQA,GAAS,EAAIC,EAEvB,OAAOE,IAQJ,SAAUzN,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAEhCL,EAAOD,QACLS,EAAMwD,uBAIG,CACL6J,MAAO,SAAe3F,EAAMnB,EAAO+G,EAASC,EAAMC,EAAQC,GACxD,IAAIC,EAAS,GACbA,EAAO5H,KAAK4B,EAAO,IAAMmD,mBAAmBtE,IAExCvG,EAAM+C,SAASuK,IACjBI,EAAO5H,KAAK,WAAa,IAAI6H,KAAKL,GAASM,eAGzC5N,EAAM8C,SAASyK,IACjBG,EAAO5H,KAAK,QAAUyH,GAGpBvN,EAAM8C,SAAS0K,IACjBE,EAAO5H,KAAK,UAAY0H,IAGX,IAAXC,GACFC,EAAO5H,KAAK,UAGdlC,SAAS8J,OAASA,EAAOxC,KAAK,OAGhCrB,KAAM,SAAcnC,GAClB,IAAImG,EAAQjK,SAAS8J,OAAOG,MAAM,IAAIC,OAAO,aAAepG,EAAO,cACnE,OAAQmG,EAAQE,mBAAmBF,EAAM,IAAM,MAGjDG,OAAQ,SAAgBtG,GACtB/H,KAAK0N,MAAM3F,EAAM,GAAIiG,KAAKM,MAAQ,SAO/B,CACLZ,MAAO,aACPxD,KAAM,WAAkB,OAAO,MAC/BmE,OAAQ,eAQT,SAAUxO,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAEhC,SAASiF,IACPnF,KAAKuO,SAAW,GAWlBpJ,EAAmBtE,UAAU2N,IAAM,SAAavI,EAAWC,GAKzD,OAJAlG,KAAKuO,SAASpI,KAAK,CACjBF,UAAWA,EACXC,SAAUA,IAELlG,KAAKuO,SAAS9L,OAAS,GAQhC0C,EAAmBtE,UAAU4N,MAAQ,SAAeC,GAC9C1O,KAAKuO,SAASG,KAChB1O,KAAKuO,SAASG,GAAM,OAYxBvJ,EAAmBtE,UAAUuB,QAAU,SAAiBE,GACtDjC,EAAM+B,QAAQpC,KAAKuO,SAAU,SAAwBI,GACzC,OAANA,GACFrM,EAAGqM,MAKT9O,EAAOD,QAAUuF,GAKZ,SAAUtF,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAC5B0O,EAAgB1O,EAAoB,IACpCoB,EAAWpB,EAAoB,IAC/BM,EAAWN,EAAoB,GAC/B2O,EAAgB3O,EAAoB,IACpC4O,EAAc5O,EAAoB,IAKtC,SAAS6O,EAA6BxJ,GAChCA,EAAOiF,aACTjF,EAAOiF,YAAYwE,mBAUvBnP,EAAOD,QAAU,SAAyB2F,GAkCxC,OAjCAwJ,EAA6BxJ,GAGzBA,EAAO0J,UAAYJ,EAActJ,EAAOC,OAC1CD,EAAOC,IAAMsJ,EAAYvJ,EAAO0J,QAAS1J,EAAOC,MAIlDD,EAAOoB,QAAUpB,EAAOoB,SAAW,GAGnCpB,EAAOe,KAAOsI,EACZrJ,EAAOe,KACPf,EAAOoB,QACPpB,EAAOyB,kBAITzB,EAAOoB,QAAUtG,EAAMc,MACrBoE,EAAOoB,QAAQiB,QAAU,GACzBrC,EAAOoB,QAAQpB,EAAOE,SAAW,GACjCF,EAAOoB,SAAW,IAGpBtG,EAAM+B,QACJ,CAAC,SAAU,MAAO,OAAQ,OAAQ,MAAO,QAAS,UAClD,SAA2BqD,UAClBF,EAAOoB,QAAQlB,MAIZF,EAAOsB,SAAWrG,EAASqG,SAE1BtB,GAAQa,KAAK,SAA6Bd,GAUvD,OATAyJ,EAA6BxJ,GAG7BD,EAASgB,KAAOsI,EACdtJ,EAASgB,KACThB,EAASqB,QACTpB,EAAO4B,mBAGF7B,GACN,SAA4B4J,GAc7B,OAbK5N,EAAS4N,KACZH,EAA6BxJ,GAGzB2J,GAAUA,EAAO5J,WACnB4J,EAAO5J,SAASgB,KAAOsI,EACrBM,EAAO5J,SAASgB,KAChB4I,EAAO5J,SAASqB,QAChBpB,EAAO4B,qBAKN1F,QAAQ8G,OAAO2G,OAOrB,SAAUrP,EAAQD,EAASM,GAEhC,aAEA,IAAIG,EAAQH,EAAoB,GAUhCL,EAAOD,QAAU,SAAuB0G,EAAMK,EAASwI,GAMrD,OAJA9O,EAAM+B,QAAQ+M,EAAK,SAAmB7M,GACpCgE,EAAOhE,EAAGgE,EAAMK,KAGXL,IAMJ,SAAUzG,EAAQD,GAEvB,aAEAC,EAAOD,QAAU,SAAkBgH,GACjC,SAAUA,IAASA,EAAMwI,cAMtB,SAAUvP,EAAQD,GAEvB,aAQAC,EAAOD,QAAU,SAAuB4F,GAItC,MAAO,gCAAgCoH,KAAKpH,KAMzC,SAAU3F,EAAQD,GAEvB,aASAC,EAAOD,QAAU,SAAqBqP,EAASI,GAC7C,OAAOA,EACHJ,EAAQvK,QAAQ,OAAQ,IAAM,IAAM2K,EAAY3K,QAAQ,OAAQ,IAChEuK,IAMD,SAAUpP,EAAQD,GAEvB,aAQA,SAASwB,EAAOyJ,GACd7K,KAAK6K,QAAUA,EAGjBzJ,EAAOP,UAAUgB,SAAW,WAC1B,MAAO,UAAY7B,KAAK6K,QAAU,KAAO7K,KAAK6K,QAAU,KAG1DzJ,EAAOP,UAAUuO,YAAa,EAE9BvP,EAAOD,QAAUwB,GAKZ,SAAUvB,EAAQD,EAASM,GAEhC,aAEA,IAAIkB,EAASlB,EAAoB,IAQjC,SAASmB,EAAYiO,GACnB,GAAwB,mBAAbA,EACT,MAAM,IAAIC,UAAU,gCAGtB,IAAIC,EACJxP,KAAK6F,QAAU,IAAIpE,QAAQ,SAAyBqE,GAClD0J,EAAiB1J,IAGnB,IAAI2J,EAAQzP,KACZsP,EAAS,SAAgBzE,GACnB4E,EAAMP,SAKVO,EAAMP,OAAS,IAAI9N,EAAOyJ,GAC1B2E,EAAeC,EAAMP,WAOzB7N,EAAYR,UAAUmO,iBAAmB,WACvC,GAAIhP,KAAKkP,OACP,MAAMlP,KAAKkP,QAQf7N,EAAYqO,OAAS,WACnB,IAAIjF,EAIJ,MAAO,CACLgF,MAJU,IAAIpO,EAAY,SAAkBsO,GAC5ClF,EAASkF,IAITlF,OAAQA,IAIZ5K,EAAOD,QAAUyB,GAKZ,SAAUxB,EAAQD,GAEvB,aAsBAC,EAAOD,QAAU,SAAgBgQ,GAC/B,OAAO,SAAcC,GACnB,OAAOD,EAAS/K,MAAM,KAAMgL,OA3gDvB3P,EAAoByP,EAAI1P,EAGxBC,EAAoB4P,EAAI,GAGjB5P,EAAoB,GAlC3B,SAASA,EAAoB6P,GAG5B,GAAG9P,EAAiB8P,GACnB,OAAO9P,EAAiB8P,GAAUnQ,QAGnC,IAAIC,EAASI,EAAiB8P,GAAY,CACzCnQ,QAAS,GACT8O,GAAIqB,EACJC,QAAQ,GAUT,OANA5P,EAAQ2P,GAAU9N,KAAKpC,EAAOD,QAASC,EAAQA,EAAOD,QAASM,GAG/DL,EAAOmQ,QAAS,EAGTnQ,EAAOD,QAzBT,IAAUQ,EAEZH","file":"axios.js","sourcesContent":["/* axios v0.17.1 | (c) 2017 by Matt Zabriskie */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"axios\"] = factory();\n\telse\n\t\troot[\"axios\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1);\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar bind = __webpack_require__(3);\n\tvar Axios = __webpack_require__(5);\n\tvar defaults = __webpack_require__(6);\n\t\n\t/**\n\t * Create an instance of Axios\n\t *\n\t * @param {Object} defaultConfig The default config for the instance\n\t * @return {Axios} A new instance of Axios\n\t */\n\tfunction createInstance(defaultConfig) {\n\t var context = new Axios(defaultConfig);\n\t var instance = bind(Axios.prototype.request, context);\n\t\n\t // Copy axios.prototype to instance\n\t utils.extend(instance, Axios.prototype, context);\n\t\n\t // Copy context to instance\n\t utils.extend(instance, context);\n\t\n\t return instance;\n\t}\n\t\n\t// Create the default instance to be exported\n\tvar axios = createInstance(defaults);\n\t\n\t// Expose Axios class to allow class inheritance\n\taxios.Axios = Axios;\n\t\n\t// Factory for creating new instances\n\taxios.create = function create(instanceConfig) {\n\t return createInstance(utils.merge(defaults, instanceConfig));\n\t};\n\t\n\t// Expose Cancel & CancelToken\n\taxios.Cancel = __webpack_require__(23);\n\taxios.CancelToken = __webpack_require__(24);\n\taxios.isCancel = __webpack_require__(20);\n\t\n\t// Expose all/spread\n\taxios.all = function all(promises) {\n\t return Promise.all(promises);\n\t};\n\taxios.spread = __webpack_require__(25);\n\t\n\tmodule.exports = axios;\n\t\n\t// Allow use of default import syntax in TypeScript\n\tmodule.exports.default = axios;\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar bind = __webpack_require__(3);\n\tvar isBuffer = __webpack_require__(4);\n\t\n\t/*global toString:true*/\n\t\n\t// utils is a library of generic helper functions non-specific to axios\n\t\n\tvar toString = Object.prototype.toString;\n\t\n\t/**\n\t * Determine if a value is an Array\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an Array, otherwise false\n\t */\n\tfunction isArray(val) {\n\t return toString.call(val) === '[object Array]';\n\t}\n\t\n\t/**\n\t * Determine if a value is an ArrayBuffer\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n\t */\n\tfunction isArrayBuffer(val) {\n\t return toString.call(val) === '[object ArrayBuffer]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a FormData\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an FormData, otherwise false\n\t */\n\tfunction isFormData(val) {\n\t return (typeof FormData !== 'undefined') && (val instanceof FormData);\n\t}\n\t\n\t/**\n\t * Determine if a value is a view on an ArrayBuffer\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n\t */\n\tfunction isArrayBufferView(val) {\n\t var result;\n\t if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n\t result = ArrayBuffer.isView(val);\n\t } else {\n\t result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Determine if a value is a String\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a String, otherwise false\n\t */\n\tfunction isString(val) {\n\t return typeof val === 'string';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Number\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Number, otherwise false\n\t */\n\tfunction isNumber(val) {\n\t return typeof val === 'number';\n\t}\n\t\n\t/**\n\t * Determine if a value is undefined\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if the value is undefined, otherwise false\n\t */\n\tfunction isUndefined(val) {\n\t return typeof val === 'undefined';\n\t}\n\t\n\t/**\n\t * Determine if a value is an Object\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an Object, otherwise false\n\t */\n\tfunction isObject(val) {\n\t return val !== null && typeof val === 'object';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Date\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Date, otherwise false\n\t */\n\tfunction isDate(val) {\n\t return toString.call(val) === '[object Date]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a File\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a File, otherwise false\n\t */\n\tfunction isFile(val) {\n\t return toString.call(val) === '[object File]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Blob\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Blob, otherwise false\n\t */\n\tfunction isBlob(val) {\n\t return toString.call(val) === '[object Blob]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Function\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Function, otherwise false\n\t */\n\tfunction isFunction(val) {\n\t return toString.call(val) === '[object Function]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Stream\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Stream, otherwise false\n\t */\n\tfunction isStream(val) {\n\t return isObject(val) && isFunction(val.pipe);\n\t}\n\t\n\t/**\n\t * Determine if a value is a URLSearchParams object\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n\t */\n\tfunction isURLSearchParams(val) {\n\t return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;\n\t}\n\t\n\t/**\n\t * Trim excess whitespace off the beginning and end of a string\n\t *\n\t * @param {String} str The String to trim\n\t * @returns {String} The String freed of excess whitespace\n\t */\n\tfunction trim(str) {\n\t return str.replace(/^\\s*/, '').replace(/\\s*$/, '');\n\t}\n\t\n\t/**\n\t * Determine if we're running in a standard browser environment\n\t *\n\t * This allows axios to run in a web worker, and react-native.\n\t * Both environments support XMLHttpRequest, but not fully standard globals.\n\t *\n\t * web workers:\n\t * typeof window -> undefined\n\t * typeof document -> undefined\n\t *\n\t * react-native:\n\t * navigator.product -> 'ReactNative'\n\t */\n\tfunction isStandardBrowserEnv() {\n\t if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {\n\t return false;\n\t }\n\t return (\n\t typeof window !== 'undefined' &&\n\t typeof document !== 'undefined'\n\t );\n\t}\n\t\n\t/**\n\t * Iterate over an Array or an Object invoking a function for each item.\n\t *\n\t * If `obj` is an Array callback will be called passing\n\t * the value, index, and complete array for each item.\n\t *\n\t * If 'obj' is an Object callback will be called passing\n\t * the value, key, and complete object for each property.\n\t *\n\t * @param {Object|Array} obj The object to iterate\n\t * @param {Function} fn The callback to invoke for each item\n\t */\n\tfunction forEach(obj, fn) {\n\t // Don't bother if no value provided\n\t if (obj === null || typeof obj === 'undefined') {\n\t return;\n\t }\n\t\n\t // Force an array if not already something iterable\n\t if (typeof obj !== 'object') {\n\t /*eslint no-param-reassign:0*/\n\t obj = [obj];\n\t }\n\t\n\t if (isArray(obj)) {\n\t // Iterate over array values\n\t for (var i = 0, l = obj.length; i < l; i++) {\n\t fn.call(null, obj[i], i, obj);\n\t }\n\t } else {\n\t // Iterate over object keys\n\t for (var key in obj) {\n\t if (Object.prototype.hasOwnProperty.call(obj, key)) {\n\t fn.call(null, obj[key], key, obj);\n\t }\n\t }\n\t }\n\t}\n\t\n\t/**\n\t * Accepts varargs expecting each argument to be an object, then\n\t * immutably merges the properties of each object and returns result.\n\t *\n\t * When multiple objects contain the same key the later object in\n\t * the arguments list will take precedence.\n\t *\n\t * Example:\n\t *\n\t * ```js\n\t * var result = merge({foo: 123}, {foo: 456});\n\t * console.log(result.foo); // outputs 456\n\t * ```\n\t *\n\t * @param {Object} obj1 Object to merge\n\t * @returns {Object} Result of all merge properties\n\t */\n\tfunction merge(/* obj1, obj2, obj3, ... */) {\n\t var result = {};\n\t function assignValue(val, key) {\n\t if (typeof result[key] === 'object' && typeof val === 'object') {\n\t result[key] = merge(result[key], val);\n\t } else {\n\t result[key] = val;\n\t }\n\t }\n\t\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t forEach(arguments[i], assignValue);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Extends object a by mutably adding to it the properties of object b.\n\t *\n\t * @param {Object} a The object to be extended\n\t * @param {Object} b The object to copy properties from\n\t * @param {Object} thisArg The object to bind function to\n\t * @return {Object} The resulting value of object a\n\t */\n\tfunction extend(a, b, thisArg) {\n\t forEach(b, function assignValue(val, key) {\n\t if (thisArg && typeof val === 'function') {\n\t a[key] = bind(val, thisArg);\n\t } else {\n\t a[key] = val;\n\t }\n\t });\n\t return a;\n\t}\n\t\n\tmodule.exports = {\n\t isArray: isArray,\n\t isArrayBuffer: isArrayBuffer,\n\t isBuffer: isBuffer,\n\t isFormData: isFormData,\n\t isArrayBufferView: isArrayBufferView,\n\t isString: isString,\n\t isNumber: isNumber,\n\t isObject: isObject,\n\t isUndefined: isUndefined,\n\t isDate: isDate,\n\t isFile: isFile,\n\t isBlob: isBlob,\n\t isFunction: isFunction,\n\t isStream: isStream,\n\t isURLSearchParams: isURLSearchParams,\n\t isStandardBrowserEnv: isStandardBrowserEnv,\n\t forEach: forEach,\n\t merge: merge,\n\t extend: extend,\n\t trim: trim\n\t};\n\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = function bind(fn, thisArg) {\n\t return function wrap() {\n\t var args = new Array(arguments.length);\n\t for (var i = 0; i < args.length; i++) {\n\t args[i] = arguments[i];\n\t }\n\t return fn.apply(thisArg, args);\n\t };\n\t};\n\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports) {\n\n\t/*!\n\t * Determine if an object is a Buffer\n\t *\n\t * @author Feross Aboukhadijeh \n\t * @license MIT\n\t */\n\t\n\t// The _isBuffer check is for Safari 5-7 support, because it's missing\n\t// Object.prototype.constructor. Remove this eventually\n\tmodule.exports = function (obj) {\n\t return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n\t}\n\t\n\tfunction isBuffer (obj) {\n\t return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n\t}\n\t\n\t// For Node v0.10 support. Remove this eventually.\n\tfunction isSlowBuffer (obj) {\n\t return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n\t}\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar defaults = __webpack_require__(6);\n\tvar utils = __webpack_require__(2);\n\tvar InterceptorManager = __webpack_require__(17);\n\tvar dispatchRequest = __webpack_require__(18);\n\t\n\t/**\n\t * Create a new instance of Axios\n\t *\n\t * @param {Object} instanceConfig The default config for the instance\n\t */\n\tfunction Axios(instanceConfig) {\n\t this.defaults = instanceConfig;\n\t this.interceptors = {\n\t request: new InterceptorManager(),\n\t response: new InterceptorManager()\n\t };\n\t}\n\t\n\t/**\n\t * Dispatch a request\n\t *\n\t * @param {Object} config The config specific for this request (merged with this.defaults)\n\t */\n\tAxios.prototype.request = function request(config) {\n\t /*eslint no-param-reassign:0*/\n\t // Allow for axios('example/url'[, config]) a la fetch API\n\t if (typeof config === 'string') {\n\t config = utils.merge({\n\t url: arguments[0]\n\t }, arguments[1]);\n\t }\n\t\n\t config = utils.merge(defaults, this.defaults, { method: 'get' }, config);\n\t config.method = config.method.toLowerCase();\n\t\n\t // Hook up interceptors middleware\n\t var chain = [dispatchRequest, undefined];\n\t var promise = Promise.resolve(config);\n\t\n\t this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n\t chain.unshift(interceptor.fulfilled, interceptor.rejected);\n\t });\n\t\n\t this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n\t chain.push(interceptor.fulfilled, interceptor.rejected);\n\t });\n\t\n\t while (chain.length) {\n\t promise = promise.then(chain.shift(), chain.shift());\n\t }\n\t\n\t return promise;\n\t};\n\t\n\t// Provide aliases for supported request methods\n\tutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n\t /*eslint func-names:0*/\n\t Axios.prototype[method] = function(url, config) {\n\t return this.request(utils.merge(config || {}, {\n\t method: method,\n\t url: url\n\t }));\n\t };\n\t});\n\t\n\tutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n\t /*eslint func-names:0*/\n\t Axios.prototype[method] = function(url, data, config) {\n\t return this.request(utils.merge(config || {}, {\n\t method: method,\n\t url: url,\n\t data: data\n\t }));\n\t };\n\t});\n\t\n\tmodule.exports = Axios;\n\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar normalizeHeaderName = __webpack_require__(7);\n\t\n\tvar DEFAULT_CONTENT_TYPE = {\n\t 'Content-Type': 'application/x-www-form-urlencoded'\n\t};\n\t\n\tfunction setContentTypeIfUnset(headers, value) {\n\t if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {\n\t headers['Content-Type'] = value;\n\t }\n\t}\n\t\n\tfunction getDefaultAdapter() {\n\t var adapter;\n\t if (typeof XMLHttpRequest !== 'undefined') {\n\t // For browsers use XHR adapter\n\t adapter = __webpack_require__(8);\n\t } else if (typeof process !== 'undefined') {\n\t // For node use HTTP adapter\n\t adapter = __webpack_require__(8);\n\t }\n\t return adapter;\n\t}\n\t\n\tvar defaults = {\n\t adapter: getDefaultAdapter(),\n\t\n\t transformRequest: [function transformRequest(data, headers) {\n\t normalizeHeaderName(headers, 'Content-Type');\n\t if (utils.isFormData(data) ||\n\t utils.isArrayBuffer(data) ||\n\t utils.isBuffer(data) ||\n\t utils.isStream(data) ||\n\t utils.isFile(data) ||\n\t utils.isBlob(data)\n\t ) {\n\t return data;\n\t }\n\t if (utils.isArrayBufferView(data)) {\n\t return data.buffer;\n\t }\n\t if (utils.isURLSearchParams(data)) {\n\t setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');\n\t return data.toString();\n\t }\n\t if (utils.isObject(data)) {\n\t setContentTypeIfUnset(headers, 'application/json;charset=utf-8');\n\t return JSON.stringify(data);\n\t }\n\t return data;\n\t }],\n\t\n\t transformResponse: [function transformResponse(data) {\n\t /*eslint no-param-reassign:0*/\n\t if (typeof data === 'string') {\n\t try {\n\t data = JSON.parse(data);\n\t } catch (e) { /* Ignore */ }\n\t }\n\t return data;\n\t }],\n\t\n\t timeout: 0,\n\t\n\t xsrfCookieName: 'XSRF-TOKEN',\n\t xsrfHeaderName: 'X-XSRF-TOKEN',\n\t\n\t maxContentLength: -1,\n\t\n\t validateStatus: function validateStatus(status) {\n\t return status >= 200 && status < 300;\n\t }\n\t};\n\t\n\tdefaults.headers = {\n\t common: {\n\t 'Accept': 'application/json, text/plain, */*'\n\t }\n\t};\n\t\n\tutils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {\n\t defaults.headers[method] = {};\n\t});\n\t\n\tutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n\t defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);\n\t});\n\t\n\tmodule.exports = defaults;\n\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tmodule.exports = function normalizeHeaderName(headers, normalizedName) {\n\t utils.forEach(headers, function processHeader(value, name) {\n\t if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {\n\t headers[normalizedName] = value;\n\t delete headers[name];\n\t }\n\t });\n\t};\n\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar settle = __webpack_require__(9);\n\tvar buildURL = __webpack_require__(12);\n\tvar parseHeaders = __webpack_require__(13);\n\tvar isURLSameOrigin = __webpack_require__(14);\n\tvar createError = __webpack_require__(10);\n\tvar btoa = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || __webpack_require__(15);\n\t\n\tmodule.exports = function xhrAdapter(config) {\n\t return new Promise(function dispatchXhrRequest(resolve, reject) {\n\t var requestData = config.data;\n\t var requestHeaders = config.headers;\n\t\n\t if (utils.isFormData(requestData)) {\n\t delete requestHeaders['Content-Type']; // Let the browser set it\n\t }\n\t\n\t var request = new XMLHttpRequest();\n\t var loadEvent = 'onreadystatechange';\n\t var xDomain = false;\n\t\n\t // For IE 8/9 CORS support\n\t // Only supports POST and GET calls and doesn't returns the response headers.\n\t // DON'T do this for testing b/c XMLHttpRequest is mocked, not XDomainRequest.\n\t if ((\"production\") !== 'test' &&\n\t typeof window !== 'undefined' &&\n\t window.XDomainRequest && !('withCredentials' in request) &&\n\t !isURLSameOrigin(config.url)) {\n\t request = new window.XDomainRequest();\n\t loadEvent = 'onload';\n\t xDomain = true;\n\t request.onprogress = function handleProgress() {};\n\t request.ontimeout = function handleTimeout() {};\n\t }\n\t\n\t // HTTP basic authentication\n\t if (config.auth) {\n\t var username = config.auth.username || '';\n\t var password = config.auth.password || '';\n\t requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);\n\t }\n\t\n\t request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);\n\t\n\t // Set the request timeout in MS\n\t request.timeout = config.timeout;\n\t\n\t // Listen for ready state\n\t request[loadEvent] = function handleLoad() {\n\t if (!request || (request.readyState !== 4 && !xDomain)) {\n\t return;\n\t }\n\t\n\t // The request errored out and we didn't get a response, this will be\n\t // handled by onerror instead\n\t // With one exception: request that using file: protocol, most browsers\n\t // will return status as 0 even though it's a successful request\n\t if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n\t return;\n\t }\n\t\n\t // Prepare the response\n\t var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;\n\t var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;\n\t var response = {\n\t data: responseData,\n\t // IE sends 1223 instead of 204 (https://github.com/axios/axios/issues/201)\n\t status: request.status === 1223 ? 204 : request.status,\n\t statusText: request.status === 1223 ? 'No Content' : request.statusText,\n\t headers: responseHeaders,\n\t config: config,\n\t request: request\n\t };\n\t\n\t settle(resolve, reject, response);\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Handle low level network errors\n\t request.onerror = function handleError() {\n\t // Real errors are hidden from us by the browser\n\t // onerror should only fire if it's a network error\n\t reject(createError('Network Error', config, null, request));\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Handle timeout\n\t request.ontimeout = function handleTimeout() {\n\t reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',\n\t request));\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Add xsrf header\n\t // This is only done if running in a standard browser environment.\n\t // Specifically not if we're in a web worker, or react-native.\n\t if (utils.isStandardBrowserEnv()) {\n\t var cookies = __webpack_require__(16);\n\t\n\t // Add xsrf header\n\t var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?\n\t cookies.read(config.xsrfCookieName) :\n\t undefined;\n\t\n\t if (xsrfValue) {\n\t requestHeaders[config.xsrfHeaderName] = xsrfValue;\n\t }\n\t }\n\t\n\t // Add headers to the request\n\t if ('setRequestHeader' in request) {\n\t utils.forEach(requestHeaders, function setRequestHeader(val, key) {\n\t if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {\n\t // Remove Content-Type if data is undefined\n\t delete requestHeaders[key];\n\t } else {\n\t // Otherwise add header to the request\n\t request.setRequestHeader(key, val);\n\t }\n\t });\n\t }\n\t\n\t // Add withCredentials to request if needed\n\t if (config.withCredentials) {\n\t request.withCredentials = true;\n\t }\n\t\n\t // Add responseType to request if needed\n\t if (config.responseType) {\n\t try {\n\t request.responseType = config.responseType;\n\t } catch (e) {\n\t // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.\n\t // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.\n\t if (config.responseType !== 'json') {\n\t throw e;\n\t }\n\t }\n\t }\n\t\n\t // Handle progress if needed\n\t if (typeof config.onDownloadProgress === 'function') {\n\t request.addEventListener('progress', config.onDownloadProgress);\n\t }\n\t\n\t // Not all browsers support upload events\n\t if (typeof config.onUploadProgress === 'function' && request.upload) {\n\t request.upload.addEventListener('progress', config.onUploadProgress);\n\t }\n\t\n\t if (config.cancelToken) {\n\t // Handle cancellation\n\t config.cancelToken.promise.then(function onCanceled(cancel) {\n\t if (!request) {\n\t return;\n\t }\n\t\n\t request.abort();\n\t reject(cancel);\n\t // Clean up request\n\t request = null;\n\t });\n\t }\n\t\n\t if (requestData === undefined) {\n\t requestData = null;\n\t }\n\t\n\t // Send the request\n\t request.send(requestData);\n\t });\n\t};\n\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar createError = __webpack_require__(10);\n\t\n\t/**\n\t * Resolve or reject a Promise based on response status.\n\t *\n\t * @param {Function} resolve A function that resolves the promise.\n\t * @param {Function} reject A function that rejects the promise.\n\t * @param {object} response The response.\n\t */\n\tmodule.exports = function settle(resolve, reject, response) {\n\t var validateStatus = response.config.validateStatus;\n\t // Note: status is not exposed by XDomainRequest\n\t if (!response.status || !validateStatus || validateStatus(response.status)) {\n\t resolve(response);\n\t } else {\n\t reject(createError(\n\t 'Request failed with status code ' + response.status,\n\t response.config,\n\t null,\n\t response.request,\n\t response\n\t ));\n\t }\n\t};\n\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar enhanceError = __webpack_require__(11);\n\t\n\t/**\n\t * Create an Error with the specified message, config, error code, request and response.\n\t *\n\t * @param {string} message The error message.\n\t * @param {Object} config The config.\n\t * @param {string} [code] The error code (for example, 'ECONNABORTED').\n\t * @param {Object} [request] The request.\n\t * @param {Object} [response] The response.\n\t * @returns {Error} The created error.\n\t */\n\tmodule.exports = function createError(message, config, code, request, response) {\n\t var error = new Error(message);\n\t return enhanceError(error, config, code, request, response);\n\t};\n\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Update an Error with the specified config, error code, and response.\n\t *\n\t * @param {Error} error The error to update.\n\t * @param {Object} config The config.\n\t * @param {string} [code] The error code (for example, 'ECONNABORTED').\n\t * @param {Object} [request] The request.\n\t * @param {Object} [response] The response.\n\t * @returns {Error} The error.\n\t */\n\tmodule.exports = function enhanceError(error, config, code, request, response) {\n\t error.config = config;\n\t if (code) {\n\t error.code = code;\n\t }\n\t error.request = request;\n\t error.response = response;\n\t return error;\n\t};\n\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tfunction encode(val) {\n\t return encodeURIComponent(val).\n\t replace(/%40/gi, '@').\n\t replace(/%3A/gi, ':').\n\t replace(/%24/g, '$').\n\t replace(/%2C/gi, ',').\n\t replace(/%20/g, '+').\n\t replace(/%5B/gi, '[').\n\t replace(/%5D/gi, ']');\n\t}\n\t\n\t/**\n\t * Build a URL by appending params to the end\n\t *\n\t * @param {string} url The base of the url (e.g., http://www.google.com)\n\t * @param {object} [params] The params to be appended\n\t * @returns {string} The formatted url\n\t */\n\tmodule.exports = function buildURL(url, params, paramsSerializer) {\n\t /*eslint no-param-reassign:0*/\n\t if (!params) {\n\t return url;\n\t }\n\t\n\t var serializedParams;\n\t if (paramsSerializer) {\n\t serializedParams = paramsSerializer(params);\n\t } else if (utils.isURLSearchParams(params)) {\n\t serializedParams = params.toString();\n\t } else {\n\t var parts = [];\n\t\n\t utils.forEach(params, function serialize(val, key) {\n\t if (val === null || typeof val === 'undefined') {\n\t return;\n\t }\n\t\n\t if (utils.isArray(val)) {\n\t key = key + '[]';\n\t }\n\t\n\t if (!utils.isArray(val)) {\n\t val = [val];\n\t }\n\t\n\t utils.forEach(val, function parseValue(v) {\n\t if (utils.isDate(v)) {\n\t v = v.toISOString();\n\t } else if (utils.isObject(v)) {\n\t v = JSON.stringify(v);\n\t }\n\t parts.push(encode(key) + '=' + encode(v));\n\t });\n\t });\n\t\n\t serializedParams = parts.join('&');\n\t }\n\t\n\t if (serializedParams) {\n\t url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n\t }\n\t\n\t return url;\n\t};\n\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\t// Headers whose duplicates are ignored by node\n\t// c.f. https://nodejs.org/api/http.html#http_message_headers\n\tvar ignoreDuplicateOf = [\n\t 'age', 'authorization', 'content-length', 'content-type', 'etag',\n\t 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n\t 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n\t 'referer', 'retry-after', 'user-agent'\n\t];\n\t\n\t/**\n\t * Parse headers into an object\n\t *\n\t * ```\n\t * Date: Wed, 27 Aug 2014 08:58:49 GMT\n\t * Content-Type: application/json\n\t * Connection: keep-alive\n\t * Transfer-Encoding: chunked\n\t * ```\n\t *\n\t * @param {String} headers Headers needing to be parsed\n\t * @returns {Object} Headers parsed into an object\n\t */\n\tmodule.exports = function parseHeaders(headers) {\n\t var parsed = {};\n\t var key;\n\t var val;\n\t var i;\n\t\n\t if (!headers) { return parsed; }\n\t\n\t utils.forEach(headers.split('\\n'), function parser(line) {\n\t i = line.indexOf(':');\n\t key = utils.trim(line.substr(0, i)).toLowerCase();\n\t val = utils.trim(line.substr(i + 1));\n\t\n\t if (key) {\n\t if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {\n\t return;\n\t }\n\t if (key === 'set-cookie') {\n\t parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);\n\t } else {\n\t parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n\t }\n\t }\n\t });\n\t\n\t return parsed;\n\t};\n\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tmodule.exports = (\n\t utils.isStandardBrowserEnv() ?\n\t\n\t // Standard browser envs have full support of the APIs needed to test\n\t // whether the request URL is of the same origin as current location.\n\t (function standardBrowserEnv() {\n\t var msie = /(msie|trident)/i.test(navigator.userAgent);\n\t var urlParsingNode = document.createElement('a');\n\t var originURL;\n\t\n\t /**\n\t * Parse a URL to discover it's components\n\t *\n\t * @param {String} url The URL to be parsed\n\t * @returns {Object}\n\t */\n\t function resolveURL(url) {\n\t var href = url;\n\t\n\t if (msie) {\n\t // IE needs attribute set twice to normalize properties\n\t urlParsingNode.setAttribute('href', href);\n\t href = urlParsingNode.href;\n\t }\n\t\n\t urlParsingNode.setAttribute('href', href);\n\t\n\t // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n\t return {\n\t href: urlParsingNode.href,\n\t protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n\t host: urlParsingNode.host,\n\t search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n\t hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n\t hostname: urlParsingNode.hostname,\n\t port: urlParsingNode.port,\n\t pathname: (urlParsingNode.pathname.charAt(0) === '/') ?\n\t urlParsingNode.pathname :\n\t '/' + urlParsingNode.pathname\n\t };\n\t }\n\t\n\t originURL = resolveURL(window.location.href);\n\t\n\t /**\n\t * Determine if a URL shares the same origin as the current location\n\t *\n\t * @param {String} requestURL The URL to test\n\t * @returns {boolean} True if URL shares the same origin, otherwise false\n\t */\n\t return function isURLSameOrigin(requestURL) {\n\t var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;\n\t return (parsed.protocol === originURL.protocol &&\n\t parsed.host === originURL.host);\n\t };\n\t })() :\n\t\n\t // Non standard browser envs (web workers, react-native) lack needed support.\n\t (function nonStandardBrowserEnv() {\n\t return function isURLSameOrigin() {\n\t return true;\n\t };\n\t })()\n\t);\n\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t// btoa polyfill for IE<10 courtesy https://github.com/davidchambers/Base64.js\n\t\n\tvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n\t\n\tfunction E() {\n\t this.message = 'String contains an invalid character';\n\t}\n\tE.prototype = new Error;\n\tE.prototype.code = 5;\n\tE.prototype.name = 'InvalidCharacterError';\n\t\n\tfunction btoa(input) {\n\t var str = String(input);\n\t var output = '';\n\t for (\n\t // initialize result and counter\n\t var block, charCode, idx = 0, map = chars;\n\t // if the next str index does not exist:\n\t // change the mapping table to \"=\"\n\t // check if d has no fractional digits\n\t str.charAt(idx | 0) || (map = '=', idx % 1);\n\t // \"8 - idx % 1 * 8\" generates the sequence 2, 4, 6, 8\n\t output += map.charAt(63 & block >> 8 - idx % 1 * 8)\n\t ) {\n\t charCode = str.charCodeAt(idx += 3 / 4);\n\t if (charCode > 0xFF) {\n\t throw new E();\n\t }\n\t block = block << 8 | charCode;\n\t }\n\t return output;\n\t}\n\t\n\tmodule.exports = btoa;\n\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tmodule.exports = (\n\t utils.isStandardBrowserEnv() ?\n\t\n\t // Standard browser envs support document.cookie\n\t (function standardBrowserEnv() {\n\t return {\n\t write: function write(name, value, expires, path, domain, secure) {\n\t var cookie = [];\n\t cookie.push(name + '=' + encodeURIComponent(value));\n\t\n\t if (utils.isNumber(expires)) {\n\t cookie.push('expires=' + new Date(expires).toGMTString());\n\t }\n\t\n\t if (utils.isString(path)) {\n\t cookie.push('path=' + path);\n\t }\n\t\n\t if (utils.isString(domain)) {\n\t cookie.push('domain=' + domain);\n\t }\n\t\n\t if (secure === true) {\n\t cookie.push('secure');\n\t }\n\t\n\t document.cookie = cookie.join('; ');\n\t },\n\t\n\t read: function read(name) {\n\t var match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n\t return (match ? decodeURIComponent(match[3]) : null);\n\t },\n\t\n\t remove: function remove(name) {\n\t this.write(name, '', Date.now() - 86400000);\n\t }\n\t };\n\t })() :\n\t\n\t // Non standard browser env (web workers, react-native) lack needed support.\n\t (function nonStandardBrowserEnv() {\n\t return {\n\t write: function write() {},\n\t read: function read() { return null; },\n\t remove: function remove() {}\n\t };\n\t })()\n\t);\n\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tfunction InterceptorManager() {\n\t this.handlers = [];\n\t}\n\t\n\t/**\n\t * Add a new interceptor to the stack\n\t *\n\t * @param {Function} fulfilled The function to handle `then` for a `Promise`\n\t * @param {Function} rejected The function to handle `reject` for a `Promise`\n\t *\n\t * @return {Number} An ID used to remove interceptor later\n\t */\n\tInterceptorManager.prototype.use = function use(fulfilled, rejected) {\n\t this.handlers.push({\n\t fulfilled: fulfilled,\n\t rejected: rejected\n\t });\n\t return this.handlers.length - 1;\n\t};\n\t\n\t/**\n\t * Remove an interceptor from the stack\n\t *\n\t * @param {Number} id The ID that was returned by `use`\n\t */\n\tInterceptorManager.prototype.eject = function eject(id) {\n\t if (this.handlers[id]) {\n\t this.handlers[id] = null;\n\t }\n\t};\n\t\n\t/**\n\t * Iterate over all the registered interceptors\n\t *\n\t * This method is particularly useful for skipping over any\n\t * interceptors that may have become `null` calling `eject`.\n\t *\n\t * @param {Function} fn The function to call for each interceptor\n\t */\n\tInterceptorManager.prototype.forEach = function forEach(fn) {\n\t utils.forEach(this.handlers, function forEachHandler(h) {\n\t if (h !== null) {\n\t fn(h);\n\t }\n\t });\n\t};\n\t\n\tmodule.exports = InterceptorManager;\n\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar transformData = __webpack_require__(19);\n\tvar isCancel = __webpack_require__(20);\n\tvar defaults = __webpack_require__(6);\n\tvar isAbsoluteURL = __webpack_require__(21);\n\tvar combineURLs = __webpack_require__(22);\n\t\n\t/**\n\t * Throws a `Cancel` if cancellation has been requested.\n\t */\n\tfunction throwIfCancellationRequested(config) {\n\t if (config.cancelToken) {\n\t config.cancelToken.throwIfRequested();\n\t }\n\t}\n\t\n\t/**\n\t * Dispatch a request to the server using the configured adapter.\n\t *\n\t * @param {object} config The config that is to be used for the request\n\t * @returns {Promise} The Promise to be fulfilled\n\t */\n\tmodule.exports = function dispatchRequest(config) {\n\t throwIfCancellationRequested(config);\n\t\n\t // Support baseURL config\n\t if (config.baseURL && !isAbsoluteURL(config.url)) {\n\t config.url = combineURLs(config.baseURL, config.url);\n\t }\n\t\n\t // Ensure headers exist\n\t config.headers = config.headers || {};\n\t\n\t // Transform request data\n\t config.data = transformData(\n\t config.data,\n\t config.headers,\n\t config.transformRequest\n\t );\n\t\n\t // Flatten headers\n\t config.headers = utils.merge(\n\t config.headers.common || {},\n\t config.headers[config.method] || {},\n\t config.headers || {}\n\t );\n\t\n\t utils.forEach(\n\t ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n\t function cleanHeaderConfig(method) {\n\t delete config.headers[method];\n\t }\n\t );\n\t\n\t var adapter = config.adapter || defaults.adapter;\n\t\n\t return adapter(config).then(function onAdapterResolution(response) {\n\t throwIfCancellationRequested(config);\n\t\n\t // Transform response data\n\t response.data = transformData(\n\t response.data,\n\t response.headers,\n\t config.transformResponse\n\t );\n\t\n\t return response;\n\t }, function onAdapterRejection(reason) {\n\t if (!isCancel(reason)) {\n\t throwIfCancellationRequested(config);\n\t\n\t // Transform response data\n\t if (reason && reason.response) {\n\t reason.response.data = transformData(\n\t reason.response.data,\n\t reason.response.headers,\n\t config.transformResponse\n\t );\n\t }\n\t }\n\t\n\t return Promise.reject(reason);\n\t });\n\t};\n\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\t/**\n\t * Transform the data for a request or a response\n\t *\n\t * @param {Object|String} data The data to be transformed\n\t * @param {Array} headers The headers for the request or response\n\t * @param {Array|Function} fns A single function or Array of functions\n\t * @returns {*} The resulting transformed data\n\t */\n\tmodule.exports = function transformData(data, headers, fns) {\n\t /*eslint no-param-reassign:0*/\n\t utils.forEach(fns, function transform(fn) {\n\t data = fn(data, headers);\n\t });\n\t\n\t return data;\n\t};\n\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = function isCancel(value) {\n\t return !!(value && value.__CANCEL__);\n\t};\n\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Determines whether the specified URL is absolute\n\t *\n\t * @param {string} url The URL to test\n\t * @returns {boolean} True if the specified URL is absolute, otherwise false\n\t */\n\tmodule.exports = function isAbsoluteURL(url) {\n\t // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n\t // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n\t // by any combination of letters, digits, plus, period, or hyphen.\n\t return /^([a-z][a-z\\d\\+\\-\\.]*:)?\\/\\//i.test(url);\n\t};\n\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Creates a new URL by combining the specified URLs\n\t *\n\t * @param {string} baseURL The base URL\n\t * @param {string} relativeURL The relative URL\n\t * @returns {string} The combined URL\n\t */\n\tmodule.exports = function combineURLs(baseURL, relativeURL) {\n\t return relativeURL\n\t ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n\t : baseURL;\n\t};\n\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * A `Cancel` is an object that is thrown when an operation is canceled.\n\t *\n\t * @class\n\t * @param {string=} message The message.\n\t */\n\tfunction Cancel(message) {\n\t this.message = message;\n\t}\n\t\n\tCancel.prototype.toString = function toString() {\n\t return 'Cancel' + (this.message ? ': ' + this.message : '');\n\t};\n\t\n\tCancel.prototype.__CANCEL__ = true;\n\t\n\tmodule.exports = Cancel;\n\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar Cancel = __webpack_require__(23);\n\t\n\t/**\n\t * A `CancelToken` is an object that can be used to request cancellation of an operation.\n\t *\n\t * @class\n\t * @param {Function} executor The executor function.\n\t */\n\tfunction CancelToken(executor) {\n\t if (typeof executor !== 'function') {\n\t throw new TypeError('executor must be a function.');\n\t }\n\t\n\t var resolvePromise;\n\t this.promise = new Promise(function promiseExecutor(resolve) {\n\t resolvePromise = resolve;\n\t });\n\t\n\t var token = this;\n\t executor(function cancel(message) {\n\t if (token.reason) {\n\t // Cancellation has already been requested\n\t return;\n\t }\n\t\n\t token.reason = new Cancel(message);\n\t resolvePromise(token.reason);\n\t });\n\t}\n\t\n\t/**\n\t * Throws a `Cancel` if cancellation has been requested.\n\t */\n\tCancelToken.prototype.throwIfRequested = function throwIfRequested() {\n\t if (this.reason) {\n\t throw this.reason;\n\t }\n\t};\n\t\n\t/**\n\t * Returns an object that contains a new `CancelToken` and a function that, when called,\n\t * cancels the `CancelToken`.\n\t */\n\tCancelToken.source = function source() {\n\t var cancel;\n\t var token = new CancelToken(function executor(c) {\n\t cancel = c;\n\t });\n\t return {\n\t token: token,\n\t cancel: cancel\n\t };\n\t};\n\t\n\tmodule.exports = CancelToken;\n\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Syntactic sugar for invoking a function and expanding an array for arguments.\n\t *\n\t * Common use case would be to use `Function.prototype.apply`.\n\t *\n\t * ```js\n\t * function f(x, y, z) {}\n\t * var args = [1, 2, 3];\n\t * f.apply(null, args);\n\t * ```\n\t *\n\t * With `spread` this example can be re-written.\n\t *\n\t * ```js\n\t * spread(function(x, y, z) {})([1, 2, 3]);\n\t * ```\n\t *\n\t * @param {Function} callback\n\t * @returns {Function}\n\t */\n\tmodule.exports = function spread(callback) {\n\t return function wrap(arr) {\n\t return callback.apply(null, arr);\n\t };\n\t};\n\n\n/***/ })\n/******/ ])\n});\n;\n//# sourceMappingURL=axios.map"]} \ No newline at end of file diff --git a/lib/bootstrap/js/bootstrap.js b/lib/bootstrap/js/bootstrap.js index a70854acddb..815903485ea 100644 --- a/lib/bootstrap/js/bootstrap.js +++ b/lib/bootstrap/js/bootstrap.js @@ -1,2 +1,2 @@ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");!function(t){"use strict";var e=jQuery.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1||3this.$items.length-1||t<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(idocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},a.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},a.prototype.checkScrollbar=function(){var t=window.innerWidth;if(!t){var e=document.documentElement.getBoundingClientRect();t=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},m.prototype.init=function(t,e,i){if(this.enabled=!0,this.type=t,this.$element=g(e),this.options=this.getOptions(i),this.$viewport=this.options.viewport&&g(g.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var o=this.options.trigger.split(" "),n=o.length;n--;){var s=o[n];if("click"==s)this.$element.on("click."+this.type,this.options.selector,g.proxy(this.toggle,this));else if("manual"!=s){var a="hover"==s?"mouseenter":"focusin",r="hover"==s?"mouseleave":"focusout";this.$element.on(a+"."+this.type,this.options.selector,g.proxy(this.enter,this)),this.$element.on(r+"."+this.type,this.options.selector,g.proxy(this.leave,this))}}this.options.selector?this._options=g.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},m.prototype.getDefaults=function(){return m.DEFAULTS},m.prototype.getOptions=function(t){return(t=g.extend({},this.getDefaults(),this.$element.data(),t)).delay&&"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),t},m.prototype.getDelegateOptions=function(){var i={},o=this.getDefaults();return this._options&&g.each(this._options,function(t,e){o[t]!=e&&(i[t]=e)}),i},m.prototype.enter=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusin"==t.type?"focus":"hover"]=!0),e.tip().hasClass("in")||"in"==e.hoverState)e.hoverState="in";else{if(clearTimeout(e.timeout),e.hoverState="in",!e.options.delay||!e.options.delay.show)return e.show();e.timeout=setTimeout(function(){"in"==e.hoverState&&e.show()},e.options.delay.show)}},m.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},m.prototype.leave=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusout"==t.type?"focus":"hover"]=!1),!e.isInStateTrue()){if(clearTimeout(e.timeout),e.hoverState="out",!e.options.delay||!e.options.delay.hide)return e.hide();e.timeout=setTimeout(function(){"out"==e.hoverState&&e.hide()},e.options.delay.hide)}},m.prototype.show=function(){var t=g.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(t);var e=g.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(t.isDefaultPrevented()||!e)return;var i=this,o=this.tip(),n=this.getUID(this.type);this.setContent(),o.attr("id",n),this.$element.attr("aria-describedby",n),this.options.animation&&o.addClass("fade");var s="function"==typeof this.options.placement?this.options.placement.call(this,o[0],this.$element[0]):this.options.placement,a=/\s?auto?\s?/i,r=a.test(s);r&&(s=s.replace(a,"")||"top"),o.detach().css({top:0,left:0,display:"block"}).addClass(s).data("bs."+this.type,this),this.options.container?o.appendTo(this.options.container):o.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var l=this.getPosition(),h=o[0].offsetWidth,d=o[0].offsetHeight;if(r){var p=s,c=this.getPosition(this.$viewport);s="bottom"==s&&l.bottom+d>c.bottom?"top":"top"==s&&l.top-dc.width?"left":"left"==s&&l.left-ha.top+a.height&&(n.top=a.top+a.height-l)}else{var h=e.left-s,d=e.left+s+i;ha.right&&(n.left=a.left+a.width-d)}return n},m.prototype.getTitle=function(){var t=this.$element,e=this.options;return t.attr("data-original-title")||("function"==typeof e.title?e.title.call(t[0]):e.title)},m.prototype.getUID=function(t){for(;t+=~~(1e6*Math.random()),document.getElementById(t););return t},m.prototype.tip=function(){if(!this.$tip&&(this.$tip=g(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},m.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},m.prototype.enable=function(){this.enabled=!0},m.prototype.disable=function(){this.enabled=!1},m.prototype.toggleEnabled=function(){this.enabled=!this.enabled},m.prototype.toggle=function(t){var e=this;t&&((e=g(t.currentTarget).data("bs."+this.type))||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e))),t?(e.inState.click=!e.inState.click,e.isInStateTrue()?e.enter(e):e.leave(e)):e.tip().hasClass("in")?e.leave(e):e.enter(e)},m.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null,t.$element=null})};var t=g.fn.tooltip;g.fn.tooltip=function(o){return this.each(function(){var t=g(this),e=t.data("bs.tooltip"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.tooltip",e=new m(this,i)),"string"==typeof o&&e[o]())})},g.fn.tooltip.Constructor=m,g.fn.tooltip.noConflict=function(){return g.fn.tooltip=t,this}}(jQuery),function(n){"use strict";var s=function(t,e){this.init("popover",t,e)};if(!n.fn.tooltip)throw new Error("Popover requires tooltip.js");s.VERSION="3.3.7",s.DEFAULTS=n.extend({},n.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),((s.prototype=n.extend({},n.fn.tooltip.Constructor.prototype)).constructor=s).prototype.getDefaults=function(){return s.DEFAULTS},s.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();t.find(".popover-title")[this.options.html?"html":"text"](e),t.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof i?"html":"append":"text"](i),t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},s.prototype.hasContent=function(){return this.getTitle()||this.getContent()},s.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},s.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var t=n.fn.popover;n.fn.popover=function(o){return this.each(function(){var t=n(this),e=t.data("bs.popover"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.popover",e=new s(this,i)),"string"==typeof o&&e[o]())})},n.fn.popover.Constructor=s,n.fn.popover.noConflict=function(){return n.fn.popover=t,this}}(jQuery),function(s){"use strict";function n(t,e){this.$body=s(document.body),this.$scrollElement=s(t).is(document.body)?s(window):s(t),this.options=s.extend({},n.DEFAULTS,e),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",s.proxy(this.process,this)),this.refresh(),this.process()}function e(o){return this.each(function(){var t=s(this),e=t.data("bs.scrollspy"),i="object"==typeof o&&o;e||t.data("bs.scrollspy",e=new n(this,i)),"string"==typeof o&&e[o]()})}n.VERSION="3.3.7",n.DEFAULTS={offset:10},n.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},n.prototype.refresh=function(){var t=this,o="offset",n=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),s.isWindow(this.$scrollElement[0])||(o="position",n=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var t=s(this),e=t.data("target")||t.attr("href"),i=/^#./.test(e)&&s(e);return i&&i.length&&i.is(":visible")&&[[i[o]().top+n,e]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},n.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),n=this.offsets,s=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),o<=e)return a!=(t=s[s.length-1])&&this.activate(t);if(a&&e=n[t]&&(void 0===n[t+1]||e .active"),n=i&&r.support.transition&&(o.length&&o.hasClass("fade")||!!e.find("> .fade").length);function s(){o.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),t.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),n?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu").length&&t.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),i&&i()}o.length&&n?o.one("bsTransitionEnd",s).emulateTransitionEnd(a.TRANSITION_DURATION):s(),o.removeClass("in")};var t=r.fn.tab;r.fn.tab=e,r.fn.tab.Constructor=a,r.fn.tab.noConflict=function(){return r.fn.tab=t,this};var i=function(t){t.preventDefault(),e.call(r(this),"show")};r(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',i).on("click.bs.tab.data-api",'[data-toggle="pill"]',i)}(jQuery),function(l){"use strict";var h=function(t,e){this.options=l.extend({},h.DEFAULTS,e),this.$target=l(this.options.target).on("scroll.bs.affix.data-api",l.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",l.proxy(this.checkPositionWithEventLoop,this)),this.$element=l(t),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};function i(o){return this.each(function(){var t=l(this),e=t.data("bs.affix"),i="object"==typeof o&&o;e||t.data("bs.affix",e=new h(this,i)),"string"==typeof o&&e[o]()})}h.VERSION="3.3.7",h.RESET="affix affix-top affix-bottom",h.DEFAULTS={offset:0,target:window},h.prototype.getState=function(t,e,i,o){var n=this.$target.scrollTop(),s=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return nthis.$items.length-1||t<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(idocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},a.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},a.prototype.checkScrollbar=function(){var t=window.innerWidth;if(!t){var e=document.documentElement.getBoundingClientRect();t=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},m.prototype.init=function(t,e,i){if(this.enabled=!0,this.type=t,this.$element=g(e),this.options=this.getOptions(i),this.$viewport=this.options.viewport&&g(g.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var o=this.options.trigger.split(" "),n=o.length;n--;){var s=o[n];if("click"==s)this.$element.on("click."+this.type,this.options.selector,g.proxy(this.toggle,this));else if("manual"!=s){var a="hover"==s?"mouseenter":"focusin",r="hover"==s?"mouseleave":"focusout";this.$element.on(a+"."+this.type,this.options.selector,g.proxy(this.enter,this)),this.$element.on(r+"."+this.type,this.options.selector,g.proxy(this.leave,this))}}this.options.selector?this._options=g.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},m.prototype.getDefaults=function(){return m.DEFAULTS},m.prototype.getOptions=function(t){return(t=g.extend({},this.getDefaults(),this.$element.data(),t)).delay&&"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),t},m.prototype.getDelegateOptions=function(){var i={},o=this.getDefaults();return this._options&&g.each(this._options,function(t,e){o[t]!=e&&(i[t]=e)}),i},m.prototype.enter=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusin"==t.type?"focus":"hover"]=!0),e.tip().hasClass("in")||"in"==e.hoverState)e.hoverState="in";else{if(clearTimeout(e.timeout),e.hoverState="in",!e.options.delay||!e.options.delay.show)return e.show();e.timeout=setTimeout(function(){"in"==e.hoverState&&e.show()},e.options.delay.show)}},m.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},m.prototype.leave=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusout"==t.type?"focus":"hover"]=!1),!e.isInStateTrue()){if(clearTimeout(e.timeout),e.hoverState="out",!e.options.delay||!e.options.delay.hide)return e.hide();e.timeout=setTimeout(function(){"out"==e.hoverState&&e.hide()},e.options.delay.hide)}},m.prototype.show=function(){var t=g.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(t);var e=g.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(t.isDefaultPrevented()||!e)return;var i=this,o=this.tip(),n=this.getUID(this.type);this.setContent(),o.attr("id",n),this.$element.attr("aria-describedby",n),this.options.animation&&o.addClass("fade");var s="function"==typeof this.options.placement?this.options.placement.call(this,o[0],this.$element[0]):this.options.placement,a=/\s?auto?\s?/i,r=a.test(s);r&&(s=s.replace(a,"")||"top"),o.detach().css({top:0,left:0,display:"block"}).addClass(s).data("bs."+this.type,this),this.options.container?o.appendTo(this.options.container):o.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var l=this.getPosition(),h=o[0].offsetWidth,d=o[0].offsetHeight;if(r){var p=s,c=this.getPosition(this.$viewport);s="bottom"==s&&l.bottom+d>c.bottom?"top":"top"==s&&l.top-dc.width?"left":"left"==s&&l.left-ha.top+a.height&&(n.top=a.top+a.height-l)}else{var h=e.left-s,d=e.left+s+i;ha.right&&(n.left=a.left+a.width-d)}return n},m.prototype.getTitle=function(){var t=this.$element,e=this.options;return t.attr("data-original-title")||("function"==typeof e.title?e.title.call(t[0]):e.title)},m.prototype.getUID=function(t){for(;t+=~~(1e6*Math.random()),document.getElementById(t););return t},m.prototype.tip=function(){if(!this.$tip&&(this.$tip=g(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},m.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},m.prototype.enable=function(){this.enabled=!0},m.prototype.disable=function(){this.enabled=!1},m.prototype.toggleEnabled=function(){this.enabled=!this.enabled},m.prototype.toggle=function(t){var e=this;t&&((e=g(t.currentTarget).data("bs."+this.type))||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e))),t?(e.inState.click=!e.inState.click,e.isInStateTrue()?e.enter(e):e.leave(e)):e.tip().hasClass("in")?e.leave(e):e.enter(e)},m.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null,t.$element=null})};var t=g.fn.tooltip;g.fn.tooltip=function(o){return this.each(function(){var t=g(this),e=t.data("bs.tooltip"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.tooltip",e=new m(this,i)),"string"==typeof o&&e[o]())})},g.fn.tooltip.Constructor=m,g.fn.tooltip.noConflict=function(){return g.fn.tooltip=t,this}}(jQuery),function(n){"use strict";function s(t,e){this.init("popover",t,e)}if(!n.fn.tooltip)throw new Error("Popover requires tooltip.js");s.VERSION="3.3.7",s.DEFAULTS=n.extend({},n.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),((s.prototype=n.extend({},n.fn.tooltip.Constructor.prototype)).constructor=s).prototype.getDefaults=function(){return s.DEFAULTS},s.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();t.find(".popover-title")[this.options.html?"html":"text"](e),t.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof i?"html":"append":"text"](i),t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},s.prototype.hasContent=function(){return this.getTitle()||this.getContent()},s.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},s.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var t=n.fn.popover;n.fn.popover=function(o){return this.each(function(){var t=n(this),e=t.data("bs.popover"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.popover",e=new s(this,i)),"string"==typeof o&&e[o]())})},n.fn.popover.Constructor=s,n.fn.popover.noConflict=function(){return n.fn.popover=t,this}}(jQuery),function(s){"use strict";function n(t,e){this.$body=s(document.body),this.$scrollElement=s(t).is(document.body)?s(window):s(t),this.options=s.extend({},n.DEFAULTS,e),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",s.proxy(this.process,this)),this.refresh(),this.process()}function e(o){return this.each(function(){var t=s(this),e=t.data("bs.scrollspy"),i="object"==typeof o&&o;e||t.data("bs.scrollspy",e=new n(this,i)),"string"==typeof o&&e[o]()})}n.VERSION="3.3.7",n.DEFAULTS={offset:10},n.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},n.prototype.refresh=function(){var t=this,o="offset",n=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),s.isWindow(this.$scrollElement[0])||(o="position",n=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var t=s(this),e=t.data("target")||t.attr("href"),i=/^#./.test(e)&&s(e);return i&&i.length&&i.is(":visible")&&[[i[o]().top+n,e]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},n.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),n=this.offsets,s=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),o<=e)return a!=(t=s[s.length-1])&&this.activate(t);if(a&&e=n[t]&&(void 0===n[t+1]||e .active"),n=i&&r.support.transition&&(o.length&&o.hasClass("fade")||!!e.find("> .fade").length);function s(){o.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),t.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),n?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu").length&&t.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),i&&i()}o.length&&n?o.one("bsTransitionEnd",s).emulateTransitionEnd(a.TRANSITION_DURATION):s(),o.removeClass("in")};var t=r.fn.tab;r.fn.tab=e,r.fn.tab.Constructor=a,r.fn.tab.noConflict=function(){return r.fn.tab=t,this};function i(t){t.preventDefault(),e.call(r(this),"show")}r(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',i).on("click.bs.tab.data-api",'[data-toggle="pill"]',i)}(jQuery),function(l){"use strict";var h=function(t,e){this.options=l.extend({},h.DEFAULTS,e),this.$target=l(this.options.target).on("scroll.bs.affix.data-api",l.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",l.proxy(this.checkPositionWithEventLoop,this)),this.$element=l(t),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};function i(o){return this.each(function(){var t=l(this),e=t.data("bs.affix"),i="object"==typeof o&&o;e||t.data("bs.affix",e=new h(this,i)),"string"==typeof o&&e[o]()})}h.VERSION="3.3.7",h.RESET="affix affix-top affix-bottom",h.DEFAULTS={offset:0,target:window},h.prototype.getState=function(t,e,i,o){var n=this.$target.scrollTop(),s=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return n 3)) {\n throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')\n }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.7\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n // ============================================================\n\n function transitionEnd() {\n var el = document.createElement('bootstrap')\n\n var transEndEventNames = {\n WebkitTransition : 'webkitTransitionEnd',\n MozTransition : 'transitionend',\n OTransition : 'oTransitionEnd otransitionend',\n transition : 'transitionend'\n }\n\n for (var name in transEndEventNames) {\n if (el.style[name] !== undefined) {\n return { end: transEndEventNames[name] }\n }\n }\n\n return false // explicit for ie8 ( ._.)\n }\n\n // http://blog.alexmaccaw.com/css-transitions\n $.fn.emulateTransitionEnd = function (duration) {\n var called = false\n var $el = this\n $(this).one('bsTransitionEnd', function () { called = true })\n var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n setTimeout(callback, duration)\n return this\n }\n\n $(function () {\n $.support.transition = transitionEnd()\n\n if (!$.support.transition) return\n\n $.event.special.bsTransitionEnd = {\n bindType: $.support.transition.end,\n delegateType: $.support.transition.end,\n handle: function (e) {\n if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n }\n }\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.7\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // ALERT CLASS DEFINITION\n // ======================\n\n var dismiss = '[data-dismiss=\"alert\"]'\n var Alert = function (el) {\n $(el).on('click', dismiss, this.close)\n }\n\n Alert.VERSION = '3.3.7'\n\n Alert.TRANSITION_DURATION = 150\n\n Alert.prototype.close = function (e) {\n var $this = $(this)\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = $(selector === '#' ? [] : selector)\n\n if (e) e.preventDefault()\n\n if (!$parent.length) {\n $parent = $this.closest('.alert')\n }\n\n $parent.trigger(e = $.Event('close.bs.alert'))\n\n if (e.isDefaultPrevented()) return\n\n $parent.removeClass('in')\n\n function removeElement() {\n // detach from parent, fire event then clean up data\n $parent.detach().trigger('closed.bs.alert').remove()\n }\n\n $.support.transition && $parent.hasClass('fade') ?\n $parent\n .one('bsTransitionEnd', removeElement)\n .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n removeElement()\n }\n\n\n // ALERT PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.alert')\n\n if (!data) $this.data('bs.alert', (data = new Alert(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.alert\n\n $.fn.alert = Plugin\n $.fn.alert.Constructor = Alert\n\n\n // ALERT NO CONFLICT\n // =================\n\n $.fn.alert.noConflict = function () {\n $.fn.alert = old\n return this\n }\n\n\n // ALERT DATA-API\n // ==============\n\n $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.7\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // BUTTON PUBLIC CLASS DEFINITION\n // ==============================\n\n var Button = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Button.DEFAULTS, options)\n this.isLoading = false\n }\n\n Button.VERSION = '3.3.7'\n\n Button.DEFAULTS = {\n loadingText: 'loading...'\n }\n\n Button.prototype.setState = function (state) {\n var d = 'disabled'\n var $el = this.$element\n var val = $el.is('input') ? 'val' : 'html'\n var data = $el.data()\n\n state += 'Text'\n\n if (data.resetText == null) $el.data('resetText', $el[val]())\n\n // push to event loop to allow forms to submit\n setTimeout($.proxy(function () {\n $el[val](data[state] == null ? this.options[state] : data[state])\n\n if (state == 'loadingText') {\n this.isLoading = true\n $el.addClass(d).attr(d, d).prop(d, true)\n } else if (this.isLoading) {\n this.isLoading = false\n $el.removeClass(d).removeAttr(d).prop(d, false)\n }\n }, this), 0)\n }\n\n Button.prototype.toggle = function () {\n var changed = true\n var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n if ($parent.length) {\n var $input = this.$element.find('input')\n if ($input.prop('type') == 'radio') {\n if ($input.prop('checked')) changed = false\n $parent.find('.active').removeClass('active')\n this.$element.addClass('active')\n } else if ($input.prop('type') == 'checkbox') {\n if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false\n this.$element.toggleClass('active')\n }\n $input.prop('checked', this.$element.hasClass('active'))\n if (changed) $input.trigger('change')\n } else {\n this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n this.$element.toggleClass('active')\n }\n }\n\n\n // BUTTON PLUGIN DEFINITION\n // ========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.button')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n if (option == 'toggle') data.toggle()\n else if (option) data.setState(option)\n })\n }\n\n var old = $.fn.button\n\n $.fn.button = Plugin\n $.fn.button.Constructor = Button\n\n\n // BUTTON NO CONFLICT\n // ==================\n\n $.fn.button.noConflict = function () {\n $.fn.button = old\n return this\n }\n\n\n // BUTTON DATA-API\n // ===============\n\n $(document)\n .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n var $btn = $(e.target).closest('.btn')\n Plugin.call($btn, 'toggle')\n if (!($(e.target).is('input[type=\"radio\"], input[type=\"checkbox\"]'))) {\n // Prevent double click on radios, and the double selections (so cancellation) on checkboxes\n e.preventDefault()\n // The target component still receive the focus\n if ($btn.is('input,button')) $btn.trigger('focus')\n else $btn.find('input:visible,button:visible').first().trigger('focus')\n }\n })\n .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.7\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CAROUSEL CLASS DEFINITION\n // =========================\n\n var Carousel = function (element, options) {\n this.$element = $(element)\n this.$indicators = this.$element.find('.carousel-indicators')\n this.options = options\n this.paused = null\n this.sliding = null\n this.interval = null\n this.$active = null\n this.$items = null\n\n this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n }\n\n Carousel.VERSION = '3.3.7'\n\n Carousel.TRANSITION_DURATION = 600\n\n Carousel.DEFAULTS = {\n interval: 5000,\n pause: 'hover',\n wrap: true,\n keyboard: true\n }\n\n Carousel.prototype.keydown = function (e) {\n if (/input|textarea/i.test(e.target.tagName)) return\n switch (e.which) {\n case 37: this.prev(); break\n case 39: this.next(); break\n default: return\n }\n\n e.preventDefault()\n }\n\n Carousel.prototype.cycle = function (e) {\n e || (this.paused = false)\n\n this.interval && clearInterval(this.interval)\n\n this.options.interval\n && !this.paused\n && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n return this\n }\n\n Carousel.prototype.getItemIndex = function (item) {\n this.$items = item.parent().children('.item')\n return this.$items.index(item || this.$active)\n }\n\n Carousel.prototype.getItemForDirection = function (direction, active) {\n var activeIndex = this.getItemIndex(active)\n var willWrap = (direction == 'prev' && activeIndex === 0)\n || (direction == 'next' && activeIndex == (this.$items.length - 1))\n if (willWrap && !this.options.wrap) return active\n var delta = direction == 'prev' ? -1 : 1\n var itemIndex = (activeIndex + delta) % this.$items.length\n return this.$items.eq(itemIndex)\n }\n\n Carousel.prototype.to = function (pos) {\n var that = this\n var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n if (pos > (this.$items.length - 1) || pos < 0) return\n\n if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n if (activeIndex == pos) return this.pause().cycle()\n\n return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n }\n\n Carousel.prototype.pause = function (e) {\n e || (this.paused = true)\n\n if (this.$element.find('.next, .prev').length && $.support.transition) {\n this.$element.trigger($.support.transition.end)\n this.cycle(true)\n }\n\n this.interval = clearInterval(this.interval)\n\n return this\n }\n\n Carousel.prototype.next = function () {\n if (this.sliding) return\n return this.slide('next')\n }\n\n Carousel.prototype.prev = function () {\n if (this.sliding) return\n return this.slide('prev')\n }\n\n Carousel.prototype.slide = function (type, next) {\n var $active = this.$element.find('.item.active')\n var $next = next || this.getItemForDirection(type, $active)\n var isCycling = this.interval\n var direction = type == 'next' ? 'left' : 'right'\n var that = this\n\n if ($next.hasClass('active')) return (this.sliding = false)\n\n var relatedTarget = $next[0]\n var slideEvent = $.Event('slide.bs.carousel', {\n relatedTarget: relatedTarget,\n direction: direction\n })\n this.$element.trigger(slideEvent)\n if (slideEvent.isDefaultPrevented()) return\n\n this.sliding = true\n\n isCycling && this.pause()\n\n if (this.$indicators.length) {\n this.$indicators.find('.active').removeClass('active')\n var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n $nextIndicator && $nextIndicator.addClass('active')\n }\n\n var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n if ($.support.transition && this.$element.hasClass('slide')) {\n $next.addClass(type)\n $next[0].offsetWidth // force reflow\n $active.addClass(direction)\n $next.addClass(direction)\n $active\n .one('bsTransitionEnd', function () {\n $next.removeClass([type, direction].join(' ')).addClass('active')\n $active.removeClass(['active', direction].join(' '))\n that.sliding = false\n setTimeout(function () {\n that.$element.trigger(slidEvent)\n }, 0)\n })\n .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n } else {\n $active.removeClass('active')\n $next.addClass('active')\n this.sliding = false\n this.$element.trigger(slidEvent)\n }\n\n isCycling && this.cycle()\n\n return this\n }\n\n\n // CAROUSEL PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.carousel')\n var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n var action = typeof option == 'string' ? option : options.slide\n\n if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n if (typeof option == 'number') data.to(option)\n else if (action) data[action]()\n else if (options.interval) data.pause().cycle()\n })\n }\n\n var old = $.fn.carousel\n\n $.fn.carousel = Plugin\n $.fn.carousel.Constructor = Carousel\n\n\n // CAROUSEL NO CONFLICT\n // ====================\n\n $.fn.carousel.noConflict = function () {\n $.fn.carousel = old\n return this\n }\n\n\n // CAROUSEL DATA-API\n // =================\n\n var clickHandler = function (e) {\n var href\n var $this = $(this)\n var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n if (!$target.hasClass('carousel')) return\n var options = $.extend({}, $target.data(), $this.data())\n var slideIndex = $this.attr('data-slide-to')\n if (slideIndex) options.interval = false\n\n Plugin.call($target, options)\n\n if (slideIndex) {\n $target.data('bs.carousel').to(slideIndex)\n }\n\n e.preventDefault()\n }\n\n $(document)\n .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n $(window).on('load', function () {\n $('[data-ride=\"carousel\"]').each(function () {\n var $carousel = $(this)\n Plugin.call($carousel, $carousel.data())\n })\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.7\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n/* jshint latedef: false */\n\n+function ($) {\n 'use strict';\n\n // COLLAPSE PUBLIC CLASS DEFINITION\n // ================================\n\n var Collapse = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Collapse.DEFAULTS, options)\n this.$trigger = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n this.transitioning = null\n\n if (this.options.parent) {\n this.$parent = this.getParent()\n } else {\n this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n }\n\n if (this.options.toggle) this.toggle()\n }\n\n Collapse.VERSION = '3.3.7'\n\n Collapse.TRANSITION_DURATION = 350\n\n Collapse.DEFAULTS = {\n toggle: true\n }\n\n Collapse.prototype.dimension = function () {\n var hasWidth = this.$element.hasClass('width')\n return hasWidth ? 'width' : 'height'\n }\n\n Collapse.prototype.show = function () {\n if (this.transitioning || this.$element.hasClass('in')) return\n\n var activesData\n var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n if (actives && actives.length) {\n activesData = actives.data('bs.collapse')\n if (activesData && activesData.transitioning) return\n }\n\n var startEvent = $.Event('show.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n if (actives && actives.length) {\n Plugin.call(actives, 'hide')\n activesData || actives.data('bs.collapse', null)\n }\n\n var dimension = this.dimension()\n\n this.$element\n .removeClass('collapse')\n .addClass('collapsing')[dimension](0)\n .attr('aria-expanded', true)\n\n this.$trigger\n .removeClass('collapsed')\n .attr('aria-expanded', true)\n\n this.transitioning = 1\n\n var complete = function () {\n this.$element\n .removeClass('collapsing')\n .addClass('collapse in')[dimension]('')\n this.transitioning = 0\n this.$element\n .trigger('shown.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n this.$element\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n }\n\n Collapse.prototype.hide = function () {\n if (this.transitioning || !this.$element.hasClass('in')) return\n\n var startEvent = $.Event('hide.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n var dimension = this.dimension()\n\n this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n this.$element\n .addClass('collapsing')\n .removeClass('collapse in')\n .attr('aria-expanded', false)\n\n this.$trigger\n .addClass('collapsed')\n .attr('aria-expanded', false)\n\n this.transitioning = 1\n\n var complete = function () {\n this.transitioning = 0\n this.$element\n .removeClass('collapsing')\n .addClass('collapse')\n .trigger('hidden.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n this.$element\n [dimension](0)\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n }\n\n Collapse.prototype.toggle = function () {\n this[this.$element.hasClass('in') ? 'hide' : 'show']()\n }\n\n Collapse.prototype.getParent = function () {\n return $(this.options.parent)\n .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n .each($.proxy(function (i, element) {\n var $element = $(element)\n this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n }, this))\n .end()\n }\n\n Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n var isOpen = $element.hasClass('in')\n\n $element.attr('aria-expanded', isOpen)\n $trigger\n .toggleClass('collapsed', !isOpen)\n .attr('aria-expanded', isOpen)\n }\n\n function getTargetFromTrigger($trigger) {\n var href\n var target = $trigger.attr('data-target')\n || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n return $(target)\n }\n\n\n // COLLAPSE PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.collapse')\n var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.collapse\n\n $.fn.collapse = Plugin\n $.fn.collapse.Constructor = Collapse\n\n\n // COLLAPSE NO CONFLICT\n // ====================\n\n $.fn.collapse.noConflict = function () {\n $.fn.collapse = old\n return this\n }\n\n\n // COLLAPSE DATA-API\n // =================\n\n $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n var $this = $(this)\n\n if (!$this.attr('data-target')) e.preventDefault()\n\n var $target = getTargetFromTrigger($this)\n var data = $target.data('bs.collapse')\n var option = data ? 'toggle' : $this.data()\n\n Plugin.call($target, option)\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.7\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // DROPDOWN CLASS DEFINITION\n // =========================\n\n var backdrop = '.dropdown-backdrop'\n var toggle = '[data-toggle=\"dropdown\"]'\n var Dropdown = function (element) {\n $(element).on('click.bs.dropdown', this.toggle)\n }\n\n Dropdown.VERSION = '3.3.7'\n\n function getParent($this) {\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = selector && $(selector)\n\n return $parent && $parent.length ? $parent : $this.parent()\n }\n\n function clearMenus(e) {\n if (e && e.which === 3) return\n $(backdrop).remove()\n $(toggle).each(function () {\n var $this = $(this)\n var $parent = getParent($this)\n var relatedTarget = { relatedTarget: this }\n\n if (!$parent.hasClass('open')) return\n\n if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return\n\n $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this.attr('aria-expanded', 'false')\n $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))\n })\n }\n\n Dropdown.prototype.toggle = function (e) {\n var $this = $(this)\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n clearMenus()\n\n if (!isActive) {\n if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n // if mobile we use a backdrop because click events don't delegate\n $(document.createElement('div'))\n .addClass('dropdown-backdrop')\n .insertAfter($(this))\n .on('click', clearMenus)\n }\n\n var relatedTarget = { relatedTarget: this }\n $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this\n .trigger('focus')\n .attr('aria-expanded', 'true')\n\n $parent\n .toggleClass('open')\n .trigger($.Event('shown.bs.dropdown', relatedTarget))\n }\n\n return false\n }\n\n Dropdown.prototype.keydown = function (e) {\n if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n var $this = $(this)\n\n e.preventDefault()\n e.stopPropagation()\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n if (!isActive && e.which != 27 || isActive && e.which == 27) {\n if (e.which == 27) $parent.find(toggle).trigger('focus')\n return $this.trigger('click')\n }\n\n var desc = ' li:not(.disabled):visible a'\n var $items = $parent.find('.dropdown-menu' + desc)\n\n if (!$items.length) return\n\n var index = $items.index(e.target)\n\n if (e.which == 38 && index > 0) index-- // up\n if (e.which == 40 && index < $items.length - 1) index++ // down\n if (!~index) index = 0\n\n $items.eq(index).trigger('focus')\n }\n\n\n // DROPDOWN PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.dropdown')\n\n if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.dropdown\n\n $.fn.dropdown = Plugin\n $.fn.dropdown.Constructor = Dropdown\n\n\n // DROPDOWN NO CONFLICT\n // ====================\n\n $.fn.dropdown.noConflict = function () {\n $.fn.dropdown = old\n return this\n }\n\n\n // APPLY TO STANDARD DROPDOWN ELEMENTS\n // ===================================\n\n $(document)\n .on('click.bs.dropdown.data-api', clearMenus)\n .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.7\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // MODAL CLASS DEFINITION\n // ======================\n\n var Modal = function (element, options) {\n this.options = options\n this.$body = $(document.body)\n this.$element = $(element)\n this.$dialog = this.$element.find('.modal-dialog')\n this.$backdrop = null\n this.isShown = null\n this.originalBodyPad = null\n this.scrollbarWidth = 0\n this.ignoreBackdropClick = false\n\n if (this.options.remote) {\n this.$element\n .find('.modal-content')\n .load(this.options.remote, $.proxy(function () {\n this.$element.trigger('loaded.bs.modal')\n }, this))\n }\n }\n\n Modal.VERSION = '3.3.7'\n\n Modal.TRANSITION_DURATION = 300\n Modal.BACKDROP_TRANSITION_DURATION = 150\n\n Modal.DEFAULTS = {\n backdrop: true,\n keyboard: true,\n show: true\n }\n\n Modal.prototype.toggle = function (_relatedTarget) {\n return this.isShown ? this.hide() : this.show(_relatedTarget)\n }\n\n Modal.prototype.show = function (_relatedTarget) {\n var that = this\n var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n this.$element.trigger(e)\n\n if (this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = true\n\n this.checkScrollbar()\n this.setScrollbar()\n this.$body.addClass('modal-open')\n\n this.escape()\n this.resize()\n\n this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n })\n })\n\n this.backdrop(function () {\n var transition = $.support.transition && that.$element.hasClass('fade')\n\n if (!that.$element.parent().length) {\n that.$element.appendTo(that.$body) // don't move modals dom position\n }\n\n that.$element\n .show()\n .scrollTop(0)\n\n that.adjustDialog()\n\n if (transition) {\n that.$element[0].offsetWidth // force reflow\n }\n\n that.$element.addClass('in')\n\n that.enforceFocus()\n\n var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n transition ?\n that.$dialog // wait for modal to slide in\n .one('bsTransitionEnd', function () {\n that.$element.trigger('focus').trigger(e)\n })\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n that.$element.trigger('focus').trigger(e)\n })\n }\n\n Modal.prototype.hide = function (e) {\n if (e) e.preventDefault()\n\n e = $.Event('hide.bs.modal')\n\n this.$element.trigger(e)\n\n if (!this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = false\n\n this.escape()\n this.resize()\n\n $(document).off('focusin.bs.modal')\n\n this.$element\n .removeClass('in')\n .off('click.dismiss.bs.modal')\n .off('mouseup.dismiss.bs.modal')\n\n this.$dialog.off('mousedown.dismiss.bs.modal')\n\n $.support.transition && this.$element.hasClass('fade') ?\n this.$element\n .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n this.hideModal()\n }\n\n Modal.prototype.enforceFocus = function () {\n $(document)\n .off('focusin.bs.modal') // guard against infinite focus loop\n .on('focusin.bs.modal', $.proxy(function (e) {\n if (document !== e.target &&\n this.$element[0] !== e.target &&\n !this.$element.has(e.target).length) {\n this.$element.trigger('focus')\n }\n }, this))\n }\n\n Modal.prototype.escape = function () {\n if (this.isShown && this.options.keyboard) {\n this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n e.which == 27 && this.hide()\n }, this))\n } else if (!this.isShown) {\n this.$element.off('keydown.dismiss.bs.modal')\n }\n }\n\n Modal.prototype.resize = function () {\n if (this.isShown) {\n $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n } else {\n $(window).off('resize.bs.modal')\n }\n }\n\n Modal.prototype.hideModal = function () {\n var that = this\n this.$element.hide()\n this.backdrop(function () {\n that.$body.removeClass('modal-open')\n that.resetAdjustments()\n that.resetScrollbar()\n that.$element.trigger('hidden.bs.modal')\n })\n }\n\n Modal.prototype.removeBackdrop = function () {\n this.$backdrop && this.$backdrop.remove()\n this.$backdrop = null\n }\n\n Modal.prototype.backdrop = function (callback) {\n var that = this\n var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n if (this.isShown && this.options.backdrop) {\n var doAnimate = $.support.transition && animate\n\n this.$backdrop = $(document.createElement('div'))\n .addClass('modal-backdrop ' + animate)\n .appendTo(this.$body)\n\n this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n if (this.ignoreBackdropClick) {\n this.ignoreBackdropClick = false\n return\n }\n if (e.target !== e.currentTarget) return\n this.options.backdrop == 'static'\n ? this.$element[0].focus()\n : this.hide()\n }, this))\n\n if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n this.$backdrop.addClass('in')\n\n if (!callback) return\n\n doAnimate ?\n this.$backdrop\n .one('bsTransitionEnd', callback)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callback()\n\n } else if (!this.isShown && this.$backdrop) {\n this.$backdrop.removeClass('in')\n\n var callbackRemove = function () {\n that.removeBackdrop()\n callback && callback()\n }\n $.support.transition && this.$element.hasClass('fade') ?\n this.$backdrop\n .one('bsTransitionEnd', callbackRemove)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callbackRemove()\n\n } else if (callback) {\n callback()\n }\n }\n\n // these following methods are used to handle overflowing modals\n\n Modal.prototype.handleUpdate = function () {\n this.adjustDialog()\n }\n\n Modal.prototype.adjustDialog = function () {\n var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n this.$element.css({\n paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n })\n }\n\n Modal.prototype.resetAdjustments = function () {\n this.$element.css({\n paddingLeft: '',\n paddingRight: ''\n })\n }\n\n Modal.prototype.checkScrollbar = function () {\n var fullWindowWidth = window.innerWidth\n if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n var documentElementRect = document.documentElement.getBoundingClientRect()\n fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n }\n this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n this.scrollbarWidth = this.measureScrollbar()\n }\n\n Modal.prototype.setScrollbar = function () {\n var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n this.originalBodyPad = document.body.style.paddingRight || ''\n if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n }\n\n Modal.prototype.resetScrollbar = function () {\n this.$body.css('padding-right', this.originalBodyPad)\n }\n\n Modal.prototype.measureScrollbar = function () { // thx walsh\n var scrollDiv = document.createElement('div')\n scrollDiv.className = 'modal-scrollbar-measure'\n this.$body.append(scrollDiv)\n var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n this.$body[0].removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n\n // MODAL PLUGIN DEFINITION\n // =======================\n\n function Plugin(option, _relatedTarget) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.modal')\n var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n if (typeof option == 'string') data[option](_relatedTarget)\n else if (options.show) data.show(_relatedTarget)\n })\n }\n\n var old = $.fn.modal\n\n $.fn.modal = Plugin\n $.fn.modal.Constructor = Modal\n\n\n // MODAL NO CONFLICT\n // =================\n\n $.fn.modal.noConflict = function () {\n $.fn.modal = old\n return this\n }\n\n\n // MODAL DATA-API\n // ==============\n\n $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n var $this = $(this)\n var href = $this.attr('href')\n var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n if ($this.is('a')) e.preventDefault()\n\n $target.one('show.bs.modal', function (showEvent) {\n if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n $target.one('hidden.bs.modal', function () {\n $this.is(':visible') && $this.trigger('focus')\n })\n })\n Plugin.call($target, option, this)\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.7\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // TOOLTIP PUBLIC CLASS DEFINITION\n // ===============================\n\n var Tooltip = function (element, options) {\n this.type = null\n this.options = null\n this.enabled = null\n this.timeout = null\n this.hoverState = null\n this.$element = null\n this.inState = null\n\n this.init('tooltip', element, options)\n }\n\n Tooltip.VERSION = '3.3.7'\n\n Tooltip.TRANSITION_DURATION = 150\n\n Tooltip.DEFAULTS = {\n animation: true,\n placement: 'top',\n selector: false,\n template: '
',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n container: false,\n viewport: {\n selector: 'body',\n padding: 0\n }\n }\n\n Tooltip.prototype.init = function (type, element, options) {\n this.enabled = true\n this.type = type\n this.$element = $(element)\n this.options = this.getOptions(options)\n this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n this.inState = { click: false, hover: false, focus: false }\n\n if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n }\n\n var triggers = this.options.trigger.split(' ')\n\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i]\n\n if (trigger == 'click') {\n this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n } else if (trigger != 'manual') {\n var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'\n var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n }\n }\n\n this.options.selector ?\n (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n this.fixTitle()\n }\n\n Tooltip.prototype.getDefaults = function () {\n return Tooltip.DEFAULTS\n }\n\n Tooltip.prototype.getOptions = function (options) {\n options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n if (options.delay && typeof options.delay == 'number') {\n options.delay = {\n show: options.delay,\n hide: options.delay\n }\n }\n\n return options\n }\n\n Tooltip.prototype.getDelegateOptions = function () {\n var options = {}\n var defaults = this.getDefaults()\n\n this._options && $.each(this._options, function (key, value) {\n if (defaults[key] != value) options[key] = value\n })\n\n return options\n }\n\n Tooltip.prototype.enter = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n if (obj instanceof $.Event) {\n self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true\n }\n\n if (self.tip().hasClass('in') || self.hoverState == 'in') {\n self.hoverState = 'in'\n return\n }\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'in'\n\n if (!self.options.delay || !self.options.delay.show) return self.show()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'in') self.show()\n }, self.options.delay.show)\n }\n\n Tooltip.prototype.isInStateTrue = function () {\n for (var key in this.inState) {\n if (this.inState[key]) return true\n }\n\n return false\n }\n\n Tooltip.prototype.leave = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n if (obj instanceof $.Event) {\n self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false\n }\n\n if (self.isInStateTrue()) return\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'out'\n\n if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'out') self.hide()\n }, self.options.delay.hide)\n }\n\n Tooltip.prototype.show = function () {\n var e = $.Event('show.bs.' + this.type)\n\n if (this.hasContent() && this.enabled) {\n this.$element.trigger(e)\n\n var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n if (e.isDefaultPrevented() || !inDom) return\n var that = this\n\n var $tip = this.tip()\n\n var tipId = this.getUID(this.type)\n\n this.setContent()\n $tip.attr('id', tipId)\n this.$element.attr('aria-describedby', tipId)\n\n if (this.options.animation) $tip.addClass('fade')\n\n var placement = typeof this.options.placement == 'function' ?\n this.options.placement.call(this, $tip[0], this.$element[0]) :\n this.options.placement\n\n var autoToken = /\\s?auto?\\s?/i\n var autoPlace = autoToken.test(placement)\n if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n $tip\n .detach()\n .css({ top: 0, left: 0, display: 'block' })\n .addClass(placement)\n .data('bs.' + this.type, this)\n\n this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n this.$element.trigger('inserted.bs.' + this.type)\n\n var pos = this.getPosition()\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (autoPlace) {\n var orgPlacement = placement\n var viewportDim = this.getPosition(this.$viewport)\n\n placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :\n placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :\n placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :\n placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :\n placement\n\n $tip\n .removeClass(orgPlacement)\n .addClass(placement)\n }\n\n var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n this.applyPlacement(calculatedOffset, placement)\n\n var complete = function () {\n var prevHoverState = that.hoverState\n that.$element.trigger('shown.bs.' + that.type)\n that.hoverState = null\n\n if (prevHoverState == 'out') that.leave(that)\n }\n\n $.support.transition && this.$tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n }\n }\n\n Tooltip.prototype.applyPlacement = function (offset, placement) {\n var $tip = this.tip()\n var width = $tip[0].offsetWidth\n var height = $tip[0].offsetHeight\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt($tip.css('margin-top'), 10)\n var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0\n if (isNaN(marginLeft)) marginLeft = 0\n\n offset.top += marginTop\n offset.left += marginLeft\n\n // $.fn.offset doesn't round pixel values\n // so we use setOffset directly with our own function B-0\n $.offset.setOffset($tip[0], $.extend({\n using: function (props) {\n $tip.css({\n top: Math.round(props.top),\n left: Math.round(props.left)\n })\n }\n }, offset), 0)\n\n $tip.addClass('in')\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (placement == 'top' && actualHeight != height) {\n offset.top = offset.top + height - actualHeight\n }\n\n var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n if (delta.left) offset.left += delta.left\n else offset.top += delta.top\n\n var isVertical = /top|bottom/.test(placement)\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n $tip.offset(offset)\n this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n }\n\n Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n this.arrow()\n .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isVertical ? 'top' : 'left', '')\n }\n\n Tooltip.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n\n $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n $tip.removeClass('fade in top bottom left right')\n }\n\n Tooltip.prototype.hide = function (callback) {\n var that = this\n var $tip = $(this.$tip)\n var e = $.Event('hide.bs.' + this.type)\n\n function complete() {\n if (that.hoverState != 'in') $tip.detach()\n if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.\n that.$element\n .removeAttr('aria-describedby')\n .trigger('hidden.bs.' + that.type)\n }\n callback && callback()\n }\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n $tip.removeClass('in')\n\n $.support.transition && $tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n\n this.hoverState = null\n\n return this\n }\n\n Tooltip.prototype.fixTitle = function () {\n var $e = this.$element\n if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {\n $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n }\n }\n\n Tooltip.prototype.hasContent = function () {\n return this.getTitle()\n }\n\n Tooltip.prototype.getPosition = function ($element) {\n $element = $element || this.$element\n\n var el = $element[0]\n var isBody = el.tagName == 'BODY'\n\n var elRect = el.getBoundingClientRect()\n if (elRect.width == null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n }\n var isSvg = window.SVGElement && el instanceof window.SVGElement\n // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.\n // See https://github.com/twbs/bootstrap/issues/20280\n var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())\n var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n return $.extend({}, elRect, scroll, outerDims, elOffset)\n }\n\n Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n }\n\n Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 }\n if (!this.$viewport) return delta\n\n var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n var viewportDimensions = this.getPosition(this.$viewport)\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll\n var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n }\n } else {\n var leftEdgeOffset = pos.left - viewportPadding\n var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n }\n }\n\n return delta\n }\n\n Tooltip.prototype.getTitle = function () {\n var title\n var $e = this.$element\n var o = this.options\n\n title = $e.attr('data-original-title')\n || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)\n\n return title\n }\n\n Tooltip.prototype.getUID = function (prefix) {\n do prefix += ~~(Math.random() * 1000000)\n while (document.getElementById(prefix))\n return prefix\n }\n\n Tooltip.prototype.tip = function () {\n if (!this.$tip) {\n this.$tip = $(this.options.template)\n if (this.$tip.length != 1) {\n throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n }\n }\n return this.$tip\n }\n\n Tooltip.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n }\n\n Tooltip.prototype.enable = function () {\n this.enabled = true\n }\n\n Tooltip.prototype.disable = function () {\n this.enabled = false\n }\n\n Tooltip.prototype.toggleEnabled = function () {\n this.enabled = !this.enabled\n }\n\n Tooltip.prototype.toggle = function (e) {\n var self = this\n if (e) {\n self = $(e.currentTarget).data('bs.' + this.type)\n if (!self) {\n self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n $(e.currentTarget).data('bs.' + this.type, self)\n }\n }\n\n if (e) {\n self.inState.click = !self.inState.click\n if (self.isInStateTrue()) self.enter(self)\n else self.leave(self)\n } else {\n self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n }\n }\n\n Tooltip.prototype.destroy = function () {\n var that = this\n clearTimeout(this.timeout)\n this.hide(function () {\n that.$element.off('.' + that.type).removeData('bs.' + that.type)\n if (that.$tip) {\n that.$tip.detach()\n }\n that.$tip = null\n that.$arrow = null\n that.$viewport = null\n that.$element = null\n })\n }\n\n\n // TOOLTIP PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tooltip')\n var options = typeof option == 'object' && option\n\n if (!data && /destroy|hide/.test(option)) return\n if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tooltip\n\n $.fn.tooltip = Plugin\n $.fn.tooltip.Constructor = Tooltip\n\n\n // TOOLTIP NO CONFLICT\n // ===================\n\n $.fn.tooltip.noConflict = function () {\n $.fn.tooltip = old\n return this\n }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.7\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // POPOVER PUBLIC CLASS DEFINITION\n // ===============================\n\n var Popover = function (element, options) {\n this.init('popover', element, options)\n }\n\n if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n Popover.VERSION = '3.3.7'\n\n Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '

'\n })\n\n\n // NOTE: POPOVER EXTENDS tooltip.js\n // ================================\n\n Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n Popover.prototype.constructor = Popover\n\n Popover.prototype.getDefaults = function () {\n return Popover.DEFAULTS\n }\n\n Popover.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n var content = this.getContent()\n\n $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n ](content)\n\n $tip.removeClass('fade top bottom left right in')\n\n // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n // this manually by checking the contents.\n if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n }\n\n Popover.prototype.hasContent = function () {\n return this.getTitle() || this.getContent()\n }\n\n Popover.prototype.getContent = function () {\n var $e = this.$element\n var o = this.options\n\n return $e.attr('data-content')\n || (typeof o.content == 'function' ?\n o.content.call($e[0]) :\n o.content)\n }\n\n Popover.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n }\n\n\n // POPOVER PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.popover')\n var options = typeof option == 'object' && option\n\n if (!data && /destroy|hide/.test(option)) return\n if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.popover\n\n $.fn.popover = Plugin\n $.fn.popover.Constructor = Popover\n\n\n // POPOVER NO CONFLICT\n // ===================\n\n $.fn.popover.noConflict = function () {\n $.fn.popover = old\n return this\n }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.7\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // SCROLLSPY CLASS DEFINITION\n // ==========================\n\n function ScrollSpy(element, options) {\n this.$body = $(document.body)\n this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n this.options = $.extend({}, ScrollSpy.DEFAULTS, options)\n this.selector = (this.options.target || '') + ' .nav li > a'\n this.offsets = []\n this.targets = []\n this.activeTarget = null\n this.scrollHeight = 0\n\n this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n this.refresh()\n this.process()\n }\n\n ScrollSpy.VERSION = '3.3.7'\n\n ScrollSpy.DEFAULTS = {\n offset: 10\n }\n\n ScrollSpy.prototype.getScrollHeight = function () {\n return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n }\n\n ScrollSpy.prototype.refresh = function () {\n var that = this\n var offsetMethod = 'offset'\n var offsetBase = 0\n\n this.offsets = []\n this.targets = []\n this.scrollHeight = this.getScrollHeight()\n\n if (!$.isWindow(this.$scrollElement[0])) {\n offsetMethod = 'position'\n offsetBase = this.$scrollElement.scrollTop()\n }\n\n this.$body\n .find(this.selector)\n .map(function () {\n var $el = $(this)\n var href = $el.data('target') || $el.attr('href')\n var $href = /^#./.test(href) && $(href)\n\n return ($href\n && $href.length\n && $href.is(':visible')\n && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n })\n .sort(function (a, b) { return a[0] - b[0] })\n .each(function () {\n that.offsets.push(this[0])\n that.targets.push(this[1])\n })\n }\n\n ScrollSpy.prototype.process = function () {\n var scrollTop = this.$scrollElement.scrollTop() + this.options.offset\n var scrollHeight = this.getScrollHeight()\n var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()\n var offsets = this.offsets\n var targets = this.targets\n var activeTarget = this.activeTarget\n var i\n\n if (this.scrollHeight != scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n }\n\n if (activeTarget && scrollTop < offsets[0]) {\n this.activeTarget = null\n return this.clear()\n }\n\n for (i = offsets.length; i--;) {\n activeTarget != targets[i]\n && scrollTop >= offsets[i]\n && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n && this.activate(targets[i])\n }\n }\n\n ScrollSpy.prototype.activate = function (target) {\n this.activeTarget = target\n\n this.clear()\n\n var selector = this.selector +\n '[data-target=\"' + target + '\"],' +\n this.selector + '[href=\"' + target + '\"]'\n\n var active = $(selector)\n .parents('li')\n .addClass('active')\n\n if (active.parent('.dropdown-menu').length) {\n active = active\n .closest('li.dropdown')\n .addClass('active')\n }\n\n active.trigger('activate.bs.scrollspy')\n }\n\n ScrollSpy.prototype.clear = function () {\n $(this.selector)\n .parentsUntil(this.options.target, '.active')\n .removeClass('active')\n }\n\n\n // SCROLLSPY PLUGIN DEFINITION\n // ===========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.scrollspy')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.scrollspy\n\n $.fn.scrollspy = Plugin\n $.fn.scrollspy.Constructor = ScrollSpy\n\n\n // SCROLLSPY NO CONFLICT\n // =====================\n\n $.fn.scrollspy.noConflict = function () {\n $.fn.scrollspy = old\n return this\n }\n\n\n // SCROLLSPY DATA-API\n // ==================\n\n $(window).on('load.bs.scrollspy.data-api', function () {\n $('[data-spy=\"scroll\"]').each(function () {\n var $spy = $(this)\n Plugin.call($spy, $spy.data())\n })\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.7\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // TAB CLASS DEFINITION\n // ====================\n\n var Tab = function (element) {\n // jscs:disable requireDollarBeforejQueryAssignment\n this.element = $(element)\n // jscs:enable requireDollarBeforejQueryAssignment\n }\n\n Tab.VERSION = '3.3.7'\n\n Tab.TRANSITION_DURATION = 150\n\n Tab.prototype.show = function () {\n var $this = this.element\n var $ul = $this.closest('ul:not(.dropdown-menu)')\n var selector = $this.data('target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n if ($this.parent('li').hasClass('active')) return\n\n var $previous = $ul.find('.active:last a')\n var hideEvent = $.Event('hide.bs.tab', {\n relatedTarget: $this[0]\n })\n var showEvent = $.Event('show.bs.tab', {\n relatedTarget: $previous[0]\n })\n\n $previous.trigger(hideEvent)\n $this.trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n var $target = $(selector)\n\n this.activate($this.closest('li'), $ul)\n this.activate($target, $target.parent(), function () {\n $previous.trigger({\n type: 'hidden.bs.tab',\n relatedTarget: $this[0]\n })\n $this.trigger({\n type: 'shown.bs.tab',\n relatedTarget: $previous[0]\n })\n })\n }\n\n Tab.prototype.activate = function (element, container, callback) {\n var $active = container.find('> .active')\n var transition = callback\n && $.support.transition\n && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)\n\n function next() {\n $active\n .removeClass('active')\n .find('> .dropdown-menu > .active')\n .removeClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', false)\n\n element\n .addClass('active')\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n\n if (transition) {\n element[0].offsetWidth // reflow for transition\n element.addClass('in')\n } else {\n element.removeClass('fade')\n }\n\n if (element.parent('.dropdown-menu').length) {\n element\n .closest('li.dropdown')\n .addClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n }\n\n callback && callback()\n }\n\n $active.length && transition ?\n $active\n .one('bsTransitionEnd', next)\n .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n next()\n\n $active.removeClass('in')\n }\n\n\n // TAB PLUGIN DEFINITION\n // =====================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tab')\n\n if (!data) $this.data('bs.tab', (data = new Tab(this)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tab\n\n $.fn.tab = Plugin\n $.fn.tab.Constructor = Tab\n\n\n // TAB NO CONFLICT\n // ===============\n\n $.fn.tab.noConflict = function () {\n $.fn.tab = old\n return this\n }\n\n\n // TAB DATA-API\n // ============\n\n var clickHandler = function (e) {\n e.preventDefault()\n Plugin.call($(this), 'show')\n }\n\n $(document)\n .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.7\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // AFFIX CLASS DEFINITION\n // ======================\n\n var Affix = function (element, options) {\n this.options = $.extend({}, Affix.DEFAULTS, options)\n\n this.$target = $(this.options.target)\n .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))\n\n this.$element = $(element)\n this.affixed = null\n this.unpin = null\n this.pinnedOffset = null\n\n this.checkPosition()\n }\n\n Affix.VERSION = '3.3.7'\n\n Affix.RESET = 'affix affix-top affix-bottom'\n\n Affix.DEFAULTS = {\n offset: 0,\n target: window\n }\n\n Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n var targetHeight = this.$target.height()\n\n if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n if (this.affixed == 'bottom') {\n if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n }\n\n var initializing = this.affixed == null\n var colliderTop = initializing ? scrollTop : position.top\n var colliderHeight = initializing ? targetHeight : height\n\n if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n return false\n }\n\n Affix.prototype.getPinnedOffset = function () {\n if (this.pinnedOffset) return this.pinnedOffset\n this.$element.removeClass(Affix.RESET).addClass('affix')\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n return (this.pinnedOffset = position.top - scrollTop)\n }\n\n Affix.prototype.checkPositionWithEventLoop = function () {\n setTimeout($.proxy(this.checkPosition, this), 1)\n }\n\n Affix.prototype.checkPosition = function () {\n if (!this.$element.is(':visible')) return\n\n var height = this.$element.height()\n var offset = this.options.offset\n var offsetTop = offset.top\n var offsetBottom = offset.bottom\n var scrollHeight = Math.max($(document).height(), $(document.body).height())\n\n if (typeof offset != 'object') offsetBottom = offsetTop = offset\n if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)\n if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n if (this.affixed != affix) {\n if (this.unpin != null) this.$element.css('top', '')\n\n var affixType = 'affix' + (affix ? '-' + affix : '')\n var e = $.Event(affixType + '.bs.affix')\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n this.affixed = affix\n this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n this.$element\n .removeClass(Affix.RESET)\n .addClass(affixType)\n .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n }\n\n if (affix == 'bottom') {\n this.$element.offset({\n top: scrollHeight - height - offsetBottom\n })\n }\n }\n\n\n // AFFIX PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.affix')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.affix\n\n $.fn.affix = Plugin\n $.fn.affix.Constructor = Affix\n\n\n // AFFIX NO CONFLICT\n // =================\n\n $.fn.affix.noConflict = function () {\n $.fn.affix = old\n return this\n }\n\n\n // AFFIX DATA-API\n // ==============\n\n $(window).on('load', function () {\n $('[data-spy=\"affix\"]').each(function () {\n var $spy = $(this)\n var data = $spy.data()\n\n data.offset = data.offset || {}\n\n if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n if (data.offsetTop != null) data.offset.top = data.offsetTop\n\n Plugin.call($spy, data)\n })\n })\n\n}(jQuery);\n"]} \ No newline at end of file +{"version":3,"sources":["bootstrap.js"],"names":["jQuery","Error","$","version","fn","jquery","split","emulateTransitionEnd","duration","called","$el","this","one","setTimeout","trigger","support","transition","end","el","document","createElement","transEndEventNames","WebkitTransition","MozTransition","OTransition","name","undefined","style","transitionEnd","event","special","bsTransitionEnd","bindType","delegateType","handle","e","target","is","handleObj","handler","apply","arguments","Alert","on","dismiss","close","VERSION","TRANSITION_DURATION","prototype","$this","selector","attr","replace","$parent","removeElement","detach","remove","preventDefault","length","closest","Event","isDefaultPrevented","removeClass","hasClass","old","alert","option","each","data","call","Constructor","noConflict","Button","element","options","$element","extend","DEFAULTS","isLoading","Plugin","toggle","setState","loadingText","state","d","val","resetText","proxy","addClass","prop","removeAttr","changed","$input","find","toggleClass","button","$btn","first","test","type","Carousel","$indicators","paused","sliding","interval","$active","$items","keyboard","keydown","pause","documentElement","cycle","action","slide","to","wrap","tagName","which","prev","next","clearInterval","setInterval","getItemIndex","item","parent","children","index","getItemForDirection","direction","active","activeIndex","itemIndex","eq","pos","that","$next","isCycling","relatedTarget","slideEvent","$nextIndicator","slidEvent","offsetWidth","join","carousel","clickHandler","href","$target","slideIndex","window","$carousel","Collapse","$trigger","id","transitioning","getParent","addAriaAndCollapsedClass","getTargetFromTrigger","dimension","show","activesData","actives","startEvent","complete","scrollSize","camelCase","hide","offsetHeight","i","isOpen","collapse","Dropdown","clearMenus","contains","isActive","insertAfter","stopPropagation","dropdown","Modal","$body","body","$dialog","$backdrop","isShown","originalBodyPad","scrollbarWidth","ignoreBackdropClick","remote","load","_relatedTarget","BACKDROP_TRANSITION_DURATION","backdrop","checkScrollbar","setScrollbar","escape","resize","appendTo","scrollTop","adjustDialog","enforceFocus","off","hideModal","has","handleUpdate","resetAdjustments","resetScrollbar","removeBackdrop","callback","animate","doAnimate","currentTarget","focus","callbackRemove","modalIsOverflowing","scrollHeight","clientHeight","css","paddingLeft","bodyIsOverflowing","paddingRight","fullWindowWidth","innerWidth","documentElementRect","getBoundingClientRect","right","Math","abs","left","clientWidth","measureScrollbar","bodyPad","parseInt","scrollDiv","className","append","removeChild","modal","showEvent","Tooltip","enabled","timeout","hoverState","inState","init","animation","placement","template","title","delay","html","container","viewport","padding","getOptions","$viewport","isFunction","click","hover","constructor","triggers","eventIn","eventOut","enter","leave","_options","fixTitle","getDefaults","getDelegateOptions","defaults","key","value","obj","self","tip","clearTimeout","isInStateTrue","hasContent","inDom","ownerDocument","$tip","tipId","getUID","setContent","autoToken","autoPlace","top","display","getPosition","actualWidth","actualHeight","orgPlacement","viewportDim","bottom","width","calculatedOffset","getCalculatedOffset","applyPlacement","prevHoverState","offset","height","marginTop","marginLeft","isNaN","setOffset","using","props","round","delta","getViewportAdjustedDelta","isVertical","arrowDelta","arrowOffsetPosition","replaceArrow","arrow","getTitle","$e","isBody","elRect","isSvg","SVGElement","elOffset","scroll","outerDims","viewportPadding","viewportDimensions","topEdgeOffset","bottomEdgeOffset","leftEdgeOffset","rightEdgeOffset","o","prefix","random","getElementById","$arrow","enable","disable","toggleEnabled","destroy","removeData","tooltip","Popover","content","getContent","popover","ScrollSpy","$scrollElement","offsets","targets","activeTarget","process","refresh","getScrollHeight","max","offsetMethod","offsetBase","isWindow","map","$href","sort","a","b","push","maxScroll","activate","clear","parents","parentsUntil","scrollspy","$spy","Tab","$ul","$previous","hideEvent","tab","Affix","checkPosition","checkPositionWithEventLoop","affixed","unpin","pinnedOffset","RESET","getState","offsetTop","offsetBottom","position","targetHeight","initializing","colliderTop","getPinnedOffset","affix","affixType"],"mappings":"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","file":"bootstrap.js","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under the MIT license\n */\n\nif (typeof jQuery === 'undefined') {\n throw new Error('Bootstrap\\'s JavaScript requires jQuery')\n}\n\n+function ($) {\n 'use strict';\n var version = $.fn.jquery.split(' ')[0].split('.')\n if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {\n throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')\n }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.7\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n // ============================================================\n\n function transitionEnd() {\n var el = document.createElement('bootstrap')\n\n var transEndEventNames = {\n WebkitTransition : 'webkitTransitionEnd',\n MozTransition : 'transitionend',\n OTransition : 'oTransitionEnd otransitionend',\n transition : 'transitionend'\n }\n\n for (var name in transEndEventNames) {\n if (el.style[name] !== undefined) {\n return { end: transEndEventNames[name] }\n }\n }\n\n return false // explicit for ie8 ( ._.)\n }\n\n // http://blog.alexmaccaw.com/css-transitions\n $.fn.emulateTransitionEnd = function (duration) {\n var called = false\n var $el = this\n $(this).one('bsTransitionEnd', function () { called = true })\n var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n setTimeout(callback, duration)\n return this\n }\n\n $(function () {\n $.support.transition = transitionEnd()\n\n if (!$.support.transition) return\n\n $.event.special.bsTransitionEnd = {\n bindType: $.support.transition.end,\n delegateType: $.support.transition.end,\n handle: function (e) {\n if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n }\n }\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.7\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // ALERT CLASS DEFINITION\n // ======================\n\n var dismiss = '[data-dismiss=\"alert\"]'\n var Alert = function (el) {\n $(el).on('click', dismiss, this.close)\n }\n\n Alert.VERSION = '3.3.7'\n\n Alert.TRANSITION_DURATION = 150\n\n Alert.prototype.close = function (e) {\n var $this = $(this)\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = $(selector === '#' ? [] : selector)\n\n if (e) e.preventDefault()\n\n if (!$parent.length) {\n $parent = $this.closest('.alert')\n }\n\n $parent.trigger(e = $.Event('close.bs.alert'))\n\n if (e.isDefaultPrevented()) return\n\n $parent.removeClass('in')\n\n function removeElement() {\n // detach from parent, fire event then clean up data\n $parent.detach().trigger('closed.bs.alert').remove()\n }\n\n $.support.transition && $parent.hasClass('fade') ?\n $parent\n .one('bsTransitionEnd', removeElement)\n .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n removeElement()\n }\n\n\n // ALERT PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.alert')\n\n if (!data) $this.data('bs.alert', (data = new Alert(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.alert\n\n $.fn.alert = Plugin\n $.fn.alert.Constructor = Alert\n\n\n // ALERT NO CONFLICT\n // =================\n\n $.fn.alert.noConflict = function () {\n $.fn.alert = old\n return this\n }\n\n\n // ALERT DATA-API\n // ==============\n\n $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.7\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // BUTTON PUBLIC CLASS DEFINITION\n // ==============================\n\n var Button = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Button.DEFAULTS, options)\n this.isLoading = false\n }\n\n Button.VERSION = '3.3.7'\n\n Button.DEFAULTS = {\n loadingText: 'loading...'\n }\n\n Button.prototype.setState = function (state) {\n var d = 'disabled'\n var $el = this.$element\n var val = $el.is('input') ? 'val' : 'html'\n var data = $el.data()\n\n state += 'Text'\n\n if (data.resetText == null) $el.data('resetText', $el[val]())\n\n // push to event loop to allow forms to submit\n setTimeout($.proxy(function () {\n $el[val](data[state] == null ? this.options[state] : data[state])\n\n if (state == 'loadingText') {\n this.isLoading = true\n $el.addClass(d).attr(d, d).prop(d, true)\n } else if (this.isLoading) {\n this.isLoading = false\n $el.removeClass(d).removeAttr(d).prop(d, false)\n }\n }, this), 0)\n }\n\n Button.prototype.toggle = function () {\n var changed = true\n var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n if ($parent.length) {\n var $input = this.$element.find('input')\n if ($input.prop('type') == 'radio') {\n if ($input.prop('checked')) changed = false\n $parent.find('.active').removeClass('active')\n this.$element.addClass('active')\n } else if ($input.prop('type') == 'checkbox') {\n if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false\n this.$element.toggleClass('active')\n }\n $input.prop('checked', this.$element.hasClass('active'))\n if (changed) $input.trigger('change')\n } else {\n this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n this.$element.toggleClass('active')\n }\n }\n\n\n // BUTTON PLUGIN DEFINITION\n // ========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.button')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n if (option == 'toggle') data.toggle()\n else if (option) data.setState(option)\n })\n }\n\n var old = $.fn.button\n\n $.fn.button = Plugin\n $.fn.button.Constructor = Button\n\n\n // BUTTON NO CONFLICT\n // ==================\n\n $.fn.button.noConflict = function () {\n $.fn.button = old\n return this\n }\n\n\n // BUTTON DATA-API\n // ===============\n\n $(document)\n .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n var $btn = $(e.target).closest('.btn')\n Plugin.call($btn, 'toggle')\n if (!($(e.target).is('input[type=\"radio\"], input[type=\"checkbox\"]'))) {\n // Prevent double click on radios, and the double selections (so cancellation) on checkboxes\n e.preventDefault()\n // The target component still receive the focus\n if ($btn.is('input,button')) $btn.trigger('focus')\n else $btn.find('input:visible,button:visible').first().trigger('focus')\n }\n })\n .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.7\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CAROUSEL CLASS DEFINITION\n // =========================\n\n var Carousel = function (element, options) {\n this.$element = $(element)\n this.$indicators = this.$element.find('.carousel-indicators')\n this.options = options\n this.paused = null\n this.sliding = null\n this.interval = null\n this.$active = null\n this.$items = null\n\n this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n }\n\n Carousel.VERSION = '3.3.7'\n\n Carousel.TRANSITION_DURATION = 600\n\n Carousel.DEFAULTS = {\n interval: 5000,\n pause: 'hover',\n wrap: true,\n keyboard: true\n }\n\n Carousel.prototype.keydown = function (e) {\n if (/input|textarea/i.test(e.target.tagName)) return\n switch (e.which) {\n case 37: this.prev(); break\n case 39: this.next(); break\n default: return\n }\n\n e.preventDefault()\n }\n\n Carousel.prototype.cycle = function (e) {\n e || (this.paused = false)\n\n this.interval && clearInterval(this.interval)\n\n this.options.interval\n && !this.paused\n && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n return this\n }\n\n Carousel.prototype.getItemIndex = function (item) {\n this.$items = item.parent().children('.item')\n return this.$items.index(item || this.$active)\n }\n\n Carousel.prototype.getItemForDirection = function (direction, active) {\n var activeIndex = this.getItemIndex(active)\n var willWrap = (direction == 'prev' && activeIndex === 0)\n || (direction == 'next' && activeIndex == (this.$items.length - 1))\n if (willWrap && !this.options.wrap) return active\n var delta = direction == 'prev' ? -1 : 1\n var itemIndex = (activeIndex + delta) % this.$items.length\n return this.$items.eq(itemIndex)\n }\n\n Carousel.prototype.to = function (pos) {\n var that = this\n var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n if (pos > (this.$items.length - 1) || pos < 0) return\n\n if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n if (activeIndex == pos) return this.pause().cycle()\n\n return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n }\n\n Carousel.prototype.pause = function (e) {\n e || (this.paused = true)\n\n if (this.$element.find('.next, .prev').length && $.support.transition) {\n this.$element.trigger($.support.transition.end)\n this.cycle(true)\n }\n\n this.interval = clearInterval(this.interval)\n\n return this\n }\n\n Carousel.prototype.next = function () {\n if (this.sliding) return\n return this.slide('next')\n }\n\n Carousel.prototype.prev = function () {\n if (this.sliding) return\n return this.slide('prev')\n }\n\n Carousel.prototype.slide = function (type, next) {\n var $active = this.$element.find('.item.active')\n var $next = next || this.getItemForDirection(type, $active)\n var isCycling = this.interval\n var direction = type == 'next' ? 'left' : 'right'\n var that = this\n\n if ($next.hasClass('active')) return (this.sliding = false)\n\n var relatedTarget = $next[0]\n var slideEvent = $.Event('slide.bs.carousel', {\n relatedTarget: relatedTarget,\n direction: direction\n })\n this.$element.trigger(slideEvent)\n if (slideEvent.isDefaultPrevented()) return\n\n this.sliding = true\n\n isCycling && this.pause()\n\n if (this.$indicators.length) {\n this.$indicators.find('.active').removeClass('active')\n var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n $nextIndicator && $nextIndicator.addClass('active')\n }\n\n var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n if ($.support.transition && this.$element.hasClass('slide')) {\n $next.addClass(type)\n $next[0].offsetWidth // force reflow\n $active.addClass(direction)\n $next.addClass(direction)\n $active\n .one('bsTransitionEnd', function () {\n $next.removeClass([type, direction].join(' ')).addClass('active')\n $active.removeClass(['active', direction].join(' '))\n that.sliding = false\n setTimeout(function () {\n that.$element.trigger(slidEvent)\n }, 0)\n })\n .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n } else {\n $active.removeClass('active')\n $next.addClass('active')\n this.sliding = false\n this.$element.trigger(slidEvent)\n }\n\n isCycling && this.cycle()\n\n return this\n }\n\n\n // CAROUSEL PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.carousel')\n var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n var action = typeof option == 'string' ? option : options.slide\n\n if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n if (typeof option == 'number') data.to(option)\n else if (action) data[action]()\n else if (options.interval) data.pause().cycle()\n })\n }\n\n var old = $.fn.carousel\n\n $.fn.carousel = Plugin\n $.fn.carousel.Constructor = Carousel\n\n\n // CAROUSEL NO CONFLICT\n // ====================\n\n $.fn.carousel.noConflict = function () {\n $.fn.carousel = old\n return this\n }\n\n\n // CAROUSEL DATA-API\n // =================\n\n var clickHandler = function (e) {\n var href\n var $this = $(this)\n var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n if (!$target.hasClass('carousel')) return\n var options = $.extend({}, $target.data(), $this.data())\n var slideIndex = $this.attr('data-slide-to')\n if (slideIndex) options.interval = false\n\n Plugin.call($target, options)\n\n if (slideIndex) {\n $target.data('bs.carousel').to(slideIndex)\n }\n\n e.preventDefault()\n }\n\n $(document)\n .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n $(window).on('load', function () {\n $('[data-ride=\"carousel\"]').each(function () {\n var $carousel = $(this)\n Plugin.call($carousel, $carousel.data())\n })\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.7\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n/* jshint latedef: false */\n\n+function ($) {\n 'use strict';\n\n // COLLAPSE PUBLIC CLASS DEFINITION\n // ================================\n\n var Collapse = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Collapse.DEFAULTS, options)\n this.$trigger = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n this.transitioning = null\n\n if (this.options.parent) {\n this.$parent = this.getParent()\n } else {\n this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n }\n\n if (this.options.toggle) this.toggle()\n }\n\n Collapse.VERSION = '3.3.7'\n\n Collapse.TRANSITION_DURATION = 350\n\n Collapse.DEFAULTS = {\n toggle: true\n }\n\n Collapse.prototype.dimension = function () {\n var hasWidth = this.$element.hasClass('width')\n return hasWidth ? 'width' : 'height'\n }\n\n Collapse.prototype.show = function () {\n if (this.transitioning || this.$element.hasClass('in')) return\n\n var activesData\n var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n if (actives && actives.length) {\n activesData = actives.data('bs.collapse')\n if (activesData && activesData.transitioning) return\n }\n\n var startEvent = $.Event('show.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n if (actives && actives.length) {\n Plugin.call(actives, 'hide')\n activesData || actives.data('bs.collapse', null)\n }\n\n var dimension = this.dimension()\n\n this.$element\n .removeClass('collapse')\n .addClass('collapsing')[dimension](0)\n .attr('aria-expanded', true)\n\n this.$trigger\n .removeClass('collapsed')\n .attr('aria-expanded', true)\n\n this.transitioning = 1\n\n var complete = function () {\n this.$element\n .removeClass('collapsing')\n .addClass('collapse in')[dimension]('')\n this.transitioning = 0\n this.$element\n .trigger('shown.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n this.$element\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n }\n\n Collapse.prototype.hide = function () {\n if (this.transitioning || !this.$element.hasClass('in')) return\n\n var startEvent = $.Event('hide.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n var dimension = this.dimension()\n\n this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n this.$element\n .addClass('collapsing')\n .removeClass('collapse in')\n .attr('aria-expanded', false)\n\n this.$trigger\n .addClass('collapsed')\n .attr('aria-expanded', false)\n\n this.transitioning = 1\n\n var complete = function () {\n this.transitioning = 0\n this.$element\n .removeClass('collapsing')\n .addClass('collapse')\n .trigger('hidden.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n this.$element\n [dimension](0)\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n }\n\n Collapse.prototype.toggle = function () {\n this[this.$element.hasClass('in') ? 'hide' : 'show']()\n }\n\n Collapse.prototype.getParent = function () {\n return $(this.options.parent)\n .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n .each($.proxy(function (i, element) {\n var $element = $(element)\n this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n }, this))\n .end()\n }\n\n Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n var isOpen = $element.hasClass('in')\n\n $element.attr('aria-expanded', isOpen)\n $trigger\n .toggleClass('collapsed', !isOpen)\n .attr('aria-expanded', isOpen)\n }\n\n function getTargetFromTrigger($trigger) {\n var href\n var target = $trigger.attr('data-target')\n || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n return $(target)\n }\n\n\n // COLLAPSE PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.collapse')\n var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.collapse\n\n $.fn.collapse = Plugin\n $.fn.collapse.Constructor = Collapse\n\n\n // COLLAPSE NO CONFLICT\n // ====================\n\n $.fn.collapse.noConflict = function () {\n $.fn.collapse = old\n return this\n }\n\n\n // COLLAPSE DATA-API\n // =================\n\n $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n var $this = $(this)\n\n if (!$this.attr('data-target')) e.preventDefault()\n\n var $target = getTargetFromTrigger($this)\n var data = $target.data('bs.collapse')\n var option = data ? 'toggle' : $this.data()\n\n Plugin.call($target, option)\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.7\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // DROPDOWN CLASS DEFINITION\n // =========================\n\n var backdrop = '.dropdown-backdrop'\n var toggle = '[data-toggle=\"dropdown\"]'\n var Dropdown = function (element) {\n $(element).on('click.bs.dropdown', this.toggle)\n }\n\n Dropdown.VERSION = '3.3.7'\n\n function getParent($this) {\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = selector && $(selector)\n\n return $parent && $parent.length ? $parent : $this.parent()\n }\n\n function clearMenus(e) {\n if (e && e.which === 3) return\n $(backdrop).remove()\n $(toggle).each(function () {\n var $this = $(this)\n var $parent = getParent($this)\n var relatedTarget = { relatedTarget: this }\n\n if (!$parent.hasClass('open')) return\n\n if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return\n\n $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this.attr('aria-expanded', 'false')\n $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))\n })\n }\n\n Dropdown.prototype.toggle = function (e) {\n var $this = $(this)\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n clearMenus()\n\n if (!isActive) {\n if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n // if mobile we use a backdrop because click events don't delegate\n $(document.createElement('div'))\n .addClass('dropdown-backdrop')\n .insertAfter($(this))\n .on('click', clearMenus)\n }\n\n var relatedTarget = { relatedTarget: this }\n $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this\n .trigger('focus')\n .attr('aria-expanded', 'true')\n\n $parent\n .toggleClass('open')\n .trigger($.Event('shown.bs.dropdown', relatedTarget))\n }\n\n return false\n }\n\n Dropdown.prototype.keydown = function (e) {\n if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n var $this = $(this)\n\n e.preventDefault()\n e.stopPropagation()\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n if (!isActive && e.which != 27 || isActive && e.which == 27) {\n if (e.which == 27) $parent.find(toggle).trigger('focus')\n return $this.trigger('click')\n }\n\n var desc = ' li:not(.disabled):visible a'\n var $items = $parent.find('.dropdown-menu' + desc)\n\n if (!$items.length) return\n\n var index = $items.index(e.target)\n\n if (e.which == 38 && index > 0) index-- // up\n if (e.which == 40 && index < $items.length - 1) index++ // down\n if (!~index) index = 0\n\n $items.eq(index).trigger('focus')\n }\n\n\n // DROPDOWN PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.dropdown')\n\n if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.dropdown\n\n $.fn.dropdown = Plugin\n $.fn.dropdown.Constructor = Dropdown\n\n\n // DROPDOWN NO CONFLICT\n // ====================\n\n $.fn.dropdown.noConflict = function () {\n $.fn.dropdown = old\n return this\n }\n\n\n // APPLY TO STANDARD DROPDOWN ELEMENTS\n // ===================================\n\n $(document)\n .on('click.bs.dropdown.data-api', clearMenus)\n .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.7\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // MODAL CLASS DEFINITION\n // ======================\n\n var Modal = function (element, options) {\n this.options = options\n this.$body = $(document.body)\n this.$element = $(element)\n this.$dialog = this.$element.find('.modal-dialog')\n this.$backdrop = null\n this.isShown = null\n this.originalBodyPad = null\n this.scrollbarWidth = 0\n this.ignoreBackdropClick = false\n\n if (this.options.remote) {\n this.$element\n .find('.modal-content')\n .load(this.options.remote, $.proxy(function () {\n this.$element.trigger('loaded.bs.modal')\n }, this))\n }\n }\n\n Modal.VERSION = '3.3.7'\n\n Modal.TRANSITION_DURATION = 300\n Modal.BACKDROP_TRANSITION_DURATION = 150\n\n Modal.DEFAULTS = {\n backdrop: true,\n keyboard: true,\n show: true\n }\n\n Modal.prototype.toggle = function (_relatedTarget) {\n return this.isShown ? this.hide() : this.show(_relatedTarget)\n }\n\n Modal.prototype.show = function (_relatedTarget) {\n var that = this\n var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n this.$element.trigger(e)\n\n if (this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = true\n\n this.checkScrollbar()\n this.setScrollbar()\n this.$body.addClass('modal-open')\n\n this.escape()\n this.resize()\n\n this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n })\n })\n\n this.backdrop(function () {\n var transition = $.support.transition && that.$element.hasClass('fade')\n\n if (!that.$element.parent().length) {\n that.$element.appendTo(that.$body) // don't move modals dom position\n }\n\n that.$element\n .show()\n .scrollTop(0)\n\n that.adjustDialog()\n\n if (transition) {\n that.$element[0].offsetWidth // force reflow\n }\n\n that.$element.addClass('in')\n\n that.enforceFocus()\n\n var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n transition ?\n that.$dialog // wait for modal to slide in\n .one('bsTransitionEnd', function () {\n that.$element.trigger('focus').trigger(e)\n })\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n that.$element.trigger('focus').trigger(e)\n })\n }\n\n Modal.prototype.hide = function (e) {\n if (e) e.preventDefault()\n\n e = $.Event('hide.bs.modal')\n\n this.$element.trigger(e)\n\n if (!this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = false\n\n this.escape()\n this.resize()\n\n $(document).off('focusin.bs.modal')\n\n this.$element\n .removeClass('in')\n .off('click.dismiss.bs.modal')\n .off('mouseup.dismiss.bs.modal')\n\n this.$dialog.off('mousedown.dismiss.bs.modal')\n\n $.support.transition && this.$element.hasClass('fade') ?\n this.$element\n .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n this.hideModal()\n }\n\n Modal.prototype.enforceFocus = function () {\n $(document)\n .off('focusin.bs.modal') // guard against infinite focus loop\n .on('focusin.bs.modal', $.proxy(function (e) {\n if (document !== e.target &&\n this.$element[0] !== e.target &&\n !this.$element.has(e.target).length) {\n this.$element.trigger('focus')\n }\n }, this))\n }\n\n Modal.prototype.escape = function () {\n if (this.isShown && this.options.keyboard) {\n this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n e.which == 27 && this.hide()\n }, this))\n } else if (!this.isShown) {\n this.$element.off('keydown.dismiss.bs.modal')\n }\n }\n\n Modal.prototype.resize = function () {\n if (this.isShown) {\n $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n } else {\n $(window).off('resize.bs.modal')\n }\n }\n\n Modal.prototype.hideModal = function () {\n var that = this\n this.$element.hide()\n this.backdrop(function () {\n that.$body.removeClass('modal-open')\n that.resetAdjustments()\n that.resetScrollbar()\n that.$element.trigger('hidden.bs.modal')\n })\n }\n\n Modal.prototype.removeBackdrop = function () {\n this.$backdrop && this.$backdrop.remove()\n this.$backdrop = null\n }\n\n Modal.prototype.backdrop = function (callback) {\n var that = this\n var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n if (this.isShown && this.options.backdrop) {\n var doAnimate = $.support.transition && animate\n\n this.$backdrop = $(document.createElement('div'))\n .addClass('modal-backdrop ' + animate)\n .appendTo(this.$body)\n\n this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n if (this.ignoreBackdropClick) {\n this.ignoreBackdropClick = false\n return\n }\n if (e.target !== e.currentTarget) return\n this.options.backdrop == 'static'\n ? this.$element[0].focus()\n : this.hide()\n }, this))\n\n if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n this.$backdrop.addClass('in')\n\n if (!callback) return\n\n doAnimate ?\n this.$backdrop\n .one('bsTransitionEnd', callback)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callback()\n\n } else if (!this.isShown && this.$backdrop) {\n this.$backdrop.removeClass('in')\n\n var callbackRemove = function () {\n that.removeBackdrop()\n callback && callback()\n }\n $.support.transition && this.$element.hasClass('fade') ?\n this.$backdrop\n .one('bsTransitionEnd', callbackRemove)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callbackRemove()\n\n } else if (callback) {\n callback()\n }\n }\n\n // these following methods are used to handle overflowing modals\n\n Modal.prototype.handleUpdate = function () {\n this.adjustDialog()\n }\n\n Modal.prototype.adjustDialog = function () {\n var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n this.$element.css({\n paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n })\n }\n\n Modal.prototype.resetAdjustments = function () {\n this.$element.css({\n paddingLeft: '',\n paddingRight: ''\n })\n }\n\n Modal.prototype.checkScrollbar = function () {\n var fullWindowWidth = window.innerWidth\n if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n var documentElementRect = document.documentElement.getBoundingClientRect()\n fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n }\n this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n this.scrollbarWidth = this.measureScrollbar()\n }\n\n Modal.prototype.setScrollbar = function () {\n var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n this.originalBodyPad = document.body.style.paddingRight || ''\n if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n }\n\n Modal.prototype.resetScrollbar = function () {\n this.$body.css('padding-right', this.originalBodyPad)\n }\n\n Modal.prototype.measureScrollbar = function () { // thx walsh\n var scrollDiv = document.createElement('div')\n scrollDiv.className = 'modal-scrollbar-measure'\n this.$body.append(scrollDiv)\n var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n this.$body[0].removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n\n // MODAL PLUGIN DEFINITION\n // =======================\n\n function Plugin(option, _relatedTarget) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.modal')\n var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n if (typeof option == 'string') data[option](_relatedTarget)\n else if (options.show) data.show(_relatedTarget)\n })\n }\n\n var old = $.fn.modal\n\n $.fn.modal = Plugin\n $.fn.modal.Constructor = Modal\n\n\n // MODAL NO CONFLICT\n // =================\n\n $.fn.modal.noConflict = function () {\n $.fn.modal = old\n return this\n }\n\n\n // MODAL DATA-API\n // ==============\n\n $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n var $this = $(this)\n var href = $this.attr('href')\n var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n if ($this.is('a')) e.preventDefault()\n\n $target.one('show.bs.modal', function (showEvent) {\n if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n $target.one('hidden.bs.modal', function () {\n $this.is(':visible') && $this.trigger('focus')\n })\n })\n Plugin.call($target, option, this)\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.7\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // TOOLTIP PUBLIC CLASS DEFINITION\n // ===============================\n\n var Tooltip = function (element, options) {\n this.type = null\n this.options = null\n this.enabled = null\n this.timeout = null\n this.hoverState = null\n this.$element = null\n this.inState = null\n\n this.init('tooltip', element, options)\n }\n\n Tooltip.VERSION = '3.3.7'\n\n Tooltip.TRANSITION_DURATION = 150\n\n Tooltip.DEFAULTS = {\n animation: true,\n placement: 'top',\n selector: false,\n template: '
',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n container: false,\n viewport: {\n selector: 'body',\n padding: 0\n }\n }\n\n Tooltip.prototype.init = function (type, element, options) {\n this.enabled = true\n this.type = type\n this.$element = $(element)\n this.options = this.getOptions(options)\n this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n this.inState = { click: false, hover: false, focus: false }\n\n if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n }\n\n var triggers = this.options.trigger.split(' ')\n\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i]\n\n if (trigger == 'click') {\n this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n } else if (trigger != 'manual') {\n var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'\n var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n }\n }\n\n this.options.selector ?\n (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n this.fixTitle()\n }\n\n Tooltip.prototype.getDefaults = function () {\n return Tooltip.DEFAULTS\n }\n\n Tooltip.prototype.getOptions = function (options) {\n options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n if (options.delay && typeof options.delay == 'number') {\n options.delay = {\n show: options.delay,\n hide: options.delay\n }\n }\n\n return options\n }\n\n Tooltip.prototype.getDelegateOptions = function () {\n var options = {}\n var defaults = this.getDefaults()\n\n this._options && $.each(this._options, function (key, value) {\n if (defaults[key] != value) options[key] = value\n })\n\n return options\n }\n\n Tooltip.prototype.enter = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n if (obj instanceof $.Event) {\n self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true\n }\n\n if (self.tip().hasClass('in') || self.hoverState == 'in') {\n self.hoverState = 'in'\n return\n }\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'in'\n\n if (!self.options.delay || !self.options.delay.show) return self.show()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'in') self.show()\n }, self.options.delay.show)\n }\n\n Tooltip.prototype.isInStateTrue = function () {\n for (var key in this.inState) {\n if (this.inState[key]) return true\n }\n\n return false\n }\n\n Tooltip.prototype.leave = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n if (obj instanceof $.Event) {\n self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false\n }\n\n if (self.isInStateTrue()) return\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'out'\n\n if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'out') self.hide()\n }, self.options.delay.hide)\n }\n\n Tooltip.prototype.show = function () {\n var e = $.Event('show.bs.' + this.type)\n\n if (this.hasContent() && this.enabled) {\n this.$element.trigger(e)\n\n var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n if (e.isDefaultPrevented() || !inDom) return\n var that = this\n\n var $tip = this.tip()\n\n var tipId = this.getUID(this.type)\n\n this.setContent()\n $tip.attr('id', tipId)\n this.$element.attr('aria-describedby', tipId)\n\n if (this.options.animation) $tip.addClass('fade')\n\n var placement = typeof this.options.placement == 'function' ?\n this.options.placement.call(this, $tip[0], this.$element[0]) :\n this.options.placement\n\n var autoToken = /\\s?auto?\\s?/i\n var autoPlace = autoToken.test(placement)\n if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n $tip\n .detach()\n .css({ top: 0, left: 0, display: 'block' })\n .addClass(placement)\n .data('bs.' + this.type, this)\n\n this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n this.$element.trigger('inserted.bs.' + this.type)\n\n var pos = this.getPosition()\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (autoPlace) {\n var orgPlacement = placement\n var viewportDim = this.getPosition(this.$viewport)\n\n placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :\n placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :\n placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :\n placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :\n placement\n\n $tip\n .removeClass(orgPlacement)\n .addClass(placement)\n }\n\n var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n this.applyPlacement(calculatedOffset, placement)\n\n var complete = function () {\n var prevHoverState = that.hoverState\n that.$element.trigger('shown.bs.' + that.type)\n that.hoverState = null\n\n if (prevHoverState == 'out') that.leave(that)\n }\n\n $.support.transition && this.$tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n }\n }\n\n Tooltip.prototype.applyPlacement = function (offset, placement) {\n var $tip = this.tip()\n var width = $tip[0].offsetWidth\n var height = $tip[0].offsetHeight\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt($tip.css('margin-top'), 10)\n var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0\n if (isNaN(marginLeft)) marginLeft = 0\n\n offset.top += marginTop\n offset.left += marginLeft\n\n // $.fn.offset doesn't round pixel values\n // so we use setOffset directly with our own function B-0\n $.offset.setOffset($tip[0], $.extend({\n using: function (props) {\n $tip.css({\n top: Math.round(props.top),\n left: Math.round(props.left)\n })\n }\n }, offset), 0)\n\n $tip.addClass('in')\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (placement == 'top' && actualHeight != height) {\n offset.top = offset.top + height - actualHeight\n }\n\n var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n if (delta.left) offset.left += delta.left\n else offset.top += delta.top\n\n var isVertical = /top|bottom/.test(placement)\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n $tip.offset(offset)\n this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n }\n\n Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n this.arrow()\n .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isVertical ? 'top' : 'left', '')\n }\n\n Tooltip.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n\n $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n $tip.removeClass('fade in top bottom left right')\n }\n\n Tooltip.prototype.hide = function (callback) {\n var that = this\n var $tip = $(this.$tip)\n var e = $.Event('hide.bs.' + this.type)\n\n function complete() {\n if (that.hoverState != 'in') $tip.detach()\n if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.\n that.$element\n .removeAttr('aria-describedby')\n .trigger('hidden.bs.' + that.type)\n }\n callback && callback()\n }\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n $tip.removeClass('in')\n\n $.support.transition && $tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n\n this.hoverState = null\n\n return this\n }\n\n Tooltip.prototype.fixTitle = function () {\n var $e = this.$element\n if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {\n $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n }\n }\n\n Tooltip.prototype.hasContent = function () {\n return this.getTitle()\n }\n\n Tooltip.prototype.getPosition = function ($element) {\n $element = $element || this.$element\n\n var el = $element[0]\n var isBody = el.tagName == 'BODY'\n\n var elRect = el.getBoundingClientRect()\n if (elRect.width == null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n }\n var isSvg = window.SVGElement && el instanceof window.SVGElement\n // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.\n // See https://github.com/twbs/bootstrap/issues/20280\n var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())\n var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n return $.extend({}, elRect, scroll, outerDims, elOffset)\n }\n\n Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n }\n\n Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 }\n if (!this.$viewport) return delta\n\n var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n var viewportDimensions = this.getPosition(this.$viewport)\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll\n var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n }\n } else {\n var leftEdgeOffset = pos.left - viewportPadding\n var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n }\n }\n\n return delta\n }\n\n Tooltip.prototype.getTitle = function () {\n var title\n var $e = this.$element\n var o = this.options\n\n title = $e.attr('data-original-title')\n || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)\n\n return title\n }\n\n Tooltip.prototype.getUID = function (prefix) {\n do prefix += ~~(Math.random() * 1000000)\n while (document.getElementById(prefix))\n return prefix\n }\n\n Tooltip.prototype.tip = function () {\n if (!this.$tip) {\n this.$tip = $(this.options.template)\n if (this.$tip.length != 1) {\n throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n }\n }\n return this.$tip\n }\n\n Tooltip.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n }\n\n Tooltip.prototype.enable = function () {\n this.enabled = true\n }\n\n Tooltip.prototype.disable = function () {\n this.enabled = false\n }\n\n Tooltip.prototype.toggleEnabled = function () {\n this.enabled = !this.enabled\n }\n\n Tooltip.prototype.toggle = function (e) {\n var self = this\n if (e) {\n self = $(e.currentTarget).data('bs.' + this.type)\n if (!self) {\n self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n $(e.currentTarget).data('bs.' + this.type, self)\n }\n }\n\n if (e) {\n self.inState.click = !self.inState.click\n if (self.isInStateTrue()) self.enter(self)\n else self.leave(self)\n } else {\n self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n }\n }\n\n Tooltip.prototype.destroy = function () {\n var that = this\n clearTimeout(this.timeout)\n this.hide(function () {\n that.$element.off('.' + that.type).removeData('bs.' + that.type)\n if (that.$tip) {\n that.$tip.detach()\n }\n that.$tip = null\n that.$arrow = null\n that.$viewport = null\n that.$element = null\n })\n }\n\n\n // TOOLTIP PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tooltip')\n var options = typeof option == 'object' && option\n\n if (!data && /destroy|hide/.test(option)) return\n if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tooltip\n\n $.fn.tooltip = Plugin\n $.fn.tooltip.Constructor = Tooltip\n\n\n // TOOLTIP NO CONFLICT\n // ===================\n\n $.fn.tooltip.noConflict = function () {\n $.fn.tooltip = old\n return this\n }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.7\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // POPOVER PUBLIC CLASS DEFINITION\n // ===============================\n\n var Popover = function (element, options) {\n this.init('popover', element, options)\n }\n\n if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n Popover.VERSION = '3.3.7'\n\n Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '

'\n })\n\n\n // NOTE: POPOVER EXTENDS tooltip.js\n // ================================\n\n Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n Popover.prototype.constructor = Popover\n\n Popover.prototype.getDefaults = function () {\n return Popover.DEFAULTS\n }\n\n Popover.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n var content = this.getContent()\n\n $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n ](content)\n\n $tip.removeClass('fade top bottom left right in')\n\n // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n // this manually by checking the contents.\n if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n }\n\n Popover.prototype.hasContent = function () {\n return this.getTitle() || this.getContent()\n }\n\n Popover.prototype.getContent = function () {\n var $e = this.$element\n var o = this.options\n\n return $e.attr('data-content')\n || (typeof o.content == 'function' ?\n o.content.call($e[0]) :\n o.content)\n }\n\n Popover.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n }\n\n\n // POPOVER PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.popover')\n var options = typeof option == 'object' && option\n\n if (!data && /destroy|hide/.test(option)) return\n if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.popover\n\n $.fn.popover = Plugin\n $.fn.popover.Constructor = Popover\n\n\n // POPOVER NO CONFLICT\n // ===================\n\n $.fn.popover.noConflict = function () {\n $.fn.popover = old\n return this\n }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.7\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // SCROLLSPY CLASS DEFINITION\n // ==========================\n\n function ScrollSpy(element, options) {\n this.$body = $(document.body)\n this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n this.options = $.extend({}, ScrollSpy.DEFAULTS, options)\n this.selector = (this.options.target || '') + ' .nav li > a'\n this.offsets = []\n this.targets = []\n this.activeTarget = null\n this.scrollHeight = 0\n\n this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n this.refresh()\n this.process()\n }\n\n ScrollSpy.VERSION = '3.3.7'\n\n ScrollSpy.DEFAULTS = {\n offset: 10\n }\n\n ScrollSpy.prototype.getScrollHeight = function () {\n return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n }\n\n ScrollSpy.prototype.refresh = function () {\n var that = this\n var offsetMethod = 'offset'\n var offsetBase = 0\n\n this.offsets = []\n this.targets = []\n this.scrollHeight = this.getScrollHeight()\n\n if (!$.isWindow(this.$scrollElement[0])) {\n offsetMethod = 'position'\n offsetBase = this.$scrollElement.scrollTop()\n }\n\n this.$body\n .find(this.selector)\n .map(function () {\n var $el = $(this)\n var href = $el.data('target') || $el.attr('href')\n var $href = /^#./.test(href) && $(href)\n\n return ($href\n && $href.length\n && $href.is(':visible')\n && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n })\n .sort(function (a, b) { return a[0] - b[0] })\n .each(function () {\n that.offsets.push(this[0])\n that.targets.push(this[1])\n })\n }\n\n ScrollSpy.prototype.process = function () {\n var scrollTop = this.$scrollElement.scrollTop() + this.options.offset\n var scrollHeight = this.getScrollHeight()\n var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()\n var offsets = this.offsets\n var targets = this.targets\n var activeTarget = this.activeTarget\n var i\n\n if (this.scrollHeight != scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n }\n\n if (activeTarget && scrollTop < offsets[0]) {\n this.activeTarget = null\n return this.clear()\n }\n\n for (i = offsets.length; i--;) {\n activeTarget != targets[i]\n && scrollTop >= offsets[i]\n && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n && this.activate(targets[i])\n }\n }\n\n ScrollSpy.prototype.activate = function (target) {\n this.activeTarget = target\n\n this.clear()\n\n var selector = this.selector +\n '[data-target=\"' + target + '\"],' +\n this.selector + '[href=\"' + target + '\"]'\n\n var active = $(selector)\n .parents('li')\n .addClass('active')\n\n if (active.parent('.dropdown-menu').length) {\n active = active\n .closest('li.dropdown')\n .addClass('active')\n }\n\n active.trigger('activate.bs.scrollspy')\n }\n\n ScrollSpy.prototype.clear = function () {\n $(this.selector)\n .parentsUntil(this.options.target, '.active')\n .removeClass('active')\n }\n\n\n // SCROLLSPY PLUGIN DEFINITION\n // ===========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.scrollspy')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.scrollspy\n\n $.fn.scrollspy = Plugin\n $.fn.scrollspy.Constructor = ScrollSpy\n\n\n // SCROLLSPY NO CONFLICT\n // =====================\n\n $.fn.scrollspy.noConflict = function () {\n $.fn.scrollspy = old\n return this\n }\n\n\n // SCROLLSPY DATA-API\n // ==================\n\n $(window).on('load.bs.scrollspy.data-api', function () {\n $('[data-spy=\"scroll\"]').each(function () {\n var $spy = $(this)\n Plugin.call($spy, $spy.data())\n })\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.7\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // TAB CLASS DEFINITION\n // ====================\n\n var Tab = function (element) {\n // jscs:disable requireDollarBeforejQueryAssignment\n this.element = $(element)\n // jscs:enable requireDollarBeforejQueryAssignment\n }\n\n Tab.VERSION = '3.3.7'\n\n Tab.TRANSITION_DURATION = 150\n\n Tab.prototype.show = function () {\n var $this = this.element\n var $ul = $this.closest('ul:not(.dropdown-menu)')\n var selector = $this.data('target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n if ($this.parent('li').hasClass('active')) return\n\n var $previous = $ul.find('.active:last a')\n var hideEvent = $.Event('hide.bs.tab', {\n relatedTarget: $this[0]\n })\n var showEvent = $.Event('show.bs.tab', {\n relatedTarget: $previous[0]\n })\n\n $previous.trigger(hideEvent)\n $this.trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n var $target = $(selector)\n\n this.activate($this.closest('li'), $ul)\n this.activate($target, $target.parent(), function () {\n $previous.trigger({\n type: 'hidden.bs.tab',\n relatedTarget: $this[0]\n })\n $this.trigger({\n type: 'shown.bs.tab',\n relatedTarget: $previous[0]\n })\n })\n }\n\n Tab.prototype.activate = function (element, container, callback) {\n var $active = container.find('> .active')\n var transition = callback\n && $.support.transition\n && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)\n\n function next() {\n $active\n .removeClass('active')\n .find('> .dropdown-menu > .active')\n .removeClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', false)\n\n element\n .addClass('active')\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n\n if (transition) {\n element[0].offsetWidth // reflow for transition\n element.addClass('in')\n } else {\n element.removeClass('fade')\n }\n\n if (element.parent('.dropdown-menu').length) {\n element\n .closest('li.dropdown')\n .addClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n }\n\n callback && callback()\n }\n\n $active.length && transition ?\n $active\n .one('bsTransitionEnd', next)\n .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n next()\n\n $active.removeClass('in')\n }\n\n\n // TAB PLUGIN DEFINITION\n // =====================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tab')\n\n if (!data) $this.data('bs.tab', (data = new Tab(this)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tab\n\n $.fn.tab = Plugin\n $.fn.tab.Constructor = Tab\n\n\n // TAB NO CONFLICT\n // ===============\n\n $.fn.tab.noConflict = function () {\n $.fn.tab = old\n return this\n }\n\n\n // TAB DATA-API\n // ============\n\n var clickHandler = function (e) {\n e.preventDefault()\n Plugin.call($(this), 'show')\n }\n\n $(document)\n .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.7\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // AFFIX CLASS DEFINITION\n // ======================\n\n var Affix = function (element, options) {\n this.options = $.extend({}, Affix.DEFAULTS, options)\n\n this.$target = $(this.options.target)\n .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))\n\n this.$element = $(element)\n this.affixed = null\n this.unpin = null\n this.pinnedOffset = null\n\n this.checkPosition()\n }\n\n Affix.VERSION = '3.3.7'\n\n Affix.RESET = 'affix affix-top affix-bottom'\n\n Affix.DEFAULTS = {\n offset: 0,\n target: window\n }\n\n Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n var targetHeight = this.$target.height()\n\n if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n if (this.affixed == 'bottom') {\n if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n }\n\n var initializing = this.affixed == null\n var colliderTop = initializing ? scrollTop : position.top\n var colliderHeight = initializing ? targetHeight : height\n\n if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n return false\n }\n\n Affix.prototype.getPinnedOffset = function () {\n if (this.pinnedOffset) return this.pinnedOffset\n this.$element.removeClass(Affix.RESET).addClass('affix')\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n return (this.pinnedOffset = position.top - scrollTop)\n }\n\n Affix.prototype.checkPositionWithEventLoop = function () {\n setTimeout($.proxy(this.checkPosition, this), 1)\n }\n\n Affix.prototype.checkPosition = function () {\n if (!this.$element.is(':visible')) return\n\n var height = this.$element.height()\n var offset = this.options.offset\n var offsetTop = offset.top\n var offsetBottom = offset.bottom\n var scrollHeight = Math.max($(document).height(), $(document.body).height())\n\n if (typeof offset != 'object') offsetBottom = offsetTop = offset\n if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)\n if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n if (this.affixed != affix) {\n if (this.unpin != null) this.$element.css('top', '')\n\n var affixType = 'affix' + (affix ? '-' + affix : '')\n var e = $.Event(affixType + '.bs.affix')\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n this.affixed = affix\n this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n this.$element\n .removeClass(Affix.RESET)\n .addClass(affixType)\n .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n }\n\n if (affix == 'bottom') {\n this.$element.offset({\n top: scrollHeight - height - offsetBottom\n })\n }\n }\n\n\n // AFFIX PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.affix')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.affix\n\n $.fn.affix = Plugin\n $.fn.affix.Constructor = Affix\n\n\n // AFFIX NO CONFLICT\n // =================\n\n $.fn.affix.noConflict = function () {\n $.fn.affix = old\n return this\n }\n\n\n // AFFIX DATA-API\n // ==============\n\n $(window).on('load', function () {\n $('[data-spy=\"affix\"]').each(function () {\n var $spy = $(this)\n var data = $spy.data()\n\n data.offset = data.offset || {}\n\n if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n if (data.offsetTop != null) data.offset.top = data.offsetTop\n\n Plugin.call($spy, data)\n })\n })\n\n}(jQuery);\n"]} \ No newline at end of file diff --git a/lib/d3/d3.js b/lib/d3/d3.js index ed4dac32162..c5fb65f4485 100644 --- a/lib/d3/d3.js +++ b/lib/d3/d3.js @@ -1,2 +1,2 @@ -!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(t.d3=t.d3||{})}(this,function(I){"use strict";function a(t,n){return t>>1;o(t[i],n)<0?e=i+1:r=i}return e},right:function(t,n,e,r){for(null==e&&(e=0),null==r&&(r=t.length);e>>1;0>8&15|n>>4&240,n>>4&15|240&n,(15&n)<<4|15&n,1):(n=an.exec(t))?gn(parseInt(n[1],16)):(n=cn.exec(t))?new xn(n[1],n[2],n[3],1):(n=sn.exec(t))?new xn(255*n[1]/100,255*n[2]/100,255*n[3]/100,1):(n=fn.exec(t))?_n(n[1],n[2],n[3],n[4]):(n=ln.exec(t))?_n(255*n[1]/100,255*n[2]/100,255*n[3]/100,n[4]):(n=hn.exec(t))?bn(n[1],n[2]/100,n[3]/100,1):(n=pn.exec(t))?bn(n[1],n[2]/100,n[3]/100,n[4]):dn.hasOwnProperty(t)?gn(dn[t]):"transparent"===t?new xn(NaN,NaN,NaN,0):null}function gn(t){return new xn(t>>16&255,t>>8&255,255&t,1)}function _n(t,n,e,r){return r<=0&&(t=n=e=NaN),new xn(t,n,e,r)}function yn(t){return t instanceof tn||(t=vn(t)),t?new xn((t=t.rgb()).r,t.g,t.b,t.opacity):new xn}function mn(t,n,e,r){return 1===arguments.length?yn(t):new xn(t,n,e,null==r?1:r)}function xn(t,n,e,r){this.r=+t,this.g=+n,this.b=+e,this.opacity=+r}function bn(t,n,e,r){return r<=0?t=n=e=NaN:e<=0||1<=e?t=n=NaN:n<=0&&(t=NaN),new Mn(t,n,e,r)}function wn(t,n,e,r){return 1===arguments.length?function(t){if(t instanceof Mn)return new Mn(t.h,t.s,t.l,t.opacity);if(t instanceof tn||(t=vn(t)),!t)return new Mn;if(t instanceof Mn)return t;var n=(t=t.rgb()).r/255,e=t.g/255,r=t.b/255,i=Math.min(n,e,r),o=Math.max(n,e,r),u=NaN,a=o-i,c=(o+i)/2;return a?(u=n===o?(e-r)/a+6*(ea&&(i=r.slice(a,i),s[c]?s[c]+=i:s[++c]=i),(n=n[0])===(e=e[0])?s[c]?s[c]+=e:s[++c]=e:(s[++c]=null,f.push({i:c,x:he(n,e)})),a=ve.lastIndex;return ae._time&&(r=e._time),(t=e)._next):(n=e._next,e._next=null,t?t._next=n:je=n);Xe=t,cr(r)}(),Qe=0}}function ar(){var t=Ke.now(),n=t-Ge;Zehr)throw new Error("too late; already scheduled");return e}function br(t,n){var e=wr(t,n);if(e.state>dr)throw new Error("too late; already started");return e}function wr(t,n){var e=t.__transition;if(!e||!(e=e[n]))throw new Error("transition not found");return e}function Mr(t,n){var e,r,i,o=t.__transition,u=!0;if(o){for(i in n=null==n?null:n+"",o)(e=o[i]).name===n?(r=e.state>dr&&e.state<_r,e.state=yr,e.timer.stop(),r&&e.on.call("interrupt",t,t.__data__,e.index,e.group),delete o[i]):u=!1;u&&delete t.__transition}}function Tr(t,n,e){var r=t._id;return t.each(function(){var t=br(this,r);(t.value||(t.value={}))[n]=e.apply(this,arguments)}),function(t){return wr(t,r).value[n]}}function Nr(t,n){var e;return("number"==typeof n?he:n instanceof vn?ue:(e=vn(n))?(n=e,ue):ge)(t,n)}var kr=Rt.prototype.constructor;var Sr=0;function Er(t,n,e,r){this._groups=t,this._parents=n,this._name=e,this._id=r}function Ar(t){return Rt().transition(t)}function Cr(){return++Sr}var zr=Rt.prototype;function Pr(t){return((t*=2)<=1?t*t:--t*(2-t)+1)/2}function Rr(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}Er.prototype=Ar.prototype={constructor:Er,select:function(t){var n=this._name,e=this._id;"function"!=typeof t&&(t=G(t));for(var r=this._groups,i=r.length,o=new Array(i),u=0;uMath.abs(t[1]-S[1])?p=!0:h=!0),S=t,l=!0,pi(),R()}function R(){var t;switch(s=S[0]-k[0],f=S[1]-k[1],g){case vi:case di:_&&(s=Math.max(b-n,Math.min(M-o,s)),e=n+s,u=o+s),y&&(f=Math.max(w-r,Math.min(T-a,f)),i=r+f,c=a+f);break;case gi:_<0?(s=Math.max(b-n,Math.min(M-n,s)),e=n+s,u=o):0<_&&(s=Math.max(b-o,Math.min(M-o,s)),e=n,u=o+s),y<0?(f=Math.max(w-r,Math.min(T-r,f)),i=r+f,c=a):0Bi&&i){var h=e-o,p=r-u,d=a*a+c*c,v=h*h+p*p,g=Math.sqrt(d),_=Math.sqrt(l),y=i*Math.tan((Ii-Math.acos((d+l-v)/(2*g*_)))/2),m=y/_,x=y/g;Math.abs(m-1)>Bi&&(this._+="L"+(t+m*s)+","+(n+m*f)),this._+="A"+i+","+i+",0,0,"+ +(s*pBi||Math.abs(this._y1-s)>Bi)&&(this._+="L"+c+","+s),e&&(l<0&&(l=l%Yi+Yi),Hi=i?a=!0:10===(n=r.charCodeAt(o++))?c=!0:13===n&&(c=!0,10===r.charCodeAt(o)&&++o),r.slice(e+1,t-1).replace(/""/g,'"')}for(;o=(o=(v+_)/2))?v=o:_=o,(f=e>=(u=(g+y)/2))?g=u:y=u,!(p=(i=p)[l=f<<1|s]))return i[l]=d,t;if(a=+t._x.call(null,p.data),c=+t._y.call(null,p.data),n===a&&e===c)return d.next=p,i?i[l]=d:t._root=d,t;for(;i=i?i[l]=new Array(4):t._root=new Array(4),(s=n>=(o=(v+_)/2))?v=o:_=o,(f=e>=(u=(g+y)/2))?g=u:y=u,(l=f<<1|s)==(h=(u<=c)<<1|o<=a););return i[h]=p,i[l]=d,t}function No(t,n,e,r,i){this.node=t,this.x0=n,this.y0=e,this.x1=r,this.y1=i}function ko(t){return t[0]}function So(t){return t[1]}function Eo(t,n,e){var r=new Ao(null==n?ko:n,null==e?So:e,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function Ao(t,n,e,r,i,o){this._x=t,this._y=n,this._x0=e,this._y0=r,this._x1=i,this._y1=o,this._root=void 0}function Co(t){for(var n={data:t.data},e=n;t=t.next;)e=e.next={data:t.data};return n}var zo=Eo.prototype=Ao.prototype;function Po(t){return t.x+t.vx}function Ro(t){return t.y+t.vy}function Lo(t){return t.index}function qo(t,n){var e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function Do(t){return t.x}function Uo(t){return t.y}zo.copy=function(){var t,n,e=new Ao(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return e;if(!r.length)return e._root=Co(r),e;for(t=[{source:r,target:e._root=new Array(4)}];r=t.pop();)for(var i=0;i<4;++i)(n=r.source[i])&&(n.length?t.push({source:n,target:r.target[i]=new Array(4)}):r.target[i]=Co(n));return e},zo.add=function(t){var n=+this._x.call(null,t),e=+this._y.call(null,t);return To(this.cover(n,e),n,e,t)},zo.addAll=function(t){var n,e,r,i,o=t.length,u=new Array(o),a=new Array(o),c=1/0,s=1/0,f=-1/0,l=-1/0;for(e=0;eh||(o=c.y0)>p||(u=c.x1)=(a=(d+g)/2))?d=a:g=a,(f=u>=(c=(v+_)/2))?v=c:_=c,!(p=(n=p)[l=f<<1|s]))return this;if(!p.length)break;(n[l+1&3]||n[l+2&3]||n[l+3&3])&&(e=n,h=l)}for(;p.data!==t;)if(!(p=(r=p).next))return this;return(i=p.next)&&delete p.next,r?i?r.next=i:delete r.next:n?(i?n[l]=i:delete n[l],(p=n[0]||n[1]||n[2]||n[3])&&p===(n[3]||n[2]||n[1]||n[0])&&!p.length&&(e?e[h]=p:this._root=p)):this._root=i,this},zo.removeAll=function(t){for(var n=0,e=t.length;ni+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}var Ho={"":function(t,n){t:for(var e,r=(t=t.toPrecision(n)).length,i=1,o=-1;i=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;function Xo(t){return new Vo(t)}function Vo(t){if(!(n=jo.exec(t)))throw new Error("invalid format: "+t);var n,e=n[1]||" ",r=n[2]||">",i=n[3]||"-",o=n[4]||"",u=!!n[5],a=n[6]&&+n[6],c=!!n[7],s=n[8]&&+n[8].slice(1),f=n[9]||"";"n"===f?(c=!0,f="g"):Ho[f]||(f=""),(u||"0"===e&&"="===r)&&(u=!0,e="0",r="="),this.fill=e,this.align=r,this.sign=i,this.symbol=o,this.zero=u,this.width=a,this.comma=c,this.precision=s,this.type=f}function Wo(t){return t}Xo.prototype=Vo.prototype,Vo.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(null==this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(null==this.precision?"":"."+Math.max(0,0|this.precision))+this.type};var $o,Zo=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function Go(t){var n,a,c,b=t.grouping&&t.thousands?(a=t.grouping,c=t.thousands,function(t,n){for(var e=t.length,r=[],i=0,o=a[0],u=0;0n));)o=a[i=(i+1)%a.length];return r.reverse().join(c)}):Wo,r=t.currency,w=t.decimal,M=t.numerals?(n=t.numerals,function(t){return t.replace(/[0-9]/g,function(t){return n[+t]})}):Wo,i=t.percent||"%";function u(t){var s=(t=Xo(t)).fill,f=t.align,l=t.sign,n=t.symbol,h=t.zero,p=t.width,d=t.comma,v=t.precision,g=t.type,_="$"===n?r[0]:"#"===n&&/[boxX]/.test(g)?"0"+g.toLowerCase():"",y="$"===n?r[1]:/[%p]/.test(g)?i:"",m=Ho[g],x=!g||/[defgprs%]/.test(g);function e(t){var n,e,r,i=_,o=y;if("c"===g)o=m(t)+o,t="";else{var u=(t=+t)<0;if(t=m(Math.abs(t),v),u&&0==+t&&(u=!1),i=(u?"("===l?l:"-":"-"===l||"("===l?"":l)+i,o=("s"===g?Zo[8+Oo/3]:"")+o+(u&&"("===l?")":""),x)for(n=-1,e=t.length;++n>1)+i+t+o+c.slice(a);break;default:t=c+i+t+o}return M(t)}return v=null==v?g?6:12:/[gprs]/.test(g)?Math.max(1,Math.min(21,v)):Math.max(0,Math.min(20,v)),e.toString=function(){return t+""},e}return{format:u,formatPrefix:function(t,n){var e=u(((t=Xo(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(Yo(n)/3))),i=Math.pow(10,-r),o=Zo[8+r/3];return function(t){return e(i*t)+o}}}}function Qo(t){return $o=Go(t),I.format=$o.format,I.formatPrefix=$o.formatPrefix,$o}function Jo(t){return Math.max(0,-Yo(Math.abs(t)))}function Ko(t,n){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(Yo(n)/3)))-Yo(Math.abs(t)))}function tu(t,n){return t=Math.abs(t),n=Math.abs(n)-t,Math.max(0,Yo(n)-Yo(t))+1}function nu(){return new eu}function eu(){this.reset()}Qo({decimal:".",thousands:",",grouping:[3],currency:["$",""]}),eu.prototype={constructor:eu,reset:function(){this.s=this.t=0},add:function(t){iu(ru,t,this.t),iu(this,ru.s,this.s),this.s?this.t+=ru.t:this.s=ru.t},valueOf:function(){return this.s}};var ru=new eu;function iu(t,n,e){var r=t.s=n+e,i=r-n,o=r-i;t.t=n-o+(e-i)}var ou=1e-6,uu=Math.PI,au=uu/2,cu=uu/4,su=2*uu,fu=180/uu,lu=uu/180,hu=Math.abs,pu=Math.atan,du=Math.atan2,vu=Math.cos,gu=Math.ceil,_u=Math.exp,yu=Math.log,mu=Math.pow,xu=Math.sin,bu=Math.sign||function(t){return 0La(Fu,Yu)&&(Yu=t):La(t,Yu)>La(Fu,Yu)&&(Fu=t):Fu<=Yu?(tLa(Fu,Yu)&&(Yu=t):La(t,Yu)>La(Fu,Yu)&&(Fu=t)}else aa.push(ca=[Fu=t,Yu=t]);nou&&(Fu=-(Yu=180)),ca[0]=Fu,ca[1]=Yu,Vu=null}function La(t,n){return(n-=t)<0?n+360:n}function qa(t,n){return t[0]-n[0]}function Da(t,n){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nou?pu((xu(r)*(a=vu(o))*xu(i)-xu(o)*(u=vu(r))*xu(e))/(u*a*c)):(r+o)/2,l.point(v,d),l.lineEnd(),l.lineStart(),l.point(s,d),h=0),l.point(p=t,d=n),v=s},lineEnd:function(){l.lineEnd(),p=d=NaN},clean:function(){return 2-h}}},function(t,n,e,r){var i;if(null==t)i=e*au,r.point(-uu,i),r.point(0,i),r.point(uu,i),r.point(uu,0),r.point(uu,-i),r.point(0,-i),r.point(-uu,-i),r.point(-uu,0),r.point(-uu,i);else if(hu(t[0]-n[0])>ou){var o=t[0]ou;function v(t,n){return vu(t)*vu(n)>k}function g(t,n,e){var r=[1,0,0],i=ra(na(t),na(n)),o=ea(i,i),u=i[0],a=o-u*u;if(!a)return!e&&t;var c=k*o/a,s=-k*u/a,f=ra(r,i),l=oa(r,c);ia(l,oa(i,s));var h=f,p=ea(l,h),d=ea(h,h),v=p*p-d*(ea(l,l)-1);if(!(v<0)){var g=wu(v),_=oa(h,(-p-g)/d);if(ia(_,l),_=ta(_),!e)return _;var y,m=t[0],x=n[0],b=t[1],w=n[1];xou}).map(s)).concat(N(gu(u/d)*d,o,d).filter(function(t){return hu(t%g)>ou}).map(f))}return y.lines=function(){return t().map(function(t){return{type:"LineString",coordinates:t}})},y.outline=function(){return{type:"Polygon",coordinates:[l(i).concat(h(a).slice(1),l(r).reverse().slice(1),h(c).reverse().slice(1))]}},y.extent=function(t){return arguments.length?y.extentMajor(t).extentMinor(t):y.extentMinor()},y.extentMajor=function(t){return arguments.length?(i=+t[0][0],r=+t[1][0],c=+t[0][1],a=+t[1][1],rou&&0<--i);return[t/(.8707+(o=r*r)*(o*(o*o*o*(.003971-.001529*o)-.013791)-.131979)),r]},_f.invert=of(Nu),yf.invert=of(function(t){return 2*pu(t)}),mf.invert=function(t,n){return[-n,2*pu(_u(t))-au]},Ef.prototype=Tf.prototype={constructor:Ef,count:function(){return this.eachAfter(Mf)},each:function(t){var n,e,r,i,o=this,u=[o];do{for(n=u.reverse(),u=[];o=n.pop();)if(t(o),e=o.children)for(r=0,i=e.length;rsv){var a=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*a-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,i=(i*a-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>sv){var s=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*s+t._x1*t._l23_2a-n*t._l12_2a)/f,u=(u*s+t._y1*t._l23_2a-e*t._l12_2a)/f}t._context.bezierCurveTo(r,i,o,u,t._x2,t._y2)}function bg(t,n){this._context=t,this._alpha=n}bg.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3;default:xg(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var wg=function n(e){function t(t){return e?new bg(t,e):new dg(t,0)}return t.alpha=function(t){return n(+t)},t}(.5);function Mg(t,n){this._context=t,this._alpha=n}Mg.prototype={areaStart:ug,areaEnd:ug,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:xg(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var Tg=function n(e){function t(t){return e?new Mg(t,e):new gg(t,0)}return t.alpha=function(t){return n(+t)},t}(.5);function Ng(t,n){this._context=t,this._alpha=n}Ng.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:xg(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var kg=function n(e){function t(t){return e?new Ng(t,e):new yg(t,0)}return t.alpha=function(t){return n(+t)},t}(.5);function Sg(t){this._context=t}function Eg(t){return t<0?-1:1}function Ag(t,n,e){var r=t._x1-t._x0,i=n-t._x1,o=(t._y1-t._y0)/(r||i<0&&-0),u=(e-t._y1)/(i||r<0&&-0),a=(o*i+u*r)/(r+i);return(Eg(o)+Eg(u))*Math.min(Math.abs(o),Math.abs(u),.5*Math.abs(a))||0}function Cg(t,n){var e=t._x1-t._x0;return e?(3*(t._y1-t._y0)/e-n)/2:n}function zg(t,n,e){var r=t._x0,i=t._y0,o=t._x1,u=t._y1,a=(o-r)/3;t._context.bezierCurveTo(r+a,i+a*n,o-a,u-a*e,o,u)}function Pg(t){this._context=t}function Rg(t){this._context=new Lg(t)}function Lg(t){this._context=t}function qg(t){this._context=t}function Dg(t){var n,e,r=t.length-1,i=new Array(r),o=new Array(r),u=new Array(r);for(o[i[0]=0]=2,u[0]=t[0]+2*t[1],n=1;n=i)return}else c=[v,e];o=[v,i]}else{if(c){if(c[1]=i)return}else c=[(e-a)/u,e];o=[(i-a)/u,i]}else{if(c){if(c[1]=r)return}else c=[n,u*n+a];o=[r,u*r+a]}else{if(c){if(c[0]x_||Math.abs(i[0][1]-i[1][1])>x_)||delete m_[o]}(u,a,c,s),function(t,n,e,r){var i,o,u,a,c,s,f,l,h,p,d,v,g,_,y=__.length,m=!0;for(i=0;ix_||Math.abs(v-h)>x_)&&(c.splice(a,0,m_.push(Jg(u,p,Math.abs(d-t)=e)return null;for(var r=u-c.site[0],i=a-c.site[1],l=r*r+i*i;c=s.cells[n=f],f=null,c.halfedges.forEach(function(t){var n=s.edges[t],e=n.left;if(e!==c.site&&e||(e=n.right)){var r=u-e[0],i=a-e[1],o=r*r+i*i;oa;)c.pop(),--s;var f,l=new Array(s+1);for(n=0;n<=s;++n)(f=l[n]=[]).x0=0=d.length)return null!=h&&t.sort(h),null!=p?p(t):t;for(var n,o,u,a=-1,c=t.length,s=d[e++],f=Ki(),l=r();++ad.length)return t;var i,o=u[r-1];return null!=p&&r>=d.length?i=t.entries():(i=[],t.each(function(t,n){i.push({key:n,values:e(t,r)})})),null!=o?i.sort(function(t,n){return o(t.key,n.key)}):i}(v(t,0,eo,ro),0)},key:function(t){return d.push(t),n},sortKeys:function(t){return u[d.length-1]=t,n},sortValues:function(t){return h=t,n},rollup:function(t){return p=t,n}}},I.set=uo,I.map=Ki,I.keys=function(t){var n=[];for(var e in t)n.push(e);return n},I.values=function(t){var n=[];for(var e in t)n.push(t[e]);return n},I.entries=function(t){var n=[];for(var e in t)n.push({key:e,value:t[e]});return n},I.color=vn,I.rgb=mn,I.hsl=wn,I.lab=qn,I.hcl=Yn,I.cubehelix=Gn,I.dispatch=Y,I.drag=function(){var e,r,i,o,u=$t,a=Zt,n=Gt,c=Qt,d={},v=Y("start","drag","end"),g=0,s=0;function _(t){t.on("mousedown.drag",f).filter(c).on("touchstart.drag",p).on("touchmove.drag",y).on("touchend.drag touchcancel.drag",m).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function f(){if(!o&&u.apply(this,arguments)){var t=x("mouse",a.apply(this,arguments),It,this,arguments);t&&(Lt(I.event.view).on("mousemove.drag",l,!0).on("mouseup.drag",h,!0),jt(I.event.view),Bt(),i=!1,e=I.event.clientX,r=I.event.clientY,t("start"))}}function l(){if(Ht(),!i){var t=I.event.clientX-e,n=I.event.clientY-r;i=sl.index){var c=h-o.x-o.vx,s=p-o.y-o.vy,f=c*c+s*s;ft.r&&(t.r=t[n].r)}function e(){if(o){var t,n,e=o.length;for(u=new Array(e),t=0;tLa(r[0],r[1])&&(r[1]=i[1]),La(i[0],r[1])>La(r[0],r[1])&&(r[0]=i[0])):o.push(r=i);for(u=-1/0,n=0,r=o[e=o.length-1];n<=e;r=i,++n)i=o[n],(a=La(r[1],i[0]))>u&&(u=a,Fu=i[0],Yu=r[1])}return aa=ca=null,Fu===1/0||Iu===1/0?[[NaN,NaN],[NaN,NaN]]:[[Fu,Iu],[Yu,Bu]]},I.geoCentroid=function(t){sa=fa=la=ha=pa=da=va=ga=_a=ya=ma=0,Ru(t,Ua);var n=_a,e=ya,r=ma,i=n*n+e*e+r*r;return i<1e-12&&(n=da,e=va,r=ga,far.x&&(r=t),t.depth>i.depth&&(i=t)});var o=e===r?1:m(e,r)/2,u=o-e.x,a=s/(r.x+o+u),c=f/(i.depth||1);t.eachBefore(function(t){t.x=(t.x+u)*a,t.y=t.depth*c})}return t}function h(t){var n=t.children,e=t.parent.children,r=t.i?e[t.i-1]:null;if(n){!function(t){for(var n,e=0,r=0,i=t.children,o=i.length;0<=--o;)(n=i[o]).z+=e,n.m+=e,e+=n.s+(r+=n.c)}(t);var i=(n[0].z+n[n.length-1].z)/2;r?(t.z=r.z+m(t._,r._),t.m=t.z-i):t.z=i}else r&&(t.z=r.z+m(t._,r._));t.parent.A=function(t,n,e){if(n){for(var r,i=t,o=t,u=n,a=i.parent.children[0],c=i.m,s=o.m,f=u.m,l=a.m;u=il(u),i=rl(i),u&&i;)a=rl(a),(o=il(o)).a=t,0<(r=u.z+f-i.z-c+m(u._,i._))&&(_=t,y=e,h=(g=u).a.parent===_.parent?g.a:y,v=(d=r)/((p=t).i-h.i),p.c-=v,p.s+=d,h.c+=v,p.z+=d,p.m+=d,c+=r,s+=r),f+=u.m,c+=i.m,l+=a.m,s+=o.m;u&&!il(o)&&(o.t=u,o.m+=f-s),i&&!rl(a)&&(a.t=i,a.m+=c-l,e=t)}var h,p,d,v,g,_,y;return e}(t,r,t.parent.A||e[0])}function p(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function d(t){t.x*=s,t.y=t.depth*f}return n.separation=function(t){return arguments.length?(m=t,n):m},n.size=function(t){return arguments.length?(l=!1,s=+t[0],f=+t[1],n):l?null:[s,f]},n.nodeSize=function(t){return arguments.length?(l=!0,s=+t[0],f=+t[1],n):l?[s,f]:null},n},I.treemap=function(){var u=sl,n=!1,e=1,r=1,a=[0],c=jf,s=jf,f=jf,l=jf,h=jf;function i(t){return t.x0=t.y0=0,t.x1=e,t.y1=r,t.eachBefore(o),a=[0],n&&t.eachBefore(Gf),t}function o(t){var n=a[t.depth],e=t.x0+n,r=t.y0+n,i=t.x1-n,o=t.y1-n;i>>1;m[p]sv?(w+=z*=_?1:-1,M-=z):(T=0,w=M=(d+v)/2),(N-=2*P)>sv?(x+=P*=_?1:-1,b-=P):(N=0,x=b=(d+v)/2)}var R=p*iv(x),L=p*av(x),q=h*iv(M),D=h*av(M);if(svpr&&e.name===n)return new Er([[t]],si,n,+r);return null},I.interrupt=Mr,I.voronoi=function(){var i=jg,o=Xg,n=null;function e(r){return new M_(r.map(function(t,n){var e=[Math.round(i(t,n,r)/x_)*x_,Math.round(o(t,n,r)/x_)*x_];return e.index=n,e.data=t,e}),n)}return e.polygons=function(t){return e(t).polygons()},e.links=function(t){return e(t).links()},e.triangles=function(t){return e(t).triangles()},e.x=function(t){return arguments.length?(i="function"==typeof t?t:Hg(+t),e):i},e.y=function(t){return arguments.length?(o="function"==typeof t?t:Hg(+t),e):o},e.extent=function(t){return arguments.length?(n=null==t?null:[[+t[0][0],+t[0][1]],[+t[1][0],+t[1][1]]],e):n&&[[n[0][0],n[0][1]],[n[1][0],n[1][1]]]},e.size=function(t){return arguments.length?(n=null==t?null:[[0,0],[+t[0],+t[1]]],e):n&&[n[1][0]-n[0][0],n[1][1]-n[0][1]]},e},I.zoom=function(){var p,o,a=z_,f=P_,d=D_,i=L_,n=q_,u=[0,1/0],v=[[-1/0,-1/0],[1/0,1/0]],c=250,l=Le,s=[],e=Y("start","zoom","end"),h=500,g=150,_=0;function y(t){t.property("__zoom",R_).on("wheel.zoom",r).on("mousedown.zoom",N).on("dblclick.zoom",k).filter(n).on("touchstart.zoom",S).on("touchmove.zoom",E).on("touchend.zoom touchcancel.zoom",A).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function m(t,n){return(n=Math.max(u[0],Math.min(u[1],n)))===t.k?t:new k_(n,t.x,t.y)}function x(t,n,e){var r=n[0]-e[0]*t.k,i=n[1]-e[1]*t.k;return r===t.x&&i===t.y?t:new k_(t.k,r,i)}function b(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function w(t,c,s){t.on("start.zoom",function(){M(this,arguments).start()}).on("interrupt.zoom end.zoom",function(){M(this,arguments).end()}).tween("zoom",function(){var t=arguments,r=M(this,t),n=f.apply(this,t),i=s||b(n),o=Math.max(n[1][0]-n[0][0],n[1][1]-n[0][1]),e=this.__zoom,u="function"==typeof c?c.apply(this,t):c,a=l(e.invert(i).concat(o/e.k),u.invert(i).concat(o/u.k));return function(t){if(1===t)t=u;else{var n=a(t),e=o/n[2];t=new k_(e,i[0]-n[0]*e,i[1]-n[1]*e)}r.zoom(null,t)}})}function M(t,n){for(var e,r=0,i=s.length;r>>1;o(t[i],n)<0?e=1+i:r=i}return e},right:function(t,n,e,r){for(null==e&&(e=0),null==r&&(r=t.length);e>>1;0>8&15|n>>4&240,n>>4&15|240&n,(15&n)<<4|15&n,1):(n=an.exec(t))?gn(parseInt(n[1],16)):(n=cn.exec(t))?new xn(n[1],n[2],n[3],1):(n=sn.exec(t))?new xn(255*n[1]/100,255*n[2]/100,255*n[3]/100,1):(n=fn.exec(t))?_n(n[1],n[2],n[3],n[4]):(n=ln.exec(t))?_n(255*n[1]/100,255*n[2]/100,255*n[3]/100,n[4]):(n=hn.exec(t))?bn(n[1],n[2]/100,n[3]/100,1):(n=pn.exec(t))?bn(n[1],n[2]/100,n[3]/100,n[4]):dn.hasOwnProperty(t)?gn(dn[t]):"transparent"===t?new xn(NaN,NaN,NaN,0):null}function gn(t){return new xn(t>>16&255,t>>8&255,255&t,1)}function _n(t,n,e,r){return r<=0&&(t=n=e=NaN),new xn(t,n,e,r)}function yn(t){return t instanceof tn||(t=vn(t)),t?new xn((t=t.rgb()).r,t.g,t.b,t.opacity):new xn}function mn(t,n,e,r){return 1===arguments.length?yn(t):new xn(t,n,e,null==r?1:r)}function xn(t,n,e,r){this.r=+t,this.g=+n,this.b=+e,this.opacity=+r}function bn(t,n,e,r){return r<=0?t=n=e=NaN:e<=0||1<=e?t=n=NaN:n<=0&&(t=NaN),new Mn(t,n,e,r)}function wn(t,n,e,r){return 1===arguments.length?function(t){if(t instanceof Mn)return new Mn(t.h,t.s,t.l,t.opacity);if(t instanceof tn||(t=vn(t)),!t)return new Mn;if(t instanceof Mn)return t;var n=(t=t.rgb()).r/255,e=t.g/255,r=t.b/255,i=Math.min(n,e,r),o=Math.max(n,e,r),u=NaN,a=o-i,c=(o+i)/2;return a?(u=n===o?(e-r)/a+6*(eo&&(i=r.slice(o,i),a[u]?a[u]+=i:a[++u]=i),(n=n[0])===(e=e[0])?a[u]?a[u]+=e:a[++u]=e:(a[++u]=null,c.push({i:u,x:he(n,e)})),o=ve.lastIndex;return oe._time&&(r=e._time),(t=e)._next):(n=e._next,e._next=null,t?t._next=n:je=n);Xe=t,cr(r)}(),Qe=0}}function ar(){var t=Ke.now(),n=t-Ge;Zehr)throw new Error("too late; already scheduled");return e}function br(t,n){var e=wr(t,n);if(e.state>dr)throw new Error("too late; already started");return e}function wr(t,n){var e=t.__transition;if(!e||!(e=e[n]))throw new Error("transition not found");return e}function Mr(t,n){var e,r,i,o=t.__transition,u=!0;if(o){for(i in n=null==n?null:n+"",o)(e=o[i]).name===n?(r=e.state>dr&&e.state<_r,e.state=yr,e.timer.stop(),r&&e.on.call("interrupt",t,t.__data__,e.index,e.group),delete o[i]):u=!1;u&&delete t.__transition}}function Tr(t,n,e){var r=t._id;return t.each(function(){var t=br(this,r);(t.value||(t.value={}))[n]=e.apply(this,arguments)}),function(t){return wr(t,r).value[n]}}function Nr(t,n){var e;return("number"==typeof n?he:n instanceof vn?ue:(e=vn(n))?(n=e,ue):ge)(t,n)}var kr=Rt.prototype.constructor;var Sr=0;function Er(t,n,e,r){this._groups=t,this._parents=n,this._name=e,this._id=r}function Ar(t){return Rt().transition(t)}function Cr(){return++Sr}var zr=Rt.prototype;function Pr(t){return((t*=2)<=1?t*t:--t*(2-t)+1)/2}function Rr(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}Er.prototype=Ar.prototype={constructor:Er,select:function(t){var n=this._name,e=this._id;"function"!=typeof t&&(t=G(t));for(var r=this._groups,i=r.length,o=new Array(i),u=0;uMath.abs(t[1]-S[1])?p=!0:h=!0),S=t,l=!0,pi(),R()}function R(){var t;switch(s=S[0]-k[0],f=S[1]-k[1],g){case vi:case di:_&&(s=Math.max(b-n,Math.min(M-o,s)),e=n+s,u=o+s),y&&(f=Math.max(w-r,Math.min(T-a,f)),i=r+f,c=a+f);break;case gi:_<0?(s=Math.max(b-n,Math.min(M-n,s)),e=n+s,u=o):0<_&&(s=Math.max(b-o,Math.min(M-o,s)),e=n,u=o+s),y<0?(f=Math.max(w-r,Math.min(T-r,f)),i=r+f,c=a):0Bi&&i){var h=e-o,p=r-u,d=a*a+c*c,v=h*h+p*p,g=Math.sqrt(d),_=Math.sqrt(l),y=i*Math.tan((Ii-Math.acos((d+l-v)/(2*g*_)))/2),m=y/_,x=y/g;Math.abs(m-1)>Bi&&(this._+="L"+(t+m*s)+","+(n+m*f)),this._+="A"+i+","+i+",0,0,"+ +(s*pBi||Math.abs(this._y1-s)>Bi)&&(this._+="L"+c+","+s),e&&(l<0&&(l=l%Yi+Yi),Hi=i?a=!0:10===(n=r.charCodeAt(o++))?c=!0:13===n&&(c=!0,10===r.charCodeAt(o)&&++o),r.slice(e+1,t-1).replace(/""/g,'"')}for(;o=(o=(v+_)/2))?v=o:_=o,(f=e>=(u=(g+y)/2))?g=u:y=u,!(p=(i=p)[l=f<<1|s]))return i[l]=d,t;if(a=+t._x.call(null,p.data),c=+t._y.call(null,p.data),n===a&&e===c)return d.next=p,i?i[l]=d:t._root=d,t;for(;i=i?i[l]=new Array(4):t._root=new Array(4),(s=n>=(o=(v+_)/2))?v=o:_=o,(f=e>=(u=(g+y)/2))?g=u:y=u,(l=f<<1|s)==(h=(u<=c)<<1|o<=a););return i[h]=p,i[l]=d,t}function No(t,n,e,r,i){this.node=t,this.x0=n,this.y0=e,this.x1=r,this.y1=i}function ko(t){return t[0]}function So(t){return t[1]}function Eo(t,n,e){var r=new Ao(null==n?ko:n,null==e?So:e,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function Ao(t,n,e,r,i,o){this._x=t,this._y=n,this._x0=e,this._y0=r,this._x1=i,this._y1=o,this._root=void 0}function Co(t){for(var n={data:t.data},e=n;t=t.next;)e=e.next={data:t.data};return n}var zo=Eo.prototype=Ao.prototype;function Po(t){return t.x+t.vx}function Ro(t){return t.y+t.vy}function Lo(t){return t.index}function qo(t,n){var e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function Do(t){return t.x}function Uo(t){return t.y}zo.copy=function(){var t,n,e=new Ao(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return e;if(!r.length)return e._root=Co(r),e;for(t=[{source:r,target:e._root=new Array(4)}];r=t.pop();)for(var i=0;i<4;++i)(n=r.source[i])&&(n.length?t.push({source:n,target:r.target[i]=new Array(4)}):r.target[i]=Co(n));return e},zo.add=function(t){var n=+this._x.call(null,t),e=+this._y.call(null,t);return To(this.cover(n,e),n,e,t)},zo.addAll=function(t){var n,e,r,i,o=t.length,u=new Array(o),a=new Array(o),c=1/0,s=1/0,f=-1/0,l=-1/0;for(e=0;eh||(o=c.y0)>p||(u=c.x1)=(a=(d+g)/2))?d=a:g=a,(f=u>=(c=(v+_)/2))?v=c:_=c,!(p=(n=p)[l=f<<1|s]))return this;if(!p.length)break;(n[l+1&3]||n[l+2&3]||n[l+3&3])&&(e=n,h=l)}for(;p.data!==t;)if(!(p=(r=p).next))return this;return(i=p.next)&&delete p.next,r?i?r.next=i:delete r.next:n?(i?n[l]=i:delete n[l],(p=n[0]||n[1]||n[2]||n[3])&&p===(n[3]||n[2]||n[1]||n[0])&&!p.length&&(e?e[h]=p:this._root=p)):this._root=i,this},zo.removeAll=function(t){for(var n=0,e=t.length;ni+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}var Ho={"":function(t,n){t:for(var e,r=(t=t.toPrecision(n)).length,i=1,o=-1;i=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;function Xo(t){return new Vo(t)}function Vo(t){if(!(n=jo.exec(t)))throw new Error("invalid format: "+t);var n,e=n[1]||" ",r=n[2]||">",i=n[3]||"-",o=n[4]||"",u=!!n[5],a=n[6]&&+n[6],c=!!n[7],s=n[8]&&+n[8].slice(1),f=n[9]||"";"n"===f?(c=!0,f="g"):Ho[f]||(f=""),(u||"0"===e&&"="===r)&&(u=!0,e="0",r="="),this.fill=e,this.align=r,this.sign=i,this.symbol=o,this.zero=u,this.width=a,this.comma=c,this.precision=s,this.type=f}function Wo(t){return t}Xo.prototype=Vo.prototype,Vo.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(null==this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(null==this.precision?"":"."+Math.max(0,0|this.precision))+this.type};var $o,Zo=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function Go(t){var b=t.grouping&&t.thousands?function(a,c){return function(t,n){for(var e=t.length,r=[],i=0,o=a[0],u=0;0n));)o=a[i=(i+1)%a.length];return r.reverse().join(c)}}(t.grouping,t.thousands):Wo,r=t.currency,w=t.decimal,M=t.numerals?function(n){return function(t){return t.replace(/[0-9]/g,function(t){return n[+t]})}}(t.numerals):Wo,i=t.percent||"%";function u(t){var s=(t=Xo(t)).fill,f=t.align,l=t.sign,n=t.symbol,h=t.zero,p=t.width,d=t.comma,v=t.precision,g=t.type,_="$"===n?r[0]:"#"===n&&/[boxX]/.test(g)?"0"+g.toLowerCase():"",y="$"===n?r[1]:/[%p]/.test(g)?i:"",m=Ho[g],x=!g||/[defgprs%]/.test(g);function e(t){var n,e,r,i=_,o=y;if("c"===g)o=m(t)+o,t="";else{var u=(t=+t)<0;if(t=m(Math.abs(t),v),u&&0==+t&&(u=!1),i=(u?"("===l?l:"-":"-"===l||"("===l?"":l)+i,o=("s"===g?Zo[8+Oo/3]:"")+o+(u&&"("===l?")":""),x)for(n=-1,e=t.length;++n>1)+i+t+o+c.slice(a);break;default:t=c+i+t+o}return M(t)}return v=null==v?g?6:12:/[gprs]/.test(g)?Math.max(1,Math.min(21,v)):Math.max(0,Math.min(20,v)),e.toString=function(){return t+""},e}return{format:u,formatPrefix:function(t,n){var e=u(((t=Xo(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(Yo(n)/3))),i=Math.pow(10,-r),o=Zo[8+r/3];return function(t){return e(i*t)+o}}}}function Qo(t){return $o=Go(t),I.format=$o.format,I.formatPrefix=$o.formatPrefix,$o}function Jo(t){return Math.max(0,-Yo(Math.abs(t)))}function Ko(t,n){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(Yo(n)/3)))-Yo(Math.abs(t)))}function tu(t,n){return t=Math.abs(t),n=Math.abs(n)-t,Math.max(0,Yo(n)-Yo(t))+1}function nu(){return new eu}function eu(){this.reset()}Qo({decimal:".",thousands:",",grouping:[3],currency:["$",""]}),eu.prototype={constructor:eu,reset:function(){this.s=this.t=0},add:function(t){iu(ru,t,this.t),iu(this,ru.s,this.s),this.s?this.t+=ru.t:this.s=ru.t},valueOf:function(){return this.s}};var ru=new eu;function iu(t,n,e){var r=t.s=n+e,i=r-n,o=r-i;t.t=n-o+(e-i)}var ou=1e-6,uu=Math.PI,au=uu/2,cu=uu/4,su=2*uu,fu=180/uu,lu=uu/180,hu=Math.abs,pu=Math.atan,du=Math.atan2,vu=Math.cos,gu=Math.ceil,_u=Math.exp,yu=Math.log,mu=Math.pow,xu=Math.sin,bu=Math.sign||function(t){return 0La(Fu,Yu)&&(Yu=t):La(t,Yu)>La(Fu,Yu)&&(Fu=t):Fu<=Yu?(tLa(Fu,Yu)&&(Yu=t):La(t,Yu)>La(Fu,Yu)&&(Fu=t)}else aa.push(ca=[Fu=t,Yu=t]);nou&&(Fu=-(Yu=180)),ca[0]=Fu,ca[1]=Yu,Vu=null}function La(t,n){return(n-=t)<0?n+360:n}function qa(t,n){return t[0]-n[0]}function Da(t,n){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nou?pu((xu(n)*(o=vu(r))*xu(e)-xu(r)*(i=vu(n))*xu(t))/(i*o*u)):(n+r)/2}(u,a,t,n),i.point(c,a),i.lineEnd(),i.lineStart(),i.point(e,a),o=0),i.point(u=t,a=n),c=e},lineEnd:function(){i.lineEnd(),u=a=NaN},clean:function(){return 2-o}}},function(t,n,e,r){var i;if(null==t)i=e*au,r.point(-uu,i),r.point(0,i),r.point(uu,i),r.point(uu,0),r.point(uu,-i),r.point(0,-i),r.point(-uu,-i),r.point(-uu,0),r.point(-uu,i);else if(hu(t[0]-n[0])>ou){var o=t[0]ou;function v(t,n){return vu(t)*vu(n)>k}function g(t,n,e){var r=[1,0,0],i=ra(na(t),na(n)),o=ea(i,i),u=i[0],a=o-u*u;if(!a)return!e&&t;var c=k*o/a,s=-k*u/a,f=ra(r,i),l=oa(r,c);ia(l,oa(i,s));var h=f,p=ea(l,h),d=ea(h,h),v=p*p-d*(ea(l,l)-1);if(!(v<0)){var g=wu(v),_=oa(h,(-p-g)/d);if(ia(_,l),_=ta(_),!e)return _;var y,m=t[0],x=n[0],b=t[1],w=n[1];xou}).map(s)).concat(N(gu(u/d)*d,o,d).filter(function(t){return hu(t%g)>ou}).map(f))}return y.lines=function(){return t().map(function(t){return{type:"LineString",coordinates:t}})},y.outline=function(){return{type:"Polygon",coordinates:[l(i).concat(h(a).slice(1),l(r).reverse().slice(1),h(c).reverse().slice(1))]}},y.extent=function(t){return arguments.length?y.extentMajor(t).extentMinor(t):y.extentMinor()},y.extentMajor=function(t){return arguments.length?(i=+t[0][0],r=+t[1][0],c=+t[0][1],a=+t[1][1],rou&&0<--i);return[t/(.8707+(o=r*r)*(o*(o*o*o*(.003971-.001529*o)-.013791)-.131979)),r]},_f.invert=of(Nu),yf.invert=of(function(t){return 2*pu(t)}),mf.invert=function(t,n){return[-n,2*pu(_u(t))-au]},Ef.prototype=Tf.prototype={constructor:Ef,count:function(){return this.eachAfter(Mf)},each:function(t){var n,e,r,i,o=this,u=[o];do{for(n=u.reverse(),u=[];o=n.pop();)if(t(o),e=o.children)for(r=0,i=e.length;rsv){var a=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*a-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,i=(i*a-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>sv){var s=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*s+t._x1*t._l23_2a-n*t._l12_2a)/f,u=(u*s+t._y1*t._l23_2a-e*t._l12_2a)/f}t._context.bezierCurveTo(r,i,o,u,t._x2,t._y2)}function bg(t,n){this._context=t,this._alpha=n}bg.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3;default:xg(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var wg=function n(e){function t(t){return e?new bg(t,e):new dg(t,0)}return t.alpha=function(t){return n(+t)},t}(.5);function Mg(t,n){this._context=t,this._alpha=n}Mg.prototype={areaStart:ug,areaEnd:ug,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:xg(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var Tg=function n(e){function t(t){return e?new Mg(t,e):new gg(t,0)}return t.alpha=function(t){return n(+t)},t}(.5);function Ng(t,n){this._context=t,this._alpha=n}Ng.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:xg(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var kg=function n(e){function t(t){return e?new Ng(t,e):new yg(t,0)}return t.alpha=function(t){return n(+t)},t}(.5);function Sg(t){this._context=t}function Eg(t){return t<0?-1:1}function Ag(t,n,e){var r=t._x1-t._x0,i=n-t._x1,o=(t._y1-t._y0)/(r||i<0&&-0),u=(e-t._y1)/(i||r<0&&-0),a=(o*i+u*r)/(r+i);return(Eg(o)+Eg(u))*Math.min(Math.abs(o),Math.abs(u),.5*Math.abs(a))||0}function Cg(t,n){var e=t._x1-t._x0;return e?(3*(t._y1-t._y0)/e-n)/2:n}function zg(t,n,e){var r=t._x0,i=t._y0,o=t._x1,u=t._y1,a=(o-r)/3;t._context.bezierCurveTo(r+a,i+a*n,o-a,u-a*e,o,u)}function Pg(t){this._context=t}function Rg(t){this._context=new Lg(t)}function Lg(t){this._context=t}function qg(t){this._context=t}function Dg(t){var n,e,r=t.length-1,i=new Array(r),o=new Array(r),u=new Array(r);for(o[i[0]=0]=2,u[0]=t[0]+2*t[1],n=1;n=i)return}else c=[v,e];o=[v,i]}else{if(c){if(c[1]=i)return}else c=[(e-a)/u,e];o=[(i-a)/u,i]}else{if(c){if(c[1]=r)return}else c=[n,u*n+a];o=[r,u*r+a]}else{if(c){if(c[0]x_||Math.abs(i[0][1]-i[1][1])>x_)||delete m_[o]}(u,a,c,s),function(t,n,e,r){var i,o,u,a,c,s,f,l,h,p,d,v,g,_,y=__.length,m=!0;for(i=0;ix_||Math.abs(v-h)>x_)&&(c.splice(a,0,m_.push(Jg(u,p,Math.abs(d-t)=e)return null;for(var r=u-c.site[0],i=a-c.site[1],l=r*r+i*i;c=s.cells[n=f],f=null,c.halfedges.forEach(function(t){var n=s.edges[t],e=n.left;if(e!==c.site&&e||(e=n.right)){var r=u-e[0],i=a-e[1],o=r*r+i*i;oa;)c.pop(),--s;var f,l=new Array(s+1);for(n=0;n<=s;++n)(f=l[n]=[]).x0=0=d.length)return null!=h&&t.sort(h),null!=p?p(t):t;for(var n,o,u,a=-1,c=t.length,s=d[e++],f=Ki(),l=r();++ad.length)return t;var i,o=u[r-1];return null!=p&&r>=d.length?i=t.entries():(i=[],t.each(function(t,n){i.push({key:n,values:e(t,r)})})),null!=o?i.sort(function(t,n){return o(t.key,n.key)}):i}(v(t,0,eo,ro),0)},key:function(t){return d.push(t),n},sortKeys:function(t){return u[d.length-1]=t,n},sortValues:function(t){return h=t,n},rollup:function(t){return p=t,n}}},I.set=uo,I.map=Ki,I.keys=function(t){var n=[];for(var e in t)n.push(e);return n},I.values=function(t){var n=[];for(var e in t)n.push(t[e]);return n},I.entries=function(t){var n=[];for(var e in t)n.push({key:e,value:t[e]});return n},I.color=vn,I.rgb=mn,I.hsl=wn,I.lab=qn,I.hcl=Yn,I.cubehelix=Gn,I.dispatch=Y,I.drag=function(){var e,r,i,o,u=$t,a=Zt,n=Gt,c=Qt,d={},v=Y("start","drag","end"),g=0,s=0;function _(t){t.on("mousedown.drag",f).filter(c).on("touchstart.drag",p).on("touchmove.drag",y).on("touchend.drag touchcancel.drag",m).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function f(){if(!o&&u.apply(this,arguments)){var t=x("mouse",a.apply(this,arguments),It,this,arguments);t&&(Lt(I.event.view).on("mousemove.drag",l,!0).on("mouseup.drag",h,!0),jt(I.event.view),Bt(),i=!1,e=I.event.clientX,r=I.event.clientY,t("start"))}}function l(){if(Ht(),!i){var t=I.event.clientX-e,n=I.event.clientY-r;i=sl.index){var c=h-o.x-o.vx,s=p-o.y-o.vy,f=c*c+s*s;ft.r&&(t.r=t[n].r)}function e(){if(o){var t,n,e=o.length;for(u=new Array(e),t=0;tLa(r[0],r[1])&&(r[1]=i[1]),La(i[0],r[1])>La(r[0],r[1])&&(r[0]=i[0])):o.push(r=i);for(u=-1/0,n=0,r=o[e=o.length-1];n<=e;r=i,++n)i=o[n],(a=La(r[1],i[0]))>u&&(u=a,Fu=i[0],Yu=r[1])}return aa=ca=null,Fu===1/0||Iu===1/0?[[NaN,NaN],[NaN,NaN]]:[[Fu,Iu],[Yu,Bu]]},I.geoCentroid=function(t){sa=fa=la=ha=pa=da=va=ga=_a=ya=ma=0,Ru(t,Ua);var n=_a,e=ya,r=ma,i=n*n+e*e+r*r;return i<1e-12&&(n=da,e=va,r=ga,far.x&&(r=t),t.depth>i.depth&&(i=t)});var o=e===r?1:m(e,r)/2,u=o-e.x,a=s/(r.x+o+u),c=f/(i.depth||1);t.eachBefore(function(t){t.x=(t.x+u)*a,t.y=t.depth*c})}return t}function h(t){var n=t.children,e=t.parent.children,r=t.i?e[t.i-1]:null;if(n){!function(t){for(var n,e=0,r=0,i=t.children,o=i.length;0<=--o;)(n=i[o]).z+=e,n.m+=e,e+=n.s+(r+=n.c)}(t);var i=(n[0].z+n[n.length-1].z)/2;r?(t.z=r.z+m(t._,r._),t.m=t.z-i):t.z=i}else r&&(t.z=r.z+m(t._,r._));t.parent.A=function(t,n,e){if(n){for(var r,i=t,o=t,u=n,a=i.parent.children[0],c=i.m,s=o.m,f=u.m,l=a.m;u=il(u),i=rl(i),u&&i;)a=rl(a),(o=il(o)).a=t,0<(r=u.z+f-i.z-c+m(u._,i._))&&(_=t,y=e,h=(g=u).a.parent===_.parent?g.a:y,v=(d=r)/((p=t).i-h.i),p.c-=v,p.s+=d,h.c+=v,p.z+=d,p.m+=d,c+=r,s+=r),f+=u.m,c+=i.m,l+=a.m,s+=o.m;u&&!il(o)&&(o.t=u,o.m+=f-s),i&&!rl(a)&&(a.t=i,a.m+=c-l,e=t)}var h,p,d,v,g,_,y;return e}(t,r,t.parent.A||e[0])}function p(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function d(t){t.x*=s,t.y=t.depth*f}return n.separation=function(t){return arguments.length?(m=t,n):m},n.size=function(t){return arguments.length?(l=!1,s=+t[0],f=+t[1],n):l?null:[s,f]},n.nodeSize=function(t){return arguments.length?(l=!0,s=+t[0],f=+t[1],n):l?[s,f]:null},n},I.treemap=function(){var u=sl,n=!1,e=1,r=1,a=[0],c=jf,s=jf,f=jf,l=jf,h=jf;function i(t){return t.x0=t.y0=0,t.x1=e,t.y1=r,t.eachBefore(o),a=[0],n&&t.eachBefore(Gf),t}function o(t){var n=a[t.depth],e=t.x0+n,r=t.y0+n,i=t.x1-n,o=t.y1-n;i>>1;m[p]sv?(h+=b*=a?1:-1,p-=b):(d=0,h=p=(i+o)/2),(v-=2*w)>sv?(f+=w*=a?1:-1,l-=w):(v=0,f=l=(i+o)/2)}var M=r*iv(f),T=r*av(f),N=e*iv(p),k=e*av(p);if(svpr&&e.name===n)return new Er([[t]],si,n,+r);return null},I.interrupt=Mr,I.voronoi=function(){var i=jg,o=Xg,n=null;function e(r){return new M_(r.map(function(t,n){var e=[Math.round(i(t,n,r)/x_)*x_,Math.round(o(t,n,r)/x_)*x_];return e.index=n,e.data=t,e}),n)}return e.polygons=function(t){return e(t).polygons()},e.links=function(t){return e(t).links()},e.triangles=function(t){return e(t).triangles()},e.x=function(t){return arguments.length?(i="function"==typeof t?t:Hg(+t),e):i},e.y=function(t){return arguments.length?(o="function"==typeof t?t:Hg(+t),e):o},e.extent=function(t){return arguments.length?(n=null==t?null:[[+t[0][0],+t[0][1]],[+t[1][0],+t[1][1]]],e):n&&[[n[0][0],n[0][1]],[n[1][0],n[1][1]]]},e.size=function(t){return arguments.length?(n=null==t?null:[[0,0],[+t[0],+t[1]]],e):n&&[n[1][0]-n[0][0],n[1][1]-n[0][1]]},e},I.zoom=function(){var p,o,a=z_,f=P_,d=D_,i=L_,n=q_,u=[0,1/0],v=[[-1/0,-1/0],[1/0,1/0]],c=250,l=Le,s=[],e=Y("start","zoom","end"),h=500,g=150,_=0;function y(t){t.property("__zoom",R_).on("wheel.zoom",r).on("mousedown.zoom",N).on("dblclick.zoom",k).filter(n).on("touchstart.zoom",S).on("touchmove.zoom",E).on("touchend.zoom touchcancel.zoom",A).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function m(t,n){return(n=Math.max(u[0],Math.min(u[1],n)))===t.k?t:new k_(n,t.x,t.y)}function x(t,n,e){var r=n[0]-e[0]*t.k,i=n[1]-e[1]*t.k;return r===t.x&&i===t.y?t:new k_(t.k,r,i)}function b(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function w(t,c,s){t.on("start.zoom",function(){M(this,arguments).start()}).on("interrupt.zoom end.zoom",function(){M(this,arguments).end()}).tween("zoom",function(){var t=arguments,r=M(this,t),n=f.apply(this,t),i=s||b(n),o=Math.max(n[1][0]-n[0][0],n[1][1]-n[0][1]),e=this.__zoom,u="function"==typeof c?c.apply(this,t):c,a=l(e.invert(i).concat(o/e.k),u.invert(i).concat(o/u.k));return function(t){if(1===t)t=u;else{var n=a(t),e=o/n[2];t=new k_(e,i[0]-n[0]*e,i[1]-n[1]*e)}r.zoom(null,t)}})}function M(t,n){for(var e,r=0,i=s.length;r b ? 1 : a >= b ? 0 : NaN;\n}\n\nfunction bisector(compare) {\n if (compare.length === 1) compare = ascendingComparator(compare);\n return {\n left: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) < 0) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n },\n right: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) > 0) hi = mid;\n else lo = mid + 1;\n }\n return lo;\n }\n };\n}\n\nfunction ascendingComparator(f) {\n return function(d, x) {\n return ascending(f(d), x);\n };\n}\n\nvar ascendingBisect = bisector(ascending);\nvar bisectRight = ascendingBisect.right;\nvar bisectLeft = ascendingBisect.left;\n\nfunction pairs(array, f) {\n if (f == null) f = pair;\n var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);\n while (i < n) pairs[i] = f(p, p = array[++i]);\n return pairs;\n}\n\nfunction pair(a, b) {\n return [a, b];\n}\n\nfunction cross(values0, values1, reduce) {\n var n0 = values0.length,\n n1 = values1.length,\n values = new Array(n0 * n1),\n i0,\n i1,\n i,\n value0;\n\n if (reduce == null) reduce = pair;\n\n for (i0 = i = 0; i0 < n0; ++i0) {\n for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {\n values[i] = reduce(value0, values1[i1]);\n }\n }\n\n return values;\n}\n\nfunction descending(a, b) {\n return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n}\n\nfunction number(x) {\n return x === null ? NaN : +x;\n}\n\nfunction variance(values, valueof) {\n var n = values.length,\n m = 0,\n i = -1,\n mean = 0,\n value,\n delta,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n if (m > 1) return sum / (m - 1);\n}\n\nfunction deviation(array, f) {\n var v = variance(array, f);\n return v ? Math.sqrt(v) : v;\n}\n\nfunction extent(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n return [min, max];\n}\n\nvar array = Array.prototype;\n\nvar slice = array.slice;\nvar map = array.map;\n\nfunction constant(x) {\n return function() {\n return x;\n };\n}\n\nfunction identity(x) {\n return x;\n}\n\nfunction sequence(start, stop, step) {\n start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;\n\n var i = -1,\n n = Math.max(0, Math.ceil((stop - start) / step)) | 0,\n range = new Array(n);\n\n while (++i < n) {\n range[i] = start + i * step;\n }\n\n return range;\n}\n\nvar e10 = Math.sqrt(50);\nvar e5 = Math.sqrt(10);\nvar e2 = Math.sqrt(2);\n\nfunction ticks(start, stop, count) {\n var reverse,\n i = -1,\n n,\n ticks,\n step;\n\n stop = +stop, start = +start, count = +count;\n if (start === stop && count > 0) return [start];\n if (reverse = stop < start) n = start, start = stop, stop = n;\n if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];\n\n if (step > 0) {\n start = Math.ceil(start / step);\n stop = Math.floor(stop / step);\n ticks = new Array(n = Math.ceil(stop - start + 1));\n while (++i < n) ticks[i] = (start + i) * step;\n } else {\n start = Math.floor(start * step);\n stop = Math.ceil(stop * step);\n ticks = new Array(n = Math.ceil(start - stop + 1));\n while (++i < n) ticks[i] = (start - i) / step;\n }\n\n if (reverse) ticks.reverse();\n\n return ticks;\n}\n\nfunction tickIncrement(start, stop, count) {\n var step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log(step) / Math.LN10),\n error = step / Math.pow(10, power);\n return power >= 0\n ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)\n : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);\n}\n\nfunction tickStep(start, stop, count) {\n var step0 = Math.abs(stop - start) / Math.max(0, count),\n step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),\n error = step0 / step1;\n if (error >= e10) step1 *= 10;\n else if (error >= e5) step1 *= 5;\n else if (error >= e2) step1 *= 2;\n return stop < start ? -step1 : step1;\n}\n\nfunction sturges(values) {\n return Math.ceil(Math.log(values.length) / Math.LN2) + 1;\n}\n\nfunction histogram() {\n var value = identity,\n domain = extent,\n threshold = sturges;\n\n function histogram(data) {\n var i,\n n = data.length,\n x,\n values = new Array(n);\n\n for (i = 0; i < n; ++i) {\n values[i] = value(data[i], i, data);\n }\n\n var xz = domain(values),\n x0 = xz[0],\n x1 = xz[1],\n tz = threshold(values, x0, x1);\n\n // Convert number of thresholds into uniform thresholds.\n if (!Array.isArray(tz)) {\n tz = tickStep(x0, x1, tz);\n tz = sequence(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive\n }\n\n // Remove any thresholds outside the domain.\n var m = tz.length;\n while (tz[0] <= x0) tz.shift(), --m;\n while (tz[m - 1] > x1) tz.pop(), --m;\n\n var bins = new Array(m + 1),\n bin;\n\n // Initialize bins.\n for (i = 0; i <= m; ++i) {\n bin = bins[i] = [];\n bin.x0 = i > 0 ? tz[i - 1] : x0;\n bin.x1 = i < m ? tz[i] : x1;\n }\n\n // Assign data to bins by value, ignoring any outside the domain.\n for (i = 0; i < n; ++i) {\n x = values[i];\n if (x0 <= x && x <= x1) {\n bins[bisectRight(tz, x, 0, m)].push(data[i]);\n }\n }\n\n return bins;\n }\n\n histogram.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant(_), histogram) : value;\n };\n\n histogram.domain = function(_) {\n return arguments.length ? (domain = typeof _ === \"function\" ? _ : constant([_[0], _[1]]), histogram) : domain;\n };\n\n histogram.thresholds = function(_) {\n return arguments.length ? (threshold = typeof _ === \"function\" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;\n };\n\n return histogram;\n}\n\nfunction threshold(values, p, valueof) {\n if (valueof == null) valueof = number;\n if (!(n = values.length)) return;\n if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);\n if (p >= 1) return +valueof(values[n - 1], n - 1, values);\n var n,\n i = (n - 1) * p,\n i0 = Math.floor(i),\n value0 = +valueof(values[i0], i0, values),\n value1 = +valueof(values[i0 + 1], i0 + 1, values);\n return value0 + (value1 - value0) * (i - i0);\n}\n\nfunction freedmanDiaconis(values, min, max) {\n values = map.call(values, number).sort(ascending);\n return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));\n}\n\nfunction scott(values, min, max) {\n return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));\n}\n\nfunction max(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n return max;\n}\n\nfunction mean(values, valueof) {\n var n = values.length,\n m = n,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) sum += value;\n else --m;\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;\n else --m;\n }\n }\n\n if (m) return sum / m;\n}\n\nfunction median(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n numbers = [];\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n numbers.push(value);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n numbers.push(value);\n }\n }\n }\n\n return threshold(numbers.sort(ascending), 0.5);\n}\n\nfunction merge(arrays) {\n var n = arrays.length,\n m,\n i = -1,\n j = 0,\n merged,\n array;\n\n while (++i < n) j += arrays[i].length;\n merged = new Array(j);\n\n while (--n >= 0) {\n array = arrays[n];\n m = array.length;\n while (--m >= 0) {\n merged[--j] = array[m];\n }\n }\n\n return merged;\n}\n\nfunction min(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n return min;\n}\n\nfunction permute(array, indexes) {\n var i = indexes.length, permutes = new Array(i);\n while (i--) permutes[i] = array[indexes[i]];\n return permutes;\n}\n\nfunction scan(values, compare) {\n if (!(n = values.length)) return;\n var n,\n i = 0,\n j = 0,\n xi,\n xj = values[j];\n\n if (compare == null) compare = ascending;\n\n while (++i < n) {\n if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {\n xj = xi, j = i;\n }\n }\n\n if (compare(xj, xj) === 0) return j;\n}\n\nfunction shuffle(array, i0, i1) {\n var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),\n t,\n i;\n\n while (m) {\n i = Math.random() * m-- | 0;\n t = array[m + i0];\n array[m + i0] = array[i + i0];\n array[i + i0] = t;\n }\n\n return array;\n}\n\nfunction sum(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (value = +values[i]) sum += value; // Note: zero and null are equivalent.\n }\n }\n\n else {\n while (++i < n) {\n if (value = +valueof(values[i], i, values)) sum += value;\n }\n }\n\n return sum;\n}\n\nfunction transpose(matrix) {\n if (!(n = matrix.length)) return [];\n for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {\n for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {\n row[j] = matrix[j][i];\n }\n }\n return transpose;\n}\n\nfunction length(d) {\n return d.length;\n}\n\nfunction zip() {\n return transpose(arguments);\n}\n\nvar slice$1 = Array.prototype.slice;\n\nfunction identity$1(x) {\n return x;\n}\n\nvar top = 1;\nvar right = 2;\nvar bottom = 3;\nvar left = 4;\nvar epsilon = 1e-6;\n\nfunction translateX(x) {\n return \"translate(\" + (x + 0.5) + \",0)\";\n}\n\nfunction translateY(y) {\n return \"translate(0,\" + (y + 0.5) + \")\";\n}\n\nfunction number$1(scale) {\n return function(d) {\n return +scale(d);\n };\n}\n\nfunction center(scale) {\n var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset.\n if (scale.round()) offset = Math.round(offset);\n return function(d) {\n return +scale(d) + offset;\n };\n}\n\nfunction entering() {\n return !this.__axis;\n}\n\nfunction axis(orient, scale) {\n var tickArguments = [],\n tickValues = null,\n tickFormat = null,\n tickSizeInner = 6,\n tickSizeOuter = 6,\n tickPadding = 3,\n k = orient === top || orient === left ? -1 : 1,\n x = orient === left || orient === right ? \"x\" : \"y\",\n transform = orient === top || orient === bottom ? translateX : translateY;\n\n function axis(context) {\n var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,\n format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat,\n spacing = Math.max(tickSizeInner, 0) + tickPadding,\n range = scale.range(),\n range0 = +range[0] + 0.5,\n range1 = +range[range.length - 1] + 0.5,\n position = (scale.bandwidth ? center : number$1)(scale.copy()),\n selection = context.selection ? context.selection() : context,\n path = selection.selectAll(\".domain\").data([null]),\n tick = selection.selectAll(\".tick\").data(values, scale).order(),\n tickExit = tick.exit(),\n tickEnter = tick.enter().append(\"g\").attr(\"class\", \"tick\"),\n line = tick.select(\"line\"),\n text = tick.select(\"text\");\n\n path = path.merge(path.enter().insert(\"path\", \".tick\")\n .attr(\"class\", \"domain\")\n .attr(\"stroke\", \"#000\"));\n\n tick = tick.merge(tickEnter);\n\n line = line.merge(tickEnter.append(\"line\")\n .attr(\"stroke\", \"#000\")\n .attr(x + \"2\", k * tickSizeInner));\n\n text = text.merge(tickEnter.append(\"text\")\n .attr(\"fill\", \"#000\")\n .attr(x, k * spacing)\n .attr(\"dy\", orient === top ? \"0em\" : orient === bottom ? \"0.71em\" : \"0.32em\"));\n\n if (context !== selection) {\n path = path.transition(context);\n tick = tick.transition(context);\n line = line.transition(context);\n text = text.transition(context);\n\n tickExit = tickExit.transition(context)\n .attr(\"opacity\", epsilon)\n .attr(\"transform\", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute(\"transform\"); });\n\n tickEnter\n .attr(\"opacity\", epsilon)\n .attr(\"transform\", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });\n }\n\n tickExit.remove();\n\n path\n .attr(\"d\", orient === left || orient == right\n ? \"M\" + k * tickSizeOuter + \",\" + range0 + \"H0.5V\" + range1 + \"H\" + k * tickSizeOuter\n : \"M\" + range0 + \",\" + k * tickSizeOuter + \"V0.5H\" + range1 + \"V\" + k * tickSizeOuter);\n\n tick\n .attr(\"opacity\", 1)\n .attr(\"transform\", function(d) { return transform(position(d)); });\n\n line\n .attr(x + \"2\", k * tickSizeInner);\n\n text\n .attr(x, k * spacing)\n .text(format);\n\n selection.filter(entering)\n .attr(\"fill\", \"none\")\n .attr(\"font-size\", 10)\n .attr(\"font-family\", \"sans-serif\")\n .attr(\"text-anchor\", orient === right ? \"start\" : orient === left ? \"end\" : \"middle\");\n\n selection\n .each(function() { this.__axis = position; });\n }\n\n axis.scale = function(_) {\n return arguments.length ? (scale = _, axis) : scale;\n };\n\n axis.ticks = function() {\n return tickArguments = slice$1.call(arguments), axis;\n };\n\n axis.tickArguments = function(_) {\n return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice();\n };\n\n axis.tickValues = function(_) {\n return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice();\n };\n\n axis.tickFormat = function(_) {\n return arguments.length ? (tickFormat = _, axis) : tickFormat;\n };\n\n axis.tickSize = function(_) {\n return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;\n };\n\n axis.tickSizeInner = function(_) {\n return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;\n };\n\n axis.tickSizeOuter = function(_) {\n return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;\n };\n\n axis.tickPadding = function(_) {\n return arguments.length ? (tickPadding = +_, axis) : tickPadding;\n };\n\n return axis;\n}\n\nfunction axisTop(scale) {\n return axis(top, scale);\n}\n\nfunction axisRight(scale) {\n return axis(right, scale);\n}\n\nfunction axisBottom(scale) {\n return axis(bottom, scale);\n}\n\nfunction axisLeft(scale) {\n return axis(left, scale);\n}\n\nvar noop = {value: function() {}};\n\nfunction dispatch() {\n for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {\n if (!(t = arguments[i] + \"\") || (t in _)) throw new Error(\"illegal type: \" + t);\n _[t] = [];\n }\n return new Dispatch(_);\n}\n\nfunction Dispatch(_) {\n this._ = _;\n}\n\nfunction parseTypenames(typenames, types) {\n return typenames.trim().split(/^|\\s+/).map(function(t) {\n var name = \"\", i = t.indexOf(\".\");\n if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n if (t && !types.hasOwnProperty(t)) throw new Error(\"unknown type: \" + t);\n return {type: t, name: name};\n });\n}\n\nDispatch.prototype = dispatch.prototype = {\n constructor: Dispatch,\n on: function(typename, callback) {\n var _ = this._,\n T = parseTypenames(typename + \"\", _),\n t,\n i = -1,\n n = T.length;\n\n // If no callback was specified, return the callback of the given type and name.\n if (arguments.length < 2) {\n while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;\n return;\n }\n\n // If a type was specified, set the callback for the given type and name.\n // Otherwise, if a null callback was specified, remove callbacks of the given name.\n if (callback != null && typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n while (++i < n) {\n if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);\n else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);\n }\n\n return this;\n },\n copy: function() {\n var copy = {}, _ = this._;\n for (var t in _) copy[t] = _[t].slice();\n return new Dispatch(copy);\n },\n call: function(type, that) {\n if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];\n if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n },\n apply: function(type, that, args) {\n if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n }\n};\n\nfunction get(type, name) {\n for (var i = 0, n = type.length, c; i < n; ++i) {\n if ((c = type[i]).name === name) {\n return c.value;\n }\n }\n}\n\nfunction set(type, name, callback) {\n for (var i = 0, n = type.length; i < n; ++i) {\n if (type[i].name === name) {\n type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));\n break;\n }\n }\n if (callback != null) type.push({name: name, value: callback});\n return type;\n}\n\nvar xhtml = \"http://www.w3.org/1999/xhtml\";\n\nvar namespaces = {\n svg: \"http://www.w3.org/2000/svg\",\n xhtml: xhtml,\n xlink: \"http://www.w3.org/1999/xlink\",\n xml: \"http://www.w3.org/XML/1998/namespace\",\n xmlns: \"http://www.w3.org/2000/xmlns/\"\n};\n\nfunction namespace(name) {\n var prefix = name += \"\", i = prefix.indexOf(\":\");\n if (i >= 0 && (prefix = name.slice(0, i)) !== \"xmlns\") name = name.slice(i + 1);\n return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;\n}\n\nfunction creatorInherit(name) {\n return function() {\n var document = this.ownerDocument,\n uri = this.namespaceURI;\n return uri === xhtml && document.documentElement.namespaceURI === xhtml\n ? document.createElement(name)\n : document.createElementNS(uri, name);\n };\n}\n\nfunction creatorFixed(fullname) {\n return function() {\n return this.ownerDocument.createElementNS(fullname.space, fullname.local);\n };\n}\n\nfunction creator(name) {\n var fullname = namespace(name);\n return (fullname.local\n ? creatorFixed\n : creatorInherit)(fullname);\n}\n\nfunction none() {}\n\nfunction selector(selector) {\n return selector == null ? none : function() {\n return this.querySelector(selector);\n };\n}\n\nfunction selection_select(select) {\n if (typeof select !== \"function\") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if (\"__data__\" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n\nfunction empty$1() {\n return [];\n}\n\nfunction selectorAll(selector) {\n return selector == null ? empty$1 : function() {\n return this.querySelectorAll(selector);\n };\n}\n\nfunction selection_selectAll(select) {\n if (typeof select !== \"function\") select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n subgroups.push(select.call(node, node.__data__, i, group));\n parents.push(node);\n }\n }\n }\n\n return new Selection(subgroups, parents);\n}\n\nvar matcher = function(selector) {\n return function() {\n return this.matches(selector);\n };\n};\n\nif (typeof document !== \"undefined\") {\n var element = document.documentElement;\n if (!element.matches) {\n var vendorMatches = element.webkitMatchesSelector\n || element.msMatchesSelector\n || element.mozMatchesSelector\n || element.oMatchesSelector;\n matcher = function(selector) {\n return function() {\n return vendorMatches.call(this, selector);\n };\n };\n }\n}\n\nvar matcher$1 = matcher;\n\nfunction selection_filter(match) {\n if (typeof match !== \"function\") match = matcher$1(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n\nfunction sparse(update) {\n return new Array(update.length);\n}\n\nfunction selection_enter() {\n return new Selection(this._enter || this._groups.map(sparse), this._parents);\n}\n\nfunction EnterNode(parent, datum) {\n this.ownerDocument = parent.ownerDocument;\n this.namespaceURI = parent.namespaceURI;\n this._next = null;\n this._parent = parent;\n this.__data__ = datum;\n}\n\nEnterNode.prototype = {\n constructor: EnterNode,\n appendChild: function(child) { return this._parent.insertBefore(child, this._next); },\n insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },\n querySelector: function(selector) { return this._parent.querySelector(selector); },\n querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }\n};\n\nfunction constant$1(x) {\n return function() {\n return x;\n };\n}\n\nvar keyPrefix = \"$\"; // Protect against keys like “__proto__”.\n\nfunction bindIndex(parent, group, enter, update, exit, data) {\n var i = 0,\n node,\n groupLength = group.length,\n dataLength = data.length;\n\n // Put any non-null nodes that fit into update.\n // Put any null nodes into enter.\n // Put any remaining data into enter.\n for (; i < dataLength; ++i) {\n if (node = group[i]) {\n node.__data__ = data[i];\n update[i] = node;\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n }\n\n // Put any non-null nodes that don’t fit into exit.\n for (; i < groupLength; ++i) {\n if (node = group[i]) {\n exit[i] = node;\n }\n }\n}\n\nfunction bindKey(parent, group, enter, update, exit, data, key) {\n var i,\n node,\n nodeByKeyValue = {},\n groupLength = group.length,\n dataLength = data.length,\n keyValues = new Array(groupLength),\n keyValue;\n\n // Compute the key for each node.\n // If multiple nodes have the same key, the duplicates are added to exit.\n for (i = 0; i < groupLength; ++i) {\n if (node = group[i]) {\n keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);\n if (keyValue in nodeByKeyValue) {\n exit[i] = node;\n } else {\n nodeByKeyValue[keyValue] = node;\n }\n }\n }\n\n // Compute the key for each datum.\n // If there a node associated with this key, join and add it to update.\n // If there is not (or the key is a duplicate), add it to enter.\n for (i = 0; i < dataLength; ++i) {\n keyValue = keyPrefix + key.call(parent, data[i], i, data);\n if (node = nodeByKeyValue[keyValue]) {\n update[i] = node;\n node.__data__ = data[i];\n nodeByKeyValue[keyValue] = null;\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n }\n\n // Add any remaining nodes that were not bound to data to exit.\n for (i = 0; i < groupLength; ++i) {\n if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {\n exit[i] = node;\n }\n }\n}\n\nfunction selection_data(value, key) {\n if (!value) {\n data = new Array(this.size()), j = -1;\n this.each(function(d) { data[++j] = d; });\n return data;\n }\n\n var bind = key ? bindKey : bindIndex,\n parents = this._parents,\n groups = this._groups;\n\n if (typeof value !== \"function\") value = constant$1(value);\n\n for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {\n var parent = parents[j],\n group = groups[j],\n groupLength = group.length,\n data = value.call(parent, parent && parent.__data__, j, parents),\n dataLength = data.length,\n enterGroup = enter[j] = new Array(dataLength),\n updateGroup = update[j] = new Array(dataLength),\n exitGroup = exit[j] = new Array(groupLength);\n\n bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);\n\n // Now connect the enter nodes to their following update node, such that\n // appendChild can insert the materialized enter node before this node,\n // rather than at the end of the parent node.\n for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {\n if (previous = enterGroup[i0]) {\n if (i0 >= i1) i1 = i0 + 1;\n while (!(next = updateGroup[i1]) && ++i1 < dataLength);\n previous._next = next || null;\n }\n }\n }\n\n update = new Selection(update, parents);\n update._enter = enter;\n update._exit = exit;\n return update;\n}\n\nfunction selection_exit() {\n return new Selection(this._exit || this._groups.map(sparse), this._parents);\n}\n\nfunction selection_merge(selection$$1) {\n\n for (var groups0 = this._groups, groups1 = selection$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Selection(merges, this._parents);\n}\n\nfunction selection_order() {\n\n for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {\n for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {\n if (node = group[i]) {\n if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);\n next = node;\n }\n }\n }\n\n return this;\n}\n\nfunction selection_sort(compare) {\n if (!compare) compare = ascending$1;\n\n function compareNode(a, b) {\n return a && b ? compare(a.__data__, b.__data__) : !a - !b;\n }\n\n for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n sortgroup[i] = node;\n }\n }\n sortgroup.sort(compareNode);\n }\n\n return new Selection(sortgroups, this._parents).order();\n}\n\nfunction ascending$1(a, b) {\n return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n\nfunction selection_call() {\n var callback = arguments[0];\n arguments[0] = this;\n callback.apply(null, arguments);\n return this;\n}\n\nfunction selection_nodes() {\n var nodes = new Array(this.size()), i = -1;\n this.each(function() { nodes[++i] = this; });\n return nodes;\n}\n\nfunction selection_node() {\n\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {\n var node = group[i];\n if (node) return node;\n }\n }\n\n return null;\n}\n\nfunction selection_size() {\n var size = 0;\n this.each(function() { ++size; });\n return size;\n}\n\nfunction selection_empty() {\n return !this.node();\n}\n\nfunction selection_each(callback) {\n\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {\n if (node = group[i]) callback.call(node, node.__data__, i, group);\n }\n }\n\n return this;\n}\n\nfunction attrRemove(name) {\n return function() {\n this.removeAttribute(name);\n };\n}\n\nfunction attrRemoveNS(fullname) {\n return function() {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attrConstant(name, value) {\n return function() {\n this.setAttribute(name, value);\n };\n}\n\nfunction attrConstantNS(fullname, value) {\n return function() {\n this.setAttributeNS(fullname.space, fullname.local, value);\n };\n}\n\nfunction attrFunction(name, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttribute(name);\n else this.setAttribute(name, v);\n };\n}\n\nfunction attrFunctionNS(fullname, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttributeNS(fullname.space, fullname.local);\n else this.setAttributeNS(fullname.space, fullname.local, v);\n };\n}\n\nfunction selection_attr(name, value) {\n var fullname = namespace(name);\n\n if (arguments.length < 2) {\n var node = this.node();\n return fullname.local\n ? node.getAttributeNS(fullname.space, fullname.local)\n : node.getAttribute(fullname);\n }\n\n return this.each((value == null\n ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === \"function\"\n ? (fullname.local ? attrFunctionNS : attrFunction)\n : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));\n}\n\nfunction defaultView(node) {\n return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node\n || (node.document && node) // node is a Window\n || node.defaultView; // node is a Document\n}\n\nfunction styleRemove(name) {\n return function() {\n this.style.removeProperty(name);\n };\n}\n\nfunction styleConstant(name, value, priority) {\n return function() {\n this.style.setProperty(name, value, priority);\n };\n}\n\nfunction styleFunction(name, value, priority) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.style.removeProperty(name);\n else this.style.setProperty(name, v, priority);\n };\n}\n\nfunction selection_style(name, value, priority) {\n return arguments.length > 1\n ? this.each((value == null\n ? styleRemove : typeof value === \"function\"\n ? styleFunction\n : styleConstant)(name, value, priority == null ? \"\" : priority))\n : styleValue(this.node(), name);\n}\n\nfunction styleValue(node, name) {\n return node.style.getPropertyValue(name)\n || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);\n}\n\nfunction propertyRemove(name) {\n return function() {\n delete this[name];\n };\n}\n\nfunction propertyConstant(name, value) {\n return function() {\n this[name] = value;\n };\n}\n\nfunction propertyFunction(name, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) delete this[name];\n else this[name] = v;\n };\n}\n\nfunction selection_property(name, value) {\n return arguments.length > 1\n ? this.each((value == null\n ? propertyRemove : typeof value === \"function\"\n ? propertyFunction\n : propertyConstant)(name, value))\n : this.node()[name];\n}\n\nfunction classArray(string) {\n return string.trim().split(/^|\\s+/);\n}\n\nfunction classList(node) {\n return node.classList || new ClassList(node);\n}\n\nfunction ClassList(node) {\n this._node = node;\n this._names = classArray(node.getAttribute(\"class\") || \"\");\n}\n\nClassList.prototype = {\n add: function(name) {\n var i = this._names.indexOf(name);\n if (i < 0) {\n this._names.push(name);\n this._node.setAttribute(\"class\", this._names.join(\" \"));\n }\n },\n remove: function(name) {\n var i = this._names.indexOf(name);\n if (i >= 0) {\n this._names.splice(i, 1);\n this._node.setAttribute(\"class\", this._names.join(\" \"));\n }\n },\n contains: function(name) {\n return this._names.indexOf(name) >= 0;\n }\n};\n\nfunction classedAdd(node, names) {\n var list = classList(node), i = -1, n = names.length;\n while (++i < n) list.add(names[i]);\n}\n\nfunction classedRemove(node, names) {\n var list = classList(node), i = -1, n = names.length;\n while (++i < n) list.remove(names[i]);\n}\n\nfunction classedTrue(names) {\n return function() {\n classedAdd(this, names);\n };\n}\n\nfunction classedFalse(names) {\n return function() {\n classedRemove(this, names);\n };\n}\n\nfunction classedFunction(names, value) {\n return function() {\n (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);\n };\n}\n\nfunction selection_classed(name, value) {\n var names = classArray(name + \"\");\n\n if (arguments.length < 2) {\n var list = classList(this.node()), i = -1, n = names.length;\n while (++i < n) if (!list.contains(names[i])) return false;\n return true;\n }\n\n return this.each((typeof value === \"function\"\n ? classedFunction : value\n ? classedTrue\n : classedFalse)(names, value));\n}\n\nfunction textRemove() {\n this.textContent = \"\";\n}\n\nfunction textConstant(value) {\n return function() {\n this.textContent = value;\n };\n}\n\nfunction textFunction(value) {\n return function() {\n var v = value.apply(this, arguments);\n this.textContent = v == null ? \"\" : v;\n };\n}\n\nfunction selection_text(value) {\n return arguments.length\n ? this.each(value == null\n ? textRemove : (typeof value === \"function\"\n ? textFunction\n : textConstant)(value))\n : this.node().textContent;\n}\n\nfunction htmlRemove() {\n this.innerHTML = \"\";\n}\n\nfunction htmlConstant(value) {\n return function() {\n this.innerHTML = value;\n };\n}\n\nfunction htmlFunction(value) {\n return function() {\n var v = value.apply(this, arguments);\n this.innerHTML = v == null ? \"\" : v;\n };\n}\n\nfunction selection_html(value) {\n return arguments.length\n ? this.each(value == null\n ? htmlRemove : (typeof value === \"function\"\n ? htmlFunction\n : htmlConstant)(value))\n : this.node().innerHTML;\n}\n\nfunction raise() {\n if (this.nextSibling) this.parentNode.appendChild(this);\n}\n\nfunction selection_raise() {\n return this.each(raise);\n}\n\nfunction lower() {\n if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);\n}\n\nfunction selection_lower() {\n return this.each(lower);\n}\n\nfunction selection_append(name) {\n var create = typeof name === \"function\" ? name : creator(name);\n return this.select(function() {\n return this.appendChild(create.apply(this, arguments));\n });\n}\n\nfunction constantNull() {\n return null;\n}\n\nfunction selection_insert(name, before) {\n var create = typeof name === \"function\" ? name : creator(name),\n select = before == null ? constantNull : typeof before === \"function\" ? before : selector(before);\n return this.select(function() {\n return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);\n });\n}\n\nfunction remove() {\n var parent = this.parentNode;\n if (parent) parent.removeChild(this);\n}\n\nfunction selection_remove() {\n return this.each(remove);\n}\n\nfunction selection_cloneShallow() {\n return this.parentNode.insertBefore(this.cloneNode(false), this.nextSibling);\n}\n\nfunction selection_cloneDeep() {\n return this.parentNode.insertBefore(this.cloneNode(true), this.nextSibling);\n}\n\nfunction selection_clone(deep) {\n return this.select(deep ? selection_cloneDeep : selection_cloneShallow);\n}\n\nfunction selection_datum(value) {\n return arguments.length\n ? this.property(\"__data__\", value)\n : this.node().__data__;\n}\n\nvar filterEvents = {};\n\nexports.event = null;\n\nif (typeof document !== \"undefined\") {\n var element$1 = document.documentElement;\n if (!(\"onmouseenter\" in element$1)) {\n filterEvents = {mouseenter: \"mouseover\", mouseleave: \"mouseout\"};\n }\n}\n\nfunction filterContextListener(listener, index, group) {\n listener = contextListener(listener, index, group);\n return function(event) {\n var related = event.relatedTarget;\n if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {\n listener.call(this, event);\n }\n };\n}\n\nfunction contextListener(listener, index, group) {\n return function(event1) {\n var event0 = exports.event; // Events can be reentrant (e.g., focus).\n exports.event = event1;\n try {\n listener.call(this, this.__data__, index, group);\n } finally {\n exports.event = event0;\n }\n };\n}\n\nfunction parseTypenames$1(typenames) {\n return typenames.trim().split(/^|\\s+/).map(function(t) {\n var name = \"\", i = t.indexOf(\".\");\n if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n return {type: t, name: name};\n });\n}\n\nfunction onRemove(typename) {\n return function() {\n var on = this.__on;\n if (!on) return;\n for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {\n if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {\n this.removeEventListener(o.type, o.listener, o.capture);\n } else {\n on[++i] = o;\n }\n }\n if (++i) on.length = i;\n else delete this.__on;\n };\n}\n\nfunction onAdd(typename, value, capture) {\n var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;\n return function(d, i, group) {\n var on = this.__on, o, listener = wrap(value, i, group);\n if (on) for (var j = 0, m = on.length; j < m; ++j) {\n if ((o = on[j]).type === typename.type && o.name === typename.name) {\n this.removeEventListener(o.type, o.listener, o.capture);\n this.addEventListener(o.type, o.listener = listener, o.capture = capture);\n o.value = value;\n return;\n }\n }\n this.addEventListener(typename.type, listener, capture);\n o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};\n if (!on) this.__on = [o];\n else on.push(o);\n };\n}\n\nfunction selection_on(typename, value, capture) {\n var typenames = parseTypenames$1(typename + \"\"), i, n = typenames.length, t;\n\n if (arguments.length < 2) {\n var on = this.node().__on;\n if (on) for (var j = 0, m = on.length, o; j < m; ++j) {\n for (i = 0, o = on[j]; i < n; ++i) {\n if ((t = typenames[i]).type === o.type && t.name === o.name) {\n return o.value;\n }\n }\n }\n return;\n }\n\n on = value ? onAdd : onRemove;\n if (capture == null) capture = false;\n for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));\n return this;\n}\n\nfunction customEvent(event1, listener, that, args) {\n var event0 = exports.event;\n event1.sourceEvent = exports.event;\n exports.event = event1;\n try {\n return listener.apply(that, args);\n } finally {\n exports.event = event0;\n }\n}\n\nfunction dispatchEvent(node, type, params) {\n var window = defaultView(node),\n event = window.CustomEvent;\n\n if (typeof event === \"function\") {\n event = new event(type, params);\n } else {\n event = window.document.createEvent(\"Event\");\n if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;\n else event.initEvent(type, false, false);\n }\n\n node.dispatchEvent(event);\n}\n\nfunction dispatchConstant(type, params) {\n return function() {\n return dispatchEvent(this, type, params);\n };\n}\n\nfunction dispatchFunction(type, params) {\n return function() {\n return dispatchEvent(this, type, params.apply(this, arguments));\n };\n}\n\nfunction selection_dispatch(type, params) {\n return this.each((typeof params === \"function\"\n ? dispatchFunction\n : dispatchConstant)(type, params));\n}\n\nvar root = [null];\n\nfunction Selection(groups, parents) {\n this._groups = groups;\n this._parents = parents;\n}\n\nfunction selection() {\n return new Selection([[document.documentElement]], root);\n}\n\nSelection.prototype = selection.prototype = {\n constructor: Selection,\n select: selection_select,\n selectAll: selection_selectAll,\n filter: selection_filter,\n data: selection_data,\n enter: selection_enter,\n exit: selection_exit,\n merge: selection_merge,\n order: selection_order,\n sort: selection_sort,\n call: selection_call,\n nodes: selection_nodes,\n node: selection_node,\n size: selection_size,\n empty: selection_empty,\n each: selection_each,\n attr: selection_attr,\n style: selection_style,\n property: selection_property,\n classed: selection_classed,\n text: selection_text,\n html: selection_html,\n raise: selection_raise,\n lower: selection_lower,\n append: selection_append,\n insert: selection_insert,\n remove: selection_remove,\n clone: selection_clone,\n datum: selection_datum,\n on: selection_on,\n dispatch: selection_dispatch\n};\n\nfunction select(selector) {\n return typeof selector === \"string\"\n ? new Selection([[document.querySelector(selector)]], [document.documentElement])\n : new Selection([[selector]], root);\n}\n\nfunction create(name) {\n return select(creator(name).call(document.documentElement));\n}\n\nvar nextId = 0;\n\nfunction local$1() {\n return new Local;\n}\n\nfunction Local() {\n this._ = \"@\" + (++nextId).toString(36);\n}\n\nLocal.prototype = local$1.prototype = {\n constructor: Local,\n get: function(node) {\n var id = this._;\n while (!(id in node)) if (!(node = node.parentNode)) return;\n return node[id];\n },\n set: function(node, value) {\n return node[this._] = value;\n },\n remove: function(node) {\n return this._ in node && delete node[this._];\n },\n toString: function() {\n return this._;\n }\n};\n\nfunction sourceEvent() {\n var current = exports.event, source;\n while (source = current.sourceEvent) current = source;\n return current;\n}\n\nfunction point(node, event) {\n var svg = node.ownerSVGElement || node;\n\n if (svg.createSVGPoint) {\n var point = svg.createSVGPoint();\n point.x = event.clientX, point.y = event.clientY;\n point = point.matrixTransform(node.getScreenCTM().inverse());\n return [point.x, point.y];\n }\n\n var rect = node.getBoundingClientRect();\n return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];\n}\n\nfunction mouse(node) {\n var event = sourceEvent();\n if (event.changedTouches) event = event.changedTouches[0];\n return point(node, event);\n}\n\nfunction selectAll(selector) {\n return typeof selector === \"string\"\n ? new Selection([document.querySelectorAll(selector)], [document.documentElement])\n : new Selection([selector == null ? [] : selector], root);\n}\n\nfunction touch(node, touches, identifier) {\n if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;\n\n for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {\n if ((touch = touches[i]).identifier === identifier) {\n return point(node, touch);\n }\n }\n\n return null;\n}\n\nfunction touches(node, touches) {\n if (touches == null) touches = sourceEvent().touches;\n\n for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {\n points[i] = point(node, touches[i]);\n }\n\n return points;\n}\n\nfunction nopropagation() {\n exports.event.stopImmediatePropagation();\n}\n\nfunction noevent() {\n exports.event.preventDefault();\n exports.event.stopImmediatePropagation();\n}\n\nfunction dragDisable(view) {\n var root = view.document.documentElement,\n selection = select(view).on(\"dragstart.drag\", noevent, true);\n if (\"onselectstart\" in root) {\n selection.on(\"selectstart.drag\", noevent, true);\n } else {\n root.__noselect = root.style.MozUserSelect;\n root.style.MozUserSelect = \"none\";\n }\n}\n\nfunction yesdrag(view, noclick) {\n var root = view.document.documentElement,\n selection = select(view).on(\"dragstart.drag\", null);\n if (noclick) {\n selection.on(\"click.drag\", noevent, true);\n setTimeout(function() { selection.on(\"click.drag\", null); }, 0);\n }\n if (\"onselectstart\" in root) {\n selection.on(\"selectstart.drag\", null);\n } else {\n root.style.MozUserSelect = root.__noselect;\n delete root.__noselect;\n }\n}\n\nfunction constant$2(x) {\n return function() {\n return x;\n };\n}\n\nfunction DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {\n this.target = target;\n this.type = type;\n this.subject = subject;\n this.identifier = id;\n this.active = active;\n this.x = x;\n this.y = y;\n this.dx = dx;\n this.dy = dy;\n this._ = dispatch;\n}\n\nDragEvent.prototype.on = function() {\n var value = this._.on.apply(this._, arguments);\n return value === this._ ? this : value;\n};\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter$1() {\n return !exports.event.button;\n}\n\nfunction defaultContainer() {\n return this.parentNode;\n}\n\nfunction defaultSubject(d) {\n return d == null ? {x: exports.event.x, y: exports.event.y} : d;\n}\n\nfunction defaultTouchable() {\n return \"ontouchstart\" in this;\n}\n\nfunction drag() {\n var filter = defaultFilter$1,\n container = defaultContainer,\n subject = defaultSubject,\n touchable = defaultTouchable,\n gestures = {},\n listeners = dispatch(\"start\", \"drag\", \"end\"),\n active = 0,\n mousedownx,\n mousedowny,\n mousemoving,\n touchending,\n clickDistance2 = 0;\n\n function drag(selection) {\n selection\n .on(\"mousedown.drag\", mousedowned)\n .filter(touchable)\n .on(\"touchstart.drag\", touchstarted)\n .on(\"touchmove.drag\", touchmoved)\n .on(\"touchend.drag touchcancel.drag\", touchended)\n .style(\"touch-action\", \"none\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\");\n }\n\n function mousedowned() {\n if (touchending || !filter.apply(this, arguments)) return;\n var gesture = beforestart(\"mouse\", container.apply(this, arguments), mouse, this, arguments);\n if (!gesture) return;\n select(exports.event.view).on(\"mousemove.drag\", mousemoved, true).on(\"mouseup.drag\", mouseupped, true);\n dragDisable(exports.event.view);\n nopropagation();\n mousemoving = false;\n mousedownx = exports.event.clientX;\n mousedowny = exports.event.clientY;\n gesture(\"start\");\n }\n\n function mousemoved() {\n noevent();\n if (!mousemoving) {\n var dx = exports.event.clientX - mousedownx, dy = exports.event.clientY - mousedowny;\n mousemoving = dx * dx + dy * dy > clickDistance2;\n }\n gestures.mouse(\"drag\");\n }\n\n function mouseupped() {\n select(exports.event.view).on(\"mousemove.drag mouseup.drag\", null);\n yesdrag(exports.event.view, mousemoving);\n noevent();\n gestures.mouse(\"end\");\n }\n\n function touchstarted() {\n if (!filter.apply(this, arguments)) return;\n var touches = exports.event.changedTouches,\n c = container.apply(this, arguments),\n n = touches.length, i, gesture;\n\n for (i = 0; i < n; ++i) {\n if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) {\n nopropagation();\n gesture(\"start\");\n }\n }\n }\n\n function touchmoved() {\n var touches = exports.event.changedTouches,\n n = touches.length, i, gesture;\n\n for (i = 0; i < n; ++i) {\n if (gesture = gestures[touches[i].identifier]) {\n noevent();\n gesture(\"drag\");\n }\n }\n }\n\n function touchended() {\n var touches = exports.event.changedTouches,\n n = touches.length, i, gesture;\n\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n for (i = 0; i < n; ++i) {\n if (gesture = gestures[touches[i].identifier]) {\n nopropagation();\n gesture(\"end\");\n }\n }\n }\n\n function beforestart(id, container, point, that, args) {\n var p = point(container, id), s, dx, dy,\n sublisteners = listeners.copy();\n\n if (!customEvent(new DragEvent(drag, \"beforestart\", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {\n if ((exports.event.subject = s = subject.apply(that, args)) == null) return false;\n dx = s.x - p[0] || 0;\n dy = s.y - p[1] || 0;\n return true;\n })) return;\n\n return function gesture(type) {\n var p0 = p, n;\n switch (type) {\n case \"start\": gestures[id] = gesture, n = active++; break;\n case \"end\": delete gestures[id], --active; // nobreak\n case \"drag\": p = point(container, id), n = active; break;\n }\n customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);\n };\n }\n\n drag.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant$2(!!_), drag) : filter;\n };\n\n drag.container = function(_) {\n return arguments.length ? (container = typeof _ === \"function\" ? _ : constant$2(_), drag) : container;\n };\n\n drag.subject = function(_) {\n return arguments.length ? (subject = typeof _ === \"function\" ? _ : constant$2(_), drag) : subject;\n };\n\n drag.touchable = function(_) {\n return arguments.length ? (touchable = typeof _ === \"function\" ? _ : constant$2(!!_), drag) : touchable;\n };\n\n drag.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? drag : value;\n };\n\n drag.clickDistance = function(_) {\n return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);\n };\n\n return drag;\n}\n\nfunction define(constructor, factory, prototype) {\n constructor.prototype = factory.prototype = prototype;\n prototype.constructor = constructor;\n}\n\nfunction extend(parent, definition) {\n var prototype = Object.create(parent.prototype);\n for (var key in definition) prototype[key] = definition[key];\n return prototype;\n}\n\nfunction Color() {}\n\nvar darker = 0.7;\nvar brighter = 1 / darker;\n\nvar reI = \"\\\\s*([+-]?\\\\d+)\\\\s*\";\nvar reN = \"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\";\nvar reP = \"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\";\nvar reHex3 = /^#([0-9a-f]{3})$/;\nvar reHex6 = /^#([0-9a-f]{6})$/;\nvar reRgbInteger = new RegExp(\"^rgb\\\\(\" + [reI, reI, reI] + \"\\\\)$\");\nvar reRgbPercent = new RegExp(\"^rgb\\\\(\" + [reP, reP, reP] + \"\\\\)$\");\nvar reRgbaInteger = new RegExp(\"^rgba\\\\(\" + [reI, reI, reI, reN] + \"\\\\)$\");\nvar reRgbaPercent = new RegExp(\"^rgba\\\\(\" + [reP, reP, reP, reN] + \"\\\\)$\");\nvar reHslPercent = new RegExp(\"^hsl\\\\(\" + [reN, reP, reP] + \"\\\\)$\");\nvar reHslaPercent = new RegExp(\"^hsla\\\\(\" + [reN, reP, reP, reN] + \"\\\\)$\");\n\nvar named = {\n aliceblue: 0xf0f8ff,\n antiquewhite: 0xfaebd7,\n aqua: 0x00ffff,\n aquamarine: 0x7fffd4,\n azure: 0xf0ffff,\n beige: 0xf5f5dc,\n bisque: 0xffe4c4,\n black: 0x000000,\n blanchedalmond: 0xffebcd,\n blue: 0x0000ff,\n blueviolet: 0x8a2be2,\n brown: 0xa52a2a,\n burlywood: 0xdeb887,\n cadetblue: 0x5f9ea0,\n chartreuse: 0x7fff00,\n chocolate: 0xd2691e,\n coral: 0xff7f50,\n cornflowerblue: 0x6495ed,\n cornsilk: 0xfff8dc,\n crimson: 0xdc143c,\n cyan: 0x00ffff,\n darkblue: 0x00008b,\n darkcyan: 0x008b8b,\n darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9,\n darkgreen: 0x006400,\n darkgrey: 0xa9a9a9,\n darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b,\n darkolivegreen: 0x556b2f,\n darkorange: 0xff8c00,\n darkorchid: 0x9932cc,\n darkred: 0x8b0000,\n darksalmon: 0xe9967a,\n darkseagreen: 0x8fbc8f,\n darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f,\n darkslategrey: 0x2f4f4f,\n darkturquoise: 0x00ced1,\n darkviolet: 0x9400d3,\n deeppink: 0xff1493,\n deepskyblue: 0x00bfff,\n dimgray: 0x696969,\n dimgrey: 0x696969,\n dodgerblue: 0x1e90ff,\n firebrick: 0xb22222,\n floralwhite: 0xfffaf0,\n forestgreen: 0x228b22,\n fuchsia: 0xff00ff,\n gainsboro: 0xdcdcdc,\n ghostwhite: 0xf8f8ff,\n gold: 0xffd700,\n goldenrod: 0xdaa520,\n gray: 0x808080,\n green: 0x008000,\n greenyellow: 0xadff2f,\n grey: 0x808080,\n honeydew: 0xf0fff0,\n hotpink: 0xff69b4,\n indianred: 0xcd5c5c,\n indigo: 0x4b0082,\n ivory: 0xfffff0,\n khaki: 0xf0e68c,\n lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5,\n lawngreen: 0x7cfc00,\n lemonchiffon: 0xfffacd,\n lightblue: 0xadd8e6,\n lightcoral: 0xf08080,\n lightcyan: 0xe0ffff,\n lightgoldenrodyellow: 0xfafad2,\n lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90,\n lightgrey: 0xd3d3d3,\n lightpink: 0xffb6c1,\n lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa,\n lightskyblue: 0x87cefa,\n lightslategray: 0x778899,\n lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de,\n lightyellow: 0xffffe0,\n lime: 0x00ff00,\n limegreen: 0x32cd32,\n linen: 0xfaf0e6,\n magenta: 0xff00ff,\n maroon: 0x800000,\n mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd,\n mediumorchid: 0xba55d3,\n mediumpurple: 0x9370db,\n mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee,\n mediumspringgreen: 0x00fa9a,\n mediumturquoise: 0x48d1cc,\n mediumvioletred: 0xc71585,\n midnightblue: 0x191970,\n mintcream: 0xf5fffa,\n mistyrose: 0xffe4e1,\n moccasin: 0xffe4b5,\n navajowhite: 0xffdead,\n navy: 0x000080,\n oldlace: 0xfdf5e6,\n olive: 0x808000,\n olivedrab: 0x6b8e23,\n orange: 0xffa500,\n orangered: 0xff4500,\n orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa,\n palegreen: 0x98fb98,\n paleturquoise: 0xafeeee,\n palevioletred: 0xdb7093,\n papayawhip: 0xffefd5,\n peachpuff: 0xffdab9,\n peru: 0xcd853f,\n pink: 0xffc0cb,\n plum: 0xdda0dd,\n powderblue: 0xb0e0e6,\n purple: 0x800080,\n rebeccapurple: 0x663399,\n red: 0xff0000,\n rosybrown: 0xbc8f8f,\n royalblue: 0x4169e1,\n saddlebrown: 0x8b4513,\n salmon: 0xfa8072,\n sandybrown: 0xf4a460,\n seagreen: 0x2e8b57,\n seashell: 0xfff5ee,\n sienna: 0xa0522d,\n silver: 0xc0c0c0,\n skyblue: 0x87ceeb,\n slateblue: 0x6a5acd,\n slategray: 0x708090,\n slategrey: 0x708090,\n snow: 0xfffafa,\n springgreen: 0x00ff7f,\n steelblue: 0x4682b4,\n tan: 0xd2b48c,\n teal: 0x008080,\n thistle: 0xd8bfd8,\n tomato: 0xff6347,\n turquoise: 0x40e0d0,\n violet: 0xee82ee,\n wheat: 0xf5deb3,\n white: 0xffffff,\n whitesmoke: 0xf5f5f5,\n yellow: 0xffff00,\n yellowgreen: 0x9acd32\n};\n\ndefine(Color, color, {\n displayable: function() {\n return this.rgb().displayable();\n },\n toString: function() {\n return this.rgb() + \"\";\n }\n});\n\nfunction color(format) {\n var m;\n format = (format + \"\").trim().toLowerCase();\n return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00\n : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000\n : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n : named.hasOwnProperty(format) ? rgbn(named[format])\n : format === \"transparent\" ? new Rgb(NaN, NaN, NaN, 0)\n : null;\n}\n\nfunction rgbn(n) {\n return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n if (a <= 0) r = g = b = NaN;\n return new Rgb(r, g, b, a);\n}\n\nfunction rgbConvert(o) {\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Rgb;\n o = o.rgb();\n return new Rgb(o.r, o.g, o.b, o.opacity);\n}\n\nfunction rgb(r, g, b, opacity) {\n return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\n\nfunction Rgb(r, g, b, opacity) {\n this.r = +r;\n this.g = +g;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Rgb, rgb, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n rgb: function() {\n return this;\n },\n displayable: function() {\n return (0 <= this.r && this.r <= 255)\n && (0 <= this.g && this.g <= 255)\n && (0 <= this.b && this.b <= 255)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n toString: function() {\n var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));\n return (a === 1 ? \"rgb(\" : \"rgba(\")\n + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + \", \"\n + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + \", \"\n + Math.max(0, Math.min(255, Math.round(this.b) || 0))\n + (a === 1 ? \")\" : \", \" + a + \")\");\n }\n}));\n\nfunction hsla(h, s, l, a) {\n if (a <= 0) h = s = l = NaN;\n else if (l <= 0 || l >= 1) h = s = NaN;\n else if (s <= 0) h = NaN;\n return new Hsl(h, s, l, a);\n}\n\nfunction hslConvert(o) {\n if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Hsl;\n if (o instanceof Hsl) return o;\n o = o.rgb();\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n h = NaN,\n s = max - min,\n l = (max + min) / 2;\n if (s) {\n if (r === max) h = (g - b) / s + (g < b) * 6;\n else if (g === max) h = (b - r) / s + 2;\n else h = (r - g) / s + 4;\n s /= l < 0.5 ? max + min : 2 - max - min;\n h *= 60;\n } else {\n s = l > 0 && l < 1 ? 0 : h;\n }\n return new Hsl(h, s, l, o.opacity);\n}\n\nfunction hsl(h, s, l, opacity) {\n return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hsl, hsl, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n rgb: function() {\n var h = this.h % 360 + (this.h < 0) * 360,\n s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n l = this.l,\n m2 = l + (l < 0.5 ? l : 1 - l) * s,\n m1 = 2 * l - m2;\n return new Rgb(\n hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),\n hsl2rgb(h, m1, m2),\n hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),\n this.opacity\n );\n },\n displayable: function() {\n return (0 <= this.s && this.s <= 1 || isNaN(this.s))\n && (0 <= this.l && this.l <= 1)\n && (0 <= this.opacity && this.opacity <= 1);\n }\n}));\n\n/* From FvD 13.37, CSS Color Module Level 3 */\nfunction hsl2rgb(h, m1, m2) {\n return (h < 60 ? m1 + (m2 - m1) * h / 60\n : h < 180 ? m2\n : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60\n : m1) * 255;\n}\n\nvar deg2rad = Math.PI / 180;\nvar rad2deg = 180 / Math.PI;\n\nvar Kn = 18;\nvar Xn = 0.950470;\nvar Yn = 1;\nvar Zn = 1.088830;\nvar t0 = 4 / 29;\nvar t1 = 6 / 29;\nvar t2 = 3 * t1 * t1;\nvar t3 = t1 * t1 * t1;\n\nfunction labConvert(o) {\n if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);\n if (o instanceof Hcl) {\n var h = o.h * deg2rad;\n return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);\n }\n if (!(o instanceof Rgb)) o = rgbConvert(o);\n var b = rgb2xyz(o.r),\n a = rgb2xyz(o.g),\n l = rgb2xyz(o.b),\n x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),\n y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),\n z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);\n return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);\n}\n\nfunction lab(l, a, b, opacity) {\n return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);\n}\n\nfunction Lab(l, a, b, opacity) {\n this.l = +l;\n this.a = +a;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Lab, lab, extend(Color, {\n brighter: function(k) {\n return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);\n },\n darker: function(k) {\n return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);\n },\n rgb: function() {\n var y = (this.l + 16) / 116,\n x = isNaN(this.a) ? y : y + this.a / 500,\n z = isNaN(this.b) ? y : y - this.b / 200;\n y = Yn * lab2xyz(y);\n x = Xn * lab2xyz(x);\n z = Zn * lab2xyz(z);\n return new Rgb(\n xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB\n xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),\n xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),\n this.opacity\n );\n }\n}));\n\nfunction xyz2lab(t) {\n return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;\n}\n\nfunction lab2xyz(t) {\n return t > t1 ? t * t * t : t2 * (t - t0);\n}\n\nfunction xyz2rgb(x) {\n return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);\n}\n\nfunction rgb2xyz(x) {\n return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);\n}\n\nfunction hclConvert(o) {\n if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);\n if (!(o instanceof Lab)) o = labConvert(o);\n var h = Math.atan2(o.b, o.a) * rad2deg;\n return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);\n}\n\nfunction hcl(h, c, l, opacity) {\n return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hcl(h, c, l, opacity) {\n this.h = +h;\n this.c = +c;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hcl, hcl, extend(Color, {\n brighter: function(k) {\n return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);\n },\n darker: function(k) {\n return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);\n },\n rgb: function() {\n return labConvert(this).rgb();\n }\n}));\n\nvar A = -0.14861;\nvar B = +1.78277;\nvar C = -0.29227;\nvar D = -0.90649;\nvar E = +1.97294;\nvar ED = E * D;\nvar EB = E * B;\nvar BC_DA = B * C - D * A;\n\nfunction cubehelixConvert(o) {\n if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Rgb)) o = rgbConvert(o);\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),\n bl = b - l,\n k = (E * (g - l) - C * bl) / D,\n s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1\n h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;\n return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);\n}\n\nfunction cubehelix(h, s, l, opacity) {\n return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Cubehelix(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Cubehelix, cubehelix, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n },\n rgb: function() {\n var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,\n l = +this.l,\n a = isNaN(this.s) ? 0 : this.s * l * (1 - l),\n cosh = Math.cos(h),\n sinh = Math.sin(h);\n return new Rgb(\n 255 * (l + a * (A * cosh + B * sinh)),\n 255 * (l + a * (C * cosh + D * sinh)),\n 255 * (l + a * (E * cosh)),\n this.opacity\n );\n }\n}));\n\nfunction basis(t1, v0, v1, v2, v3) {\n var t2 = t1 * t1, t3 = t2 * t1;\n return ((1 - 3 * t1 + 3 * t2 - t3) * v0\n + (4 - 6 * t2 + 3 * t3) * v1\n + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2\n + t3 * v3) / 6;\n}\n\nfunction basis$1(values) {\n var n = values.length - 1;\n return function(t) {\n var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),\n v1 = values[i],\n v2 = values[i + 1],\n v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,\n v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n\nfunction basisClosed(values) {\n var n = values.length;\n return function(t) {\n var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),\n v0 = values[(i + n - 1) % n],\n v1 = values[i % n],\n v2 = values[(i + 1) % n],\n v3 = values[(i + 2) % n];\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n\nfunction constant$3(x) {\n return function() {\n return x;\n };\n}\n\nfunction linear(a, d) {\n return function(t) {\n return a + t * d;\n };\n}\n\nfunction exponential(a, b, y) {\n return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {\n return Math.pow(a + t * b, y);\n };\n}\n\nfunction hue(a, b) {\n var d = b - a;\n return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);\n}\n\nfunction gamma(y) {\n return (y = +y) === 1 ? nogamma : function(a, b) {\n return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);\n };\n}\n\nfunction nogamma(a, b) {\n var d = b - a;\n return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);\n}\n\nvar interpolateRgb = (function rgbGamma(y) {\n var color$$1 = gamma(y);\n\n function rgb$$1(start, end) {\n var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),\n g = color$$1(start.g, end.g),\n b = color$$1(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.r = r(t);\n start.g = g(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n rgb$$1.gamma = rgbGamma;\n\n return rgb$$1;\n})(1);\n\nfunction rgbSpline(spline) {\n return function(colors) {\n var n = colors.length,\n r = new Array(n),\n g = new Array(n),\n b = new Array(n),\n i, color$$1;\n for (i = 0; i < n; ++i) {\n color$$1 = rgb(colors[i]);\n r[i] = color$$1.r || 0;\n g[i] = color$$1.g || 0;\n b[i] = color$$1.b || 0;\n }\n r = spline(r);\n g = spline(g);\n b = spline(b);\n color$$1.opacity = 1;\n return function(t) {\n color$$1.r = r(t);\n color$$1.g = g(t);\n color$$1.b = b(t);\n return color$$1 + \"\";\n };\n };\n}\n\nvar rgbBasis = rgbSpline(basis$1);\nvar rgbBasisClosed = rgbSpline(basisClosed);\n\nfunction array$1(a, b) {\n var nb = b ? b.length : 0,\n na = a ? Math.min(nb, a.length) : 0,\n x = new Array(na),\n c = new Array(nb),\n i;\n\n for (i = 0; i < na; ++i) x[i] = interpolateValue(a[i], b[i]);\n for (; i < nb; ++i) c[i] = b[i];\n\n return function(t) {\n for (i = 0; i < na; ++i) c[i] = x[i](t);\n return c;\n };\n}\n\nfunction date(a, b) {\n var d = new Date;\n return a = +a, b -= a, function(t) {\n return d.setTime(a + b * t), d;\n };\n}\n\nfunction reinterpolate(a, b) {\n return a = +a, b -= a, function(t) {\n return a + b * t;\n };\n}\n\nfunction object(a, b) {\n var i = {},\n c = {},\n k;\n\n if (a === null || typeof a !== \"object\") a = {};\n if (b === null || typeof b !== \"object\") b = {};\n\n for (k in b) {\n if (k in a) {\n i[k] = interpolateValue(a[k], b[k]);\n } else {\n c[k] = b[k];\n }\n }\n\n return function(t) {\n for (k in i) c[k] = i[k](t);\n return c;\n };\n}\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g;\nvar reB = new RegExp(reA.source, \"g\");\n\nfunction zero(b) {\n return function() {\n return b;\n };\n}\n\nfunction one(b) {\n return function(t) {\n return b(t) + \"\";\n };\n}\n\nfunction interpolateString(a, b) {\n var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b\n am, // current match in a\n bm, // current match in b\n bs, // string preceding current number in b, if any\n i = -1, // index in s\n s = [], // string constants and placeholders\n q = []; // number interpolators\n\n // Coerce inputs to strings.\n a = a + \"\", b = b + \"\";\n\n // Interpolate pairs of numbers in a & b.\n while ((am = reA.exec(a))\n && (bm = reB.exec(b))) {\n if ((bs = bm.index) > bi) { // a string precedes the next number in b\n bs = b.slice(bi, bs);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match\n if (s[i]) s[i] += bm; // coalesce with previous string\n else s[++i] = bm;\n } else { // interpolate non-matching numbers\n s[++i] = null;\n q.push({i: i, x: reinterpolate(am, bm)});\n }\n bi = reB.lastIndex;\n }\n\n // Add remains of b.\n if (bi < b.length) {\n bs = b.slice(bi);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n\n // Special optimization for only a single match.\n // Otherwise, interpolate each of the numbers and rejoin the string.\n return s.length < 2 ? (q[0]\n ? one(q[0].x)\n : zero(b))\n : (b = q.length, function(t) {\n for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n });\n}\n\nfunction interpolateValue(a, b) {\n var t = typeof b, c;\n return b == null || t === \"boolean\" ? constant$3(b)\n : (t === \"number\" ? reinterpolate\n : t === \"string\" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString)\n : b instanceof color ? interpolateRgb\n : b instanceof Date ? date\n : Array.isArray(b) ? array$1\n : typeof b.valueOf !== \"function\" && typeof b.toString !== \"function\" || isNaN(b) ? object\n : reinterpolate)(a, b);\n}\n\nfunction interpolateRound(a, b) {\n return a = +a, b -= a, function(t) {\n return Math.round(a + b * t);\n };\n}\n\nvar degrees = 180 / Math.PI;\n\nvar identity$2 = {\n translateX: 0,\n translateY: 0,\n rotate: 0,\n skewX: 0,\n scaleX: 1,\n scaleY: 1\n};\n\nfunction decompose(a, b, c, d, e, f) {\n var scaleX, scaleY, skewX;\n if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;\n if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;\n if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;\n if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;\n return {\n translateX: e,\n translateY: f,\n rotate: Math.atan2(b, a) * degrees,\n skewX: Math.atan(skewX) * degrees,\n scaleX: scaleX,\n scaleY: scaleY\n };\n}\n\nvar cssNode;\nvar cssRoot;\nvar cssView;\nvar svgNode;\n\nfunction parseCss(value) {\n if (value === \"none\") return identity$2;\n if (!cssNode) cssNode = document.createElement(\"DIV\"), cssRoot = document.documentElement, cssView = document.defaultView;\n cssNode.style.transform = value;\n value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue(\"transform\");\n cssRoot.removeChild(cssNode);\n value = value.slice(7, -1).split(\",\");\n return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);\n}\n\nfunction parseSvg(value) {\n if (value == null) return identity$2;\n if (!svgNode) svgNode = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n svgNode.setAttribute(\"transform\", value);\n if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;\n value = value.matrix;\n return decompose(value.a, value.b, value.c, value.d, value.e, value.f);\n}\n\nfunction interpolateTransform(parse, pxComma, pxParen, degParen) {\n\n function pop(s) {\n return s.length ? s.pop() + \" \" : \"\";\n }\n\n function translate(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(\"translate(\", null, pxComma, null, pxParen);\n q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});\n } else if (xb || yb) {\n s.push(\"translate(\" + xb + pxComma + yb + pxParen);\n }\n }\n\n function rotate(a, b, s, q) {\n if (a !== b) {\n if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path\n q.push({i: s.push(pop(s) + \"rotate(\", null, degParen) - 2, x: reinterpolate(a, b)});\n } else if (b) {\n s.push(pop(s) + \"rotate(\" + b + degParen);\n }\n }\n\n function skewX(a, b, s, q) {\n if (a !== b) {\n q.push({i: s.push(pop(s) + \"skewX(\", null, degParen) - 2, x: reinterpolate(a, b)});\n } else if (b) {\n s.push(pop(s) + \"skewX(\" + b + degParen);\n }\n }\n\n function scale(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(pop(s) + \"scale(\", null, \",\", null, \")\");\n q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});\n } else if (xb !== 1 || yb !== 1) {\n s.push(pop(s) + \"scale(\" + xb + \",\" + yb + \")\");\n }\n }\n\n return function(a, b) {\n var s = [], // string constants and placeholders\n q = []; // number interpolators\n a = parse(a), b = parse(b);\n translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);\n rotate(a.rotate, b.rotate, s, q);\n skewX(a.skewX, b.skewX, s, q);\n scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);\n a = b = null; // gc\n return function(t) {\n var i = -1, n = q.length, o;\n while (++i < n) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n };\n };\n}\n\nvar interpolateTransformCss = interpolateTransform(parseCss, \"px, \", \"px)\", \"deg)\");\nvar interpolateTransformSvg = interpolateTransform(parseSvg, \", \", \")\", \")\");\n\nvar rho = Math.SQRT2;\nvar rho2 = 2;\nvar rho4 = 4;\nvar epsilon2 = 1e-12;\n\nfunction cosh(x) {\n return ((x = Math.exp(x)) + 1 / x) / 2;\n}\n\nfunction sinh(x) {\n return ((x = Math.exp(x)) - 1 / x) / 2;\n}\n\nfunction tanh(x) {\n return ((x = Math.exp(2 * x)) - 1) / (x + 1);\n}\n\n// p0 = [ux0, uy0, w0]\n// p1 = [ux1, uy1, w1]\nfunction interpolateZoom(p0, p1) {\n var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],\n ux1 = p1[0], uy1 = p1[1], w1 = p1[2],\n dx = ux1 - ux0,\n dy = uy1 - uy0,\n d2 = dx * dx + dy * dy,\n i,\n S;\n\n // Special case for u0 ≅ u1.\n if (d2 < epsilon2) {\n S = Math.log(w1 / w0) / rho;\n i = function(t) {\n return [\n ux0 + t * dx,\n uy0 + t * dy,\n w0 * Math.exp(rho * t * S)\n ];\n };\n }\n\n // General case.\n else {\n var d1 = Math.sqrt(d2),\n b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),\n b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),\n r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),\n r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);\n S = (r1 - r0) / rho;\n i = function(t) {\n var s = t * S,\n coshr0 = cosh(r0),\n u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));\n return [\n ux0 + u * dx,\n uy0 + u * dy,\n w0 * coshr0 / cosh(rho * s + r0)\n ];\n };\n }\n\n i.duration = S * 1000;\n\n return i;\n}\n\nfunction hsl$1(hue$$1) {\n return function(start, end) {\n var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),\n s = nogamma(start.s, end.s),\n l = nogamma(start.l, end.l),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.s = s(t);\n start.l = l(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n}\n\nvar hsl$2 = hsl$1(hue);\nvar hslLong = hsl$1(nogamma);\n\nfunction lab$1(start, end) {\n var l = nogamma((start = lab(start)).l, (end = lab(end)).l),\n a = nogamma(start.a, end.a),\n b = nogamma(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.l = l(t);\n start.a = a(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n}\n\nfunction hcl$1(hue$$1) {\n return function(start, end) {\n var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),\n c = nogamma(start.c, end.c),\n l = nogamma(start.l, end.l),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.c = c(t);\n start.l = l(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n}\n\nvar hcl$2 = hcl$1(hue);\nvar hclLong = hcl$1(nogamma);\n\nfunction cubehelix$1(hue$$1) {\n return (function cubehelixGamma(y) {\n y = +y;\n\n function cubehelix$$1(start, end) {\n var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),\n s = nogamma(start.s, end.s),\n l = nogamma(start.l, end.l),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.s = s(t);\n start.l = l(Math.pow(t, y));\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n cubehelix$$1.gamma = cubehelixGamma;\n\n return cubehelix$$1;\n })(1);\n}\n\nvar cubehelix$2 = cubehelix$1(hue);\nvar cubehelixLong = cubehelix$1(nogamma);\n\nfunction quantize(interpolator, n) {\n var samples = new Array(n);\n for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));\n return samples;\n}\n\nvar frame = 0;\nvar timeout = 0;\nvar interval = 0;\nvar pokeDelay = 1000;\nvar taskHead;\nvar taskTail;\nvar clockLast = 0;\nvar clockNow = 0;\nvar clockSkew = 0;\nvar clock = typeof performance === \"object\" && performance.now ? performance : Date;\nvar setFrame = typeof window === \"object\" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };\n\nfunction now() {\n return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);\n}\n\nfunction clearNow() {\n clockNow = 0;\n}\n\nfunction Timer() {\n this._call =\n this._time =\n this._next = null;\n}\n\nTimer.prototype = timer.prototype = {\n constructor: Timer,\n restart: function(callback, delay, time) {\n if (typeof callback !== \"function\") throw new TypeError(\"callback is not a function\");\n time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);\n if (!this._next && taskTail !== this) {\n if (taskTail) taskTail._next = this;\n else taskHead = this;\n taskTail = this;\n }\n this._call = callback;\n this._time = time;\n sleep();\n },\n stop: function() {\n if (this._call) {\n this._call = null;\n this._time = Infinity;\n sleep();\n }\n }\n};\n\nfunction timer(callback, delay, time) {\n var t = new Timer;\n t.restart(callback, delay, time);\n return t;\n}\n\nfunction timerFlush() {\n now(); // Get the current time, if not already set.\n ++frame; // Pretend we’ve set an alarm, if we haven’t already.\n var t = taskHead, e;\n while (t) {\n if ((e = clockNow - t._time) >= 0) t._call.call(null, e);\n t = t._next;\n }\n --frame;\n}\n\nfunction wake() {\n clockNow = (clockLast = clock.now()) + clockSkew;\n frame = timeout = 0;\n try {\n timerFlush();\n } finally {\n frame = 0;\n nap();\n clockNow = 0;\n }\n}\n\nfunction poke() {\n var now = clock.now(), delay = now - clockLast;\n if (delay > pokeDelay) clockSkew -= delay, clockLast = now;\n}\n\nfunction nap() {\n var t0, t1 = taskHead, t2, time = Infinity;\n while (t1) {\n if (t1._call) {\n if (time > t1._time) time = t1._time;\n t0 = t1, t1 = t1._next;\n } else {\n t2 = t1._next, t1._next = null;\n t1 = t0 ? t0._next = t2 : taskHead = t2;\n }\n }\n taskTail = t0;\n sleep(time);\n}\n\nfunction sleep(time) {\n if (frame) return; // Soonest alarm already set, or will be.\n if (timeout) timeout = clearTimeout(timeout);\n var delay = time - clockNow; // Strictly less than if we recomputed clockNow.\n if (delay > 24) {\n if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);\n if (interval) interval = clearInterval(interval);\n } else {\n if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);\n frame = 1, setFrame(wake);\n }\n}\n\nfunction timeout$1(callback, delay, time) {\n var t = new Timer;\n delay = delay == null ? 0 : +delay;\n t.restart(function(elapsed) {\n t.stop();\n callback(elapsed + delay);\n }, delay, time);\n return t;\n}\n\nfunction interval$1(callback, delay, time) {\n var t = new Timer, total = delay;\n if (delay == null) return t.restart(callback, delay, time), t;\n delay = +delay, time = time == null ? now() : +time;\n t.restart(function tick(elapsed) {\n elapsed += total;\n t.restart(tick, total += delay, time);\n callback(elapsed);\n }, delay, time);\n return t;\n}\n\nvar emptyOn = dispatch(\"start\", \"end\", \"interrupt\");\nvar emptyTween = [];\n\nvar CREATED = 0;\nvar SCHEDULED = 1;\nvar STARTING = 2;\nvar STARTED = 3;\nvar RUNNING = 4;\nvar ENDING = 5;\nvar ENDED = 6;\n\nfunction schedule(node, name, id, index, group, timing) {\n var schedules = node.__transition;\n if (!schedules) node.__transition = {};\n else if (id in schedules) return;\n create$1(node, id, {\n name: name,\n index: index, // For context during callback.\n group: group, // For context during callback.\n on: emptyOn,\n tween: emptyTween,\n time: timing.time,\n delay: timing.delay,\n duration: timing.duration,\n ease: timing.ease,\n timer: null,\n state: CREATED\n });\n}\n\nfunction init(node, id) {\n var schedule = get$1(node, id);\n if (schedule.state > CREATED) throw new Error(\"too late; already scheduled\");\n return schedule;\n}\n\nfunction set$1(node, id) {\n var schedule = get$1(node, id);\n if (schedule.state > STARTING) throw new Error(\"too late; already started\");\n return schedule;\n}\n\nfunction get$1(node, id) {\n var schedule = node.__transition;\n if (!schedule || !(schedule = schedule[id])) throw new Error(\"transition not found\");\n return schedule;\n}\n\nfunction create$1(node, id, self) {\n var schedules = node.__transition,\n tween;\n\n // Initialize the self timer when the transition is created.\n // Note the actual delay is not known until the first callback!\n schedules[id] = self;\n self.timer = timer(schedule, 0, self.time);\n\n function schedule(elapsed) {\n self.state = SCHEDULED;\n self.timer.restart(start, self.delay, self.time);\n\n // If the elapsed delay is less than our first sleep, start immediately.\n if (self.delay <= elapsed) start(elapsed - self.delay);\n }\n\n function start(elapsed) {\n var i, j, n, o;\n\n // If the state is not SCHEDULED, then we previously errored on start.\n if (self.state !== SCHEDULED) return stop();\n\n for (i in schedules) {\n o = schedules[i];\n if (o.name !== self.name) continue;\n\n // While this element already has a starting transition during this frame,\n // defer starting an interrupting transition until that transition has a\n // chance to tick (and possibly end); see d3/d3-transition#54!\n if (o.state === STARTED) return timeout$1(start);\n\n // Interrupt the active transition, if any.\n // Dispatch the interrupt event.\n if (o.state === RUNNING) {\n o.state = ENDED;\n o.timer.stop();\n o.on.call(\"interrupt\", node, node.__data__, o.index, o.group);\n delete schedules[i];\n }\n\n // Cancel any pre-empted transitions. No interrupt event is dispatched\n // because the cancelled transitions never started. Note that this also\n // removes this transition from the pending list!\n else if (+i < id) {\n o.state = ENDED;\n o.timer.stop();\n delete schedules[i];\n }\n }\n\n // Defer the first tick to end of the current frame; see d3/d3#1576.\n // Note the transition may be canceled after start and before the first tick!\n // Note this must be scheduled before the start event; see d3/d3-transition#16!\n // Assuming this is successful, subsequent callbacks go straight to tick.\n timeout$1(function() {\n if (self.state === STARTED) {\n self.state = RUNNING;\n self.timer.restart(tick, self.delay, self.time);\n tick(elapsed);\n }\n });\n\n // Dispatch the start event.\n // Note this must be done before the tween are initialized.\n self.state = STARTING;\n self.on.call(\"start\", node, node.__data__, self.index, self.group);\n if (self.state !== STARTING) return; // interrupted\n self.state = STARTED;\n\n // Initialize the tween, deleting null tween.\n tween = new Array(n = self.tween.length);\n for (i = 0, j = -1; i < n; ++i) {\n if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {\n tween[++j] = o;\n }\n }\n tween.length = j + 1;\n }\n\n function tick(elapsed) {\n var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),\n i = -1,\n n = tween.length;\n\n while (++i < n) {\n tween[i].call(null, t);\n }\n\n // Dispatch the end event.\n if (self.state === ENDING) {\n self.on.call(\"end\", node, node.__data__, self.index, self.group);\n stop();\n }\n }\n\n function stop() {\n self.state = ENDED;\n self.timer.stop();\n delete schedules[id];\n for (var i in schedules) return; // eslint-disable-line no-unused-vars\n delete node.__transition;\n }\n}\n\nfunction interrupt(node, name) {\n var schedules = node.__transition,\n schedule$$1,\n active,\n empty = true,\n i;\n\n if (!schedules) return;\n\n name = name == null ? null : name + \"\";\n\n for (i in schedules) {\n if ((schedule$$1 = schedules[i]).name !== name) { empty = false; continue; }\n active = schedule$$1.state > STARTING && schedule$$1.state < ENDING;\n schedule$$1.state = ENDED;\n schedule$$1.timer.stop();\n if (active) schedule$$1.on.call(\"interrupt\", node, node.__data__, schedule$$1.index, schedule$$1.group);\n delete schedules[i];\n }\n\n if (empty) delete node.__transition;\n}\n\nfunction selection_interrupt(name) {\n return this.each(function() {\n interrupt(this, name);\n });\n}\n\nfunction tweenRemove(id, name) {\n var tween0, tween1;\n return function() {\n var schedule$$1 = set$1(this, id),\n tween = schedule$$1.tween;\n\n // If this node shared tween with the previous node,\n // just assign the updated shared tween and we’re done!\n // Otherwise, copy-on-write.\n if (tween !== tween0) {\n tween1 = tween0 = tween;\n for (var i = 0, n = tween1.length; i < n; ++i) {\n if (tween1[i].name === name) {\n tween1 = tween1.slice();\n tween1.splice(i, 1);\n break;\n }\n }\n }\n\n schedule$$1.tween = tween1;\n };\n}\n\nfunction tweenFunction(id, name, value) {\n var tween0, tween1;\n if (typeof value !== \"function\") throw new Error;\n return function() {\n var schedule$$1 = set$1(this, id),\n tween = schedule$$1.tween;\n\n // If this node shared tween with the previous node,\n // just assign the updated shared tween and we’re done!\n // Otherwise, copy-on-write.\n if (tween !== tween0) {\n tween1 = (tween0 = tween).slice();\n for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {\n if (tween1[i].name === name) {\n tween1[i] = t;\n break;\n }\n }\n if (i === n) tween1.push(t);\n }\n\n schedule$$1.tween = tween1;\n };\n}\n\nfunction transition_tween(name, value) {\n var id = this._id;\n\n name += \"\";\n\n if (arguments.length < 2) {\n var tween = get$1(this.node(), id).tween;\n for (var i = 0, n = tween.length, t; i < n; ++i) {\n if ((t = tween[i]).name === name) {\n return t.value;\n }\n }\n return null;\n }\n\n return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));\n}\n\nfunction tweenValue(transition, name, value) {\n var id = transition._id;\n\n transition.each(function() {\n var schedule$$1 = set$1(this, id);\n (schedule$$1.value || (schedule$$1.value = {}))[name] = value.apply(this, arguments);\n });\n\n return function(node) {\n return get$1(node, id).value[name];\n };\n}\n\nfunction interpolate(a, b) {\n var c;\n return (typeof b === \"number\" ? reinterpolate\n : b instanceof color ? interpolateRgb\n : (c = color(b)) ? (b = c, interpolateRgb)\n : interpolateString)(a, b);\n}\n\nfunction attrRemove$1(name) {\n return function() {\n this.removeAttribute(name);\n };\n}\n\nfunction attrRemoveNS$1(fullname) {\n return function() {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attrConstant$1(name, interpolate$$1, value1) {\n var value00,\n interpolate0;\n return function() {\n var value0 = this.getAttribute(name);\n return value0 === value1 ? null\n : value0 === value00 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value1);\n };\n}\n\nfunction attrConstantNS$1(fullname, interpolate$$1, value1) {\n var value00,\n interpolate0;\n return function() {\n var value0 = this.getAttributeNS(fullname.space, fullname.local);\n return value0 === value1 ? null\n : value0 === value00 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value1);\n };\n}\n\nfunction attrFunction$1(name, interpolate$$1, value) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0, value1 = value(this);\n if (value1 == null) return void this.removeAttribute(name);\n value0 = this.getAttribute(name);\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n };\n}\n\nfunction attrFunctionNS$1(fullname, interpolate$$1, value) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0, value1 = value(this);\n if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);\n value0 = this.getAttributeNS(fullname.space, fullname.local);\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n };\n}\n\nfunction transition_attr(name, value) {\n var fullname = namespace(name), i = fullname === \"transform\" ? interpolateTransformSvg : interpolate;\n return this.attrTween(name, typeof value === \"function\"\n ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, \"attr.\" + name, value))\n : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)\n : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + \"\"));\n}\n\nfunction attrTweenNS(fullname, value) {\n function tween() {\n var node = this, i = value.apply(node, arguments);\n return i && function(t) {\n node.setAttributeNS(fullname.space, fullname.local, i(t));\n };\n }\n tween._value = value;\n return tween;\n}\n\nfunction attrTween(name, value) {\n function tween() {\n var node = this, i = value.apply(node, arguments);\n return i && function(t) {\n node.setAttribute(name, i(t));\n };\n }\n tween._value = value;\n return tween;\n}\n\nfunction transition_attrTween(name, value) {\n var key = \"attr.\" + name;\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== \"function\") throw new Error;\n var fullname = namespace(name);\n return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));\n}\n\nfunction delayFunction(id, value) {\n return function() {\n init(this, id).delay = +value.apply(this, arguments);\n };\n}\n\nfunction delayConstant(id, value) {\n return value = +value, function() {\n init(this, id).delay = value;\n };\n}\n\nfunction transition_delay(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each((typeof value === \"function\"\n ? delayFunction\n : delayConstant)(id, value))\n : get$1(this.node(), id).delay;\n}\n\nfunction durationFunction(id, value) {\n return function() {\n set$1(this, id).duration = +value.apply(this, arguments);\n };\n}\n\nfunction durationConstant(id, value) {\n return value = +value, function() {\n set$1(this, id).duration = value;\n };\n}\n\nfunction transition_duration(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each((typeof value === \"function\"\n ? durationFunction\n : durationConstant)(id, value))\n : get$1(this.node(), id).duration;\n}\n\nfunction easeConstant(id, value) {\n if (typeof value !== \"function\") throw new Error;\n return function() {\n set$1(this, id).ease = value;\n };\n}\n\nfunction transition_ease(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each(easeConstant(id, value))\n : get$1(this.node(), id).ease;\n}\n\nfunction transition_filter(match) {\n if (typeof match !== \"function\") match = matcher$1(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Transition(subgroups, this._parents, this._name, this._id);\n}\n\nfunction transition_merge(transition$$1) {\n if (transition$$1._id !== this._id) throw new Error;\n\n for (var groups0 = this._groups, groups1 = transition$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Transition(merges, this._parents, this._name, this._id);\n}\n\nfunction start(name) {\n return (name + \"\").trim().split(/^|\\s+/).every(function(t) {\n var i = t.indexOf(\".\");\n if (i >= 0) t = t.slice(0, i);\n return !t || t === \"start\";\n });\n}\n\nfunction onFunction(id, name, listener) {\n var on0, on1, sit = start(name) ? init : set$1;\n return function() {\n var schedule$$1 = sit(this, id),\n on = schedule$$1.on;\n\n // If this node shared a dispatch with the previous node,\n // just assign the updated shared dispatch and we’re done!\n // Otherwise, copy-on-write.\n if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);\n\n schedule$$1.on = on1;\n };\n}\n\nfunction transition_on(name, listener) {\n var id = this._id;\n\n return arguments.length < 2\n ? get$1(this.node(), id).on.on(name)\n : this.each(onFunction(id, name, listener));\n}\n\nfunction removeFunction(id) {\n return function() {\n var parent = this.parentNode;\n for (var i in this.__transition) if (+i !== id) return;\n if (parent) parent.removeChild(this);\n };\n}\n\nfunction transition_remove() {\n return this.on(\"end.remove\", removeFunction(this._id));\n}\n\nfunction transition_select(select) {\n var name = this._name,\n id = this._id;\n\n if (typeof select !== \"function\") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if (\"__data__\" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));\n }\n }\n }\n\n return new Transition(subgroups, this._parents, name, id);\n}\n\nfunction transition_selectAll(select) {\n var name = this._name,\n id = this._id;\n\n if (typeof select !== \"function\") select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n for (var children = select.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) {\n if (child = children[k]) {\n schedule(child, name, id, k, children, inherit);\n }\n }\n subgroups.push(children);\n parents.push(node);\n }\n }\n }\n\n return new Transition(subgroups, parents, name, id);\n}\n\nvar Selection$1 = selection.prototype.constructor;\n\nfunction transition_selection() {\n return new Selection$1(this._groups, this._parents);\n}\n\nfunction styleRemove$1(name, interpolate$$1) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0 = styleValue(this, name),\n value1 = (this.style.removeProperty(name), styleValue(this, name));\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n };\n}\n\nfunction styleRemoveEnd(name) {\n return function() {\n this.style.removeProperty(name);\n };\n}\n\nfunction styleConstant$1(name, interpolate$$1, value1) {\n var value00,\n interpolate0;\n return function() {\n var value0 = styleValue(this, name);\n return value0 === value1 ? null\n : value0 === value00 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value1);\n };\n}\n\nfunction styleFunction$1(name, interpolate$$1, value) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0 = styleValue(this, name),\n value1 = value(this);\n if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name));\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n };\n}\n\nfunction transition_style(name, value, priority) {\n var i = (name += \"\") === \"transform\" ? interpolateTransformCss : interpolate;\n return value == null ? this\n .styleTween(name, styleRemove$1(name, i))\n .on(\"end.style.\" + name, styleRemoveEnd(name))\n : this.styleTween(name, typeof value === \"function\"\n ? styleFunction$1(name, i, tweenValue(this, \"style.\" + name, value))\n : styleConstant$1(name, i, value + \"\"), priority);\n}\n\nfunction styleTween(name, value, priority) {\n function tween() {\n var node = this, i = value.apply(node, arguments);\n return i && function(t) {\n node.style.setProperty(name, i(t), priority);\n };\n }\n tween._value = value;\n return tween;\n}\n\nfunction transition_styleTween(name, value, priority) {\n var key = \"style.\" + (name += \"\");\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== \"function\") throw new Error;\n return this.tween(key, styleTween(name, value, priority == null ? \"\" : priority));\n}\n\nfunction textConstant$1(value) {\n return function() {\n this.textContent = value;\n };\n}\n\nfunction textFunction$1(value) {\n return function() {\n var value1 = value(this);\n this.textContent = value1 == null ? \"\" : value1;\n };\n}\n\nfunction transition_text(value) {\n return this.tween(\"text\", typeof value === \"function\"\n ? textFunction$1(tweenValue(this, \"text\", value))\n : textConstant$1(value == null ? \"\" : value + \"\"));\n}\n\nfunction transition_transition() {\n var name = this._name,\n id0 = this._id,\n id1 = newId();\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n var inherit = get$1(node, id0);\n schedule(node, name, id1, i, group, {\n time: inherit.time + inherit.delay + inherit.duration,\n delay: 0,\n duration: inherit.duration,\n ease: inherit.ease\n });\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id1);\n}\n\nvar id = 0;\n\nfunction Transition(groups, parents, name, id) {\n this._groups = groups;\n this._parents = parents;\n this._name = name;\n this._id = id;\n}\n\nfunction transition(name) {\n return selection().transition(name);\n}\n\nfunction newId() {\n return ++id;\n}\n\nvar selection_prototype = selection.prototype;\n\nTransition.prototype = transition.prototype = {\n constructor: Transition,\n select: transition_select,\n selectAll: transition_selectAll,\n filter: transition_filter,\n merge: transition_merge,\n selection: transition_selection,\n transition: transition_transition,\n call: selection_prototype.call,\n nodes: selection_prototype.nodes,\n node: selection_prototype.node,\n size: selection_prototype.size,\n empty: selection_prototype.empty,\n each: selection_prototype.each,\n on: transition_on,\n attr: transition_attr,\n attrTween: transition_attrTween,\n style: transition_style,\n styleTween: transition_styleTween,\n text: transition_text,\n remove: transition_remove,\n tween: transition_tween,\n delay: transition_delay,\n duration: transition_duration,\n ease: transition_ease\n};\n\nfunction linear$1(t) {\n return +t;\n}\n\nfunction quadIn(t) {\n return t * t;\n}\n\nfunction quadOut(t) {\n return t * (2 - t);\n}\n\nfunction quadInOut(t) {\n return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;\n}\n\nfunction cubicIn(t) {\n return t * t * t;\n}\n\nfunction cubicOut(t) {\n return --t * t * t + 1;\n}\n\nfunction cubicInOut(t) {\n return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;\n}\n\nvar exponent = 3;\n\nvar polyIn = (function custom(e) {\n e = +e;\n\n function polyIn(t) {\n return Math.pow(t, e);\n }\n\n polyIn.exponent = custom;\n\n return polyIn;\n})(exponent);\n\nvar polyOut = (function custom(e) {\n e = +e;\n\n function polyOut(t) {\n return 1 - Math.pow(1 - t, e);\n }\n\n polyOut.exponent = custom;\n\n return polyOut;\n})(exponent);\n\nvar polyInOut = (function custom(e) {\n e = +e;\n\n function polyInOut(t) {\n return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;\n }\n\n polyInOut.exponent = custom;\n\n return polyInOut;\n})(exponent);\n\nvar pi = Math.PI;\nvar halfPi = pi / 2;\n\nfunction sinIn(t) {\n return 1 - Math.cos(t * halfPi);\n}\n\nfunction sinOut(t) {\n return Math.sin(t * halfPi);\n}\n\nfunction sinInOut(t) {\n return (1 - Math.cos(pi * t)) / 2;\n}\n\nfunction expIn(t) {\n return Math.pow(2, 10 * t - 10);\n}\n\nfunction expOut(t) {\n return 1 - Math.pow(2, -10 * t);\n}\n\nfunction expInOut(t) {\n return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;\n}\n\nfunction circleIn(t) {\n return 1 - Math.sqrt(1 - t * t);\n}\n\nfunction circleOut(t) {\n return Math.sqrt(1 - --t * t);\n}\n\nfunction circleInOut(t) {\n return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;\n}\n\nvar b1 = 4 / 11;\nvar b2 = 6 / 11;\nvar b3 = 8 / 11;\nvar b4 = 3 / 4;\nvar b5 = 9 / 11;\nvar b6 = 10 / 11;\nvar b7 = 15 / 16;\nvar b8 = 21 / 22;\nvar b9 = 63 / 64;\nvar b0 = 1 / b1 / b1;\n\nfunction bounceIn(t) {\n return 1 - bounceOut(1 - t);\n}\n\nfunction bounceOut(t) {\n return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;\n}\n\nfunction bounceInOut(t) {\n return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;\n}\n\nvar overshoot = 1.70158;\n\nvar backIn = (function custom(s) {\n s = +s;\n\n function backIn(t) {\n return t * t * ((s + 1) * t - s);\n }\n\n backIn.overshoot = custom;\n\n return backIn;\n})(overshoot);\n\nvar backOut = (function custom(s) {\n s = +s;\n\n function backOut(t) {\n return --t * t * ((s + 1) * t + s) + 1;\n }\n\n backOut.overshoot = custom;\n\n return backOut;\n})(overshoot);\n\nvar backInOut = (function custom(s) {\n s = +s;\n\n function backInOut(t) {\n return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;\n }\n\n backInOut.overshoot = custom;\n\n return backInOut;\n})(overshoot);\n\nvar tau = 2 * Math.PI;\nvar amplitude = 1;\nvar period = 0.3;\n\nvar elasticIn = (function custom(a, p) {\n var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n function elasticIn(t) {\n return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);\n }\n\n elasticIn.amplitude = function(a) { return custom(a, p * tau); };\n elasticIn.period = function(p) { return custom(a, p); };\n\n return elasticIn;\n})(amplitude, period);\n\nvar elasticOut = (function custom(a, p) {\n var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n function elasticOut(t) {\n return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);\n }\n\n elasticOut.amplitude = function(a) { return custom(a, p * tau); };\n elasticOut.period = function(p) { return custom(a, p); };\n\n return elasticOut;\n})(amplitude, period);\n\nvar elasticInOut = (function custom(a, p) {\n var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n function elasticInOut(t) {\n return ((t = t * 2 - 1) < 0\n ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)\n : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;\n }\n\n elasticInOut.amplitude = function(a) { return custom(a, p * tau); };\n elasticInOut.period = function(p) { return custom(a, p); };\n\n return elasticInOut;\n})(amplitude, period);\n\nvar defaultTiming = {\n time: null, // Set on use.\n delay: 0,\n duration: 250,\n ease: cubicInOut\n};\n\nfunction inherit(node, id) {\n var timing;\n while (!(timing = node.__transition) || !(timing = timing[id])) {\n if (!(node = node.parentNode)) {\n return defaultTiming.time = now(), defaultTiming;\n }\n }\n return timing;\n}\n\nfunction selection_transition(name) {\n var id,\n timing;\n\n if (name instanceof Transition) {\n id = name._id, name = name._name;\n } else {\n id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + \"\";\n }\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n schedule(node, name, id, i, group, timing || inherit(node, id));\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id);\n}\n\nselection.prototype.interrupt = selection_interrupt;\nselection.prototype.transition = selection_transition;\n\nvar root$1 = [null];\n\nfunction active(node, name) {\n var schedules = node.__transition,\n schedule$$1,\n i;\n\n if (schedules) {\n name = name == null ? null : name + \"\";\n for (i in schedules) {\n if ((schedule$$1 = schedules[i]).state > SCHEDULED && schedule$$1.name === name) {\n return new Transition([[node]], root$1, name, +i);\n }\n }\n }\n\n return null;\n}\n\nfunction constant$4(x) {\n return function() {\n return x;\n };\n}\n\nfunction BrushEvent(target, type, selection) {\n this.target = target;\n this.type = type;\n this.selection = selection;\n}\n\nfunction nopropagation$1() {\n exports.event.stopImmediatePropagation();\n}\n\nfunction noevent$1() {\n exports.event.preventDefault();\n exports.event.stopImmediatePropagation();\n}\n\nvar MODE_DRAG = {name: \"drag\"};\nvar MODE_SPACE = {name: \"space\"};\nvar MODE_HANDLE = {name: \"handle\"};\nvar MODE_CENTER = {name: \"center\"};\n\nvar X = {\n name: \"x\",\n handles: [\"e\", \"w\"].map(type),\n input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },\n output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }\n};\n\nvar Y = {\n name: \"y\",\n handles: [\"n\", \"s\"].map(type),\n input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },\n output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }\n};\n\nvar XY = {\n name: \"xy\",\n handles: [\"n\", \"e\", \"s\", \"w\", \"nw\", \"ne\", \"se\", \"sw\"].map(type),\n input: function(xy) { return xy; },\n output: function(xy) { return xy; }\n};\n\nvar cursors = {\n overlay: \"crosshair\",\n selection: \"move\",\n n: \"ns-resize\",\n e: \"ew-resize\",\n s: \"ns-resize\",\n w: \"ew-resize\",\n nw: \"nwse-resize\",\n ne: \"nesw-resize\",\n se: \"nwse-resize\",\n sw: \"nesw-resize\"\n};\n\nvar flipX = {\n e: \"w\",\n w: \"e\",\n nw: \"ne\",\n ne: \"nw\",\n se: \"sw\",\n sw: \"se\"\n};\n\nvar flipY = {\n n: \"s\",\n s: \"n\",\n nw: \"sw\",\n ne: \"se\",\n se: \"ne\",\n sw: \"nw\"\n};\n\nvar signsX = {\n overlay: +1,\n selection: +1,\n n: null,\n e: +1,\n s: null,\n w: -1,\n nw: -1,\n ne: +1,\n se: +1,\n sw: -1\n};\n\nvar signsY = {\n overlay: +1,\n selection: +1,\n n: -1,\n e: null,\n s: +1,\n w: null,\n nw: -1,\n ne: -1,\n se: +1,\n sw: +1\n};\n\nfunction type(t) {\n return {type: t};\n}\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter() {\n return !exports.event.button;\n}\n\nfunction defaultExtent() {\n var svg = this.ownerSVGElement || this;\n return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];\n}\n\n// Like d3.local, but with the name “__brush” rather than auto-generated.\nfunction local(node) {\n while (!node.__brush) if (!(node = node.parentNode)) return;\n return node.__brush;\n}\n\nfunction empty(extent) {\n return extent[0][0] === extent[1][0]\n || extent[0][1] === extent[1][1];\n}\n\nfunction brushSelection(node) {\n var state = node.__brush;\n return state ? state.dim.output(state.selection) : null;\n}\n\nfunction brushX() {\n return brush$1(X);\n}\n\nfunction brushY() {\n return brush$1(Y);\n}\n\nfunction brush() {\n return brush$1(XY);\n}\n\nfunction brush$1(dim) {\n var extent = defaultExtent,\n filter = defaultFilter,\n listeners = dispatch(brush, \"start\", \"brush\", \"end\"),\n handleSize = 6,\n touchending;\n\n function brush(group) {\n var overlay = group\n .property(\"__brush\", initialize)\n .selectAll(\".overlay\")\n .data([type(\"overlay\")]);\n\n overlay.enter().append(\"rect\")\n .attr(\"class\", \"overlay\")\n .attr(\"pointer-events\", \"all\")\n .attr(\"cursor\", cursors.overlay)\n .merge(overlay)\n .each(function() {\n var extent = local(this).extent;\n select(this)\n .attr(\"x\", extent[0][0])\n .attr(\"y\", extent[0][1])\n .attr(\"width\", extent[1][0] - extent[0][0])\n .attr(\"height\", extent[1][1] - extent[0][1]);\n });\n\n group.selectAll(\".selection\")\n .data([type(\"selection\")])\n .enter().append(\"rect\")\n .attr(\"class\", \"selection\")\n .attr(\"cursor\", cursors.selection)\n .attr(\"fill\", \"#777\")\n .attr(\"fill-opacity\", 0.3)\n .attr(\"stroke\", \"#fff\")\n .attr(\"shape-rendering\", \"crispEdges\");\n\n var handle = group.selectAll(\".handle\")\n .data(dim.handles, function(d) { return d.type; });\n\n handle.exit().remove();\n\n handle.enter().append(\"rect\")\n .attr(\"class\", function(d) { return \"handle handle--\" + d.type; })\n .attr(\"cursor\", function(d) { return cursors[d.type]; });\n\n group\n .each(redraw)\n .attr(\"fill\", \"none\")\n .attr(\"pointer-events\", \"all\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\")\n .on(\"mousedown.brush touchstart.brush\", started);\n }\n\n brush.move = function(group, selection) {\n if (group.selection) {\n group\n .on(\"start.brush\", function() { emitter(this, arguments).beforestart().start(); })\n .on(\"interrupt.brush end.brush\", function() { emitter(this, arguments).end(); })\n .tween(\"brush\", function() {\n var that = this,\n state = that.__brush,\n emit = emitter(that, arguments),\n selection0 = state.selection,\n selection1 = dim.input(typeof selection === \"function\" ? selection.apply(this, arguments) : selection, state.extent),\n i = interpolateValue(selection0, selection1);\n\n function tween(t) {\n state.selection = t === 1 && empty(selection1) ? null : i(t);\n redraw.call(that);\n emit.brush();\n }\n\n return selection0 && selection1 ? tween : tween(1);\n });\n } else {\n group\n .each(function() {\n var that = this,\n args = arguments,\n state = that.__brush,\n selection1 = dim.input(typeof selection === \"function\" ? selection.apply(that, args) : selection, state.extent),\n emit = emitter(that, args).beforestart();\n\n interrupt(that);\n state.selection = selection1 == null || empty(selection1) ? null : selection1;\n redraw.call(that);\n emit.start().brush().end();\n });\n }\n };\n\n function redraw() {\n var group = select(this),\n selection = local(this).selection;\n\n if (selection) {\n group.selectAll(\".selection\")\n .style(\"display\", null)\n .attr(\"x\", selection[0][0])\n .attr(\"y\", selection[0][1])\n .attr(\"width\", selection[1][0] - selection[0][0])\n .attr(\"height\", selection[1][1] - selection[0][1]);\n\n group.selectAll(\".handle\")\n .style(\"display\", null)\n .attr(\"x\", function(d) { return d.type[d.type.length - 1] === \"e\" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })\n .attr(\"y\", function(d) { return d.type[0] === \"s\" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })\n .attr(\"width\", function(d) { return d.type === \"n\" || d.type === \"s\" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })\n .attr(\"height\", function(d) { return d.type === \"e\" || d.type === \"w\" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });\n }\n\n else {\n group.selectAll(\".selection,.handle\")\n .style(\"display\", \"none\")\n .attr(\"x\", null)\n .attr(\"y\", null)\n .attr(\"width\", null)\n .attr(\"height\", null);\n }\n }\n\n function emitter(that, args) {\n return that.__brush.emitter || new Emitter(that, args);\n }\n\n function Emitter(that, args) {\n this.that = that;\n this.args = args;\n this.state = that.__brush;\n this.active = 0;\n }\n\n Emitter.prototype = {\n beforestart: function() {\n if (++this.active === 1) this.state.emitter = this, this.starting = true;\n return this;\n },\n start: function() {\n if (this.starting) this.starting = false, this.emit(\"start\");\n return this;\n },\n brush: function() {\n this.emit(\"brush\");\n return this;\n },\n end: function() {\n if (--this.active === 0) delete this.state.emitter, this.emit(\"end\");\n return this;\n },\n emit: function(type) {\n customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);\n }\n };\n\n function started() {\n if (exports.event.touches) { if (exports.event.changedTouches.length < exports.event.touches.length) return noevent$1(); }\n else if (touchending) return;\n if (!filter.apply(this, arguments)) return;\n\n var that = this,\n type = exports.event.target.__data__.type,\n mode = (exports.event.metaKey ? type = \"overlay\" : type) === \"selection\" ? MODE_DRAG : (exports.event.altKey ? MODE_CENTER : MODE_HANDLE),\n signX = dim === Y ? null : signsX[type],\n signY = dim === X ? null : signsY[type],\n state = local(that),\n extent = state.extent,\n selection = state.selection,\n W = extent[0][0], w0, w1,\n N = extent[0][1], n0, n1,\n E = extent[1][0], e0, e1,\n S = extent[1][1], s0, s1,\n dx,\n dy,\n moving,\n shifting = signX && signY && exports.event.shiftKey,\n lockX,\n lockY,\n point0 = mouse(that),\n point = point0,\n emit = emitter(that, arguments).beforestart();\n\n if (type === \"overlay\") {\n state.selection = selection = [\n [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],\n [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]\n ];\n } else {\n w0 = selection[0][0];\n n0 = selection[0][1];\n e0 = selection[1][0];\n s0 = selection[1][1];\n }\n\n w1 = w0;\n n1 = n0;\n e1 = e0;\n s1 = s0;\n\n var group = select(that)\n .attr(\"pointer-events\", \"none\");\n\n var overlay = group.selectAll(\".overlay\")\n .attr(\"cursor\", cursors[type]);\n\n if (exports.event.touches) {\n group\n .on(\"touchmove.brush\", moved, true)\n .on(\"touchend.brush touchcancel.brush\", ended, true);\n } else {\n var view = select(exports.event.view)\n .on(\"keydown.brush\", keydowned, true)\n .on(\"keyup.brush\", keyupped, true)\n .on(\"mousemove.brush\", moved, true)\n .on(\"mouseup.brush\", ended, true);\n\n dragDisable(exports.event.view);\n }\n\n nopropagation$1();\n interrupt(that);\n redraw.call(that);\n emit.start();\n\n function moved() {\n var point1 = mouse(that);\n if (shifting && !lockX && !lockY) {\n if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;\n else lockX = true;\n }\n point = point1;\n moving = true;\n noevent$1();\n move();\n }\n\n function move() {\n var t;\n\n dx = point[0] - point0[0];\n dy = point[1] - point0[1];\n\n switch (mode) {\n case MODE_SPACE:\n case MODE_DRAG: {\n if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;\n if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;\n break;\n }\n case MODE_HANDLE: {\n if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;\n else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;\n if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;\n else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;\n break;\n }\n case MODE_CENTER: {\n if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));\n if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));\n break;\n }\n }\n\n if (e1 < w1) {\n signX *= -1;\n t = w0, w0 = e0, e0 = t;\n t = w1, w1 = e1, e1 = t;\n if (type in flipX) overlay.attr(\"cursor\", cursors[type = flipX[type]]);\n }\n\n if (s1 < n1) {\n signY *= -1;\n t = n0, n0 = s0, s0 = t;\n t = n1, n1 = s1, s1 = t;\n if (type in flipY) overlay.attr(\"cursor\", cursors[type = flipY[type]]);\n }\n\n if (state.selection) selection = state.selection; // May be set by brush.move!\n if (lockX) w1 = selection[0][0], e1 = selection[1][0];\n if (lockY) n1 = selection[0][1], s1 = selection[1][1];\n\n if (selection[0][0] !== w1\n || selection[0][1] !== n1\n || selection[1][0] !== e1\n || selection[1][1] !== s1) {\n state.selection = [[w1, n1], [e1, s1]];\n redraw.call(that);\n emit.brush();\n }\n }\n\n function ended() {\n nopropagation$1();\n if (exports.event.touches) {\n if (exports.event.touches.length) return;\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n group.on(\"touchmove.brush touchend.brush touchcancel.brush\", null);\n } else {\n yesdrag(exports.event.view, moving);\n view.on(\"keydown.brush keyup.brush mousemove.brush mouseup.brush\", null);\n }\n group.attr(\"pointer-events\", \"all\");\n overlay.attr(\"cursor\", cursors.overlay);\n if (state.selection) selection = state.selection; // May be set by brush.move (on start)!\n if (empty(selection)) state.selection = null, redraw.call(that);\n emit.end();\n }\n\n function keydowned() {\n switch (exports.event.keyCode) {\n case 16: { // SHIFT\n shifting = signX && signY;\n break;\n }\n case 18: { // ALT\n if (mode === MODE_HANDLE) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n move();\n }\n break;\n }\n case 32: { // SPACE; takes priority over ALT\n if (mode === MODE_HANDLE || mode === MODE_CENTER) {\n if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;\n if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;\n mode = MODE_SPACE;\n overlay.attr(\"cursor\", cursors.selection);\n move();\n }\n break;\n }\n default: return;\n }\n noevent$1();\n }\n\n function keyupped() {\n switch (exports.event.keyCode) {\n case 16: { // SHIFT\n if (shifting) {\n lockX = lockY = shifting = false;\n move();\n }\n break;\n }\n case 18: { // ALT\n if (mode === MODE_CENTER) {\n if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n move();\n }\n break;\n }\n case 32: { // SPACE\n if (mode === MODE_SPACE) {\n if (exports.event.altKey) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n } else {\n if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n }\n overlay.attr(\"cursor\", cursors[type]);\n move();\n }\n break;\n }\n default: return;\n }\n noevent$1();\n }\n }\n\n function initialize() {\n var state = this.__brush || {selection: null};\n state.extent = extent.apply(this, arguments);\n state.dim = dim;\n return state;\n }\n\n brush.extent = function(_) {\n return arguments.length ? (extent = typeof _ === \"function\" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;\n };\n\n brush.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant$4(!!_), brush) : filter;\n };\n\n brush.handleSize = function(_) {\n return arguments.length ? (handleSize = +_, brush) : handleSize;\n };\n\n brush.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? brush : value;\n };\n\n return brush;\n}\n\nvar cos = Math.cos;\nvar sin = Math.sin;\nvar pi$1 = Math.PI;\nvar halfPi$1 = pi$1 / 2;\nvar tau$1 = pi$1 * 2;\nvar max$1 = Math.max;\n\nfunction compareValue(compare) {\n return function(a, b) {\n return compare(\n a.source.value + a.target.value,\n b.source.value + b.target.value\n );\n };\n}\n\nfunction chord() {\n var padAngle = 0,\n sortGroups = null,\n sortSubgroups = null,\n sortChords = null;\n\n function chord(matrix) {\n var n = matrix.length,\n groupSums = [],\n groupIndex = sequence(n),\n subgroupIndex = [],\n chords = [],\n groups = chords.groups = new Array(n),\n subgroups = new Array(n * n),\n k,\n x,\n x0,\n dx,\n i,\n j;\n\n // Compute the sum.\n k = 0, i = -1; while (++i < n) {\n x = 0, j = -1; while (++j < n) {\n x += matrix[i][j];\n }\n groupSums.push(x);\n subgroupIndex.push(sequence(n));\n k += x;\n }\n\n // Sort groups…\n if (sortGroups) groupIndex.sort(function(a, b) {\n return sortGroups(groupSums[a], groupSums[b]);\n });\n\n // Sort subgroups…\n if (sortSubgroups) subgroupIndex.forEach(function(d, i) {\n d.sort(function(a, b) {\n return sortSubgroups(matrix[i][a], matrix[i][b]);\n });\n });\n\n // Convert the sum to scaling factor for [0, 2pi].\n // TODO Allow start and end angle to be specified?\n // TODO Allow padding to be specified as percentage?\n k = max$1(0, tau$1 - padAngle * n) / k;\n dx = k ? padAngle : tau$1 / n;\n\n // Compute the start and end angle for each group and subgroup.\n // Note: Opera has a bug reordering object literal properties!\n x = 0, i = -1; while (++i < n) {\n x0 = x, j = -1; while (++j < n) {\n var di = groupIndex[i],\n dj = subgroupIndex[di][j],\n v = matrix[di][dj],\n a0 = x,\n a1 = x += v * k;\n subgroups[dj * n + di] = {\n index: di,\n subindex: dj,\n startAngle: a0,\n endAngle: a1,\n value: v\n };\n }\n groups[di] = {\n index: di,\n startAngle: x0,\n endAngle: x,\n value: groupSums[di]\n };\n x += dx;\n }\n\n // Generate chords for each (non-empty) subgroup-subgroup link.\n i = -1; while (++i < n) {\n j = i - 1; while (++j < n) {\n var source = subgroups[j * n + i],\n target = subgroups[i * n + j];\n if (source.value || target.value) {\n chords.push(source.value < target.value\n ? {source: target, target: source}\n : {source: source, target: target});\n }\n }\n }\n\n return sortChords ? chords.sort(sortChords) : chords;\n }\n\n chord.padAngle = function(_) {\n return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;\n };\n\n chord.sortGroups = function(_) {\n return arguments.length ? (sortGroups = _, chord) : sortGroups;\n };\n\n chord.sortSubgroups = function(_) {\n return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;\n };\n\n chord.sortChords = function(_) {\n return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;\n };\n\n return chord;\n}\n\nvar slice$2 = Array.prototype.slice;\n\nfunction constant$5(x) {\n return function() {\n return x;\n };\n}\n\nvar pi$2 = Math.PI;\nvar tau$2 = 2 * pi$2;\nvar epsilon$1 = 1e-6;\nvar tauEpsilon = tau$2 - epsilon$1;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon$1)) {}\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon$1) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau$2 + tau$2;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon$1) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi$2)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nfunction defaultSource(d) {\n return d.source;\n}\n\nfunction defaultTarget(d) {\n return d.target;\n}\n\nfunction defaultRadius(d) {\n return d.radius;\n}\n\nfunction defaultStartAngle(d) {\n return d.startAngle;\n}\n\nfunction defaultEndAngle(d) {\n return d.endAngle;\n}\n\nfunction ribbon() {\n var source = defaultSource,\n target = defaultTarget,\n radius = defaultRadius,\n startAngle = defaultStartAngle,\n endAngle = defaultEndAngle,\n context = null;\n\n function ribbon() {\n var buffer,\n argv = slice$2.call(arguments),\n s = source.apply(this, argv),\n t = target.apply(this, argv),\n sr = +radius.apply(this, (argv[0] = s, argv)),\n sa0 = startAngle.apply(this, argv) - halfPi$1,\n sa1 = endAngle.apply(this, argv) - halfPi$1,\n sx0 = sr * cos(sa0),\n sy0 = sr * sin(sa0),\n tr = +radius.apply(this, (argv[0] = t, argv)),\n ta0 = startAngle.apply(this, argv) - halfPi$1,\n ta1 = endAngle.apply(this, argv) - halfPi$1;\n\n if (!context) context = buffer = path();\n\n context.moveTo(sx0, sy0);\n context.arc(0, 0, sr, sa0, sa1);\n if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?\n context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));\n context.arc(0, 0, tr, ta0, ta1);\n }\n context.quadraticCurveTo(0, 0, sx0, sy0);\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n ribbon.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$5(+_), ribbon) : radius;\n };\n\n ribbon.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant$5(+_), ribbon) : startAngle;\n };\n\n ribbon.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant$5(+_), ribbon) : endAngle;\n };\n\n ribbon.source = function(_) {\n return arguments.length ? (source = _, ribbon) : source;\n };\n\n ribbon.target = function(_) {\n return arguments.length ? (target = _, ribbon) : target;\n };\n\n ribbon.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, ribbon) : context;\n };\n\n return ribbon;\n}\n\nvar prefix = \"$\";\n\nfunction Map() {}\n\nMap.prototype = map$1.prototype = {\n constructor: Map,\n has: function(key) {\n return (prefix + key) in this;\n },\n get: function(key) {\n return this[prefix + key];\n },\n set: function(key, value) {\n this[prefix + key] = value;\n return this;\n },\n remove: function(key) {\n var property = prefix + key;\n return property in this && delete this[property];\n },\n clear: function() {\n for (var property in this) if (property[0] === prefix) delete this[property];\n },\n keys: function() {\n var keys = [];\n for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));\n return keys;\n },\n values: function() {\n var values = [];\n for (var property in this) if (property[0] === prefix) values.push(this[property]);\n return values;\n },\n entries: function() {\n var entries = [];\n for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});\n return entries;\n },\n size: function() {\n var size = 0;\n for (var property in this) if (property[0] === prefix) ++size;\n return size;\n },\n empty: function() {\n for (var property in this) if (property[0] === prefix) return false;\n return true;\n },\n each: function(f) {\n for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);\n }\n};\n\nfunction map$1(object, f) {\n var map = new Map;\n\n // Copy constructor.\n if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });\n\n // Index array by numeric index or specified key function.\n else if (Array.isArray(object)) {\n var i = -1,\n n = object.length,\n o;\n\n if (f == null) while (++i < n) map.set(i, object[i]);\n else while (++i < n) map.set(f(o = object[i], i, object), o);\n }\n\n // Convert object to map.\n else if (object) for (var key in object) map.set(key, object[key]);\n\n return map;\n}\n\nfunction nest() {\n var keys = [],\n sortKeys = [],\n sortValues,\n rollup,\n nest;\n\n function apply(array, depth, createResult, setResult) {\n if (depth >= keys.length) {\n if (sortValues != null) array.sort(sortValues);\n return rollup != null ? rollup(array) : array;\n }\n\n var i = -1,\n n = array.length,\n key = keys[depth++],\n keyValue,\n value,\n valuesByKey = map$1(),\n values,\n result = createResult();\n\n while (++i < n) {\n if (values = valuesByKey.get(keyValue = key(value = array[i]) + \"\")) {\n values.push(value);\n } else {\n valuesByKey.set(keyValue, [value]);\n }\n }\n\n valuesByKey.each(function(values, key) {\n setResult(result, key, apply(values, depth, createResult, setResult));\n });\n\n return result;\n }\n\n function entries(map, depth) {\n if (++depth > keys.length) return map;\n var array, sortKey = sortKeys[depth - 1];\n if (rollup != null && depth >= keys.length) array = map.entries();\n else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });\n return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;\n }\n\n return nest = {\n object: function(array) { return apply(array, 0, createObject, setObject); },\n map: function(array) { return apply(array, 0, createMap, setMap); },\n entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },\n key: function(d) { keys.push(d); return nest; },\n sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },\n sortValues: function(order) { sortValues = order; return nest; },\n rollup: function(f) { rollup = f; return nest; }\n };\n}\n\nfunction createObject() {\n return {};\n}\n\nfunction setObject(object, key, value) {\n object[key] = value;\n}\n\nfunction createMap() {\n return map$1();\n}\n\nfunction setMap(map, key, value) {\n map.set(key, value);\n}\n\nfunction Set() {}\n\nvar proto = map$1.prototype;\n\nSet.prototype = set$2.prototype = {\n constructor: Set,\n has: proto.has,\n add: function(value) {\n value += \"\";\n this[prefix + value] = value;\n return this;\n },\n remove: proto.remove,\n clear: proto.clear,\n values: proto.keys,\n size: proto.size,\n empty: proto.empty,\n each: proto.each\n};\n\nfunction set$2(object, f) {\n var set = new Set;\n\n // Copy constructor.\n if (object instanceof Set) object.each(function(value) { set.add(value); });\n\n // Otherwise, assume it’s an array.\n else if (object) {\n var i = -1, n = object.length;\n if (f == null) while (++i < n) set.add(object[i]);\n else while (++i < n) set.add(f(object[i], i, object));\n }\n\n return set;\n}\n\nfunction keys(map) {\n var keys = [];\n for (var key in map) keys.push(key);\n return keys;\n}\n\nfunction values(map) {\n var values = [];\n for (var key in map) values.push(map[key]);\n return values;\n}\n\nfunction entries(map) {\n var entries = [];\n for (var key in map) entries.push({key: key, value: map[key]});\n return entries;\n}\n\nvar EOL = {};\nvar EOF = {};\nvar QUOTE = 34;\nvar NEWLINE = 10;\nvar RETURN = 13;\n\nfunction objectConverter(columns) {\n return new Function(\"d\", \"return {\" + columns.map(function(name, i) {\n return JSON.stringify(name) + \": d[\" + i + \"]\";\n }).join(\",\") + \"}\");\n}\n\nfunction customConverter(columns, f) {\n var object = objectConverter(columns);\n return function(row, i) {\n return f(object(row), i, columns);\n };\n}\n\n// Compute unique columns in order of discovery.\nfunction inferColumns(rows) {\n var columnSet = Object.create(null),\n columns = [];\n\n rows.forEach(function(row) {\n for (var column in row) {\n if (!(column in columnSet)) {\n columns.push(columnSet[column] = column);\n }\n }\n });\n\n return columns;\n}\n\nfunction dsv(delimiter) {\n var reFormat = new RegExp(\"[\\\"\" + delimiter + \"\\n\\r]\"),\n DELIMITER = delimiter.charCodeAt(0);\n\n function parse(text, f) {\n var convert, columns, rows = parseRows(text, function(row, i) {\n if (convert) return convert(row, i - 1);\n columns = row, convert = f ? customConverter(row, f) : objectConverter(row);\n });\n rows.columns = columns || [];\n return rows;\n }\n\n function parseRows(text, f) {\n var rows = [], // output rows\n N = text.length,\n I = 0, // current character index\n n = 0, // current line number\n t, // current token\n eof = N <= 0, // current token followed by EOF?\n eol = false; // current token followed by EOL?\n\n // Strip the trailing newline.\n if (text.charCodeAt(N - 1) === NEWLINE) --N;\n if (text.charCodeAt(N - 1) === RETURN) --N;\n\n function token() {\n if (eof) return EOF;\n if (eol) return eol = false, EOL;\n\n // Unescape quotes.\n var i, j = I, c;\n if (text.charCodeAt(j) === QUOTE) {\n while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);\n if ((i = I) >= N) eof = true;\n else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n return text.slice(j + 1, i - 1).replace(/\"\"/g, \"\\\"\");\n }\n\n // Find next delimiter or newline.\n while (I < N) {\n if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n else if (c !== DELIMITER) continue;\n return text.slice(j, i);\n }\n\n // Return last token before EOF.\n return eof = true, text.slice(j, N);\n }\n\n while ((t = token()) !== EOF) {\n var row = [];\n while (t !== EOL && t !== EOF) row.push(t), t = token();\n if (f && (row = f(row, n++)) == null) continue;\n rows.push(row);\n }\n\n return rows;\n }\n\n function format(rows, columns) {\n if (columns == null) columns = inferColumns(rows);\n return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {\n return columns.map(function(column) {\n return formatValue(row[column]);\n }).join(delimiter);\n })).join(\"\\n\");\n }\n\n function formatRows(rows) {\n return rows.map(formatRow).join(\"\\n\");\n }\n\n function formatRow(row) {\n return row.map(formatValue).join(delimiter);\n }\n\n function formatValue(text) {\n return text == null ? \"\"\n : reFormat.test(text += \"\") ? \"\\\"\" + text.replace(/\"/g, \"\\\"\\\"\") + \"\\\"\"\n : text;\n }\n\n return {\n parse: parse,\n parseRows: parseRows,\n format: format,\n formatRows: formatRows\n };\n}\n\nvar csv = dsv(\",\");\n\nvar csvParse = csv.parse;\nvar csvParseRows = csv.parseRows;\nvar csvFormat = csv.format;\nvar csvFormatRows = csv.formatRows;\n\nvar tsv = dsv(\"\\t\");\n\nvar tsvParse = tsv.parse;\nvar tsvParseRows = tsv.parseRows;\nvar tsvFormat = tsv.format;\nvar tsvFormatRows = tsv.formatRows;\n\nfunction center$1(x, y) {\n var nodes;\n\n if (x == null) x = 0;\n if (y == null) y = 0;\n\n function force() {\n var i,\n n = nodes.length,\n node,\n sx = 0,\n sy = 0;\n\n for (i = 0; i < n; ++i) {\n node = nodes[i], sx += node.x, sy += node.y;\n }\n\n for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {\n node = nodes[i], node.x -= sx, node.y -= sy;\n }\n }\n\n force.initialize = function(_) {\n nodes = _;\n };\n\n force.x = function(_) {\n return arguments.length ? (x = +_, force) : x;\n };\n\n force.y = function(_) {\n return arguments.length ? (y = +_, force) : y;\n };\n\n return force;\n}\n\nfunction constant$6(x) {\n return function() {\n return x;\n };\n}\n\nfunction jiggle() {\n return (Math.random() - 0.5) * 1e-6;\n}\n\nfunction tree_add(d) {\n var x = +this._x.call(null, d),\n y = +this._y.call(null, d);\n return add(this.cover(x, y), x, y, d);\n}\n\nfunction add(tree, x, y, d) {\n if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points\n\n var parent,\n node = tree._root,\n leaf = {data: d},\n x0 = tree._x0,\n y0 = tree._y0,\n x1 = tree._x1,\n y1 = tree._y1,\n xm,\n ym,\n xp,\n yp,\n right,\n bottom,\n i,\n j;\n\n // If the tree is empty, initialize the root as a leaf.\n if (!node) return tree._root = leaf, tree;\n\n // Find the existing leaf for the new point, or add it.\n while (node.length) {\n if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;\n if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;\n if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;\n }\n\n // Is the new point is exactly coincident with the existing point?\n xp = +tree._x.call(null, node.data);\n yp = +tree._y.call(null, node.data);\n if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;\n\n // Otherwise, split the leaf node until the old and new point are separated.\n do {\n parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);\n if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;\n if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;\n } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));\n return parent[j] = node, parent[i] = leaf, tree;\n}\n\nfunction addAll(data) {\n var d, i, n = data.length,\n x,\n y,\n xz = new Array(n),\n yz = new Array(n),\n x0 = Infinity,\n y0 = Infinity,\n x1 = -Infinity,\n y1 = -Infinity;\n\n // Compute the points and their extent.\n for (i = 0; i < n; ++i) {\n if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;\n xz[i] = x;\n yz[i] = y;\n if (x < x0) x0 = x;\n if (x > x1) x1 = x;\n if (y < y0) y0 = y;\n if (y > y1) y1 = y;\n }\n\n // If there were no (valid) points, inherit the existing extent.\n if (x1 < x0) x0 = this._x0, x1 = this._x1;\n if (y1 < y0) y0 = this._y0, y1 = this._y1;\n\n // Expand the tree to cover the new points.\n this.cover(x0, y0).cover(x1, y1);\n\n // Add the new points.\n for (i = 0; i < n; ++i) {\n add(this, xz[i], yz[i], data[i]);\n }\n\n return this;\n}\n\nfunction tree_cover(x, y) {\n if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points\n\n var x0 = this._x0,\n y0 = this._y0,\n x1 = this._x1,\n y1 = this._y1;\n\n // If the quadtree has no extent, initialize them.\n // Integer extent are necessary so that if we later double the extent,\n // the existing quadrant boundaries don’t change due to floating point error!\n if (isNaN(x0)) {\n x1 = (x0 = Math.floor(x)) + 1;\n y1 = (y0 = Math.floor(y)) + 1;\n }\n\n // Otherwise, double repeatedly to cover.\n else if (x0 > x || x > x1 || y0 > y || y > y1) {\n var z = x1 - x0,\n node = this._root,\n parent,\n i;\n\n switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {\n case 0: {\n do parent = new Array(4), parent[i] = node, node = parent;\n while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);\n break;\n }\n case 1: {\n do parent = new Array(4), parent[i] = node, node = parent;\n while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);\n break;\n }\n case 2: {\n do parent = new Array(4), parent[i] = node, node = parent;\n while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);\n break;\n }\n case 3: {\n do parent = new Array(4), parent[i] = node, node = parent;\n while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);\n break;\n }\n }\n\n if (this._root && this._root.length) this._root = node;\n }\n\n // If the quadtree covers the point already, just return.\n else return this;\n\n this._x0 = x0;\n this._y0 = y0;\n this._x1 = x1;\n this._y1 = y1;\n return this;\n}\n\nfunction tree_data() {\n var data = [];\n this.visit(function(node) {\n if (!node.length) do data.push(node.data); while (node = node.next)\n });\n return data;\n}\n\nfunction tree_extent(_) {\n return arguments.length\n ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])\n : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];\n}\n\nfunction Quad(node, x0, y0, x1, y1) {\n this.node = node;\n this.x0 = x0;\n this.y0 = y0;\n this.x1 = x1;\n this.y1 = y1;\n}\n\nfunction tree_find(x, y, radius) {\n var data,\n x0 = this._x0,\n y0 = this._y0,\n x1,\n y1,\n x2,\n y2,\n x3 = this._x1,\n y3 = this._y1,\n quads = [],\n node = this._root,\n q,\n i;\n\n if (node) quads.push(new Quad(node, x0, y0, x3, y3));\n if (radius == null) radius = Infinity;\n else {\n x0 = x - radius, y0 = y - radius;\n x3 = x + radius, y3 = y + radius;\n radius *= radius;\n }\n\n while (q = quads.pop()) {\n\n // Stop searching if this quadrant can’t contain a closer node.\n if (!(node = q.node)\n || (x1 = q.x0) > x3\n || (y1 = q.y0) > y3\n || (x2 = q.x1) < x0\n || (y2 = q.y1) < y0) continue;\n\n // Bisect the current quadrant.\n if (node.length) {\n var xm = (x1 + x2) / 2,\n ym = (y1 + y2) / 2;\n\n quads.push(\n new Quad(node[3], xm, ym, x2, y2),\n new Quad(node[2], x1, ym, xm, y2),\n new Quad(node[1], xm, y1, x2, ym),\n new Quad(node[0], x1, y1, xm, ym)\n );\n\n // Visit the closest quadrant first.\n if (i = (y >= ym) << 1 | (x >= xm)) {\n q = quads[quads.length - 1];\n quads[quads.length - 1] = quads[quads.length - 1 - i];\n quads[quads.length - 1 - i] = q;\n }\n }\n\n // Visit this point. (Visiting coincident points isn’t necessary!)\n else {\n var dx = x - +this._x.call(null, node.data),\n dy = y - +this._y.call(null, node.data),\n d2 = dx * dx + dy * dy;\n if (d2 < radius) {\n var d = Math.sqrt(radius = d2);\n x0 = x - d, y0 = y - d;\n x3 = x + d, y3 = y + d;\n data = node.data;\n }\n }\n }\n\n return data;\n}\n\nfunction tree_remove(d) {\n if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points\n\n var parent,\n node = this._root,\n retainer,\n previous,\n next,\n x0 = this._x0,\n y0 = this._y0,\n x1 = this._x1,\n y1 = this._y1,\n x,\n y,\n xm,\n ym,\n right,\n bottom,\n i,\n j;\n\n // If the tree is empty, initialize the root as a leaf.\n if (!node) return this;\n\n // Find the leaf node for the point.\n // While descending, also retain the deepest parent with a non-removed sibling.\n if (node.length) while (true) {\n if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;\n if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;\n if (!(parent = node, node = node[i = bottom << 1 | right])) return this;\n if (!node.length) break;\n if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;\n }\n\n // Find the point to remove.\n while (node.data !== d) if (!(previous = node, node = node.next)) return this;\n if (next = node.next) delete node.next;\n\n // If there are multiple coincident points, remove just the point.\n if (previous) return next ? previous.next = next : delete previous.next, this;\n\n // If this is the root point, remove it.\n if (!parent) return this._root = next, this;\n\n // Remove this leaf.\n next ? parent[i] = next : delete parent[i];\n\n // If the parent now contains exactly one leaf, collapse superfluous parents.\n if ((node = parent[0] || parent[1] || parent[2] || parent[3])\n && node === (parent[3] || parent[2] || parent[1] || parent[0])\n && !node.length) {\n if (retainer) retainer[j] = node;\n else this._root = node;\n }\n\n return this;\n}\n\nfunction removeAll(data) {\n for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);\n return this;\n}\n\nfunction tree_root() {\n return this._root;\n}\n\nfunction tree_size() {\n var size = 0;\n this.visit(function(node) {\n if (!node.length) do ++size; while (node = node.next)\n });\n return size;\n}\n\nfunction tree_visit(callback) {\n var quads = [], q, node = this._root, child, x0, y0, x1, y1;\n if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));\n while (q = quads.pop()) {\n if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {\n var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;\n if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));\n if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));\n if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));\n if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));\n }\n }\n return this;\n}\n\nfunction tree_visitAfter(callback) {\n var quads = [], next = [], q;\n if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));\n while (q = quads.pop()) {\n var node = q.node;\n if (node.length) {\n var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;\n if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));\n if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));\n if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));\n if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));\n }\n next.push(q);\n }\n while (q = next.pop()) {\n callback(q.node, q.x0, q.y0, q.x1, q.y1);\n }\n return this;\n}\n\nfunction defaultX(d) {\n return d[0];\n}\n\nfunction tree_x(_) {\n return arguments.length ? (this._x = _, this) : this._x;\n}\n\nfunction defaultY(d) {\n return d[1];\n}\n\nfunction tree_y(_) {\n return arguments.length ? (this._y = _, this) : this._y;\n}\n\nfunction quadtree(nodes, x, y) {\n var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);\n return nodes == null ? tree : tree.addAll(nodes);\n}\n\nfunction Quadtree(x, y, x0, y0, x1, y1) {\n this._x = x;\n this._y = y;\n this._x0 = x0;\n this._y0 = y0;\n this._x1 = x1;\n this._y1 = y1;\n this._root = undefined;\n}\n\nfunction leaf_copy(leaf) {\n var copy = {data: leaf.data}, next = copy;\n while (leaf = leaf.next) next = next.next = {data: leaf.data};\n return copy;\n}\n\nvar treeProto = quadtree.prototype = Quadtree.prototype;\n\ntreeProto.copy = function() {\n var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),\n node = this._root,\n nodes,\n child;\n\n if (!node) return copy;\n\n if (!node.length) return copy._root = leaf_copy(node), copy;\n\n nodes = [{source: node, target: copy._root = new Array(4)}];\n while (node = nodes.pop()) {\n for (var i = 0; i < 4; ++i) {\n if (child = node.source[i]) {\n if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});\n else node.target[i] = leaf_copy(child);\n }\n }\n }\n\n return copy;\n};\n\ntreeProto.add = tree_add;\ntreeProto.addAll = addAll;\ntreeProto.cover = tree_cover;\ntreeProto.data = tree_data;\ntreeProto.extent = tree_extent;\ntreeProto.find = tree_find;\ntreeProto.remove = tree_remove;\ntreeProto.removeAll = removeAll;\ntreeProto.root = tree_root;\ntreeProto.size = tree_size;\ntreeProto.visit = tree_visit;\ntreeProto.visitAfter = tree_visitAfter;\ntreeProto.x = tree_x;\ntreeProto.y = tree_y;\n\nfunction x(d) {\n return d.x + d.vx;\n}\n\nfunction y(d) {\n return d.y + d.vy;\n}\n\nfunction collide(radius) {\n var nodes,\n radii,\n strength = 1,\n iterations = 1;\n\n if (typeof radius !== \"function\") radius = constant$6(radius == null ? 1 : +radius);\n\n function force() {\n var i, n = nodes.length,\n tree,\n node,\n xi,\n yi,\n ri,\n ri2;\n\n for (var k = 0; k < iterations; ++k) {\n tree = quadtree(nodes, x, y).visitAfter(prepare);\n for (i = 0; i < n; ++i) {\n node = nodes[i];\n ri = radii[node.index], ri2 = ri * ri;\n xi = node.x + node.vx;\n yi = node.y + node.vy;\n tree.visit(apply);\n }\n }\n\n function apply(quad, x0, y0, x1, y1) {\n var data = quad.data, rj = quad.r, r = ri + rj;\n if (data) {\n if (data.index > node.index) {\n var x = xi - data.x - data.vx,\n y = yi - data.y - data.vy,\n l = x * x + y * y;\n if (l < r * r) {\n if (x === 0) x = jiggle(), l += x * x;\n if (y === 0) y = jiggle(), l += y * y;\n l = (r - (l = Math.sqrt(l))) / l * strength;\n node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));\n node.vy += (y *= l) * r;\n data.vx -= x * (r = 1 - r);\n data.vy -= y * r;\n }\n }\n return;\n }\n return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;\n }\n }\n\n function prepare(quad) {\n if (quad.data) return quad.r = radii[quad.data.index];\n for (var i = quad.r = 0; i < 4; ++i) {\n if (quad[i] && quad[i].r > quad.r) {\n quad.r = quad[i].r;\n }\n }\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length, node;\n radii = new Array(n);\n for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.iterations = function(_) {\n return arguments.length ? (iterations = +_, force) : iterations;\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = +_, force) : strength;\n };\n\n force.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : radius;\n };\n\n return force;\n}\n\nfunction index(d) {\n return d.index;\n}\n\nfunction find(nodeById, nodeId) {\n var node = nodeById.get(nodeId);\n if (!node) throw new Error(\"missing: \" + nodeId);\n return node;\n}\n\nfunction link(links) {\n var id = index,\n strength = defaultStrength,\n strengths,\n distance = constant$6(30),\n distances,\n nodes,\n count,\n bias,\n iterations = 1;\n\n if (links == null) links = [];\n\n function defaultStrength(link) {\n return 1 / Math.min(count[link.source.index], count[link.target.index]);\n }\n\n function force(alpha) {\n for (var k = 0, n = links.length; k < iterations; ++k) {\n for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {\n link = links[i], source = link.source, target = link.target;\n x = target.x + target.vx - source.x - source.vx || jiggle();\n y = target.y + target.vy - source.y - source.vy || jiggle();\n l = Math.sqrt(x * x + y * y);\n l = (l - distances[i]) / l * alpha * strengths[i];\n x *= l, y *= l;\n target.vx -= x * (b = bias[i]);\n target.vy -= y * b;\n source.vx += x * (b = 1 - b);\n source.vy += y * b;\n }\n }\n }\n\n function initialize() {\n if (!nodes) return;\n\n var i,\n n = nodes.length,\n m = links.length,\n nodeById = map$1(nodes, id),\n link;\n\n for (i = 0, count = new Array(n); i < m; ++i) {\n link = links[i], link.index = i;\n if (typeof link.source !== \"object\") link.source = find(nodeById, link.source);\n if (typeof link.target !== \"object\") link.target = find(nodeById, link.target);\n count[link.source.index] = (count[link.source.index] || 0) + 1;\n count[link.target.index] = (count[link.target.index] || 0) + 1;\n }\n\n for (i = 0, bias = new Array(m); i < m; ++i) {\n link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);\n }\n\n strengths = new Array(m), initializeStrength();\n distances = new Array(m), initializeDistance();\n }\n\n function initializeStrength() {\n if (!nodes) return;\n\n for (var i = 0, n = links.length; i < n; ++i) {\n strengths[i] = +strength(links[i], i, links);\n }\n }\n\n function initializeDistance() {\n if (!nodes) return;\n\n for (var i = 0, n = links.length; i < n; ++i) {\n distances[i] = +distance(links[i], i, links);\n }\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.links = function(_) {\n return arguments.length ? (links = _, initialize(), force) : links;\n };\n\n force.id = function(_) {\n return arguments.length ? (id = _, force) : id;\n };\n\n force.iterations = function(_) {\n return arguments.length ? (iterations = +_, force) : iterations;\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initializeStrength(), force) : strength;\n };\n\n force.distance = function(_) {\n return arguments.length ? (distance = typeof _ === \"function\" ? _ : constant$6(+_), initializeDistance(), force) : distance;\n };\n\n return force;\n}\n\nfunction x$1(d) {\n return d.x;\n}\n\nfunction y$1(d) {\n return d.y;\n}\n\nvar initialRadius = 10;\nvar initialAngle = Math.PI * (3 - Math.sqrt(5));\n\nfunction simulation(nodes) {\n var simulation,\n alpha = 1,\n alphaMin = 0.001,\n alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),\n alphaTarget = 0,\n velocityDecay = 0.6,\n forces = map$1(),\n stepper = timer(step),\n event = dispatch(\"tick\", \"end\");\n\n if (nodes == null) nodes = [];\n\n function step() {\n tick();\n event.call(\"tick\", simulation);\n if (alpha < alphaMin) {\n stepper.stop();\n event.call(\"end\", simulation);\n }\n }\n\n function tick() {\n var i, n = nodes.length, node;\n\n alpha += (alphaTarget - alpha) * alphaDecay;\n\n forces.each(function(force) {\n force(alpha);\n });\n\n for (i = 0; i < n; ++i) {\n node = nodes[i];\n if (node.fx == null) node.x += node.vx *= velocityDecay;\n else node.x = node.fx, node.vx = 0;\n if (node.fy == null) node.y += node.vy *= velocityDecay;\n else node.y = node.fy, node.vy = 0;\n }\n }\n\n function initializeNodes() {\n for (var i = 0, n = nodes.length, node; i < n; ++i) {\n node = nodes[i], node.index = i;\n if (isNaN(node.x) || isNaN(node.y)) {\n var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;\n node.x = radius * Math.cos(angle);\n node.y = radius * Math.sin(angle);\n }\n if (isNaN(node.vx) || isNaN(node.vy)) {\n node.vx = node.vy = 0;\n }\n }\n }\n\n function initializeForce(force) {\n if (force.initialize) force.initialize(nodes);\n return force;\n }\n\n initializeNodes();\n\n return simulation = {\n tick: tick,\n\n restart: function() {\n return stepper.restart(step), simulation;\n },\n\n stop: function() {\n return stepper.stop(), simulation;\n },\n\n nodes: function(_) {\n return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;\n },\n\n alpha: function(_) {\n return arguments.length ? (alpha = +_, simulation) : alpha;\n },\n\n alphaMin: function(_) {\n return arguments.length ? (alphaMin = +_, simulation) : alphaMin;\n },\n\n alphaDecay: function(_) {\n return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;\n },\n\n alphaTarget: function(_) {\n return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;\n },\n\n velocityDecay: function(_) {\n return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;\n },\n\n force: function(name, _) {\n return arguments.length > 1 ? (_ == null ? forces.remove(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name);\n },\n\n find: function(x, y, radius) {\n var i = 0,\n n = nodes.length,\n dx,\n dy,\n d2,\n node,\n closest;\n\n if (radius == null) radius = Infinity;\n else radius *= radius;\n\n for (i = 0; i < n; ++i) {\n node = nodes[i];\n dx = x - node.x;\n dy = y - node.y;\n d2 = dx * dx + dy * dy;\n if (d2 < radius) closest = node, radius = d2;\n }\n\n return closest;\n },\n\n on: function(name, _) {\n return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);\n }\n };\n}\n\nfunction manyBody() {\n var nodes,\n node,\n alpha,\n strength = constant$6(-30),\n strengths,\n distanceMin2 = 1,\n distanceMax2 = Infinity,\n theta2 = 0.81;\n\n function force(_) {\n var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate);\n for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length, node;\n strengths = new Array(n);\n for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);\n }\n\n function accumulate(quad) {\n var strength = 0, q, c, weight = 0, x, y, i;\n\n // For internal nodes, accumulate forces from child quadrants.\n if (quad.length) {\n for (x = y = i = 0; i < 4; ++i) {\n if ((q = quad[i]) && (c = Math.abs(q.value))) {\n strength += q.value, weight += c, x += c * q.x, y += c * q.y;\n }\n }\n quad.x = x / weight;\n quad.y = y / weight;\n }\n\n // For leaf nodes, accumulate forces from coincident quadrants.\n else {\n q = quad;\n q.x = q.data.x;\n q.y = q.data.y;\n do strength += strengths[q.data.index];\n while (q = q.next);\n }\n\n quad.value = strength;\n }\n\n function apply(quad, x1, _, x2) {\n if (!quad.value) return true;\n\n var x = quad.x - node.x,\n y = quad.y - node.y,\n w = x2 - x1,\n l = x * x + y * y;\n\n // Apply the Barnes-Hut approximation if possible.\n // Limit forces for very close nodes; randomize direction if coincident.\n if (w * w / theta2 < l) {\n if (l < distanceMax2) {\n if (x === 0) x = jiggle(), l += x * x;\n if (y === 0) y = jiggle(), l += y * y;\n if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);\n node.vx += x * quad.value * alpha / l;\n node.vy += y * quad.value * alpha / l;\n }\n return true;\n }\n\n // Otherwise, process points directly.\n else if (quad.length || l >= distanceMax2) return;\n\n // Limit forces for very close nodes; randomize direction if coincident.\n if (quad.data !== node || quad.next) {\n if (x === 0) x = jiggle(), l += x * x;\n if (y === 0) y = jiggle(), l += y * y;\n if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);\n }\n\n do if (quad.data !== node) {\n w = strengths[quad.data.index] * alpha / l;\n node.vx += x * w;\n node.vy += y * w;\n } while (quad = quad.next);\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n };\n\n force.distanceMin = function(_) {\n return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);\n };\n\n force.distanceMax = function(_) {\n return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);\n };\n\n force.theta = function(_) {\n return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);\n };\n\n return force;\n}\n\nfunction radial(radius, x, y) {\n var nodes,\n strength = constant$6(0.1),\n strengths,\n radiuses;\n\n if (typeof radius !== \"function\") radius = constant$6(+radius);\n if (x == null) x = 0;\n if (y == null) y = 0;\n\n function force(alpha) {\n for (var i = 0, n = nodes.length; i < n; ++i) {\n var node = nodes[i],\n dx = node.x - x || 1e-6,\n dy = node.y - y || 1e-6,\n r = Math.sqrt(dx * dx + dy * dy),\n k = (radiuses[i] - r) * strengths[i] * alpha / r;\n node.vx += dx * k;\n node.vy += dy * k;\n }\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length;\n strengths = new Array(n);\n radiuses = new Array(n);\n for (i = 0; i < n; ++i) {\n radiuses[i] = +radius(nodes[i], i, nodes);\n strengths[i] = isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, nodes);\n }\n }\n\n force.initialize = function(_) {\n nodes = _, initialize();\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n };\n\n force.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : radius;\n };\n\n force.x = function(_) {\n return arguments.length ? (x = +_, force) : x;\n };\n\n force.y = function(_) {\n return arguments.length ? (y = +_, force) : y;\n };\n\n return force;\n}\n\nfunction x$2(x) {\n var strength = constant$6(0.1),\n nodes,\n strengths,\n xz;\n\n if (typeof x !== \"function\") x = constant$6(x == null ? 0 : +x);\n\n function force(alpha) {\n for (var i = 0, n = nodes.length, node; i < n; ++i) {\n node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;\n }\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length;\n strengths = new Array(n);\n xz = new Array(n);\n for (i = 0; i < n; ++i) {\n strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);\n }\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n };\n\n force.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : x;\n };\n\n return force;\n}\n\nfunction y$2(y) {\n var strength = constant$6(0.1),\n nodes,\n strengths,\n yz;\n\n if (typeof y !== \"function\") y = constant$6(y == null ? 0 : +y);\n\n function force(alpha) {\n for (var i = 0, n = nodes.length, node; i < n; ++i) {\n node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;\n }\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length;\n strengths = new Array(n);\n yz = new Array(n);\n for (i = 0; i < n; ++i) {\n strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);\n }\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n };\n\n force.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : y;\n };\n\n return force;\n}\n\n// Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimal(1.23) returns [\"123\", 0].\nfunction formatDecimal(x, p) {\n if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf(\"e\")) < 0) return null; // NaN, ±Infinity\n var i, coefficient = x.slice(0, i);\n\n // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n return [\n coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,\n +x.slice(i + 1)\n ];\n}\n\nfunction exponent$1(x) {\n return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;\n}\n\nfunction formatGroup(grouping, thousands) {\n return function(value, width) {\n var i = value.length,\n t = [],\n j = 0,\n g = grouping[0],\n length = 0;\n\n while (i > 0 && g > 0) {\n if (length + g + 1 > width) g = Math.max(1, width - length);\n t.push(value.substring(i -= g, i + g));\n if ((length += g + 1) > width) break;\n g = grouping[j = (j + 1) % grouping.length];\n }\n\n return t.reverse().join(thousands);\n };\n}\n\nfunction formatNumerals(numerals) {\n return function(value) {\n return value.replace(/[0-9]/g, function(i) {\n return numerals[+i];\n });\n };\n}\n\nfunction formatDefault(x, p) {\n x = x.toPrecision(p);\n\n out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (x[i]) {\n case \".\": i0 = i1 = i; break;\n case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n case \"e\": break out;\n default: if (i0 > 0) i0 = 0; break;\n }\n }\n\n return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;\n}\n\nvar prefixExponent;\n\nfunction formatPrefixAuto(x, p) {\n var d = formatDecimal(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1],\n i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n n = coefficient.length;\n return i === n ? coefficient\n : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n\nfunction formatRounded(x, p) {\n var d = formatDecimal(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1];\n return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n}\n\nvar formatTypes = {\n \"\": formatDefault,\n \"%\": function(x, p) { return (x * 100).toFixed(p); },\n \"b\": function(x) { return Math.round(x).toString(2); },\n \"c\": function(x) { return x + \"\"; },\n \"d\": function(x) { return Math.round(x).toString(10); },\n \"e\": function(x, p) { return x.toExponential(p); },\n \"f\": function(x, p) { return x.toFixed(p); },\n \"g\": function(x, p) { return x.toPrecision(p); },\n \"o\": function(x) { return Math.round(x).toString(8); },\n \"p\": function(x, p) { return formatRounded(x * 100, p); },\n \"r\": formatRounded,\n \"s\": formatPrefixAuto,\n \"X\": function(x) { return Math.round(x).toString(16).toUpperCase(); },\n \"x\": function(x) { return Math.round(x).toString(16); }\n};\n\n// [[fill]align][sign][symbol][0][width][,][.precision][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-\\( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?([a-z%])?$/i;\n\nfunction formatSpecifier(specifier) {\n return new FormatSpecifier(specifier);\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nfunction FormatSpecifier(specifier) {\n if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n\n var match,\n fill = match[1] || \" \",\n align = match[2] || \">\",\n sign = match[3] || \"-\",\n symbol = match[4] || \"\",\n zero = !!match[5],\n width = match[6] && +match[6],\n comma = !!match[7],\n precision = match[8] && +match[8].slice(1),\n type = match[9] || \"\";\n\n // The \"n\" type is an alias for \",g\".\n if (type === \"n\") comma = true, type = \"g\";\n\n // Map invalid types to the default format.\n else if (!formatTypes[type]) type = \"\";\n\n // If zero fill is specified, padding goes after sign and before digits.\n if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n this.fill = fill;\n this.align = align;\n this.sign = sign;\n this.symbol = symbol;\n this.zero = zero;\n this.width = width;\n this.comma = comma;\n this.precision = precision;\n this.type = type;\n}\n\nFormatSpecifier.prototype.toString = function() {\n return this.fill\n + this.align\n + this.sign\n + this.symbol\n + (this.zero ? \"0\" : \"\")\n + (this.width == null ? \"\" : Math.max(1, this.width | 0))\n + (this.comma ? \",\" : \"\")\n + (this.precision == null ? \"\" : \".\" + Math.max(0, this.precision | 0))\n + this.type;\n};\n\nfunction identity$3(x) {\n return x;\n}\n\nvar prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"\\xB5\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nfunction formatLocale(locale) {\n var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,\n currency = locale.currency,\n decimal = locale.decimal,\n numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3,\n percent = locale.percent || \"%\";\n\n function newFormat(specifier) {\n specifier = formatSpecifier(specifier);\n\n var fill = specifier.fill,\n align = specifier.align,\n sign = specifier.sign,\n symbol = specifier.symbol,\n zero = specifier.zero,\n width = specifier.width,\n comma = specifier.comma,\n precision = specifier.precision,\n type = specifier.type;\n\n // Compute the prefix and suffix.\n // For SI-prefix, the suffix is lazily computed.\n var prefix = symbol === \"$\" ? currency[0] : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\",\n suffix = symbol === \"$\" ? currency[1] : /[%p]/.test(type) ? percent : \"\";\n\n // What format function should we use?\n // Is this an integer type?\n // Can this type generate exponential notation?\n var formatType = formatTypes[type],\n maybeSuffix = !type || /[defgprs%]/.test(type);\n\n // Set the default precision if not specified,\n // or clamp the specified precision to the supported range.\n // For significant precision, it must be in [1, 21].\n // For fixed precision, it must be in [0, 20].\n precision = precision == null ? (type ? 6 : 12)\n : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n : Math.max(0, Math.min(20, precision));\n\n function format(value) {\n var valuePrefix = prefix,\n valueSuffix = suffix,\n i, n, c;\n\n if (type === \"c\") {\n valueSuffix = formatType(value) + valueSuffix;\n value = \"\";\n } else {\n value = +value;\n\n // Perform the initial formatting.\n var valueNegative = value < 0;\n value = formatType(Math.abs(value), precision);\n\n // If a negative value rounds to zero during formatting, treat as positive.\n if (valueNegative && +value === 0) valueNegative = false;\n\n // Compute the prefix and suffix.\n valuePrefix = (valueNegative ? (sign === \"(\" ? sign : \"-\") : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n valueSuffix = (type === \"s\" ? prefixes[8 + prefixExponent / 3] : \"\") + valueSuffix + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n // Break the formatted value into the integer “value” part that can be\n // grouped, and fractional or exponential “suffix” part that is not.\n if (maybeSuffix) {\n i = -1, n = value.length;\n while (++i < n) {\n if (c = value.charCodeAt(i), 48 > c || c > 57) {\n valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n value = value.slice(0, i);\n break;\n }\n }\n }\n }\n\n // If the fill character is not \"0\", grouping is applied before padding.\n if (comma && !zero) value = group(value, Infinity);\n\n // Compute the padding.\n var length = valuePrefix.length + value.length + valueSuffix.length,\n padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n // If the fill character is \"0\", grouping is applied after padding.\n if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n // Reconstruct the final output based on the desired alignment.\n switch (align) {\n case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n default: value = padding + valuePrefix + value + valueSuffix; break;\n }\n\n return numerals(value);\n }\n\n format.toString = function() {\n return specifier + \"\";\n };\n\n return format;\n }\n\n function formatPrefix(specifier, value) {\n var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier)),\n e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,\n k = Math.pow(10, -e),\n prefix = prefixes[8 + e / 3];\n return function(value) {\n return f(k * value) + prefix;\n };\n }\n\n return {\n format: newFormat,\n formatPrefix: formatPrefix\n };\n}\n\nvar locale;\n\n\n\ndefaultLocale({\n decimal: \".\",\n thousands: \",\",\n grouping: [3],\n currency: [\"$\", \"\"]\n});\n\nfunction defaultLocale(definition) {\n locale = formatLocale(definition);\n exports.format = locale.format;\n exports.formatPrefix = locale.formatPrefix;\n return locale;\n}\n\nfunction precisionFixed(step) {\n return Math.max(0, -exponent$1(Math.abs(step)));\n}\n\nfunction precisionPrefix(step, value) {\n return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));\n}\n\nfunction precisionRound(step, max) {\n step = Math.abs(step), max = Math.abs(max) - step;\n return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;\n}\n\n// Adds floating point numbers with twice the normal precision.\n// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and\n// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)\n// 305–363 (1997).\n// Code adapted from GeographicLib by Charles F. F. Karney,\n// http://geographiclib.sourceforge.net/\n\nfunction adder() {\n return new Adder;\n}\n\nfunction Adder() {\n this.reset();\n}\n\nAdder.prototype = {\n constructor: Adder,\n reset: function() {\n this.s = // rounded value\n this.t = 0; // exact error\n },\n add: function(y) {\n add$1(temp, y, this.t);\n add$1(this, temp.s, this.s);\n if (this.s) this.t += temp.t;\n else this.s = temp.t;\n },\n valueOf: function() {\n return this.s;\n }\n};\n\nvar temp = new Adder;\n\nfunction add$1(adder, a, b) {\n var x = adder.s = a + b,\n bv = x - a,\n av = x - bv;\n adder.t = (a - av) + (b - bv);\n}\n\nvar epsilon$2 = 1e-6;\nvar epsilon2$1 = 1e-12;\nvar pi$3 = Math.PI;\nvar halfPi$2 = pi$3 / 2;\nvar quarterPi = pi$3 / 4;\nvar tau$3 = pi$3 * 2;\n\nvar degrees$1 = 180 / pi$3;\nvar radians = pi$3 / 180;\n\nvar abs = Math.abs;\nvar atan = Math.atan;\nvar atan2 = Math.atan2;\nvar cos$1 = Math.cos;\nvar ceil = Math.ceil;\nvar exp = Math.exp;\n\nvar log = Math.log;\nvar pow = Math.pow;\nvar sin$1 = Math.sin;\nvar sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };\nvar sqrt = Math.sqrt;\nvar tan = Math.tan;\n\nfunction acos(x) {\n return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);\n}\n\nfunction asin(x) {\n return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);\n}\n\nfunction haversin(x) {\n return (x = sin$1(x / 2)) * x;\n}\n\nfunction noop$1() {}\n\nfunction streamGeometry(geometry, stream) {\n if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {\n streamGeometryType[geometry.type](geometry, stream);\n }\n}\n\nvar streamObjectType = {\n Feature: function(object, stream) {\n streamGeometry(object.geometry, stream);\n },\n FeatureCollection: function(object, stream) {\n var features = object.features, i = -1, n = features.length;\n while (++i < n) streamGeometry(features[i].geometry, stream);\n }\n};\n\nvar streamGeometryType = {\n Sphere: function(object, stream) {\n stream.sphere();\n },\n Point: function(object, stream) {\n object = object.coordinates;\n stream.point(object[0], object[1], object[2]);\n },\n MultiPoint: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);\n },\n LineString: function(object, stream) {\n streamLine(object.coordinates, stream, 0);\n },\n MultiLineString: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) streamLine(coordinates[i], stream, 0);\n },\n Polygon: function(object, stream) {\n streamPolygon(object.coordinates, stream);\n },\n MultiPolygon: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) streamPolygon(coordinates[i], stream);\n },\n GeometryCollection: function(object, stream) {\n var geometries = object.geometries, i = -1, n = geometries.length;\n while (++i < n) streamGeometry(geometries[i], stream);\n }\n};\n\nfunction streamLine(coordinates, stream, closed) {\n var i = -1, n = coordinates.length - closed, coordinate;\n stream.lineStart();\n while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);\n stream.lineEnd();\n}\n\nfunction streamPolygon(coordinates, stream) {\n var i = -1, n = coordinates.length;\n stream.polygonStart();\n while (++i < n) streamLine(coordinates[i], stream, 1);\n stream.polygonEnd();\n}\n\nfunction geoStream(object, stream) {\n if (object && streamObjectType.hasOwnProperty(object.type)) {\n streamObjectType[object.type](object, stream);\n } else {\n streamGeometry(object, stream);\n }\n}\n\nvar areaRingSum = adder();\n\nvar areaSum = adder();\nvar lambda00;\nvar phi00;\nvar lambda0;\nvar cosPhi0;\nvar sinPhi0;\n\nvar areaStream = {\n point: noop$1,\n lineStart: noop$1,\n lineEnd: noop$1,\n polygonStart: function() {\n areaRingSum.reset();\n areaStream.lineStart = areaRingStart;\n areaStream.lineEnd = areaRingEnd;\n },\n polygonEnd: function() {\n var areaRing = +areaRingSum;\n areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);\n this.lineStart = this.lineEnd = this.point = noop$1;\n },\n sphere: function() {\n areaSum.add(tau$3);\n }\n};\n\nfunction areaRingStart() {\n areaStream.point = areaPointFirst;\n}\n\nfunction areaRingEnd() {\n areaPoint(lambda00, phi00);\n}\n\nfunction areaPointFirst(lambda, phi) {\n areaStream.point = areaPoint;\n lambda00 = lambda, phi00 = phi;\n lambda *= radians, phi *= radians;\n lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);\n}\n\nfunction areaPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n phi = phi / 2 + quarterPi; // half the angular distance from south pole\n\n // Spherical excess E for a spherical triangle with vertices: south pole,\n // previous point, current point. Uses a formula derived from Cagnoli’s\n // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).\n var dLambda = lambda - lambda0,\n sdLambda = dLambda >= 0 ? 1 : -1,\n adLambda = sdLambda * dLambda,\n cosPhi = cos$1(phi),\n sinPhi = sin$1(phi),\n k = sinPhi0 * sinPhi,\n u = cosPhi0 * cosPhi + k * cos$1(adLambda),\n v = k * sdLambda * sin$1(adLambda);\n areaRingSum.add(atan2(v, u));\n\n // Advance the previous points.\n lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;\n}\n\nfunction area(object) {\n areaSum.reset();\n geoStream(object, areaStream);\n return areaSum * 2;\n}\n\nfunction spherical(cartesian) {\n return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];\n}\n\nfunction cartesian(spherical) {\n var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);\n return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];\n}\n\nfunction cartesianDot(a, b) {\n return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n\nfunction cartesianCross(a, b) {\n return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];\n}\n\n// TODO return a\nfunction cartesianAddInPlace(a, b) {\n a[0] += b[0], a[1] += b[1], a[2] += b[2];\n}\n\nfunction cartesianScale(vector, k) {\n return [vector[0] * k, vector[1] * k, vector[2] * k];\n}\n\n// TODO return d\nfunction cartesianNormalizeInPlace(d) {\n var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);\n d[0] /= l, d[1] /= l, d[2] /= l;\n}\n\nvar lambda0$1;\nvar phi0;\nvar lambda1;\nvar phi1;\nvar lambda2;\nvar lambda00$1;\nvar phi00$1;\nvar p0;\nvar deltaSum = adder();\nvar ranges;\nvar range;\n\nvar boundsStream = {\n point: boundsPoint,\n lineStart: boundsLineStart,\n lineEnd: boundsLineEnd,\n polygonStart: function() {\n boundsStream.point = boundsRingPoint;\n boundsStream.lineStart = boundsRingStart;\n boundsStream.lineEnd = boundsRingEnd;\n deltaSum.reset();\n areaStream.polygonStart();\n },\n polygonEnd: function() {\n areaStream.polygonEnd();\n boundsStream.point = boundsPoint;\n boundsStream.lineStart = boundsLineStart;\n boundsStream.lineEnd = boundsLineEnd;\n if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);\n else if (deltaSum > epsilon$2) phi1 = 90;\n else if (deltaSum < -epsilon$2) phi0 = -90;\n range[0] = lambda0$1, range[1] = lambda1;\n }\n};\n\nfunction boundsPoint(lambda, phi) {\n ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);\n if (phi < phi0) phi0 = phi;\n if (phi > phi1) phi1 = phi;\n}\n\nfunction linePoint(lambda, phi) {\n var p = cartesian([lambda * radians, phi * radians]);\n if (p0) {\n var normal = cartesianCross(p0, p),\n equatorial = [normal[1], -normal[0], 0],\n inflection = cartesianCross(equatorial, normal);\n cartesianNormalizeInPlace(inflection);\n inflection = spherical(inflection);\n var delta = lambda - lambda2,\n sign$$1 = delta > 0 ? 1 : -1,\n lambdai = inflection[0] * degrees$1 * sign$$1,\n phii,\n antimeridian = abs(delta) > 180;\n if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {\n phii = inflection[1] * degrees$1;\n if (phii > phi1) phi1 = phii;\n } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {\n phii = -inflection[1] * degrees$1;\n if (phii < phi0) phi0 = phii;\n } else {\n if (phi < phi0) phi0 = phi;\n if (phi > phi1) phi1 = phi;\n }\n if (antimeridian) {\n if (lambda < lambda2) {\n if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;\n } else {\n if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;\n }\n } else {\n if (lambda1 >= lambda0$1) {\n if (lambda < lambda0$1) lambda0$1 = lambda;\n if (lambda > lambda1) lambda1 = lambda;\n } else {\n if (lambda > lambda2) {\n if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;\n } else {\n if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;\n }\n }\n }\n } else {\n ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);\n }\n if (phi < phi0) phi0 = phi;\n if (phi > phi1) phi1 = phi;\n p0 = p, lambda2 = lambda;\n}\n\nfunction boundsLineStart() {\n boundsStream.point = linePoint;\n}\n\nfunction boundsLineEnd() {\n range[0] = lambda0$1, range[1] = lambda1;\n boundsStream.point = boundsPoint;\n p0 = null;\n}\n\nfunction boundsRingPoint(lambda, phi) {\n if (p0) {\n var delta = lambda - lambda2;\n deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);\n } else {\n lambda00$1 = lambda, phi00$1 = phi;\n }\n areaStream.point(lambda, phi);\n linePoint(lambda, phi);\n}\n\nfunction boundsRingStart() {\n areaStream.lineStart();\n}\n\nfunction boundsRingEnd() {\n boundsRingPoint(lambda00$1, phi00$1);\n areaStream.lineEnd();\n if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180);\n range[0] = lambda0$1, range[1] = lambda1;\n p0 = null;\n}\n\n// Finds the left-right distance between two longitudes.\n// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want\n// the distance between ±180° to be 360°.\nfunction angle(lambda0, lambda1) {\n return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;\n}\n\nfunction rangeCompare(a, b) {\n return a[0] - b[0];\n}\n\nfunction rangeContains(range, x) {\n return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;\n}\n\nfunction bounds(feature) {\n var i, n, a, b, merged, deltaMax, delta;\n\n phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);\n ranges = [];\n geoStream(feature, boundsStream);\n\n // First, sort ranges by their minimum longitudes.\n if (n = ranges.length) {\n ranges.sort(rangeCompare);\n\n // Then, merge any ranges that overlap.\n for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {\n b = ranges[i];\n if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {\n if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];\n if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];\n } else {\n merged.push(a = b);\n }\n }\n\n // Finally, find the largest gap between the merged ranges.\n // The final bounding box will be the inverse of this gap.\n for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {\n b = merged[i];\n if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];\n }\n }\n\n ranges = range = null;\n\n return lambda0$1 === Infinity || phi0 === Infinity\n ? [[NaN, NaN], [NaN, NaN]]\n : [[lambda0$1, phi0], [lambda1, phi1]];\n}\n\nvar W0;\nvar W1;\nvar X0;\nvar Y0;\nvar Z0;\nvar X1;\nvar Y1;\nvar Z1;\nvar X2;\nvar Y2;\nvar Z2;\nvar lambda00$2;\nvar phi00$2;\nvar x0;\nvar y0;\nvar z0; // previous point\n\nvar centroidStream = {\n sphere: noop$1,\n point: centroidPoint,\n lineStart: centroidLineStart,\n lineEnd: centroidLineEnd,\n polygonStart: function() {\n centroidStream.lineStart = centroidRingStart;\n centroidStream.lineEnd = centroidRingEnd;\n },\n polygonEnd: function() {\n centroidStream.lineStart = centroidLineStart;\n centroidStream.lineEnd = centroidLineEnd;\n }\n};\n\n// Arithmetic mean of Cartesian vectors.\nfunction centroidPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos$1(phi);\n centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));\n}\n\nfunction centroidPointCartesian(x, y, z) {\n ++W0;\n X0 += (x - X0) / W0;\n Y0 += (y - Y0) / W0;\n Z0 += (z - Z0) / W0;\n}\n\nfunction centroidLineStart() {\n centroidStream.point = centroidLinePointFirst;\n}\n\nfunction centroidLinePointFirst(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos$1(phi);\n x0 = cosPhi * cos$1(lambda);\n y0 = cosPhi * sin$1(lambda);\n z0 = sin$1(phi);\n centroidStream.point = centroidLinePoint;\n centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroidLinePoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos$1(phi),\n x = cosPhi * cos$1(lambda),\n y = cosPhi * sin$1(lambda),\n z = sin$1(phi),\n w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);\n W1 += w;\n X1 += w * (x0 + (x0 = x));\n Y1 += w * (y0 + (y0 = y));\n Z1 += w * (z0 + (z0 = z));\n centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroidLineEnd() {\n centroidStream.point = centroidPoint;\n}\n\n// See J. E. Brock, The Inertia Tensor for a Spherical Triangle,\n// J. Applied Mechanics 42, 239 (1975).\nfunction centroidRingStart() {\n centroidStream.point = centroidRingPointFirst;\n}\n\nfunction centroidRingEnd() {\n centroidRingPoint(lambda00$2, phi00$2);\n centroidStream.point = centroidPoint;\n}\n\nfunction centroidRingPointFirst(lambda, phi) {\n lambda00$2 = lambda, phi00$2 = phi;\n lambda *= radians, phi *= radians;\n centroidStream.point = centroidRingPoint;\n var cosPhi = cos$1(phi);\n x0 = cosPhi * cos$1(lambda);\n y0 = cosPhi * sin$1(lambda);\n z0 = sin$1(phi);\n centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroidRingPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos$1(phi),\n x = cosPhi * cos$1(lambda),\n y = cosPhi * sin$1(lambda),\n z = sin$1(phi),\n cx = y0 * z - z0 * y,\n cy = z0 * x - x0 * z,\n cz = x0 * y - y0 * x,\n m = sqrt(cx * cx + cy * cy + cz * cz),\n w = asin(m), // line weight = angle\n v = m && -w / m; // area weight multiplier\n X2 += v * cx;\n Y2 += v * cy;\n Z2 += v * cz;\n W1 += w;\n X1 += w * (x0 + (x0 = x));\n Y1 += w * (y0 + (y0 = y));\n Z1 += w * (z0 + (z0 = z));\n centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroid(object) {\n W0 = W1 =\n X0 = Y0 = Z0 =\n X1 = Y1 = Z1 =\n X2 = Y2 = Z2 = 0;\n geoStream(object, centroidStream);\n\n var x = X2,\n y = Y2,\n z = Z2,\n m = x * x + y * y + z * z;\n\n // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.\n if (m < epsilon2$1) {\n x = X1, y = Y1, z = Z1;\n // If the feature has zero length, fall back to arithmetic mean of point vectors.\n if (W1 < epsilon$2) x = X0, y = Y0, z = Z0;\n m = x * x + y * y + z * z;\n // If the feature still has an undefined ccentroid, then return.\n if (m < epsilon2$1) return [NaN, NaN];\n }\n\n return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];\n}\n\nfunction constant$7(x) {\n return function() {\n return x;\n };\n}\n\nfunction compose(a, b) {\n\n function compose(x, y) {\n return x = a(x, y), b(x[0], x[1]);\n }\n\n if (a.invert && b.invert) compose.invert = function(x, y) {\n return x = b.invert(x, y), x && a.invert(x[0], x[1]);\n };\n\n return compose;\n}\n\nfunction rotationIdentity(lambda, phi) {\n return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];\n}\n\nrotationIdentity.invert = rotationIdentity;\n\nfunction rotateRadians(deltaLambda, deltaPhi, deltaGamma) {\n return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))\n : rotationLambda(deltaLambda))\n : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)\n : rotationIdentity);\n}\n\nfunction forwardRotationLambda(deltaLambda) {\n return function(lambda, phi) {\n return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];\n };\n}\n\nfunction rotationLambda(deltaLambda) {\n var rotation = forwardRotationLambda(deltaLambda);\n rotation.invert = forwardRotationLambda(-deltaLambda);\n return rotation;\n}\n\nfunction rotationPhiGamma(deltaPhi, deltaGamma) {\n var cosDeltaPhi = cos$1(deltaPhi),\n sinDeltaPhi = sin$1(deltaPhi),\n cosDeltaGamma = cos$1(deltaGamma),\n sinDeltaGamma = sin$1(deltaGamma);\n\n function rotation(lambda, phi) {\n var cosPhi = cos$1(phi),\n x = cos$1(lambda) * cosPhi,\n y = sin$1(lambda) * cosPhi,\n z = sin$1(phi),\n k = z * cosDeltaPhi + x * sinDeltaPhi;\n return [\n atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),\n asin(k * cosDeltaGamma + y * sinDeltaGamma)\n ];\n }\n\n rotation.invert = function(lambda, phi) {\n var cosPhi = cos$1(phi),\n x = cos$1(lambda) * cosPhi,\n y = sin$1(lambda) * cosPhi,\n z = sin$1(phi),\n k = z * cosDeltaGamma - y * sinDeltaGamma;\n return [\n atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),\n asin(k * cosDeltaPhi - x * sinDeltaPhi)\n ];\n };\n\n return rotation;\n}\n\nfunction rotation(rotate) {\n rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);\n\n function forward(coordinates) {\n coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);\n return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;\n }\n\n forward.invert = function(coordinates) {\n coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);\n return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;\n };\n\n return forward;\n}\n\n// Generates a circle centered at [0°, 0°], with a given radius and precision.\nfunction circleStream(stream, radius, delta, direction, t0, t1) {\n if (!delta) return;\n var cosRadius = cos$1(radius),\n sinRadius = sin$1(radius),\n step = direction * delta;\n if (t0 == null) {\n t0 = radius + direction * tau$3;\n t1 = radius - step / 2;\n } else {\n t0 = circleRadius(cosRadius, t0);\n t1 = circleRadius(cosRadius, t1);\n if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3;\n }\n for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {\n point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);\n stream.point(point[0], point[1]);\n }\n}\n\n// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].\nfunction circleRadius(cosRadius, point) {\n point = cartesian(point), point[0] -= cosRadius;\n cartesianNormalizeInPlace(point);\n var radius = acos(-point[1]);\n return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;\n}\n\nfunction circle() {\n var center = constant$7([0, 0]),\n radius = constant$7(90),\n precision = constant$7(6),\n ring,\n rotate,\n stream = {point: point};\n\n function point(x, y) {\n ring.push(x = rotate(x, y));\n x[0] *= degrees$1, x[1] *= degrees$1;\n }\n\n function circle() {\n var c = center.apply(this, arguments),\n r = radius.apply(this, arguments) * radians,\n p = precision.apply(this, arguments) * radians;\n ring = [];\n rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;\n circleStream(stream, r, p, 1);\n c = {type: \"Polygon\", coordinates: [ring]};\n ring = rotate = null;\n return c;\n }\n\n circle.center = function(_) {\n return arguments.length ? (center = typeof _ === \"function\" ? _ : constant$7([+_[0], +_[1]]), circle) : center;\n };\n\n circle.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$7(+_), circle) : radius;\n };\n\n circle.precision = function(_) {\n return arguments.length ? (precision = typeof _ === \"function\" ? _ : constant$7(+_), circle) : precision;\n };\n\n return circle;\n}\n\nfunction clipBuffer() {\n var lines = [],\n line;\n return {\n point: function(x, y) {\n line.push([x, y]);\n },\n lineStart: function() {\n lines.push(line = []);\n },\n lineEnd: noop$1,\n rejoin: function() {\n if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));\n },\n result: function() {\n var result = lines;\n lines = [];\n line = null;\n return result;\n }\n };\n}\n\nfunction pointEqual(a, b) {\n return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;\n}\n\nfunction Intersection(point, points, other, entry) {\n this.x = point;\n this.z = points;\n this.o = other; // another intersection\n this.e = entry; // is an entry?\n this.v = false; // visited\n this.n = this.p = null; // next & previous\n}\n\n// A generalized polygon clipping algorithm: given a polygon that has been cut\n// into its visible line segments, and rejoins the segments by interpolating\n// along the clip edge.\nfunction clipRejoin(segments, compareIntersection, startInside, interpolate, stream) {\n var subject = [],\n clip = [],\n i,\n n;\n\n segments.forEach(function(segment) {\n if ((n = segment.length - 1) <= 0) return;\n var n, p0 = segment[0], p1 = segment[n], x;\n\n // If the first and last points of a segment are coincident, then treat as a\n // closed ring. TODO if all rings are closed, then the winding order of the\n // exterior ring should be checked.\n if (pointEqual(p0, p1)) {\n stream.lineStart();\n for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);\n stream.lineEnd();\n return;\n }\n\n subject.push(x = new Intersection(p0, segment, null, true));\n clip.push(x.o = new Intersection(p0, null, x, false));\n subject.push(x = new Intersection(p1, segment, null, false));\n clip.push(x.o = new Intersection(p1, null, x, true));\n });\n\n if (!subject.length) return;\n\n clip.sort(compareIntersection);\n link$1(subject);\n link$1(clip);\n\n for (i = 0, n = clip.length; i < n; ++i) {\n clip[i].e = startInside = !startInside;\n }\n\n var start = subject[0],\n points,\n point;\n\n while (1) {\n // Find first unvisited intersection.\n var current = start,\n isSubject = true;\n while (current.v) if ((current = current.n) === start) return;\n points = current.z;\n stream.lineStart();\n do {\n current.v = current.o.v = true;\n if (current.e) {\n if (isSubject) {\n for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);\n } else {\n interpolate(current.x, current.n.x, 1, stream);\n }\n current = current.n;\n } else {\n if (isSubject) {\n points = current.p.z;\n for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);\n } else {\n interpolate(current.x, current.p.x, -1, stream);\n }\n current = current.p;\n }\n current = current.o;\n points = current.z;\n isSubject = !isSubject;\n } while (!current.v);\n stream.lineEnd();\n }\n}\n\nfunction link$1(array) {\n if (!(n = array.length)) return;\n var n,\n i = 0,\n a = array[0],\n b;\n while (++i < n) {\n a.n = b = array[i];\n b.p = a;\n a = b;\n }\n a.n = b = array[0];\n b.p = a;\n}\n\nvar sum$1 = adder();\n\nfunction polygonContains(polygon, point) {\n var lambda = point[0],\n phi = point[1],\n normal = [sin$1(lambda), -cos$1(lambda), 0],\n angle = 0,\n winding = 0;\n\n sum$1.reset();\n\n for (var i = 0, n = polygon.length; i < n; ++i) {\n if (!(m = (ring = polygon[i]).length)) continue;\n var ring,\n m,\n point0 = ring[m - 1],\n lambda0 = point0[0],\n phi0 = point0[1] / 2 + quarterPi,\n sinPhi0 = sin$1(phi0),\n cosPhi0 = cos$1(phi0);\n\n for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {\n var point1 = ring[j],\n lambda1 = point1[0],\n phi1 = point1[1] / 2 + quarterPi,\n sinPhi1 = sin$1(phi1),\n cosPhi1 = cos$1(phi1),\n delta = lambda1 - lambda0,\n sign$$1 = delta >= 0 ? 1 : -1,\n absDelta = sign$$1 * delta,\n antimeridian = absDelta > pi$3,\n k = sinPhi0 * sinPhi1;\n\n sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));\n angle += antimeridian ? delta + sign$$1 * tau$3 : delta;\n\n // Are the longitudes either side of the point’s meridian (lambda),\n // and are the latitudes smaller than the parallel (phi)?\n if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {\n var arc = cartesianCross(cartesian(point0), cartesian(point1));\n cartesianNormalizeInPlace(arc);\n var intersection = cartesianCross(normal, arc);\n cartesianNormalizeInPlace(intersection);\n var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);\n if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {\n winding += antimeridian ^ delta >= 0 ? 1 : -1;\n }\n }\n }\n }\n\n // First, determine whether the South pole is inside or outside:\n //\n // It is inside if:\n // * the polygon winds around it in a clockwise direction.\n // * the polygon does not (cumulatively) wind around it, but has a negative\n // (counter-clockwise) area.\n //\n // Second, count the (signed) number of times a segment crosses a lambda\n // from the point to the South pole. If it is zero, then the point is the\n // same side as the South pole.\n\n return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1);\n}\n\nfunction clip(pointVisible, clipLine, interpolate, start) {\n return function(sink) {\n var line = clipLine(sink),\n ringBuffer = clipBuffer(),\n ringSink = clipLine(ringBuffer),\n polygonStarted = false,\n polygon,\n segments,\n ring;\n\n var clip = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: function() {\n clip.point = pointRing;\n clip.lineStart = ringStart;\n clip.lineEnd = ringEnd;\n segments = [];\n polygon = [];\n },\n polygonEnd: function() {\n clip.point = point;\n clip.lineStart = lineStart;\n clip.lineEnd = lineEnd;\n segments = merge(segments);\n var startInside = polygonContains(polygon, start);\n if (segments.length) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n clipRejoin(segments, compareIntersection, startInside, interpolate, sink);\n } else if (startInside) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n sink.lineStart();\n interpolate(null, null, 1, sink);\n sink.lineEnd();\n }\n if (polygonStarted) sink.polygonEnd(), polygonStarted = false;\n segments = polygon = null;\n },\n sphere: function() {\n sink.polygonStart();\n sink.lineStart();\n interpolate(null, null, 1, sink);\n sink.lineEnd();\n sink.polygonEnd();\n }\n };\n\n function point(lambda, phi) {\n if (pointVisible(lambda, phi)) sink.point(lambda, phi);\n }\n\n function pointLine(lambda, phi) {\n line.point(lambda, phi);\n }\n\n function lineStart() {\n clip.point = pointLine;\n line.lineStart();\n }\n\n function lineEnd() {\n clip.point = point;\n line.lineEnd();\n }\n\n function pointRing(lambda, phi) {\n ring.push([lambda, phi]);\n ringSink.point(lambda, phi);\n }\n\n function ringStart() {\n ringSink.lineStart();\n ring = [];\n }\n\n function ringEnd() {\n pointRing(ring[0][0], ring[0][1]);\n ringSink.lineEnd();\n\n var clean = ringSink.clean(),\n ringSegments = ringBuffer.result(),\n i, n = ringSegments.length, m,\n segment,\n point;\n\n ring.pop();\n polygon.push(ring);\n ring = null;\n\n if (!n) return;\n\n // No intersections.\n if (clean & 1) {\n segment = ringSegments[0];\n if ((m = segment.length - 1) > 0) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n sink.lineStart();\n for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);\n sink.lineEnd();\n }\n return;\n }\n\n // Rejoin connected segments.\n // TODO reuse ringBuffer.rejoin()?\n if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));\n\n segments.push(ringSegments.filter(validSegment));\n }\n\n return clip;\n };\n}\n\nfunction validSegment(segment) {\n return segment.length > 1;\n}\n\n// Intersections are sorted along the clip edge. For both antimeridian cutting\n// and circle clipping, the same comparison is used.\nfunction compareIntersection(a, b) {\n return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1])\n - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]);\n}\n\nvar clipAntimeridian = clip(\n function() { return true; },\n clipAntimeridianLine,\n clipAntimeridianInterpolate,\n [-pi$3, -halfPi$2]\n);\n\n// Takes a line and cuts into visible segments. Return values: 0 - there were\n// intersections or the line was empty; 1 - no intersections; 2 - there were\n// intersections, and the first and last segments should be rejoined.\nfunction clipAntimeridianLine(stream) {\n var lambda0 = NaN,\n phi0 = NaN,\n sign0 = NaN,\n clean; // no intersections\n\n return {\n lineStart: function() {\n stream.lineStart();\n clean = 1;\n },\n point: function(lambda1, phi1) {\n var sign1 = lambda1 > 0 ? pi$3 : -pi$3,\n delta = abs(lambda1 - lambda0);\n if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole\n stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2);\n stream.point(sign0, phi0);\n stream.lineEnd();\n stream.lineStart();\n stream.point(sign1, phi0);\n stream.point(lambda1, phi0);\n clean = 0;\n } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian\n if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies\n if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2;\n phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);\n stream.point(sign0, phi0);\n stream.lineEnd();\n stream.lineStart();\n stream.point(sign1, phi0);\n clean = 0;\n }\n stream.point(lambda0 = lambda1, phi0 = phi1);\n sign0 = sign1;\n },\n lineEnd: function() {\n stream.lineEnd();\n lambda0 = phi0 = NaN;\n },\n clean: function() {\n return 2 - clean; // if intersections, rejoin first and last segments\n }\n };\n}\n\nfunction clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {\n var cosPhi0,\n cosPhi1,\n sinLambda0Lambda1 = sin$1(lambda0 - lambda1);\n return abs(sinLambda0Lambda1) > epsilon$2\n ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)\n - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))\n / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))\n : (phi0 + phi1) / 2;\n}\n\nfunction clipAntimeridianInterpolate(from, to, direction, stream) {\n var phi;\n if (from == null) {\n phi = direction * halfPi$2;\n stream.point(-pi$3, phi);\n stream.point(0, phi);\n stream.point(pi$3, phi);\n stream.point(pi$3, 0);\n stream.point(pi$3, -phi);\n stream.point(0, -phi);\n stream.point(-pi$3, -phi);\n stream.point(-pi$3, 0);\n stream.point(-pi$3, phi);\n } else if (abs(from[0] - to[0]) > epsilon$2) {\n var lambda = from[0] < to[0] ? pi$3 : -pi$3;\n phi = direction * lambda / 2;\n stream.point(-lambda, phi);\n stream.point(0, phi);\n stream.point(lambda, phi);\n } else {\n stream.point(to[0], to[1]);\n }\n}\n\nfunction clipCircle(radius) {\n var cr = cos$1(radius),\n delta = 6 * radians,\n smallRadius = cr > 0,\n notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case\n\n function interpolate(from, to, direction, stream) {\n circleStream(stream, radius, delta, direction, from, to);\n }\n\n function visible(lambda, phi) {\n return cos$1(lambda) * cos$1(phi) > cr;\n }\n\n // Takes a line and cuts into visible segments. Return values used for polygon\n // clipping: 0 - there were intersections or the line was empty; 1 - no\n // intersections 2 - there were intersections, and the first and last segments\n // should be rejoined.\n function clipLine(stream) {\n var point0, // previous point\n c0, // code for previous point\n v0, // visibility of previous point\n v00, // visibility of first point\n clean; // no intersections\n return {\n lineStart: function() {\n v00 = v0 = false;\n clean = 1;\n },\n point: function(lambda, phi) {\n var point1 = [lambda, phi],\n point2,\n v = visible(lambda, phi),\n c = smallRadius\n ? v ? 0 : code(lambda, phi)\n : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;\n if (!point0 && (v00 = v0 = v)) stream.lineStart();\n // Handle degeneracies.\n // TODO ignore if not clipping polygons.\n if (v !== v0) {\n point2 = intersect(point0, point1);\n if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {\n point1[0] += epsilon$2;\n point1[1] += epsilon$2;\n v = visible(point1[0], point1[1]);\n }\n }\n if (v !== v0) {\n clean = 0;\n if (v) {\n // outside going in\n stream.lineStart();\n point2 = intersect(point1, point0);\n stream.point(point2[0], point2[1]);\n } else {\n // inside going out\n point2 = intersect(point0, point1);\n stream.point(point2[0], point2[1]);\n stream.lineEnd();\n }\n point0 = point2;\n } else if (notHemisphere && point0 && smallRadius ^ v) {\n var t;\n // If the codes for two points are different, or are both zero,\n // and there this segment intersects with the small circle.\n if (!(c & c0) && (t = intersect(point1, point0, true))) {\n clean = 0;\n if (smallRadius) {\n stream.lineStart();\n stream.point(t[0][0], t[0][1]);\n stream.point(t[1][0], t[1][1]);\n stream.lineEnd();\n } else {\n stream.point(t[1][0], t[1][1]);\n stream.lineEnd();\n stream.lineStart();\n stream.point(t[0][0], t[0][1]);\n }\n }\n }\n if (v && (!point0 || !pointEqual(point0, point1))) {\n stream.point(point1[0], point1[1]);\n }\n point0 = point1, v0 = v, c0 = c;\n },\n lineEnd: function() {\n if (v0) stream.lineEnd();\n point0 = null;\n },\n // Rejoin first and last segments if there were intersections and the first\n // and last points were visible.\n clean: function() {\n return clean | ((v00 && v0) << 1);\n }\n };\n }\n\n // Intersects the great circle between a and b with the clip circle.\n function intersect(a, b, two) {\n var pa = cartesian(a),\n pb = cartesian(b);\n\n // We have two planes, n1.p = d1 and n2.p = d2.\n // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).\n var n1 = [1, 0, 0], // normal\n n2 = cartesianCross(pa, pb),\n n2n2 = cartesianDot(n2, n2),\n n1n2 = n2[0], // cartesianDot(n1, n2),\n determinant = n2n2 - n1n2 * n1n2;\n\n // Two polar points.\n if (!determinant) return !two && a;\n\n var c1 = cr * n2n2 / determinant,\n c2 = -cr * n1n2 / determinant,\n n1xn2 = cartesianCross(n1, n2),\n A = cartesianScale(n1, c1),\n B = cartesianScale(n2, c2);\n cartesianAddInPlace(A, B);\n\n // Solve |p(t)|^2 = 1.\n var u = n1xn2,\n w = cartesianDot(A, u),\n uu = cartesianDot(u, u),\n t2 = w * w - uu * (cartesianDot(A, A) - 1);\n\n if (t2 < 0) return;\n\n var t = sqrt(t2),\n q = cartesianScale(u, (-w - t) / uu);\n cartesianAddInPlace(q, A);\n q = spherical(q);\n\n if (!two) return q;\n\n // Two intersection points.\n var lambda0 = a[0],\n lambda1 = b[0],\n phi0 = a[1],\n phi1 = b[1],\n z;\n\n if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;\n\n var delta = lambda1 - lambda0,\n polar = abs(delta - pi$3) < epsilon$2,\n meridian = polar || delta < epsilon$2;\n\n if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;\n\n // Check that the first point is between a and b.\n if (meridian\n ? polar\n ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1)\n : phi0 <= q[1] && q[1] <= phi1\n : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {\n var q1 = cartesianScale(u, (-w + t) / uu);\n cartesianAddInPlace(q1, A);\n return [q, spherical(q1)];\n }\n }\n\n // Generates a 4-bit vector representing the location of a point relative to\n // the small circle's bounding box.\n function code(lambda, phi) {\n var r = smallRadius ? radius : pi$3 - radius,\n code = 0;\n if (lambda < -r) code |= 1; // left\n else if (lambda > r) code |= 2; // right\n if (phi < -r) code |= 4; // below\n else if (phi > r) code |= 8; // above\n return code;\n }\n\n return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]);\n}\n\nfunction clipLine(a, b, x0, y0, x1, y1) {\n var ax = a[0],\n ay = a[1],\n bx = b[0],\n by = b[1],\n t0 = 0,\n t1 = 1,\n dx = bx - ax,\n dy = by - ay,\n r;\n\n r = x0 - ax;\n if (!dx && r > 0) return;\n r /= dx;\n if (dx < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dx > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = x1 - ax;\n if (!dx && r < 0) return;\n r /= dx;\n if (dx < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dx > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n r = y0 - ay;\n if (!dy && r > 0) return;\n r /= dy;\n if (dy < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dy > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = y1 - ay;\n if (!dy && r < 0) return;\n r /= dy;\n if (dy < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dy > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;\n if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;\n return true;\n}\n\nvar clipMax = 1e9;\nvar clipMin = -clipMax;\n\n// TODO Use d3-polygon’s polygonContains here for the ring check?\n// TODO Eliminate duplicate buffering in clipBuffer and polygon.push?\n\nfunction clipRectangle(x0, y0, x1, y1) {\n\n function visible(x, y) {\n return x0 <= x && x <= x1 && y0 <= y && y <= y1;\n }\n\n function interpolate(from, to, direction, stream) {\n var a = 0, a1 = 0;\n if (from == null\n || (a = corner(from, direction)) !== (a1 = corner(to, direction))\n || comparePoint(from, to) < 0 ^ direction > 0) {\n do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);\n while ((a = (a + direction + 4) % 4) !== a1);\n } else {\n stream.point(to[0], to[1]);\n }\n }\n\n function corner(p, direction) {\n return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3\n : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1\n : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0\n : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon\n }\n\n function compareIntersection(a, b) {\n return comparePoint(a.x, b.x);\n }\n\n function comparePoint(a, b) {\n var ca = corner(a, 1),\n cb = corner(b, 1);\n return ca !== cb ? ca - cb\n : ca === 0 ? b[1] - a[1]\n : ca === 1 ? a[0] - b[0]\n : ca === 2 ? a[1] - b[1]\n : b[0] - a[0];\n }\n\n return function(stream) {\n var activeStream = stream,\n bufferStream = clipBuffer(),\n segments,\n polygon,\n ring,\n x__, y__, v__, // first point\n x_, y_, v_, // previous point\n first,\n clean;\n\n var clipStream = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: polygonStart,\n polygonEnd: polygonEnd\n };\n\n function point(x, y) {\n if (visible(x, y)) activeStream.point(x, y);\n }\n\n function polygonInside() {\n var winding = 0;\n\n for (var i = 0, n = polygon.length; i < n; ++i) {\n for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {\n a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];\n if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }\n else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }\n }\n }\n\n return winding;\n }\n\n // Buffer geometry within a polygon and then clip it en masse.\n function polygonStart() {\n activeStream = bufferStream, segments = [], polygon = [], clean = true;\n }\n\n function polygonEnd() {\n var startInside = polygonInside(),\n cleanInside = clean && startInside,\n visible = (segments = merge(segments)).length;\n if (cleanInside || visible) {\n stream.polygonStart();\n if (cleanInside) {\n stream.lineStart();\n interpolate(null, null, 1, stream);\n stream.lineEnd();\n }\n if (visible) {\n clipRejoin(segments, compareIntersection, startInside, interpolate, stream);\n }\n stream.polygonEnd();\n }\n activeStream = stream, segments = polygon = ring = null;\n }\n\n function lineStart() {\n clipStream.point = linePoint;\n if (polygon) polygon.push(ring = []);\n first = true;\n v_ = false;\n x_ = y_ = NaN;\n }\n\n // TODO rather than special-case polygons, simply handle them separately.\n // Ideally, coincident intersection points should be jittered to avoid\n // clipping issues.\n function lineEnd() {\n if (segments) {\n linePoint(x__, y__);\n if (v__ && v_) bufferStream.rejoin();\n segments.push(bufferStream.result());\n }\n clipStream.point = point;\n if (v_) activeStream.lineEnd();\n }\n\n function linePoint(x, y) {\n var v = visible(x, y);\n if (polygon) ring.push([x, y]);\n if (first) {\n x__ = x, y__ = y, v__ = v;\n first = false;\n if (v) {\n activeStream.lineStart();\n activeStream.point(x, y);\n }\n } else {\n if (v && v_) activeStream.point(x, y);\n else {\n var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],\n b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];\n if (clipLine(a, b, x0, y0, x1, y1)) {\n if (!v_) {\n activeStream.lineStart();\n activeStream.point(a[0], a[1]);\n }\n activeStream.point(b[0], b[1]);\n if (!v) activeStream.lineEnd();\n clean = false;\n } else if (v) {\n activeStream.lineStart();\n activeStream.point(x, y);\n clean = false;\n }\n }\n }\n x_ = x, y_ = y, v_ = v;\n }\n\n return clipStream;\n };\n}\n\nfunction extent$1() {\n var x0 = 0,\n y0 = 0,\n x1 = 960,\n y1 = 500,\n cache,\n cacheStream,\n clip;\n\n return clip = {\n stream: function(stream) {\n return cache && cacheStream === stream ? cache : cache = clipRectangle(x0, y0, x1, y1)(cacheStream = stream);\n },\n extent: function(_) {\n return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];\n }\n };\n}\n\nvar lengthSum = adder();\nvar lambda0$2;\nvar sinPhi0$1;\nvar cosPhi0$1;\n\nvar lengthStream = {\n sphere: noop$1,\n point: noop$1,\n lineStart: lengthLineStart,\n lineEnd: noop$1,\n polygonStart: noop$1,\n polygonEnd: noop$1\n};\n\nfunction lengthLineStart() {\n lengthStream.point = lengthPointFirst;\n lengthStream.lineEnd = lengthLineEnd;\n}\n\nfunction lengthLineEnd() {\n lengthStream.point = lengthStream.lineEnd = noop$1;\n}\n\nfunction lengthPointFirst(lambda, phi) {\n lambda *= radians, phi *= radians;\n lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);\n lengthStream.point = lengthPoint;\n}\n\nfunction lengthPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var sinPhi = sin$1(phi),\n cosPhi = cos$1(phi),\n delta = abs(lambda - lambda0$2),\n cosDelta = cos$1(delta),\n sinDelta = sin$1(delta),\n x = cosPhi * sinDelta,\n y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,\n z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;\n lengthSum.add(atan2(sqrt(x * x + y * y), z));\n lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;\n}\n\nfunction length$1(object) {\n lengthSum.reset();\n geoStream(object, lengthStream);\n return +lengthSum;\n}\n\nvar coordinates = [null, null];\nvar object$1 = {type: \"LineString\", coordinates: coordinates};\n\nfunction distance(a, b) {\n coordinates[0] = a;\n coordinates[1] = b;\n return length$1(object$1);\n}\n\nvar containsObjectType = {\n Feature: function(object, point) {\n return containsGeometry(object.geometry, point);\n },\n FeatureCollection: function(object, point) {\n var features = object.features, i = -1, n = features.length;\n while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;\n return false;\n }\n};\n\nvar containsGeometryType = {\n Sphere: function() {\n return true;\n },\n Point: function(object, point) {\n return containsPoint(object.coordinates, point);\n },\n MultiPoint: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsPoint(coordinates[i], point)) return true;\n return false;\n },\n LineString: function(object, point) {\n return containsLine(object.coordinates, point);\n },\n MultiLineString: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsLine(coordinates[i], point)) return true;\n return false;\n },\n Polygon: function(object, point) {\n return containsPolygon(object.coordinates, point);\n },\n MultiPolygon: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsPolygon(coordinates[i], point)) return true;\n return false;\n },\n GeometryCollection: function(object, point) {\n var geometries = object.geometries, i = -1, n = geometries.length;\n while (++i < n) if (containsGeometry(geometries[i], point)) return true;\n return false;\n }\n};\n\nfunction containsGeometry(geometry, point) {\n return geometry && containsGeometryType.hasOwnProperty(geometry.type)\n ? containsGeometryType[geometry.type](geometry, point)\n : false;\n}\n\nfunction containsPoint(coordinates, point) {\n return distance(coordinates, point) === 0;\n}\n\nfunction containsLine(coordinates, point) {\n var ab = distance(coordinates[0], coordinates[1]),\n ao = distance(coordinates[0], point),\n ob = distance(point, coordinates[1]);\n return ao + ob <= ab + epsilon$2;\n}\n\nfunction containsPolygon(coordinates, point) {\n return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));\n}\n\nfunction ringRadians(ring) {\n return ring = ring.map(pointRadians), ring.pop(), ring;\n}\n\nfunction pointRadians(point) {\n return [point[0] * radians, point[1] * radians];\n}\n\nfunction contains(object, point) {\n return (object && containsObjectType.hasOwnProperty(object.type)\n ? containsObjectType[object.type]\n : containsGeometry)(object, point);\n}\n\nfunction graticuleX(y0, y1, dy) {\n var y = sequence(y0, y1 - epsilon$2, dy).concat(y1);\n return function(x) { return y.map(function(y) { return [x, y]; }); };\n}\n\nfunction graticuleY(x0, x1, dx) {\n var x = sequence(x0, x1 - epsilon$2, dx).concat(x1);\n return function(y) { return x.map(function(x) { return [x, y]; }); };\n}\n\nfunction graticule() {\n var x1, x0, X1, X0,\n y1, y0, Y1, Y0,\n dx = 10, dy = dx, DX = 90, DY = 360,\n x, y, X, Y,\n precision = 2.5;\n\n function graticule() {\n return {type: \"MultiLineString\", coordinates: lines()};\n }\n\n function lines() {\n return sequence(ceil(X0 / DX) * DX, X1, DX).map(X)\n .concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y))\n .concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x))\n .concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y));\n }\n\n graticule.lines = function() {\n return lines().map(function(coordinates) { return {type: \"LineString\", coordinates: coordinates}; });\n };\n\n graticule.outline = function() {\n return {\n type: \"Polygon\",\n coordinates: [\n X(X0).concat(\n Y(Y1).slice(1),\n X(X1).reverse().slice(1),\n Y(Y0).reverse().slice(1))\n ]\n };\n };\n\n graticule.extent = function(_) {\n if (!arguments.length) return graticule.extentMinor();\n return graticule.extentMajor(_).extentMinor(_);\n };\n\n graticule.extentMajor = function(_) {\n if (!arguments.length) return [[X0, Y0], [X1, Y1]];\n X0 = +_[0][0], X1 = +_[1][0];\n Y0 = +_[0][1], Y1 = +_[1][1];\n if (X0 > X1) _ = X0, X0 = X1, X1 = _;\n if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;\n return graticule.precision(precision);\n };\n\n graticule.extentMinor = function(_) {\n if (!arguments.length) return [[x0, y0], [x1, y1]];\n x0 = +_[0][0], x1 = +_[1][0];\n y0 = +_[0][1], y1 = +_[1][1];\n if (x0 > x1) _ = x0, x0 = x1, x1 = _;\n if (y0 > y1) _ = y0, y0 = y1, y1 = _;\n return graticule.precision(precision);\n };\n\n graticule.step = function(_) {\n if (!arguments.length) return graticule.stepMinor();\n return graticule.stepMajor(_).stepMinor(_);\n };\n\n graticule.stepMajor = function(_) {\n if (!arguments.length) return [DX, DY];\n DX = +_[0], DY = +_[1];\n return graticule;\n };\n\n graticule.stepMinor = function(_) {\n if (!arguments.length) return [dx, dy];\n dx = +_[0], dy = +_[1];\n return graticule;\n };\n\n graticule.precision = function(_) {\n if (!arguments.length) return precision;\n precision = +_;\n x = graticuleX(y0, y1, 90);\n y = graticuleY(x0, x1, precision);\n X = graticuleX(Y0, Y1, 90);\n Y = graticuleY(X0, X1, precision);\n return graticule;\n };\n\n return graticule\n .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])\n .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);\n}\n\nfunction graticule10() {\n return graticule()();\n}\n\nfunction interpolate$1(a, b) {\n var x0 = a[0] * radians,\n y0 = a[1] * radians,\n x1 = b[0] * radians,\n y1 = b[1] * radians,\n cy0 = cos$1(y0),\n sy0 = sin$1(y0),\n cy1 = cos$1(y1),\n sy1 = sin$1(y1),\n kx0 = cy0 * cos$1(x0),\n ky0 = cy0 * sin$1(x0),\n kx1 = cy1 * cos$1(x1),\n ky1 = cy1 * sin$1(x1),\n d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),\n k = sin$1(d);\n\n var interpolate = d ? function(t) {\n var B = sin$1(t *= d) / k,\n A = sin$1(d - t) / k,\n x = A * kx0 + B * kx1,\n y = A * ky0 + B * ky1,\n z = A * sy0 + B * sy1;\n return [\n atan2(y, x) * degrees$1,\n atan2(z, sqrt(x * x + y * y)) * degrees$1\n ];\n } : function() {\n return [x0 * degrees$1, y0 * degrees$1];\n };\n\n interpolate.distance = d;\n\n return interpolate;\n}\n\nfunction identity$4(x) {\n return x;\n}\n\nvar areaSum$1 = adder();\nvar areaRingSum$1 = adder();\nvar x00;\nvar y00;\nvar x0$1;\nvar y0$1;\n\nvar areaStream$1 = {\n point: noop$1,\n lineStart: noop$1,\n lineEnd: noop$1,\n polygonStart: function() {\n areaStream$1.lineStart = areaRingStart$1;\n areaStream$1.lineEnd = areaRingEnd$1;\n },\n polygonEnd: function() {\n areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1;\n areaSum$1.add(abs(areaRingSum$1));\n areaRingSum$1.reset();\n },\n result: function() {\n var area = areaSum$1 / 2;\n areaSum$1.reset();\n return area;\n }\n};\n\nfunction areaRingStart$1() {\n areaStream$1.point = areaPointFirst$1;\n}\n\nfunction areaPointFirst$1(x, y) {\n areaStream$1.point = areaPoint$1;\n x00 = x0$1 = x, y00 = y0$1 = y;\n}\n\nfunction areaPoint$1(x, y) {\n areaRingSum$1.add(y0$1 * x - x0$1 * y);\n x0$1 = x, y0$1 = y;\n}\n\nfunction areaRingEnd$1() {\n areaPoint$1(x00, y00);\n}\n\nvar x0$2 = Infinity;\nvar y0$2 = x0$2;\nvar x1 = -x0$2;\nvar y1 = x1;\n\nvar boundsStream$1 = {\n point: boundsPoint$1,\n lineStart: noop$1,\n lineEnd: noop$1,\n polygonStart: noop$1,\n polygonEnd: noop$1,\n result: function() {\n var bounds = [[x0$2, y0$2], [x1, y1]];\n x1 = y1 = -(y0$2 = x0$2 = Infinity);\n return bounds;\n }\n};\n\nfunction boundsPoint$1(x, y) {\n if (x < x0$2) x0$2 = x;\n if (x > x1) x1 = x;\n if (y < y0$2) y0$2 = y;\n if (y > y1) y1 = y;\n}\n\n// TODO Enforce positive area for exterior, negative area for interior?\n\nvar X0$1 = 0;\nvar Y0$1 = 0;\nvar Z0$1 = 0;\nvar X1$1 = 0;\nvar Y1$1 = 0;\nvar Z1$1 = 0;\nvar X2$1 = 0;\nvar Y2$1 = 0;\nvar Z2$1 = 0;\nvar x00$1;\nvar y00$1;\nvar x0$3;\nvar y0$3;\n\nvar centroidStream$1 = {\n point: centroidPoint$1,\n lineStart: centroidLineStart$1,\n lineEnd: centroidLineEnd$1,\n polygonStart: function() {\n centroidStream$1.lineStart = centroidRingStart$1;\n centroidStream$1.lineEnd = centroidRingEnd$1;\n },\n polygonEnd: function() {\n centroidStream$1.point = centroidPoint$1;\n centroidStream$1.lineStart = centroidLineStart$1;\n centroidStream$1.lineEnd = centroidLineEnd$1;\n },\n result: function() {\n var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]\n : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]\n : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]\n : [NaN, NaN];\n X0$1 = Y0$1 = Z0$1 =\n X1$1 = Y1$1 = Z1$1 =\n X2$1 = Y2$1 = Z2$1 = 0;\n return centroid;\n }\n};\n\nfunction centroidPoint$1(x, y) {\n X0$1 += x;\n Y0$1 += y;\n ++Z0$1;\n}\n\nfunction centroidLineStart$1() {\n centroidStream$1.point = centroidPointFirstLine;\n}\n\nfunction centroidPointFirstLine(x, y) {\n centroidStream$1.point = centroidPointLine;\n centroidPoint$1(x0$3 = x, y0$3 = y);\n}\n\nfunction centroidPointLine(x, y) {\n var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);\n X1$1 += z * (x0$3 + x) / 2;\n Y1$1 += z * (y0$3 + y) / 2;\n Z1$1 += z;\n centroidPoint$1(x0$3 = x, y0$3 = y);\n}\n\nfunction centroidLineEnd$1() {\n centroidStream$1.point = centroidPoint$1;\n}\n\nfunction centroidRingStart$1() {\n centroidStream$1.point = centroidPointFirstRing;\n}\n\nfunction centroidRingEnd$1() {\n centroidPointRing(x00$1, y00$1);\n}\n\nfunction centroidPointFirstRing(x, y) {\n centroidStream$1.point = centroidPointRing;\n centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);\n}\n\nfunction centroidPointRing(x, y) {\n var dx = x - x0$3,\n dy = y - y0$3,\n z = sqrt(dx * dx + dy * dy);\n\n X1$1 += z * (x0$3 + x) / 2;\n Y1$1 += z * (y0$3 + y) / 2;\n Z1$1 += z;\n\n z = y0$3 * x - x0$3 * y;\n X2$1 += z * (x0$3 + x);\n Y2$1 += z * (y0$3 + y);\n Z2$1 += z * 3;\n centroidPoint$1(x0$3 = x, y0$3 = y);\n}\n\nfunction PathContext(context) {\n this._context = context;\n}\n\nPathContext.prototype = {\n _radius: 4.5,\n pointRadius: function(_) {\n return this._radius = _, this;\n },\n polygonStart: function() {\n this._line = 0;\n },\n polygonEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line === 0) this._context.closePath();\n this._point = NaN;\n },\n point: function(x, y) {\n switch (this._point) {\n case 0: {\n this._context.moveTo(x, y);\n this._point = 1;\n break;\n }\n case 1: {\n this._context.lineTo(x, y);\n break;\n }\n default: {\n this._context.moveTo(x + this._radius, y);\n this._context.arc(x, y, this._radius, 0, tau$3);\n break;\n }\n }\n },\n result: noop$1\n};\n\nvar lengthSum$1 = adder();\nvar lengthRing;\nvar x00$2;\nvar y00$2;\nvar x0$4;\nvar y0$4;\n\nvar lengthStream$1 = {\n point: noop$1,\n lineStart: function() {\n lengthStream$1.point = lengthPointFirst$1;\n },\n lineEnd: function() {\n if (lengthRing) lengthPoint$1(x00$2, y00$2);\n lengthStream$1.point = noop$1;\n },\n polygonStart: function() {\n lengthRing = true;\n },\n polygonEnd: function() {\n lengthRing = null;\n },\n result: function() {\n var length = +lengthSum$1;\n lengthSum$1.reset();\n return length;\n }\n};\n\nfunction lengthPointFirst$1(x, y) {\n lengthStream$1.point = lengthPoint$1;\n x00$2 = x0$4 = x, y00$2 = y0$4 = y;\n}\n\nfunction lengthPoint$1(x, y) {\n x0$4 -= x, y0$4 -= y;\n lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));\n x0$4 = x, y0$4 = y;\n}\n\nfunction PathString() {\n this._string = [];\n}\n\nPathString.prototype = {\n _radius: 4.5,\n _circle: circle$1(4.5),\n pointRadius: function(_) {\n if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;\n return this;\n },\n polygonStart: function() {\n this._line = 0;\n },\n polygonEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line === 0) this._string.push(\"Z\");\n this._point = NaN;\n },\n point: function(x, y) {\n switch (this._point) {\n case 0: {\n this._string.push(\"M\", x, \",\", y);\n this._point = 1;\n break;\n }\n case 1: {\n this._string.push(\"L\", x, \",\", y);\n break;\n }\n default: {\n if (this._circle == null) this._circle = circle$1(this._radius);\n this._string.push(\"M\", x, \",\", y, this._circle);\n break;\n }\n }\n },\n result: function() {\n if (this._string.length) {\n var result = this._string.join(\"\");\n this._string = [];\n return result;\n } else {\n return null;\n }\n }\n};\n\nfunction circle$1(radius) {\n return \"m0,\" + radius\n + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + -2 * radius\n + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + 2 * radius\n + \"z\";\n}\n\nfunction index$1(projection, context) {\n var pointRadius = 4.5,\n projectionStream,\n contextStream;\n\n function path(object) {\n if (object) {\n if (typeof pointRadius === \"function\") contextStream.pointRadius(+pointRadius.apply(this, arguments));\n geoStream(object, projectionStream(contextStream));\n }\n return contextStream.result();\n }\n\n path.area = function(object) {\n geoStream(object, projectionStream(areaStream$1));\n return areaStream$1.result();\n };\n\n path.measure = function(object) {\n geoStream(object, projectionStream(lengthStream$1));\n return lengthStream$1.result();\n };\n\n path.bounds = function(object) {\n geoStream(object, projectionStream(boundsStream$1));\n return boundsStream$1.result();\n };\n\n path.centroid = function(object) {\n geoStream(object, projectionStream(centroidStream$1));\n return centroidStream$1.result();\n };\n\n path.projection = function(_) {\n return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection;\n };\n\n path.context = function(_) {\n if (!arguments.length) return context;\n contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);\n if (typeof pointRadius !== \"function\") contextStream.pointRadius(pointRadius);\n return path;\n };\n\n path.pointRadius = function(_) {\n if (!arguments.length) return pointRadius;\n pointRadius = typeof _ === \"function\" ? _ : (contextStream.pointRadius(+_), +_);\n return path;\n };\n\n return path.projection(projection).context(context);\n}\n\nfunction transform(methods) {\n return {\n stream: transformer(methods)\n };\n}\n\nfunction transformer(methods) {\n return function(stream) {\n var s = new TransformStream;\n for (var key in methods) s[key] = methods[key];\n s.stream = stream;\n return s;\n };\n}\n\nfunction TransformStream() {}\n\nTransformStream.prototype = {\n constructor: TransformStream,\n point: function(x, y) { this.stream.point(x, y); },\n sphere: function() { this.stream.sphere(); },\n lineStart: function() { this.stream.lineStart(); },\n lineEnd: function() { this.stream.lineEnd(); },\n polygonStart: function() { this.stream.polygonStart(); },\n polygonEnd: function() { this.stream.polygonEnd(); }\n};\n\nfunction fit(projection, fitBounds, object) {\n var clip = projection.clipExtent && projection.clipExtent();\n projection.scale(150).translate([0, 0]);\n if (clip != null) projection.clipExtent(null);\n geoStream(object, projection.stream(boundsStream$1));\n fitBounds(boundsStream$1.result());\n if (clip != null) projection.clipExtent(clip);\n return projection;\n}\n\nfunction fitExtent(projection, extent, object) {\n return fit(projection, function(b) {\n var w = extent[1][0] - extent[0][0],\n h = extent[1][1] - extent[0][1],\n k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),\n x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,\n y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;\n projection.scale(150 * k).translate([x, y]);\n }, object);\n}\n\nfunction fitSize(projection, size, object) {\n return fitExtent(projection, [[0, 0], size], object);\n}\n\nfunction fitWidth(projection, width, object) {\n return fit(projection, function(b) {\n var w = +width,\n k = w / (b[1][0] - b[0][0]),\n x = (w - k * (b[1][0] + b[0][0])) / 2,\n y = -k * b[0][1];\n projection.scale(150 * k).translate([x, y]);\n }, object);\n}\n\nfunction fitHeight(projection, height, object) {\n return fit(projection, function(b) {\n var h = +height,\n k = h / (b[1][1] - b[0][1]),\n x = -k * b[0][0],\n y = (h - k * (b[1][1] + b[0][1])) / 2;\n projection.scale(150 * k).translate([x, y]);\n }, object);\n}\n\nvar maxDepth = 16;\nvar cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)\n\nfunction resample(project, delta2) {\n return +delta2 ? resample$1(project, delta2) : resampleNone(project);\n}\n\nfunction resampleNone(project) {\n return transformer({\n point: function(x, y) {\n x = project(x, y);\n this.stream.point(x[0], x[1]);\n }\n });\n}\n\nfunction resample$1(project, delta2) {\n\n function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {\n var dx = x1 - x0,\n dy = y1 - y0,\n d2 = dx * dx + dy * dy;\n if (d2 > 4 * delta2 && depth--) {\n var a = a0 + a1,\n b = b0 + b1,\n c = c0 + c1,\n m = sqrt(a * a + b * b + c * c),\n phi2 = asin(c /= m),\n lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),\n p = project(lambda2, phi2),\n x2 = p[0],\n y2 = p[1],\n dx2 = x2 - x0,\n dy2 = y2 - y0,\n dz = dy * dx2 - dx * dy2;\n if (dz * dz / d2 > delta2 // perpendicular projected distance\n || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end\n || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);\n stream.point(x2, y2);\n resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);\n }\n }\n }\n return function(stream) {\n var lambda00, x00, y00, a00, b00, c00, // first point\n lambda0, x0, y0, a0, b0, c0; // previous point\n\n var resampleStream = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },\n polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }\n };\n\n function point(x, y) {\n x = project(x, y);\n stream.point(x[0], x[1]);\n }\n\n function lineStart() {\n x0 = NaN;\n resampleStream.point = linePoint;\n stream.lineStart();\n }\n\n function linePoint(lambda, phi) {\n var c = cartesian([lambda, phi]), p = project(lambda, phi);\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);\n stream.point(x0, y0);\n }\n\n function lineEnd() {\n resampleStream.point = point;\n stream.lineEnd();\n }\n\n function ringStart() {\n lineStart();\n resampleStream.point = ringPoint;\n resampleStream.lineEnd = ringEnd;\n }\n\n function ringPoint(lambda, phi) {\n linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;\n resampleStream.point = linePoint;\n }\n\n function ringEnd() {\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);\n resampleStream.lineEnd = lineEnd;\n lineEnd();\n }\n\n return resampleStream;\n };\n}\n\nvar transformRadians = transformer({\n point: function(x, y) {\n this.stream.point(x * radians, y * radians);\n }\n});\n\nfunction transformRotate(rotate) {\n return transformer({\n point: function(x, y) {\n var r = rotate(x, y);\n return this.stream.point(r[0], r[1]);\n }\n });\n}\n\nfunction projection(project) {\n return projectionMutator(function() { return project; })();\n}\n\nfunction projectionMutator(projectAt) {\n var project,\n k = 150, // scale\n x = 480, y = 250, // translate\n dx, dy, lambda = 0, phi = 0, // center\n deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate\n theta = null, preclip = clipAntimeridian, // clip angle\n x0 = null, y0, x1, y1, postclip = identity$4, // clip extent\n delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision\n cache,\n cacheStream;\n\n function projection(point) {\n point = projectRotate(point[0] * radians, point[1] * radians);\n return [point[0] * k + dx, dy - point[1] * k];\n }\n\n function invert(point) {\n point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);\n return point && [point[0] * degrees$1, point[1] * degrees$1];\n }\n\n function projectTransform(x, y) {\n return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];\n }\n\n projection.stream = function(stream) {\n return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream)))));\n };\n\n projection.preclip = function(_) {\n return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip;\n };\n\n projection.postclip = function(_) {\n return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;\n };\n\n projection.clipAngle = function(_) {\n return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;\n };\n\n projection.clipExtent = function(_) {\n return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n };\n\n projection.scale = function(_) {\n return arguments.length ? (k = +_, recenter()) : k;\n };\n\n projection.translate = function(_) {\n return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];\n };\n\n projection.center = function(_) {\n return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];\n };\n\n projection.rotate = function(_) {\n return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1];\n };\n\n projection.precision = function(_) {\n return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);\n };\n\n projection.fitExtent = function(extent, object) {\n return fitExtent(projection, extent, object);\n };\n\n projection.fitSize = function(size, object) {\n return fitSize(projection, size, object);\n };\n\n projection.fitWidth = function(width, object) {\n return fitWidth(projection, width, object);\n };\n\n projection.fitHeight = function(height, object) {\n return fitHeight(projection, height, object);\n };\n\n function recenter() {\n projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);\n var center = project(lambda, phi);\n dx = x - center[0] * k;\n dy = y + center[1] * k;\n return reset();\n }\n\n function reset() {\n cache = cacheStream = null;\n return projection;\n }\n\n return function() {\n project = projectAt.apply(this, arguments);\n projection.invert = project.invert && invert;\n return recenter();\n };\n}\n\nfunction conicProjection(projectAt) {\n var phi0 = 0,\n phi1 = pi$3 / 3,\n m = projectionMutator(projectAt),\n p = m(phi0, phi1);\n\n p.parallels = function(_) {\n return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];\n };\n\n return p;\n}\n\nfunction cylindricalEqualAreaRaw(phi0) {\n var cosPhi0 = cos$1(phi0);\n\n function forward(lambda, phi) {\n return [lambda * cosPhi0, sin$1(phi) / cosPhi0];\n }\n\n forward.invert = function(x, y) {\n return [x / cosPhi0, asin(y * cosPhi0)];\n };\n\n return forward;\n}\n\nfunction conicEqualAreaRaw(y0, y1) {\n var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;\n\n // Are the parallels symmetrical around the Equator?\n if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);\n\n var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;\n\n function project(x, y) {\n var r = sqrt(c - 2 * n * sin$1(y)) / n;\n return [r * sin$1(x *= n), r0 - r * cos$1(x)];\n }\n\n project.invert = function(x, y) {\n var r0y = r0 - y;\n return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];\n };\n\n return project;\n}\n\nfunction conicEqualArea() {\n return conicProjection(conicEqualAreaRaw)\n .scale(155.424)\n .center([0, 33.6442]);\n}\n\nfunction albers() {\n return conicEqualArea()\n .parallels([29.5, 45.5])\n .scale(1070)\n .translate([480, 250])\n .rotate([96, 0])\n .center([-0.6, 38.7]);\n}\n\n// The projections must have mutually exclusive clip regions on the sphere,\n// as this will avoid emitting interleaving lines and polygons.\nfunction multiplex(streams) {\n var n = streams.length;\n return {\n point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },\n sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },\n lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },\n lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },\n polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },\n polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }\n };\n}\n\n// A composite projection for the United States, configured by default for\n// 960×500. The projection also works quite well at 960×600 if you change the\n// scale to 1285 and adjust the translate accordingly. The set of standard\n// parallels for each region comes from USGS, which is published here:\n// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers\nfunction albersUsa() {\n var cache,\n cacheStream,\n lower48 = albers(), lower48Point,\n alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338\n hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007\n point, pointStream = {point: function(x, y) { point = [x, y]; }};\n\n function albersUsa(coordinates) {\n var x = coordinates[0], y = coordinates[1];\n return point = null, (lower48Point.point(x, y), point)\n || (alaskaPoint.point(x, y), point)\n || (hawaiiPoint.point(x, y), point);\n }\n\n albersUsa.invert = function(coordinates) {\n var k = lower48.scale(),\n t = lower48.translate(),\n x = (coordinates[0] - t[0]) / k,\n y = (coordinates[1] - t[1]) / k;\n return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska\n : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii\n : lower48).invert(coordinates);\n };\n\n albersUsa.stream = function(stream) {\n return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);\n };\n\n albersUsa.precision = function(_) {\n if (!arguments.length) return lower48.precision();\n lower48.precision(_), alaska.precision(_), hawaii.precision(_);\n return reset();\n };\n\n albersUsa.scale = function(_) {\n if (!arguments.length) return lower48.scale();\n lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);\n return albersUsa.translate(lower48.translate());\n };\n\n albersUsa.translate = function(_) {\n if (!arguments.length) return lower48.translate();\n var k = lower48.scale(), x = +_[0], y = +_[1];\n\n lower48Point = lower48\n .translate(_)\n .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])\n .stream(pointStream);\n\n alaskaPoint = alaska\n .translate([x - 0.307 * k, y + 0.201 * k])\n .clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]])\n .stream(pointStream);\n\n hawaiiPoint = hawaii\n .translate([x - 0.205 * k, y + 0.212 * k])\n .clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]])\n .stream(pointStream);\n\n return reset();\n };\n\n albersUsa.fitExtent = function(extent, object) {\n return fitExtent(albersUsa, extent, object);\n };\n\n albersUsa.fitSize = function(size, object) {\n return fitSize(albersUsa, size, object);\n };\n\n albersUsa.fitWidth = function(width, object) {\n return fitWidth(albersUsa, width, object);\n };\n\n albersUsa.fitHeight = function(height, object) {\n return fitHeight(albersUsa, height, object);\n };\n\n function reset() {\n cache = cacheStream = null;\n return albersUsa;\n }\n\n return albersUsa.scale(1070);\n}\n\nfunction azimuthalRaw(scale) {\n return function(x, y) {\n var cx = cos$1(x),\n cy = cos$1(y),\n k = scale(cx * cy);\n return [\n k * cy * sin$1(x),\n k * sin$1(y)\n ];\n }\n}\n\nfunction azimuthalInvert(angle) {\n return function(x, y) {\n var z = sqrt(x * x + y * y),\n c = angle(z),\n sc = sin$1(c),\n cc = cos$1(c);\n return [\n atan2(x * sc, z * cc),\n asin(z && y * sc / z)\n ];\n }\n}\n\nvar azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {\n return sqrt(2 / (1 + cxcy));\n});\n\nazimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {\n return 2 * asin(z / 2);\n});\n\nfunction azimuthalEqualArea() {\n return projection(azimuthalEqualAreaRaw)\n .scale(124.75)\n .clipAngle(180 - 1e-3);\n}\n\nvar azimuthalEquidistantRaw = azimuthalRaw(function(c) {\n return (c = acos(c)) && c / sin$1(c);\n});\n\nazimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {\n return z;\n});\n\nfunction azimuthalEquidistant() {\n return projection(azimuthalEquidistantRaw)\n .scale(79.4188)\n .clipAngle(180 - 1e-3);\n}\n\nfunction mercatorRaw(lambda, phi) {\n return [lambda, log(tan((halfPi$2 + phi) / 2))];\n}\n\nmercatorRaw.invert = function(x, y) {\n return [x, 2 * atan(exp(y)) - halfPi$2];\n};\n\nfunction mercator() {\n return mercatorProjection(mercatorRaw)\n .scale(961 / tau$3);\n}\n\nfunction mercatorProjection(project) {\n var m = projection(project),\n center = m.center,\n scale = m.scale,\n translate = m.translate,\n clipExtent = m.clipExtent,\n x0 = null, y0, x1, y1; // clip extent\n\n m.scale = function(_) {\n return arguments.length ? (scale(_), reclip()) : scale();\n };\n\n m.translate = function(_) {\n return arguments.length ? (translate(_), reclip()) : translate();\n };\n\n m.center = function(_) {\n return arguments.length ? (center(_), reclip()) : center();\n };\n\n m.clipExtent = function(_) {\n return arguments.length ? (_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n };\n\n function reclip() {\n var k = pi$3 * scale(),\n t = m(rotation(m.rotate()).invert([0, 0]));\n return clipExtent(x0 == null\n ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw\n ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]\n : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);\n }\n\n return reclip();\n}\n\nfunction tany(y) {\n return tan((halfPi$2 + y) / 2);\n}\n\nfunction conicConformalRaw(y0, y1) {\n var cy0 = cos$1(y0),\n n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)),\n f = cy0 * pow(tany(y0), n) / n;\n\n if (!n) return mercatorRaw;\n\n function project(x, y) {\n if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; }\n else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; }\n var r = f / pow(tany(y), n);\n return [r * sin$1(n * x), f - r * cos$1(n * x)];\n }\n\n project.invert = function(x, y) {\n var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy);\n return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2];\n };\n\n return project;\n}\n\nfunction conicConformal() {\n return conicProjection(conicConformalRaw)\n .scale(109.5)\n .parallels([30, 30]);\n}\n\nfunction equirectangularRaw(lambda, phi) {\n return [lambda, phi];\n}\n\nequirectangularRaw.invert = equirectangularRaw;\n\nfunction equirectangular() {\n return projection(equirectangularRaw)\n .scale(152.63);\n}\n\nfunction conicEquidistantRaw(y0, y1) {\n var cy0 = cos$1(y0),\n n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),\n g = cy0 / n + y0;\n\n if (abs(n) < epsilon$2) return equirectangularRaw;\n\n function project(x, y) {\n var gy = g - y, nx = n * x;\n return [gy * sin$1(nx), g - gy * cos$1(nx)];\n }\n\n project.invert = function(x, y) {\n var gy = g - y;\n return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)];\n };\n\n return project;\n}\n\nfunction conicEquidistant() {\n return conicProjection(conicEquidistantRaw)\n .scale(131.154)\n .center([0, 13.9389]);\n}\n\nfunction gnomonicRaw(x, y) {\n var cy = cos$1(y), k = cos$1(x) * cy;\n return [cy * sin$1(x) / k, sin$1(y) / k];\n}\n\ngnomonicRaw.invert = azimuthalInvert(atan);\n\nfunction gnomonic() {\n return projection(gnomonicRaw)\n .scale(144.049)\n .clipAngle(60);\n}\n\nfunction scaleTranslate(kx, ky, tx, ty) {\n return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({\n point: function(x, y) {\n this.stream.point(x * kx + tx, y * ky + ty);\n }\n });\n}\n\nfunction identity$5() {\n var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform$$1 = identity$4, // scale, translate and reflect\n x0 = null, y0, x1, y1, // clip extent\n postclip = identity$4,\n cache,\n cacheStream,\n projection;\n\n function reset() {\n cache = cacheStream = null;\n return projection;\n }\n\n return projection = {\n stream: function(stream) {\n return cache && cacheStream === stream ? cache : cache = transform$$1(postclip(cacheStream = stream));\n },\n postclip: function(_) {\n return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;\n },\n clipExtent: function(_) {\n return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n },\n scale: function(_) {\n return arguments.length ? (transform$$1 = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;\n },\n translate: function(_) {\n return arguments.length ? (transform$$1 = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];\n },\n reflectX: function(_) {\n return arguments.length ? (transform$$1 = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;\n },\n reflectY: function(_) {\n return arguments.length ? (transform$$1 = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;\n },\n fitExtent: function(extent, object) {\n return fitExtent(projection, extent, object);\n },\n fitSize: function(size, object) {\n return fitSize(projection, size, object);\n },\n fitWidth: function(width, object) {\n return fitWidth(projection, width, object);\n },\n fitHeight: function(height, object) {\n return fitHeight(projection, height, object);\n }\n };\n}\n\nfunction naturalEarth1Raw(lambda, phi) {\n var phi2 = phi * phi, phi4 = phi2 * phi2;\n return [\n lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),\n phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))\n ];\n}\n\nnaturalEarth1Raw.invert = function(x, y) {\n var phi = y, i = 25, delta;\n do {\n var phi2 = phi * phi, phi4 = phi2 * phi2;\n phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /\n (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));\n } while (abs(delta) > epsilon$2 && --i > 0);\n return [\n x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),\n phi\n ];\n};\n\nfunction naturalEarth1() {\n return projection(naturalEarth1Raw)\n .scale(175.295);\n}\n\nfunction orthographicRaw(x, y) {\n return [cos$1(y) * sin$1(x), sin$1(y)];\n}\n\northographicRaw.invert = azimuthalInvert(asin);\n\nfunction orthographic() {\n return projection(orthographicRaw)\n .scale(249.5)\n .clipAngle(90 + epsilon$2);\n}\n\nfunction stereographicRaw(x, y) {\n var cy = cos$1(y), k = 1 + cos$1(x) * cy;\n return [cy * sin$1(x) / k, sin$1(y) / k];\n}\n\nstereographicRaw.invert = azimuthalInvert(function(z) {\n return 2 * atan(z);\n});\n\nfunction stereographic() {\n return projection(stereographicRaw)\n .scale(250)\n .clipAngle(142);\n}\n\nfunction transverseMercatorRaw(lambda, phi) {\n return [log(tan((halfPi$2 + phi) / 2)), -lambda];\n}\n\ntransverseMercatorRaw.invert = function(x, y) {\n return [-y, 2 * atan(exp(x)) - halfPi$2];\n};\n\nfunction transverseMercator() {\n var m = mercatorProjection(transverseMercatorRaw),\n center = m.center,\n rotate = m.rotate;\n\n m.center = function(_) {\n return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);\n };\n\n m.rotate = function(_) {\n return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);\n };\n\n return rotate([0, 0, 90])\n .scale(159.155);\n}\n\nfunction defaultSeparation(a, b) {\n return a.parent === b.parent ? 1 : 2;\n}\n\nfunction meanX(children) {\n return children.reduce(meanXReduce, 0) / children.length;\n}\n\nfunction meanXReduce(x, c) {\n return x + c.x;\n}\n\nfunction maxY(children) {\n return 1 + children.reduce(maxYReduce, 0);\n}\n\nfunction maxYReduce(y, c) {\n return Math.max(y, c.y);\n}\n\nfunction leafLeft(node) {\n var children;\n while (children = node.children) node = children[0];\n return node;\n}\n\nfunction leafRight(node) {\n var children;\n while (children = node.children) node = children[children.length - 1];\n return node;\n}\n\nfunction cluster() {\n var separation = defaultSeparation,\n dx = 1,\n dy = 1,\n nodeSize = false;\n\n function cluster(root) {\n var previousNode,\n x = 0;\n\n // First walk, computing the initial x & y values.\n root.eachAfter(function(node) {\n var children = node.children;\n if (children) {\n node.x = meanX(children);\n node.y = maxY(children);\n } else {\n node.x = previousNode ? x += separation(node, previousNode) : 0;\n node.y = 0;\n previousNode = node;\n }\n });\n\n var left = leafLeft(root),\n right = leafRight(root),\n x0 = left.x - separation(left, right) / 2,\n x1 = right.x + separation(right, left) / 2;\n\n // Second walk, normalizing x & y to the desired size.\n return root.eachAfter(nodeSize ? function(node) {\n node.x = (node.x - root.x) * dx;\n node.y = (root.y - node.y) * dy;\n } : function(node) {\n node.x = (node.x - x0) / (x1 - x0) * dx;\n node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;\n });\n }\n\n cluster.separation = function(x) {\n return arguments.length ? (separation = x, cluster) : separation;\n };\n\n cluster.size = function(x) {\n return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);\n };\n\n cluster.nodeSize = function(x) {\n return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);\n };\n\n return cluster;\n}\n\nfunction count(node) {\n var sum = 0,\n children = node.children,\n i = children && children.length;\n if (!i) sum = 1;\n else while (--i >= 0) sum += children[i].value;\n node.value = sum;\n}\n\nfunction node_count() {\n return this.eachAfter(count);\n}\n\nfunction node_each(callback) {\n var node = this, current, next = [node], children, i, n;\n do {\n current = next.reverse(), next = [];\n while (node = current.pop()) {\n callback(node), children = node.children;\n if (children) for (i = 0, n = children.length; i < n; ++i) {\n next.push(children[i]);\n }\n }\n } while (next.length);\n return this;\n}\n\nfunction node_eachBefore(callback) {\n var node = this, nodes = [node], children, i;\n while (node = nodes.pop()) {\n callback(node), children = node.children;\n if (children) for (i = children.length - 1; i >= 0; --i) {\n nodes.push(children[i]);\n }\n }\n return this;\n}\n\nfunction node_eachAfter(callback) {\n var node = this, nodes = [node], next = [], children, i, n;\n while (node = nodes.pop()) {\n next.push(node), children = node.children;\n if (children) for (i = 0, n = children.length; i < n; ++i) {\n nodes.push(children[i]);\n }\n }\n while (node = next.pop()) {\n callback(node);\n }\n return this;\n}\n\nfunction node_sum(value) {\n return this.eachAfter(function(node) {\n var sum = +value(node.data) || 0,\n children = node.children,\n i = children && children.length;\n while (--i >= 0) sum += children[i].value;\n node.value = sum;\n });\n}\n\nfunction node_sort(compare) {\n return this.eachBefore(function(node) {\n if (node.children) {\n node.children.sort(compare);\n }\n });\n}\n\nfunction node_path(end) {\n var start = this,\n ancestor = leastCommonAncestor(start, end),\n nodes = [start];\n while (start !== ancestor) {\n start = start.parent;\n nodes.push(start);\n }\n var k = nodes.length;\n while (end !== ancestor) {\n nodes.splice(k, 0, end);\n end = end.parent;\n }\n return nodes;\n}\n\nfunction leastCommonAncestor(a, b) {\n if (a === b) return a;\n var aNodes = a.ancestors(),\n bNodes = b.ancestors(),\n c = null;\n a = aNodes.pop();\n b = bNodes.pop();\n while (a === b) {\n c = a;\n a = aNodes.pop();\n b = bNodes.pop();\n }\n return c;\n}\n\nfunction node_ancestors() {\n var node = this, nodes = [node];\n while (node = node.parent) {\n nodes.push(node);\n }\n return nodes;\n}\n\nfunction node_descendants() {\n var nodes = [];\n this.each(function(node) {\n nodes.push(node);\n });\n return nodes;\n}\n\nfunction node_leaves() {\n var leaves = [];\n this.eachBefore(function(node) {\n if (!node.children) {\n leaves.push(node);\n }\n });\n return leaves;\n}\n\nfunction node_links() {\n var root = this, links = [];\n root.each(function(node) {\n if (node !== root) { // Don’t include the root’s parent, if any.\n links.push({source: node.parent, target: node});\n }\n });\n return links;\n}\n\nfunction hierarchy(data, children) {\n var root = new Node(data),\n valued = +data.value && (root.value = data.value),\n node,\n nodes = [root],\n child,\n childs,\n i,\n n;\n\n if (children == null) children = defaultChildren;\n\n while (node = nodes.pop()) {\n if (valued) node.value = +node.data.value;\n if ((childs = children(node.data)) && (n = childs.length)) {\n node.children = new Array(n);\n for (i = n - 1; i >= 0; --i) {\n nodes.push(child = node.children[i] = new Node(childs[i]));\n child.parent = node;\n child.depth = node.depth + 1;\n }\n }\n }\n\n return root.eachBefore(computeHeight);\n}\n\nfunction node_copy() {\n return hierarchy(this).eachBefore(copyData);\n}\n\nfunction defaultChildren(d) {\n return d.children;\n}\n\nfunction copyData(node) {\n node.data = node.data.data;\n}\n\nfunction computeHeight(node) {\n var height = 0;\n do node.height = height;\n while ((node = node.parent) && (node.height < ++height));\n}\n\nfunction Node(data) {\n this.data = data;\n this.depth =\n this.height = 0;\n this.parent = null;\n}\n\nNode.prototype = hierarchy.prototype = {\n constructor: Node,\n count: node_count,\n each: node_each,\n eachAfter: node_eachAfter,\n eachBefore: node_eachBefore,\n sum: node_sum,\n sort: node_sort,\n path: node_path,\n ancestors: node_ancestors,\n descendants: node_descendants,\n leaves: node_leaves,\n links: node_links,\n copy: node_copy\n};\n\nvar slice$3 = Array.prototype.slice;\n\nfunction shuffle$1(array) {\n var m = array.length,\n t,\n i;\n\n while (m) {\n i = Math.random() * m-- | 0;\n t = array[m];\n array[m] = array[i];\n array[i] = t;\n }\n\n return array;\n}\n\nfunction enclose(circles) {\n var i = 0, n = (circles = shuffle$1(slice$3.call(circles))).length, B = [], p, e;\n\n while (i < n) {\n p = circles[i];\n if (e && enclosesWeak(e, p)) ++i;\n else e = encloseBasis(B = extendBasis(B, p)), i = 0;\n }\n\n return e;\n}\n\nfunction extendBasis(B, p) {\n var i, j;\n\n if (enclosesWeakAll(p, B)) return [p];\n\n // If we get here then B must have at least one element.\n for (i = 0; i < B.length; ++i) {\n if (enclosesNot(p, B[i])\n && enclosesWeakAll(encloseBasis2(B[i], p), B)) {\n return [B[i], p];\n }\n }\n\n // If we get here then B must have at least two elements.\n for (i = 0; i < B.length - 1; ++i) {\n for (j = i + 1; j < B.length; ++j) {\n if (enclosesNot(encloseBasis2(B[i], B[j]), p)\n && enclosesNot(encloseBasis2(B[i], p), B[j])\n && enclosesNot(encloseBasis2(B[j], p), B[i])\n && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {\n return [B[i], B[j], p];\n }\n }\n }\n\n // If we get here then something is very wrong.\n throw new Error;\n}\n\nfunction enclosesNot(a, b) {\n var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;\n return dr < 0 || dr * dr < dx * dx + dy * dy;\n}\n\nfunction enclosesWeak(a, b) {\n var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y;\n return dr > 0 && dr * dr > dx * dx + dy * dy;\n}\n\nfunction enclosesWeakAll(a, B) {\n for (var i = 0; i < B.length; ++i) {\n if (!enclosesWeak(a, B[i])) {\n return false;\n }\n }\n return true;\n}\n\nfunction encloseBasis(B) {\n switch (B.length) {\n case 1: return encloseBasis1(B[0]);\n case 2: return encloseBasis2(B[0], B[1]);\n case 3: return encloseBasis3(B[0], B[1], B[2]);\n }\n}\n\nfunction encloseBasis1(a) {\n return {\n x: a.x,\n y: a.y,\n r: a.r\n };\n}\n\nfunction encloseBasis2(a, b) {\n var x1 = a.x, y1 = a.y, r1 = a.r,\n x2 = b.x, y2 = b.y, r2 = b.r,\n x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,\n l = Math.sqrt(x21 * x21 + y21 * y21);\n return {\n x: (x1 + x2 + x21 / l * r21) / 2,\n y: (y1 + y2 + y21 / l * r21) / 2,\n r: (l + r1 + r2) / 2\n };\n}\n\nfunction encloseBasis3(a, b, c) {\n var x1 = a.x, y1 = a.y, r1 = a.r,\n x2 = b.x, y2 = b.y, r2 = b.r,\n x3 = c.x, y3 = c.y, r3 = c.r,\n a2 = x1 - x2,\n a3 = x1 - x3,\n b2 = y1 - y2,\n b3 = y1 - y3,\n c2 = r2 - r1,\n c3 = r3 - r1,\n d1 = x1 * x1 + y1 * y1 - r1 * r1,\n d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,\n d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,\n ab = a3 * b2 - a2 * b3,\n xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,\n xb = (b3 * c2 - b2 * c3) / ab,\n ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,\n yb = (a2 * c3 - a3 * c2) / ab,\n A = xb * xb + yb * yb - 1,\n B = 2 * (r1 + xa * xb + ya * yb),\n C = xa * xa + ya * ya - r1 * r1,\n r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);\n return {\n x: x1 + xa + xb * r,\n y: y1 + ya + yb * r,\n r: r\n };\n}\n\nfunction place(a, b, c) {\n var ax = a.x,\n ay = a.y,\n da = b.r + c.r,\n db = a.r + c.r,\n dx = b.x - ax,\n dy = b.y - ay,\n dc = dx * dx + dy * dy;\n if (dc) {\n var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),\n y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);\n c.x = ax + x * dx + y * dy;\n c.y = ay + x * dy - y * dx;\n } else {\n c.x = ax + db;\n c.y = ay;\n }\n}\n\nfunction intersects(a, b) {\n var dx = b.x - a.x,\n dy = b.y - a.y,\n dr = a.r + b.r;\n return dr * dr - 1e-6 > dx * dx + dy * dy;\n}\n\nfunction score(node) {\n var a = node._,\n b = node.next._,\n ab = a.r + b.r,\n dx = (a.x * b.r + b.x * a.r) / ab,\n dy = (a.y * b.r + b.y * a.r) / ab;\n return dx * dx + dy * dy;\n}\n\nfunction Node$1(circle) {\n this._ = circle;\n this.next = null;\n this.previous = null;\n}\n\nfunction packEnclose(circles) {\n if (!(n = circles.length)) return 0;\n\n var a, b, c, n, aa, ca, i, j, k, sj, sk;\n\n // Place the first circle.\n a = circles[0], a.x = 0, a.y = 0;\n if (!(n > 1)) return a.r;\n\n // Place the second circle.\n b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;\n if (!(n > 2)) return a.r + b.r;\n\n // Place the third circle.\n place(b, a, c = circles[2]);\n\n // Initialize the front-chain using the first three circles a, b and c.\n a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);\n a.next = c.previous = b;\n b.next = a.previous = c;\n c.next = b.previous = a;\n\n // Attempt to place each remaining circle…\n pack: for (i = 3; i < n; ++i) {\n place(a._, b._, c = circles[i]), c = new Node$1(c);\n\n // Find the closest intersecting circle on the front-chain, if any.\n // “Closeness” is determined by linear distance along the front-chain.\n // “Ahead” or “behind” is likewise determined by linear distance.\n j = b.next, k = a.previous, sj = b._.r, sk = a._.r;\n do {\n if (sj <= sk) {\n if (intersects(j._, c._)) {\n b = j, a.next = b, b.previous = a, --i;\n continue pack;\n }\n sj += j._.r, j = j.next;\n } else {\n if (intersects(k._, c._)) {\n a = k, a.next = b, b.previous = a, --i;\n continue pack;\n }\n sk += k._.r, k = k.previous;\n }\n } while (j !== k.next);\n\n // Success! Insert the new circle c between a and b.\n c.previous = a, c.next = b, a.next = b.previous = b = c;\n\n // Compute the new closest circle pair to the centroid.\n aa = score(a);\n while ((c = c.next) !== b) {\n if ((ca = score(c)) < aa) {\n a = c, aa = ca;\n }\n }\n b = a.next;\n }\n\n // Compute the enclosing circle of the front chain.\n a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);\n\n // Translate the circles to put the enclosing circle around the origin.\n for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;\n\n return c.r;\n}\n\nfunction siblings(circles) {\n packEnclose(circles);\n return circles;\n}\n\nfunction optional(f) {\n return f == null ? null : required(f);\n}\n\nfunction required(f) {\n if (typeof f !== \"function\") throw new Error;\n return f;\n}\n\nfunction constantZero() {\n return 0;\n}\n\nfunction constant$8(x) {\n return function() {\n return x;\n };\n}\n\nfunction defaultRadius$1(d) {\n return Math.sqrt(d.value);\n}\n\nfunction index$2() {\n var radius = null,\n dx = 1,\n dy = 1,\n padding = constantZero;\n\n function pack(root) {\n root.x = dx / 2, root.y = dy / 2;\n if (radius) {\n root.eachBefore(radiusLeaf(radius))\n .eachAfter(packChildren(padding, 0.5))\n .eachBefore(translateChild(1));\n } else {\n root.eachBefore(radiusLeaf(defaultRadius$1))\n .eachAfter(packChildren(constantZero, 1))\n .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))\n .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));\n }\n return root;\n }\n\n pack.radius = function(x) {\n return arguments.length ? (radius = optional(x), pack) : radius;\n };\n\n pack.size = function(x) {\n return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];\n };\n\n pack.padding = function(x) {\n return arguments.length ? (padding = typeof x === \"function\" ? x : constant$8(+x), pack) : padding;\n };\n\n return pack;\n}\n\nfunction radiusLeaf(radius) {\n return function(node) {\n if (!node.children) {\n node.r = Math.max(0, +radius(node) || 0);\n }\n };\n}\n\nfunction packChildren(padding, k) {\n return function(node) {\n if (children = node.children) {\n var children,\n i,\n n = children.length,\n r = padding(node) * k || 0,\n e;\n\n if (r) for (i = 0; i < n; ++i) children[i].r += r;\n e = packEnclose(children);\n if (r) for (i = 0; i < n; ++i) children[i].r -= r;\n node.r = e + r;\n }\n };\n}\n\nfunction translateChild(k) {\n return function(node) {\n var parent = node.parent;\n node.r *= k;\n if (parent) {\n node.x = parent.x + k * node.x;\n node.y = parent.y + k * node.y;\n }\n };\n}\n\nfunction roundNode(node) {\n node.x0 = Math.round(node.x0);\n node.y0 = Math.round(node.y0);\n node.x1 = Math.round(node.x1);\n node.y1 = Math.round(node.y1);\n}\n\nfunction treemapDice(parent, x0, y0, x1, y1) {\n var nodes = parent.children,\n node,\n i = -1,\n n = nodes.length,\n k = parent.value && (x1 - x0) / parent.value;\n\n while (++i < n) {\n node = nodes[i], node.y0 = y0, node.y1 = y1;\n node.x0 = x0, node.x1 = x0 += node.value * k;\n }\n}\n\nfunction partition() {\n var dx = 1,\n dy = 1,\n padding = 0,\n round = false;\n\n function partition(root) {\n var n = root.height + 1;\n root.x0 =\n root.y0 = padding;\n root.x1 = dx;\n root.y1 = dy / n;\n root.eachBefore(positionNode(dy, n));\n if (round) root.eachBefore(roundNode);\n return root;\n }\n\n function positionNode(dy, n) {\n return function(node) {\n if (node.children) {\n treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);\n }\n var x0 = node.x0,\n y0 = node.y0,\n x1 = node.x1 - padding,\n y1 = node.y1 - padding;\n if (x1 < x0) x0 = x1 = (x0 + x1) / 2;\n if (y1 < y0) y0 = y1 = (y0 + y1) / 2;\n node.x0 = x0;\n node.y0 = y0;\n node.x1 = x1;\n node.y1 = y1;\n };\n }\n\n partition.round = function(x) {\n return arguments.length ? (round = !!x, partition) : round;\n };\n\n partition.size = function(x) {\n return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];\n };\n\n partition.padding = function(x) {\n return arguments.length ? (padding = +x, partition) : padding;\n };\n\n return partition;\n}\n\nvar keyPrefix$1 = \"$\";\nvar preroot = {depth: -1};\nvar ambiguous = {};\n\nfunction defaultId(d) {\n return d.id;\n}\n\nfunction defaultParentId(d) {\n return d.parentId;\n}\n\nfunction stratify() {\n var id = defaultId,\n parentId = defaultParentId;\n\n function stratify(data) {\n var d,\n i,\n n = data.length,\n root,\n parent,\n node,\n nodes = new Array(n),\n nodeId,\n nodeKey,\n nodeByKey = {};\n\n for (i = 0; i < n; ++i) {\n d = data[i], node = nodes[i] = new Node(d);\n if ((nodeId = id(d, i, data)) != null && (nodeId += \"\")) {\n nodeKey = keyPrefix$1 + (node.id = nodeId);\n nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;\n }\n }\n\n for (i = 0; i < n; ++i) {\n node = nodes[i], nodeId = parentId(data[i], i, data);\n if (nodeId == null || !(nodeId += \"\")) {\n if (root) throw new Error(\"multiple roots\");\n root = node;\n } else {\n parent = nodeByKey[keyPrefix$1 + nodeId];\n if (!parent) throw new Error(\"missing: \" + nodeId);\n if (parent === ambiguous) throw new Error(\"ambiguous: \" + nodeId);\n if (parent.children) parent.children.push(node);\n else parent.children = [node];\n node.parent = parent;\n }\n }\n\n if (!root) throw new Error(\"no root\");\n root.parent = preroot;\n root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);\n root.parent = null;\n if (n > 0) throw new Error(\"cycle\");\n\n return root;\n }\n\n stratify.id = function(x) {\n return arguments.length ? (id = required(x), stratify) : id;\n };\n\n stratify.parentId = function(x) {\n return arguments.length ? (parentId = required(x), stratify) : parentId;\n };\n\n return stratify;\n}\n\nfunction defaultSeparation$1(a, b) {\n return a.parent === b.parent ? 1 : 2;\n}\n\n// function radialSeparation(a, b) {\n// return (a.parent === b.parent ? 1 : 2) / a.depth;\n// }\n\n// This function is used to traverse the left contour of a subtree (or\n// subforest). It returns the successor of v on this contour. This successor is\n// either given by the leftmost child of v or by the thread of v. The function\n// returns null if and only if v is on the highest level of its subtree.\nfunction nextLeft(v) {\n var children = v.children;\n return children ? children[0] : v.t;\n}\n\n// This function works analogously to nextLeft.\nfunction nextRight(v) {\n var children = v.children;\n return children ? children[children.length - 1] : v.t;\n}\n\n// Shifts the current subtree rooted at w+. This is done by increasing\n// prelim(w+) and mod(w+) by shift.\nfunction moveSubtree(wm, wp, shift) {\n var change = shift / (wp.i - wm.i);\n wp.c -= change;\n wp.s += shift;\n wm.c += change;\n wp.z += shift;\n wp.m += shift;\n}\n\n// All other shifts, applied to the smaller subtrees between w- and w+, are\n// performed by this function. To prepare the shifts, we have to adjust\n// change(w+), shift(w+), and change(w-).\nfunction executeShifts(v) {\n var shift = 0,\n change = 0,\n children = v.children,\n i = children.length,\n w;\n while (--i >= 0) {\n w = children[i];\n w.z += shift;\n w.m += shift;\n shift += w.s + (change += w.c);\n }\n}\n\n// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,\n// returns the specified (default) ancestor.\nfunction nextAncestor(vim, v, ancestor) {\n return vim.a.parent === v.parent ? vim.a : ancestor;\n}\n\nfunction TreeNode(node, i) {\n this._ = node;\n this.parent = null;\n this.children = null;\n this.A = null; // default ancestor\n this.a = this; // ancestor\n this.z = 0; // prelim\n this.m = 0; // mod\n this.c = 0; // change\n this.s = 0; // shift\n this.t = null; // thread\n this.i = i; // number\n}\n\nTreeNode.prototype = Object.create(Node.prototype);\n\nfunction treeRoot(root) {\n var tree = new TreeNode(root, 0),\n node,\n nodes = [tree],\n child,\n children,\n i,\n n;\n\n while (node = nodes.pop()) {\n if (children = node._.children) {\n node.children = new Array(n = children.length);\n for (i = n - 1; i >= 0; --i) {\n nodes.push(child = node.children[i] = new TreeNode(children[i], i));\n child.parent = node;\n }\n }\n }\n\n (tree.parent = new TreeNode(null, 0)).children = [tree];\n return tree;\n}\n\n// Node-link tree diagram using the Reingold-Tilford \"tidy\" algorithm\nfunction tree() {\n var separation = defaultSeparation$1,\n dx = 1,\n dy = 1,\n nodeSize = null;\n\n function tree(root) {\n var t = treeRoot(root);\n\n // Compute the layout using Buchheim et al.’s algorithm.\n t.eachAfter(firstWalk), t.parent.m = -t.z;\n t.eachBefore(secondWalk);\n\n // If a fixed node size is specified, scale x and y.\n if (nodeSize) root.eachBefore(sizeNode);\n\n // If a fixed tree size is specified, scale x and y based on the extent.\n // Compute the left-most, right-most, and depth-most nodes for extents.\n else {\n var left = root,\n right = root,\n bottom = root;\n root.eachBefore(function(node) {\n if (node.x < left.x) left = node;\n if (node.x > right.x) right = node;\n if (node.depth > bottom.depth) bottom = node;\n });\n var s = left === right ? 1 : separation(left, right) / 2,\n tx = s - left.x,\n kx = dx / (right.x + s + tx),\n ky = dy / (bottom.depth || 1);\n root.eachBefore(function(node) {\n node.x = (node.x + tx) * kx;\n node.y = node.depth * ky;\n });\n }\n\n return root;\n }\n\n // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is\n // applied recursively to the children of v, as well as the function\n // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the\n // node v is placed to the midpoint of its outermost children.\n function firstWalk(v) {\n var children = v.children,\n siblings = v.parent.children,\n w = v.i ? siblings[v.i - 1] : null;\n if (children) {\n executeShifts(v);\n var midpoint = (children[0].z + children[children.length - 1].z) / 2;\n if (w) {\n v.z = w.z + separation(v._, w._);\n v.m = v.z - midpoint;\n } else {\n v.z = midpoint;\n }\n } else if (w) {\n v.z = w.z + separation(v._, w._);\n }\n v.parent.A = apportion(v, w, v.parent.A || siblings[0]);\n }\n\n // Computes all real x-coordinates by summing up the modifiers recursively.\n function secondWalk(v) {\n v._.x = v.z + v.parent.m;\n v.m += v.parent.m;\n }\n\n // The core of the algorithm. Here, a new subtree is combined with the\n // previous subtrees. Threads are used to traverse the inside and outside\n // contours of the left and right subtree up to the highest common level. The\n // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the\n // superscript o means outside and i means inside, the subscript - means left\n // subtree and + means right subtree. For summing up the modifiers along the\n // contour, we use respective variables si+, si-, so-, and so+. Whenever two\n // nodes of the inside contours conflict, we compute the left one of the\n // greatest uncommon ancestors using the function ANCESTOR and call MOVE\n // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.\n // Finally, we add a new thread (if necessary).\n function apportion(v, w, ancestor) {\n if (w) {\n var vip = v,\n vop = v,\n vim = w,\n vom = vip.parent.children[0],\n sip = vip.m,\n sop = vop.m,\n sim = vim.m,\n som = vom.m,\n shift;\n while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {\n vom = nextLeft(vom);\n vop = nextRight(vop);\n vop.a = v;\n shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);\n if (shift > 0) {\n moveSubtree(nextAncestor(vim, v, ancestor), v, shift);\n sip += shift;\n sop += shift;\n }\n sim += vim.m;\n sip += vip.m;\n som += vom.m;\n sop += vop.m;\n }\n if (vim && !nextRight(vop)) {\n vop.t = vim;\n vop.m += sim - sop;\n }\n if (vip && !nextLeft(vom)) {\n vom.t = vip;\n vom.m += sip - som;\n ancestor = v;\n }\n }\n return ancestor;\n }\n\n function sizeNode(node) {\n node.x *= dx;\n node.y = node.depth * dy;\n }\n\n tree.separation = function(x) {\n return arguments.length ? (separation = x, tree) : separation;\n };\n\n tree.size = function(x) {\n return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);\n };\n\n tree.nodeSize = function(x) {\n return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);\n };\n\n return tree;\n}\n\nfunction treemapSlice(parent, x0, y0, x1, y1) {\n var nodes = parent.children,\n node,\n i = -1,\n n = nodes.length,\n k = parent.value && (y1 - y0) / parent.value;\n\n while (++i < n) {\n node = nodes[i], node.x0 = x0, node.x1 = x1;\n node.y0 = y0, node.y1 = y0 += node.value * k;\n }\n}\n\nvar phi = (1 + Math.sqrt(5)) / 2;\n\nfunction squarifyRatio(ratio, parent, x0, y0, x1, y1) {\n var rows = [],\n nodes = parent.children,\n row,\n nodeValue,\n i0 = 0,\n i1 = 0,\n n = nodes.length,\n dx, dy,\n value = parent.value,\n sumValue,\n minValue,\n maxValue,\n newRatio,\n minRatio,\n alpha,\n beta;\n\n while (i0 < n) {\n dx = x1 - x0, dy = y1 - y0;\n\n // Find the next non-empty node.\n do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);\n minValue = maxValue = sumValue;\n alpha = Math.max(dy / dx, dx / dy) / (value * ratio);\n beta = sumValue * sumValue * alpha;\n minRatio = Math.max(maxValue / beta, beta / minValue);\n\n // Keep adding nodes while the aspect ratio maintains or improves.\n for (; i1 < n; ++i1) {\n sumValue += nodeValue = nodes[i1].value;\n if (nodeValue < minValue) minValue = nodeValue;\n if (nodeValue > maxValue) maxValue = nodeValue;\n beta = sumValue * sumValue * alpha;\n newRatio = Math.max(maxValue / beta, beta / minValue);\n if (newRatio > minRatio) { sumValue -= nodeValue; break; }\n minRatio = newRatio;\n }\n\n // Position and record the row orientation.\n rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});\n if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);\n else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);\n value -= sumValue, i0 = i1;\n }\n\n return rows;\n}\n\nvar squarify = (function custom(ratio) {\n\n function squarify(parent, x0, y0, x1, y1) {\n squarifyRatio(ratio, parent, x0, y0, x1, y1);\n }\n\n squarify.ratio = function(x) {\n return custom((x = +x) > 1 ? x : 1);\n };\n\n return squarify;\n})(phi);\n\nfunction index$3() {\n var tile = squarify,\n round = false,\n dx = 1,\n dy = 1,\n paddingStack = [0],\n paddingInner = constantZero,\n paddingTop = constantZero,\n paddingRight = constantZero,\n paddingBottom = constantZero,\n paddingLeft = constantZero;\n\n function treemap(root) {\n root.x0 =\n root.y0 = 0;\n root.x1 = dx;\n root.y1 = dy;\n root.eachBefore(positionNode);\n paddingStack = [0];\n if (round) root.eachBefore(roundNode);\n return root;\n }\n\n function positionNode(node) {\n var p = paddingStack[node.depth],\n x0 = node.x0 + p,\n y0 = node.y0 + p,\n x1 = node.x1 - p,\n y1 = node.y1 - p;\n if (x1 < x0) x0 = x1 = (x0 + x1) / 2;\n if (y1 < y0) y0 = y1 = (y0 + y1) / 2;\n node.x0 = x0;\n node.y0 = y0;\n node.x1 = x1;\n node.y1 = y1;\n if (node.children) {\n p = paddingStack[node.depth + 1] = paddingInner(node) / 2;\n x0 += paddingLeft(node) - p;\n y0 += paddingTop(node) - p;\n x1 -= paddingRight(node) - p;\n y1 -= paddingBottom(node) - p;\n if (x1 < x0) x0 = x1 = (x0 + x1) / 2;\n if (y1 < y0) y0 = y1 = (y0 + y1) / 2;\n tile(node, x0, y0, x1, y1);\n }\n }\n\n treemap.round = function(x) {\n return arguments.length ? (round = !!x, treemap) : round;\n };\n\n treemap.size = function(x) {\n return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];\n };\n\n treemap.tile = function(x) {\n return arguments.length ? (tile = required(x), treemap) : tile;\n };\n\n treemap.padding = function(x) {\n return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();\n };\n\n treemap.paddingInner = function(x) {\n return arguments.length ? (paddingInner = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingInner;\n };\n\n treemap.paddingOuter = function(x) {\n return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();\n };\n\n treemap.paddingTop = function(x) {\n return arguments.length ? (paddingTop = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingTop;\n };\n\n treemap.paddingRight = function(x) {\n return arguments.length ? (paddingRight = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingRight;\n };\n\n treemap.paddingBottom = function(x) {\n return arguments.length ? (paddingBottom = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingBottom;\n };\n\n treemap.paddingLeft = function(x) {\n return arguments.length ? (paddingLeft = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingLeft;\n };\n\n return treemap;\n}\n\nfunction binary(parent, x0, y0, x1, y1) {\n var nodes = parent.children,\n i, n = nodes.length,\n sum, sums = new Array(n + 1);\n\n for (sums[0] = sum = i = 0; i < n; ++i) {\n sums[i + 1] = sum += nodes[i].value;\n }\n\n partition(0, n, parent.value, x0, y0, x1, y1);\n\n function partition(i, j, value, x0, y0, x1, y1) {\n if (i >= j - 1) {\n var node = nodes[i];\n node.x0 = x0, node.y0 = y0;\n node.x1 = x1, node.y1 = y1;\n return;\n }\n\n var valueOffset = sums[i],\n valueTarget = (value / 2) + valueOffset,\n k = i + 1,\n hi = j - 1;\n\n while (k < hi) {\n var mid = k + hi >>> 1;\n if (sums[mid] < valueTarget) k = mid + 1;\n else hi = mid;\n }\n\n if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;\n\n var valueLeft = sums[k] - valueOffset,\n valueRight = value - valueLeft;\n\n if ((x1 - x0) > (y1 - y0)) {\n var xk = (x0 * valueRight + x1 * valueLeft) / value;\n partition(i, k, valueLeft, x0, y0, xk, y1);\n partition(k, j, valueRight, xk, y0, x1, y1);\n } else {\n var yk = (y0 * valueRight + y1 * valueLeft) / value;\n partition(i, k, valueLeft, x0, y0, x1, yk);\n partition(k, j, valueRight, x0, yk, x1, y1);\n }\n }\n}\n\nfunction sliceDice(parent, x0, y0, x1, y1) {\n (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);\n}\n\nvar resquarify = (function custom(ratio) {\n\n function resquarify(parent, x0, y0, x1, y1) {\n if ((rows = parent._squarify) && (rows.ratio === ratio)) {\n var rows,\n row,\n nodes,\n i,\n j = -1,\n n,\n m = rows.length,\n value = parent.value;\n\n while (++j < m) {\n row = rows[j], nodes = row.children;\n for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;\n if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);\n else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);\n value -= row.value;\n }\n } else {\n parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);\n rows.ratio = ratio;\n }\n }\n\n resquarify.ratio = function(x) {\n return custom((x = +x) > 1 ? x : 1);\n };\n\n return resquarify;\n})(phi);\n\nfunction area$1(polygon) {\n var i = -1,\n n = polygon.length,\n a,\n b = polygon[n - 1],\n area = 0;\n\n while (++i < n) {\n a = b;\n b = polygon[i];\n area += a[1] * b[0] - a[0] * b[1];\n }\n\n return area / 2;\n}\n\nfunction centroid$1(polygon) {\n var i = -1,\n n = polygon.length,\n x = 0,\n y = 0,\n a,\n b = polygon[n - 1],\n c,\n k = 0;\n\n while (++i < n) {\n a = b;\n b = polygon[i];\n k += c = a[0] * b[1] - b[0] * a[1];\n x += (a[0] + b[0]) * c;\n y += (a[1] + b[1]) * c;\n }\n\n return k *= 3, [x / k, y / k];\n}\n\n// Returns the 2D cross product of AB and AC vectors, i.e., the z-component of\n// the 3D cross product in a quadrant I Cartesian coordinate system (+x is\n// right, +y is up). Returns a positive value if ABC is counter-clockwise,\n// negative if clockwise, and zero if the points are collinear.\nfunction cross$1(a, b, c) {\n return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\n}\n\nfunction lexicographicOrder(a, b) {\n return a[0] - b[0] || a[1] - b[1];\n}\n\n// Computes the upper convex hull per the monotone chain algorithm.\n// Assumes points.length >= 3, is sorted by x, unique in y.\n// Returns an array of indices into points in left-to-right order.\nfunction computeUpperHullIndexes(points) {\n var n = points.length,\n indexes = [0, 1],\n size = 2;\n\n for (var i = 2; i < n; ++i) {\n while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;\n indexes[size++] = i;\n }\n\n return indexes.slice(0, size); // remove popped points\n}\n\nfunction hull(points) {\n if ((n = points.length) < 3) return null;\n\n var i,\n n,\n sortedPoints = new Array(n),\n flippedPoints = new Array(n);\n\n for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];\n sortedPoints.sort(lexicographicOrder);\n for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];\n\n var upperIndexes = computeUpperHullIndexes(sortedPoints),\n lowerIndexes = computeUpperHullIndexes(flippedPoints);\n\n // Construct the hull polygon, removing possible duplicate endpoints.\n var skipLeft = lowerIndexes[0] === upperIndexes[0],\n skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],\n hull = [];\n\n // Add upper hull in right-to-l order.\n // Then add lower hull in left-to-right order.\n for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);\n for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);\n\n return hull;\n}\n\nfunction contains$1(polygon, point) {\n var n = polygon.length,\n p = polygon[n - 1],\n x = point[0], y = point[1],\n x0 = p[0], y0 = p[1],\n x1, y1,\n inside = false;\n\n for (var i = 0; i < n; ++i) {\n p = polygon[i], x1 = p[0], y1 = p[1];\n if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;\n x0 = x1, y0 = y1;\n }\n\n return inside;\n}\n\nfunction length$2(polygon) {\n var i = -1,\n n = polygon.length,\n b = polygon[n - 1],\n xa,\n ya,\n xb = b[0],\n yb = b[1],\n perimeter = 0;\n\n while (++i < n) {\n xa = xb;\n ya = yb;\n b = polygon[i];\n xb = b[0];\n yb = b[1];\n xa -= xb;\n ya -= yb;\n perimeter += Math.sqrt(xa * xa + ya * ya);\n }\n\n return perimeter;\n}\n\nvar slice$4 = [].slice;\n\nvar noabort = {};\n\nfunction Queue(size) {\n this._size = size;\n this._call =\n this._error = null;\n this._tasks = [];\n this._data = [];\n this._waiting =\n this._active =\n this._ended =\n this._start = 0; // inside a synchronous task callback?\n}\n\nQueue.prototype = queue.prototype = {\n constructor: Queue,\n defer: function(callback) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback\");\n if (this._call) throw new Error(\"defer after await\");\n if (this._error != null) return this;\n var t = slice$4.call(arguments, 1);\n t.push(callback);\n ++this._waiting, this._tasks.push(t);\n poke$1(this);\n return this;\n },\n abort: function() {\n if (this._error == null) abort(this, new Error(\"abort\"));\n return this;\n },\n await: function(callback) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback\");\n if (this._call) throw new Error(\"multiple await\");\n this._call = function(error, results) { callback.apply(null, [error].concat(results)); };\n maybeNotify(this);\n return this;\n },\n awaitAll: function(callback) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback\");\n if (this._call) throw new Error(\"multiple await\");\n this._call = callback;\n maybeNotify(this);\n return this;\n }\n};\n\nfunction poke$1(q) {\n if (!q._start) {\n try { start$1(q); } // let the current task complete\n catch (e) {\n if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously\n else if (!q._data) throw e; // await callback errored synchronously\n }\n }\n}\n\nfunction start$1(q) {\n while (q._start = q._waiting && q._active < q._size) {\n var i = q._ended + q._active,\n t = q._tasks[i],\n j = t.length - 1,\n c = t[j];\n t[j] = end(q, i);\n --q._waiting, ++q._active;\n t = c.apply(null, t);\n if (!q._tasks[i]) continue; // task finished synchronously\n q._tasks[i] = t || noabort;\n }\n}\n\nfunction end(q, i) {\n return function(e, r) {\n if (!q._tasks[i]) return; // ignore multiple callbacks\n --q._active, ++q._ended;\n q._tasks[i] = null;\n if (q._error != null) return; // ignore secondary errors\n if (e != null) {\n abort(q, e);\n } else {\n q._data[i] = r;\n if (q._waiting) poke$1(q);\n else maybeNotify(q);\n }\n };\n}\n\nfunction abort(q, e) {\n var i = q._tasks.length, t;\n q._error = e; // ignore active callbacks\n q._data = undefined; // allow gc\n q._waiting = NaN; // prevent starting\n\n while (--i >= 0) {\n if (t = q._tasks[i]) {\n q._tasks[i] = null;\n if (t.abort) {\n try { t.abort(); }\n catch (e) { /* ignore */ }\n }\n }\n }\n\n q._active = NaN; // allow notification\n maybeNotify(q);\n}\n\nfunction maybeNotify(q) {\n if (!q._active && q._call) {\n var d = q._data;\n q._data = undefined; // allow gc\n q._call(q._error, d);\n }\n}\n\nfunction queue(concurrency) {\n if (concurrency == null) concurrency = Infinity;\n else if (!((concurrency = +concurrency) >= 1)) throw new Error(\"invalid concurrency\");\n return new Queue(concurrency);\n}\n\nfunction defaultSource$1() {\n return Math.random();\n}\n\nvar uniform = (function sourceRandomUniform(source) {\n function randomUniform(min, max) {\n min = min == null ? 0 : +min;\n max = max == null ? 1 : +max;\n if (arguments.length === 1) max = min, min = 0;\n else max -= min;\n return function() {\n return source() * max + min;\n };\n }\n\n randomUniform.source = sourceRandomUniform;\n\n return randomUniform;\n})(defaultSource$1);\n\nvar normal = (function sourceRandomNormal(source) {\n function randomNormal(mu, sigma) {\n var x, r;\n mu = mu == null ? 0 : +mu;\n sigma = sigma == null ? 1 : +sigma;\n return function() {\n var y;\n\n // If available, use the second previously-generated uniform random.\n if (x != null) y = x, x = null;\n\n // Otherwise, generate a new x and y.\n else do {\n x = source() * 2 - 1;\n y = source() * 2 - 1;\n r = x * x + y * y;\n } while (!r || r > 1);\n\n return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);\n };\n }\n\n randomNormal.source = sourceRandomNormal;\n\n return randomNormal;\n})(defaultSource$1);\n\nvar logNormal = (function sourceRandomLogNormal(source) {\n function randomLogNormal() {\n var randomNormal = normal.source(source).apply(this, arguments);\n return function() {\n return Math.exp(randomNormal());\n };\n }\n\n randomLogNormal.source = sourceRandomLogNormal;\n\n return randomLogNormal;\n})(defaultSource$1);\n\nvar irwinHall = (function sourceRandomIrwinHall(source) {\n function randomIrwinHall(n) {\n return function() {\n for (var sum = 0, i = 0; i < n; ++i) sum += source();\n return sum;\n };\n }\n\n randomIrwinHall.source = sourceRandomIrwinHall;\n\n return randomIrwinHall;\n})(defaultSource$1);\n\nvar bates = (function sourceRandomBates(source) {\n function randomBates(n) {\n var randomIrwinHall = irwinHall.source(source)(n);\n return function() {\n return randomIrwinHall() / n;\n };\n }\n\n randomBates.source = sourceRandomBates;\n\n return randomBates;\n})(defaultSource$1);\n\nvar exponential$1 = (function sourceRandomExponential(source) {\n function randomExponential(lambda) {\n return function() {\n return -Math.log(1 - source()) / lambda;\n };\n }\n\n randomExponential.source = sourceRandomExponential;\n\n return randomExponential;\n})(defaultSource$1);\n\nfunction request(url, callback) {\n var request,\n event = dispatch(\"beforesend\", \"progress\", \"load\", \"error\"),\n mimeType,\n headers = map$1(),\n xhr = new XMLHttpRequest,\n user = null,\n password = null,\n response,\n responseType,\n timeout = 0;\n\n // If IE does not support CORS, use XDomainRequest.\n if (typeof XDomainRequest !== \"undefined\"\n && !(\"withCredentials\" in xhr)\n && /^(http(s)?:)?\\/\\//.test(url)) xhr = new XDomainRequest;\n\n \"onload\" in xhr\n ? xhr.onload = xhr.onerror = xhr.ontimeout = respond\n : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };\n\n function respond(o) {\n var status = xhr.status, result;\n if (!status && hasResponse(xhr)\n || status >= 200 && status < 300\n || status === 304) {\n if (response) {\n try {\n result = response.call(request, xhr);\n } catch (e) {\n event.call(\"error\", request, e);\n return;\n }\n } else {\n result = xhr;\n }\n event.call(\"load\", request, result);\n } else {\n event.call(\"error\", request, o);\n }\n }\n\n xhr.onprogress = function(e) {\n event.call(\"progress\", request, e);\n };\n\n request = {\n header: function(name, value) {\n name = (name + \"\").toLowerCase();\n if (arguments.length < 2) return headers.get(name);\n if (value == null) headers.remove(name);\n else headers.set(name, value + \"\");\n return request;\n },\n\n // If mimeType is non-null and no Accept header is set, a default is used.\n mimeType: function(value) {\n if (!arguments.length) return mimeType;\n mimeType = value == null ? null : value + \"\";\n return request;\n },\n\n // Specifies what type the response value should take;\n // for instance, arraybuffer, blob, document, or text.\n responseType: function(value) {\n if (!arguments.length) return responseType;\n responseType = value;\n return request;\n },\n\n timeout: function(value) {\n if (!arguments.length) return timeout;\n timeout = +value;\n return request;\n },\n\n user: function(value) {\n return arguments.length < 1 ? user : (user = value == null ? null : value + \"\", request);\n },\n\n password: function(value) {\n return arguments.length < 1 ? password : (password = value == null ? null : value + \"\", request);\n },\n\n // Specify how to convert the response content to a specific type;\n // changes the callback value on \"load\" events.\n response: function(value) {\n response = value;\n return request;\n },\n\n // Alias for send(\"GET\", …).\n get: function(data, callback) {\n return request.send(\"GET\", data, callback);\n },\n\n // Alias for send(\"POST\", …).\n post: function(data, callback) {\n return request.send(\"POST\", data, callback);\n },\n\n // If callback is non-null, it will be used for error and load events.\n send: function(method, data, callback) {\n xhr.open(method, url, true, user, password);\n if (mimeType != null && !headers.has(\"accept\")) headers.set(\"accept\", mimeType + \",*/*\");\n if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });\n if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);\n if (responseType != null) xhr.responseType = responseType;\n if (timeout > 0) xhr.timeout = timeout;\n if (callback == null && typeof data === \"function\") callback = data, data = null;\n if (callback != null && callback.length === 1) callback = fixCallback(callback);\n if (callback != null) request.on(\"error\", callback).on(\"load\", function(xhr) { callback(null, xhr); });\n event.call(\"beforesend\", request, xhr);\n xhr.send(data == null ? null : data);\n return request;\n },\n\n abort: function() {\n xhr.abort();\n return request;\n },\n\n on: function() {\n var value = event.on.apply(event, arguments);\n return value === event ? request : value;\n }\n };\n\n if (callback != null) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n return request.get(callback);\n }\n\n return request;\n}\n\nfunction fixCallback(callback) {\n return function(error, xhr) {\n callback(error == null ? xhr : null);\n };\n}\n\nfunction hasResponse(xhr) {\n var type = xhr.responseType;\n return type && type !== \"text\"\n ? xhr.response // null on error\n : xhr.responseText; // \"\" on error\n}\n\nfunction type$1(defaultMimeType, response) {\n return function(url, callback) {\n var r = request(url).mimeType(defaultMimeType).response(response);\n if (callback != null) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n return r.get(callback);\n }\n return r;\n };\n}\n\nvar html = type$1(\"text/html\", function(xhr) {\n return document.createRange().createContextualFragment(xhr.responseText);\n});\n\nvar json = type$1(\"application/json\", function(xhr) {\n return JSON.parse(xhr.responseText);\n});\n\nvar text = type$1(\"text/plain\", function(xhr) {\n return xhr.responseText;\n});\n\nvar xml = type$1(\"application/xml\", function(xhr) {\n var xml = xhr.responseXML;\n if (!xml) throw new Error(\"parse error\");\n return xml;\n});\n\nfunction dsv$1(defaultMimeType, parse) {\n return function(url, row, callback) {\n if (arguments.length < 3) callback = row, row = null;\n var r = request(url).mimeType(defaultMimeType);\n r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };\n r.row(row);\n return callback ? r.get(callback) : r;\n };\n}\n\nfunction responseOf(parse, row) {\n return function(request$$1) {\n return parse(request$$1.responseText, row);\n };\n}\n\nvar csv$1 = dsv$1(\"text/csv\", csvParse);\n\nvar tsv$1 = dsv$1(\"text/tab-separated-values\", tsvParse);\n\nvar array$2 = Array.prototype;\n\nvar map$3 = array$2.map;\nvar slice$5 = array$2.slice;\n\nvar implicit = {name: \"implicit\"};\n\nfunction ordinal(range) {\n var index = map$1(),\n domain = [],\n unknown = implicit;\n\n range = range == null ? [] : slice$5.call(range);\n\n function scale(d) {\n var key = d + \"\", i = index.get(key);\n if (!i) {\n if (unknown !== implicit) return unknown;\n index.set(key, i = domain.push(d));\n }\n return range[(i - 1) % range.length];\n }\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [], index = map$1();\n var i = -1, n = _.length, d, key;\n while (++i < n) if (!index.has(key = (d = _[i]) + \"\")) index.set(key, domain.push(d));\n return scale;\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice$5.call(_), scale) : range.slice();\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.copy = function() {\n return ordinal()\n .domain(domain)\n .range(range)\n .unknown(unknown);\n };\n\n return scale;\n}\n\nfunction band() {\n var scale = ordinal().unknown(undefined),\n domain = scale.domain,\n ordinalRange = scale.range,\n range$$1 = [0, 1],\n step,\n bandwidth,\n round = false,\n paddingInner = 0,\n paddingOuter = 0,\n align = 0.5;\n\n delete scale.unknown;\n\n function rescale() {\n var n = domain().length,\n reverse = range$$1[1] < range$$1[0],\n start = range$$1[reverse - 0],\n stop = range$$1[1 - reverse];\n step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);\n if (round) step = Math.floor(step);\n start += (stop - start - step * (n - paddingInner)) * align;\n bandwidth = step * (1 - paddingInner);\n if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);\n var values = sequence(n).map(function(i) { return start + step * i; });\n return ordinalRange(reverse ? values.reverse() : values);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();\n };\n\n scale.rangeRound = function(_) {\n return range$$1 = [+_[0], +_[1]], round = true, rescale();\n };\n\n scale.bandwidth = function() {\n return bandwidth;\n };\n\n scale.step = function() {\n return step;\n };\n\n scale.round = function(_) {\n return arguments.length ? (round = !!_, rescale()) : round;\n };\n\n scale.padding = function(_) {\n return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n };\n\n scale.paddingInner = function(_) {\n return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n };\n\n scale.paddingOuter = function(_) {\n return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;\n };\n\n scale.align = function(_) {\n return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;\n };\n\n scale.copy = function() {\n return band()\n .domain(domain())\n .range(range$$1)\n .round(round)\n .paddingInner(paddingInner)\n .paddingOuter(paddingOuter)\n .align(align);\n };\n\n return rescale();\n}\n\nfunction pointish(scale) {\n var copy = scale.copy;\n\n scale.padding = scale.paddingOuter;\n delete scale.paddingInner;\n delete scale.paddingOuter;\n\n scale.copy = function() {\n return pointish(copy());\n };\n\n return scale;\n}\n\nfunction point$1() {\n return pointish(band().paddingInner(1));\n}\n\nfunction constant$9(x) {\n return function() {\n return x;\n };\n}\n\nfunction number$2(x) {\n return +x;\n}\n\nvar unit = [0, 1];\n\nfunction deinterpolateLinear(a, b) {\n return (b -= (a = +a))\n ? function(x) { return (x - a) / b; }\n : constant$9(b);\n}\n\nfunction deinterpolateClamp(deinterpolate) {\n return function(a, b) {\n var d = deinterpolate(a = +a, b = +b);\n return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };\n };\n}\n\nfunction reinterpolateClamp(reinterpolate) {\n return function(a, b) {\n var r = reinterpolate(a = +a, b = +b);\n return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };\n };\n}\n\nfunction bimap(domain, range, deinterpolate, reinterpolate) {\n var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];\n if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);\n else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);\n return function(x) { return r0(d0(x)); };\n}\n\nfunction polymap(domain, range, deinterpolate, reinterpolate) {\n var j = Math.min(domain.length, range.length) - 1,\n d = new Array(j),\n r = new Array(j),\n i = -1;\n\n // Reverse descending domains.\n if (domain[j] < domain[0]) {\n domain = domain.slice().reverse();\n range = range.slice().reverse();\n }\n\n while (++i < j) {\n d[i] = deinterpolate(domain[i], domain[i + 1]);\n r[i] = reinterpolate(range[i], range[i + 1]);\n }\n\n return function(x) {\n var i = bisectRight(domain, x, 1, j) - 1;\n return r[i](d[i](x));\n };\n}\n\nfunction copy(source, target) {\n return target\n .domain(source.domain())\n .range(source.range())\n .interpolate(source.interpolate())\n .clamp(source.clamp());\n}\n\n// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].\n// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].\nfunction continuous(deinterpolate, reinterpolate) {\n var domain = unit,\n range = unit,\n interpolate$$1 = interpolateValue,\n clamp = false,\n piecewise,\n output,\n input;\n\n function rescale() {\n piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap;\n output = input = null;\n return scale;\n }\n\n function scale(x) {\n return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);\n }\n\n scale.invert = function(y) {\n return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();\n };\n\n scale.rangeRound = function(_) {\n return range = slice$5.call(_), interpolate$$1 = interpolateRound, rescale();\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, rescale()) : clamp;\n };\n\n scale.interpolate = function(_) {\n return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;\n };\n\n return rescale();\n}\n\nfunction tickFormat(domain, count, specifier) {\n var start = domain[0],\n stop = domain[domain.length - 1],\n step = tickStep(start, stop, count == null ? 10 : count),\n precision;\n specifier = formatSpecifier(specifier == null ? \",f\" : specifier);\n switch (specifier.type) {\n case \"s\": {\n var value = Math.max(Math.abs(start), Math.abs(stop));\n if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n return exports.formatPrefix(specifier, value);\n }\n case \"\":\n case \"e\":\n case \"g\":\n case \"p\":\n case \"r\": {\n if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === \"e\");\n break;\n }\n case \"f\":\n case \"%\": {\n if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === \"%\") * 2;\n break;\n }\n }\n return exports.format(specifier);\n}\n\nfunction linearish(scale) {\n var domain = scale.domain;\n\n scale.ticks = function(count) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], count == null ? 10 : count);\n };\n\n scale.tickFormat = function(count, specifier) {\n return tickFormat(domain(), count, specifier);\n };\n\n scale.nice = function(count) {\n if (count == null) count = 10;\n\n var d = domain(),\n i0 = 0,\n i1 = d.length - 1,\n start = d[i0],\n stop = d[i1],\n step;\n\n if (stop < start) {\n step = start, start = stop, stop = step;\n step = i0, i0 = i1, i1 = step;\n }\n\n step = tickIncrement(start, stop, count);\n\n if (step > 0) {\n start = Math.floor(start / step) * step;\n stop = Math.ceil(stop / step) * step;\n step = tickIncrement(start, stop, count);\n } else if (step < 0) {\n start = Math.ceil(start * step) / step;\n stop = Math.floor(stop * step) / step;\n step = tickIncrement(start, stop, count);\n }\n\n if (step > 0) {\n d[i0] = Math.floor(start / step) * step;\n d[i1] = Math.ceil(stop / step) * step;\n domain(d);\n } else if (step < 0) {\n d[i0] = Math.ceil(start * step) / step;\n d[i1] = Math.floor(stop * step) / step;\n domain(d);\n }\n\n return scale;\n };\n\n return scale;\n}\n\nfunction linear$2() {\n var scale = continuous(deinterpolateLinear, reinterpolate);\n\n scale.copy = function() {\n return copy(scale, linear$2());\n };\n\n return linearish(scale);\n}\n\nfunction identity$6() {\n var domain = [0, 1];\n\n function scale(x) {\n return +x;\n }\n\n scale.invert = scale;\n\n scale.domain = scale.range = function(_) {\n return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice();\n };\n\n scale.copy = function() {\n return identity$6().domain(domain);\n };\n\n return linearish(scale);\n}\n\nfunction nice(domain, interval) {\n domain = domain.slice();\n\n var i0 = 0,\n i1 = domain.length - 1,\n x0 = domain[i0],\n x1 = domain[i1],\n t;\n\n if (x1 < x0) {\n t = i0, i0 = i1, i1 = t;\n t = x0, x0 = x1, x1 = t;\n }\n\n domain[i0] = interval.floor(x0);\n domain[i1] = interval.ceil(x1);\n return domain;\n}\n\nfunction deinterpolate(a, b) {\n return (b = Math.log(b / a))\n ? function(x) { return Math.log(x / a) / b; }\n : constant$9(b);\n}\n\nfunction reinterpolate$1(a, b) {\n return a < 0\n ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }\n : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };\n}\n\nfunction pow10(x) {\n return isFinite(x) ? +(\"1e\" + x) : x < 0 ? 0 : x;\n}\n\nfunction powp(base) {\n return base === 10 ? pow10\n : base === Math.E ? Math.exp\n : function(x) { return Math.pow(base, x); };\n}\n\nfunction logp(base) {\n return base === Math.E ? Math.log\n : base === 10 && Math.log10\n || base === 2 && Math.log2\n || (base = Math.log(base), function(x) { return Math.log(x) / base; });\n}\n\nfunction reflect(f) {\n return function(x) {\n return -f(-x);\n };\n}\n\nfunction log$1() {\n var scale = continuous(deinterpolate, reinterpolate$1).domain([1, 10]),\n domain = scale.domain,\n base = 10,\n logs = logp(10),\n pows = powp(10);\n\n function rescale() {\n logs = logp(base), pows = powp(base);\n if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);\n return scale;\n }\n\n scale.base = function(_) {\n return arguments.length ? (base = +_, rescale()) : base;\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.ticks = function(count) {\n var d = domain(),\n u = d[0],\n v = d[d.length - 1],\n r;\n\n if (r = v < u) i = u, u = v, v = i;\n\n var i = logs(u),\n j = logs(v),\n p,\n k,\n t,\n n = count == null ? 10 : +count,\n z = [];\n\n if (!(base % 1) && j - i < n) {\n i = Math.round(i) - 1, j = Math.round(j) + 1;\n if (u > 0) for (; i < j; ++i) {\n for (k = 1, p = pows(i); k < base; ++k) {\n t = p * k;\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n } else for (; i < j; ++i) {\n for (k = base - 1, p = pows(i); k >= 1; --k) {\n t = p * k;\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n }\n } else {\n z = ticks(i, j, Math.min(j - i, n)).map(pows);\n }\n\n return r ? z.reverse() : z;\n };\n\n scale.tickFormat = function(count, specifier) {\n if (specifier == null) specifier = base === 10 ? \".0e\" : \",\";\n if (typeof specifier !== \"function\") specifier = exports.format(specifier);\n if (count === Infinity) return specifier;\n if (count == null) count = 10;\n var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?\n return function(d) {\n var i = d / pows(Math.round(logs(d)));\n if (i * base < base - 0.5) i *= base;\n return i <= k ? specifier(d) : \"\";\n };\n };\n\n scale.nice = function() {\n return domain(nice(domain(), {\n floor: function(x) { return pows(Math.floor(logs(x))); },\n ceil: function(x) { return pows(Math.ceil(logs(x))); }\n }));\n };\n\n scale.copy = function() {\n return copy(scale, log$1().base(base));\n };\n\n return scale;\n}\n\nfunction raise$1(x, exponent) {\n return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);\n}\n\nfunction pow$1() {\n var exponent = 1,\n scale = continuous(deinterpolate, reinterpolate),\n domain = scale.domain;\n\n function deinterpolate(a, b) {\n return (b = raise$1(b, exponent) - (a = raise$1(a, exponent)))\n ? function(x) { return (raise$1(x, exponent) - a) / b; }\n : constant$9(b);\n }\n\n function reinterpolate(a, b) {\n b = raise$1(b, exponent) - (a = raise$1(a, exponent));\n return function(t) { return raise$1(a + b * t, 1 / exponent); };\n }\n\n scale.exponent = function(_) {\n return arguments.length ? (exponent = +_, domain(domain())) : exponent;\n };\n\n scale.copy = function() {\n return copy(scale, pow$1().exponent(exponent));\n };\n\n return linearish(scale);\n}\n\nfunction sqrt$1() {\n return pow$1().exponent(0.5);\n}\n\nfunction quantile$$1() {\n var domain = [],\n range = [],\n thresholds = [];\n\n function rescale() {\n var i = 0, n = Math.max(1, range.length);\n thresholds = new Array(n - 1);\n while (++i < n) thresholds[i - 1] = threshold(domain, i / n);\n return scale;\n }\n\n function scale(x) {\n if (!isNaN(x = +x)) return range[bisectRight(thresholds, x)];\n }\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN] : [\n i > 0 ? thresholds[i - 1] : domain[0],\n i < thresholds.length ? thresholds[i] : domain[domain.length - 1]\n ];\n };\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [];\n for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);\n domain.sort(ascending);\n return rescale();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();\n };\n\n scale.quantiles = function() {\n return thresholds.slice();\n };\n\n scale.copy = function() {\n return quantile$$1()\n .domain(domain)\n .range(range);\n };\n\n return scale;\n}\n\nfunction quantize$1() {\n var x0 = 0,\n x1 = 1,\n n = 1,\n domain = [0.5],\n range = [0, 1];\n\n function scale(x) {\n if (x <= x) return range[bisectRight(domain, x, 0, n)];\n }\n\n function rescale() {\n var i = -1;\n domain = new Array(n);\n while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);\n return scale;\n }\n\n scale.domain = function(_) {\n return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];\n };\n\n scale.range = function(_) {\n return arguments.length ? (n = (range = slice$5.call(_)).length - 1, rescale()) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN]\n : i < 1 ? [x0, domain[0]]\n : i >= n ? [domain[n - 1], x1]\n : [domain[i - 1], domain[i]];\n };\n\n scale.copy = function() {\n return quantize$1()\n .domain([x0, x1])\n .range(range);\n };\n\n return linearish(scale);\n}\n\nfunction threshold$1() {\n var domain = [0.5],\n range = [0, 1],\n n = 1;\n\n function scale(x) {\n if (x <= x) return range[bisectRight(domain, x, 0, n)];\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return [domain[i - 1], domain[i]];\n };\n\n scale.copy = function() {\n return threshold$1()\n .domain(domain)\n .range(range);\n };\n\n return scale;\n}\n\nvar t0$1 = new Date;\nvar t1$1 = new Date;\n\nfunction newInterval(floori, offseti, count, field) {\n\n function interval(date) {\n return floori(date = new Date(+date)), date;\n }\n\n interval.floor = interval;\n\n interval.ceil = function(date) {\n return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;\n };\n\n interval.round = function(date) {\n var d0 = interval(date),\n d1 = interval.ceil(date);\n return date - d0 < d1 - date ? d0 : d1;\n };\n\n interval.offset = function(date, step) {\n return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n };\n\n interval.range = function(start, stop, step) {\n var range = [], previous;\n start = interval.ceil(start);\n step = step == null ? 1 : Math.floor(step);\n if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n do range.push(previous = new Date(+start)), offseti(start, step), floori(start);\n while (previous < start && start < stop);\n return range;\n };\n\n interval.filter = function(test) {\n return newInterval(function(date) {\n if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);\n }, function(date, step) {\n if (date >= date) {\n if (step < 0) while (++step <= 0) {\n while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty\n } else while (--step >= 0) {\n while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty\n }\n }\n });\n };\n\n if (count) {\n interval.count = function(start, end) {\n t0$1.setTime(+start), t1$1.setTime(+end);\n floori(t0$1), floori(t1$1);\n return Math.floor(count(t0$1, t1$1));\n };\n\n interval.every = function(step) {\n step = Math.floor(step);\n return !isFinite(step) || !(step > 0) ? null\n : !(step > 1) ? interval\n : interval.filter(field\n ? function(d) { return field(d) % step === 0; }\n : function(d) { return interval.count(0, d) % step === 0; });\n };\n }\n\n return interval;\n}\n\nvar millisecond = newInterval(function() {\n // noop\n}, function(date, step) {\n date.setTime(+date + step);\n}, function(start, end) {\n return end - start;\n});\n\n// An optimized implementation for this simple case.\nmillisecond.every = function(k) {\n k = Math.floor(k);\n if (!isFinite(k) || !(k > 0)) return null;\n if (!(k > 1)) return millisecond;\n return newInterval(function(date) {\n date.setTime(Math.floor(date / k) * k);\n }, function(date, step) {\n date.setTime(+date + step * k);\n }, function(start, end) {\n return (end - start) / k;\n });\n};\n\nvar milliseconds = millisecond.range;\n\nvar durationSecond$1 = 1e3;\nvar durationMinute$1 = 6e4;\nvar durationHour$1 = 36e5;\nvar durationDay$1 = 864e5;\nvar durationWeek$1 = 6048e5;\n\nvar second = newInterval(function(date) {\n date.setTime(Math.floor(date / durationSecond$1) * durationSecond$1);\n}, function(date, step) {\n date.setTime(+date + step * durationSecond$1);\n}, function(start, end) {\n return (end - start) / durationSecond$1;\n}, function(date) {\n return date.getUTCSeconds();\n});\n\nvar seconds = second.range;\n\nvar minute = newInterval(function(date) {\n date.setTime(Math.floor(date / durationMinute$1) * durationMinute$1);\n}, function(date, step) {\n date.setTime(+date + step * durationMinute$1);\n}, function(start, end) {\n return (end - start) / durationMinute$1;\n}, function(date) {\n return date.getMinutes();\n});\n\nvar minutes = minute.range;\n\nvar hour = newInterval(function(date) {\n var offset = date.getTimezoneOffset() * durationMinute$1 % durationHour$1;\n if (offset < 0) offset += durationHour$1;\n date.setTime(Math.floor((+date - offset) / durationHour$1) * durationHour$1 + offset);\n}, function(date, step) {\n date.setTime(+date + step * durationHour$1);\n}, function(start, end) {\n return (end - start) / durationHour$1;\n}, function(date) {\n return date.getHours();\n});\n\nvar hours = hour.range;\n\nvar day = newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setDate(date.getDate() + step);\n}, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationDay$1;\n}, function(date) {\n return date.getDate() - 1;\n});\n\nvar days = day.range;\n\nfunction weekday(i) {\n return newInterval(function(date) {\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setDate(date.getDate() + step * 7);\n }, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationWeek$1;\n });\n}\n\nvar sunday = weekday(0);\nvar monday = weekday(1);\nvar tuesday = weekday(2);\nvar wednesday = weekday(3);\nvar thursday = weekday(4);\nvar friday = weekday(5);\nvar saturday = weekday(6);\n\nvar sundays = sunday.range;\nvar mondays = monday.range;\nvar tuesdays = tuesday.range;\nvar wednesdays = wednesday.range;\nvar thursdays = thursday.range;\nvar fridays = friday.range;\nvar saturdays = saturday.range;\n\nvar month = newInterval(function(date) {\n date.setDate(1);\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setMonth(date.getMonth() + step);\n}, function(start, end) {\n return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n}, function(date) {\n return date.getMonth();\n});\n\nvar months = month.range;\n\nvar year = newInterval(function(date) {\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setFullYear(date.getFullYear() + step);\n}, function(start, end) {\n return end.getFullYear() - start.getFullYear();\n}, function(date) {\n return date.getFullYear();\n});\n\n// An optimized implementation for this simple case.\nyear.every = function(k) {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {\n date.setFullYear(Math.floor(date.getFullYear() / k) * k);\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setFullYear(date.getFullYear() + step * k);\n });\n};\n\nvar years = year.range;\n\nvar utcMinute = newInterval(function(date) {\n date.setUTCSeconds(0, 0);\n}, function(date, step) {\n date.setTime(+date + step * durationMinute$1);\n}, function(start, end) {\n return (end - start) / durationMinute$1;\n}, function(date) {\n return date.getUTCMinutes();\n});\n\nvar utcMinutes = utcMinute.range;\n\nvar utcHour = newInterval(function(date) {\n date.setUTCMinutes(0, 0, 0);\n}, function(date, step) {\n date.setTime(+date + step * durationHour$1);\n}, function(start, end) {\n return (end - start) / durationHour$1;\n}, function(date) {\n return date.getUTCHours();\n});\n\nvar utcHours = utcHour.range;\n\nvar utcDay = newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step);\n}, function(start, end) {\n return (end - start) / durationDay$1;\n}, function(date) {\n return date.getUTCDate() - 1;\n});\n\nvar utcDays = utcDay.range;\n\nfunction utcWeekday(i) {\n return newInterval(function(date) {\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, function(start, end) {\n return (end - start) / durationWeek$1;\n });\n}\n\nvar utcSunday = utcWeekday(0);\nvar utcMonday = utcWeekday(1);\nvar utcTuesday = utcWeekday(2);\nvar utcWednesday = utcWeekday(3);\nvar utcThursday = utcWeekday(4);\nvar utcFriday = utcWeekday(5);\nvar utcSaturday = utcWeekday(6);\n\nvar utcSundays = utcSunday.range;\nvar utcMondays = utcMonday.range;\nvar utcTuesdays = utcTuesday.range;\nvar utcWednesdays = utcWednesday.range;\nvar utcThursdays = utcThursday.range;\nvar utcFridays = utcFriday.range;\nvar utcSaturdays = utcSaturday.range;\n\nvar utcMonth = newInterval(function(date) {\n date.setUTCDate(1);\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCMonth(date.getUTCMonth() + step);\n}, function(start, end) {\n return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n}, function(date) {\n return date.getUTCMonth();\n});\n\nvar utcMonths = utcMonth.range;\n\nvar utcYear = newInterval(function(date) {\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n}, function(start, end) {\n return end.getUTCFullYear() - start.getUTCFullYear();\n}, function(date) {\n return date.getUTCFullYear();\n});\n\n// An optimized implementation for this simple case.\nutcYear.every = function(k) {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {\n date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step * k);\n });\n};\n\nvar utcYears = utcYear.range;\n\nfunction localDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);\n date.setFullYear(d.y);\n return date;\n }\n return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);\n}\n\nfunction utcDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));\n date.setUTCFullYear(d.y);\n return date;\n }\n return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));\n}\n\nfunction newYear(y) {\n return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};\n}\n\nfunction formatLocale$1(locale) {\n var locale_dateTime = locale.dateTime,\n locale_date = locale.date,\n locale_time = locale.time,\n locale_periods = locale.periods,\n locale_weekdays = locale.days,\n locale_shortWeekdays = locale.shortDays,\n locale_months = locale.months,\n locale_shortMonths = locale.shortMonths;\n\n var periodRe = formatRe(locale_periods),\n periodLookup = formatLookup(locale_periods),\n weekdayRe = formatRe(locale_weekdays),\n weekdayLookup = formatLookup(locale_weekdays),\n shortWeekdayRe = formatRe(locale_shortWeekdays),\n shortWeekdayLookup = formatLookup(locale_shortWeekdays),\n monthRe = formatRe(locale_months),\n monthLookup = formatLookup(locale_months),\n shortMonthRe = formatRe(locale_shortMonths),\n shortMonthLookup = formatLookup(locale_shortMonths);\n\n var formats = {\n \"a\": formatShortWeekday,\n \"A\": formatWeekday,\n \"b\": formatShortMonth,\n \"B\": formatMonth,\n \"c\": null,\n \"d\": formatDayOfMonth,\n \"e\": formatDayOfMonth,\n \"f\": formatMicroseconds,\n \"H\": formatHour24,\n \"I\": formatHour12,\n \"j\": formatDayOfYear,\n \"L\": formatMilliseconds,\n \"m\": formatMonthNumber,\n \"M\": formatMinutes,\n \"p\": formatPeriod,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatSeconds,\n \"u\": formatWeekdayNumberMonday,\n \"U\": formatWeekNumberSunday,\n \"V\": formatWeekNumberISO,\n \"w\": formatWeekdayNumberSunday,\n \"W\": formatWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatYear,\n \"Y\": formatFullYear,\n \"Z\": formatZone,\n \"%\": formatLiteralPercent\n };\n\n var utcFormats = {\n \"a\": formatUTCShortWeekday,\n \"A\": formatUTCWeekday,\n \"b\": formatUTCShortMonth,\n \"B\": formatUTCMonth,\n \"c\": null,\n \"d\": formatUTCDayOfMonth,\n \"e\": formatUTCDayOfMonth,\n \"f\": formatUTCMicroseconds,\n \"H\": formatUTCHour24,\n \"I\": formatUTCHour12,\n \"j\": formatUTCDayOfYear,\n \"L\": formatUTCMilliseconds,\n \"m\": formatUTCMonthNumber,\n \"M\": formatUTCMinutes,\n \"p\": formatUTCPeriod,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatUTCSeconds,\n \"u\": formatUTCWeekdayNumberMonday,\n \"U\": formatUTCWeekNumberSunday,\n \"V\": formatUTCWeekNumberISO,\n \"w\": formatUTCWeekdayNumberSunday,\n \"W\": formatUTCWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatUTCYear,\n \"Y\": formatUTCFullYear,\n \"Z\": formatUTCZone,\n \"%\": formatLiteralPercent\n };\n\n var parses = {\n \"a\": parseShortWeekday,\n \"A\": parseWeekday,\n \"b\": parseShortMonth,\n \"B\": parseMonth,\n \"c\": parseLocaleDateTime,\n \"d\": parseDayOfMonth,\n \"e\": parseDayOfMonth,\n \"f\": parseMicroseconds,\n \"H\": parseHour24,\n \"I\": parseHour24,\n \"j\": parseDayOfYear,\n \"L\": parseMilliseconds,\n \"m\": parseMonthNumber,\n \"M\": parseMinutes,\n \"p\": parsePeriod,\n \"Q\": parseUnixTimestamp,\n \"s\": parseUnixTimestampSeconds,\n \"S\": parseSeconds,\n \"u\": parseWeekdayNumberMonday,\n \"U\": parseWeekNumberSunday,\n \"V\": parseWeekNumberISO,\n \"w\": parseWeekdayNumberSunday,\n \"W\": parseWeekNumberMonday,\n \"x\": parseLocaleDate,\n \"X\": parseLocaleTime,\n \"y\": parseYear,\n \"Y\": parseFullYear,\n \"Z\": parseZone,\n \"%\": parseLiteralPercent\n };\n\n // These recursive directive definitions must be deferred.\n formats.x = newFormat(locale_date, formats);\n formats.X = newFormat(locale_time, formats);\n formats.c = newFormat(locale_dateTime, formats);\n utcFormats.x = newFormat(locale_date, utcFormats);\n utcFormats.X = newFormat(locale_time, utcFormats);\n utcFormats.c = newFormat(locale_dateTime, utcFormats);\n\n function newFormat(specifier, formats) {\n return function(date) {\n var string = [],\n i = -1,\n j = 0,\n n = specifier.length,\n c,\n pad,\n format;\n\n if (!(date instanceof Date)) date = new Date(+date);\n\n while (++i < n) {\n if (specifier.charCodeAt(i) === 37) {\n string.push(specifier.slice(j, i));\n if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);\n else pad = c === \"e\" ? \" \" : \"0\";\n if (format = formats[c]) c = format(date, pad);\n string.push(c);\n j = i + 1;\n }\n }\n\n string.push(specifier.slice(j, i));\n return string.join(\"\");\n };\n }\n\n function newParse(specifier, newDate) {\n return function(string) {\n var d = newYear(1900),\n i = parseSpecifier(d, specifier, string += \"\", 0),\n week, day$$1;\n if (i != string.length) return null;\n\n // If a UNIX timestamp is specified, return it.\n if (\"Q\" in d) return new Date(d.Q);\n\n // The am-pm flag is 0 for AM, and 1 for PM.\n if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n\n // Convert day-of-week and week-of-year to day-of-year.\n if (\"V\" in d) {\n if (d.V < 1 || d.V > 53) return null;\n if (!(\"w\" in d)) d.w = 1;\n if (\"Z\" in d) {\n week = utcDate(newYear(d.y)), day$$1 = week.getUTCDay();\n week = day$$1 > 4 || day$$1 === 0 ? utcMonday.ceil(week) : utcMonday(week);\n week = utcDay.offset(week, (d.V - 1) * 7);\n d.y = week.getUTCFullYear();\n d.m = week.getUTCMonth();\n d.d = week.getUTCDate() + (d.w + 6) % 7;\n } else {\n week = newDate(newYear(d.y)), day$$1 = week.getDay();\n week = day$$1 > 4 || day$$1 === 0 ? monday.ceil(week) : monday(week);\n week = day.offset(week, (d.V - 1) * 7);\n d.y = week.getFullYear();\n d.m = week.getMonth();\n d.d = week.getDate() + (d.w + 6) % 7;\n }\n } else if (\"W\" in d || \"U\" in d) {\n if (!(\"w\" in d)) d.w = \"u\" in d ? d.u % 7 : \"W\" in d ? 1 : 0;\n day$$1 = \"Z\" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();\n d.m = 0;\n d.d = \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7;\n }\n\n // If a time zone is specified, all fields are interpreted as UTC and then\n // offset according to the specified time zone.\n if (\"Z\" in d) {\n d.H += d.Z / 100 | 0;\n d.M += d.Z % 100;\n return utcDate(d);\n }\n\n // Otherwise, all fields are in local time.\n return newDate(d);\n };\n }\n\n function parseSpecifier(d, specifier, string, j) {\n var i = 0,\n n = specifier.length,\n m = string.length,\n c,\n parse;\n\n while (i < n) {\n if (j >= m) return -1;\n c = specifier.charCodeAt(i++);\n if (c === 37) {\n c = specifier.charAt(i++);\n parse = parses[c in pads ? specifier.charAt(i++) : c];\n if (!parse || ((j = parse(d, string, j)) < 0)) return -1;\n } else if (c != string.charCodeAt(j++)) {\n return -1;\n }\n }\n\n return j;\n }\n\n function parsePeriod(d, string, i) {\n var n = periodRe.exec(string.slice(i));\n return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseShortWeekday(d, string, i) {\n var n = shortWeekdayRe.exec(string.slice(i));\n return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseWeekday(d, string, i) {\n var n = weekdayRe.exec(string.slice(i));\n return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseShortMonth(d, string, i) {\n var n = shortMonthRe.exec(string.slice(i));\n return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseMonth(d, string, i) {\n var n = monthRe.exec(string.slice(i));\n return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseLocaleDateTime(d, string, i) {\n return parseSpecifier(d, locale_dateTime, string, i);\n }\n\n function parseLocaleDate(d, string, i) {\n return parseSpecifier(d, locale_date, string, i);\n }\n\n function parseLocaleTime(d, string, i) {\n return parseSpecifier(d, locale_time, string, i);\n }\n\n function formatShortWeekday(d) {\n return locale_shortWeekdays[d.getDay()];\n }\n\n function formatWeekday(d) {\n return locale_weekdays[d.getDay()];\n }\n\n function formatShortMonth(d) {\n return locale_shortMonths[d.getMonth()];\n }\n\n function formatMonth(d) {\n return locale_months[d.getMonth()];\n }\n\n function formatPeriod(d) {\n return locale_periods[+(d.getHours() >= 12)];\n }\n\n function formatUTCShortWeekday(d) {\n return locale_shortWeekdays[d.getUTCDay()];\n }\n\n function formatUTCWeekday(d) {\n return locale_weekdays[d.getUTCDay()];\n }\n\n function formatUTCShortMonth(d) {\n return locale_shortMonths[d.getUTCMonth()];\n }\n\n function formatUTCMonth(d) {\n return locale_months[d.getUTCMonth()];\n }\n\n function formatUTCPeriod(d) {\n return locale_periods[+(d.getUTCHours() >= 12)];\n }\n\n return {\n format: function(specifier) {\n var f = newFormat(specifier += \"\", formats);\n f.toString = function() { return specifier; };\n return f;\n },\n parse: function(specifier) {\n var p = newParse(specifier += \"\", localDate);\n p.toString = function() { return specifier; };\n return p;\n },\n utcFormat: function(specifier) {\n var f = newFormat(specifier += \"\", utcFormats);\n f.toString = function() { return specifier; };\n return f;\n },\n utcParse: function(specifier) {\n var p = newParse(specifier, utcDate);\n p.toString = function() { return specifier; };\n return p;\n }\n };\n}\n\nvar pads = {\"-\": \"\", \"_\": \" \", \"0\": \"0\"};\nvar numberRe = /^\\s*\\d+/;\nvar percentRe = /^%/;\nvar requoteRe = /[\\\\^$*+?|[\\]().{}]/g;\n\nfunction pad(value, fill, width) {\n var sign = value < 0 ? \"-\" : \"\",\n string = (sign ? -value : value) + \"\",\n length = string.length;\n return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n}\n\nfunction requote(s) {\n return s.replace(requoteRe, \"\\\\$&\");\n}\n\nfunction formatRe(names) {\n return new RegExp(\"^(?:\" + names.map(requote).join(\"|\") + \")\", \"i\");\n}\n\nfunction formatLookup(names) {\n var map = {}, i = -1, n = names.length;\n while (++i < n) map[names[i].toLowerCase()] = i;\n return map;\n}\n\nfunction parseWeekdayNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.w = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekdayNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.u = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.U = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberISO(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.V = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.W = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseFullYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 4));\n return n ? (d.y = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;\n}\n\nfunction parseZone(d, string, i) {\n var n = /^(Z)|([+-]\\d\\d)(?::?(\\d\\d))?/.exec(string.slice(i, i + 6));\n return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || \"00\")), i + n[0].length) : -1;\n}\n\nfunction parseMonthNumber(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.m = n[0] - 1, i + n[0].length) : -1;\n}\n\nfunction parseDayOfMonth(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseDayOfYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseHour24(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.H = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMinutes(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.M = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.S = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMilliseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.L = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMicroseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 6));\n return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;\n}\n\nfunction parseLiteralPercent(d, string, i) {\n var n = percentRe.exec(string.slice(i, i + 1));\n return n ? i + n[0].length : -1;\n}\n\nfunction parseUnixTimestamp(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseUnixTimestampSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = (+n[0]) * 1000, i + n[0].length) : -1;\n}\n\nfunction formatDayOfMonth(d, p) {\n return pad(d.getDate(), p, 2);\n}\n\nfunction formatHour24(d, p) {\n return pad(d.getHours(), p, 2);\n}\n\nfunction formatHour12(d, p) {\n return pad(d.getHours() % 12 || 12, p, 2);\n}\n\nfunction formatDayOfYear(d, p) {\n return pad(1 + day.count(year(d), d), p, 3);\n}\n\nfunction formatMilliseconds(d, p) {\n return pad(d.getMilliseconds(), p, 3);\n}\n\nfunction formatMicroseconds(d, p) {\n return formatMilliseconds(d, p) + \"000\";\n}\n\nfunction formatMonthNumber(d, p) {\n return pad(d.getMonth() + 1, p, 2);\n}\n\nfunction formatMinutes(d, p) {\n return pad(d.getMinutes(), p, 2);\n}\n\nfunction formatSeconds(d, p) {\n return pad(d.getSeconds(), p, 2);\n}\n\nfunction formatWeekdayNumberMonday(d) {\n var day$$1 = d.getDay();\n return day$$1 === 0 ? 7 : day$$1;\n}\n\nfunction formatWeekNumberSunday(d, p) {\n return pad(sunday.count(year(d), d), p, 2);\n}\n\nfunction formatWeekNumberISO(d, p) {\n var day$$1 = d.getDay();\n d = (day$$1 >= 4 || day$$1 === 0) ? thursday(d) : thursday.ceil(d);\n return pad(thursday.count(year(d), d) + (year(d).getDay() === 4), p, 2);\n}\n\nfunction formatWeekdayNumberSunday(d) {\n return d.getDay();\n}\n\nfunction formatWeekNumberMonday(d, p) {\n return pad(monday.count(year(d), d), p, 2);\n}\n\nfunction formatYear(d, p) {\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatFullYear(d, p) {\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatZone(d) {\n var z = d.getTimezoneOffset();\n return (z > 0 ? \"-\" : (z *= -1, \"+\"))\n + pad(z / 60 | 0, \"0\", 2)\n + pad(z % 60, \"0\", 2);\n}\n\nfunction formatUTCDayOfMonth(d, p) {\n return pad(d.getUTCDate(), p, 2);\n}\n\nfunction formatUTCHour24(d, p) {\n return pad(d.getUTCHours(), p, 2);\n}\n\nfunction formatUTCHour12(d, p) {\n return pad(d.getUTCHours() % 12 || 12, p, 2);\n}\n\nfunction formatUTCDayOfYear(d, p) {\n return pad(1 + utcDay.count(utcYear(d), d), p, 3);\n}\n\nfunction formatUTCMilliseconds(d, p) {\n return pad(d.getUTCMilliseconds(), p, 3);\n}\n\nfunction formatUTCMicroseconds(d, p) {\n return formatUTCMilliseconds(d, p) + \"000\";\n}\n\nfunction formatUTCMonthNumber(d, p) {\n return pad(d.getUTCMonth() + 1, p, 2);\n}\n\nfunction formatUTCMinutes(d, p) {\n return pad(d.getUTCMinutes(), p, 2);\n}\n\nfunction formatUTCSeconds(d, p) {\n return pad(d.getUTCSeconds(), p, 2);\n}\n\nfunction formatUTCWeekdayNumberMonday(d) {\n var dow = d.getUTCDay();\n return dow === 0 ? 7 : dow;\n}\n\nfunction formatUTCWeekNumberSunday(d, p) {\n return pad(utcSunday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCWeekNumberISO(d, p) {\n var day$$1 = d.getUTCDay();\n d = (day$$1 >= 4 || day$$1 === 0) ? utcThursday(d) : utcThursday.ceil(d);\n return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);\n}\n\nfunction formatUTCWeekdayNumberSunday(d) {\n return d.getUTCDay();\n}\n\nfunction formatUTCWeekNumberMonday(d, p) {\n return pad(utcMonday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCYear(d, p) {\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCFullYear(d, p) {\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCZone() {\n return \"+0000\";\n}\n\nfunction formatLiteralPercent() {\n return \"%\";\n}\n\nfunction formatUnixTimestamp(d) {\n return +d;\n}\n\nfunction formatUnixTimestampSeconds(d) {\n return Math.floor(+d / 1000);\n}\n\nvar locale$1;\n\n\n\n\n\ndefaultLocale$1({\n dateTime: \"%x, %X\",\n date: \"%-m/%-d/%Y\",\n time: \"%-I:%M:%S %p\",\n periods: [\"AM\", \"PM\"],\n days: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n shortDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n shortMonths: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n});\n\nfunction defaultLocale$1(definition) {\n locale$1 = formatLocale$1(definition);\n exports.timeFormat = locale$1.format;\n exports.timeParse = locale$1.parse;\n exports.utcFormat = locale$1.utcFormat;\n exports.utcParse = locale$1.utcParse;\n return locale$1;\n}\n\nvar isoSpecifier = \"%Y-%m-%dT%H:%M:%S.%LZ\";\n\nfunction formatIsoNative(date) {\n return date.toISOString();\n}\n\nvar formatIso = Date.prototype.toISOString\n ? formatIsoNative\n : exports.utcFormat(isoSpecifier);\n\nfunction parseIsoNative(string) {\n var date = new Date(string);\n return isNaN(date) ? null : date;\n}\n\nvar parseIso = +new Date(\"2000-01-01T00:00:00.000Z\")\n ? parseIsoNative\n : exports.utcParse(isoSpecifier);\n\nvar durationSecond = 1000;\nvar durationMinute = durationSecond * 60;\nvar durationHour = durationMinute * 60;\nvar durationDay = durationHour * 24;\nvar durationWeek = durationDay * 7;\nvar durationMonth = durationDay * 30;\nvar durationYear = durationDay * 365;\n\nfunction date$1(t) {\n return new Date(t);\n}\n\nfunction number$3(t) {\n return t instanceof Date ? +t : +new Date(+t);\n}\n\nfunction calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {\n var scale = continuous(deinterpolateLinear, reinterpolate),\n invert = scale.invert,\n domain = scale.domain;\n\n var formatMillisecond = format(\".%L\"),\n formatSecond = format(\":%S\"),\n formatMinute = format(\"%I:%M\"),\n formatHour = format(\"%I %p\"),\n formatDay = format(\"%a %d\"),\n formatWeek = format(\"%b %d\"),\n formatMonth = format(\"%B\"),\n formatYear = format(\"%Y\");\n\n var tickIntervals = [\n [second$$1, 1, durationSecond],\n [second$$1, 5, 5 * durationSecond],\n [second$$1, 15, 15 * durationSecond],\n [second$$1, 30, 30 * durationSecond],\n [minute$$1, 1, durationMinute],\n [minute$$1, 5, 5 * durationMinute],\n [minute$$1, 15, 15 * durationMinute],\n [minute$$1, 30, 30 * durationMinute],\n [ hour$$1, 1, durationHour ],\n [ hour$$1, 3, 3 * durationHour ],\n [ hour$$1, 6, 6 * durationHour ],\n [ hour$$1, 12, 12 * durationHour ],\n [ day$$1, 1, durationDay ],\n [ day$$1, 2, 2 * durationDay ],\n [ week, 1, durationWeek ],\n [ month$$1, 1, durationMonth ],\n [ month$$1, 3, 3 * durationMonth ],\n [ year$$1, 1, durationYear ]\n ];\n\n function tickFormat(date) {\n return (second$$1(date) < date ? formatMillisecond\n : minute$$1(date) < date ? formatSecond\n : hour$$1(date) < date ? formatMinute\n : day$$1(date) < date ? formatHour\n : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)\n : year$$1(date) < date ? formatMonth\n : formatYear)(date);\n }\n\n function tickInterval(interval, start, stop, step) {\n if (interval == null) interval = 10;\n\n // If a desired tick count is specified, pick a reasonable tick interval\n // based on the extent of the domain and a rough estimate of tick size.\n // Otherwise, assume interval is already a time interval and use it.\n if (typeof interval === \"number\") {\n var target = Math.abs(stop - start) / interval,\n i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);\n if (i === tickIntervals.length) {\n step = tickStep(start / durationYear, stop / durationYear, interval);\n interval = year$$1;\n } else if (i) {\n i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];\n step = i[1];\n interval = i[0];\n } else {\n step = Math.max(tickStep(start, stop, interval), 1);\n interval = millisecond$$1;\n }\n }\n\n return step == null ? interval : interval.every(step);\n }\n\n scale.invert = function(y) {\n return new Date(invert(y));\n };\n\n scale.domain = function(_) {\n return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$1);\n };\n\n scale.ticks = function(interval, step) {\n var d = domain(),\n t0 = d[0],\n t1 = d[d.length - 1],\n r = t1 < t0,\n t;\n if (r) t = t0, t0 = t1, t1 = t;\n t = tickInterval(interval, t0, t1, step);\n t = t ? t.range(t0, t1 + 1) : []; // inclusive stop\n return r ? t.reverse() : t;\n };\n\n scale.tickFormat = function(count, specifier) {\n return specifier == null ? tickFormat : format(specifier);\n };\n\n scale.nice = function(interval, step) {\n var d = domain();\n return (interval = tickInterval(interval, d[0], d[d.length - 1], step))\n ? domain(nice(d, interval))\n : scale;\n };\n\n scale.copy = function() {\n return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));\n };\n\n return scale;\n}\n\nfunction time() {\n return calendar(year, month, sunday, day, hour, minute, second, millisecond, exports.timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);\n}\n\nfunction utcTime() {\n return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, exports.utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);\n}\n\nfunction colors(s) {\n return s.match(/.{6}/g).map(function(x) {\n return \"#\" + x;\n });\n}\n\nvar category10 = colors(\"1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf\");\n\nvar category20b = colors(\"393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6\");\n\nvar category20c = colors(\"3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9\");\n\nvar category20 = colors(\"1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5\");\n\nvar cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));\n\nvar warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));\n\nvar cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));\n\nvar rainbow = cubehelix();\n\nfunction rainbow$1(t) {\n if (t < 0 || t > 1) t -= Math.floor(t);\n var ts = Math.abs(t - 0.5);\n rainbow.h = 360 * t - 100;\n rainbow.s = 1.5 - 1.5 * ts;\n rainbow.l = 0.8 - 0.9 * ts;\n return rainbow + \"\";\n}\n\nfunction ramp(range) {\n var n = range.length;\n return function(t) {\n return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];\n };\n}\n\nvar viridis = ramp(colors(\"44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725\"));\n\nvar magma = ramp(colors(\"00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf\"));\n\nvar inferno = ramp(colors(\"00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4\"));\n\nvar plasma = ramp(colors(\"0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921\"));\n\nfunction sequential(interpolator) {\n var x0 = 0,\n x1 = 1,\n clamp = false;\n\n function scale(x) {\n var t = (x - x0) / (x1 - x0);\n return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, scale) : clamp;\n };\n\n scale.interpolator = function(_) {\n return arguments.length ? (interpolator = _, scale) : interpolator;\n };\n\n scale.copy = function() {\n return sequential(interpolator).domain([x0, x1]).clamp(clamp);\n };\n\n return linearish(scale);\n}\n\nfunction constant$10(x) {\n return function constant() {\n return x;\n };\n}\n\nvar abs$1 = Math.abs;\nvar atan2$1 = Math.atan2;\nvar cos$2 = Math.cos;\nvar max$2 = Math.max;\nvar min$1 = Math.min;\nvar sin$2 = Math.sin;\nvar sqrt$2 = Math.sqrt;\n\nvar epsilon$3 = 1e-12;\nvar pi$4 = Math.PI;\nvar halfPi$3 = pi$4 / 2;\nvar tau$4 = 2 * pi$4;\n\nfunction acos$1(x) {\n return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);\n}\n\nfunction asin$1(x) {\n return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x);\n}\n\nfunction arcInnerRadius(d) {\n return d.innerRadius;\n}\n\nfunction arcOuterRadius(d) {\n return d.outerRadius;\n}\n\nfunction arcStartAngle(d) {\n return d.startAngle;\n}\n\nfunction arcEndAngle(d) {\n return d.endAngle;\n}\n\nfunction arcPadAngle(d) {\n return d && d.padAngle; // Note: optional!\n}\n\nfunction intersect(x0, y0, x1, y1, x2, y2, x3, y3) {\n var x10 = x1 - x0, y10 = y1 - y0,\n x32 = x3 - x2, y32 = y3 - y2,\n t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);\n return [x0 + t * x10, y0 + t * y10];\n}\n\n// Compute perpendicular offset line of length rc.\n// http://mathworld.wolfram.com/Circle-LineIntersection.html\nfunction cornerTangents(x0, y0, x1, y1, r1, rc, cw) {\n var x01 = x0 - x1,\n y01 = y0 - y1,\n lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01),\n ox = lo * y01,\n oy = -lo * x01,\n x11 = x0 + ox,\n y11 = y0 + oy,\n x10 = x1 + ox,\n y10 = y1 + oy,\n x00 = (x11 + x10) / 2,\n y00 = (y11 + y10) / 2,\n dx = x10 - x11,\n dy = y10 - y11,\n d2 = dx * dx + dy * dy,\n r = r1 - rc,\n D = x11 * y10 - x10 * y11,\n d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)),\n cx0 = (D * dy - dx * d) / d2,\n cy0 = (-D * dx - dy * d) / d2,\n cx1 = (D * dy + dx * d) / d2,\n cy1 = (-D * dx + dy * d) / d2,\n dx0 = cx0 - x00,\n dy0 = cy0 - y00,\n dx1 = cx1 - x00,\n dy1 = cy1 - y00;\n\n // Pick the closer of the two intersection points.\n // TODO Is there a faster way to determine which intersection to use?\n if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n\n return {\n cx: cx0,\n cy: cy0,\n x01: -ox,\n y01: -oy,\n x11: cx0 * (r1 / r - 1),\n y11: cy0 * (r1 / r - 1)\n };\n}\n\nfunction arc() {\n var innerRadius = arcInnerRadius,\n outerRadius = arcOuterRadius,\n cornerRadius = constant$10(0),\n padRadius = null,\n startAngle = arcStartAngle,\n endAngle = arcEndAngle,\n padAngle = arcPadAngle,\n context = null;\n\n function arc() {\n var buffer,\n r,\n r0 = +innerRadius.apply(this, arguments),\n r1 = +outerRadius.apply(this, arguments),\n a0 = startAngle.apply(this, arguments) - halfPi$3,\n a1 = endAngle.apply(this, arguments) - halfPi$3,\n da = abs$1(a1 - a0),\n cw = a1 > a0;\n\n if (!context) context = buffer = path();\n\n // Ensure that the outer radius is always larger than the inner radius.\n if (r1 < r0) r = r1, r1 = r0, r0 = r;\n\n // Is it a point?\n if (!(r1 > epsilon$3)) context.moveTo(0, 0);\n\n // Or is it a circle or annulus?\n else if (da > tau$4 - epsilon$3) {\n context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0));\n context.arc(0, 0, r1, a0, a1, !cw);\n if (r0 > epsilon$3) {\n context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1));\n context.arc(0, 0, r0, a1, a0, cw);\n }\n }\n\n // Or is it a circular or annular sector?\n else {\n var a01 = a0,\n a11 = a1,\n a00 = a0,\n a10 = a1,\n da0 = da,\n da1 = da,\n ap = padAngle.apply(this, arguments) / 2,\n rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)),\n rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),\n rc0 = rc,\n rc1 = rc,\n t0,\n t1;\n\n // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.\n if (rp > epsilon$3) {\n var p0 = asin$1(rp / r0 * sin$2(ap)),\n p1 = asin$1(rp / r1 * sin$2(ap));\n if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;\n else da0 = 0, a00 = a10 = (a0 + a1) / 2;\n if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;\n else da1 = 0, a01 = a11 = (a0 + a1) / 2;\n }\n\n var x01 = r1 * cos$2(a01),\n y01 = r1 * sin$2(a01),\n x10 = r0 * cos$2(a10),\n y10 = r0 * sin$2(a10);\n\n // Apply rounded corners?\n if (rc > epsilon$3) {\n var x11 = r1 * cos$2(a11),\n y11 = r1 * sin$2(a11),\n x00 = r0 * cos$2(a00),\n y00 = r0 * sin$2(a00);\n\n // Restrict the corner radius according to the sector angle.\n if (da < pi$4) {\n var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],\n ax = x01 - oc[0],\n ay = y01 - oc[1],\n bx = x11 - oc[0],\n by = y11 - oc[1],\n kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2),\n lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]);\n rc0 = min$1(rc, (r0 - lc) / (kc - 1));\n rc1 = min$1(rc, (r1 - lc) / (kc + 1));\n }\n }\n\n // Is the sector collapsed to a line?\n if (!(da1 > epsilon$3)) context.moveTo(x01, y01);\n\n // Does the sector’s outer ring have rounded corners?\n else if (rc1 > epsilon$3) {\n t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);\n t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);\n\n context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r1, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), !cw);\n context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the outer ring just a circular arc?\n else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);\n\n // Is there no inner ring, and it’s a circular sector?\n // Or perhaps it’s an annular sector collapsed due to padding?\n if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);\n\n // Does the sector’s inner ring (or point) have rounded corners?\n else if (rc0 > epsilon$3) {\n t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);\n t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);\n\n context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r0, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), cw);\n context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the inner ring just a circular arc?\n else context.arc(0, 0, r0, a10, a00, cw);\n }\n\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n arc.centroid = function() {\n var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,\n a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2;\n return [cos$2(a) * r, sin$2(a) * r];\n };\n\n arc.innerRadius = function(_) {\n return arguments.length ? (innerRadius = typeof _ === \"function\" ? _ : constant$10(+_), arc) : innerRadius;\n };\n\n arc.outerRadius = function(_) {\n return arguments.length ? (outerRadius = typeof _ === \"function\" ? _ : constant$10(+_), arc) : outerRadius;\n };\n\n arc.cornerRadius = function(_) {\n return arguments.length ? (cornerRadius = typeof _ === \"function\" ? _ : constant$10(+_), arc) : cornerRadius;\n };\n\n arc.padRadius = function(_) {\n return arguments.length ? (padRadius = _ == null ? null : typeof _ === \"function\" ? _ : constant$10(+_), arc) : padRadius;\n };\n\n arc.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant$10(+_), arc) : startAngle;\n };\n\n arc.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant$10(+_), arc) : endAngle;\n };\n\n arc.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant$10(+_), arc) : padAngle;\n };\n\n arc.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, arc) : context;\n };\n\n return arc;\n}\n\nfunction Linear(context) {\n this._context = context;\n}\n\nLinear.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: this._context.lineTo(x, y); break;\n }\n }\n};\n\nfunction curveLinear(context) {\n return new Linear(context);\n}\n\nfunction x$3(p) {\n return p[0];\n}\n\nfunction y$3(p) {\n return p[1];\n}\n\nfunction line() {\n var x$$1 = x$3,\n y$$1 = y$3,\n defined = constant$10(true),\n context = null,\n curve = curveLinear,\n output = null;\n\n function line(data) {\n var i,\n n = data.length,\n d,\n defined0 = false,\n buffer;\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) output.lineStart();\n else output.lineEnd();\n }\n if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n line.x = function(_) {\n return arguments.length ? (x$$1 = typeof _ === \"function\" ? _ : constant$10(+_), line) : x$$1;\n };\n\n line.y = function(_) {\n return arguments.length ? (y$$1 = typeof _ === \"function\" ? _ : constant$10(+_), line) : y$$1;\n };\n\n line.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant$10(!!_), line) : defined;\n };\n\n line.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;\n };\n\n line.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;\n };\n\n return line;\n}\n\nfunction area$2() {\n var x0 = x$3,\n x1 = null,\n y0 = constant$10(0),\n y1 = y$3,\n defined = constant$10(true),\n context = null,\n curve = curveLinear,\n output = null;\n\n function area(data) {\n var i,\n j,\n k,\n n = data.length,\n d,\n defined0 = false,\n buffer,\n x0z = new Array(n),\n y0z = new Array(n);\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) {\n j = i;\n output.areaStart();\n output.lineStart();\n } else {\n output.lineEnd();\n output.lineStart();\n for (k = i - 1; k >= j; --k) {\n output.point(x0z[k], y0z[k]);\n }\n output.lineEnd();\n output.areaEnd();\n }\n }\n if (defined0) {\n x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);\n output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);\n }\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n function arealine() {\n return line().defined(defined).curve(curve).context(context);\n }\n\n area.x = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant$10(+_), x1 = null, area) : x0;\n };\n\n area.x0 = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant$10(+_), area) : x0;\n };\n\n area.x1 = function(_) {\n return arguments.length ? (x1 = _ == null ? null : typeof _ === \"function\" ? _ : constant$10(+_), area) : x1;\n };\n\n area.y = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant$10(+_), y1 = null, area) : y0;\n };\n\n area.y0 = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant$10(+_), area) : y0;\n };\n\n area.y1 = function(_) {\n return arguments.length ? (y1 = _ == null ? null : typeof _ === \"function\" ? _ : constant$10(+_), area) : y1;\n };\n\n area.lineX0 =\n area.lineY0 = function() {\n return arealine().x(x0).y(y0);\n };\n\n area.lineY1 = function() {\n return arealine().x(x0).y(y1);\n };\n\n area.lineX1 = function() {\n return arealine().x(x1).y(y0);\n };\n\n area.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant$10(!!_), area) : defined;\n };\n\n area.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;\n };\n\n area.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;\n };\n\n return area;\n}\n\nfunction descending$1(a, b) {\n return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n}\n\nfunction identity$7(d) {\n return d;\n}\n\nfunction pie() {\n var value = identity$7,\n sortValues = descending$1,\n sort = null,\n startAngle = constant$10(0),\n endAngle = constant$10(tau$4),\n padAngle = constant$10(0);\n\n function pie(data) {\n var i,\n n = data.length,\n j,\n k,\n sum = 0,\n index = new Array(n),\n arcs = new Array(n),\n a0 = +startAngle.apply(this, arguments),\n da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)),\n a1,\n p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),\n pa = p * (da < 0 ? -1 : 1),\n v;\n\n for (i = 0; i < n; ++i) {\n if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {\n sum += v;\n }\n }\n\n // Optionally sort the arcs by previously-computed values or by data.\n if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });\n else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });\n\n // Compute the arcs! They are stored in the original data's order.\n for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {\n j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {\n data: data[j],\n index: i,\n value: v,\n startAngle: a0,\n endAngle: a1,\n padAngle: p\n };\n }\n\n return arcs;\n }\n\n pie.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant$10(+_), pie) : value;\n };\n\n pie.sortValues = function(_) {\n return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;\n };\n\n pie.sort = function(_) {\n return arguments.length ? (sort = _, sortValues = null, pie) : sort;\n };\n\n pie.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant$10(+_), pie) : startAngle;\n };\n\n pie.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant$10(+_), pie) : endAngle;\n };\n\n pie.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant$10(+_), pie) : padAngle;\n };\n\n return pie;\n}\n\nvar curveRadialLinear = curveRadial(curveLinear);\n\nfunction Radial(curve) {\n this._curve = curve;\n}\n\nRadial.prototype = {\n areaStart: function() {\n this._curve.areaStart();\n },\n areaEnd: function() {\n this._curve.areaEnd();\n },\n lineStart: function() {\n this._curve.lineStart();\n },\n lineEnd: function() {\n this._curve.lineEnd();\n },\n point: function(a, r) {\n this._curve.point(r * Math.sin(a), r * -Math.cos(a));\n }\n};\n\nfunction curveRadial(curve) {\n\n function radial(context) {\n return new Radial(curve(context));\n }\n\n radial._curve = curve;\n\n return radial;\n}\n\nfunction lineRadial(l) {\n var c = l.curve;\n\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n\n l.curve = function(_) {\n return arguments.length ? c(curveRadial(_)) : c()._curve;\n };\n\n return l;\n}\n\nfunction lineRadial$1() {\n return lineRadial(line().curve(curveRadialLinear));\n}\n\nfunction areaRadial() {\n var a = area$2().curve(curveRadialLinear),\n c = a.curve,\n x0 = a.lineX0,\n x1 = a.lineX1,\n y0 = a.lineY0,\n y1 = a.lineY1;\n\n a.angle = a.x, delete a.x;\n a.startAngle = a.x0, delete a.x0;\n a.endAngle = a.x1, delete a.x1;\n a.radius = a.y, delete a.y;\n a.innerRadius = a.y0, delete a.y0;\n a.outerRadius = a.y1, delete a.y1;\n a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;\n a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;\n a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;\n a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;\n\n a.curve = function(_) {\n return arguments.length ? c(curveRadial(_)) : c()._curve;\n };\n\n return a;\n}\n\nfunction pointRadial(x, y) {\n return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];\n}\n\nvar slice$6 = Array.prototype.slice;\n\nfunction linkSource(d) {\n return d.source;\n}\n\nfunction linkTarget(d) {\n return d.target;\n}\n\nfunction link$2(curve) {\n var source = linkSource,\n target = linkTarget,\n x$$1 = x$3,\n y$$1 = y$3,\n context = null;\n\n function link() {\n var buffer, argv = slice$6.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n if (!context) context = buffer = path();\n curve(context, +x$$1.apply(this, (argv[0] = s, argv)), +y$$1.apply(this, argv), +x$$1.apply(this, (argv[0] = t, argv)), +y$$1.apply(this, argv));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n link.source = function(_) {\n return arguments.length ? (source = _, link) : source;\n };\n\n link.target = function(_) {\n return arguments.length ? (target = _, link) : target;\n };\n\n link.x = function(_) {\n return arguments.length ? (x$$1 = typeof _ === \"function\" ? _ : constant$10(+_), link) : x$$1;\n };\n\n link.y = function(_) {\n return arguments.length ? (y$$1 = typeof _ === \"function\" ? _ : constant$10(+_), link) : y$$1;\n };\n\n link.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, link) : context;\n };\n\n return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial$1(context, x0, y0, x1, y1) {\n var p0 = pointRadial(x0, y0),\n p1 = pointRadial(x0, y0 = (y0 + y1) / 2),\n p2 = pointRadial(x1, y0),\n p3 = pointRadial(x1, y1);\n context.moveTo(p0[0], p0[1]);\n context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nfunction linkHorizontal() {\n return link$2(curveHorizontal);\n}\n\nfunction linkVertical() {\n return link$2(curveVertical);\n}\n\nfunction linkRadial() {\n var l = link$2(curveRadial$1);\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n return l;\n}\n\nvar circle$2 = {\n draw: function(context, size) {\n var r = Math.sqrt(size / pi$4);\n context.moveTo(r, 0);\n context.arc(0, 0, r, 0, tau$4);\n }\n};\n\nvar cross$2 = {\n draw: function(context, size) {\n var r = Math.sqrt(size / 5) / 2;\n context.moveTo(-3 * r, -r);\n context.lineTo(-r, -r);\n context.lineTo(-r, -3 * r);\n context.lineTo(r, -3 * r);\n context.lineTo(r, -r);\n context.lineTo(3 * r, -r);\n context.lineTo(3 * r, r);\n context.lineTo(r, r);\n context.lineTo(r, 3 * r);\n context.lineTo(-r, 3 * r);\n context.lineTo(-r, r);\n context.lineTo(-3 * r, r);\n context.closePath();\n }\n};\n\nvar tan30 = Math.sqrt(1 / 3);\nvar tan30_2 = tan30 * 2;\n\nvar diamond = {\n draw: function(context, size) {\n var y = Math.sqrt(size / tan30_2),\n x = y * tan30;\n context.moveTo(0, -y);\n context.lineTo(x, 0);\n context.lineTo(0, y);\n context.lineTo(-x, 0);\n context.closePath();\n }\n};\n\nvar ka = 0.89081309152928522810;\nvar kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10);\nvar kx = Math.sin(tau$4 / 10) * kr;\nvar ky = -Math.cos(tau$4 / 10) * kr;\n\nvar star = {\n draw: function(context, size) {\n var r = Math.sqrt(size * ka),\n x = kx * r,\n y = ky * r;\n context.moveTo(0, -r);\n context.lineTo(x, y);\n for (var i = 1; i < 5; ++i) {\n var a = tau$4 * i / 5,\n c = Math.cos(a),\n s = Math.sin(a);\n context.lineTo(s * r, -c * r);\n context.lineTo(c * x - s * y, s * x + c * y);\n }\n context.closePath();\n }\n};\n\nvar square = {\n draw: function(context, size) {\n var w = Math.sqrt(size),\n x = -w / 2;\n context.rect(x, x, w, w);\n }\n};\n\nvar sqrt3 = Math.sqrt(3);\n\nvar triangle = {\n draw: function(context, size) {\n var y = -Math.sqrt(size / (sqrt3 * 3));\n context.moveTo(0, y * 2);\n context.lineTo(-sqrt3 * y, -y);\n context.lineTo(sqrt3 * y, -y);\n context.closePath();\n }\n};\n\nvar c = -0.5;\nvar s = Math.sqrt(3) / 2;\nvar k = 1 / Math.sqrt(12);\nvar a = (k / 2 + 1) * 3;\n\nvar wye = {\n draw: function(context, size) {\n var r = Math.sqrt(size / a),\n x0 = r / 2,\n y0 = r * k,\n x1 = x0,\n y1 = r * k + r,\n x2 = -x1,\n y2 = y1;\n context.moveTo(x0, y0);\n context.lineTo(x1, y1);\n context.lineTo(x2, y2);\n context.lineTo(c * x0 - s * y0, s * x0 + c * y0);\n context.lineTo(c * x1 - s * y1, s * x1 + c * y1);\n context.lineTo(c * x2 - s * y2, s * x2 + c * y2);\n context.lineTo(c * x0 + s * y0, c * y0 - s * x0);\n context.lineTo(c * x1 + s * y1, c * y1 - s * x1);\n context.lineTo(c * x2 + s * y2, c * y2 - s * x2);\n context.closePath();\n }\n};\n\nvar symbols = [\n circle$2,\n cross$2,\n diamond,\n square,\n star,\n triangle,\n wye\n];\n\nfunction symbol() {\n var type = constant$10(circle$2),\n size = constant$10(64),\n context = null;\n\n function symbol() {\n var buffer;\n if (!context) context = buffer = path();\n type.apply(this, arguments).draw(context, +size.apply(this, arguments));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n symbol.type = function(_) {\n return arguments.length ? (type = typeof _ === \"function\" ? _ : constant$10(_), symbol) : type;\n };\n\n symbol.size = function(_) {\n return arguments.length ? (size = typeof _ === \"function\" ? _ : constant$10(+_), symbol) : size;\n };\n\n symbol.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, symbol) : context;\n };\n\n return symbol;\n}\n\nfunction noop$2() {}\n\nfunction point$2(that, x, y) {\n that._context.bezierCurveTo(\n (2 * that._x0 + that._x1) / 3,\n (2 * that._y0 + that._y1) / 3,\n (that._x0 + 2 * that._x1) / 3,\n (that._y0 + 2 * that._y1) / 3,\n (that._x0 + 4 * that._x1 + x) / 6,\n (that._y0 + 4 * that._y1 + y) / 6\n );\n}\n\nfunction Basis(context) {\n this._context = context;\n}\n\nBasis.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 3: point$2(this, this._x1, this._y1); // proceed\n case 2: this._context.lineTo(this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed\n default: point$2(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nfunction basis$2(context) {\n return new Basis(context);\n}\n\nfunction BasisClosed(context) {\n this._context = context;\n}\n\nBasisClosed.prototype = {\n areaStart: noop$2,\n areaEnd: noop$2,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x2, this._y2);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);\n this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x2, this._y2);\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x2 = x, this._y2 = y; break;\n case 1: this._point = 2; this._x3 = x, this._y3 = y; break;\n case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;\n default: point$2(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nfunction basisClosed$1(context) {\n return new BasisClosed(context);\n}\n\nfunction BasisOpen(context) {\n this._context = context;\n}\n\nBasisOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;\n case 3: this._point = 4; // proceed\n default: point$2(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nfunction basisOpen(context) {\n return new BasisOpen(context);\n}\n\nfunction Bundle(context, beta) {\n this._basis = new Basis(context);\n this._beta = beta;\n}\n\nBundle.prototype = {\n lineStart: function() {\n this._x = [];\n this._y = [];\n this._basis.lineStart();\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n j = x.length - 1;\n\n if (j > 0) {\n var x0 = x[0],\n y0 = y[0],\n dx = x[j] - x0,\n dy = y[j] - y0,\n i = -1,\n t;\n\n while (++i <= j) {\n t = i / j;\n this._basis.point(\n this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),\n this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)\n );\n }\n }\n\n this._x = this._y = null;\n this._basis.lineEnd();\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\nvar bundle = (function custom(beta) {\n\n function bundle(context) {\n return beta === 1 ? new Basis(context) : new Bundle(context, beta);\n }\n\n bundle.beta = function(beta) {\n return custom(+beta);\n };\n\n return bundle;\n})(0.85);\n\nfunction point$3(that, x, y) {\n that._context.bezierCurveTo(\n that._x1 + that._k * (that._x2 - that._x0),\n that._y1 + that._k * (that._y2 - that._y0),\n that._x2 + that._k * (that._x1 - x),\n that._y2 + that._k * (that._y1 - y),\n that._x2,\n that._y2\n );\n}\n\nfunction Cardinal(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinal.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: point$3(this, this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; this._x1 = x, this._y1 = y; break;\n case 2: this._point = 3; // proceed\n default: point$3(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar cardinal = (function custom(tension) {\n\n function cardinal(context) {\n return new Cardinal(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n\nfunction CardinalClosed(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalClosed.prototype = {\n areaStart: noop$2,\n areaEnd: noop$2,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point$3(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar cardinalClosed = (function custom(tension) {\n\n function cardinal$$1(context) {\n return new CardinalClosed(context, tension);\n }\n\n cardinal$$1.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal$$1;\n})(0);\n\nfunction CardinalOpen(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point$3(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar cardinalOpen = (function custom(tension) {\n\n function cardinal$$1(context) {\n return new CardinalOpen(context, tension);\n }\n\n cardinal$$1.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal$$1;\n})(0);\n\nfunction point$4(that, x, y) {\n var x1 = that._x1,\n y1 = that._y1,\n x2 = that._x2,\n y2 = that._y2;\n\n if (that._l01_a > epsilon$3) {\n var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,\n n = 3 * that._l01_a * (that._l01_a + that._l12_a);\n x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;\n y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;\n }\n\n if (that._l23_a > epsilon$3) {\n var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,\n m = 3 * that._l23_a * (that._l23_a + that._l12_a);\n x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;\n y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;\n }\n\n that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);\n}\n\nfunction CatmullRom(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRom.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: this.point(this._x2, this._y2); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; // proceed\n default: point$4(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar catmullRom = (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n\nfunction CatmullRomClosed(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomClosed.prototype = {\n areaStart: noop$2,\n areaEnd: noop$2,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point$4(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar catmullRomClosed = (function custom(alpha) {\n\n function catmullRom$$1(context) {\n return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);\n }\n\n catmullRom$$1.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom$$1;\n})(0.5);\n\nfunction CatmullRomOpen(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point$4(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar catmullRomOpen = (function custom(alpha) {\n\n function catmullRom$$1(context) {\n return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);\n }\n\n catmullRom$$1.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom$$1;\n})(0.5);\n\nfunction LinearClosed(context) {\n this._context = context;\n}\n\nLinearClosed.prototype = {\n areaStart: noop$2,\n areaEnd: noop$2,\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._point) this._context.closePath();\n },\n point: function(x, y) {\n x = +x, y = +y;\n if (this._point) this._context.lineTo(x, y);\n else this._point = 1, this._context.moveTo(x, y);\n }\n};\n\nfunction linearClosed(context) {\n return new LinearClosed(context);\n}\n\nfunction sign$1(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point$5(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point$5(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point$5(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n};\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nfunction monotoneX(context) {\n return new MonotoneX(context);\n}\n\nfunction monotoneY(context) {\n return new MonotoneY(context);\n}\n\nfunction Natural(context) {\n this._context = context;\n}\n\nNatural.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = [];\n this._y = [];\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n n = x.length;\n\n if (n) {\n this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);\n if (n === 2) {\n this._context.lineTo(x[1], y[1]);\n } else {\n var px = controlPoints(x),\n py = controlPoints(y);\n for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {\n this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);\n }\n }\n }\n\n if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();\n this._line = 1 - this._line;\n this._x = this._y = null;\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\n// See https://www.particleincell.com/2012/bezier-splines/ for derivation.\nfunction controlPoints(x) {\n var i,\n n = x.length - 1,\n m,\n a = new Array(n),\n b = new Array(n),\n r = new Array(n);\n a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];\n for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];\n a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];\n for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];\n a[n - 1] = r[n - 1] / b[n - 1];\n for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];\n b[n - 1] = (x[n] + a[n - 1]) / 2;\n for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];\n return [a, b];\n}\n\nfunction natural(context) {\n return new Natural(context);\n}\n\nfunction Step(context, t) {\n this._context = context;\n this._t = t;\n}\n\nStep.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = this._y = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: {\n if (this._t <= 0) {\n this._context.lineTo(this._x, y);\n this._context.lineTo(x, y);\n } else {\n var x1 = this._x * (1 - this._t) + x * this._t;\n this._context.lineTo(x1, this._y);\n this._context.lineTo(x1, y);\n }\n break;\n }\n }\n this._x = x, this._y = y;\n }\n};\n\nfunction step(context) {\n return new Step(context, 0.5);\n}\n\nfunction stepBefore(context) {\n return new Step(context, 0);\n}\n\nfunction stepAfter(context) {\n return new Step(context, 1);\n}\n\nfunction none$1(series, order) {\n if (!((n = series.length) > 1)) return;\n for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {\n s0 = s1, s1 = series[order[i]];\n for (j = 0; j < m; ++j) {\n s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];\n }\n }\n}\n\nfunction none$2(series) {\n var n = series.length, o = new Array(n);\n while (--n >= 0) o[n] = n;\n return o;\n}\n\nfunction stackValue(d, key) {\n return d[key];\n}\n\nfunction stack() {\n var keys = constant$10([]),\n order = none$2,\n offset = none$1,\n value = stackValue;\n\n function stack(data) {\n var kz = keys.apply(this, arguments),\n i,\n m = data.length,\n n = kz.length,\n sz = new Array(n),\n oz;\n\n for (i = 0; i < n; ++i) {\n for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {\n si[j] = sij = [0, +value(data[j], ki, j, data)];\n sij.data = data[j];\n }\n si.key = ki;\n }\n\n for (i = 0, oz = order(sz); i < n; ++i) {\n sz[oz[i]].index = i;\n }\n\n offset(sz, oz);\n return sz;\n }\n\n stack.keys = function(_) {\n return arguments.length ? (keys = typeof _ === \"function\" ? _ : constant$10(slice$6.call(_)), stack) : keys;\n };\n\n stack.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant$10(+_), stack) : value;\n };\n\n stack.order = function(_) {\n return arguments.length ? (order = _ == null ? none$2 : typeof _ === \"function\" ? _ : constant$10(slice$6.call(_)), stack) : order;\n };\n\n stack.offset = function(_) {\n return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;\n };\n\n return stack;\n}\n\nfunction expand(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {\n for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;\n if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;\n }\n none$1(series, order);\n}\n\nfunction diverging(series, order) {\n if (!((n = series.length) > 1)) return;\n for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {\n for (yp = yn = 0, i = 0; i < n; ++i) {\n if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {\n d[0] = yp, d[1] = yp += dy;\n } else if (dy < 0) {\n d[1] = yn, d[0] = yn += dy;\n } else {\n d[0] = yp;\n }\n }\n }\n}\n\nfunction silhouette(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {\n for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;\n s0[j][1] += s0[j][0] = -y / 2;\n }\n none$1(series, order);\n}\n\nfunction wiggle(series, order) {\n if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;\n for (var y = 0, j = 1, s0, m, n; j < m; ++j) {\n for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {\n var si = series[order[i]],\n sij0 = si[j][1] || 0,\n sij1 = si[j - 1][1] || 0,\n s3 = (sij0 - sij1) / 2;\n for (var k = 0; k < i; ++k) {\n var sk = series[order[k]],\n skj0 = sk[j][1] || 0,\n skj1 = sk[j - 1][1] || 0;\n s3 += skj0 - skj1;\n }\n s1 += sij0, s2 += s3 * sij0;\n }\n s0[j - 1][1] += s0[j - 1][0] = y;\n if (s1) y -= s2 / s1;\n }\n s0[j - 1][1] += s0[j - 1][0] = y;\n none$1(series, order);\n}\n\nfunction ascending$2(series) {\n var sums = series.map(sum$2);\n return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });\n}\n\nfunction sum$2(series) {\n var s = 0, i = -1, n = series.length, v;\n while (++i < n) if (v = +series[i][1]) s += v;\n return s;\n}\n\nfunction descending$2(series) {\n return ascending$2(series).reverse();\n}\n\nfunction insideOut(series) {\n var n = series.length,\n i,\n j,\n sums = series.map(sum$2),\n order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }),\n top = 0,\n bottom = 0,\n tops = [],\n bottoms = [];\n\n for (i = 0; i < n; ++i) {\n j = order[i];\n if (top < bottom) {\n top += sums[j];\n tops.push(j);\n } else {\n bottom += sums[j];\n bottoms.push(j);\n }\n }\n\n return bottoms.reverse().concat(tops);\n}\n\nfunction reverse(series) {\n return none$2(series).reverse();\n}\n\nfunction constant$11(x) {\n return function() {\n return x;\n };\n}\n\nfunction x$4(d) {\n return d[0];\n}\n\nfunction y$4(d) {\n return d[1];\n}\n\nfunction RedBlackTree() {\n this._ = null; // root node\n}\n\nfunction RedBlackNode(node) {\n node.U = // parent node\n node.C = // color - true for red, false for black\n node.L = // left node\n node.R = // right node\n node.P = // previous node\n node.N = null; // next node\n}\n\nRedBlackTree.prototype = {\n constructor: RedBlackTree,\n\n insert: function(after, node) {\n var parent, grandpa, uncle;\n\n if (after) {\n node.P = after;\n node.N = after.N;\n if (after.N) after.N.P = node;\n after.N = node;\n if (after.R) {\n after = after.R;\n while (after.L) after = after.L;\n after.L = node;\n } else {\n after.R = node;\n }\n parent = after;\n } else if (this._) {\n after = RedBlackFirst(this._);\n node.P = null;\n node.N = after;\n after.P = after.L = node;\n parent = after;\n } else {\n node.P = node.N = null;\n this._ = node;\n parent = null;\n }\n node.L = node.R = null;\n node.U = parent;\n node.C = true;\n\n after = node;\n while (parent && parent.C) {\n grandpa = parent.U;\n if (parent === grandpa.L) {\n uncle = grandpa.R;\n if (uncle && uncle.C) {\n parent.C = uncle.C = false;\n grandpa.C = true;\n after = grandpa;\n } else {\n if (after === parent.R) {\n RedBlackRotateLeft(this, parent);\n after = parent;\n parent = after.U;\n }\n parent.C = false;\n grandpa.C = true;\n RedBlackRotateRight(this, grandpa);\n }\n } else {\n uncle = grandpa.L;\n if (uncle && uncle.C) {\n parent.C = uncle.C = false;\n grandpa.C = true;\n after = grandpa;\n } else {\n if (after === parent.L) {\n RedBlackRotateRight(this, parent);\n after = parent;\n parent = after.U;\n }\n parent.C = false;\n grandpa.C = true;\n RedBlackRotateLeft(this, grandpa);\n }\n }\n parent = after.U;\n }\n this._.C = false;\n },\n\n remove: function(node) {\n if (node.N) node.N.P = node.P;\n if (node.P) node.P.N = node.N;\n node.N = node.P = null;\n\n var parent = node.U,\n sibling,\n left = node.L,\n right = node.R,\n next,\n red;\n\n if (!left) next = right;\n else if (!right) next = left;\n else next = RedBlackFirst(right);\n\n if (parent) {\n if (parent.L === node) parent.L = next;\n else parent.R = next;\n } else {\n this._ = next;\n }\n\n if (left && right) {\n red = next.C;\n next.C = node.C;\n next.L = left;\n left.U = next;\n if (next !== right) {\n parent = next.U;\n next.U = node.U;\n node = next.R;\n parent.L = node;\n next.R = right;\n right.U = next;\n } else {\n next.U = parent;\n parent = next;\n node = next.R;\n }\n } else {\n red = node.C;\n node = next;\n }\n\n if (node) node.U = parent;\n if (red) return;\n if (node && node.C) { node.C = false; return; }\n\n do {\n if (node === this._) break;\n if (node === parent.L) {\n sibling = parent.R;\n if (sibling.C) {\n sibling.C = false;\n parent.C = true;\n RedBlackRotateLeft(this, parent);\n sibling = parent.R;\n }\n if ((sibling.L && sibling.L.C)\n || (sibling.R && sibling.R.C)) {\n if (!sibling.R || !sibling.R.C) {\n sibling.L.C = false;\n sibling.C = true;\n RedBlackRotateRight(this, sibling);\n sibling = parent.R;\n }\n sibling.C = parent.C;\n parent.C = sibling.R.C = false;\n RedBlackRotateLeft(this, parent);\n node = this._;\n break;\n }\n } else {\n sibling = parent.L;\n if (sibling.C) {\n sibling.C = false;\n parent.C = true;\n RedBlackRotateRight(this, parent);\n sibling = parent.L;\n }\n if ((sibling.L && sibling.L.C)\n || (sibling.R && sibling.R.C)) {\n if (!sibling.L || !sibling.L.C) {\n sibling.R.C = false;\n sibling.C = true;\n RedBlackRotateLeft(this, sibling);\n sibling = parent.L;\n }\n sibling.C = parent.C;\n parent.C = sibling.L.C = false;\n RedBlackRotateRight(this, parent);\n node = this._;\n break;\n }\n }\n sibling.C = true;\n node = parent;\n parent = parent.U;\n } while (!node.C);\n\n if (node) node.C = false;\n }\n};\n\nfunction RedBlackRotateLeft(tree, node) {\n var p = node,\n q = node.R,\n parent = p.U;\n\n if (parent) {\n if (parent.L === p) parent.L = q;\n else parent.R = q;\n } else {\n tree._ = q;\n }\n\n q.U = parent;\n p.U = q;\n p.R = q.L;\n if (p.R) p.R.U = p;\n q.L = p;\n}\n\nfunction RedBlackRotateRight(tree, node) {\n var p = node,\n q = node.L,\n parent = p.U;\n\n if (parent) {\n if (parent.L === p) parent.L = q;\n else parent.R = q;\n } else {\n tree._ = q;\n }\n\n q.U = parent;\n p.U = q;\n p.L = q.R;\n if (p.L) p.L.U = p;\n q.R = p;\n}\n\nfunction RedBlackFirst(node) {\n while (node.L) node = node.L;\n return node;\n}\n\nfunction createEdge(left, right, v0, v1) {\n var edge = [null, null],\n index = edges.push(edge) - 1;\n edge.left = left;\n edge.right = right;\n if (v0) setEdgeEnd(edge, left, right, v0);\n if (v1) setEdgeEnd(edge, right, left, v1);\n cells[left.index].halfedges.push(index);\n cells[right.index].halfedges.push(index);\n return edge;\n}\n\nfunction createBorderEdge(left, v0, v1) {\n var edge = [v0, v1];\n edge.left = left;\n return edge;\n}\n\nfunction setEdgeEnd(edge, left, right, vertex) {\n if (!edge[0] && !edge[1]) {\n edge[0] = vertex;\n edge.left = left;\n edge.right = right;\n } else if (edge.left === right) {\n edge[1] = vertex;\n } else {\n edge[0] = vertex;\n }\n}\n\n// Liang–Barsky line clipping.\nfunction clipEdge(edge, x0, y0, x1, y1) {\n var a = edge[0],\n b = edge[1],\n ax = a[0],\n ay = a[1],\n bx = b[0],\n by = b[1],\n t0 = 0,\n t1 = 1,\n dx = bx - ax,\n dy = by - ay,\n r;\n\n r = x0 - ax;\n if (!dx && r > 0) return;\n r /= dx;\n if (dx < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dx > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = x1 - ax;\n if (!dx && r < 0) return;\n r /= dx;\n if (dx < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dx > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n r = y0 - ay;\n if (!dy && r > 0) return;\n r /= dy;\n if (dy < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dy > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = y1 - ay;\n if (!dy && r < 0) return;\n r /= dy;\n if (dy < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dy > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?\n\n if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];\n if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];\n return true;\n}\n\nfunction connectEdge(edge, x0, y0, x1, y1) {\n var v1 = edge[1];\n if (v1) return true;\n\n var v0 = edge[0],\n left = edge.left,\n right = edge.right,\n lx = left[0],\n ly = left[1],\n rx = right[0],\n ry = right[1],\n fx = (lx + rx) / 2,\n fy = (ly + ry) / 2,\n fm,\n fb;\n\n if (ry === ly) {\n if (fx < x0 || fx >= x1) return;\n if (lx > rx) {\n if (!v0) v0 = [fx, y0];\n else if (v0[1] >= y1) return;\n v1 = [fx, y1];\n } else {\n if (!v0) v0 = [fx, y1];\n else if (v0[1] < y0) return;\n v1 = [fx, y0];\n }\n } else {\n fm = (lx - rx) / (ry - ly);\n fb = fy - fm * fx;\n if (fm < -1 || fm > 1) {\n if (lx > rx) {\n if (!v0) v0 = [(y0 - fb) / fm, y0];\n else if (v0[1] >= y1) return;\n v1 = [(y1 - fb) / fm, y1];\n } else {\n if (!v0) v0 = [(y1 - fb) / fm, y1];\n else if (v0[1] < y0) return;\n v1 = [(y0 - fb) / fm, y0];\n }\n } else {\n if (ly < ry) {\n if (!v0) v0 = [x0, fm * x0 + fb];\n else if (v0[0] >= x1) return;\n v1 = [x1, fm * x1 + fb];\n } else {\n if (!v0) v0 = [x1, fm * x1 + fb];\n else if (v0[0] < x0) return;\n v1 = [x0, fm * x0 + fb];\n }\n }\n }\n\n edge[0] = v0;\n edge[1] = v1;\n return true;\n}\n\nfunction clipEdges(x0, y0, x1, y1) {\n var i = edges.length,\n edge;\n\n while (i--) {\n if (!connectEdge(edge = edges[i], x0, y0, x1, y1)\n || !clipEdge(edge, x0, y0, x1, y1)\n || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4\n || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {\n delete edges[i];\n }\n }\n}\n\nfunction createCell(site) {\n return cells[site.index] = {\n site: site,\n halfedges: []\n };\n}\n\nfunction cellHalfedgeAngle(cell, edge) {\n var site = cell.site,\n va = edge.left,\n vb = edge.right;\n if (site === vb) vb = va, va = site;\n if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);\n if (site === va) va = edge[1], vb = edge[0];\n else va = edge[0], vb = edge[1];\n return Math.atan2(va[0] - vb[0], vb[1] - va[1]);\n}\n\nfunction cellHalfedgeStart(cell, edge) {\n return edge[+(edge.left !== cell.site)];\n}\n\nfunction cellHalfedgeEnd(cell, edge) {\n return edge[+(edge.left === cell.site)];\n}\n\nfunction sortCellHalfedges() {\n for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {\n if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {\n var index = new Array(m),\n array = new Array(m);\n for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);\n index.sort(function(i, j) { return array[j] - array[i]; });\n for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];\n for (j = 0; j < m; ++j) halfedges[j] = array[j];\n }\n }\n}\n\nfunction clipCells(x0, y0, x1, y1) {\n var nCells = cells.length,\n iCell,\n cell,\n site,\n iHalfedge,\n halfedges,\n nHalfedges,\n start,\n startX,\n startY,\n end,\n endX,\n endY,\n cover = true;\n\n for (iCell = 0; iCell < nCells; ++iCell) {\n if (cell = cells[iCell]) {\n site = cell.site;\n halfedges = cell.halfedges;\n iHalfedge = halfedges.length;\n\n // Remove any dangling clipped edges.\n while (iHalfedge--) {\n if (!edges[halfedges[iHalfedge]]) {\n halfedges.splice(iHalfedge, 1);\n }\n }\n\n // Insert any border edges as necessary.\n iHalfedge = 0, nHalfedges = halfedges.length;\n while (iHalfedge < nHalfedges) {\n end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];\n start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];\n if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) {\n halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,\n Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]\n : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]\n : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]\n : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]\n : null)) - 1);\n ++nHalfedges;\n }\n }\n\n if (nHalfedges) cover = false;\n }\n }\n\n // If there weren’t any edges, have the closest site cover the extent.\n // It doesn’t matter which corner of the extent we measure!\n if (cover) {\n var dx, dy, d2, dc = Infinity;\n\n for (iCell = 0, cover = null; iCell < nCells; ++iCell) {\n if (cell = cells[iCell]) {\n site = cell.site;\n dx = site[0] - x0;\n dy = site[1] - y0;\n d2 = dx * dx + dy * dy;\n if (d2 < dc) dc = d2, cover = cell;\n }\n }\n\n if (cover) {\n var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];\n cover.halfedges.push(\n edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,\n edges.push(createBorderEdge(site, v01, v11)) - 1,\n edges.push(createBorderEdge(site, v11, v10)) - 1,\n edges.push(createBorderEdge(site, v10, v00)) - 1\n );\n }\n }\n\n // Lastly delete any cells with no edges; these were entirely clipped.\n for (iCell = 0; iCell < nCells; ++iCell) {\n if (cell = cells[iCell]) {\n if (!cell.halfedges.length) {\n delete cells[iCell];\n }\n }\n }\n}\n\nvar circlePool = [];\n\nvar firstCircle;\n\nfunction Circle() {\n RedBlackNode(this);\n this.x =\n this.y =\n this.arc =\n this.site =\n this.cy = null;\n}\n\nfunction attachCircle(arc) {\n var lArc = arc.P,\n rArc = arc.N;\n\n if (!lArc || !rArc) return;\n\n var lSite = lArc.site,\n cSite = arc.site,\n rSite = rArc.site;\n\n if (lSite === rSite) return;\n\n var bx = cSite[0],\n by = cSite[1],\n ax = lSite[0] - bx,\n ay = lSite[1] - by,\n cx = rSite[0] - bx,\n cy = rSite[1] - by;\n\n var d = 2 * (ax * cy - ay * cx);\n if (d >= -epsilon2$2) return;\n\n var ha = ax * ax + ay * ay,\n hc = cx * cx + cy * cy,\n x = (cy * ha - ay * hc) / d,\n y = (ax * hc - cx * ha) / d;\n\n var circle = circlePool.pop() || new Circle;\n circle.arc = arc;\n circle.site = cSite;\n circle.x = x + bx;\n circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom\n\n arc.circle = circle;\n\n var before = null,\n node = circles._;\n\n while (node) {\n if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {\n if (node.L) node = node.L;\n else { before = node.P; break; }\n } else {\n if (node.R) node = node.R;\n else { before = node; break; }\n }\n }\n\n circles.insert(before, circle);\n if (!before) firstCircle = circle;\n}\n\nfunction detachCircle(arc) {\n var circle = arc.circle;\n if (circle) {\n if (!circle.P) firstCircle = circle.N;\n circles.remove(circle);\n circlePool.push(circle);\n RedBlackNode(circle);\n arc.circle = null;\n }\n}\n\nvar beachPool = [];\n\nfunction Beach() {\n RedBlackNode(this);\n this.edge =\n this.site =\n this.circle = null;\n}\n\nfunction createBeach(site) {\n var beach = beachPool.pop() || new Beach;\n beach.site = site;\n return beach;\n}\n\nfunction detachBeach(beach) {\n detachCircle(beach);\n beaches.remove(beach);\n beachPool.push(beach);\n RedBlackNode(beach);\n}\n\nfunction removeBeach(beach) {\n var circle = beach.circle,\n x = circle.x,\n y = circle.cy,\n vertex = [x, y],\n previous = beach.P,\n next = beach.N,\n disappearing = [beach];\n\n detachBeach(beach);\n\n var lArc = previous;\n while (lArc.circle\n && Math.abs(x - lArc.circle.x) < epsilon$4\n && Math.abs(y - lArc.circle.cy) < epsilon$4) {\n previous = lArc.P;\n disappearing.unshift(lArc);\n detachBeach(lArc);\n lArc = previous;\n }\n\n disappearing.unshift(lArc);\n detachCircle(lArc);\n\n var rArc = next;\n while (rArc.circle\n && Math.abs(x - rArc.circle.x) < epsilon$4\n && Math.abs(y - rArc.circle.cy) < epsilon$4) {\n next = rArc.N;\n disappearing.push(rArc);\n detachBeach(rArc);\n rArc = next;\n }\n\n disappearing.push(rArc);\n detachCircle(rArc);\n\n var nArcs = disappearing.length,\n iArc;\n for (iArc = 1; iArc < nArcs; ++iArc) {\n rArc = disappearing[iArc];\n lArc = disappearing[iArc - 1];\n setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);\n }\n\n lArc = disappearing[0];\n rArc = disappearing[nArcs - 1];\n rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);\n\n attachCircle(lArc);\n attachCircle(rArc);\n}\n\nfunction addBeach(site) {\n var x = site[0],\n directrix = site[1],\n lArc,\n rArc,\n dxl,\n dxr,\n node = beaches._;\n\n while (node) {\n dxl = leftBreakPoint(node, directrix) - x;\n if (dxl > epsilon$4) node = node.L; else {\n dxr = x - rightBreakPoint(node, directrix);\n if (dxr > epsilon$4) {\n if (!node.R) {\n lArc = node;\n break;\n }\n node = node.R;\n } else {\n if (dxl > -epsilon$4) {\n lArc = node.P;\n rArc = node;\n } else if (dxr > -epsilon$4) {\n lArc = node;\n rArc = node.N;\n } else {\n lArc = rArc = node;\n }\n break;\n }\n }\n }\n\n createCell(site);\n var newArc = createBeach(site);\n beaches.insert(lArc, newArc);\n\n if (!lArc && !rArc) return;\n\n if (lArc === rArc) {\n detachCircle(lArc);\n rArc = createBeach(lArc.site);\n beaches.insert(newArc, rArc);\n newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);\n attachCircle(lArc);\n attachCircle(rArc);\n return;\n }\n\n if (!rArc) { // && lArc\n newArc.edge = createEdge(lArc.site, newArc.site);\n return;\n }\n\n // else lArc !== rArc\n detachCircle(lArc);\n detachCircle(rArc);\n\n var lSite = lArc.site,\n ax = lSite[0],\n ay = lSite[1],\n bx = site[0] - ax,\n by = site[1] - ay,\n rSite = rArc.site,\n cx = rSite[0] - ax,\n cy = rSite[1] - ay,\n d = 2 * (bx * cy - by * cx),\n hb = bx * bx + by * by,\n hc = cx * cx + cy * cy,\n vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];\n\n setEdgeEnd(rArc.edge, lSite, rSite, vertex);\n newArc.edge = createEdge(lSite, site, null, vertex);\n rArc.edge = createEdge(site, rSite, null, vertex);\n attachCircle(lArc);\n attachCircle(rArc);\n}\n\nfunction leftBreakPoint(arc, directrix) {\n var site = arc.site,\n rfocx = site[0],\n rfocy = site[1],\n pby2 = rfocy - directrix;\n\n if (!pby2) return rfocx;\n\n var lArc = arc.P;\n if (!lArc) return -Infinity;\n\n site = lArc.site;\n var lfocx = site[0],\n lfocy = site[1],\n plby2 = lfocy - directrix;\n\n if (!plby2) return lfocx;\n\n var hl = lfocx - rfocx,\n aby2 = 1 / pby2 - 1 / plby2,\n b = hl / plby2;\n\n if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;\n\n return (rfocx + lfocx) / 2;\n}\n\nfunction rightBreakPoint(arc, directrix) {\n var rArc = arc.N;\n if (rArc) return leftBreakPoint(rArc, directrix);\n var site = arc.site;\n return site[1] === directrix ? site[0] : Infinity;\n}\n\nvar epsilon$4 = 1e-6;\nvar epsilon2$2 = 1e-12;\nvar beaches;\nvar cells;\nvar circles;\nvar edges;\n\nfunction triangleArea(a, b, c) {\n return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);\n}\n\nfunction lexicographic(a, b) {\n return b[1] - a[1]\n || b[0] - a[0];\n}\n\nfunction Diagram(sites, extent) {\n var site = sites.sort(lexicographic).pop(),\n x,\n y,\n circle;\n\n edges = [];\n cells = new Array(sites.length);\n beaches = new RedBlackTree;\n circles = new RedBlackTree;\n\n while (true) {\n circle = firstCircle;\n if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {\n if (site[0] !== x || site[1] !== y) {\n addBeach(site);\n x = site[0], y = site[1];\n }\n site = sites.pop();\n } else if (circle) {\n removeBeach(circle.arc);\n } else {\n break;\n }\n }\n\n sortCellHalfedges();\n\n if (extent) {\n var x0 = +extent[0][0],\n y0 = +extent[0][1],\n x1 = +extent[1][0],\n y1 = +extent[1][1];\n clipEdges(x0, y0, x1, y1);\n clipCells(x0, y0, x1, y1);\n }\n\n this.edges = edges;\n this.cells = cells;\n\n beaches =\n circles =\n edges =\n cells = null;\n}\n\nDiagram.prototype = {\n constructor: Diagram,\n\n polygons: function() {\n var edges = this.edges;\n\n return this.cells.map(function(cell) {\n var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });\n polygon.data = cell.site.data;\n return polygon;\n });\n },\n\n triangles: function() {\n var triangles = [],\n edges = this.edges;\n\n this.cells.forEach(function(cell, i) {\n if (!(m = (halfedges = cell.halfedges).length)) return;\n var site = cell.site,\n halfedges,\n j = -1,\n m,\n s0,\n e1 = edges[halfedges[m - 1]],\n s1 = e1.left === site ? e1.right : e1.left;\n\n while (++j < m) {\n s0 = s1;\n e1 = edges[halfedges[j]];\n s1 = e1.left === site ? e1.right : e1.left;\n if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {\n triangles.push([site.data, s0.data, s1.data]);\n }\n }\n });\n\n return triangles;\n },\n\n links: function() {\n return this.edges.filter(function(edge) {\n return edge.right;\n }).map(function(edge) {\n return {\n source: edge.left.data,\n target: edge.right.data\n };\n });\n },\n\n find: function(x, y, radius) {\n var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell;\n\n // Use the previously-found cell, or start with an arbitrary one.\n while (!(cell = that.cells[i1])) if (++i1 >= n) return null;\n var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy;\n\n // Traverse the half-edges to find a closer cell, if any.\n do {\n cell = that.cells[i0 = i1], i1 = null;\n cell.halfedges.forEach(function(e) {\n var edge = that.edges[e], v = edge.left;\n if ((v === cell.site || !v) && !(v = edge.right)) return;\n var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy;\n if (v2 < d2) d2 = v2, i1 = v.index;\n });\n } while (i1 !== null);\n\n that._found = i0;\n\n return radius == null || d2 <= radius * radius ? cell.site : null;\n }\n};\n\nfunction voronoi() {\n var x$$1 = x$4,\n y$$1 = y$4,\n extent = null;\n\n function voronoi(data) {\n return new Diagram(data.map(function(d, i) {\n var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4];\n s.index = i;\n s.data = d;\n return s;\n }), extent);\n }\n\n voronoi.polygons = function(data) {\n return voronoi(data).polygons();\n };\n\n voronoi.links = function(data) {\n return voronoi(data).links();\n };\n\n voronoi.triangles = function(data) {\n return voronoi(data).triangles();\n };\n\n voronoi.x = function(_) {\n return arguments.length ? (x$$1 = typeof _ === \"function\" ? _ : constant$11(+_), voronoi) : x$$1;\n };\n\n voronoi.y = function(_) {\n return arguments.length ? (y$$1 = typeof _ === \"function\" ? _ : constant$11(+_), voronoi) : y$$1;\n };\n\n voronoi.extent = function(_) {\n return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]];\n };\n\n voronoi.size = function(_) {\n return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];\n };\n\n return voronoi;\n}\n\nfunction constant$12(x) {\n return function() {\n return x;\n };\n}\n\nfunction ZoomEvent(target, type, transform) {\n this.target = target;\n this.type = type;\n this.transform = transform;\n}\n\nfunction Transform(k, x, y) {\n this.k = k;\n this.x = x;\n this.y = y;\n}\n\nTransform.prototype = {\n constructor: Transform,\n scale: function(k) {\n return k === 1 ? this : new Transform(this.k * k, this.x, this.y);\n },\n translate: function(x, y) {\n return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);\n },\n apply: function(point) {\n return [point[0] * this.k + this.x, point[1] * this.k + this.y];\n },\n applyX: function(x) {\n return x * this.k + this.x;\n },\n applyY: function(y) {\n return y * this.k + this.y;\n },\n invert: function(location) {\n return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];\n },\n invertX: function(x) {\n return (x - this.x) / this.k;\n },\n invertY: function(y) {\n return (y - this.y) / this.k;\n },\n rescaleX: function(x) {\n return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));\n },\n rescaleY: function(y) {\n return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));\n },\n toString: function() {\n return \"translate(\" + this.x + \",\" + this.y + \") scale(\" + this.k + \")\";\n }\n};\n\nvar identity$8 = new Transform(1, 0, 0);\n\ntransform$1.prototype = Transform.prototype;\n\nfunction transform$1(node) {\n return node.__zoom || identity$8;\n}\n\nfunction nopropagation$2() {\n exports.event.stopImmediatePropagation();\n}\n\nfunction noevent$2() {\n exports.event.preventDefault();\n exports.event.stopImmediatePropagation();\n}\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter$2() {\n return !exports.event.button;\n}\n\nfunction defaultExtent$1() {\n var e = this, w, h;\n if (e instanceof SVGElement) {\n e = e.ownerSVGElement || e;\n w = e.width.baseVal.value;\n h = e.height.baseVal.value;\n } else {\n w = e.clientWidth;\n h = e.clientHeight;\n }\n return [[0, 0], [w, h]];\n}\n\nfunction defaultTransform() {\n return this.__zoom || identity$8;\n}\n\nfunction defaultWheelDelta() {\n return -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500;\n}\n\nfunction defaultTouchable$1() {\n return \"ontouchstart\" in this;\n}\n\nfunction defaultConstrain(transform$$1, extent, translateExtent) {\n var dx0 = transform$$1.invertX(extent[0][0]) - translateExtent[0][0],\n dx1 = transform$$1.invertX(extent[1][0]) - translateExtent[1][0],\n dy0 = transform$$1.invertY(extent[0][1]) - translateExtent[0][1],\n dy1 = transform$$1.invertY(extent[1][1]) - translateExtent[1][1];\n return transform$$1.translate(\n dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),\n dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)\n );\n}\n\nfunction zoom() {\n var filter = defaultFilter$2,\n extent = defaultExtent$1,\n constrain = defaultConstrain,\n wheelDelta = defaultWheelDelta,\n touchable = defaultTouchable$1,\n scaleExtent = [0, Infinity],\n translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]],\n duration = 250,\n interpolate = interpolateZoom,\n gestures = [],\n listeners = dispatch(\"start\", \"zoom\", \"end\"),\n touchstarting,\n touchending,\n touchDelay = 500,\n wheelDelay = 150,\n clickDistance2 = 0;\n\n function zoom(selection) {\n selection\n .property(\"__zoom\", defaultTransform)\n .on(\"wheel.zoom\", wheeled)\n .on(\"mousedown.zoom\", mousedowned)\n .on(\"dblclick.zoom\", dblclicked)\n .filter(touchable)\n .on(\"touchstart.zoom\", touchstarted)\n .on(\"touchmove.zoom\", touchmoved)\n .on(\"touchend.zoom touchcancel.zoom\", touchended)\n .style(\"touch-action\", \"none\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\");\n }\n\n zoom.transform = function(collection, transform$$1) {\n var selection = collection.selection ? collection.selection() : collection;\n selection.property(\"__zoom\", defaultTransform);\n if (collection !== selection) {\n schedule(collection, transform$$1);\n } else {\n selection.interrupt().each(function() {\n gesture(this, arguments)\n .start()\n .zoom(null, typeof transform$$1 === \"function\" ? transform$$1.apply(this, arguments) : transform$$1)\n .end();\n });\n }\n };\n\n zoom.scaleBy = function(selection, k) {\n zoom.scaleTo(selection, function() {\n var k0 = this.__zoom.k,\n k1 = typeof k === \"function\" ? k.apply(this, arguments) : k;\n return k0 * k1;\n });\n };\n\n zoom.scaleTo = function(selection, k) {\n zoom.transform(selection, function() {\n var e = extent.apply(this, arguments),\n t0 = this.__zoom,\n p0 = centroid(e),\n p1 = t0.invert(p0),\n k1 = typeof k === \"function\" ? k.apply(this, arguments) : k;\n return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent);\n });\n };\n\n zoom.translateBy = function(selection, x, y) {\n zoom.transform(selection, function() {\n return constrain(this.__zoom.translate(\n typeof x === \"function\" ? x.apply(this, arguments) : x,\n typeof y === \"function\" ? y.apply(this, arguments) : y\n ), extent.apply(this, arguments), translateExtent);\n });\n };\n\n zoom.translateTo = function(selection, x, y) {\n zoom.transform(selection, function() {\n var e = extent.apply(this, arguments),\n t = this.__zoom,\n p = centroid(e);\n return constrain(identity$8.translate(p[0], p[1]).scale(t.k).translate(\n typeof x === \"function\" ? -x.apply(this, arguments) : -x,\n typeof y === \"function\" ? -y.apply(this, arguments) : -y\n ), e, translateExtent);\n });\n };\n\n function scale(transform$$1, k) {\n k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k));\n return k === transform$$1.k ? transform$$1 : new Transform(k, transform$$1.x, transform$$1.y);\n }\n\n function translate(transform$$1, p0, p1) {\n var x = p0[0] - p1[0] * transform$$1.k, y = p0[1] - p1[1] * transform$$1.k;\n return x === transform$$1.x && y === transform$$1.y ? transform$$1 : new Transform(transform$$1.k, x, y);\n }\n\n function centroid(extent) {\n return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];\n }\n\n function schedule(transition, transform$$1, center) {\n transition\n .on(\"start.zoom\", function() { gesture(this, arguments).start(); })\n .on(\"interrupt.zoom end.zoom\", function() { gesture(this, arguments).end(); })\n .tween(\"zoom\", function() {\n var that = this,\n args = arguments,\n g = gesture(that, args),\n e = extent.apply(that, args),\n p = center || centroid(e),\n w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),\n a = that.__zoom,\n b = typeof transform$$1 === \"function\" ? transform$$1.apply(that, args) : transform$$1,\n i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));\n return function(t) {\n if (t === 1) t = b; // Avoid rounding error on end.\n else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }\n g.zoom(null, t);\n };\n });\n }\n\n function gesture(that, args) {\n for (var i = 0, n = gestures.length, g; i < n; ++i) {\n if ((g = gestures[i]).that === that) {\n return g;\n }\n }\n return new Gesture(that, args);\n }\n\n function Gesture(that, args) {\n this.that = that;\n this.args = args;\n this.index = -1;\n this.active = 0;\n this.extent = extent.apply(that, args);\n }\n\n Gesture.prototype = {\n start: function() {\n if (++this.active === 1) {\n this.index = gestures.push(this) - 1;\n this.emit(\"start\");\n }\n return this;\n },\n zoom: function(key, transform$$1) {\n if (this.mouse && key !== \"mouse\") this.mouse[1] = transform$$1.invert(this.mouse[0]);\n if (this.touch0 && key !== \"touch\") this.touch0[1] = transform$$1.invert(this.touch0[0]);\n if (this.touch1 && key !== \"touch\") this.touch1[1] = transform$$1.invert(this.touch1[0]);\n this.that.__zoom = transform$$1;\n this.emit(\"zoom\");\n return this;\n },\n end: function() {\n if (--this.active === 0) {\n gestures.splice(this.index, 1);\n this.index = -1;\n this.emit(\"end\");\n }\n return this;\n },\n emit: function(type) {\n customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);\n }\n };\n\n function wheeled() {\n if (!filter.apply(this, arguments)) return;\n var g = gesture(this, arguments),\n t = this.__zoom,\n k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),\n p = mouse(this);\n\n // If the mouse is in the same location as before, reuse it.\n // If there were recent wheel events, reset the wheel idle timeout.\n if (g.wheel) {\n if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {\n g.mouse[1] = t.invert(g.mouse[0] = p);\n }\n clearTimeout(g.wheel);\n }\n\n // If this wheel event won’t trigger a transform change, ignore it.\n else if (t.k === k) return;\n\n // Otherwise, capture the mouse point and location at the start.\n else {\n g.mouse = [p, t.invert(p)];\n interrupt(this);\n g.start();\n }\n\n noevent$2();\n g.wheel = setTimeout(wheelidled, wheelDelay);\n g.zoom(\"mouse\", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));\n\n function wheelidled() {\n g.wheel = null;\n g.end();\n }\n }\n\n function mousedowned() {\n if (touchending || !filter.apply(this, arguments)) return;\n var g = gesture(this, arguments),\n v = select(exports.event.view).on(\"mousemove.zoom\", mousemoved, true).on(\"mouseup.zoom\", mouseupped, true),\n p = mouse(this),\n x0 = exports.event.clientX,\n y0 = exports.event.clientY;\n\n dragDisable(exports.event.view);\n nopropagation$2();\n g.mouse = [p, this.__zoom.invert(p)];\n interrupt(this);\n g.start();\n\n function mousemoved() {\n noevent$2();\n if (!g.moved) {\n var dx = exports.event.clientX - x0, dy = exports.event.clientY - y0;\n g.moved = dx * dx + dy * dy > clickDistance2;\n }\n g.zoom(\"mouse\", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent, translateExtent));\n }\n\n function mouseupped() {\n v.on(\"mousemove.zoom mouseup.zoom\", null);\n yesdrag(exports.event.view, g.moved);\n noevent$2();\n g.end();\n }\n }\n\n function dblclicked() {\n if (!filter.apply(this, arguments)) return;\n var t0 = this.__zoom,\n p0 = mouse(this),\n p1 = t0.invert(p0),\n k1 = t0.k * (exports.event.shiftKey ? 0.5 : 2),\n t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments), translateExtent);\n\n noevent$2();\n if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0);\n else select(this).call(zoom.transform, t1);\n }\n\n function touchstarted() {\n if (!filter.apply(this, arguments)) return;\n var g = gesture(this, arguments),\n touches = exports.event.changedTouches,\n started,\n n = touches.length, i, t, p;\n\n nopropagation$2();\n for (i = 0; i < n; ++i) {\n t = touches[i], p = touch(this, touches, t.identifier);\n p = [p, this.__zoom.invert(p), t.identifier];\n if (!g.touch0) g.touch0 = p, started = true;\n else if (!g.touch1) g.touch1 = p;\n }\n\n // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.\n if (touchstarting) {\n touchstarting = clearTimeout(touchstarting);\n if (!g.touch1) {\n g.end();\n p = select(this).on(\"dblclick.zoom\");\n if (p) p.apply(this, arguments);\n return;\n }\n }\n\n if (started) {\n touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);\n interrupt(this);\n g.start();\n }\n }\n\n function touchmoved() {\n var g = gesture(this, arguments),\n touches = exports.event.changedTouches,\n n = touches.length, i, t, p, l;\n\n noevent$2();\n if (touchstarting) touchstarting = clearTimeout(touchstarting);\n for (i = 0; i < n; ++i) {\n t = touches[i], p = touch(this, touches, t.identifier);\n if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;\n else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;\n }\n t = g.that.__zoom;\n if (g.touch1) {\n var p0 = g.touch0[0], l0 = g.touch0[1],\n p1 = g.touch1[0], l1 = g.touch1[1],\n dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,\n dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;\n t = scale(t, Math.sqrt(dp / dl));\n p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];\n l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];\n }\n else if (g.touch0) p = g.touch0[0], l = g.touch0[1];\n else return;\n g.zoom(\"touch\", constrain(translate(t, p, l), g.extent, translateExtent));\n }\n\n function touchended() {\n var g = gesture(this, arguments),\n touches = exports.event.changedTouches,\n n = touches.length, i, t;\n\n nopropagation$2();\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, touchDelay);\n for (i = 0; i < n; ++i) {\n t = touches[i];\n if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;\n else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;\n }\n if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;\n if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]);\n else g.end();\n }\n\n zoom.wheelDelta = function(_) {\n return arguments.length ? (wheelDelta = typeof _ === \"function\" ? _ : constant$12(+_), zoom) : wheelDelta;\n };\n\n zoom.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant$12(!!_), zoom) : filter;\n };\n\n zoom.touchable = function(_) {\n return arguments.length ? (touchable = typeof _ === \"function\" ? _ : constant$12(!!_), zoom) : touchable;\n };\n\n zoom.extent = function(_) {\n return arguments.length ? (extent = typeof _ === \"function\" ? _ : constant$12([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;\n };\n\n zoom.scaleExtent = function(_) {\n return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]];\n };\n\n zoom.translateExtent = function(_) {\n return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]];\n };\n\n zoom.constrain = function(_) {\n return arguments.length ? (constrain = _, zoom) : constrain;\n };\n\n zoom.duration = function(_) {\n return arguments.length ? (duration = +_, zoom) : duration;\n };\n\n zoom.interpolate = function(_) {\n return arguments.length ? (interpolate = _, zoom) : interpolate;\n };\n\n zoom.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? zoom : value;\n };\n\n zoom.clickDistance = function(_) {\n return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);\n };\n\n return zoom;\n}\n\nexports.version = version;\nexports.bisect = bisectRight;\nexports.bisectRight = bisectRight;\nexports.bisectLeft = bisectLeft;\nexports.ascending = ascending;\nexports.bisector = bisector;\nexports.cross = cross;\nexports.descending = descending;\nexports.deviation = deviation;\nexports.extent = extent;\nexports.histogram = histogram;\nexports.thresholdFreedmanDiaconis = freedmanDiaconis;\nexports.thresholdScott = scott;\nexports.thresholdSturges = sturges;\nexports.max = max;\nexports.mean = mean;\nexports.median = median;\nexports.merge = merge;\nexports.min = min;\nexports.pairs = pairs;\nexports.permute = permute;\nexports.quantile = threshold;\nexports.range = sequence;\nexports.scan = scan;\nexports.shuffle = shuffle;\nexports.sum = sum;\nexports.ticks = ticks;\nexports.tickIncrement = tickIncrement;\nexports.tickStep = tickStep;\nexports.transpose = transpose;\nexports.variance = variance;\nexports.zip = zip;\nexports.axisTop = axisTop;\nexports.axisRight = axisRight;\nexports.axisBottom = axisBottom;\nexports.axisLeft = axisLeft;\nexports.brush = brush;\nexports.brushX = brushX;\nexports.brushY = brushY;\nexports.brushSelection = brushSelection;\nexports.chord = chord;\nexports.ribbon = ribbon;\nexports.nest = nest;\nexports.set = set$2;\nexports.map = map$1;\nexports.keys = keys;\nexports.values = values;\nexports.entries = entries;\nexports.color = color;\nexports.rgb = rgb;\nexports.hsl = hsl;\nexports.lab = lab;\nexports.hcl = hcl;\nexports.cubehelix = cubehelix;\nexports.dispatch = dispatch;\nexports.drag = drag;\nexports.dragDisable = dragDisable;\nexports.dragEnable = yesdrag;\nexports.dsvFormat = dsv;\nexports.csvParse = csvParse;\nexports.csvParseRows = csvParseRows;\nexports.csvFormat = csvFormat;\nexports.csvFormatRows = csvFormatRows;\nexports.tsvParse = tsvParse;\nexports.tsvParseRows = tsvParseRows;\nexports.tsvFormat = tsvFormat;\nexports.tsvFormatRows = tsvFormatRows;\nexports.easeLinear = linear$1;\nexports.easeQuad = quadInOut;\nexports.easeQuadIn = quadIn;\nexports.easeQuadOut = quadOut;\nexports.easeQuadInOut = quadInOut;\nexports.easeCubic = cubicInOut;\nexports.easeCubicIn = cubicIn;\nexports.easeCubicOut = cubicOut;\nexports.easeCubicInOut = cubicInOut;\nexports.easePoly = polyInOut;\nexports.easePolyIn = polyIn;\nexports.easePolyOut = polyOut;\nexports.easePolyInOut = polyInOut;\nexports.easeSin = sinInOut;\nexports.easeSinIn = sinIn;\nexports.easeSinOut = sinOut;\nexports.easeSinInOut = sinInOut;\nexports.easeExp = expInOut;\nexports.easeExpIn = expIn;\nexports.easeExpOut = expOut;\nexports.easeExpInOut = expInOut;\nexports.easeCircle = circleInOut;\nexports.easeCircleIn = circleIn;\nexports.easeCircleOut = circleOut;\nexports.easeCircleInOut = circleInOut;\nexports.easeBounce = bounceOut;\nexports.easeBounceIn = bounceIn;\nexports.easeBounceOut = bounceOut;\nexports.easeBounceInOut = bounceInOut;\nexports.easeBack = backInOut;\nexports.easeBackIn = backIn;\nexports.easeBackOut = backOut;\nexports.easeBackInOut = backInOut;\nexports.easeElastic = elasticOut;\nexports.easeElasticIn = elasticIn;\nexports.easeElasticOut = elasticOut;\nexports.easeElasticInOut = elasticInOut;\nexports.forceCenter = center$1;\nexports.forceCollide = collide;\nexports.forceLink = link;\nexports.forceManyBody = manyBody;\nexports.forceRadial = radial;\nexports.forceSimulation = simulation;\nexports.forceX = x$2;\nexports.forceY = y$2;\nexports.formatDefaultLocale = defaultLocale;\nexports.formatLocale = formatLocale;\nexports.formatSpecifier = formatSpecifier;\nexports.precisionFixed = precisionFixed;\nexports.precisionPrefix = precisionPrefix;\nexports.precisionRound = precisionRound;\nexports.geoArea = area;\nexports.geoBounds = bounds;\nexports.geoCentroid = centroid;\nexports.geoCircle = circle;\nexports.geoClipAntimeridian = clipAntimeridian;\nexports.geoClipCircle = clipCircle;\nexports.geoClipExtent = extent$1;\nexports.geoClipRectangle = clipRectangle;\nexports.geoContains = contains;\nexports.geoDistance = distance;\nexports.geoGraticule = graticule;\nexports.geoGraticule10 = graticule10;\nexports.geoInterpolate = interpolate$1;\nexports.geoLength = length$1;\nexports.geoPath = index$1;\nexports.geoAlbers = albers;\nexports.geoAlbersUsa = albersUsa;\nexports.geoAzimuthalEqualArea = azimuthalEqualArea;\nexports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw;\nexports.geoAzimuthalEquidistant = azimuthalEquidistant;\nexports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw;\nexports.geoConicConformal = conicConformal;\nexports.geoConicConformalRaw = conicConformalRaw;\nexports.geoConicEqualArea = conicEqualArea;\nexports.geoConicEqualAreaRaw = conicEqualAreaRaw;\nexports.geoConicEquidistant = conicEquidistant;\nexports.geoConicEquidistantRaw = conicEquidistantRaw;\nexports.geoEquirectangular = equirectangular;\nexports.geoEquirectangularRaw = equirectangularRaw;\nexports.geoGnomonic = gnomonic;\nexports.geoGnomonicRaw = gnomonicRaw;\nexports.geoIdentity = identity$5;\nexports.geoProjection = projection;\nexports.geoProjectionMutator = projectionMutator;\nexports.geoMercator = mercator;\nexports.geoMercatorRaw = mercatorRaw;\nexports.geoNaturalEarth1 = naturalEarth1;\nexports.geoNaturalEarth1Raw = naturalEarth1Raw;\nexports.geoOrthographic = orthographic;\nexports.geoOrthographicRaw = orthographicRaw;\nexports.geoStereographic = stereographic;\nexports.geoStereographicRaw = stereographicRaw;\nexports.geoTransverseMercator = transverseMercator;\nexports.geoTransverseMercatorRaw = transverseMercatorRaw;\nexports.geoRotation = rotation;\nexports.geoStream = geoStream;\nexports.geoTransform = transform;\nexports.cluster = cluster;\nexports.hierarchy = hierarchy;\nexports.pack = index$2;\nexports.packSiblings = siblings;\nexports.packEnclose = enclose;\nexports.partition = partition;\nexports.stratify = stratify;\nexports.tree = tree;\nexports.treemap = index$3;\nexports.treemapBinary = binary;\nexports.treemapDice = treemapDice;\nexports.treemapSlice = treemapSlice;\nexports.treemapSliceDice = sliceDice;\nexports.treemapSquarify = squarify;\nexports.treemapResquarify = resquarify;\nexports.interpolate = interpolateValue;\nexports.interpolateArray = array$1;\nexports.interpolateBasis = basis$1;\nexports.interpolateBasisClosed = basisClosed;\nexports.interpolateDate = date;\nexports.interpolateNumber = reinterpolate;\nexports.interpolateObject = object;\nexports.interpolateRound = interpolateRound;\nexports.interpolateString = interpolateString;\nexports.interpolateTransformCss = interpolateTransformCss;\nexports.interpolateTransformSvg = interpolateTransformSvg;\nexports.interpolateZoom = interpolateZoom;\nexports.interpolateRgb = interpolateRgb;\nexports.interpolateRgbBasis = rgbBasis;\nexports.interpolateRgbBasisClosed = rgbBasisClosed;\nexports.interpolateHsl = hsl$2;\nexports.interpolateHslLong = hslLong;\nexports.interpolateLab = lab$1;\nexports.interpolateHcl = hcl$2;\nexports.interpolateHclLong = hclLong;\nexports.interpolateCubehelix = cubehelix$2;\nexports.interpolateCubehelixLong = cubehelixLong;\nexports.quantize = quantize;\nexports.path = path;\nexports.polygonArea = area$1;\nexports.polygonCentroid = centroid$1;\nexports.polygonHull = hull;\nexports.polygonContains = contains$1;\nexports.polygonLength = length$2;\nexports.quadtree = quadtree;\nexports.queue = queue;\nexports.randomUniform = uniform;\nexports.randomNormal = normal;\nexports.randomLogNormal = logNormal;\nexports.randomBates = bates;\nexports.randomIrwinHall = irwinHall;\nexports.randomExponential = exponential$1;\nexports.request = request;\nexports.html = html;\nexports.json = json;\nexports.text = text;\nexports.xml = xml;\nexports.csv = csv$1;\nexports.tsv = tsv$1;\nexports.scaleBand = band;\nexports.scalePoint = point$1;\nexports.scaleIdentity = identity$6;\nexports.scaleLinear = linear$2;\nexports.scaleLog = log$1;\nexports.scaleOrdinal = ordinal;\nexports.scaleImplicit = implicit;\nexports.scalePow = pow$1;\nexports.scaleSqrt = sqrt$1;\nexports.scaleQuantile = quantile$$1;\nexports.scaleQuantize = quantize$1;\nexports.scaleThreshold = threshold$1;\nexports.scaleTime = time;\nexports.scaleUtc = utcTime;\nexports.schemeCategory10 = category10;\nexports.schemeCategory20b = category20b;\nexports.schemeCategory20c = category20c;\nexports.schemeCategory20 = category20;\nexports.interpolateCubehelixDefault = cubehelix$3;\nexports.interpolateRainbow = rainbow$1;\nexports.interpolateWarm = warm;\nexports.interpolateCool = cool;\nexports.interpolateViridis = viridis;\nexports.interpolateMagma = magma;\nexports.interpolateInferno = inferno;\nexports.interpolatePlasma = plasma;\nexports.scaleSequential = sequential;\nexports.create = create;\nexports.creator = creator;\nexports.local = local$1;\nexports.matcher = matcher$1;\nexports.mouse = mouse;\nexports.namespace = namespace;\nexports.namespaces = namespaces;\nexports.clientPoint = point;\nexports.select = select;\nexports.selectAll = selectAll;\nexports.selection = selection;\nexports.selector = selector;\nexports.selectorAll = selectorAll;\nexports.style = styleValue;\nexports.touch = touch;\nexports.touches = touches;\nexports.window = defaultView;\nexports.customEvent = customEvent;\nexports.arc = arc;\nexports.area = area$2;\nexports.line = line;\nexports.pie = pie;\nexports.areaRadial = areaRadial;\nexports.radialArea = areaRadial;\nexports.lineRadial = lineRadial$1;\nexports.radialLine = lineRadial$1;\nexports.pointRadial = pointRadial;\nexports.linkHorizontal = linkHorizontal;\nexports.linkVertical = linkVertical;\nexports.linkRadial = linkRadial;\nexports.symbol = symbol;\nexports.symbols = symbols;\nexports.symbolCircle = circle$2;\nexports.symbolCross = cross$2;\nexports.symbolDiamond = diamond;\nexports.symbolSquare = square;\nexports.symbolStar = star;\nexports.symbolTriangle = triangle;\nexports.symbolWye = wye;\nexports.curveBasisClosed = basisClosed$1;\nexports.curveBasisOpen = basisOpen;\nexports.curveBasis = basis$2;\nexports.curveBundle = bundle;\nexports.curveCardinalClosed = cardinalClosed;\nexports.curveCardinalOpen = cardinalOpen;\nexports.curveCardinal = cardinal;\nexports.curveCatmullRomClosed = catmullRomClosed;\nexports.curveCatmullRomOpen = catmullRomOpen;\nexports.curveCatmullRom = catmullRom;\nexports.curveLinearClosed = linearClosed;\nexports.curveLinear = curveLinear;\nexports.curveMonotoneX = monotoneX;\nexports.curveMonotoneY = monotoneY;\nexports.curveNatural = natural;\nexports.curveStep = step;\nexports.curveStepAfter = stepAfter;\nexports.curveStepBefore = stepBefore;\nexports.stack = stack;\nexports.stackOffsetExpand = expand;\nexports.stackOffsetDiverging = diverging;\nexports.stackOffsetNone = none$1;\nexports.stackOffsetSilhouette = silhouette;\nexports.stackOffsetWiggle = wiggle;\nexports.stackOrderAscending = ascending$2;\nexports.stackOrderDescending = descending$2;\nexports.stackOrderInsideOut = insideOut;\nexports.stackOrderNone = none$2;\nexports.stackOrderReverse = reverse;\nexports.timeInterval = newInterval;\nexports.timeMillisecond = millisecond;\nexports.timeMilliseconds = milliseconds;\nexports.utcMillisecond = millisecond;\nexports.utcMilliseconds = milliseconds;\nexports.timeSecond = second;\nexports.timeSeconds = seconds;\nexports.utcSecond = second;\nexports.utcSeconds = seconds;\nexports.timeMinute = minute;\nexports.timeMinutes = minutes;\nexports.timeHour = hour;\nexports.timeHours = hours;\nexports.timeDay = day;\nexports.timeDays = days;\nexports.timeWeek = sunday;\nexports.timeWeeks = sundays;\nexports.timeSunday = sunday;\nexports.timeSundays = sundays;\nexports.timeMonday = monday;\nexports.timeMondays = mondays;\nexports.timeTuesday = tuesday;\nexports.timeTuesdays = tuesdays;\nexports.timeWednesday = wednesday;\nexports.timeWednesdays = wednesdays;\nexports.timeThursday = thursday;\nexports.timeThursdays = thursdays;\nexports.timeFriday = friday;\nexports.timeFridays = fridays;\nexports.timeSaturday = saturday;\nexports.timeSaturdays = saturdays;\nexports.timeMonth = month;\nexports.timeMonths = months;\nexports.timeYear = year;\nexports.timeYears = years;\nexports.utcMinute = utcMinute;\nexports.utcMinutes = utcMinutes;\nexports.utcHour = utcHour;\nexports.utcHours = utcHours;\nexports.utcDay = utcDay;\nexports.utcDays = utcDays;\nexports.utcWeek = utcSunday;\nexports.utcWeeks = utcSundays;\nexports.utcSunday = utcSunday;\nexports.utcSundays = utcSundays;\nexports.utcMonday = utcMonday;\nexports.utcMondays = utcMondays;\nexports.utcTuesday = utcTuesday;\nexports.utcTuesdays = utcTuesdays;\nexports.utcWednesday = utcWednesday;\nexports.utcWednesdays = utcWednesdays;\nexports.utcThursday = utcThursday;\nexports.utcThursdays = utcThursdays;\nexports.utcFriday = utcFriday;\nexports.utcFridays = utcFridays;\nexports.utcSaturday = utcSaturday;\nexports.utcSaturdays = utcSaturdays;\nexports.utcMonth = utcMonth;\nexports.utcMonths = utcMonths;\nexports.utcYear = utcYear;\nexports.utcYears = utcYears;\nexports.timeFormatDefaultLocale = defaultLocale$1;\nexports.timeFormatLocale = formatLocale$1;\nexports.isoFormat = formatIso;\nexports.isoParse = parseIso;\nexports.now = now;\nexports.timer = timer;\nexports.timerFlush = timerFlush;\nexports.timeout = timeout$1;\nexports.interval = interval$1;\nexports.transition = transition;\nexports.active = active;\nexports.interrupt = interrupt;\nexports.voronoi = voronoi;\nexports.zoom = zoom;\nexports.zoomTransform = transform$1;\nexports.zoomIdentity = identity$8;\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n"]} \ No newline at end of file +{"version":3,"sources":["d3.js"],"names":["global","factory","exports","module","define","amd","d3","this","ascending","a","b","NaN","bisector","compare","length","f","d","x","ascendingComparator","left","lo","hi","mid","right","ascendingBisect","bisectRight","bisectLeft","pair","number","variance","values","valueof","value","delta","n","m","i","mean","sum","isNaN","deviation","array","v","Math","sqrt","extent","min","max","Array","prototype","slice","map","constant","identity","sequence","start","stop","step","arguments","ceil","range","e10","e5","e2","ticks","count","reverse","tickIncrement","isFinite","floor","power","log","LN10","error","pow","tickStep","step0","abs","step1","sturges","LN2","threshold","p","i0","value0","merge","arrays","merged","j","transpose","matrix","row","slice$1","identity$1","top","bottom","epsilon","translateX","translateY","y","entering","__axis","axis","orient","scale","tickArguments","tickValues","tickFormat","tickSizeInner","tickSizeOuter","tickPadding","k","transform","context","apply","domain","format","spacing","range0","range1","position","bandwidth","offset","round","copy","selection","path","selectAll","data","tick","order","tickExit","exit","tickEnter","enter","append","attr","line","select","text","insert","transition","getAttribute","parentNode","remove","filter","each","_","call","tickSize","noop","dispatch","t","Error","Dispatch","get","type","name","c","set","callback","concat","push","constructor","on","typename","T","typenames","types","trim","split","indexOf","hasOwnProperty","parseTypenames","that","args","xhtml","namespaces","svg","xlink","xml","xmlns","namespace","prefix","space","local","creator","fullname","ownerDocument","createElementNS","document","uri","namespaceURI","documentElement","createElement","none","selector","querySelector","empty$1","selectorAll","querySelectorAll","matcher","matches","element","vendorMatches","webkitMatchesSelector","msMatchesSelector","mozMatchesSelector","oMatchesSelector","matcher$1","sparse","update","EnterNode","parent","datum","_next","_parent","__data__","appendChild","child","insertBefore","next","keyPrefix","bindIndex","group","node","groupLength","dataLength","bindKey","key","keyValue","nodeByKeyValue","keyValues","ascending$1","defaultView","styleValue","style","getPropertyValue","getComputedStyle","classArray","string","classList","ClassList","_node","_names","classedAdd","names","list","add","classedRemove","textRemove","textContent","htmlRemove","innerHTML","raise","nextSibling","lower","previousSibling","firstChild","constantNull","removeChild","selection_cloneShallow","cloneNode","selection_cloneDeep","setAttribute","join","splice","contains","filterEvents","event","mouseenter","mouseleave","filterContextListener","listener","index","contextListener","related","relatedTarget","compareDocumentPosition","event1","event0","onRemove","__on","o","removeEventListener","capture","onAdd","wrap","addEventListener","customEvent","sourceEvent","dispatchEvent","params","window","CustomEvent","createEvent","initEvent","bubbles","cancelable","detail","root","Selection","groups","parents","_groups","_parents","subgroups","subnode","subgroup","match","size","bind","constant$1","enterGroup","updateGroup","previous","i1","_enter","_exit","selection$$1","groups0","groups1","m0","m1","merges","group0","group1","sort","compareNode","sortgroups","sortgroup","nodes","empty","getAttributeNS","removeAttributeNS","removeAttribute","setAttributeNS","priority","removeProperty","setProperty","property","classed","html","create","before","clone","deep","parseTypenames$1","nextId","local$1","Local","toString","source","current","point","ownerSVGElement","createSVGPoint","clientX","clientY","matrixTransform","getScreenCTM","inverse","rect","getBoundingClientRect","clientLeft","clientTop","mouse","changedTouches","touch","touches","identifier","nopropagation","stopImmediatePropagation","noevent","preventDefault","dragDisable","view","__noselect","MozUserSelect","yesdrag","noclick","setTimeout","constant$2","DragEvent","target","subject","id","active","dx","dy","defaultFilter$1","button","defaultContainer","defaultSubject","defaultTouchable","extend","definition","Object","Color","brighter","reI","reN","reP","reHex3","reHex6","reRgbInteger","RegExp","reRgbPercent","reRgbaInteger","reRgbaPercent","reHslPercent","reHslaPercent","named","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","color","toLowerCase","exec","Rgb","parseInt","rgbn","rgba","hsla","r","g","rgbConvert","rgb","opacity","h","s","l","Hsl","hsl","hslConvert","hsl2rgb","m2","displayable","darker","deg2rad","PI","rad2deg","Xn","Yn","Zn","t0","t1","t2","t3","labConvert","Lab","Hcl","cos","sin","rgb2xyz","xyz2lab","lab","lab2xyz","xyz2rgb","hcl","atan2","hclConvert","z","B","C","D","E","ED","EB","BC_DA","cubehelix","Cubehelix","bl","cubehelixConvert","basis","v0","v1","v2","v3","basis$1","basisClosed","constant$3","linear","hue","gamma","nogamma","exponential","cosh","sinh","interpolateRgb","rgbGamma","color$$1","rgb$$1","end","rgbSpline","spline","colors","rgbBasis","rgbBasisClosed","array$1","nb","na","interpolateValue","date","Date","setTime","reinterpolate","object","reA","reB","interpolateString","am","bm","bs","bi","lastIndex","q","one","zero","isArray","valueOf","interpolateRound","cssNode","cssRoot","cssView","svgNode","degrees","identity$2","rotate","skewX","scaleX","scaleY","decompose","e","atan","interpolateTransform","parse","pxComma","pxParen","degParen","pop","xa","ya","xb","yb","translate","interpolateTransformCss","interpolateTransformSvg","baseVal","consolidate","rho","SQRT2","rho2","rho4","epsilon2","exp","interpolateZoom","p0","p1","S","ux0","uy0","w0","ux1","uy1","w1","d2","d1","b0","b1","r0","r1","coshr0","u","tanh","duration","hsl$1","hue$$1","hsl$2","hslLong","hcl$1","hcl$2","hclLong","cubehelix$1","cubehelixGamma","cubehelix$$1","cubehelix$2","cubehelixLong","taskHead","taskTail","frame","timeout","interval","pokeDelay","clockLast","clockNow","clockSkew","clock","performance","now","setFrame","requestAnimationFrame","clearNow","Timer","_call","_time","timer","delay","time","restart","timerFlush","wake","Infinity","sleep","nap","poke","clearTimeout","clearInterval","setInterval","timeout$1","elapsed","TypeError","emptyOn","emptyTween","CREATED","SCHEDULED","STARTING","STARTED","RUNNING","ENDING","ENDED","schedule","timing","schedules","__transition","self","tween","state","ease","create$1","init","get$1","set$1","interrupt","schedule$$1","tweenValue","_id","interpolate","Selection$1","Transition","_name","newId","selection_prototype","quadInOut","cubicInOut","children","inherit","transition$$1","id0","id1","on0","on1","sit","every","onFunction","attrTween","interpolate$$1","value00","value10","interpolate0","value1","_value","styleTween","styleRemove$1","styleRemoveEnd","styleFunction$1","styleConstant$1","textFunction$1","textConstant$1","removeFunction","tween0","tween1","easeConstant","polyIn","custom","exponent","polyOut","polyInOut","pi","halfPi","sinInOut","expInOut","circleInOut","b2","b3","b4","b5","b6","b7","b8","b9","bounceOut","overshoot","backIn","backOut","backInOut","tau","elasticIn","asin","amplitude","period","elasticOut","elasticInOut","defaultTiming","root$1","constant$4","BrushEvent","nopropagation$1","noevent$1","MODE_DRAG","MODE_SPACE","MODE_HANDLE","MODE_CENTER","X","handles","input","output","xy","Y","XY","cursors","overlay","w","nw","ne","se","sw","flipX","flipY","signsX","signsY","defaultFilter","defaultExtent","width","height","__brush","brush$1","dim","touchending","listeners","brush","handleSize","initialize","handle","redraw","started","emitter","Emitter","n0","n1","e0","e1","s0","s1","moving","lockX","lockY","mode","metaKey","altKey","signX","signY","W","N","shifting","shiftKey","point0","emit","beforestart","moved","ended","keyCode","move","point1","selection0","selection1","starting","pi$1","halfPi$1","tau$1","max$1","slice$2","constant$5","pi$2","tau$2","epsilon$1","tauEpsilon","Path","_x0","_y0","_x1","_y1","defaultSource","defaultTarget","defaultRadius","radius","defaultStartAngle","startAngle","defaultEndAngle","endAngle","moveTo","closePath","lineTo","quadraticCurveTo","x1","y1","bezierCurveTo","x2","y2","arcTo","x0","y0","x21","y21","x01","y01","l01_2","x20","y20","l21_2","l20_2","l21","l01","acos","t01","t21","arc","a0","a1","ccw","cw","da","Map","map$1","createObject","setObject","createMap","setMap","Set","has","clear","keys","entries","proto","set$2","EOL","EOF","objectConverter","columns","Function","JSON","stringify","dsv","delimiter","reFormat","DELIMITER","charCodeAt","parseRows","rows","I","eof","eol","token","replace","formatRow","formatValue","test","convert","customConverter","columnSet","forEach","column","inferColumns","formatRows","csv","csvParse","csvParseRows","csvFormat","csvFormatRows","tsv","tsvParse","tsvParseRows","tsvFormat","tsvFormatRows","constant$6","jiggle","random","tree","xm","ym","xp","yp","_root","leaf","_x","_y","Quad","defaultX","defaultY","quadtree","Quadtree","addAll","undefined","leaf_copy","treeProto","vx","vy","find","nodeById","nodeId","x$1","y$1","cover","xz","yz","visit","x3","y3","quads","retainer","removeAll","visitAfter","prefixExponent","initialAngle","formatDecimal","toExponential","coefficient","exponent$1","formatRounded","formatTypes","","out","toPrecision","%","toFixed","toUpperCase","re","formatSpecifier","specifier","FormatSpecifier","fill","align","sign","symbol","comma","precision","identity$3","locale","prefixes","formatLocale","grouping","thousands","substring","formatGroup","currency","decimal","numerals","formatNumerals","percent","newFormat","suffix","formatType","maybeSuffix","valuePrefix","valueSuffix","valueNegative","padding","formatPrefix","defaultLocale","precisionFixed","precisionPrefix","precisionRound","adder","Adder","reset","add$1","temp","bv","av","epsilon$2","pi$3","halfPi$2","quarterPi","tau$3","degrees$1","radians","cos$1","sin$1","haversin","noop$1","streamGeometry","geometry","stream","streamGeometryType","streamObjectType","Feature","FeatureCollection","features","Sphere","sphere","Point","coordinates","MultiPoint","LineString","streamLine","MultiLineString","Polygon","streamPolygon","MultiPolygon","GeometryCollection","geometries","closed","coordinate","lineStart","lineEnd","polygonStart","polygonEnd","geoStream","lambda00","phi00","lambda0","cosPhi0","sinPhi0","lambda0$1","phi0","lambda1","phi1","lambda2","lambda00$1","phi00$1","areaRingSum","areaSum","areaStream","areaRingStart","areaRingEnd","areaRing","areaPointFirst","areaPoint","lambda","phi","dLambda","sdLambda","adLambda","cosPhi","sinPhi","spherical","cartesian","cartesianDot","cartesianCross","cartesianAddInPlace","cartesianScale","vector","cartesianNormalizeInPlace","ranges","W0","W1","X0","Y0","Z0","X1","Y1","Z1","X2","Y2","Z2","lambda00$2","phi00$2","z0","deltaSum","boundsStream","boundsPoint","boundsLineStart","boundsLineEnd","boundsRingPoint","boundsRingStart","boundsRingEnd","linePoint","normal","inflection","phii","sign$$1","lambdai","antimeridian","angle","rangeCompare","rangeContains","centroidStream","centroidPoint","centroidLineStart","centroidLineEnd","centroidRingStart","centroidRingEnd","centroidPointCartesian","centroidLinePointFirst","centroidLinePoint","centroidRingPointFirst","centroidRingPoint","cx","cy","cz","constant$7","compose","invert","rotationIdentity","rotateRadians","deltaLambda","deltaPhi","deltaGamma","rotationLambda","rotationPhiGamma","forwardRotationLambda","rotation","cosDeltaPhi","sinDeltaPhi","cosDeltaGamma","sinDeltaGamma","forward","circleStream","direction","cosRadius","sinRadius","circleRadius","clipBuffer","lines","rejoin","shift","result","pointEqual","Intersection","points","other","entry","clipRejoin","segments","compareIntersection","startInside","clip","segment","link$1","isSubject","sum$1","polygonContains","polygon","winding","ring","sinPhi1","cosPhi1","absDelta","intersection","phiArc","pointVisible","clipLine","sink","ringBuffer","ringSink","polygonStarted","pointRing","ringStart","ringEnd","pointLine","clean","ringSegments","validSegment","clipAntimeridian","sign0","sign1","sinLambda0Lambda1","clipAntimeridianIntersect","from","to","clipCircle","cr","smallRadius","notHemisphere","visible","intersect","two","n2","n2n2","n1n2","determinant","c1","c2","n1xn2","A","uu","polar","q1","code","c0","v00","point2","clipMax","clipMin","clipRectangle","corner","comparePoint","ca","cb","x__","y__","v__","x_","y_","v_","first","activeStream","bufferStream","clipStream","polygonInside","cleanInside","ax","ay","lambda0$2","sinPhi0$1","cosPhi0$1","lengthSum","lengthStream","lengthPointFirst","lengthLineEnd","lengthPoint","cosDelta","length$1","object$1","distance","containsObjectType","containsGeometry","containsGeometryType","containsPoint","containsLine","containsPolygon","ab","ringRadians","pointRadians","graticuleX","graticuleY","graticule","DX","DY","outline","extentMajor","extentMinor","stepMajor","stepMinor","identity$4","x00","y00","x0$1","y0$1","areaSum$1","areaRingSum$1","areaStream$1","areaRingStart$1","areaRingEnd$1","area","areaPointFirst$1","areaPoint$1","x0$2","y0$2","boundsStream$1","bounds","x00$1","y00$1","x0$3","y0$3","X0$1","Y0$1","Z0$1","X1$1","Y1$1","Z1$1","X2$1","Y2$1","Z2$1","centroidStream$1","centroidPoint$1","centroidLineStart$1","centroidLineEnd$1","centroidRingStart$1","centroidRingEnd$1","centroid","centroidPointFirstLine","centroidPointLine","centroidPointFirstRing","centroidPointRing","PathContext","_context","_radius","pointRadius","_line","_point","lengthRing","x00$2","y00$2","x0$4","y0$4","lengthSum$1","lengthStream$1","lengthPointFirst$1","lengthPoint$1","PathString","_string","circle$1","transformer","methods","TransformStream","fit","projection","fitBounds","clipExtent","fitExtent","fitSize","fitWidth","fitHeight","_circle","maxDepth","cosMinDistance","resample","project","delta2","resampleLineTo","depth","phi2","dx2","dy2","dz","a00","b00","c00","resampleStream","ringPoint","resample$1","resampleNone","transformRadians","projectionMutator","projectAt","projectRotate","cache","cacheStream","theta","preclip","postclip","projectResample","projectTransform","recenter","center","transformRotate","clipAngle","conicProjection","parallels","conicEqualAreaRaw","sy0","cylindricalEqualAreaRaw","r0y","conicEqualArea","albers","azimuthalRaw","azimuthalInvert","sc","cc","azimuthalEqualAreaRaw","cxcy","azimuthalEquidistantRaw","mercatorRaw","mercatorProjection","reclip","tany","conicConformalRaw","cy0","fy","equirectangularRaw","conicEquidistantRaw","gy","nx","gnomonicRaw","scaleTranslate","kx","ky","tx","ty","naturalEarth1Raw","phi4","orthographicRaw","stereographicRaw","transverseMercatorRaw","defaultSeparation","meanXReduce","maxYReduce","hierarchy","childs","Node","valued","defaultChildren","eachBefore","computeHeight","copyData","eachAfter","ancestor","aNodes","ancestors","bNodes","leastCommonAncestor","descendants","leaves","links","slice$3","enclose","circles","shuffle$1","enclosesWeak","encloseBasis","extendBasis","enclosesWeakAll","enclosesNot","encloseBasis2","encloseBasis3","dr","encloseBasis1","r2","r21","r3","a2","a3","c3","place","db","dc","intersects","score","Node$1","circle","packEnclose","aa","sj","sk","pack","required","constantZero","constant$8","defaultRadius$1","radiusLeaf","packChildren","translateChild","roundNode","treemapDice","preroot","ambiguous","defaultId","defaultParentId","parentId","defaultSeparation$1","nextLeft","nextRight","TreeNode","treemapSlice","squarifyRatio","ratio","nodeValue","sumValue","minValue","maxValue","newRatio","minRatio","alpha","beta","dice","squarify","resquarify","_squarify","lexicographicOrder","computeUpperHullIndexes","indexes","slice$4","noabort","Queue","_size","_error","_tasks","_data","_waiting","_active","_ended","_start","poke$1","start$1","abort","maybeNotify","queue","concurrency","defaultSource$1","defer","await","results","awaitAll","uniform","sourceRandomUniform","randomUniform","sourceRandomNormal","randomNormal","mu","sigma","logNormal","sourceRandomLogNormal","randomLogNormal","irwinHall","sourceRandomIrwinHall","randomIrwinHall","bates","sourceRandomBates","randomBates","exponential$1","sourceRandomExponential","randomExponential","request","url","mimeType","response","responseType","headers","xhr","XMLHttpRequest","user","password","respond","status","responseText","hasResponse","XDomainRequest","onload","onerror","ontimeout","onreadystatechange","readyState","onprogress","header","send","post","method","open","setRequestHeader","overrideMimeType","fixCallback","type$1","defaultMimeType","createRange","createContextualFragment","json","responseXML","dsv$1","request$$1","responseOf","csv$1","tsv$1","array$2","map$3","slice$5","implicit","ordinal","unknown","band","ordinalRange","range$$1","paddingInner","paddingOuter","rescale","rangeRound","constant$9","number$2","unit","deinterpolateLinear","bimap","deinterpolate","d0","polymap","clamp","continuous","piecewise","deinterpolateClamp","reinterpolateClamp","linearish","nice","reinterpolate$1","pow10","powp","base","logp","log10","log2","reflect","raise$1","pow$1","t0$1","t1$1","newInterval","floori","offseti","field","millisecond","milliseconds","durationMinute$1","durationHour$1","second","getUTCSeconds","seconds","minute","getMinutes","minutes","hour","getTimezoneOffset","getHours","hours","day","setHours","setDate","getDate","days","weekday","getDay","sunday","monday","tuesday","wednesday","thursday","friday","saturday","sundays","mondays","tuesdays","wednesdays","thursdays","fridays","saturdays","month","setMonth","getMonth","getFullYear","months","year","setFullYear","years","utcMinute","setUTCSeconds","getUTCMinutes","utcMinutes","utcHour","setUTCMinutes","getUTCHours","utcHours","utcDay","setUTCHours","setUTCDate","getUTCDate","utcDays","utcWeekday","getUTCDay","utcSunday","utcMonday","utcTuesday","utcWednesday","utcThursday","utcFriday","utcSaturday","utcSundays","utcMondays","utcTuesdays","utcWednesdays","utcThursdays","utcFridays","utcSaturdays","utcMonth","setUTCMonth","getUTCMonth","getUTCFullYear","utcMonths","utcYear","setUTCFullYear","utcYears","localDate","H","M","L","utcDate","UTC","newYear","formatLocale$1","locale_dateTime","dateTime","locale_date","locale_time","locale_periods","periods","locale_weekdays","locale_shortWeekdays","shortDays","locale_months","locale_shortMonths","shortMonths","periodRe","formatRe","periodLookup","formatLookup","weekdayRe","weekdayLookup","shortWeekdayRe","shortWeekdayLookup","monthRe","monthLookup","shortMonthRe","shortMonthLookup","formats","formatDayOfMonth","formatMicroseconds","formatHour24","formatHour12","formatDayOfYear","formatMilliseconds","formatMonthNumber","formatMinutes","Q","formatUnixTimestamp","formatUnixTimestampSeconds","formatSeconds","formatWeekdayNumberMonday","U","formatWeekNumberSunday","V","formatWeekNumberISO","formatWeekdayNumberSunday","formatWeekNumberMonday","formatYear","formatFullYear","Z","formatZone","formatLiteralPercent","utcFormats","formatUTCDayOfMonth","formatUTCMicroseconds","formatUTCHour24","formatUTCHour12","formatUTCDayOfYear","formatUTCMilliseconds","formatUTCMonthNumber","formatUTCMinutes","formatUTCSeconds","formatUTCWeekdayNumberMonday","formatUTCWeekNumberSunday","formatUTCWeekNumberISO","formatUTCWeekdayNumberSunday","formatUTCWeekNumberMonday","formatUTCYear","formatUTCFullYear","formatUTCZone","parses","parseSpecifier","parseDayOfMonth","parseMicroseconds","parseHour24","parseDayOfYear","parseMilliseconds","parseMonthNumber","parseMinutes","parseUnixTimestamp","parseUnixTimestampSeconds","parseSeconds","parseWeekdayNumberMonday","parseWeekNumberSunday","parseWeekNumberISO","parseWeekdayNumberSunday","parseWeekNumberMonday","parseYear","parseFullYear","parseZone","parseLiteralPercent","pad","pads","charAt","newParse","newDate","week","day$$1","utcFormat","utcParse","locale$1","-","0","numberRe","percentRe","requoteRe","requote","getMilliseconds","getSeconds","getUTCMilliseconds","dow","defaultLocale$1","timeFormat","timeParse","isoSpecifier","formatIso","toISOString","parseIso","durationSecond","durationMinute","durationHour","durationDay","durationWeek","durationMonth","durationYear","date$1","number$3","calendar","year$$1","month$$1","hour$$1","minute$$1","second$$1","millisecond$$1","formatMillisecond","formatSecond","formatMinute","formatHour","formatDay","formatWeek","formatMonth","tickIntervals","tickInterval","category10","category20b","category20c","category20","cubehelix$3","warm","cool","rainbow","ramp","viridis","magma","inferno","plasma","constant$10","abs$1","atan2$1","cos$2","max$2","min$1","sin$2","sqrt$2","epsilon$3","pi$4","halfPi$3","tau$4","asin$1","arcInnerRadius","innerRadius","arcOuterRadius","outerRadius","arcStartAngle","arcEndAngle","arcPadAngle","padAngle","cornerTangents","rc","ox","oy","x11","y11","x10","y10","cx0","cx1","cy1","dx0","dy0","dx1","dy1","Linear","curveLinear","x$3","y$3","x$$1","y$$1","defined","curve","buffer","defined0","area$2","x0z","y0z","areaStart","areaEnd","arealine","lineX0","lineY0","lineY1","lineX1","descending$1","identity$7","curveRadialLinear","curveRadial","Radial","_curve","radial","lineRadial","lineRadial$1","areaRadial","lineStartAngle","lineEndAngle","lineInnerRadius","lineOuterRadius","pointRadial","slice$6","linkSource","linkTarget","link$2","link","argv","curveHorizontal","curveVertical","curveRadial$1","p2","p3","circle$2","draw","cross$2","tan30","tan30_2","diamond","kr","star","square","sqrt3","triangle","wye","symbols","noop$2","point$2","Basis","BasisClosed","BasisOpen","Bundle","_basis","_beta","_x2","_x3","_x4","_y2","_y3","_y4","bundle","point$3","_k","Cardinal","tension","cardinal","CardinalClosed","_x5","_y5","cardinalClosed","cardinal$$1","CardinalOpen","cardinalOpen","point$4","_l01_a","_l01_2a","_l12_a","_l12_2a","_l23_a","_l23_2a","CatmullRom","_alpha","x23","y23","catmullRom","CatmullRomClosed","catmullRomClosed","catmullRom$$1","CatmullRomOpen","catmullRomOpen","LinearClosed","sign$1","slope3","h0","h1","slope2","point$5","MonotoneX","MonotoneY","ReflectContext","Natural","controlPoints","Step","_t","none$1","series","none$2","stackValue","ascending$2","sums","sum$2","constant$11","x$4","y$4","RedBlackTree","RedBlackNode","R","P","RedBlackRotateLeft","RedBlackRotateRight","RedBlackFirst","createEdge","edge","edges","setEdgeEnd","cells","halfedges","createBorderEdge","vertex","clipEdge","connectEdge","fm","fb","lx","ly","rx","ry","fx","cellHalfedgeStart","cell","site","_t0","px","py","after","grandpa","uncle","sibling","firstCircle","circlePool","Circle","attachCircle","lArc","rArc","lSite","cSite","rSite","bx","by","epsilon2$2","ha","hc","detachCircle","beachPool","Beach","createBeach","beach","detachBeach","beaches","removeBeach","disappearing","epsilon$4","unshift","iArc","nArcs","addBeach","dxl","dxr","directrix","leftBreakPoint","rightBreakPoint","createCell","newArc","hb","rfocx","rfocy","pby2","lfocx","lfocy","plby2","hl","aby2","lexicographic","Diagram","sites","vb","va","sortCellHalfedges","clipEdges","iCell","iHalfedge","nHalfedges","startX","startY","endX","endY","nCells","v01","v11","v10","clipCells","constant$12","ZoomEvent","Transform","polygons","triangles","_found","applyX","applyY","location","invertX","invertY","rescaleX","rescaleY","identity$8","transform$1","__zoom","nopropagation$2","noevent$2","defaultFilter$2","defaultExtent$1","SVGElement","clientWidth","clientHeight","defaultTransform","defaultWheelDelta","deltaY","deltaMode","defaultTouchable$1","defaultConstrain","transform$$1","translateExtent","version","bisect","cross","values0","values1","reduce","descending","histogram","tz","bin","bins","thresholds","thresholdFreedmanDiaconis","thresholdScott","thresholdSturges","median","numbers","pairs","permute","permutes","quantile","scan","xi","xj","shuffle","zip","axisTop","axisRight","axisBottom","axisLeft","brushX","brushY","brushSelection","chord","sortGroups","sortSubgroups","sortChords","groupSums","groupIndex","subgroupIndex","chords","di","dj","subindex","compareValue","ribbon","sr","sa0","sa1","sx0","tr","ta0","ta1","nest","sortValues","rollup","sortKeys","createResult","setResult","valuesByKey","sortKey","drag","mousedownx","mousedowny","mousemoving","container","touchable","gestures","clickDistance2","mousedowned","touchstarted","touchmoved","touchended","gesture","mousemoved","mouseupped","sublisteners","clickDistance","dragEnable","dsvFormat","easeLinear","easeQuad","easeQuadIn","easeQuadOut","easeQuadInOut","easeCubic","easeCubicIn","easeCubicOut","easeCubicInOut","easePoly","easePolyIn","easePolyOut","easePolyInOut","easeSin","easeSinIn","easeSinOut","easeSinInOut","easeExp","easeExpIn","easeExpOut","easeExpInOut","easeCircle","easeCircleIn","easeCircleOut","easeCircleInOut","easeBounce","easeBounceIn","easeBounceOut","easeBounceInOut","easeBack","easeBackIn","easeBackOut","easeBackInOut","easeElastic","easeElasticIn","easeElasticOut","easeElasticInOut","forceCenter","force","sx","sy","forceCollide","radii","strength","iterations","yi","ri","ri2","prepare","quad","rj","forceLink","strengths","distances","bias","initializeStrength","initializeDistance","forceManyBody","distanceMin2","distanceMax2","theta2","accumulate","weight","distanceMin","distanceMax","forceRadial","radiuses","forceSimulation","simulation","alphaMin","alphaDecay","alphaTarget","velocityDecay","forces","stepper","initializeNodes","initializeForce","closest","forceX","forceY","formatDefaultLocale","geoArea","geoBounds","feature","deltaMax","geoCentroid","geoCircle","geoClipAntimeridian","geoClipCircle","geoClipExtent","geoClipRectangle","geoContains","geoDistance","geoGraticule","geoGraticule10","geoInterpolate","sy1","kx0","ky0","kx1","ky1","geoLength","geoPath","projectionStream","contextStream","measure","geoAlbers","geoAlbersUsa","lower48Point","alaskaPoint","hawaiiPoint","lower48","alaska","hawaii","pointStream","albersUsa","streams","multiplex","geoAzimuthalEqualArea","geoAzimuthalEqualAreaRaw","geoAzimuthalEquidistant","geoAzimuthalEquidistantRaw","geoConicConformal","geoConicConformalRaw","geoConicEqualArea","geoConicEqualAreaRaw","geoConicEquidistant","geoConicEquidistantRaw","geoEquirectangular","geoEquirectangularRaw","geoGnomonic","geoGnomonicRaw","geoIdentity","reflectX","reflectY","geoProjection","geoProjectionMutator","geoMercator","geoMercatorRaw","geoNaturalEarth1","geoNaturalEarth1Raw","geoOrthographic","geoOrthographicRaw","geoStereographic","geoStereographicRaw","geoTransverseMercator","geoTransverseMercatorRaw","geoRotation","geoTransform","cluster","separation","nodeSize","previousNode","meanX","maxY","leafLeft","leafRight","optional","packSiblings","partition","positionNode","stratify","nodeKey","nodeByKey","treeRoot","firstWalk","secondWalk","sizeNode","siblings","change","executeShifts","midpoint","vip","vop","vim","vom","sip","sop","sim","som","wm","wp","apportion","treemap","tile","paddingStack","paddingTop","paddingRight","paddingBottom","paddingLeft","treemapBinary","valueOffset","valueTarget","valueLeft","valueRight","xk","yk","treemapSliceDice","treemapSquarify","treemapResquarify","interpolateArray","interpolateBasis","interpolateBasisClosed","interpolateDate","interpolateNumber","interpolateObject","interpolateRgbBasis","interpolateRgbBasisClosed","interpolateHsl","interpolateHslLong","interpolateLab","interpolateHcl","interpolateHclLong","interpolateCubehelix","interpolateCubehelixLong","quantize","interpolator","samples","polygonArea","polygonCentroid","polygonHull","sortedPoints","flippedPoints","upperIndexes","lowerIndexes","skipLeft","skipRight","hull","inside","polygonLength","perimeter","scaleBand","scalePoint","pointish","scaleIdentity","identity$6","scaleLinear","linear$2","scaleLog","log$1","logs","pows","scaleOrdinal","scaleImplicit","scalePow","scaleSqrt","scaleQuantile","quantile$$1","invertExtent","quantiles","scaleQuantize","quantize$1","scaleThreshold","threshold$1","scaleTime","scaleUtc","schemeCategory10","schemeCategory20b","schemeCategory20c","schemeCategory20","interpolateCubehelixDefault","interpolateRainbow","ts","interpolateWarm","interpolateCool","interpolateViridis","interpolateMagma","interpolateInferno","interpolatePlasma","scaleSequential","sequential","clientPoint","cornerRadius","padRadius","a01","a11","a10","da0","da1","ap","rp","rc0","rc1","oc","x32","y32","kc","acos$1","lc","pie","arcs","pa","radialArea","radialLine","linkHorizontal","linkVertical","linkRadial","symbolCircle","symbolCross","symbolDiamond","symbolSquare","symbolStar","symbolTriangle","symbolWye","curveBasisClosed","curveBasisOpen","curveBasis","curveBundle","curveCardinalClosed","curveCardinalOpen","curveCardinal","curveCatmullRomClosed","curveCatmullRomOpen","curveCatmullRom","curveLinearClosed","curveMonotoneX","curveMonotoneY","curveNatural","curveStep","curveStepAfter","curveStepBefore","stack","oz","kz","sz","sij","ki","si","stackOffsetExpand","stackOffsetDiverging","yn","stackOffsetNone","stackOffsetSilhouette","stackOffsetWiggle","s2","sij0","s3","stackOrderAscending","stackOrderDescending","stackOrderInsideOut","tops","bottoms","stackOrderNone","stackOrderReverse","timeInterval","timeMillisecond","timeMilliseconds","utcMillisecond","utcMilliseconds","timeSecond","timeSeconds","utcSecond","utcSeconds","timeMinute","timeMinutes","timeHour","timeHours","timeDay","timeDays","timeWeek","timeWeeks","timeSunday","timeSundays","timeMonday","timeMondays","timeTuesday","timeTuesdays","timeWednesday","timeWednesdays","timeThursday","timeThursdays","timeFriday","timeFridays","timeSaturday","timeSaturdays","timeMonth","timeMonths","timeYear","timeYears","utcWeek","utcWeeks","timeFormatDefaultLocale","timeFormatLocale","isoFormat","isoParse","total","voronoi","zoom","touchstarting","constrain","wheelDelta","scaleExtent","touchDelay","wheelDelay","wheeled","dblclicked","Gesture","wheel","k1","touch0","touch1","l0","l1","dp","dl","collection","scaleBy","scaleTo","translateBy","translateTo","zoomTransform","zoomIdentity","defineProperty"],"mappings":"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","file":"d3.js","sourcesContent":["// https://d3js.org Version 4.13.0. Copyright 2018 Mike Bostock.\n(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.d3 = global.d3 || {})));\n}(this, (function (exports) { 'use strict';\n\nvar version = \"4.13.0\";\n\nfunction ascending(a, b) {\n return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n\nfunction bisector(compare) {\n if (compare.length === 1) compare = ascendingComparator(compare);\n return {\n left: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) < 0) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n },\n right: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) > 0) hi = mid;\n else lo = mid + 1;\n }\n return lo;\n }\n };\n}\n\nfunction ascendingComparator(f) {\n return function(d, x) {\n return ascending(f(d), x);\n };\n}\n\nvar ascendingBisect = bisector(ascending);\nvar bisectRight = ascendingBisect.right;\nvar bisectLeft = ascendingBisect.left;\n\nfunction pairs(array, f) {\n if (f == null) f = pair;\n var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);\n while (i < n) pairs[i] = f(p, p = array[++i]);\n return pairs;\n}\n\nfunction pair(a, b) {\n return [a, b];\n}\n\nfunction cross(values0, values1, reduce) {\n var n0 = values0.length,\n n1 = values1.length,\n values = new Array(n0 * n1),\n i0,\n i1,\n i,\n value0;\n\n if (reduce == null) reduce = pair;\n\n for (i0 = i = 0; i0 < n0; ++i0) {\n for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {\n values[i] = reduce(value0, values1[i1]);\n }\n }\n\n return values;\n}\n\nfunction descending(a, b) {\n return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n}\n\nfunction number(x) {\n return x === null ? NaN : +x;\n}\n\nfunction variance(values, valueof) {\n var n = values.length,\n m = 0,\n i = -1,\n mean = 0,\n value,\n delta,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n if (m > 1) return sum / (m - 1);\n}\n\nfunction deviation(array, f) {\n var v = variance(array, f);\n return v ? Math.sqrt(v) : v;\n}\n\nfunction extent(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n return [min, max];\n}\n\nvar array = Array.prototype;\n\nvar slice = array.slice;\nvar map = array.map;\n\nfunction constant(x) {\n return function() {\n return x;\n };\n}\n\nfunction identity(x) {\n return x;\n}\n\nfunction sequence(start, stop, step) {\n start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;\n\n var i = -1,\n n = Math.max(0, Math.ceil((stop - start) / step)) | 0,\n range = new Array(n);\n\n while (++i < n) {\n range[i] = start + i * step;\n }\n\n return range;\n}\n\nvar e10 = Math.sqrt(50);\nvar e5 = Math.sqrt(10);\nvar e2 = Math.sqrt(2);\n\nfunction ticks(start, stop, count) {\n var reverse,\n i = -1,\n n,\n ticks,\n step;\n\n stop = +stop, start = +start, count = +count;\n if (start === stop && count > 0) return [start];\n if (reverse = stop < start) n = start, start = stop, stop = n;\n if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];\n\n if (step > 0) {\n start = Math.ceil(start / step);\n stop = Math.floor(stop / step);\n ticks = new Array(n = Math.ceil(stop - start + 1));\n while (++i < n) ticks[i] = (start + i) * step;\n } else {\n start = Math.floor(start * step);\n stop = Math.ceil(stop * step);\n ticks = new Array(n = Math.ceil(start - stop + 1));\n while (++i < n) ticks[i] = (start - i) / step;\n }\n\n if (reverse) ticks.reverse();\n\n return ticks;\n}\n\nfunction tickIncrement(start, stop, count) {\n var step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log(step) / Math.LN10),\n error = step / Math.pow(10, power);\n return power >= 0\n ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)\n : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);\n}\n\nfunction tickStep(start, stop, count) {\n var step0 = Math.abs(stop - start) / Math.max(0, count),\n step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),\n error = step0 / step1;\n if (error >= e10) step1 *= 10;\n else if (error >= e5) step1 *= 5;\n else if (error >= e2) step1 *= 2;\n return stop < start ? -step1 : step1;\n}\n\nfunction sturges(values) {\n return Math.ceil(Math.log(values.length) / Math.LN2) + 1;\n}\n\nfunction histogram() {\n var value = identity,\n domain = extent,\n threshold = sturges;\n\n function histogram(data) {\n var i,\n n = data.length,\n x,\n values = new Array(n);\n\n for (i = 0; i < n; ++i) {\n values[i] = value(data[i], i, data);\n }\n\n var xz = domain(values),\n x0 = xz[0],\n x1 = xz[1],\n tz = threshold(values, x0, x1);\n\n // Convert number of thresholds into uniform thresholds.\n if (!Array.isArray(tz)) {\n tz = tickStep(x0, x1, tz);\n tz = sequence(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive\n }\n\n // Remove any thresholds outside the domain.\n var m = tz.length;\n while (tz[0] <= x0) tz.shift(), --m;\n while (tz[m - 1] > x1) tz.pop(), --m;\n\n var bins = new Array(m + 1),\n bin;\n\n // Initialize bins.\n for (i = 0; i <= m; ++i) {\n bin = bins[i] = [];\n bin.x0 = i > 0 ? tz[i - 1] : x0;\n bin.x1 = i < m ? tz[i] : x1;\n }\n\n // Assign data to bins by value, ignoring any outside the domain.\n for (i = 0; i < n; ++i) {\n x = values[i];\n if (x0 <= x && x <= x1) {\n bins[bisectRight(tz, x, 0, m)].push(data[i]);\n }\n }\n\n return bins;\n }\n\n histogram.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant(_), histogram) : value;\n };\n\n histogram.domain = function(_) {\n return arguments.length ? (domain = typeof _ === \"function\" ? _ : constant([_[0], _[1]]), histogram) : domain;\n };\n\n histogram.thresholds = function(_) {\n return arguments.length ? (threshold = typeof _ === \"function\" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;\n };\n\n return histogram;\n}\n\nfunction threshold(values, p, valueof) {\n if (valueof == null) valueof = number;\n if (!(n = values.length)) return;\n if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);\n if (p >= 1) return +valueof(values[n - 1], n - 1, values);\n var n,\n i = (n - 1) * p,\n i0 = Math.floor(i),\n value0 = +valueof(values[i0], i0, values),\n value1 = +valueof(values[i0 + 1], i0 + 1, values);\n return value0 + (value1 - value0) * (i - i0);\n}\n\nfunction freedmanDiaconis(values, min, max) {\n values = map.call(values, number).sort(ascending);\n return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));\n}\n\nfunction scott(values, min, max) {\n return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));\n}\n\nfunction max(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n return max;\n}\n\nfunction mean(values, valueof) {\n var n = values.length,\n m = n,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) sum += value;\n else --m;\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;\n else --m;\n }\n }\n\n if (m) return sum / m;\n}\n\nfunction median(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n numbers = [];\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n numbers.push(value);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n numbers.push(value);\n }\n }\n }\n\n return threshold(numbers.sort(ascending), 0.5);\n}\n\nfunction merge(arrays) {\n var n = arrays.length,\n m,\n i = -1,\n j = 0,\n merged,\n array;\n\n while (++i < n) j += arrays[i].length;\n merged = new Array(j);\n\n while (--n >= 0) {\n array = arrays[n];\n m = array.length;\n while (--m >= 0) {\n merged[--j] = array[m];\n }\n }\n\n return merged;\n}\n\nfunction min(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n return min;\n}\n\nfunction permute(array, indexes) {\n var i = indexes.length, permutes = new Array(i);\n while (i--) permutes[i] = array[indexes[i]];\n return permutes;\n}\n\nfunction scan(values, compare) {\n if (!(n = values.length)) return;\n var n,\n i = 0,\n j = 0,\n xi,\n xj = values[j];\n\n if (compare == null) compare = ascending;\n\n while (++i < n) {\n if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {\n xj = xi, j = i;\n }\n }\n\n if (compare(xj, xj) === 0) return j;\n}\n\nfunction shuffle(array, i0, i1) {\n var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),\n t,\n i;\n\n while (m) {\n i = Math.random() * m-- | 0;\n t = array[m + i0];\n array[m + i0] = array[i + i0];\n array[i + i0] = t;\n }\n\n return array;\n}\n\nfunction sum(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (value = +values[i]) sum += value; // Note: zero and null are equivalent.\n }\n }\n\n else {\n while (++i < n) {\n if (value = +valueof(values[i], i, values)) sum += value;\n }\n }\n\n return sum;\n}\n\nfunction transpose(matrix) {\n if (!(n = matrix.length)) return [];\n for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {\n for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {\n row[j] = matrix[j][i];\n }\n }\n return transpose;\n}\n\nfunction length(d) {\n return d.length;\n}\n\nfunction zip() {\n return transpose(arguments);\n}\n\nvar slice$1 = Array.prototype.slice;\n\nfunction identity$1(x) {\n return x;\n}\n\nvar top = 1;\nvar right = 2;\nvar bottom = 3;\nvar left = 4;\nvar epsilon = 1e-6;\n\nfunction translateX(x) {\n return \"translate(\" + (x + 0.5) + \",0)\";\n}\n\nfunction translateY(y) {\n return \"translate(0,\" + (y + 0.5) + \")\";\n}\n\nfunction number$1(scale) {\n return function(d) {\n return +scale(d);\n };\n}\n\nfunction center(scale) {\n var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset.\n if (scale.round()) offset = Math.round(offset);\n return function(d) {\n return +scale(d) + offset;\n };\n}\n\nfunction entering() {\n return !this.__axis;\n}\n\nfunction axis(orient, scale) {\n var tickArguments = [],\n tickValues = null,\n tickFormat = null,\n tickSizeInner = 6,\n tickSizeOuter = 6,\n tickPadding = 3,\n k = orient === top || orient === left ? -1 : 1,\n x = orient === left || orient === right ? \"x\" : \"y\",\n transform = orient === top || orient === bottom ? translateX : translateY;\n\n function axis(context) {\n var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,\n format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat,\n spacing = Math.max(tickSizeInner, 0) + tickPadding,\n range = scale.range(),\n range0 = +range[0] + 0.5,\n range1 = +range[range.length - 1] + 0.5,\n position = (scale.bandwidth ? center : number$1)(scale.copy()),\n selection = context.selection ? context.selection() : context,\n path = selection.selectAll(\".domain\").data([null]),\n tick = selection.selectAll(\".tick\").data(values, scale).order(),\n tickExit = tick.exit(),\n tickEnter = tick.enter().append(\"g\").attr(\"class\", \"tick\"),\n line = tick.select(\"line\"),\n text = tick.select(\"text\");\n\n path = path.merge(path.enter().insert(\"path\", \".tick\")\n .attr(\"class\", \"domain\")\n .attr(\"stroke\", \"#000\"));\n\n tick = tick.merge(tickEnter);\n\n line = line.merge(tickEnter.append(\"line\")\n .attr(\"stroke\", \"#000\")\n .attr(x + \"2\", k * tickSizeInner));\n\n text = text.merge(tickEnter.append(\"text\")\n .attr(\"fill\", \"#000\")\n .attr(x, k * spacing)\n .attr(\"dy\", orient === top ? \"0em\" : orient === bottom ? \"0.71em\" : \"0.32em\"));\n\n if (context !== selection) {\n path = path.transition(context);\n tick = tick.transition(context);\n line = line.transition(context);\n text = text.transition(context);\n\n tickExit = tickExit.transition(context)\n .attr(\"opacity\", epsilon)\n .attr(\"transform\", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute(\"transform\"); });\n\n tickEnter\n .attr(\"opacity\", epsilon)\n .attr(\"transform\", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });\n }\n\n tickExit.remove();\n\n path\n .attr(\"d\", orient === left || orient == right\n ? \"M\" + k * tickSizeOuter + \",\" + range0 + \"H0.5V\" + range1 + \"H\" + k * tickSizeOuter\n : \"M\" + range0 + \",\" + k * tickSizeOuter + \"V0.5H\" + range1 + \"V\" + k * tickSizeOuter);\n\n tick\n .attr(\"opacity\", 1)\n .attr(\"transform\", function(d) { return transform(position(d)); });\n\n line\n .attr(x + \"2\", k * tickSizeInner);\n\n text\n .attr(x, k * spacing)\n .text(format);\n\n selection.filter(entering)\n .attr(\"fill\", \"none\")\n .attr(\"font-size\", 10)\n .attr(\"font-family\", \"sans-serif\")\n .attr(\"text-anchor\", orient === right ? \"start\" : orient === left ? \"end\" : \"middle\");\n\n selection\n .each(function() { this.__axis = position; });\n }\n\n axis.scale = function(_) {\n return arguments.length ? (scale = _, axis) : scale;\n };\n\n axis.ticks = function() {\n return tickArguments = slice$1.call(arguments), axis;\n };\n\n axis.tickArguments = function(_) {\n return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice();\n };\n\n axis.tickValues = function(_) {\n return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice();\n };\n\n axis.tickFormat = function(_) {\n return arguments.length ? (tickFormat = _, axis) : tickFormat;\n };\n\n axis.tickSize = function(_) {\n return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;\n };\n\n axis.tickSizeInner = function(_) {\n return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;\n };\n\n axis.tickSizeOuter = function(_) {\n return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;\n };\n\n axis.tickPadding = function(_) {\n return arguments.length ? (tickPadding = +_, axis) : tickPadding;\n };\n\n return axis;\n}\n\nfunction axisTop(scale) {\n return axis(top, scale);\n}\n\nfunction axisRight(scale) {\n return axis(right, scale);\n}\n\nfunction axisBottom(scale) {\n return axis(bottom, scale);\n}\n\nfunction axisLeft(scale) {\n return axis(left, scale);\n}\n\nvar noop = {value: function() {}};\n\nfunction dispatch() {\n for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {\n if (!(t = arguments[i] + \"\") || (t in _)) throw new Error(\"illegal type: \" + t);\n _[t] = [];\n }\n return new Dispatch(_);\n}\n\nfunction Dispatch(_) {\n this._ = _;\n}\n\nfunction parseTypenames(typenames, types) {\n return typenames.trim().split(/^|\\s+/).map(function(t) {\n var name = \"\", i = t.indexOf(\".\");\n if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n if (t && !types.hasOwnProperty(t)) throw new Error(\"unknown type: \" + t);\n return {type: t, name: name};\n });\n}\n\nDispatch.prototype = dispatch.prototype = {\n constructor: Dispatch,\n on: function(typename, callback) {\n var _ = this._,\n T = parseTypenames(typename + \"\", _),\n t,\n i = -1,\n n = T.length;\n\n // If no callback was specified, return the callback of the given type and name.\n if (arguments.length < 2) {\n while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;\n return;\n }\n\n // If a type was specified, set the callback for the given type and name.\n // Otherwise, if a null callback was specified, remove callbacks of the given name.\n if (callback != null && typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n while (++i < n) {\n if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);\n else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);\n }\n\n return this;\n },\n copy: function() {\n var copy = {}, _ = this._;\n for (var t in _) copy[t] = _[t].slice();\n return new Dispatch(copy);\n },\n call: function(type, that) {\n if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];\n if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n },\n apply: function(type, that, args) {\n if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n }\n};\n\nfunction get(type, name) {\n for (var i = 0, n = type.length, c; i < n; ++i) {\n if ((c = type[i]).name === name) {\n return c.value;\n }\n }\n}\n\nfunction set(type, name, callback) {\n for (var i = 0, n = type.length; i < n; ++i) {\n if (type[i].name === name) {\n type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));\n break;\n }\n }\n if (callback != null) type.push({name: name, value: callback});\n return type;\n}\n\nvar xhtml = \"http://www.w3.org/1999/xhtml\";\n\nvar namespaces = {\n svg: \"http://www.w3.org/2000/svg\",\n xhtml: xhtml,\n xlink: \"http://www.w3.org/1999/xlink\",\n xml: \"http://www.w3.org/XML/1998/namespace\",\n xmlns: \"http://www.w3.org/2000/xmlns/\"\n};\n\nfunction namespace(name) {\n var prefix = name += \"\", i = prefix.indexOf(\":\");\n if (i >= 0 && (prefix = name.slice(0, i)) !== \"xmlns\") name = name.slice(i + 1);\n return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;\n}\n\nfunction creatorInherit(name) {\n return function() {\n var document = this.ownerDocument,\n uri = this.namespaceURI;\n return uri === xhtml && document.documentElement.namespaceURI === xhtml\n ? document.createElement(name)\n : document.createElementNS(uri, name);\n };\n}\n\nfunction creatorFixed(fullname) {\n return function() {\n return this.ownerDocument.createElementNS(fullname.space, fullname.local);\n };\n}\n\nfunction creator(name) {\n var fullname = namespace(name);\n return (fullname.local\n ? creatorFixed\n : creatorInherit)(fullname);\n}\n\nfunction none() {}\n\nfunction selector(selector) {\n return selector == null ? none : function() {\n return this.querySelector(selector);\n };\n}\n\nfunction selection_select(select) {\n if (typeof select !== \"function\") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if (\"__data__\" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n\nfunction empty$1() {\n return [];\n}\n\nfunction selectorAll(selector) {\n return selector == null ? empty$1 : function() {\n return this.querySelectorAll(selector);\n };\n}\n\nfunction selection_selectAll(select) {\n if (typeof select !== \"function\") select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n subgroups.push(select.call(node, node.__data__, i, group));\n parents.push(node);\n }\n }\n }\n\n return new Selection(subgroups, parents);\n}\n\nvar matcher = function(selector) {\n return function() {\n return this.matches(selector);\n };\n};\n\nif (typeof document !== \"undefined\") {\n var element = document.documentElement;\n if (!element.matches) {\n var vendorMatches = element.webkitMatchesSelector\n || element.msMatchesSelector\n || element.mozMatchesSelector\n || element.oMatchesSelector;\n matcher = function(selector) {\n return function() {\n return vendorMatches.call(this, selector);\n };\n };\n }\n}\n\nvar matcher$1 = matcher;\n\nfunction selection_filter(match) {\n if (typeof match !== \"function\") match = matcher$1(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n\nfunction sparse(update) {\n return new Array(update.length);\n}\n\nfunction selection_enter() {\n return new Selection(this._enter || this._groups.map(sparse), this._parents);\n}\n\nfunction EnterNode(parent, datum) {\n this.ownerDocument = parent.ownerDocument;\n this.namespaceURI = parent.namespaceURI;\n this._next = null;\n this._parent = parent;\n this.__data__ = datum;\n}\n\nEnterNode.prototype = {\n constructor: EnterNode,\n appendChild: function(child) { return this._parent.insertBefore(child, this._next); },\n insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },\n querySelector: function(selector) { return this._parent.querySelector(selector); },\n querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }\n};\n\nfunction constant$1(x) {\n return function() {\n return x;\n };\n}\n\nvar keyPrefix = \"$\"; // Protect against keys like “__proto__”.\n\nfunction bindIndex(parent, group, enter, update, exit, data) {\n var i = 0,\n node,\n groupLength = group.length,\n dataLength = data.length;\n\n // Put any non-null nodes that fit into update.\n // Put any null nodes into enter.\n // Put any remaining data into enter.\n for (; i < dataLength; ++i) {\n if (node = group[i]) {\n node.__data__ = data[i];\n update[i] = node;\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n }\n\n // Put any non-null nodes that don’t fit into exit.\n for (; i < groupLength; ++i) {\n if (node = group[i]) {\n exit[i] = node;\n }\n }\n}\n\nfunction bindKey(parent, group, enter, update, exit, data, key) {\n var i,\n node,\n nodeByKeyValue = {},\n groupLength = group.length,\n dataLength = data.length,\n keyValues = new Array(groupLength),\n keyValue;\n\n // Compute the key for each node.\n // If multiple nodes have the same key, the duplicates are added to exit.\n for (i = 0; i < groupLength; ++i) {\n if (node = group[i]) {\n keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);\n if (keyValue in nodeByKeyValue) {\n exit[i] = node;\n } else {\n nodeByKeyValue[keyValue] = node;\n }\n }\n }\n\n // Compute the key for each datum.\n // If there a node associated with this key, join and add it to update.\n // If there is not (or the key is a duplicate), add it to enter.\n for (i = 0; i < dataLength; ++i) {\n keyValue = keyPrefix + key.call(parent, data[i], i, data);\n if (node = nodeByKeyValue[keyValue]) {\n update[i] = node;\n node.__data__ = data[i];\n nodeByKeyValue[keyValue] = null;\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n }\n\n // Add any remaining nodes that were not bound to data to exit.\n for (i = 0; i < groupLength; ++i) {\n if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {\n exit[i] = node;\n }\n }\n}\n\nfunction selection_data(value, key) {\n if (!value) {\n data = new Array(this.size()), j = -1;\n this.each(function(d) { data[++j] = d; });\n return data;\n }\n\n var bind = key ? bindKey : bindIndex,\n parents = this._parents,\n groups = this._groups;\n\n if (typeof value !== \"function\") value = constant$1(value);\n\n for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {\n var parent = parents[j],\n group = groups[j],\n groupLength = group.length,\n data = value.call(parent, parent && parent.__data__, j, parents),\n dataLength = data.length,\n enterGroup = enter[j] = new Array(dataLength),\n updateGroup = update[j] = new Array(dataLength),\n exitGroup = exit[j] = new Array(groupLength);\n\n bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);\n\n // Now connect the enter nodes to their following update node, such that\n // appendChild can insert the materialized enter node before this node,\n // rather than at the end of the parent node.\n for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {\n if (previous = enterGroup[i0]) {\n if (i0 >= i1) i1 = i0 + 1;\n while (!(next = updateGroup[i1]) && ++i1 < dataLength);\n previous._next = next || null;\n }\n }\n }\n\n update = new Selection(update, parents);\n update._enter = enter;\n update._exit = exit;\n return update;\n}\n\nfunction selection_exit() {\n return new Selection(this._exit || this._groups.map(sparse), this._parents);\n}\n\nfunction selection_merge(selection$$1) {\n\n for (var groups0 = this._groups, groups1 = selection$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Selection(merges, this._parents);\n}\n\nfunction selection_order() {\n\n for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {\n for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {\n if (node = group[i]) {\n if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);\n next = node;\n }\n }\n }\n\n return this;\n}\n\nfunction selection_sort(compare) {\n if (!compare) compare = ascending$1;\n\n function compareNode(a, b) {\n return a && b ? compare(a.__data__, b.__data__) : !a - !b;\n }\n\n for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n sortgroup[i] = node;\n }\n }\n sortgroup.sort(compareNode);\n }\n\n return new Selection(sortgroups, this._parents).order();\n}\n\nfunction ascending$1(a, b) {\n return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n\nfunction selection_call() {\n var callback = arguments[0];\n arguments[0] = this;\n callback.apply(null, arguments);\n return this;\n}\n\nfunction selection_nodes() {\n var nodes = new Array(this.size()), i = -1;\n this.each(function() { nodes[++i] = this; });\n return nodes;\n}\n\nfunction selection_node() {\n\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {\n var node = group[i];\n if (node) return node;\n }\n }\n\n return null;\n}\n\nfunction selection_size() {\n var size = 0;\n this.each(function() { ++size; });\n return size;\n}\n\nfunction selection_empty() {\n return !this.node();\n}\n\nfunction selection_each(callback) {\n\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {\n if (node = group[i]) callback.call(node, node.__data__, i, group);\n }\n }\n\n return this;\n}\n\nfunction attrRemove(name) {\n return function() {\n this.removeAttribute(name);\n };\n}\n\nfunction attrRemoveNS(fullname) {\n return function() {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attrConstant(name, value) {\n return function() {\n this.setAttribute(name, value);\n };\n}\n\nfunction attrConstantNS(fullname, value) {\n return function() {\n this.setAttributeNS(fullname.space, fullname.local, value);\n };\n}\n\nfunction attrFunction(name, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttribute(name);\n else this.setAttribute(name, v);\n };\n}\n\nfunction attrFunctionNS(fullname, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttributeNS(fullname.space, fullname.local);\n else this.setAttributeNS(fullname.space, fullname.local, v);\n };\n}\n\nfunction selection_attr(name, value) {\n var fullname = namespace(name);\n\n if (arguments.length < 2) {\n var node = this.node();\n return fullname.local\n ? node.getAttributeNS(fullname.space, fullname.local)\n : node.getAttribute(fullname);\n }\n\n return this.each((value == null\n ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === \"function\"\n ? (fullname.local ? attrFunctionNS : attrFunction)\n : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));\n}\n\nfunction defaultView(node) {\n return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node\n || (node.document && node) // node is a Window\n || node.defaultView; // node is a Document\n}\n\nfunction styleRemove(name) {\n return function() {\n this.style.removeProperty(name);\n };\n}\n\nfunction styleConstant(name, value, priority) {\n return function() {\n this.style.setProperty(name, value, priority);\n };\n}\n\nfunction styleFunction(name, value, priority) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.style.removeProperty(name);\n else this.style.setProperty(name, v, priority);\n };\n}\n\nfunction selection_style(name, value, priority) {\n return arguments.length > 1\n ? this.each((value == null\n ? styleRemove : typeof value === \"function\"\n ? styleFunction\n : styleConstant)(name, value, priority == null ? \"\" : priority))\n : styleValue(this.node(), name);\n}\n\nfunction styleValue(node, name) {\n return node.style.getPropertyValue(name)\n || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);\n}\n\nfunction propertyRemove(name) {\n return function() {\n delete this[name];\n };\n}\n\nfunction propertyConstant(name, value) {\n return function() {\n this[name] = value;\n };\n}\n\nfunction propertyFunction(name, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) delete this[name];\n else this[name] = v;\n };\n}\n\nfunction selection_property(name, value) {\n return arguments.length > 1\n ? this.each((value == null\n ? propertyRemove : typeof value === \"function\"\n ? propertyFunction\n : propertyConstant)(name, value))\n : this.node()[name];\n}\n\nfunction classArray(string) {\n return string.trim().split(/^|\\s+/);\n}\n\nfunction classList(node) {\n return node.classList || new ClassList(node);\n}\n\nfunction ClassList(node) {\n this._node = node;\n this._names = classArray(node.getAttribute(\"class\") || \"\");\n}\n\nClassList.prototype = {\n add: function(name) {\n var i = this._names.indexOf(name);\n if (i < 0) {\n this._names.push(name);\n this._node.setAttribute(\"class\", this._names.join(\" \"));\n }\n },\n remove: function(name) {\n var i = this._names.indexOf(name);\n if (i >= 0) {\n this._names.splice(i, 1);\n this._node.setAttribute(\"class\", this._names.join(\" \"));\n }\n },\n contains: function(name) {\n return this._names.indexOf(name) >= 0;\n }\n};\n\nfunction classedAdd(node, names) {\n var list = classList(node), i = -1, n = names.length;\n while (++i < n) list.add(names[i]);\n}\n\nfunction classedRemove(node, names) {\n var list = classList(node), i = -1, n = names.length;\n while (++i < n) list.remove(names[i]);\n}\n\nfunction classedTrue(names) {\n return function() {\n classedAdd(this, names);\n };\n}\n\nfunction classedFalse(names) {\n return function() {\n classedRemove(this, names);\n };\n}\n\nfunction classedFunction(names, value) {\n return function() {\n (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);\n };\n}\n\nfunction selection_classed(name, value) {\n var names = classArray(name + \"\");\n\n if (arguments.length < 2) {\n var list = classList(this.node()), i = -1, n = names.length;\n while (++i < n) if (!list.contains(names[i])) return false;\n return true;\n }\n\n return this.each((typeof value === \"function\"\n ? classedFunction : value\n ? classedTrue\n : classedFalse)(names, value));\n}\n\nfunction textRemove() {\n this.textContent = \"\";\n}\n\nfunction textConstant(value) {\n return function() {\n this.textContent = value;\n };\n}\n\nfunction textFunction(value) {\n return function() {\n var v = value.apply(this, arguments);\n this.textContent = v == null ? \"\" : v;\n };\n}\n\nfunction selection_text(value) {\n return arguments.length\n ? this.each(value == null\n ? textRemove : (typeof value === \"function\"\n ? textFunction\n : textConstant)(value))\n : this.node().textContent;\n}\n\nfunction htmlRemove() {\n this.innerHTML = \"\";\n}\n\nfunction htmlConstant(value) {\n return function() {\n this.innerHTML = value;\n };\n}\n\nfunction htmlFunction(value) {\n return function() {\n var v = value.apply(this, arguments);\n this.innerHTML = v == null ? \"\" : v;\n };\n}\n\nfunction selection_html(value) {\n return arguments.length\n ? this.each(value == null\n ? htmlRemove : (typeof value === \"function\"\n ? htmlFunction\n : htmlConstant)(value))\n : this.node().innerHTML;\n}\n\nfunction raise() {\n if (this.nextSibling) this.parentNode.appendChild(this);\n}\n\nfunction selection_raise() {\n return this.each(raise);\n}\n\nfunction lower() {\n if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);\n}\n\nfunction selection_lower() {\n return this.each(lower);\n}\n\nfunction selection_append(name) {\n var create = typeof name === \"function\" ? name : creator(name);\n return this.select(function() {\n return this.appendChild(create.apply(this, arguments));\n });\n}\n\nfunction constantNull() {\n return null;\n}\n\nfunction selection_insert(name, before) {\n var create = typeof name === \"function\" ? name : creator(name),\n select = before == null ? constantNull : typeof before === \"function\" ? before : selector(before);\n return this.select(function() {\n return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);\n });\n}\n\nfunction remove() {\n var parent = this.parentNode;\n if (parent) parent.removeChild(this);\n}\n\nfunction selection_remove() {\n return this.each(remove);\n}\n\nfunction selection_cloneShallow() {\n return this.parentNode.insertBefore(this.cloneNode(false), this.nextSibling);\n}\n\nfunction selection_cloneDeep() {\n return this.parentNode.insertBefore(this.cloneNode(true), this.nextSibling);\n}\n\nfunction selection_clone(deep) {\n return this.select(deep ? selection_cloneDeep : selection_cloneShallow);\n}\n\nfunction selection_datum(value) {\n return arguments.length\n ? this.property(\"__data__\", value)\n : this.node().__data__;\n}\n\nvar filterEvents = {};\n\nexports.event = null;\n\nif (typeof document !== \"undefined\") {\n var element$1 = document.documentElement;\n if (!(\"onmouseenter\" in element$1)) {\n filterEvents = {mouseenter: \"mouseover\", mouseleave: \"mouseout\"};\n }\n}\n\nfunction filterContextListener(listener, index, group) {\n listener = contextListener(listener, index, group);\n return function(event) {\n var related = event.relatedTarget;\n if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {\n listener.call(this, event);\n }\n };\n}\n\nfunction contextListener(listener, index, group) {\n return function(event1) {\n var event0 = exports.event; // Events can be reentrant (e.g., focus).\n exports.event = event1;\n try {\n listener.call(this, this.__data__, index, group);\n } finally {\n exports.event = event0;\n }\n };\n}\n\nfunction parseTypenames$1(typenames) {\n return typenames.trim().split(/^|\\s+/).map(function(t) {\n var name = \"\", i = t.indexOf(\".\");\n if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n return {type: t, name: name};\n });\n}\n\nfunction onRemove(typename) {\n return function() {\n var on = this.__on;\n if (!on) return;\n for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {\n if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {\n this.removeEventListener(o.type, o.listener, o.capture);\n } else {\n on[++i] = o;\n }\n }\n if (++i) on.length = i;\n else delete this.__on;\n };\n}\n\nfunction onAdd(typename, value, capture) {\n var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;\n return function(d, i, group) {\n var on = this.__on, o, listener = wrap(value, i, group);\n if (on) for (var j = 0, m = on.length; j < m; ++j) {\n if ((o = on[j]).type === typename.type && o.name === typename.name) {\n this.removeEventListener(o.type, o.listener, o.capture);\n this.addEventListener(o.type, o.listener = listener, o.capture = capture);\n o.value = value;\n return;\n }\n }\n this.addEventListener(typename.type, listener, capture);\n o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};\n if (!on) this.__on = [o];\n else on.push(o);\n };\n}\n\nfunction selection_on(typename, value, capture) {\n var typenames = parseTypenames$1(typename + \"\"), i, n = typenames.length, t;\n\n if (arguments.length < 2) {\n var on = this.node().__on;\n if (on) for (var j = 0, m = on.length, o; j < m; ++j) {\n for (i = 0, o = on[j]; i < n; ++i) {\n if ((t = typenames[i]).type === o.type && t.name === o.name) {\n return o.value;\n }\n }\n }\n return;\n }\n\n on = value ? onAdd : onRemove;\n if (capture == null) capture = false;\n for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));\n return this;\n}\n\nfunction customEvent(event1, listener, that, args) {\n var event0 = exports.event;\n event1.sourceEvent = exports.event;\n exports.event = event1;\n try {\n return listener.apply(that, args);\n } finally {\n exports.event = event0;\n }\n}\n\nfunction dispatchEvent(node, type, params) {\n var window = defaultView(node),\n event = window.CustomEvent;\n\n if (typeof event === \"function\") {\n event = new event(type, params);\n } else {\n event = window.document.createEvent(\"Event\");\n if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;\n else event.initEvent(type, false, false);\n }\n\n node.dispatchEvent(event);\n}\n\nfunction dispatchConstant(type, params) {\n return function() {\n return dispatchEvent(this, type, params);\n };\n}\n\nfunction dispatchFunction(type, params) {\n return function() {\n return dispatchEvent(this, type, params.apply(this, arguments));\n };\n}\n\nfunction selection_dispatch(type, params) {\n return this.each((typeof params === \"function\"\n ? dispatchFunction\n : dispatchConstant)(type, params));\n}\n\nvar root = [null];\n\nfunction Selection(groups, parents) {\n this._groups = groups;\n this._parents = parents;\n}\n\nfunction selection() {\n return new Selection([[document.documentElement]], root);\n}\n\nSelection.prototype = selection.prototype = {\n constructor: Selection,\n select: selection_select,\n selectAll: selection_selectAll,\n filter: selection_filter,\n data: selection_data,\n enter: selection_enter,\n exit: selection_exit,\n merge: selection_merge,\n order: selection_order,\n sort: selection_sort,\n call: selection_call,\n nodes: selection_nodes,\n node: selection_node,\n size: selection_size,\n empty: selection_empty,\n each: selection_each,\n attr: selection_attr,\n style: selection_style,\n property: selection_property,\n classed: selection_classed,\n text: selection_text,\n html: selection_html,\n raise: selection_raise,\n lower: selection_lower,\n append: selection_append,\n insert: selection_insert,\n remove: selection_remove,\n clone: selection_clone,\n datum: selection_datum,\n on: selection_on,\n dispatch: selection_dispatch\n};\n\nfunction select(selector) {\n return typeof selector === \"string\"\n ? new Selection([[document.querySelector(selector)]], [document.documentElement])\n : new Selection([[selector]], root);\n}\n\nfunction create(name) {\n return select(creator(name).call(document.documentElement));\n}\n\nvar nextId = 0;\n\nfunction local$1() {\n return new Local;\n}\n\nfunction Local() {\n this._ = \"@\" + (++nextId).toString(36);\n}\n\nLocal.prototype = local$1.prototype = {\n constructor: Local,\n get: function(node) {\n var id = this._;\n while (!(id in node)) if (!(node = node.parentNode)) return;\n return node[id];\n },\n set: function(node, value) {\n return node[this._] = value;\n },\n remove: function(node) {\n return this._ in node && delete node[this._];\n },\n toString: function() {\n return this._;\n }\n};\n\nfunction sourceEvent() {\n var current = exports.event, source;\n while (source = current.sourceEvent) current = source;\n return current;\n}\n\nfunction point(node, event) {\n var svg = node.ownerSVGElement || node;\n\n if (svg.createSVGPoint) {\n var point = svg.createSVGPoint();\n point.x = event.clientX, point.y = event.clientY;\n point = point.matrixTransform(node.getScreenCTM().inverse());\n return [point.x, point.y];\n }\n\n var rect = node.getBoundingClientRect();\n return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];\n}\n\nfunction mouse(node) {\n var event = sourceEvent();\n if (event.changedTouches) event = event.changedTouches[0];\n return point(node, event);\n}\n\nfunction selectAll(selector) {\n return typeof selector === \"string\"\n ? new Selection([document.querySelectorAll(selector)], [document.documentElement])\n : new Selection([selector == null ? [] : selector], root);\n}\n\nfunction touch(node, touches, identifier) {\n if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;\n\n for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {\n if ((touch = touches[i]).identifier === identifier) {\n return point(node, touch);\n }\n }\n\n return null;\n}\n\nfunction touches(node, touches) {\n if (touches == null) touches = sourceEvent().touches;\n\n for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {\n points[i] = point(node, touches[i]);\n }\n\n return points;\n}\n\nfunction nopropagation() {\n exports.event.stopImmediatePropagation();\n}\n\nfunction noevent() {\n exports.event.preventDefault();\n exports.event.stopImmediatePropagation();\n}\n\nfunction dragDisable(view) {\n var root = view.document.documentElement,\n selection = select(view).on(\"dragstart.drag\", noevent, true);\n if (\"onselectstart\" in root) {\n selection.on(\"selectstart.drag\", noevent, true);\n } else {\n root.__noselect = root.style.MozUserSelect;\n root.style.MozUserSelect = \"none\";\n }\n}\n\nfunction yesdrag(view, noclick) {\n var root = view.document.documentElement,\n selection = select(view).on(\"dragstart.drag\", null);\n if (noclick) {\n selection.on(\"click.drag\", noevent, true);\n setTimeout(function() { selection.on(\"click.drag\", null); }, 0);\n }\n if (\"onselectstart\" in root) {\n selection.on(\"selectstart.drag\", null);\n } else {\n root.style.MozUserSelect = root.__noselect;\n delete root.__noselect;\n }\n}\n\nfunction constant$2(x) {\n return function() {\n return x;\n };\n}\n\nfunction DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {\n this.target = target;\n this.type = type;\n this.subject = subject;\n this.identifier = id;\n this.active = active;\n this.x = x;\n this.y = y;\n this.dx = dx;\n this.dy = dy;\n this._ = dispatch;\n}\n\nDragEvent.prototype.on = function() {\n var value = this._.on.apply(this._, arguments);\n return value === this._ ? this : value;\n};\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter$1() {\n return !exports.event.button;\n}\n\nfunction defaultContainer() {\n return this.parentNode;\n}\n\nfunction defaultSubject(d) {\n return d == null ? {x: exports.event.x, y: exports.event.y} : d;\n}\n\nfunction defaultTouchable() {\n return \"ontouchstart\" in this;\n}\n\nfunction drag() {\n var filter = defaultFilter$1,\n container = defaultContainer,\n subject = defaultSubject,\n touchable = defaultTouchable,\n gestures = {},\n listeners = dispatch(\"start\", \"drag\", \"end\"),\n active = 0,\n mousedownx,\n mousedowny,\n mousemoving,\n touchending,\n clickDistance2 = 0;\n\n function drag(selection) {\n selection\n .on(\"mousedown.drag\", mousedowned)\n .filter(touchable)\n .on(\"touchstart.drag\", touchstarted)\n .on(\"touchmove.drag\", touchmoved)\n .on(\"touchend.drag touchcancel.drag\", touchended)\n .style(\"touch-action\", \"none\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\");\n }\n\n function mousedowned() {\n if (touchending || !filter.apply(this, arguments)) return;\n var gesture = beforestart(\"mouse\", container.apply(this, arguments), mouse, this, arguments);\n if (!gesture) return;\n select(exports.event.view).on(\"mousemove.drag\", mousemoved, true).on(\"mouseup.drag\", mouseupped, true);\n dragDisable(exports.event.view);\n nopropagation();\n mousemoving = false;\n mousedownx = exports.event.clientX;\n mousedowny = exports.event.clientY;\n gesture(\"start\");\n }\n\n function mousemoved() {\n noevent();\n if (!mousemoving) {\n var dx = exports.event.clientX - mousedownx, dy = exports.event.clientY - mousedowny;\n mousemoving = dx * dx + dy * dy > clickDistance2;\n }\n gestures.mouse(\"drag\");\n }\n\n function mouseupped() {\n select(exports.event.view).on(\"mousemove.drag mouseup.drag\", null);\n yesdrag(exports.event.view, mousemoving);\n noevent();\n gestures.mouse(\"end\");\n }\n\n function touchstarted() {\n if (!filter.apply(this, arguments)) return;\n var touches = exports.event.changedTouches,\n c = container.apply(this, arguments),\n n = touches.length, i, gesture;\n\n for (i = 0; i < n; ++i) {\n if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) {\n nopropagation();\n gesture(\"start\");\n }\n }\n }\n\n function touchmoved() {\n var touches = exports.event.changedTouches,\n n = touches.length, i, gesture;\n\n for (i = 0; i < n; ++i) {\n if (gesture = gestures[touches[i].identifier]) {\n noevent();\n gesture(\"drag\");\n }\n }\n }\n\n function touchended() {\n var touches = exports.event.changedTouches,\n n = touches.length, i, gesture;\n\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n for (i = 0; i < n; ++i) {\n if (gesture = gestures[touches[i].identifier]) {\n nopropagation();\n gesture(\"end\");\n }\n }\n }\n\n function beforestart(id, container, point, that, args) {\n var p = point(container, id), s, dx, dy,\n sublisteners = listeners.copy();\n\n if (!customEvent(new DragEvent(drag, \"beforestart\", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {\n if ((exports.event.subject = s = subject.apply(that, args)) == null) return false;\n dx = s.x - p[0] || 0;\n dy = s.y - p[1] || 0;\n return true;\n })) return;\n\n return function gesture(type) {\n var p0 = p, n;\n switch (type) {\n case \"start\": gestures[id] = gesture, n = active++; break;\n case \"end\": delete gestures[id], --active; // nobreak\n case \"drag\": p = point(container, id), n = active; break;\n }\n customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);\n };\n }\n\n drag.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant$2(!!_), drag) : filter;\n };\n\n drag.container = function(_) {\n return arguments.length ? (container = typeof _ === \"function\" ? _ : constant$2(_), drag) : container;\n };\n\n drag.subject = function(_) {\n return arguments.length ? (subject = typeof _ === \"function\" ? _ : constant$2(_), drag) : subject;\n };\n\n drag.touchable = function(_) {\n return arguments.length ? (touchable = typeof _ === \"function\" ? _ : constant$2(!!_), drag) : touchable;\n };\n\n drag.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? drag : value;\n };\n\n drag.clickDistance = function(_) {\n return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);\n };\n\n return drag;\n}\n\nfunction define(constructor, factory, prototype) {\n constructor.prototype = factory.prototype = prototype;\n prototype.constructor = constructor;\n}\n\nfunction extend(parent, definition) {\n var prototype = Object.create(parent.prototype);\n for (var key in definition) prototype[key] = definition[key];\n return prototype;\n}\n\nfunction Color() {}\n\nvar darker = 0.7;\nvar brighter = 1 / darker;\n\nvar reI = \"\\\\s*([+-]?\\\\d+)\\\\s*\";\nvar reN = \"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\";\nvar reP = \"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\";\nvar reHex3 = /^#([0-9a-f]{3})$/;\nvar reHex6 = /^#([0-9a-f]{6})$/;\nvar reRgbInteger = new RegExp(\"^rgb\\\\(\" + [reI, reI, reI] + \"\\\\)$\");\nvar reRgbPercent = new RegExp(\"^rgb\\\\(\" + [reP, reP, reP] + \"\\\\)$\");\nvar reRgbaInteger = new RegExp(\"^rgba\\\\(\" + [reI, reI, reI, reN] + \"\\\\)$\");\nvar reRgbaPercent = new RegExp(\"^rgba\\\\(\" + [reP, reP, reP, reN] + \"\\\\)$\");\nvar reHslPercent = new RegExp(\"^hsl\\\\(\" + [reN, reP, reP] + \"\\\\)$\");\nvar reHslaPercent = new RegExp(\"^hsla\\\\(\" + [reN, reP, reP, reN] + \"\\\\)$\");\n\nvar named = {\n aliceblue: 0xf0f8ff,\n antiquewhite: 0xfaebd7,\n aqua: 0x00ffff,\n aquamarine: 0x7fffd4,\n azure: 0xf0ffff,\n beige: 0xf5f5dc,\n bisque: 0xffe4c4,\n black: 0x000000,\n blanchedalmond: 0xffebcd,\n blue: 0x0000ff,\n blueviolet: 0x8a2be2,\n brown: 0xa52a2a,\n burlywood: 0xdeb887,\n cadetblue: 0x5f9ea0,\n chartreuse: 0x7fff00,\n chocolate: 0xd2691e,\n coral: 0xff7f50,\n cornflowerblue: 0x6495ed,\n cornsilk: 0xfff8dc,\n crimson: 0xdc143c,\n cyan: 0x00ffff,\n darkblue: 0x00008b,\n darkcyan: 0x008b8b,\n darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9,\n darkgreen: 0x006400,\n darkgrey: 0xa9a9a9,\n darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b,\n darkolivegreen: 0x556b2f,\n darkorange: 0xff8c00,\n darkorchid: 0x9932cc,\n darkred: 0x8b0000,\n darksalmon: 0xe9967a,\n darkseagreen: 0x8fbc8f,\n darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f,\n darkslategrey: 0x2f4f4f,\n darkturquoise: 0x00ced1,\n darkviolet: 0x9400d3,\n deeppink: 0xff1493,\n deepskyblue: 0x00bfff,\n dimgray: 0x696969,\n dimgrey: 0x696969,\n dodgerblue: 0x1e90ff,\n firebrick: 0xb22222,\n floralwhite: 0xfffaf0,\n forestgreen: 0x228b22,\n fuchsia: 0xff00ff,\n gainsboro: 0xdcdcdc,\n ghostwhite: 0xf8f8ff,\n gold: 0xffd700,\n goldenrod: 0xdaa520,\n gray: 0x808080,\n green: 0x008000,\n greenyellow: 0xadff2f,\n grey: 0x808080,\n honeydew: 0xf0fff0,\n hotpink: 0xff69b4,\n indianred: 0xcd5c5c,\n indigo: 0x4b0082,\n ivory: 0xfffff0,\n khaki: 0xf0e68c,\n lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5,\n lawngreen: 0x7cfc00,\n lemonchiffon: 0xfffacd,\n lightblue: 0xadd8e6,\n lightcoral: 0xf08080,\n lightcyan: 0xe0ffff,\n lightgoldenrodyellow: 0xfafad2,\n lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90,\n lightgrey: 0xd3d3d3,\n lightpink: 0xffb6c1,\n lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa,\n lightskyblue: 0x87cefa,\n lightslategray: 0x778899,\n lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de,\n lightyellow: 0xffffe0,\n lime: 0x00ff00,\n limegreen: 0x32cd32,\n linen: 0xfaf0e6,\n magenta: 0xff00ff,\n maroon: 0x800000,\n mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd,\n mediumorchid: 0xba55d3,\n mediumpurple: 0x9370db,\n mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee,\n mediumspringgreen: 0x00fa9a,\n mediumturquoise: 0x48d1cc,\n mediumvioletred: 0xc71585,\n midnightblue: 0x191970,\n mintcream: 0xf5fffa,\n mistyrose: 0xffe4e1,\n moccasin: 0xffe4b5,\n navajowhite: 0xffdead,\n navy: 0x000080,\n oldlace: 0xfdf5e6,\n olive: 0x808000,\n olivedrab: 0x6b8e23,\n orange: 0xffa500,\n orangered: 0xff4500,\n orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa,\n palegreen: 0x98fb98,\n paleturquoise: 0xafeeee,\n palevioletred: 0xdb7093,\n papayawhip: 0xffefd5,\n peachpuff: 0xffdab9,\n peru: 0xcd853f,\n pink: 0xffc0cb,\n plum: 0xdda0dd,\n powderblue: 0xb0e0e6,\n purple: 0x800080,\n rebeccapurple: 0x663399,\n red: 0xff0000,\n rosybrown: 0xbc8f8f,\n royalblue: 0x4169e1,\n saddlebrown: 0x8b4513,\n salmon: 0xfa8072,\n sandybrown: 0xf4a460,\n seagreen: 0x2e8b57,\n seashell: 0xfff5ee,\n sienna: 0xa0522d,\n silver: 0xc0c0c0,\n skyblue: 0x87ceeb,\n slateblue: 0x6a5acd,\n slategray: 0x708090,\n slategrey: 0x708090,\n snow: 0xfffafa,\n springgreen: 0x00ff7f,\n steelblue: 0x4682b4,\n tan: 0xd2b48c,\n teal: 0x008080,\n thistle: 0xd8bfd8,\n tomato: 0xff6347,\n turquoise: 0x40e0d0,\n violet: 0xee82ee,\n wheat: 0xf5deb3,\n white: 0xffffff,\n whitesmoke: 0xf5f5f5,\n yellow: 0xffff00,\n yellowgreen: 0x9acd32\n};\n\ndefine(Color, color, {\n displayable: function() {\n return this.rgb().displayable();\n },\n toString: function() {\n return this.rgb() + \"\";\n }\n});\n\nfunction color(format) {\n var m;\n format = (format + \"\").trim().toLowerCase();\n return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00\n : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000\n : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n : named.hasOwnProperty(format) ? rgbn(named[format])\n : format === \"transparent\" ? new Rgb(NaN, NaN, NaN, 0)\n : null;\n}\n\nfunction rgbn(n) {\n return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n if (a <= 0) r = g = b = NaN;\n return new Rgb(r, g, b, a);\n}\n\nfunction rgbConvert(o) {\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Rgb;\n o = o.rgb();\n return new Rgb(o.r, o.g, o.b, o.opacity);\n}\n\nfunction rgb(r, g, b, opacity) {\n return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\n\nfunction Rgb(r, g, b, opacity) {\n this.r = +r;\n this.g = +g;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Rgb, rgb, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n rgb: function() {\n return this;\n },\n displayable: function() {\n return (0 <= this.r && this.r <= 255)\n && (0 <= this.g && this.g <= 255)\n && (0 <= this.b && this.b <= 255)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n toString: function() {\n var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));\n return (a === 1 ? \"rgb(\" : \"rgba(\")\n + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + \", \"\n + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + \", \"\n + Math.max(0, Math.min(255, Math.round(this.b) || 0))\n + (a === 1 ? \")\" : \", \" + a + \")\");\n }\n}));\n\nfunction hsla(h, s, l, a) {\n if (a <= 0) h = s = l = NaN;\n else if (l <= 0 || l >= 1) h = s = NaN;\n else if (s <= 0) h = NaN;\n return new Hsl(h, s, l, a);\n}\n\nfunction hslConvert(o) {\n if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Hsl;\n if (o instanceof Hsl) return o;\n o = o.rgb();\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n h = NaN,\n s = max - min,\n l = (max + min) / 2;\n if (s) {\n if (r === max) h = (g - b) / s + (g < b) * 6;\n else if (g === max) h = (b - r) / s + 2;\n else h = (r - g) / s + 4;\n s /= l < 0.5 ? max + min : 2 - max - min;\n h *= 60;\n } else {\n s = l > 0 && l < 1 ? 0 : h;\n }\n return new Hsl(h, s, l, o.opacity);\n}\n\nfunction hsl(h, s, l, opacity) {\n return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hsl, hsl, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n rgb: function() {\n var h = this.h % 360 + (this.h < 0) * 360,\n s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n l = this.l,\n m2 = l + (l < 0.5 ? l : 1 - l) * s,\n m1 = 2 * l - m2;\n return new Rgb(\n hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),\n hsl2rgb(h, m1, m2),\n hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),\n this.opacity\n );\n },\n displayable: function() {\n return (0 <= this.s && this.s <= 1 || isNaN(this.s))\n && (0 <= this.l && this.l <= 1)\n && (0 <= this.opacity && this.opacity <= 1);\n }\n}));\n\n/* From FvD 13.37, CSS Color Module Level 3 */\nfunction hsl2rgb(h, m1, m2) {\n return (h < 60 ? m1 + (m2 - m1) * h / 60\n : h < 180 ? m2\n : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60\n : m1) * 255;\n}\n\nvar deg2rad = Math.PI / 180;\nvar rad2deg = 180 / Math.PI;\n\nvar Kn = 18;\nvar Xn = 0.950470;\nvar Yn = 1;\nvar Zn = 1.088830;\nvar t0 = 4 / 29;\nvar t1 = 6 / 29;\nvar t2 = 3 * t1 * t1;\nvar t3 = t1 * t1 * t1;\n\nfunction labConvert(o) {\n if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);\n if (o instanceof Hcl) {\n var h = o.h * deg2rad;\n return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);\n }\n if (!(o instanceof Rgb)) o = rgbConvert(o);\n var b = rgb2xyz(o.r),\n a = rgb2xyz(o.g),\n l = rgb2xyz(o.b),\n x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),\n y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),\n z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);\n return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);\n}\n\nfunction lab(l, a, b, opacity) {\n return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);\n}\n\nfunction Lab(l, a, b, opacity) {\n this.l = +l;\n this.a = +a;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Lab, lab, extend(Color, {\n brighter: function(k) {\n return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);\n },\n darker: function(k) {\n return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);\n },\n rgb: function() {\n var y = (this.l + 16) / 116,\n x = isNaN(this.a) ? y : y + this.a / 500,\n z = isNaN(this.b) ? y : y - this.b / 200;\n y = Yn * lab2xyz(y);\n x = Xn * lab2xyz(x);\n z = Zn * lab2xyz(z);\n return new Rgb(\n xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB\n xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),\n xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),\n this.opacity\n );\n }\n}));\n\nfunction xyz2lab(t) {\n return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;\n}\n\nfunction lab2xyz(t) {\n return t > t1 ? t * t * t : t2 * (t - t0);\n}\n\nfunction xyz2rgb(x) {\n return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);\n}\n\nfunction rgb2xyz(x) {\n return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);\n}\n\nfunction hclConvert(o) {\n if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);\n if (!(o instanceof Lab)) o = labConvert(o);\n var h = Math.atan2(o.b, o.a) * rad2deg;\n return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);\n}\n\nfunction hcl(h, c, l, opacity) {\n return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hcl(h, c, l, opacity) {\n this.h = +h;\n this.c = +c;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hcl, hcl, extend(Color, {\n brighter: function(k) {\n return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);\n },\n darker: function(k) {\n return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);\n },\n rgb: function() {\n return labConvert(this).rgb();\n }\n}));\n\nvar A = -0.14861;\nvar B = +1.78277;\nvar C = -0.29227;\nvar D = -0.90649;\nvar E = +1.97294;\nvar ED = E * D;\nvar EB = E * B;\nvar BC_DA = B * C - D * A;\n\nfunction cubehelixConvert(o) {\n if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Rgb)) o = rgbConvert(o);\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),\n bl = b - l,\n k = (E * (g - l) - C * bl) / D,\n s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1\n h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;\n return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);\n}\n\nfunction cubehelix(h, s, l, opacity) {\n return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Cubehelix(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Cubehelix, cubehelix, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n },\n rgb: function() {\n var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,\n l = +this.l,\n a = isNaN(this.s) ? 0 : this.s * l * (1 - l),\n cosh = Math.cos(h),\n sinh = Math.sin(h);\n return new Rgb(\n 255 * (l + a * (A * cosh + B * sinh)),\n 255 * (l + a * (C * cosh + D * sinh)),\n 255 * (l + a * (E * cosh)),\n this.opacity\n );\n }\n}));\n\nfunction basis(t1, v0, v1, v2, v3) {\n var t2 = t1 * t1, t3 = t2 * t1;\n return ((1 - 3 * t1 + 3 * t2 - t3) * v0\n + (4 - 6 * t2 + 3 * t3) * v1\n + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2\n + t3 * v3) / 6;\n}\n\nfunction basis$1(values) {\n var n = values.length - 1;\n return function(t) {\n var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),\n v1 = values[i],\n v2 = values[i + 1],\n v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,\n v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n\nfunction basisClosed(values) {\n var n = values.length;\n return function(t) {\n var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),\n v0 = values[(i + n - 1) % n],\n v1 = values[i % n],\n v2 = values[(i + 1) % n],\n v3 = values[(i + 2) % n];\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n\nfunction constant$3(x) {\n return function() {\n return x;\n };\n}\n\nfunction linear(a, d) {\n return function(t) {\n return a + t * d;\n };\n}\n\nfunction exponential(a, b, y) {\n return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {\n return Math.pow(a + t * b, y);\n };\n}\n\nfunction hue(a, b) {\n var d = b - a;\n return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);\n}\n\nfunction gamma(y) {\n return (y = +y) === 1 ? nogamma : function(a, b) {\n return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);\n };\n}\n\nfunction nogamma(a, b) {\n var d = b - a;\n return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);\n}\n\nvar interpolateRgb = (function rgbGamma(y) {\n var color$$1 = gamma(y);\n\n function rgb$$1(start, end) {\n var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),\n g = color$$1(start.g, end.g),\n b = color$$1(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.r = r(t);\n start.g = g(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n rgb$$1.gamma = rgbGamma;\n\n return rgb$$1;\n})(1);\n\nfunction rgbSpline(spline) {\n return function(colors) {\n var n = colors.length,\n r = new Array(n),\n g = new Array(n),\n b = new Array(n),\n i, color$$1;\n for (i = 0; i < n; ++i) {\n color$$1 = rgb(colors[i]);\n r[i] = color$$1.r || 0;\n g[i] = color$$1.g || 0;\n b[i] = color$$1.b || 0;\n }\n r = spline(r);\n g = spline(g);\n b = spline(b);\n color$$1.opacity = 1;\n return function(t) {\n color$$1.r = r(t);\n color$$1.g = g(t);\n color$$1.b = b(t);\n return color$$1 + \"\";\n };\n };\n}\n\nvar rgbBasis = rgbSpline(basis$1);\nvar rgbBasisClosed = rgbSpline(basisClosed);\n\nfunction array$1(a, b) {\n var nb = b ? b.length : 0,\n na = a ? Math.min(nb, a.length) : 0,\n x = new Array(na),\n c = new Array(nb),\n i;\n\n for (i = 0; i < na; ++i) x[i] = interpolateValue(a[i], b[i]);\n for (; i < nb; ++i) c[i] = b[i];\n\n return function(t) {\n for (i = 0; i < na; ++i) c[i] = x[i](t);\n return c;\n };\n}\n\nfunction date(a, b) {\n var d = new Date;\n return a = +a, b -= a, function(t) {\n return d.setTime(a + b * t), d;\n };\n}\n\nfunction reinterpolate(a, b) {\n return a = +a, b -= a, function(t) {\n return a + b * t;\n };\n}\n\nfunction object(a, b) {\n var i = {},\n c = {},\n k;\n\n if (a === null || typeof a !== \"object\") a = {};\n if (b === null || typeof b !== \"object\") b = {};\n\n for (k in b) {\n if (k in a) {\n i[k] = interpolateValue(a[k], b[k]);\n } else {\n c[k] = b[k];\n }\n }\n\n return function(t) {\n for (k in i) c[k] = i[k](t);\n return c;\n };\n}\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g;\nvar reB = new RegExp(reA.source, \"g\");\n\nfunction zero(b) {\n return function() {\n return b;\n };\n}\n\nfunction one(b) {\n return function(t) {\n return b(t) + \"\";\n };\n}\n\nfunction interpolateString(a, b) {\n var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b\n am, // current match in a\n bm, // current match in b\n bs, // string preceding current number in b, if any\n i = -1, // index in s\n s = [], // string constants and placeholders\n q = []; // number interpolators\n\n // Coerce inputs to strings.\n a = a + \"\", b = b + \"\";\n\n // Interpolate pairs of numbers in a & b.\n while ((am = reA.exec(a))\n && (bm = reB.exec(b))) {\n if ((bs = bm.index) > bi) { // a string precedes the next number in b\n bs = b.slice(bi, bs);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match\n if (s[i]) s[i] += bm; // coalesce with previous string\n else s[++i] = bm;\n } else { // interpolate non-matching numbers\n s[++i] = null;\n q.push({i: i, x: reinterpolate(am, bm)});\n }\n bi = reB.lastIndex;\n }\n\n // Add remains of b.\n if (bi < b.length) {\n bs = b.slice(bi);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n\n // Special optimization for only a single match.\n // Otherwise, interpolate each of the numbers and rejoin the string.\n return s.length < 2 ? (q[0]\n ? one(q[0].x)\n : zero(b))\n : (b = q.length, function(t) {\n for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n });\n}\n\nfunction interpolateValue(a, b) {\n var t = typeof b, c;\n return b == null || t === \"boolean\" ? constant$3(b)\n : (t === \"number\" ? reinterpolate\n : t === \"string\" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString)\n : b instanceof color ? interpolateRgb\n : b instanceof Date ? date\n : Array.isArray(b) ? array$1\n : typeof b.valueOf !== \"function\" && typeof b.toString !== \"function\" || isNaN(b) ? object\n : reinterpolate)(a, b);\n}\n\nfunction interpolateRound(a, b) {\n return a = +a, b -= a, function(t) {\n return Math.round(a + b * t);\n };\n}\n\nvar degrees = 180 / Math.PI;\n\nvar identity$2 = {\n translateX: 0,\n translateY: 0,\n rotate: 0,\n skewX: 0,\n scaleX: 1,\n scaleY: 1\n};\n\nfunction decompose(a, b, c, d, e, f) {\n var scaleX, scaleY, skewX;\n if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;\n if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;\n if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;\n if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;\n return {\n translateX: e,\n translateY: f,\n rotate: Math.atan2(b, a) * degrees,\n skewX: Math.atan(skewX) * degrees,\n scaleX: scaleX,\n scaleY: scaleY\n };\n}\n\nvar cssNode;\nvar cssRoot;\nvar cssView;\nvar svgNode;\n\nfunction parseCss(value) {\n if (value === \"none\") return identity$2;\n if (!cssNode) cssNode = document.createElement(\"DIV\"), cssRoot = document.documentElement, cssView = document.defaultView;\n cssNode.style.transform = value;\n value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue(\"transform\");\n cssRoot.removeChild(cssNode);\n value = value.slice(7, -1).split(\",\");\n return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);\n}\n\nfunction parseSvg(value) {\n if (value == null) return identity$2;\n if (!svgNode) svgNode = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n svgNode.setAttribute(\"transform\", value);\n if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;\n value = value.matrix;\n return decompose(value.a, value.b, value.c, value.d, value.e, value.f);\n}\n\nfunction interpolateTransform(parse, pxComma, pxParen, degParen) {\n\n function pop(s) {\n return s.length ? s.pop() + \" \" : \"\";\n }\n\n function translate(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(\"translate(\", null, pxComma, null, pxParen);\n q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});\n } else if (xb || yb) {\n s.push(\"translate(\" + xb + pxComma + yb + pxParen);\n }\n }\n\n function rotate(a, b, s, q) {\n if (a !== b) {\n if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path\n q.push({i: s.push(pop(s) + \"rotate(\", null, degParen) - 2, x: reinterpolate(a, b)});\n } else if (b) {\n s.push(pop(s) + \"rotate(\" + b + degParen);\n }\n }\n\n function skewX(a, b, s, q) {\n if (a !== b) {\n q.push({i: s.push(pop(s) + \"skewX(\", null, degParen) - 2, x: reinterpolate(a, b)});\n } else if (b) {\n s.push(pop(s) + \"skewX(\" + b + degParen);\n }\n }\n\n function scale(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(pop(s) + \"scale(\", null, \",\", null, \")\");\n q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});\n } else if (xb !== 1 || yb !== 1) {\n s.push(pop(s) + \"scale(\" + xb + \",\" + yb + \")\");\n }\n }\n\n return function(a, b) {\n var s = [], // string constants and placeholders\n q = []; // number interpolators\n a = parse(a), b = parse(b);\n translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);\n rotate(a.rotate, b.rotate, s, q);\n skewX(a.skewX, b.skewX, s, q);\n scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);\n a = b = null; // gc\n return function(t) {\n var i = -1, n = q.length, o;\n while (++i < n) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n };\n };\n}\n\nvar interpolateTransformCss = interpolateTransform(parseCss, \"px, \", \"px)\", \"deg)\");\nvar interpolateTransformSvg = interpolateTransform(parseSvg, \", \", \")\", \")\");\n\nvar rho = Math.SQRT2;\nvar rho2 = 2;\nvar rho4 = 4;\nvar epsilon2 = 1e-12;\n\nfunction cosh(x) {\n return ((x = Math.exp(x)) + 1 / x) / 2;\n}\n\nfunction sinh(x) {\n return ((x = Math.exp(x)) - 1 / x) / 2;\n}\n\nfunction tanh(x) {\n return ((x = Math.exp(2 * x)) - 1) / (x + 1);\n}\n\n// p0 = [ux0, uy0, w0]\n// p1 = [ux1, uy1, w1]\nfunction interpolateZoom(p0, p1) {\n var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],\n ux1 = p1[0], uy1 = p1[1], w1 = p1[2],\n dx = ux1 - ux0,\n dy = uy1 - uy0,\n d2 = dx * dx + dy * dy,\n i,\n S;\n\n // Special case for u0 ≅ u1.\n if (d2 < epsilon2) {\n S = Math.log(w1 / w0) / rho;\n i = function(t) {\n return [\n ux0 + t * dx,\n uy0 + t * dy,\n w0 * Math.exp(rho * t * S)\n ];\n };\n }\n\n // General case.\n else {\n var d1 = Math.sqrt(d2),\n b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),\n b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),\n r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),\n r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);\n S = (r1 - r0) / rho;\n i = function(t) {\n var s = t * S,\n coshr0 = cosh(r0),\n u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));\n return [\n ux0 + u * dx,\n uy0 + u * dy,\n w0 * coshr0 / cosh(rho * s + r0)\n ];\n };\n }\n\n i.duration = S * 1000;\n\n return i;\n}\n\nfunction hsl$1(hue$$1) {\n return function(start, end) {\n var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),\n s = nogamma(start.s, end.s),\n l = nogamma(start.l, end.l),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.s = s(t);\n start.l = l(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n}\n\nvar hsl$2 = hsl$1(hue);\nvar hslLong = hsl$1(nogamma);\n\nfunction lab$1(start, end) {\n var l = nogamma((start = lab(start)).l, (end = lab(end)).l),\n a = nogamma(start.a, end.a),\n b = nogamma(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.l = l(t);\n start.a = a(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n}\n\nfunction hcl$1(hue$$1) {\n return function(start, end) {\n var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),\n c = nogamma(start.c, end.c),\n l = nogamma(start.l, end.l),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.c = c(t);\n start.l = l(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n}\n\nvar hcl$2 = hcl$1(hue);\nvar hclLong = hcl$1(nogamma);\n\nfunction cubehelix$1(hue$$1) {\n return (function cubehelixGamma(y) {\n y = +y;\n\n function cubehelix$$1(start, end) {\n var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),\n s = nogamma(start.s, end.s),\n l = nogamma(start.l, end.l),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.s = s(t);\n start.l = l(Math.pow(t, y));\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n cubehelix$$1.gamma = cubehelixGamma;\n\n return cubehelix$$1;\n })(1);\n}\n\nvar cubehelix$2 = cubehelix$1(hue);\nvar cubehelixLong = cubehelix$1(nogamma);\n\nfunction quantize(interpolator, n) {\n var samples = new Array(n);\n for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));\n return samples;\n}\n\nvar frame = 0;\nvar timeout = 0;\nvar interval = 0;\nvar pokeDelay = 1000;\nvar taskHead;\nvar taskTail;\nvar clockLast = 0;\nvar clockNow = 0;\nvar clockSkew = 0;\nvar clock = typeof performance === \"object\" && performance.now ? performance : Date;\nvar setFrame = typeof window === \"object\" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };\n\nfunction now() {\n return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);\n}\n\nfunction clearNow() {\n clockNow = 0;\n}\n\nfunction Timer() {\n this._call =\n this._time =\n this._next = null;\n}\n\nTimer.prototype = timer.prototype = {\n constructor: Timer,\n restart: function(callback, delay, time) {\n if (typeof callback !== \"function\") throw new TypeError(\"callback is not a function\");\n time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);\n if (!this._next && taskTail !== this) {\n if (taskTail) taskTail._next = this;\n else taskHead = this;\n taskTail = this;\n }\n this._call = callback;\n this._time = time;\n sleep();\n },\n stop: function() {\n if (this._call) {\n this._call = null;\n this._time = Infinity;\n sleep();\n }\n }\n};\n\nfunction timer(callback, delay, time) {\n var t = new Timer;\n t.restart(callback, delay, time);\n return t;\n}\n\nfunction timerFlush() {\n now(); // Get the current time, if not already set.\n ++frame; // Pretend we’ve set an alarm, if we haven’t already.\n var t = taskHead, e;\n while (t) {\n if ((e = clockNow - t._time) >= 0) t._call.call(null, e);\n t = t._next;\n }\n --frame;\n}\n\nfunction wake() {\n clockNow = (clockLast = clock.now()) + clockSkew;\n frame = timeout = 0;\n try {\n timerFlush();\n } finally {\n frame = 0;\n nap();\n clockNow = 0;\n }\n}\n\nfunction poke() {\n var now = clock.now(), delay = now - clockLast;\n if (delay > pokeDelay) clockSkew -= delay, clockLast = now;\n}\n\nfunction nap() {\n var t0, t1 = taskHead, t2, time = Infinity;\n while (t1) {\n if (t1._call) {\n if (time > t1._time) time = t1._time;\n t0 = t1, t1 = t1._next;\n } else {\n t2 = t1._next, t1._next = null;\n t1 = t0 ? t0._next = t2 : taskHead = t2;\n }\n }\n taskTail = t0;\n sleep(time);\n}\n\nfunction sleep(time) {\n if (frame) return; // Soonest alarm already set, or will be.\n if (timeout) timeout = clearTimeout(timeout);\n var delay = time - clockNow; // Strictly less than if we recomputed clockNow.\n if (delay > 24) {\n if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);\n if (interval) interval = clearInterval(interval);\n } else {\n if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);\n frame = 1, setFrame(wake);\n }\n}\n\nfunction timeout$1(callback, delay, time) {\n var t = new Timer;\n delay = delay == null ? 0 : +delay;\n t.restart(function(elapsed) {\n t.stop();\n callback(elapsed + delay);\n }, delay, time);\n return t;\n}\n\nfunction interval$1(callback, delay, time) {\n var t = new Timer, total = delay;\n if (delay == null) return t.restart(callback, delay, time), t;\n delay = +delay, time = time == null ? now() : +time;\n t.restart(function tick(elapsed) {\n elapsed += total;\n t.restart(tick, total += delay, time);\n callback(elapsed);\n }, delay, time);\n return t;\n}\n\nvar emptyOn = dispatch(\"start\", \"end\", \"interrupt\");\nvar emptyTween = [];\n\nvar CREATED = 0;\nvar SCHEDULED = 1;\nvar STARTING = 2;\nvar STARTED = 3;\nvar RUNNING = 4;\nvar ENDING = 5;\nvar ENDED = 6;\n\nfunction schedule(node, name, id, index, group, timing) {\n var schedules = node.__transition;\n if (!schedules) node.__transition = {};\n else if (id in schedules) return;\n create$1(node, id, {\n name: name,\n index: index, // For context during callback.\n group: group, // For context during callback.\n on: emptyOn,\n tween: emptyTween,\n time: timing.time,\n delay: timing.delay,\n duration: timing.duration,\n ease: timing.ease,\n timer: null,\n state: CREATED\n });\n}\n\nfunction init(node, id) {\n var schedule = get$1(node, id);\n if (schedule.state > CREATED) throw new Error(\"too late; already scheduled\");\n return schedule;\n}\n\nfunction set$1(node, id) {\n var schedule = get$1(node, id);\n if (schedule.state > STARTING) throw new Error(\"too late; already started\");\n return schedule;\n}\n\nfunction get$1(node, id) {\n var schedule = node.__transition;\n if (!schedule || !(schedule = schedule[id])) throw new Error(\"transition not found\");\n return schedule;\n}\n\nfunction create$1(node, id, self) {\n var schedules = node.__transition,\n tween;\n\n // Initialize the self timer when the transition is created.\n // Note the actual delay is not known until the first callback!\n schedules[id] = self;\n self.timer = timer(schedule, 0, self.time);\n\n function schedule(elapsed) {\n self.state = SCHEDULED;\n self.timer.restart(start, self.delay, self.time);\n\n // If the elapsed delay is less than our first sleep, start immediately.\n if (self.delay <= elapsed) start(elapsed - self.delay);\n }\n\n function start(elapsed) {\n var i, j, n, o;\n\n // If the state is not SCHEDULED, then we previously errored on start.\n if (self.state !== SCHEDULED) return stop();\n\n for (i in schedules) {\n o = schedules[i];\n if (o.name !== self.name) continue;\n\n // While this element already has a starting transition during this frame,\n // defer starting an interrupting transition until that transition has a\n // chance to tick (and possibly end); see d3/d3-transition#54!\n if (o.state === STARTED) return timeout$1(start);\n\n // Interrupt the active transition, if any.\n // Dispatch the interrupt event.\n if (o.state === RUNNING) {\n o.state = ENDED;\n o.timer.stop();\n o.on.call(\"interrupt\", node, node.__data__, o.index, o.group);\n delete schedules[i];\n }\n\n // Cancel any pre-empted transitions. No interrupt event is dispatched\n // because the cancelled transitions never started. Note that this also\n // removes this transition from the pending list!\n else if (+i < id) {\n o.state = ENDED;\n o.timer.stop();\n delete schedules[i];\n }\n }\n\n // Defer the first tick to end of the current frame; see d3/d3#1576.\n // Note the transition may be canceled after start and before the first tick!\n // Note this must be scheduled before the start event; see d3/d3-transition#16!\n // Assuming this is successful, subsequent callbacks go straight to tick.\n timeout$1(function() {\n if (self.state === STARTED) {\n self.state = RUNNING;\n self.timer.restart(tick, self.delay, self.time);\n tick(elapsed);\n }\n });\n\n // Dispatch the start event.\n // Note this must be done before the tween are initialized.\n self.state = STARTING;\n self.on.call(\"start\", node, node.__data__, self.index, self.group);\n if (self.state !== STARTING) return; // interrupted\n self.state = STARTED;\n\n // Initialize the tween, deleting null tween.\n tween = new Array(n = self.tween.length);\n for (i = 0, j = -1; i < n; ++i) {\n if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {\n tween[++j] = o;\n }\n }\n tween.length = j + 1;\n }\n\n function tick(elapsed) {\n var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),\n i = -1,\n n = tween.length;\n\n while (++i < n) {\n tween[i].call(null, t);\n }\n\n // Dispatch the end event.\n if (self.state === ENDING) {\n self.on.call(\"end\", node, node.__data__, self.index, self.group);\n stop();\n }\n }\n\n function stop() {\n self.state = ENDED;\n self.timer.stop();\n delete schedules[id];\n for (var i in schedules) return; // eslint-disable-line no-unused-vars\n delete node.__transition;\n }\n}\n\nfunction interrupt(node, name) {\n var schedules = node.__transition,\n schedule$$1,\n active,\n empty = true,\n i;\n\n if (!schedules) return;\n\n name = name == null ? null : name + \"\";\n\n for (i in schedules) {\n if ((schedule$$1 = schedules[i]).name !== name) { empty = false; continue; }\n active = schedule$$1.state > STARTING && schedule$$1.state < ENDING;\n schedule$$1.state = ENDED;\n schedule$$1.timer.stop();\n if (active) schedule$$1.on.call(\"interrupt\", node, node.__data__, schedule$$1.index, schedule$$1.group);\n delete schedules[i];\n }\n\n if (empty) delete node.__transition;\n}\n\nfunction selection_interrupt(name) {\n return this.each(function() {\n interrupt(this, name);\n });\n}\n\nfunction tweenRemove(id, name) {\n var tween0, tween1;\n return function() {\n var schedule$$1 = set$1(this, id),\n tween = schedule$$1.tween;\n\n // If this node shared tween with the previous node,\n // just assign the updated shared tween and we’re done!\n // Otherwise, copy-on-write.\n if (tween !== tween0) {\n tween1 = tween0 = tween;\n for (var i = 0, n = tween1.length; i < n; ++i) {\n if (tween1[i].name === name) {\n tween1 = tween1.slice();\n tween1.splice(i, 1);\n break;\n }\n }\n }\n\n schedule$$1.tween = tween1;\n };\n}\n\nfunction tweenFunction(id, name, value) {\n var tween0, tween1;\n if (typeof value !== \"function\") throw new Error;\n return function() {\n var schedule$$1 = set$1(this, id),\n tween = schedule$$1.tween;\n\n // If this node shared tween with the previous node,\n // just assign the updated shared tween and we’re done!\n // Otherwise, copy-on-write.\n if (tween !== tween0) {\n tween1 = (tween0 = tween).slice();\n for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {\n if (tween1[i].name === name) {\n tween1[i] = t;\n break;\n }\n }\n if (i === n) tween1.push(t);\n }\n\n schedule$$1.tween = tween1;\n };\n}\n\nfunction transition_tween(name, value) {\n var id = this._id;\n\n name += \"\";\n\n if (arguments.length < 2) {\n var tween = get$1(this.node(), id).tween;\n for (var i = 0, n = tween.length, t; i < n; ++i) {\n if ((t = tween[i]).name === name) {\n return t.value;\n }\n }\n return null;\n }\n\n return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));\n}\n\nfunction tweenValue(transition, name, value) {\n var id = transition._id;\n\n transition.each(function() {\n var schedule$$1 = set$1(this, id);\n (schedule$$1.value || (schedule$$1.value = {}))[name] = value.apply(this, arguments);\n });\n\n return function(node) {\n return get$1(node, id).value[name];\n };\n}\n\nfunction interpolate(a, b) {\n var c;\n return (typeof b === \"number\" ? reinterpolate\n : b instanceof color ? interpolateRgb\n : (c = color(b)) ? (b = c, interpolateRgb)\n : interpolateString)(a, b);\n}\n\nfunction attrRemove$1(name) {\n return function() {\n this.removeAttribute(name);\n };\n}\n\nfunction attrRemoveNS$1(fullname) {\n return function() {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attrConstant$1(name, interpolate$$1, value1) {\n var value00,\n interpolate0;\n return function() {\n var value0 = this.getAttribute(name);\n return value0 === value1 ? null\n : value0 === value00 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value1);\n };\n}\n\nfunction attrConstantNS$1(fullname, interpolate$$1, value1) {\n var value00,\n interpolate0;\n return function() {\n var value0 = this.getAttributeNS(fullname.space, fullname.local);\n return value0 === value1 ? null\n : value0 === value00 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value1);\n };\n}\n\nfunction attrFunction$1(name, interpolate$$1, value) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0, value1 = value(this);\n if (value1 == null) return void this.removeAttribute(name);\n value0 = this.getAttribute(name);\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n };\n}\n\nfunction attrFunctionNS$1(fullname, interpolate$$1, value) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0, value1 = value(this);\n if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);\n value0 = this.getAttributeNS(fullname.space, fullname.local);\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n };\n}\n\nfunction transition_attr(name, value) {\n var fullname = namespace(name), i = fullname === \"transform\" ? interpolateTransformSvg : interpolate;\n return this.attrTween(name, typeof value === \"function\"\n ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, \"attr.\" + name, value))\n : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)\n : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + \"\"));\n}\n\nfunction attrTweenNS(fullname, value) {\n function tween() {\n var node = this, i = value.apply(node, arguments);\n return i && function(t) {\n node.setAttributeNS(fullname.space, fullname.local, i(t));\n };\n }\n tween._value = value;\n return tween;\n}\n\nfunction attrTween(name, value) {\n function tween() {\n var node = this, i = value.apply(node, arguments);\n return i && function(t) {\n node.setAttribute(name, i(t));\n };\n }\n tween._value = value;\n return tween;\n}\n\nfunction transition_attrTween(name, value) {\n var key = \"attr.\" + name;\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== \"function\") throw new Error;\n var fullname = namespace(name);\n return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));\n}\n\nfunction delayFunction(id, value) {\n return function() {\n init(this, id).delay = +value.apply(this, arguments);\n };\n}\n\nfunction delayConstant(id, value) {\n return value = +value, function() {\n init(this, id).delay = value;\n };\n}\n\nfunction transition_delay(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each((typeof value === \"function\"\n ? delayFunction\n : delayConstant)(id, value))\n : get$1(this.node(), id).delay;\n}\n\nfunction durationFunction(id, value) {\n return function() {\n set$1(this, id).duration = +value.apply(this, arguments);\n };\n}\n\nfunction durationConstant(id, value) {\n return value = +value, function() {\n set$1(this, id).duration = value;\n };\n}\n\nfunction transition_duration(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each((typeof value === \"function\"\n ? durationFunction\n : durationConstant)(id, value))\n : get$1(this.node(), id).duration;\n}\n\nfunction easeConstant(id, value) {\n if (typeof value !== \"function\") throw new Error;\n return function() {\n set$1(this, id).ease = value;\n };\n}\n\nfunction transition_ease(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each(easeConstant(id, value))\n : get$1(this.node(), id).ease;\n}\n\nfunction transition_filter(match) {\n if (typeof match !== \"function\") match = matcher$1(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Transition(subgroups, this._parents, this._name, this._id);\n}\n\nfunction transition_merge(transition$$1) {\n if (transition$$1._id !== this._id) throw new Error;\n\n for (var groups0 = this._groups, groups1 = transition$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Transition(merges, this._parents, this._name, this._id);\n}\n\nfunction start(name) {\n return (name + \"\").trim().split(/^|\\s+/).every(function(t) {\n var i = t.indexOf(\".\");\n if (i >= 0) t = t.slice(0, i);\n return !t || t === \"start\";\n });\n}\n\nfunction onFunction(id, name, listener) {\n var on0, on1, sit = start(name) ? init : set$1;\n return function() {\n var schedule$$1 = sit(this, id),\n on = schedule$$1.on;\n\n // If this node shared a dispatch with the previous node,\n // just assign the updated shared dispatch and we’re done!\n // Otherwise, copy-on-write.\n if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);\n\n schedule$$1.on = on1;\n };\n}\n\nfunction transition_on(name, listener) {\n var id = this._id;\n\n return arguments.length < 2\n ? get$1(this.node(), id).on.on(name)\n : this.each(onFunction(id, name, listener));\n}\n\nfunction removeFunction(id) {\n return function() {\n var parent = this.parentNode;\n for (var i in this.__transition) if (+i !== id) return;\n if (parent) parent.removeChild(this);\n };\n}\n\nfunction transition_remove() {\n return this.on(\"end.remove\", removeFunction(this._id));\n}\n\nfunction transition_select(select) {\n var name = this._name,\n id = this._id;\n\n if (typeof select !== \"function\") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if (\"__data__\" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));\n }\n }\n }\n\n return new Transition(subgroups, this._parents, name, id);\n}\n\nfunction transition_selectAll(select) {\n var name = this._name,\n id = this._id;\n\n if (typeof select !== \"function\") select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n for (var children = select.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) {\n if (child = children[k]) {\n schedule(child, name, id, k, children, inherit);\n }\n }\n subgroups.push(children);\n parents.push(node);\n }\n }\n }\n\n return new Transition(subgroups, parents, name, id);\n}\n\nvar Selection$1 = selection.prototype.constructor;\n\nfunction transition_selection() {\n return new Selection$1(this._groups, this._parents);\n}\n\nfunction styleRemove$1(name, interpolate$$1) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0 = styleValue(this, name),\n value1 = (this.style.removeProperty(name), styleValue(this, name));\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n };\n}\n\nfunction styleRemoveEnd(name) {\n return function() {\n this.style.removeProperty(name);\n };\n}\n\nfunction styleConstant$1(name, interpolate$$1, value1) {\n var value00,\n interpolate0;\n return function() {\n var value0 = styleValue(this, name);\n return value0 === value1 ? null\n : value0 === value00 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value1);\n };\n}\n\nfunction styleFunction$1(name, interpolate$$1, value) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0 = styleValue(this, name),\n value1 = value(this);\n if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name));\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n };\n}\n\nfunction transition_style(name, value, priority) {\n var i = (name += \"\") === \"transform\" ? interpolateTransformCss : interpolate;\n return value == null ? this\n .styleTween(name, styleRemove$1(name, i))\n .on(\"end.style.\" + name, styleRemoveEnd(name))\n : this.styleTween(name, typeof value === \"function\"\n ? styleFunction$1(name, i, tweenValue(this, \"style.\" + name, value))\n : styleConstant$1(name, i, value + \"\"), priority);\n}\n\nfunction styleTween(name, value, priority) {\n function tween() {\n var node = this, i = value.apply(node, arguments);\n return i && function(t) {\n node.style.setProperty(name, i(t), priority);\n };\n }\n tween._value = value;\n return tween;\n}\n\nfunction transition_styleTween(name, value, priority) {\n var key = \"style.\" + (name += \"\");\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== \"function\") throw new Error;\n return this.tween(key, styleTween(name, value, priority == null ? \"\" : priority));\n}\n\nfunction textConstant$1(value) {\n return function() {\n this.textContent = value;\n };\n}\n\nfunction textFunction$1(value) {\n return function() {\n var value1 = value(this);\n this.textContent = value1 == null ? \"\" : value1;\n };\n}\n\nfunction transition_text(value) {\n return this.tween(\"text\", typeof value === \"function\"\n ? textFunction$1(tweenValue(this, \"text\", value))\n : textConstant$1(value == null ? \"\" : value + \"\"));\n}\n\nfunction transition_transition() {\n var name = this._name,\n id0 = this._id,\n id1 = newId();\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n var inherit = get$1(node, id0);\n schedule(node, name, id1, i, group, {\n time: inherit.time + inherit.delay + inherit.duration,\n delay: 0,\n duration: inherit.duration,\n ease: inherit.ease\n });\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id1);\n}\n\nvar id = 0;\n\nfunction Transition(groups, parents, name, id) {\n this._groups = groups;\n this._parents = parents;\n this._name = name;\n this._id = id;\n}\n\nfunction transition(name) {\n return selection().transition(name);\n}\n\nfunction newId() {\n return ++id;\n}\n\nvar selection_prototype = selection.prototype;\n\nTransition.prototype = transition.prototype = {\n constructor: Transition,\n select: transition_select,\n selectAll: transition_selectAll,\n filter: transition_filter,\n merge: transition_merge,\n selection: transition_selection,\n transition: transition_transition,\n call: selection_prototype.call,\n nodes: selection_prototype.nodes,\n node: selection_prototype.node,\n size: selection_prototype.size,\n empty: selection_prototype.empty,\n each: selection_prototype.each,\n on: transition_on,\n attr: transition_attr,\n attrTween: transition_attrTween,\n style: transition_style,\n styleTween: transition_styleTween,\n text: transition_text,\n remove: transition_remove,\n tween: transition_tween,\n delay: transition_delay,\n duration: transition_duration,\n ease: transition_ease\n};\n\nfunction linear$1(t) {\n return +t;\n}\n\nfunction quadIn(t) {\n return t * t;\n}\n\nfunction quadOut(t) {\n return t * (2 - t);\n}\n\nfunction quadInOut(t) {\n return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;\n}\n\nfunction cubicIn(t) {\n return t * t * t;\n}\n\nfunction cubicOut(t) {\n return --t * t * t + 1;\n}\n\nfunction cubicInOut(t) {\n return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;\n}\n\nvar exponent = 3;\n\nvar polyIn = (function custom(e) {\n e = +e;\n\n function polyIn(t) {\n return Math.pow(t, e);\n }\n\n polyIn.exponent = custom;\n\n return polyIn;\n})(exponent);\n\nvar polyOut = (function custom(e) {\n e = +e;\n\n function polyOut(t) {\n return 1 - Math.pow(1 - t, e);\n }\n\n polyOut.exponent = custom;\n\n return polyOut;\n})(exponent);\n\nvar polyInOut = (function custom(e) {\n e = +e;\n\n function polyInOut(t) {\n return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;\n }\n\n polyInOut.exponent = custom;\n\n return polyInOut;\n})(exponent);\n\nvar pi = Math.PI;\nvar halfPi = pi / 2;\n\nfunction sinIn(t) {\n return 1 - Math.cos(t * halfPi);\n}\n\nfunction sinOut(t) {\n return Math.sin(t * halfPi);\n}\n\nfunction sinInOut(t) {\n return (1 - Math.cos(pi * t)) / 2;\n}\n\nfunction expIn(t) {\n return Math.pow(2, 10 * t - 10);\n}\n\nfunction expOut(t) {\n return 1 - Math.pow(2, -10 * t);\n}\n\nfunction expInOut(t) {\n return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;\n}\n\nfunction circleIn(t) {\n return 1 - Math.sqrt(1 - t * t);\n}\n\nfunction circleOut(t) {\n return Math.sqrt(1 - --t * t);\n}\n\nfunction circleInOut(t) {\n return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;\n}\n\nvar b1 = 4 / 11;\nvar b2 = 6 / 11;\nvar b3 = 8 / 11;\nvar b4 = 3 / 4;\nvar b5 = 9 / 11;\nvar b6 = 10 / 11;\nvar b7 = 15 / 16;\nvar b8 = 21 / 22;\nvar b9 = 63 / 64;\nvar b0 = 1 / b1 / b1;\n\nfunction bounceIn(t) {\n return 1 - bounceOut(1 - t);\n}\n\nfunction bounceOut(t) {\n return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;\n}\n\nfunction bounceInOut(t) {\n return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;\n}\n\nvar overshoot = 1.70158;\n\nvar backIn = (function custom(s) {\n s = +s;\n\n function backIn(t) {\n return t * t * ((s + 1) * t - s);\n }\n\n backIn.overshoot = custom;\n\n return backIn;\n})(overshoot);\n\nvar backOut = (function custom(s) {\n s = +s;\n\n function backOut(t) {\n return --t * t * ((s + 1) * t + s) + 1;\n }\n\n backOut.overshoot = custom;\n\n return backOut;\n})(overshoot);\n\nvar backInOut = (function custom(s) {\n s = +s;\n\n function backInOut(t) {\n return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;\n }\n\n backInOut.overshoot = custom;\n\n return backInOut;\n})(overshoot);\n\nvar tau = 2 * Math.PI;\nvar amplitude = 1;\nvar period = 0.3;\n\nvar elasticIn = (function custom(a, p) {\n var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n function elasticIn(t) {\n return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);\n }\n\n elasticIn.amplitude = function(a) { return custom(a, p * tau); };\n elasticIn.period = function(p) { return custom(a, p); };\n\n return elasticIn;\n})(amplitude, period);\n\nvar elasticOut = (function custom(a, p) {\n var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n function elasticOut(t) {\n return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);\n }\n\n elasticOut.amplitude = function(a) { return custom(a, p * tau); };\n elasticOut.period = function(p) { return custom(a, p); };\n\n return elasticOut;\n})(amplitude, period);\n\nvar elasticInOut = (function custom(a, p) {\n var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n function elasticInOut(t) {\n return ((t = t * 2 - 1) < 0\n ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)\n : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;\n }\n\n elasticInOut.amplitude = function(a) { return custom(a, p * tau); };\n elasticInOut.period = function(p) { return custom(a, p); };\n\n return elasticInOut;\n})(amplitude, period);\n\nvar defaultTiming = {\n time: null, // Set on use.\n delay: 0,\n duration: 250,\n ease: cubicInOut\n};\n\nfunction inherit(node, id) {\n var timing;\n while (!(timing = node.__transition) || !(timing = timing[id])) {\n if (!(node = node.parentNode)) {\n return defaultTiming.time = now(), defaultTiming;\n }\n }\n return timing;\n}\n\nfunction selection_transition(name) {\n var id,\n timing;\n\n if (name instanceof Transition) {\n id = name._id, name = name._name;\n } else {\n id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + \"\";\n }\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n schedule(node, name, id, i, group, timing || inherit(node, id));\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id);\n}\n\nselection.prototype.interrupt = selection_interrupt;\nselection.prototype.transition = selection_transition;\n\nvar root$1 = [null];\n\nfunction active(node, name) {\n var schedules = node.__transition,\n schedule$$1,\n i;\n\n if (schedules) {\n name = name == null ? null : name + \"\";\n for (i in schedules) {\n if ((schedule$$1 = schedules[i]).state > SCHEDULED && schedule$$1.name === name) {\n return new Transition([[node]], root$1, name, +i);\n }\n }\n }\n\n return null;\n}\n\nfunction constant$4(x) {\n return function() {\n return x;\n };\n}\n\nfunction BrushEvent(target, type, selection) {\n this.target = target;\n this.type = type;\n this.selection = selection;\n}\n\nfunction nopropagation$1() {\n exports.event.stopImmediatePropagation();\n}\n\nfunction noevent$1() {\n exports.event.preventDefault();\n exports.event.stopImmediatePropagation();\n}\n\nvar MODE_DRAG = {name: \"drag\"};\nvar MODE_SPACE = {name: \"space\"};\nvar MODE_HANDLE = {name: \"handle\"};\nvar MODE_CENTER = {name: \"center\"};\n\nvar X = {\n name: \"x\",\n handles: [\"e\", \"w\"].map(type),\n input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },\n output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }\n};\n\nvar Y = {\n name: \"y\",\n handles: [\"n\", \"s\"].map(type),\n input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },\n output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }\n};\n\nvar XY = {\n name: \"xy\",\n handles: [\"n\", \"e\", \"s\", \"w\", \"nw\", \"ne\", \"se\", \"sw\"].map(type),\n input: function(xy) { return xy; },\n output: function(xy) { return xy; }\n};\n\nvar cursors = {\n overlay: \"crosshair\",\n selection: \"move\",\n n: \"ns-resize\",\n e: \"ew-resize\",\n s: \"ns-resize\",\n w: \"ew-resize\",\n nw: \"nwse-resize\",\n ne: \"nesw-resize\",\n se: \"nwse-resize\",\n sw: \"nesw-resize\"\n};\n\nvar flipX = {\n e: \"w\",\n w: \"e\",\n nw: \"ne\",\n ne: \"nw\",\n se: \"sw\",\n sw: \"se\"\n};\n\nvar flipY = {\n n: \"s\",\n s: \"n\",\n nw: \"sw\",\n ne: \"se\",\n se: \"ne\",\n sw: \"nw\"\n};\n\nvar signsX = {\n overlay: +1,\n selection: +1,\n n: null,\n e: +1,\n s: null,\n w: -1,\n nw: -1,\n ne: +1,\n se: +1,\n sw: -1\n};\n\nvar signsY = {\n overlay: +1,\n selection: +1,\n n: -1,\n e: null,\n s: +1,\n w: null,\n nw: -1,\n ne: -1,\n se: +1,\n sw: +1\n};\n\nfunction type(t) {\n return {type: t};\n}\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter() {\n return !exports.event.button;\n}\n\nfunction defaultExtent() {\n var svg = this.ownerSVGElement || this;\n return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];\n}\n\n// Like d3.local, but with the name “__brush” rather than auto-generated.\nfunction local(node) {\n while (!node.__brush) if (!(node = node.parentNode)) return;\n return node.__brush;\n}\n\nfunction empty(extent) {\n return extent[0][0] === extent[1][0]\n || extent[0][1] === extent[1][1];\n}\n\nfunction brushSelection(node) {\n var state = node.__brush;\n return state ? state.dim.output(state.selection) : null;\n}\n\nfunction brushX() {\n return brush$1(X);\n}\n\nfunction brushY() {\n return brush$1(Y);\n}\n\nfunction brush() {\n return brush$1(XY);\n}\n\nfunction brush$1(dim) {\n var extent = defaultExtent,\n filter = defaultFilter,\n listeners = dispatch(brush, \"start\", \"brush\", \"end\"),\n handleSize = 6,\n touchending;\n\n function brush(group) {\n var overlay = group\n .property(\"__brush\", initialize)\n .selectAll(\".overlay\")\n .data([type(\"overlay\")]);\n\n overlay.enter().append(\"rect\")\n .attr(\"class\", \"overlay\")\n .attr(\"pointer-events\", \"all\")\n .attr(\"cursor\", cursors.overlay)\n .merge(overlay)\n .each(function() {\n var extent = local(this).extent;\n select(this)\n .attr(\"x\", extent[0][0])\n .attr(\"y\", extent[0][1])\n .attr(\"width\", extent[1][0] - extent[0][0])\n .attr(\"height\", extent[1][1] - extent[0][1]);\n });\n\n group.selectAll(\".selection\")\n .data([type(\"selection\")])\n .enter().append(\"rect\")\n .attr(\"class\", \"selection\")\n .attr(\"cursor\", cursors.selection)\n .attr(\"fill\", \"#777\")\n .attr(\"fill-opacity\", 0.3)\n .attr(\"stroke\", \"#fff\")\n .attr(\"shape-rendering\", \"crispEdges\");\n\n var handle = group.selectAll(\".handle\")\n .data(dim.handles, function(d) { return d.type; });\n\n handle.exit().remove();\n\n handle.enter().append(\"rect\")\n .attr(\"class\", function(d) { return \"handle handle--\" + d.type; })\n .attr(\"cursor\", function(d) { return cursors[d.type]; });\n\n group\n .each(redraw)\n .attr(\"fill\", \"none\")\n .attr(\"pointer-events\", \"all\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\")\n .on(\"mousedown.brush touchstart.brush\", started);\n }\n\n brush.move = function(group, selection) {\n if (group.selection) {\n group\n .on(\"start.brush\", function() { emitter(this, arguments).beforestart().start(); })\n .on(\"interrupt.brush end.brush\", function() { emitter(this, arguments).end(); })\n .tween(\"brush\", function() {\n var that = this,\n state = that.__brush,\n emit = emitter(that, arguments),\n selection0 = state.selection,\n selection1 = dim.input(typeof selection === \"function\" ? selection.apply(this, arguments) : selection, state.extent),\n i = interpolateValue(selection0, selection1);\n\n function tween(t) {\n state.selection = t === 1 && empty(selection1) ? null : i(t);\n redraw.call(that);\n emit.brush();\n }\n\n return selection0 && selection1 ? tween : tween(1);\n });\n } else {\n group\n .each(function() {\n var that = this,\n args = arguments,\n state = that.__brush,\n selection1 = dim.input(typeof selection === \"function\" ? selection.apply(that, args) : selection, state.extent),\n emit = emitter(that, args).beforestart();\n\n interrupt(that);\n state.selection = selection1 == null || empty(selection1) ? null : selection1;\n redraw.call(that);\n emit.start().brush().end();\n });\n }\n };\n\n function redraw() {\n var group = select(this),\n selection = local(this).selection;\n\n if (selection) {\n group.selectAll(\".selection\")\n .style(\"display\", null)\n .attr(\"x\", selection[0][0])\n .attr(\"y\", selection[0][1])\n .attr(\"width\", selection[1][0] - selection[0][0])\n .attr(\"height\", selection[1][1] - selection[0][1]);\n\n group.selectAll(\".handle\")\n .style(\"display\", null)\n .attr(\"x\", function(d) { return d.type[d.type.length - 1] === \"e\" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })\n .attr(\"y\", function(d) { return d.type[0] === \"s\" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })\n .attr(\"width\", function(d) { return d.type === \"n\" || d.type === \"s\" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })\n .attr(\"height\", function(d) { return d.type === \"e\" || d.type === \"w\" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });\n }\n\n else {\n group.selectAll(\".selection,.handle\")\n .style(\"display\", \"none\")\n .attr(\"x\", null)\n .attr(\"y\", null)\n .attr(\"width\", null)\n .attr(\"height\", null);\n }\n }\n\n function emitter(that, args) {\n return that.__brush.emitter || new Emitter(that, args);\n }\n\n function Emitter(that, args) {\n this.that = that;\n this.args = args;\n this.state = that.__brush;\n this.active = 0;\n }\n\n Emitter.prototype = {\n beforestart: function() {\n if (++this.active === 1) this.state.emitter = this, this.starting = true;\n return this;\n },\n start: function() {\n if (this.starting) this.starting = false, this.emit(\"start\");\n return this;\n },\n brush: function() {\n this.emit(\"brush\");\n return this;\n },\n end: function() {\n if (--this.active === 0) delete this.state.emitter, this.emit(\"end\");\n return this;\n },\n emit: function(type) {\n customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);\n }\n };\n\n function started() {\n if (exports.event.touches) { if (exports.event.changedTouches.length < exports.event.touches.length) return noevent$1(); }\n else if (touchending) return;\n if (!filter.apply(this, arguments)) return;\n\n var that = this,\n type = exports.event.target.__data__.type,\n mode = (exports.event.metaKey ? type = \"overlay\" : type) === \"selection\" ? MODE_DRAG : (exports.event.altKey ? MODE_CENTER : MODE_HANDLE),\n signX = dim === Y ? null : signsX[type],\n signY = dim === X ? null : signsY[type],\n state = local(that),\n extent = state.extent,\n selection = state.selection,\n W = extent[0][0], w0, w1,\n N = extent[0][1], n0, n1,\n E = extent[1][0], e0, e1,\n S = extent[1][1], s0, s1,\n dx,\n dy,\n moving,\n shifting = signX && signY && exports.event.shiftKey,\n lockX,\n lockY,\n point0 = mouse(that),\n point = point0,\n emit = emitter(that, arguments).beforestart();\n\n if (type === \"overlay\") {\n state.selection = selection = [\n [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],\n [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]\n ];\n } else {\n w0 = selection[0][0];\n n0 = selection[0][1];\n e0 = selection[1][0];\n s0 = selection[1][1];\n }\n\n w1 = w0;\n n1 = n0;\n e1 = e0;\n s1 = s0;\n\n var group = select(that)\n .attr(\"pointer-events\", \"none\");\n\n var overlay = group.selectAll(\".overlay\")\n .attr(\"cursor\", cursors[type]);\n\n if (exports.event.touches) {\n group\n .on(\"touchmove.brush\", moved, true)\n .on(\"touchend.brush touchcancel.brush\", ended, true);\n } else {\n var view = select(exports.event.view)\n .on(\"keydown.brush\", keydowned, true)\n .on(\"keyup.brush\", keyupped, true)\n .on(\"mousemove.brush\", moved, true)\n .on(\"mouseup.brush\", ended, true);\n\n dragDisable(exports.event.view);\n }\n\n nopropagation$1();\n interrupt(that);\n redraw.call(that);\n emit.start();\n\n function moved() {\n var point1 = mouse(that);\n if (shifting && !lockX && !lockY) {\n if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;\n else lockX = true;\n }\n point = point1;\n moving = true;\n noevent$1();\n move();\n }\n\n function move() {\n var t;\n\n dx = point[0] - point0[0];\n dy = point[1] - point0[1];\n\n switch (mode) {\n case MODE_SPACE:\n case MODE_DRAG: {\n if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;\n if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;\n break;\n }\n case MODE_HANDLE: {\n if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;\n else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;\n if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;\n else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;\n break;\n }\n case MODE_CENTER: {\n if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));\n if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));\n break;\n }\n }\n\n if (e1 < w1) {\n signX *= -1;\n t = w0, w0 = e0, e0 = t;\n t = w1, w1 = e1, e1 = t;\n if (type in flipX) overlay.attr(\"cursor\", cursors[type = flipX[type]]);\n }\n\n if (s1 < n1) {\n signY *= -1;\n t = n0, n0 = s0, s0 = t;\n t = n1, n1 = s1, s1 = t;\n if (type in flipY) overlay.attr(\"cursor\", cursors[type = flipY[type]]);\n }\n\n if (state.selection) selection = state.selection; // May be set by brush.move!\n if (lockX) w1 = selection[0][0], e1 = selection[1][0];\n if (lockY) n1 = selection[0][1], s1 = selection[1][1];\n\n if (selection[0][0] !== w1\n || selection[0][1] !== n1\n || selection[1][0] !== e1\n || selection[1][1] !== s1) {\n state.selection = [[w1, n1], [e1, s1]];\n redraw.call(that);\n emit.brush();\n }\n }\n\n function ended() {\n nopropagation$1();\n if (exports.event.touches) {\n if (exports.event.touches.length) return;\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n group.on(\"touchmove.brush touchend.brush touchcancel.brush\", null);\n } else {\n yesdrag(exports.event.view, moving);\n view.on(\"keydown.brush keyup.brush mousemove.brush mouseup.brush\", null);\n }\n group.attr(\"pointer-events\", \"all\");\n overlay.attr(\"cursor\", cursors.overlay);\n if (state.selection) selection = state.selection; // May be set by brush.move (on start)!\n if (empty(selection)) state.selection = null, redraw.call(that);\n emit.end();\n }\n\n function keydowned() {\n switch (exports.event.keyCode) {\n case 16: { // SHIFT\n shifting = signX && signY;\n break;\n }\n case 18: { // ALT\n if (mode === MODE_HANDLE) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n move();\n }\n break;\n }\n case 32: { // SPACE; takes priority over ALT\n if (mode === MODE_HANDLE || mode === MODE_CENTER) {\n if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;\n if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;\n mode = MODE_SPACE;\n overlay.attr(\"cursor\", cursors.selection);\n move();\n }\n break;\n }\n default: return;\n }\n noevent$1();\n }\n\n function keyupped() {\n switch (exports.event.keyCode) {\n case 16: { // SHIFT\n if (shifting) {\n lockX = lockY = shifting = false;\n move();\n }\n break;\n }\n case 18: { // ALT\n if (mode === MODE_CENTER) {\n if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n move();\n }\n break;\n }\n case 32: { // SPACE\n if (mode === MODE_SPACE) {\n if (exports.event.altKey) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n } else {\n if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n }\n overlay.attr(\"cursor\", cursors[type]);\n move();\n }\n break;\n }\n default: return;\n }\n noevent$1();\n }\n }\n\n function initialize() {\n var state = this.__brush || {selection: null};\n state.extent = extent.apply(this, arguments);\n state.dim = dim;\n return state;\n }\n\n brush.extent = function(_) {\n return arguments.length ? (extent = typeof _ === \"function\" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;\n };\n\n brush.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant$4(!!_), brush) : filter;\n };\n\n brush.handleSize = function(_) {\n return arguments.length ? (handleSize = +_, brush) : handleSize;\n };\n\n brush.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? brush : value;\n };\n\n return brush;\n}\n\nvar cos = Math.cos;\nvar sin = Math.sin;\nvar pi$1 = Math.PI;\nvar halfPi$1 = pi$1 / 2;\nvar tau$1 = pi$1 * 2;\nvar max$1 = Math.max;\n\nfunction compareValue(compare) {\n return function(a, b) {\n return compare(\n a.source.value + a.target.value,\n b.source.value + b.target.value\n );\n };\n}\n\nfunction chord() {\n var padAngle = 0,\n sortGroups = null,\n sortSubgroups = null,\n sortChords = null;\n\n function chord(matrix) {\n var n = matrix.length,\n groupSums = [],\n groupIndex = sequence(n),\n subgroupIndex = [],\n chords = [],\n groups = chords.groups = new Array(n),\n subgroups = new Array(n * n),\n k,\n x,\n x0,\n dx,\n i,\n j;\n\n // Compute the sum.\n k = 0, i = -1; while (++i < n) {\n x = 0, j = -1; while (++j < n) {\n x += matrix[i][j];\n }\n groupSums.push(x);\n subgroupIndex.push(sequence(n));\n k += x;\n }\n\n // Sort groups…\n if (sortGroups) groupIndex.sort(function(a, b) {\n return sortGroups(groupSums[a], groupSums[b]);\n });\n\n // Sort subgroups…\n if (sortSubgroups) subgroupIndex.forEach(function(d, i) {\n d.sort(function(a, b) {\n return sortSubgroups(matrix[i][a], matrix[i][b]);\n });\n });\n\n // Convert the sum to scaling factor for [0, 2pi].\n // TODO Allow start and end angle to be specified?\n // TODO Allow padding to be specified as percentage?\n k = max$1(0, tau$1 - padAngle * n) / k;\n dx = k ? padAngle : tau$1 / n;\n\n // Compute the start and end angle for each group and subgroup.\n // Note: Opera has a bug reordering object literal properties!\n x = 0, i = -1; while (++i < n) {\n x0 = x, j = -1; while (++j < n) {\n var di = groupIndex[i],\n dj = subgroupIndex[di][j],\n v = matrix[di][dj],\n a0 = x,\n a1 = x += v * k;\n subgroups[dj * n + di] = {\n index: di,\n subindex: dj,\n startAngle: a0,\n endAngle: a1,\n value: v\n };\n }\n groups[di] = {\n index: di,\n startAngle: x0,\n endAngle: x,\n value: groupSums[di]\n };\n x += dx;\n }\n\n // Generate chords for each (non-empty) subgroup-subgroup link.\n i = -1; while (++i < n) {\n j = i - 1; while (++j < n) {\n var source = subgroups[j * n + i],\n target = subgroups[i * n + j];\n if (source.value || target.value) {\n chords.push(source.value < target.value\n ? {source: target, target: source}\n : {source: source, target: target});\n }\n }\n }\n\n return sortChords ? chords.sort(sortChords) : chords;\n }\n\n chord.padAngle = function(_) {\n return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;\n };\n\n chord.sortGroups = function(_) {\n return arguments.length ? (sortGroups = _, chord) : sortGroups;\n };\n\n chord.sortSubgroups = function(_) {\n return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;\n };\n\n chord.sortChords = function(_) {\n return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;\n };\n\n return chord;\n}\n\nvar slice$2 = Array.prototype.slice;\n\nfunction constant$5(x) {\n return function() {\n return x;\n };\n}\n\nvar pi$2 = Math.PI;\nvar tau$2 = 2 * pi$2;\nvar epsilon$1 = 1e-6;\nvar tauEpsilon = tau$2 - epsilon$1;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon$1)) {}\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon$1) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau$2 + tau$2;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon$1) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi$2)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nfunction defaultSource(d) {\n return d.source;\n}\n\nfunction defaultTarget(d) {\n return d.target;\n}\n\nfunction defaultRadius(d) {\n return d.radius;\n}\n\nfunction defaultStartAngle(d) {\n return d.startAngle;\n}\n\nfunction defaultEndAngle(d) {\n return d.endAngle;\n}\n\nfunction ribbon() {\n var source = defaultSource,\n target = defaultTarget,\n radius = defaultRadius,\n startAngle = defaultStartAngle,\n endAngle = defaultEndAngle,\n context = null;\n\n function ribbon() {\n var buffer,\n argv = slice$2.call(arguments),\n s = source.apply(this, argv),\n t = target.apply(this, argv),\n sr = +radius.apply(this, (argv[0] = s, argv)),\n sa0 = startAngle.apply(this, argv) - halfPi$1,\n sa1 = endAngle.apply(this, argv) - halfPi$1,\n sx0 = sr * cos(sa0),\n sy0 = sr * sin(sa0),\n tr = +radius.apply(this, (argv[0] = t, argv)),\n ta0 = startAngle.apply(this, argv) - halfPi$1,\n ta1 = endAngle.apply(this, argv) - halfPi$1;\n\n if (!context) context = buffer = path();\n\n context.moveTo(sx0, sy0);\n context.arc(0, 0, sr, sa0, sa1);\n if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?\n context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));\n context.arc(0, 0, tr, ta0, ta1);\n }\n context.quadraticCurveTo(0, 0, sx0, sy0);\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n ribbon.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$5(+_), ribbon) : radius;\n };\n\n ribbon.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant$5(+_), ribbon) : startAngle;\n };\n\n ribbon.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant$5(+_), ribbon) : endAngle;\n };\n\n ribbon.source = function(_) {\n return arguments.length ? (source = _, ribbon) : source;\n };\n\n ribbon.target = function(_) {\n return arguments.length ? (target = _, ribbon) : target;\n };\n\n ribbon.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, ribbon) : context;\n };\n\n return ribbon;\n}\n\nvar prefix = \"$\";\n\nfunction Map() {}\n\nMap.prototype = map$1.prototype = {\n constructor: Map,\n has: function(key) {\n return (prefix + key) in this;\n },\n get: function(key) {\n return this[prefix + key];\n },\n set: function(key, value) {\n this[prefix + key] = value;\n return this;\n },\n remove: function(key) {\n var property = prefix + key;\n return property in this && delete this[property];\n },\n clear: function() {\n for (var property in this) if (property[0] === prefix) delete this[property];\n },\n keys: function() {\n var keys = [];\n for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));\n return keys;\n },\n values: function() {\n var values = [];\n for (var property in this) if (property[0] === prefix) values.push(this[property]);\n return values;\n },\n entries: function() {\n var entries = [];\n for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});\n return entries;\n },\n size: function() {\n var size = 0;\n for (var property in this) if (property[0] === prefix) ++size;\n return size;\n },\n empty: function() {\n for (var property in this) if (property[0] === prefix) return false;\n return true;\n },\n each: function(f) {\n for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);\n }\n};\n\nfunction map$1(object, f) {\n var map = new Map;\n\n // Copy constructor.\n if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });\n\n // Index array by numeric index or specified key function.\n else if (Array.isArray(object)) {\n var i = -1,\n n = object.length,\n o;\n\n if (f == null) while (++i < n) map.set(i, object[i]);\n else while (++i < n) map.set(f(o = object[i], i, object), o);\n }\n\n // Convert object to map.\n else if (object) for (var key in object) map.set(key, object[key]);\n\n return map;\n}\n\nfunction nest() {\n var keys = [],\n sortKeys = [],\n sortValues,\n rollup,\n nest;\n\n function apply(array, depth, createResult, setResult) {\n if (depth >= keys.length) {\n if (sortValues != null) array.sort(sortValues);\n return rollup != null ? rollup(array) : array;\n }\n\n var i = -1,\n n = array.length,\n key = keys[depth++],\n keyValue,\n value,\n valuesByKey = map$1(),\n values,\n result = createResult();\n\n while (++i < n) {\n if (values = valuesByKey.get(keyValue = key(value = array[i]) + \"\")) {\n values.push(value);\n } else {\n valuesByKey.set(keyValue, [value]);\n }\n }\n\n valuesByKey.each(function(values, key) {\n setResult(result, key, apply(values, depth, createResult, setResult));\n });\n\n return result;\n }\n\n function entries(map, depth) {\n if (++depth > keys.length) return map;\n var array, sortKey = sortKeys[depth - 1];\n if (rollup != null && depth >= keys.length) array = map.entries();\n else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });\n return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;\n }\n\n return nest = {\n object: function(array) { return apply(array, 0, createObject, setObject); },\n map: function(array) { return apply(array, 0, createMap, setMap); },\n entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },\n key: function(d) { keys.push(d); return nest; },\n sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },\n sortValues: function(order) { sortValues = order; return nest; },\n rollup: function(f) { rollup = f; return nest; }\n };\n}\n\nfunction createObject() {\n return {};\n}\n\nfunction setObject(object, key, value) {\n object[key] = value;\n}\n\nfunction createMap() {\n return map$1();\n}\n\nfunction setMap(map, key, value) {\n map.set(key, value);\n}\n\nfunction Set() {}\n\nvar proto = map$1.prototype;\n\nSet.prototype = set$2.prototype = {\n constructor: Set,\n has: proto.has,\n add: function(value) {\n value += \"\";\n this[prefix + value] = value;\n return this;\n },\n remove: proto.remove,\n clear: proto.clear,\n values: proto.keys,\n size: proto.size,\n empty: proto.empty,\n each: proto.each\n};\n\nfunction set$2(object, f) {\n var set = new Set;\n\n // Copy constructor.\n if (object instanceof Set) object.each(function(value) { set.add(value); });\n\n // Otherwise, assume it’s an array.\n else if (object) {\n var i = -1, n = object.length;\n if (f == null) while (++i < n) set.add(object[i]);\n else while (++i < n) set.add(f(object[i], i, object));\n }\n\n return set;\n}\n\nfunction keys(map) {\n var keys = [];\n for (var key in map) keys.push(key);\n return keys;\n}\n\nfunction values(map) {\n var values = [];\n for (var key in map) values.push(map[key]);\n return values;\n}\n\nfunction entries(map) {\n var entries = [];\n for (var key in map) entries.push({key: key, value: map[key]});\n return entries;\n}\n\nvar EOL = {};\nvar EOF = {};\nvar QUOTE = 34;\nvar NEWLINE = 10;\nvar RETURN = 13;\n\nfunction objectConverter(columns) {\n return new Function(\"d\", \"return {\" + columns.map(function(name, i) {\n return JSON.stringify(name) + \": d[\" + i + \"]\";\n }).join(\",\") + \"}\");\n}\n\nfunction customConverter(columns, f) {\n var object = objectConverter(columns);\n return function(row, i) {\n return f(object(row), i, columns);\n };\n}\n\n// Compute unique columns in order of discovery.\nfunction inferColumns(rows) {\n var columnSet = Object.create(null),\n columns = [];\n\n rows.forEach(function(row) {\n for (var column in row) {\n if (!(column in columnSet)) {\n columns.push(columnSet[column] = column);\n }\n }\n });\n\n return columns;\n}\n\nfunction dsv(delimiter) {\n var reFormat = new RegExp(\"[\\\"\" + delimiter + \"\\n\\r]\"),\n DELIMITER = delimiter.charCodeAt(0);\n\n function parse(text, f) {\n var convert, columns, rows = parseRows(text, function(row, i) {\n if (convert) return convert(row, i - 1);\n columns = row, convert = f ? customConverter(row, f) : objectConverter(row);\n });\n rows.columns = columns || [];\n return rows;\n }\n\n function parseRows(text, f) {\n var rows = [], // output rows\n N = text.length,\n I = 0, // current character index\n n = 0, // current line number\n t, // current token\n eof = N <= 0, // current token followed by EOF?\n eol = false; // current token followed by EOL?\n\n // Strip the trailing newline.\n if (text.charCodeAt(N - 1) === NEWLINE) --N;\n if (text.charCodeAt(N - 1) === RETURN) --N;\n\n function token() {\n if (eof) return EOF;\n if (eol) return eol = false, EOL;\n\n // Unescape quotes.\n var i, j = I, c;\n if (text.charCodeAt(j) === QUOTE) {\n while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);\n if ((i = I) >= N) eof = true;\n else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n return text.slice(j + 1, i - 1).replace(/\"\"/g, \"\\\"\");\n }\n\n // Find next delimiter or newline.\n while (I < N) {\n if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n else if (c !== DELIMITER) continue;\n return text.slice(j, i);\n }\n\n // Return last token before EOF.\n return eof = true, text.slice(j, N);\n }\n\n while ((t = token()) !== EOF) {\n var row = [];\n while (t !== EOL && t !== EOF) row.push(t), t = token();\n if (f && (row = f(row, n++)) == null) continue;\n rows.push(row);\n }\n\n return rows;\n }\n\n function format(rows, columns) {\n if (columns == null) columns = inferColumns(rows);\n return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {\n return columns.map(function(column) {\n return formatValue(row[column]);\n }).join(delimiter);\n })).join(\"\\n\");\n }\n\n function formatRows(rows) {\n return rows.map(formatRow).join(\"\\n\");\n }\n\n function formatRow(row) {\n return row.map(formatValue).join(delimiter);\n }\n\n function formatValue(text) {\n return text == null ? \"\"\n : reFormat.test(text += \"\") ? \"\\\"\" + text.replace(/\"/g, \"\\\"\\\"\") + \"\\\"\"\n : text;\n }\n\n return {\n parse: parse,\n parseRows: parseRows,\n format: format,\n formatRows: formatRows\n };\n}\n\nvar csv = dsv(\",\");\n\nvar csvParse = csv.parse;\nvar csvParseRows = csv.parseRows;\nvar csvFormat = csv.format;\nvar csvFormatRows = csv.formatRows;\n\nvar tsv = dsv(\"\\t\");\n\nvar tsvParse = tsv.parse;\nvar tsvParseRows = tsv.parseRows;\nvar tsvFormat = tsv.format;\nvar tsvFormatRows = tsv.formatRows;\n\nfunction center$1(x, y) {\n var nodes;\n\n if (x == null) x = 0;\n if (y == null) y = 0;\n\n function force() {\n var i,\n n = nodes.length,\n node,\n sx = 0,\n sy = 0;\n\n for (i = 0; i < n; ++i) {\n node = nodes[i], sx += node.x, sy += node.y;\n }\n\n for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {\n node = nodes[i], node.x -= sx, node.y -= sy;\n }\n }\n\n force.initialize = function(_) {\n nodes = _;\n };\n\n force.x = function(_) {\n return arguments.length ? (x = +_, force) : x;\n };\n\n force.y = function(_) {\n return arguments.length ? (y = +_, force) : y;\n };\n\n return force;\n}\n\nfunction constant$6(x) {\n return function() {\n return x;\n };\n}\n\nfunction jiggle() {\n return (Math.random() - 0.5) * 1e-6;\n}\n\nfunction tree_add(d) {\n var x = +this._x.call(null, d),\n y = +this._y.call(null, d);\n return add(this.cover(x, y), x, y, d);\n}\n\nfunction add(tree, x, y, d) {\n if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points\n\n var parent,\n node = tree._root,\n leaf = {data: d},\n x0 = tree._x0,\n y0 = tree._y0,\n x1 = tree._x1,\n y1 = tree._y1,\n xm,\n ym,\n xp,\n yp,\n right,\n bottom,\n i,\n j;\n\n // If the tree is empty, initialize the root as a leaf.\n if (!node) return tree._root = leaf, tree;\n\n // Find the existing leaf for the new point, or add it.\n while (node.length) {\n if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;\n if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;\n if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;\n }\n\n // Is the new point is exactly coincident with the existing point?\n xp = +tree._x.call(null, node.data);\n yp = +tree._y.call(null, node.data);\n if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;\n\n // Otherwise, split the leaf node until the old and new point are separated.\n do {\n parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);\n if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;\n if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;\n } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));\n return parent[j] = node, parent[i] = leaf, tree;\n}\n\nfunction addAll(data) {\n var d, i, n = data.length,\n x,\n y,\n xz = new Array(n),\n yz = new Array(n),\n x0 = Infinity,\n y0 = Infinity,\n x1 = -Infinity,\n y1 = -Infinity;\n\n // Compute the points and their extent.\n for (i = 0; i < n; ++i) {\n if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;\n xz[i] = x;\n yz[i] = y;\n if (x < x0) x0 = x;\n if (x > x1) x1 = x;\n if (y < y0) y0 = y;\n if (y > y1) y1 = y;\n }\n\n // If there were no (valid) points, inherit the existing extent.\n if (x1 < x0) x0 = this._x0, x1 = this._x1;\n if (y1 < y0) y0 = this._y0, y1 = this._y1;\n\n // Expand the tree to cover the new points.\n this.cover(x0, y0).cover(x1, y1);\n\n // Add the new points.\n for (i = 0; i < n; ++i) {\n add(this, xz[i], yz[i], data[i]);\n }\n\n return this;\n}\n\nfunction tree_cover(x, y) {\n if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points\n\n var x0 = this._x0,\n y0 = this._y0,\n x1 = this._x1,\n y1 = this._y1;\n\n // If the quadtree has no extent, initialize them.\n // Integer extent are necessary so that if we later double the extent,\n // the existing quadrant boundaries don’t change due to floating point error!\n if (isNaN(x0)) {\n x1 = (x0 = Math.floor(x)) + 1;\n y1 = (y0 = Math.floor(y)) + 1;\n }\n\n // Otherwise, double repeatedly to cover.\n else if (x0 > x || x > x1 || y0 > y || y > y1) {\n var z = x1 - x0,\n node = this._root,\n parent,\n i;\n\n switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {\n case 0: {\n do parent = new Array(4), parent[i] = node, node = parent;\n while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);\n break;\n }\n case 1: {\n do parent = new Array(4), parent[i] = node, node = parent;\n while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);\n break;\n }\n case 2: {\n do parent = new Array(4), parent[i] = node, node = parent;\n while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);\n break;\n }\n case 3: {\n do parent = new Array(4), parent[i] = node, node = parent;\n while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);\n break;\n }\n }\n\n if (this._root && this._root.length) this._root = node;\n }\n\n // If the quadtree covers the point already, just return.\n else return this;\n\n this._x0 = x0;\n this._y0 = y0;\n this._x1 = x1;\n this._y1 = y1;\n return this;\n}\n\nfunction tree_data() {\n var data = [];\n this.visit(function(node) {\n if (!node.length) do data.push(node.data); while (node = node.next)\n });\n return data;\n}\n\nfunction tree_extent(_) {\n return arguments.length\n ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])\n : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];\n}\n\nfunction Quad(node, x0, y0, x1, y1) {\n this.node = node;\n this.x0 = x0;\n this.y0 = y0;\n this.x1 = x1;\n this.y1 = y1;\n}\n\nfunction tree_find(x, y, radius) {\n var data,\n x0 = this._x0,\n y0 = this._y0,\n x1,\n y1,\n x2,\n y2,\n x3 = this._x1,\n y3 = this._y1,\n quads = [],\n node = this._root,\n q,\n i;\n\n if (node) quads.push(new Quad(node, x0, y0, x3, y3));\n if (radius == null) radius = Infinity;\n else {\n x0 = x - radius, y0 = y - radius;\n x3 = x + radius, y3 = y + radius;\n radius *= radius;\n }\n\n while (q = quads.pop()) {\n\n // Stop searching if this quadrant can’t contain a closer node.\n if (!(node = q.node)\n || (x1 = q.x0) > x3\n || (y1 = q.y0) > y3\n || (x2 = q.x1) < x0\n || (y2 = q.y1) < y0) continue;\n\n // Bisect the current quadrant.\n if (node.length) {\n var xm = (x1 + x2) / 2,\n ym = (y1 + y2) / 2;\n\n quads.push(\n new Quad(node[3], xm, ym, x2, y2),\n new Quad(node[2], x1, ym, xm, y2),\n new Quad(node[1], xm, y1, x2, ym),\n new Quad(node[0], x1, y1, xm, ym)\n );\n\n // Visit the closest quadrant first.\n if (i = (y >= ym) << 1 | (x >= xm)) {\n q = quads[quads.length - 1];\n quads[quads.length - 1] = quads[quads.length - 1 - i];\n quads[quads.length - 1 - i] = q;\n }\n }\n\n // Visit this point. (Visiting coincident points isn’t necessary!)\n else {\n var dx = x - +this._x.call(null, node.data),\n dy = y - +this._y.call(null, node.data),\n d2 = dx * dx + dy * dy;\n if (d2 < radius) {\n var d = Math.sqrt(radius = d2);\n x0 = x - d, y0 = y - d;\n x3 = x + d, y3 = y + d;\n data = node.data;\n }\n }\n }\n\n return data;\n}\n\nfunction tree_remove(d) {\n if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points\n\n var parent,\n node = this._root,\n retainer,\n previous,\n next,\n x0 = this._x0,\n y0 = this._y0,\n x1 = this._x1,\n y1 = this._y1,\n x,\n y,\n xm,\n ym,\n right,\n bottom,\n i,\n j;\n\n // If the tree is empty, initialize the root as a leaf.\n if (!node) return this;\n\n // Find the leaf node for the point.\n // While descending, also retain the deepest parent with a non-removed sibling.\n if (node.length) while (true) {\n if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;\n if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;\n if (!(parent = node, node = node[i = bottom << 1 | right])) return this;\n if (!node.length) break;\n if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;\n }\n\n // Find the point to remove.\n while (node.data !== d) if (!(previous = node, node = node.next)) return this;\n if (next = node.next) delete node.next;\n\n // If there are multiple coincident points, remove just the point.\n if (previous) return next ? previous.next = next : delete previous.next, this;\n\n // If this is the root point, remove it.\n if (!parent) return this._root = next, this;\n\n // Remove this leaf.\n next ? parent[i] = next : delete parent[i];\n\n // If the parent now contains exactly one leaf, collapse superfluous parents.\n if ((node = parent[0] || parent[1] || parent[2] || parent[3])\n && node === (parent[3] || parent[2] || parent[1] || parent[0])\n && !node.length) {\n if (retainer) retainer[j] = node;\n else this._root = node;\n }\n\n return this;\n}\n\nfunction removeAll(data) {\n for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);\n return this;\n}\n\nfunction tree_root() {\n return this._root;\n}\n\nfunction tree_size() {\n var size = 0;\n this.visit(function(node) {\n if (!node.length) do ++size; while (node = node.next)\n });\n return size;\n}\n\nfunction tree_visit(callback) {\n var quads = [], q, node = this._root, child, x0, y0, x1, y1;\n if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));\n while (q = quads.pop()) {\n if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {\n var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;\n if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));\n if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));\n if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));\n if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));\n }\n }\n return this;\n}\n\nfunction tree_visitAfter(callback) {\n var quads = [], next = [], q;\n if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));\n while (q = quads.pop()) {\n var node = q.node;\n if (node.length) {\n var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;\n if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));\n if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));\n if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));\n if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));\n }\n next.push(q);\n }\n while (q = next.pop()) {\n callback(q.node, q.x0, q.y0, q.x1, q.y1);\n }\n return this;\n}\n\nfunction defaultX(d) {\n return d[0];\n}\n\nfunction tree_x(_) {\n return arguments.length ? (this._x = _, this) : this._x;\n}\n\nfunction defaultY(d) {\n return d[1];\n}\n\nfunction tree_y(_) {\n return arguments.length ? (this._y = _, this) : this._y;\n}\n\nfunction quadtree(nodes, x, y) {\n var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);\n return nodes == null ? tree : tree.addAll(nodes);\n}\n\nfunction Quadtree(x, y, x0, y0, x1, y1) {\n this._x = x;\n this._y = y;\n this._x0 = x0;\n this._y0 = y0;\n this._x1 = x1;\n this._y1 = y1;\n this._root = undefined;\n}\n\nfunction leaf_copy(leaf) {\n var copy = {data: leaf.data}, next = copy;\n while (leaf = leaf.next) next = next.next = {data: leaf.data};\n return copy;\n}\n\nvar treeProto = quadtree.prototype = Quadtree.prototype;\n\ntreeProto.copy = function() {\n var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),\n node = this._root,\n nodes,\n child;\n\n if (!node) return copy;\n\n if (!node.length) return copy._root = leaf_copy(node), copy;\n\n nodes = [{source: node, target: copy._root = new Array(4)}];\n while (node = nodes.pop()) {\n for (var i = 0; i < 4; ++i) {\n if (child = node.source[i]) {\n if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});\n else node.target[i] = leaf_copy(child);\n }\n }\n }\n\n return copy;\n};\n\ntreeProto.add = tree_add;\ntreeProto.addAll = addAll;\ntreeProto.cover = tree_cover;\ntreeProto.data = tree_data;\ntreeProto.extent = tree_extent;\ntreeProto.find = tree_find;\ntreeProto.remove = tree_remove;\ntreeProto.removeAll = removeAll;\ntreeProto.root = tree_root;\ntreeProto.size = tree_size;\ntreeProto.visit = tree_visit;\ntreeProto.visitAfter = tree_visitAfter;\ntreeProto.x = tree_x;\ntreeProto.y = tree_y;\n\nfunction x(d) {\n return d.x + d.vx;\n}\n\nfunction y(d) {\n return d.y + d.vy;\n}\n\nfunction collide(radius) {\n var nodes,\n radii,\n strength = 1,\n iterations = 1;\n\n if (typeof radius !== \"function\") radius = constant$6(radius == null ? 1 : +radius);\n\n function force() {\n var i, n = nodes.length,\n tree,\n node,\n xi,\n yi,\n ri,\n ri2;\n\n for (var k = 0; k < iterations; ++k) {\n tree = quadtree(nodes, x, y).visitAfter(prepare);\n for (i = 0; i < n; ++i) {\n node = nodes[i];\n ri = radii[node.index], ri2 = ri * ri;\n xi = node.x + node.vx;\n yi = node.y + node.vy;\n tree.visit(apply);\n }\n }\n\n function apply(quad, x0, y0, x1, y1) {\n var data = quad.data, rj = quad.r, r = ri + rj;\n if (data) {\n if (data.index > node.index) {\n var x = xi - data.x - data.vx,\n y = yi - data.y - data.vy,\n l = x * x + y * y;\n if (l < r * r) {\n if (x === 0) x = jiggle(), l += x * x;\n if (y === 0) y = jiggle(), l += y * y;\n l = (r - (l = Math.sqrt(l))) / l * strength;\n node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));\n node.vy += (y *= l) * r;\n data.vx -= x * (r = 1 - r);\n data.vy -= y * r;\n }\n }\n return;\n }\n return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;\n }\n }\n\n function prepare(quad) {\n if (quad.data) return quad.r = radii[quad.data.index];\n for (var i = quad.r = 0; i < 4; ++i) {\n if (quad[i] && quad[i].r > quad.r) {\n quad.r = quad[i].r;\n }\n }\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length, node;\n radii = new Array(n);\n for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.iterations = function(_) {\n return arguments.length ? (iterations = +_, force) : iterations;\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = +_, force) : strength;\n };\n\n force.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : radius;\n };\n\n return force;\n}\n\nfunction index(d) {\n return d.index;\n}\n\nfunction find(nodeById, nodeId) {\n var node = nodeById.get(nodeId);\n if (!node) throw new Error(\"missing: \" + nodeId);\n return node;\n}\n\nfunction link(links) {\n var id = index,\n strength = defaultStrength,\n strengths,\n distance = constant$6(30),\n distances,\n nodes,\n count,\n bias,\n iterations = 1;\n\n if (links == null) links = [];\n\n function defaultStrength(link) {\n return 1 / Math.min(count[link.source.index], count[link.target.index]);\n }\n\n function force(alpha) {\n for (var k = 0, n = links.length; k < iterations; ++k) {\n for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {\n link = links[i], source = link.source, target = link.target;\n x = target.x + target.vx - source.x - source.vx || jiggle();\n y = target.y + target.vy - source.y - source.vy || jiggle();\n l = Math.sqrt(x * x + y * y);\n l = (l - distances[i]) / l * alpha * strengths[i];\n x *= l, y *= l;\n target.vx -= x * (b = bias[i]);\n target.vy -= y * b;\n source.vx += x * (b = 1 - b);\n source.vy += y * b;\n }\n }\n }\n\n function initialize() {\n if (!nodes) return;\n\n var i,\n n = nodes.length,\n m = links.length,\n nodeById = map$1(nodes, id),\n link;\n\n for (i = 0, count = new Array(n); i < m; ++i) {\n link = links[i], link.index = i;\n if (typeof link.source !== \"object\") link.source = find(nodeById, link.source);\n if (typeof link.target !== \"object\") link.target = find(nodeById, link.target);\n count[link.source.index] = (count[link.source.index] || 0) + 1;\n count[link.target.index] = (count[link.target.index] || 0) + 1;\n }\n\n for (i = 0, bias = new Array(m); i < m; ++i) {\n link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);\n }\n\n strengths = new Array(m), initializeStrength();\n distances = new Array(m), initializeDistance();\n }\n\n function initializeStrength() {\n if (!nodes) return;\n\n for (var i = 0, n = links.length; i < n; ++i) {\n strengths[i] = +strength(links[i], i, links);\n }\n }\n\n function initializeDistance() {\n if (!nodes) return;\n\n for (var i = 0, n = links.length; i < n; ++i) {\n distances[i] = +distance(links[i], i, links);\n }\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.links = function(_) {\n return arguments.length ? (links = _, initialize(), force) : links;\n };\n\n force.id = function(_) {\n return arguments.length ? (id = _, force) : id;\n };\n\n force.iterations = function(_) {\n return arguments.length ? (iterations = +_, force) : iterations;\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initializeStrength(), force) : strength;\n };\n\n force.distance = function(_) {\n return arguments.length ? (distance = typeof _ === \"function\" ? _ : constant$6(+_), initializeDistance(), force) : distance;\n };\n\n return force;\n}\n\nfunction x$1(d) {\n return d.x;\n}\n\nfunction y$1(d) {\n return d.y;\n}\n\nvar initialRadius = 10;\nvar initialAngle = Math.PI * (3 - Math.sqrt(5));\n\nfunction simulation(nodes) {\n var simulation,\n alpha = 1,\n alphaMin = 0.001,\n alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),\n alphaTarget = 0,\n velocityDecay = 0.6,\n forces = map$1(),\n stepper = timer(step),\n event = dispatch(\"tick\", \"end\");\n\n if (nodes == null) nodes = [];\n\n function step() {\n tick();\n event.call(\"tick\", simulation);\n if (alpha < alphaMin) {\n stepper.stop();\n event.call(\"end\", simulation);\n }\n }\n\n function tick() {\n var i, n = nodes.length, node;\n\n alpha += (alphaTarget - alpha) * alphaDecay;\n\n forces.each(function(force) {\n force(alpha);\n });\n\n for (i = 0; i < n; ++i) {\n node = nodes[i];\n if (node.fx == null) node.x += node.vx *= velocityDecay;\n else node.x = node.fx, node.vx = 0;\n if (node.fy == null) node.y += node.vy *= velocityDecay;\n else node.y = node.fy, node.vy = 0;\n }\n }\n\n function initializeNodes() {\n for (var i = 0, n = nodes.length, node; i < n; ++i) {\n node = nodes[i], node.index = i;\n if (isNaN(node.x) || isNaN(node.y)) {\n var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;\n node.x = radius * Math.cos(angle);\n node.y = radius * Math.sin(angle);\n }\n if (isNaN(node.vx) || isNaN(node.vy)) {\n node.vx = node.vy = 0;\n }\n }\n }\n\n function initializeForce(force) {\n if (force.initialize) force.initialize(nodes);\n return force;\n }\n\n initializeNodes();\n\n return simulation = {\n tick: tick,\n\n restart: function() {\n return stepper.restart(step), simulation;\n },\n\n stop: function() {\n return stepper.stop(), simulation;\n },\n\n nodes: function(_) {\n return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;\n },\n\n alpha: function(_) {\n return arguments.length ? (alpha = +_, simulation) : alpha;\n },\n\n alphaMin: function(_) {\n return arguments.length ? (alphaMin = +_, simulation) : alphaMin;\n },\n\n alphaDecay: function(_) {\n return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;\n },\n\n alphaTarget: function(_) {\n return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;\n },\n\n velocityDecay: function(_) {\n return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;\n },\n\n force: function(name, _) {\n return arguments.length > 1 ? (_ == null ? forces.remove(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name);\n },\n\n find: function(x, y, radius) {\n var i = 0,\n n = nodes.length,\n dx,\n dy,\n d2,\n node,\n closest;\n\n if (radius == null) radius = Infinity;\n else radius *= radius;\n\n for (i = 0; i < n; ++i) {\n node = nodes[i];\n dx = x - node.x;\n dy = y - node.y;\n d2 = dx * dx + dy * dy;\n if (d2 < radius) closest = node, radius = d2;\n }\n\n return closest;\n },\n\n on: function(name, _) {\n return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);\n }\n };\n}\n\nfunction manyBody() {\n var nodes,\n node,\n alpha,\n strength = constant$6(-30),\n strengths,\n distanceMin2 = 1,\n distanceMax2 = Infinity,\n theta2 = 0.81;\n\n function force(_) {\n var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate);\n for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length, node;\n strengths = new Array(n);\n for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);\n }\n\n function accumulate(quad) {\n var strength = 0, q, c, weight = 0, x, y, i;\n\n // For internal nodes, accumulate forces from child quadrants.\n if (quad.length) {\n for (x = y = i = 0; i < 4; ++i) {\n if ((q = quad[i]) && (c = Math.abs(q.value))) {\n strength += q.value, weight += c, x += c * q.x, y += c * q.y;\n }\n }\n quad.x = x / weight;\n quad.y = y / weight;\n }\n\n // For leaf nodes, accumulate forces from coincident quadrants.\n else {\n q = quad;\n q.x = q.data.x;\n q.y = q.data.y;\n do strength += strengths[q.data.index];\n while (q = q.next);\n }\n\n quad.value = strength;\n }\n\n function apply(quad, x1, _, x2) {\n if (!quad.value) return true;\n\n var x = quad.x - node.x,\n y = quad.y - node.y,\n w = x2 - x1,\n l = x * x + y * y;\n\n // Apply the Barnes-Hut approximation if possible.\n // Limit forces for very close nodes; randomize direction if coincident.\n if (w * w / theta2 < l) {\n if (l < distanceMax2) {\n if (x === 0) x = jiggle(), l += x * x;\n if (y === 0) y = jiggle(), l += y * y;\n if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);\n node.vx += x * quad.value * alpha / l;\n node.vy += y * quad.value * alpha / l;\n }\n return true;\n }\n\n // Otherwise, process points directly.\n else if (quad.length || l >= distanceMax2) return;\n\n // Limit forces for very close nodes; randomize direction if coincident.\n if (quad.data !== node || quad.next) {\n if (x === 0) x = jiggle(), l += x * x;\n if (y === 0) y = jiggle(), l += y * y;\n if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);\n }\n\n do if (quad.data !== node) {\n w = strengths[quad.data.index] * alpha / l;\n node.vx += x * w;\n node.vy += y * w;\n } while (quad = quad.next);\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n };\n\n force.distanceMin = function(_) {\n return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);\n };\n\n force.distanceMax = function(_) {\n return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);\n };\n\n force.theta = function(_) {\n return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);\n };\n\n return force;\n}\n\nfunction radial(radius, x, y) {\n var nodes,\n strength = constant$6(0.1),\n strengths,\n radiuses;\n\n if (typeof radius !== \"function\") radius = constant$6(+radius);\n if (x == null) x = 0;\n if (y == null) y = 0;\n\n function force(alpha) {\n for (var i = 0, n = nodes.length; i < n; ++i) {\n var node = nodes[i],\n dx = node.x - x || 1e-6,\n dy = node.y - y || 1e-6,\n r = Math.sqrt(dx * dx + dy * dy),\n k = (radiuses[i] - r) * strengths[i] * alpha / r;\n node.vx += dx * k;\n node.vy += dy * k;\n }\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length;\n strengths = new Array(n);\n radiuses = new Array(n);\n for (i = 0; i < n; ++i) {\n radiuses[i] = +radius(nodes[i], i, nodes);\n strengths[i] = isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, nodes);\n }\n }\n\n force.initialize = function(_) {\n nodes = _, initialize();\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n };\n\n force.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : radius;\n };\n\n force.x = function(_) {\n return arguments.length ? (x = +_, force) : x;\n };\n\n force.y = function(_) {\n return arguments.length ? (y = +_, force) : y;\n };\n\n return force;\n}\n\nfunction x$2(x) {\n var strength = constant$6(0.1),\n nodes,\n strengths,\n xz;\n\n if (typeof x !== \"function\") x = constant$6(x == null ? 0 : +x);\n\n function force(alpha) {\n for (var i = 0, n = nodes.length, node; i < n; ++i) {\n node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;\n }\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length;\n strengths = new Array(n);\n xz = new Array(n);\n for (i = 0; i < n; ++i) {\n strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);\n }\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n };\n\n force.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : x;\n };\n\n return force;\n}\n\nfunction y$2(y) {\n var strength = constant$6(0.1),\n nodes,\n strengths,\n yz;\n\n if (typeof y !== \"function\") y = constant$6(y == null ? 0 : +y);\n\n function force(alpha) {\n for (var i = 0, n = nodes.length, node; i < n; ++i) {\n node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;\n }\n }\n\n function initialize() {\n if (!nodes) return;\n var i, n = nodes.length;\n strengths = new Array(n);\n yz = new Array(n);\n for (i = 0; i < n; ++i) {\n strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);\n }\n }\n\n force.initialize = function(_) {\n nodes = _;\n initialize();\n };\n\n force.strength = function(_) {\n return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n };\n\n force.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : y;\n };\n\n return force;\n}\n\n// Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimal(1.23) returns [\"123\", 0].\nfunction formatDecimal(x, p) {\n if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf(\"e\")) < 0) return null; // NaN, ±Infinity\n var i, coefficient = x.slice(0, i);\n\n // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n return [\n coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,\n +x.slice(i + 1)\n ];\n}\n\nfunction exponent$1(x) {\n return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;\n}\n\nfunction formatGroup(grouping, thousands) {\n return function(value, width) {\n var i = value.length,\n t = [],\n j = 0,\n g = grouping[0],\n length = 0;\n\n while (i > 0 && g > 0) {\n if (length + g + 1 > width) g = Math.max(1, width - length);\n t.push(value.substring(i -= g, i + g));\n if ((length += g + 1) > width) break;\n g = grouping[j = (j + 1) % grouping.length];\n }\n\n return t.reverse().join(thousands);\n };\n}\n\nfunction formatNumerals(numerals) {\n return function(value) {\n return value.replace(/[0-9]/g, function(i) {\n return numerals[+i];\n });\n };\n}\n\nfunction formatDefault(x, p) {\n x = x.toPrecision(p);\n\n out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (x[i]) {\n case \".\": i0 = i1 = i; break;\n case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n case \"e\": break out;\n default: if (i0 > 0) i0 = 0; break;\n }\n }\n\n return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;\n}\n\nvar prefixExponent;\n\nfunction formatPrefixAuto(x, p) {\n var d = formatDecimal(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1],\n i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n n = coefficient.length;\n return i === n ? coefficient\n : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n\nfunction formatRounded(x, p) {\n var d = formatDecimal(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1];\n return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n}\n\nvar formatTypes = {\n \"\": formatDefault,\n \"%\": function(x, p) { return (x * 100).toFixed(p); },\n \"b\": function(x) { return Math.round(x).toString(2); },\n \"c\": function(x) { return x + \"\"; },\n \"d\": function(x) { return Math.round(x).toString(10); },\n \"e\": function(x, p) { return x.toExponential(p); },\n \"f\": function(x, p) { return x.toFixed(p); },\n \"g\": function(x, p) { return x.toPrecision(p); },\n \"o\": function(x) { return Math.round(x).toString(8); },\n \"p\": function(x, p) { return formatRounded(x * 100, p); },\n \"r\": formatRounded,\n \"s\": formatPrefixAuto,\n \"X\": function(x) { return Math.round(x).toString(16).toUpperCase(); },\n \"x\": function(x) { return Math.round(x).toString(16); }\n};\n\n// [[fill]align][sign][symbol][0][width][,][.precision][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-\\( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?([a-z%])?$/i;\n\nfunction formatSpecifier(specifier) {\n return new FormatSpecifier(specifier);\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nfunction FormatSpecifier(specifier) {\n if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n\n var match,\n fill = match[1] || \" \",\n align = match[2] || \">\",\n sign = match[3] || \"-\",\n symbol = match[4] || \"\",\n zero = !!match[5],\n width = match[6] && +match[6],\n comma = !!match[7],\n precision = match[8] && +match[8].slice(1),\n type = match[9] || \"\";\n\n // The \"n\" type is an alias for \",g\".\n if (type === \"n\") comma = true, type = \"g\";\n\n // Map invalid types to the default format.\n else if (!formatTypes[type]) type = \"\";\n\n // If zero fill is specified, padding goes after sign and before digits.\n if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n this.fill = fill;\n this.align = align;\n this.sign = sign;\n this.symbol = symbol;\n this.zero = zero;\n this.width = width;\n this.comma = comma;\n this.precision = precision;\n this.type = type;\n}\n\nFormatSpecifier.prototype.toString = function() {\n return this.fill\n + this.align\n + this.sign\n + this.symbol\n + (this.zero ? \"0\" : \"\")\n + (this.width == null ? \"\" : Math.max(1, this.width | 0))\n + (this.comma ? \",\" : \"\")\n + (this.precision == null ? \"\" : \".\" + Math.max(0, this.precision | 0))\n + this.type;\n};\n\nfunction identity$3(x) {\n return x;\n}\n\nvar prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"\\xB5\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nfunction formatLocale(locale) {\n var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,\n currency = locale.currency,\n decimal = locale.decimal,\n numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3,\n percent = locale.percent || \"%\";\n\n function newFormat(specifier) {\n specifier = formatSpecifier(specifier);\n\n var fill = specifier.fill,\n align = specifier.align,\n sign = specifier.sign,\n symbol = specifier.symbol,\n zero = specifier.zero,\n width = specifier.width,\n comma = specifier.comma,\n precision = specifier.precision,\n type = specifier.type;\n\n // Compute the prefix and suffix.\n // For SI-prefix, the suffix is lazily computed.\n var prefix = symbol === \"$\" ? currency[0] : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\",\n suffix = symbol === \"$\" ? currency[1] : /[%p]/.test(type) ? percent : \"\";\n\n // What format function should we use?\n // Is this an integer type?\n // Can this type generate exponential notation?\n var formatType = formatTypes[type],\n maybeSuffix = !type || /[defgprs%]/.test(type);\n\n // Set the default precision if not specified,\n // or clamp the specified precision to the supported range.\n // For significant precision, it must be in [1, 21].\n // For fixed precision, it must be in [0, 20].\n precision = precision == null ? (type ? 6 : 12)\n : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n : Math.max(0, Math.min(20, precision));\n\n function format(value) {\n var valuePrefix = prefix,\n valueSuffix = suffix,\n i, n, c;\n\n if (type === \"c\") {\n valueSuffix = formatType(value) + valueSuffix;\n value = \"\";\n } else {\n value = +value;\n\n // Perform the initial formatting.\n var valueNegative = value < 0;\n value = formatType(Math.abs(value), precision);\n\n // If a negative value rounds to zero during formatting, treat as positive.\n if (valueNegative && +value === 0) valueNegative = false;\n\n // Compute the prefix and suffix.\n valuePrefix = (valueNegative ? (sign === \"(\" ? sign : \"-\") : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n valueSuffix = (type === \"s\" ? prefixes[8 + prefixExponent / 3] : \"\") + valueSuffix + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n // Break the formatted value into the integer “value” part that can be\n // grouped, and fractional or exponential “suffix” part that is not.\n if (maybeSuffix) {\n i = -1, n = value.length;\n while (++i < n) {\n if (c = value.charCodeAt(i), 48 > c || c > 57) {\n valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n value = value.slice(0, i);\n break;\n }\n }\n }\n }\n\n // If the fill character is not \"0\", grouping is applied before padding.\n if (comma && !zero) value = group(value, Infinity);\n\n // Compute the padding.\n var length = valuePrefix.length + value.length + valueSuffix.length,\n padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n // If the fill character is \"0\", grouping is applied after padding.\n if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n // Reconstruct the final output based on the desired alignment.\n switch (align) {\n case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n default: value = padding + valuePrefix + value + valueSuffix; break;\n }\n\n return numerals(value);\n }\n\n format.toString = function() {\n return specifier + \"\";\n };\n\n return format;\n }\n\n function formatPrefix(specifier, value) {\n var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier)),\n e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,\n k = Math.pow(10, -e),\n prefix = prefixes[8 + e / 3];\n return function(value) {\n return f(k * value) + prefix;\n };\n }\n\n return {\n format: newFormat,\n formatPrefix: formatPrefix\n };\n}\n\nvar locale;\n\n\n\ndefaultLocale({\n decimal: \".\",\n thousands: \",\",\n grouping: [3],\n currency: [\"$\", \"\"]\n});\n\nfunction defaultLocale(definition) {\n locale = formatLocale(definition);\n exports.format = locale.format;\n exports.formatPrefix = locale.formatPrefix;\n return locale;\n}\n\nfunction precisionFixed(step) {\n return Math.max(0, -exponent$1(Math.abs(step)));\n}\n\nfunction precisionPrefix(step, value) {\n return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));\n}\n\nfunction precisionRound(step, max) {\n step = Math.abs(step), max = Math.abs(max) - step;\n return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;\n}\n\n// Adds floating point numbers with twice the normal precision.\n// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and\n// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)\n// 305–363 (1997).\n// Code adapted from GeographicLib by Charles F. F. Karney,\n// http://geographiclib.sourceforge.net/\n\nfunction adder() {\n return new Adder;\n}\n\nfunction Adder() {\n this.reset();\n}\n\nAdder.prototype = {\n constructor: Adder,\n reset: function() {\n this.s = // rounded value\n this.t = 0; // exact error\n },\n add: function(y) {\n add$1(temp, y, this.t);\n add$1(this, temp.s, this.s);\n if (this.s) this.t += temp.t;\n else this.s = temp.t;\n },\n valueOf: function() {\n return this.s;\n }\n};\n\nvar temp = new Adder;\n\nfunction add$1(adder, a, b) {\n var x = adder.s = a + b,\n bv = x - a,\n av = x - bv;\n adder.t = (a - av) + (b - bv);\n}\n\nvar epsilon$2 = 1e-6;\nvar epsilon2$1 = 1e-12;\nvar pi$3 = Math.PI;\nvar halfPi$2 = pi$3 / 2;\nvar quarterPi = pi$3 / 4;\nvar tau$3 = pi$3 * 2;\n\nvar degrees$1 = 180 / pi$3;\nvar radians = pi$3 / 180;\n\nvar abs = Math.abs;\nvar atan = Math.atan;\nvar atan2 = Math.atan2;\nvar cos$1 = Math.cos;\nvar ceil = Math.ceil;\nvar exp = Math.exp;\n\nvar log = Math.log;\nvar pow = Math.pow;\nvar sin$1 = Math.sin;\nvar sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };\nvar sqrt = Math.sqrt;\nvar tan = Math.tan;\n\nfunction acos(x) {\n return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);\n}\n\nfunction asin(x) {\n return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);\n}\n\nfunction haversin(x) {\n return (x = sin$1(x / 2)) * x;\n}\n\nfunction noop$1() {}\n\nfunction streamGeometry(geometry, stream) {\n if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {\n streamGeometryType[geometry.type](geometry, stream);\n }\n}\n\nvar streamObjectType = {\n Feature: function(object, stream) {\n streamGeometry(object.geometry, stream);\n },\n FeatureCollection: function(object, stream) {\n var features = object.features, i = -1, n = features.length;\n while (++i < n) streamGeometry(features[i].geometry, stream);\n }\n};\n\nvar streamGeometryType = {\n Sphere: function(object, stream) {\n stream.sphere();\n },\n Point: function(object, stream) {\n object = object.coordinates;\n stream.point(object[0], object[1], object[2]);\n },\n MultiPoint: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);\n },\n LineString: function(object, stream) {\n streamLine(object.coordinates, stream, 0);\n },\n MultiLineString: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) streamLine(coordinates[i], stream, 0);\n },\n Polygon: function(object, stream) {\n streamPolygon(object.coordinates, stream);\n },\n MultiPolygon: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) streamPolygon(coordinates[i], stream);\n },\n GeometryCollection: function(object, stream) {\n var geometries = object.geometries, i = -1, n = geometries.length;\n while (++i < n) streamGeometry(geometries[i], stream);\n }\n};\n\nfunction streamLine(coordinates, stream, closed) {\n var i = -1, n = coordinates.length - closed, coordinate;\n stream.lineStart();\n while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);\n stream.lineEnd();\n}\n\nfunction streamPolygon(coordinates, stream) {\n var i = -1, n = coordinates.length;\n stream.polygonStart();\n while (++i < n) streamLine(coordinates[i], stream, 1);\n stream.polygonEnd();\n}\n\nfunction geoStream(object, stream) {\n if (object && streamObjectType.hasOwnProperty(object.type)) {\n streamObjectType[object.type](object, stream);\n } else {\n streamGeometry(object, stream);\n }\n}\n\nvar areaRingSum = adder();\n\nvar areaSum = adder();\nvar lambda00;\nvar phi00;\nvar lambda0;\nvar cosPhi0;\nvar sinPhi0;\n\nvar areaStream = {\n point: noop$1,\n lineStart: noop$1,\n lineEnd: noop$1,\n polygonStart: function() {\n areaRingSum.reset();\n areaStream.lineStart = areaRingStart;\n areaStream.lineEnd = areaRingEnd;\n },\n polygonEnd: function() {\n var areaRing = +areaRingSum;\n areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);\n this.lineStart = this.lineEnd = this.point = noop$1;\n },\n sphere: function() {\n areaSum.add(tau$3);\n }\n};\n\nfunction areaRingStart() {\n areaStream.point = areaPointFirst;\n}\n\nfunction areaRingEnd() {\n areaPoint(lambda00, phi00);\n}\n\nfunction areaPointFirst(lambda, phi) {\n areaStream.point = areaPoint;\n lambda00 = lambda, phi00 = phi;\n lambda *= radians, phi *= radians;\n lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);\n}\n\nfunction areaPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n phi = phi / 2 + quarterPi; // half the angular distance from south pole\n\n // Spherical excess E for a spherical triangle with vertices: south pole,\n // previous point, current point. Uses a formula derived from Cagnoli’s\n // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).\n var dLambda = lambda - lambda0,\n sdLambda = dLambda >= 0 ? 1 : -1,\n adLambda = sdLambda * dLambda,\n cosPhi = cos$1(phi),\n sinPhi = sin$1(phi),\n k = sinPhi0 * sinPhi,\n u = cosPhi0 * cosPhi + k * cos$1(adLambda),\n v = k * sdLambda * sin$1(adLambda);\n areaRingSum.add(atan2(v, u));\n\n // Advance the previous points.\n lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;\n}\n\nfunction area(object) {\n areaSum.reset();\n geoStream(object, areaStream);\n return areaSum * 2;\n}\n\nfunction spherical(cartesian) {\n return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];\n}\n\nfunction cartesian(spherical) {\n var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);\n return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];\n}\n\nfunction cartesianDot(a, b) {\n return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n\nfunction cartesianCross(a, b) {\n return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];\n}\n\n// TODO return a\nfunction cartesianAddInPlace(a, b) {\n a[0] += b[0], a[1] += b[1], a[2] += b[2];\n}\n\nfunction cartesianScale(vector, k) {\n return [vector[0] * k, vector[1] * k, vector[2] * k];\n}\n\n// TODO return d\nfunction cartesianNormalizeInPlace(d) {\n var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);\n d[0] /= l, d[1] /= l, d[2] /= l;\n}\n\nvar lambda0$1;\nvar phi0;\nvar lambda1;\nvar phi1;\nvar lambda2;\nvar lambda00$1;\nvar phi00$1;\nvar p0;\nvar deltaSum = adder();\nvar ranges;\nvar range;\n\nvar boundsStream = {\n point: boundsPoint,\n lineStart: boundsLineStart,\n lineEnd: boundsLineEnd,\n polygonStart: function() {\n boundsStream.point = boundsRingPoint;\n boundsStream.lineStart = boundsRingStart;\n boundsStream.lineEnd = boundsRingEnd;\n deltaSum.reset();\n areaStream.polygonStart();\n },\n polygonEnd: function() {\n areaStream.polygonEnd();\n boundsStream.point = boundsPoint;\n boundsStream.lineStart = boundsLineStart;\n boundsStream.lineEnd = boundsLineEnd;\n if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);\n else if (deltaSum > epsilon$2) phi1 = 90;\n else if (deltaSum < -epsilon$2) phi0 = -90;\n range[0] = lambda0$1, range[1] = lambda1;\n }\n};\n\nfunction boundsPoint(lambda, phi) {\n ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);\n if (phi < phi0) phi0 = phi;\n if (phi > phi1) phi1 = phi;\n}\n\nfunction linePoint(lambda, phi) {\n var p = cartesian([lambda * radians, phi * radians]);\n if (p0) {\n var normal = cartesianCross(p0, p),\n equatorial = [normal[1], -normal[0], 0],\n inflection = cartesianCross(equatorial, normal);\n cartesianNormalizeInPlace(inflection);\n inflection = spherical(inflection);\n var delta = lambda - lambda2,\n sign$$1 = delta > 0 ? 1 : -1,\n lambdai = inflection[0] * degrees$1 * sign$$1,\n phii,\n antimeridian = abs(delta) > 180;\n if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {\n phii = inflection[1] * degrees$1;\n if (phii > phi1) phi1 = phii;\n } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {\n phii = -inflection[1] * degrees$1;\n if (phii < phi0) phi0 = phii;\n } else {\n if (phi < phi0) phi0 = phi;\n if (phi > phi1) phi1 = phi;\n }\n if (antimeridian) {\n if (lambda < lambda2) {\n if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;\n } else {\n if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;\n }\n } else {\n if (lambda1 >= lambda0$1) {\n if (lambda < lambda0$1) lambda0$1 = lambda;\n if (lambda > lambda1) lambda1 = lambda;\n } else {\n if (lambda > lambda2) {\n if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;\n } else {\n if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;\n }\n }\n }\n } else {\n ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);\n }\n if (phi < phi0) phi0 = phi;\n if (phi > phi1) phi1 = phi;\n p0 = p, lambda2 = lambda;\n}\n\nfunction boundsLineStart() {\n boundsStream.point = linePoint;\n}\n\nfunction boundsLineEnd() {\n range[0] = lambda0$1, range[1] = lambda1;\n boundsStream.point = boundsPoint;\n p0 = null;\n}\n\nfunction boundsRingPoint(lambda, phi) {\n if (p0) {\n var delta = lambda - lambda2;\n deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);\n } else {\n lambda00$1 = lambda, phi00$1 = phi;\n }\n areaStream.point(lambda, phi);\n linePoint(lambda, phi);\n}\n\nfunction boundsRingStart() {\n areaStream.lineStart();\n}\n\nfunction boundsRingEnd() {\n boundsRingPoint(lambda00$1, phi00$1);\n areaStream.lineEnd();\n if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180);\n range[0] = lambda0$1, range[1] = lambda1;\n p0 = null;\n}\n\n// Finds the left-right distance between two longitudes.\n// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want\n// the distance between ±180° to be 360°.\nfunction angle(lambda0, lambda1) {\n return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;\n}\n\nfunction rangeCompare(a, b) {\n return a[0] - b[0];\n}\n\nfunction rangeContains(range, x) {\n return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;\n}\n\nfunction bounds(feature) {\n var i, n, a, b, merged, deltaMax, delta;\n\n phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);\n ranges = [];\n geoStream(feature, boundsStream);\n\n // First, sort ranges by their minimum longitudes.\n if (n = ranges.length) {\n ranges.sort(rangeCompare);\n\n // Then, merge any ranges that overlap.\n for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {\n b = ranges[i];\n if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {\n if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];\n if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];\n } else {\n merged.push(a = b);\n }\n }\n\n // Finally, find the largest gap between the merged ranges.\n // The final bounding box will be the inverse of this gap.\n for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {\n b = merged[i];\n if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];\n }\n }\n\n ranges = range = null;\n\n return lambda0$1 === Infinity || phi0 === Infinity\n ? [[NaN, NaN], [NaN, NaN]]\n : [[lambda0$1, phi0], [lambda1, phi1]];\n}\n\nvar W0;\nvar W1;\nvar X0;\nvar Y0;\nvar Z0;\nvar X1;\nvar Y1;\nvar Z1;\nvar X2;\nvar Y2;\nvar Z2;\nvar lambda00$2;\nvar phi00$2;\nvar x0;\nvar y0;\nvar z0; // previous point\n\nvar centroidStream = {\n sphere: noop$1,\n point: centroidPoint,\n lineStart: centroidLineStart,\n lineEnd: centroidLineEnd,\n polygonStart: function() {\n centroidStream.lineStart = centroidRingStart;\n centroidStream.lineEnd = centroidRingEnd;\n },\n polygonEnd: function() {\n centroidStream.lineStart = centroidLineStart;\n centroidStream.lineEnd = centroidLineEnd;\n }\n};\n\n// Arithmetic mean of Cartesian vectors.\nfunction centroidPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos$1(phi);\n centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));\n}\n\nfunction centroidPointCartesian(x, y, z) {\n ++W0;\n X0 += (x - X0) / W0;\n Y0 += (y - Y0) / W0;\n Z0 += (z - Z0) / W0;\n}\n\nfunction centroidLineStart() {\n centroidStream.point = centroidLinePointFirst;\n}\n\nfunction centroidLinePointFirst(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos$1(phi);\n x0 = cosPhi * cos$1(lambda);\n y0 = cosPhi * sin$1(lambda);\n z0 = sin$1(phi);\n centroidStream.point = centroidLinePoint;\n centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroidLinePoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos$1(phi),\n x = cosPhi * cos$1(lambda),\n y = cosPhi * sin$1(lambda),\n z = sin$1(phi),\n w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);\n W1 += w;\n X1 += w * (x0 + (x0 = x));\n Y1 += w * (y0 + (y0 = y));\n Z1 += w * (z0 + (z0 = z));\n centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroidLineEnd() {\n centroidStream.point = centroidPoint;\n}\n\n// See J. E. Brock, The Inertia Tensor for a Spherical Triangle,\n// J. Applied Mechanics 42, 239 (1975).\nfunction centroidRingStart() {\n centroidStream.point = centroidRingPointFirst;\n}\n\nfunction centroidRingEnd() {\n centroidRingPoint(lambda00$2, phi00$2);\n centroidStream.point = centroidPoint;\n}\n\nfunction centroidRingPointFirst(lambda, phi) {\n lambda00$2 = lambda, phi00$2 = phi;\n lambda *= radians, phi *= radians;\n centroidStream.point = centroidRingPoint;\n var cosPhi = cos$1(phi);\n x0 = cosPhi * cos$1(lambda);\n y0 = cosPhi * sin$1(lambda);\n z0 = sin$1(phi);\n centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroidRingPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos$1(phi),\n x = cosPhi * cos$1(lambda),\n y = cosPhi * sin$1(lambda),\n z = sin$1(phi),\n cx = y0 * z - z0 * y,\n cy = z0 * x - x0 * z,\n cz = x0 * y - y0 * x,\n m = sqrt(cx * cx + cy * cy + cz * cz),\n w = asin(m), // line weight = angle\n v = m && -w / m; // area weight multiplier\n X2 += v * cx;\n Y2 += v * cy;\n Z2 += v * cz;\n W1 += w;\n X1 += w * (x0 + (x0 = x));\n Y1 += w * (y0 + (y0 = y));\n Z1 += w * (z0 + (z0 = z));\n centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroid(object) {\n W0 = W1 =\n X0 = Y0 = Z0 =\n X1 = Y1 = Z1 =\n X2 = Y2 = Z2 = 0;\n geoStream(object, centroidStream);\n\n var x = X2,\n y = Y2,\n z = Z2,\n m = x * x + y * y + z * z;\n\n // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.\n if (m < epsilon2$1) {\n x = X1, y = Y1, z = Z1;\n // If the feature has zero length, fall back to arithmetic mean of point vectors.\n if (W1 < epsilon$2) x = X0, y = Y0, z = Z0;\n m = x * x + y * y + z * z;\n // If the feature still has an undefined ccentroid, then return.\n if (m < epsilon2$1) return [NaN, NaN];\n }\n\n return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];\n}\n\nfunction constant$7(x) {\n return function() {\n return x;\n };\n}\n\nfunction compose(a, b) {\n\n function compose(x, y) {\n return x = a(x, y), b(x[0], x[1]);\n }\n\n if (a.invert && b.invert) compose.invert = function(x, y) {\n return x = b.invert(x, y), x && a.invert(x[0], x[1]);\n };\n\n return compose;\n}\n\nfunction rotationIdentity(lambda, phi) {\n return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];\n}\n\nrotationIdentity.invert = rotationIdentity;\n\nfunction rotateRadians(deltaLambda, deltaPhi, deltaGamma) {\n return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))\n : rotationLambda(deltaLambda))\n : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)\n : rotationIdentity);\n}\n\nfunction forwardRotationLambda(deltaLambda) {\n return function(lambda, phi) {\n return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];\n };\n}\n\nfunction rotationLambda(deltaLambda) {\n var rotation = forwardRotationLambda(deltaLambda);\n rotation.invert = forwardRotationLambda(-deltaLambda);\n return rotation;\n}\n\nfunction rotationPhiGamma(deltaPhi, deltaGamma) {\n var cosDeltaPhi = cos$1(deltaPhi),\n sinDeltaPhi = sin$1(deltaPhi),\n cosDeltaGamma = cos$1(deltaGamma),\n sinDeltaGamma = sin$1(deltaGamma);\n\n function rotation(lambda, phi) {\n var cosPhi = cos$1(phi),\n x = cos$1(lambda) * cosPhi,\n y = sin$1(lambda) * cosPhi,\n z = sin$1(phi),\n k = z * cosDeltaPhi + x * sinDeltaPhi;\n return [\n atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),\n asin(k * cosDeltaGamma + y * sinDeltaGamma)\n ];\n }\n\n rotation.invert = function(lambda, phi) {\n var cosPhi = cos$1(phi),\n x = cos$1(lambda) * cosPhi,\n y = sin$1(lambda) * cosPhi,\n z = sin$1(phi),\n k = z * cosDeltaGamma - y * sinDeltaGamma;\n return [\n atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),\n asin(k * cosDeltaPhi - x * sinDeltaPhi)\n ];\n };\n\n return rotation;\n}\n\nfunction rotation(rotate) {\n rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);\n\n function forward(coordinates) {\n coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);\n return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;\n }\n\n forward.invert = function(coordinates) {\n coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);\n return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;\n };\n\n return forward;\n}\n\n// Generates a circle centered at [0°, 0°], with a given radius and precision.\nfunction circleStream(stream, radius, delta, direction, t0, t1) {\n if (!delta) return;\n var cosRadius = cos$1(radius),\n sinRadius = sin$1(radius),\n step = direction * delta;\n if (t0 == null) {\n t0 = radius + direction * tau$3;\n t1 = radius - step / 2;\n } else {\n t0 = circleRadius(cosRadius, t0);\n t1 = circleRadius(cosRadius, t1);\n if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3;\n }\n for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {\n point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);\n stream.point(point[0], point[1]);\n }\n}\n\n// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].\nfunction circleRadius(cosRadius, point) {\n point = cartesian(point), point[0] -= cosRadius;\n cartesianNormalizeInPlace(point);\n var radius = acos(-point[1]);\n return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;\n}\n\nfunction circle() {\n var center = constant$7([0, 0]),\n radius = constant$7(90),\n precision = constant$7(6),\n ring,\n rotate,\n stream = {point: point};\n\n function point(x, y) {\n ring.push(x = rotate(x, y));\n x[0] *= degrees$1, x[1] *= degrees$1;\n }\n\n function circle() {\n var c = center.apply(this, arguments),\n r = radius.apply(this, arguments) * radians,\n p = precision.apply(this, arguments) * radians;\n ring = [];\n rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;\n circleStream(stream, r, p, 1);\n c = {type: \"Polygon\", coordinates: [ring]};\n ring = rotate = null;\n return c;\n }\n\n circle.center = function(_) {\n return arguments.length ? (center = typeof _ === \"function\" ? _ : constant$7([+_[0], +_[1]]), circle) : center;\n };\n\n circle.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$7(+_), circle) : radius;\n };\n\n circle.precision = function(_) {\n return arguments.length ? (precision = typeof _ === \"function\" ? _ : constant$7(+_), circle) : precision;\n };\n\n return circle;\n}\n\nfunction clipBuffer() {\n var lines = [],\n line;\n return {\n point: function(x, y) {\n line.push([x, y]);\n },\n lineStart: function() {\n lines.push(line = []);\n },\n lineEnd: noop$1,\n rejoin: function() {\n if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));\n },\n result: function() {\n var result = lines;\n lines = [];\n line = null;\n return result;\n }\n };\n}\n\nfunction pointEqual(a, b) {\n return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;\n}\n\nfunction Intersection(point, points, other, entry) {\n this.x = point;\n this.z = points;\n this.o = other; // another intersection\n this.e = entry; // is an entry?\n this.v = false; // visited\n this.n = this.p = null; // next & previous\n}\n\n// A generalized polygon clipping algorithm: given a polygon that has been cut\n// into its visible line segments, and rejoins the segments by interpolating\n// along the clip edge.\nfunction clipRejoin(segments, compareIntersection, startInside, interpolate, stream) {\n var subject = [],\n clip = [],\n i,\n n;\n\n segments.forEach(function(segment) {\n if ((n = segment.length - 1) <= 0) return;\n var n, p0 = segment[0], p1 = segment[n], x;\n\n // If the first and last points of a segment are coincident, then treat as a\n // closed ring. TODO if all rings are closed, then the winding order of the\n // exterior ring should be checked.\n if (pointEqual(p0, p1)) {\n stream.lineStart();\n for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);\n stream.lineEnd();\n return;\n }\n\n subject.push(x = new Intersection(p0, segment, null, true));\n clip.push(x.o = new Intersection(p0, null, x, false));\n subject.push(x = new Intersection(p1, segment, null, false));\n clip.push(x.o = new Intersection(p1, null, x, true));\n });\n\n if (!subject.length) return;\n\n clip.sort(compareIntersection);\n link$1(subject);\n link$1(clip);\n\n for (i = 0, n = clip.length; i < n; ++i) {\n clip[i].e = startInside = !startInside;\n }\n\n var start = subject[0],\n points,\n point;\n\n while (1) {\n // Find first unvisited intersection.\n var current = start,\n isSubject = true;\n while (current.v) if ((current = current.n) === start) return;\n points = current.z;\n stream.lineStart();\n do {\n current.v = current.o.v = true;\n if (current.e) {\n if (isSubject) {\n for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);\n } else {\n interpolate(current.x, current.n.x, 1, stream);\n }\n current = current.n;\n } else {\n if (isSubject) {\n points = current.p.z;\n for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);\n } else {\n interpolate(current.x, current.p.x, -1, stream);\n }\n current = current.p;\n }\n current = current.o;\n points = current.z;\n isSubject = !isSubject;\n } while (!current.v);\n stream.lineEnd();\n }\n}\n\nfunction link$1(array) {\n if (!(n = array.length)) return;\n var n,\n i = 0,\n a = array[0],\n b;\n while (++i < n) {\n a.n = b = array[i];\n b.p = a;\n a = b;\n }\n a.n = b = array[0];\n b.p = a;\n}\n\nvar sum$1 = adder();\n\nfunction polygonContains(polygon, point) {\n var lambda = point[0],\n phi = point[1],\n normal = [sin$1(lambda), -cos$1(lambda), 0],\n angle = 0,\n winding = 0;\n\n sum$1.reset();\n\n for (var i = 0, n = polygon.length; i < n; ++i) {\n if (!(m = (ring = polygon[i]).length)) continue;\n var ring,\n m,\n point0 = ring[m - 1],\n lambda0 = point0[0],\n phi0 = point0[1] / 2 + quarterPi,\n sinPhi0 = sin$1(phi0),\n cosPhi0 = cos$1(phi0);\n\n for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {\n var point1 = ring[j],\n lambda1 = point1[0],\n phi1 = point1[1] / 2 + quarterPi,\n sinPhi1 = sin$1(phi1),\n cosPhi1 = cos$1(phi1),\n delta = lambda1 - lambda0,\n sign$$1 = delta >= 0 ? 1 : -1,\n absDelta = sign$$1 * delta,\n antimeridian = absDelta > pi$3,\n k = sinPhi0 * sinPhi1;\n\n sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));\n angle += antimeridian ? delta + sign$$1 * tau$3 : delta;\n\n // Are the longitudes either side of the point’s meridian (lambda),\n // and are the latitudes smaller than the parallel (phi)?\n if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {\n var arc = cartesianCross(cartesian(point0), cartesian(point1));\n cartesianNormalizeInPlace(arc);\n var intersection = cartesianCross(normal, arc);\n cartesianNormalizeInPlace(intersection);\n var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);\n if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {\n winding += antimeridian ^ delta >= 0 ? 1 : -1;\n }\n }\n }\n }\n\n // First, determine whether the South pole is inside or outside:\n //\n // It is inside if:\n // * the polygon winds around it in a clockwise direction.\n // * the polygon does not (cumulatively) wind around it, but has a negative\n // (counter-clockwise) area.\n //\n // Second, count the (signed) number of times a segment crosses a lambda\n // from the point to the South pole. If it is zero, then the point is the\n // same side as the South pole.\n\n return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1);\n}\n\nfunction clip(pointVisible, clipLine, interpolate, start) {\n return function(sink) {\n var line = clipLine(sink),\n ringBuffer = clipBuffer(),\n ringSink = clipLine(ringBuffer),\n polygonStarted = false,\n polygon,\n segments,\n ring;\n\n var clip = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: function() {\n clip.point = pointRing;\n clip.lineStart = ringStart;\n clip.lineEnd = ringEnd;\n segments = [];\n polygon = [];\n },\n polygonEnd: function() {\n clip.point = point;\n clip.lineStart = lineStart;\n clip.lineEnd = lineEnd;\n segments = merge(segments);\n var startInside = polygonContains(polygon, start);\n if (segments.length) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n clipRejoin(segments, compareIntersection, startInside, interpolate, sink);\n } else if (startInside) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n sink.lineStart();\n interpolate(null, null, 1, sink);\n sink.lineEnd();\n }\n if (polygonStarted) sink.polygonEnd(), polygonStarted = false;\n segments = polygon = null;\n },\n sphere: function() {\n sink.polygonStart();\n sink.lineStart();\n interpolate(null, null, 1, sink);\n sink.lineEnd();\n sink.polygonEnd();\n }\n };\n\n function point(lambda, phi) {\n if (pointVisible(lambda, phi)) sink.point(lambda, phi);\n }\n\n function pointLine(lambda, phi) {\n line.point(lambda, phi);\n }\n\n function lineStart() {\n clip.point = pointLine;\n line.lineStart();\n }\n\n function lineEnd() {\n clip.point = point;\n line.lineEnd();\n }\n\n function pointRing(lambda, phi) {\n ring.push([lambda, phi]);\n ringSink.point(lambda, phi);\n }\n\n function ringStart() {\n ringSink.lineStart();\n ring = [];\n }\n\n function ringEnd() {\n pointRing(ring[0][0], ring[0][1]);\n ringSink.lineEnd();\n\n var clean = ringSink.clean(),\n ringSegments = ringBuffer.result(),\n i, n = ringSegments.length, m,\n segment,\n point;\n\n ring.pop();\n polygon.push(ring);\n ring = null;\n\n if (!n) return;\n\n // No intersections.\n if (clean & 1) {\n segment = ringSegments[0];\n if ((m = segment.length - 1) > 0) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n sink.lineStart();\n for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);\n sink.lineEnd();\n }\n return;\n }\n\n // Rejoin connected segments.\n // TODO reuse ringBuffer.rejoin()?\n if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));\n\n segments.push(ringSegments.filter(validSegment));\n }\n\n return clip;\n };\n}\n\nfunction validSegment(segment) {\n return segment.length > 1;\n}\n\n// Intersections are sorted along the clip edge. For both antimeridian cutting\n// and circle clipping, the same comparison is used.\nfunction compareIntersection(a, b) {\n return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1])\n - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]);\n}\n\nvar clipAntimeridian = clip(\n function() { return true; },\n clipAntimeridianLine,\n clipAntimeridianInterpolate,\n [-pi$3, -halfPi$2]\n);\n\n// Takes a line and cuts into visible segments. Return values: 0 - there were\n// intersections or the line was empty; 1 - no intersections; 2 - there were\n// intersections, and the first and last segments should be rejoined.\nfunction clipAntimeridianLine(stream) {\n var lambda0 = NaN,\n phi0 = NaN,\n sign0 = NaN,\n clean; // no intersections\n\n return {\n lineStart: function() {\n stream.lineStart();\n clean = 1;\n },\n point: function(lambda1, phi1) {\n var sign1 = lambda1 > 0 ? pi$3 : -pi$3,\n delta = abs(lambda1 - lambda0);\n if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole\n stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2);\n stream.point(sign0, phi0);\n stream.lineEnd();\n stream.lineStart();\n stream.point(sign1, phi0);\n stream.point(lambda1, phi0);\n clean = 0;\n } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian\n if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies\n if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2;\n phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);\n stream.point(sign0, phi0);\n stream.lineEnd();\n stream.lineStart();\n stream.point(sign1, phi0);\n clean = 0;\n }\n stream.point(lambda0 = lambda1, phi0 = phi1);\n sign0 = sign1;\n },\n lineEnd: function() {\n stream.lineEnd();\n lambda0 = phi0 = NaN;\n },\n clean: function() {\n return 2 - clean; // if intersections, rejoin first and last segments\n }\n };\n}\n\nfunction clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {\n var cosPhi0,\n cosPhi1,\n sinLambda0Lambda1 = sin$1(lambda0 - lambda1);\n return abs(sinLambda0Lambda1) > epsilon$2\n ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)\n - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))\n / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))\n : (phi0 + phi1) / 2;\n}\n\nfunction clipAntimeridianInterpolate(from, to, direction, stream) {\n var phi;\n if (from == null) {\n phi = direction * halfPi$2;\n stream.point(-pi$3, phi);\n stream.point(0, phi);\n stream.point(pi$3, phi);\n stream.point(pi$3, 0);\n stream.point(pi$3, -phi);\n stream.point(0, -phi);\n stream.point(-pi$3, -phi);\n stream.point(-pi$3, 0);\n stream.point(-pi$3, phi);\n } else if (abs(from[0] - to[0]) > epsilon$2) {\n var lambda = from[0] < to[0] ? pi$3 : -pi$3;\n phi = direction * lambda / 2;\n stream.point(-lambda, phi);\n stream.point(0, phi);\n stream.point(lambda, phi);\n } else {\n stream.point(to[0], to[1]);\n }\n}\n\nfunction clipCircle(radius) {\n var cr = cos$1(radius),\n delta = 6 * radians,\n smallRadius = cr > 0,\n notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case\n\n function interpolate(from, to, direction, stream) {\n circleStream(stream, radius, delta, direction, from, to);\n }\n\n function visible(lambda, phi) {\n return cos$1(lambda) * cos$1(phi) > cr;\n }\n\n // Takes a line and cuts into visible segments. Return values used for polygon\n // clipping: 0 - there were intersections or the line was empty; 1 - no\n // intersections 2 - there were intersections, and the first and last segments\n // should be rejoined.\n function clipLine(stream) {\n var point0, // previous point\n c0, // code for previous point\n v0, // visibility of previous point\n v00, // visibility of first point\n clean; // no intersections\n return {\n lineStart: function() {\n v00 = v0 = false;\n clean = 1;\n },\n point: function(lambda, phi) {\n var point1 = [lambda, phi],\n point2,\n v = visible(lambda, phi),\n c = smallRadius\n ? v ? 0 : code(lambda, phi)\n : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;\n if (!point0 && (v00 = v0 = v)) stream.lineStart();\n // Handle degeneracies.\n // TODO ignore if not clipping polygons.\n if (v !== v0) {\n point2 = intersect(point0, point1);\n if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {\n point1[0] += epsilon$2;\n point1[1] += epsilon$2;\n v = visible(point1[0], point1[1]);\n }\n }\n if (v !== v0) {\n clean = 0;\n if (v) {\n // outside going in\n stream.lineStart();\n point2 = intersect(point1, point0);\n stream.point(point2[0], point2[1]);\n } else {\n // inside going out\n point2 = intersect(point0, point1);\n stream.point(point2[0], point2[1]);\n stream.lineEnd();\n }\n point0 = point2;\n } else if (notHemisphere && point0 && smallRadius ^ v) {\n var t;\n // If the codes for two points are different, or are both zero,\n // and there this segment intersects with the small circle.\n if (!(c & c0) && (t = intersect(point1, point0, true))) {\n clean = 0;\n if (smallRadius) {\n stream.lineStart();\n stream.point(t[0][0], t[0][1]);\n stream.point(t[1][0], t[1][1]);\n stream.lineEnd();\n } else {\n stream.point(t[1][0], t[1][1]);\n stream.lineEnd();\n stream.lineStart();\n stream.point(t[0][0], t[0][1]);\n }\n }\n }\n if (v && (!point0 || !pointEqual(point0, point1))) {\n stream.point(point1[0], point1[1]);\n }\n point0 = point1, v0 = v, c0 = c;\n },\n lineEnd: function() {\n if (v0) stream.lineEnd();\n point0 = null;\n },\n // Rejoin first and last segments if there were intersections and the first\n // and last points were visible.\n clean: function() {\n return clean | ((v00 && v0) << 1);\n }\n };\n }\n\n // Intersects the great circle between a and b with the clip circle.\n function intersect(a, b, two) {\n var pa = cartesian(a),\n pb = cartesian(b);\n\n // We have two planes, n1.p = d1 and n2.p = d2.\n // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).\n var n1 = [1, 0, 0], // normal\n n2 = cartesianCross(pa, pb),\n n2n2 = cartesianDot(n2, n2),\n n1n2 = n2[0], // cartesianDot(n1, n2),\n determinant = n2n2 - n1n2 * n1n2;\n\n // Two polar points.\n if (!determinant) return !two && a;\n\n var c1 = cr * n2n2 / determinant,\n c2 = -cr * n1n2 / determinant,\n n1xn2 = cartesianCross(n1, n2),\n A = cartesianScale(n1, c1),\n B = cartesianScale(n2, c2);\n cartesianAddInPlace(A, B);\n\n // Solve |p(t)|^2 = 1.\n var u = n1xn2,\n w = cartesianDot(A, u),\n uu = cartesianDot(u, u),\n t2 = w * w - uu * (cartesianDot(A, A) - 1);\n\n if (t2 < 0) return;\n\n var t = sqrt(t2),\n q = cartesianScale(u, (-w - t) / uu);\n cartesianAddInPlace(q, A);\n q = spherical(q);\n\n if (!two) return q;\n\n // Two intersection points.\n var lambda0 = a[0],\n lambda1 = b[0],\n phi0 = a[1],\n phi1 = b[1],\n z;\n\n if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;\n\n var delta = lambda1 - lambda0,\n polar = abs(delta - pi$3) < epsilon$2,\n meridian = polar || delta < epsilon$2;\n\n if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;\n\n // Check that the first point is between a and b.\n if (meridian\n ? polar\n ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1)\n : phi0 <= q[1] && q[1] <= phi1\n : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {\n var q1 = cartesianScale(u, (-w + t) / uu);\n cartesianAddInPlace(q1, A);\n return [q, spherical(q1)];\n }\n }\n\n // Generates a 4-bit vector representing the location of a point relative to\n // the small circle's bounding box.\n function code(lambda, phi) {\n var r = smallRadius ? radius : pi$3 - radius,\n code = 0;\n if (lambda < -r) code |= 1; // left\n else if (lambda > r) code |= 2; // right\n if (phi < -r) code |= 4; // below\n else if (phi > r) code |= 8; // above\n return code;\n }\n\n return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]);\n}\n\nfunction clipLine(a, b, x0, y0, x1, y1) {\n var ax = a[0],\n ay = a[1],\n bx = b[0],\n by = b[1],\n t0 = 0,\n t1 = 1,\n dx = bx - ax,\n dy = by - ay,\n r;\n\n r = x0 - ax;\n if (!dx && r > 0) return;\n r /= dx;\n if (dx < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dx > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = x1 - ax;\n if (!dx && r < 0) return;\n r /= dx;\n if (dx < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dx > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n r = y0 - ay;\n if (!dy && r > 0) return;\n r /= dy;\n if (dy < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dy > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = y1 - ay;\n if (!dy && r < 0) return;\n r /= dy;\n if (dy < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dy > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;\n if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;\n return true;\n}\n\nvar clipMax = 1e9;\nvar clipMin = -clipMax;\n\n// TODO Use d3-polygon’s polygonContains here for the ring check?\n// TODO Eliminate duplicate buffering in clipBuffer and polygon.push?\n\nfunction clipRectangle(x0, y0, x1, y1) {\n\n function visible(x, y) {\n return x0 <= x && x <= x1 && y0 <= y && y <= y1;\n }\n\n function interpolate(from, to, direction, stream) {\n var a = 0, a1 = 0;\n if (from == null\n || (a = corner(from, direction)) !== (a1 = corner(to, direction))\n || comparePoint(from, to) < 0 ^ direction > 0) {\n do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);\n while ((a = (a + direction + 4) % 4) !== a1);\n } else {\n stream.point(to[0], to[1]);\n }\n }\n\n function corner(p, direction) {\n return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3\n : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1\n : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0\n : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon\n }\n\n function compareIntersection(a, b) {\n return comparePoint(a.x, b.x);\n }\n\n function comparePoint(a, b) {\n var ca = corner(a, 1),\n cb = corner(b, 1);\n return ca !== cb ? ca - cb\n : ca === 0 ? b[1] - a[1]\n : ca === 1 ? a[0] - b[0]\n : ca === 2 ? a[1] - b[1]\n : b[0] - a[0];\n }\n\n return function(stream) {\n var activeStream = stream,\n bufferStream = clipBuffer(),\n segments,\n polygon,\n ring,\n x__, y__, v__, // first point\n x_, y_, v_, // previous point\n first,\n clean;\n\n var clipStream = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: polygonStart,\n polygonEnd: polygonEnd\n };\n\n function point(x, y) {\n if (visible(x, y)) activeStream.point(x, y);\n }\n\n function polygonInside() {\n var winding = 0;\n\n for (var i = 0, n = polygon.length; i < n; ++i) {\n for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {\n a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];\n if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }\n else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }\n }\n }\n\n return winding;\n }\n\n // Buffer geometry within a polygon and then clip it en masse.\n function polygonStart() {\n activeStream = bufferStream, segments = [], polygon = [], clean = true;\n }\n\n function polygonEnd() {\n var startInside = polygonInside(),\n cleanInside = clean && startInside,\n visible = (segments = merge(segments)).length;\n if (cleanInside || visible) {\n stream.polygonStart();\n if (cleanInside) {\n stream.lineStart();\n interpolate(null, null, 1, stream);\n stream.lineEnd();\n }\n if (visible) {\n clipRejoin(segments, compareIntersection, startInside, interpolate, stream);\n }\n stream.polygonEnd();\n }\n activeStream = stream, segments = polygon = ring = null;\n }\n\n function lineStart() {\n clipStream.point = linePoint;\n if (polygon) polygon.push(ring = []);\n first = true;\n v_ = false;\n x_ = y_ = NaN;\n }\n\n // TODO rather than special-case polygons, simply handle them separately.\n // Ideally, coincident intersection points should be jittered to avoid\n // clipping issues.\n function lineEnd() {\n if (segments) {\n linePoint(x__, y__);\n if (v__ && v_) bufferStream.rejoin();\n segments.push(bufferStream.result());\n }\n clipStream.point = point;\n if (v_) activeStream.lineEnd();\n }\n\n function linePoint(x, y) {\n var v = visible(x, y);\n if (polygon) ring.push([x, y]);\n if (first) {\n x__ = x, y__ = y, v__ = v;\n first = false;\n if (v) {\n activeStream.lineStart();\n activeStream.point(x, y);\n }\n } else {\n if (v && v_) activeStream.point(x, y);\n else {\n var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],\n b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];\n if (clipLine(a, b, x0, y0, x1, y1)) {\n if (!v_) {\n activeStream.lineStart();\n activeStream.point(a[0], a[1]);\n }\n activeStream.point(b[0], b[1]);\n if (!v) activeStream.lineEnd();\n clean = false;\n } else if (v) {\n activeStream.lineStart();\n activeStream.point(x, y);\n clean = false;\n }\n }\n }\n x_ = x, y_ = y, v_ = v;\n }\n\n return clipStream;\n };\n}\n\nfunction extent$1() {\n var x0 = 0,\n y0 = 0,\n x1 = 960,\n y1 = 500,\n cache,\n cacheStream,\n clip;\n\n return clip = {\n stream: function(stream) {\n return cache && cacheStream === stream ? cache : cache = clipRectangle(x0, y0, x1, y1)(cacheStream = stream);\n },\n extent: function(_) {\n return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];\n }\n };\n}\n\nvar lengthSum = adder();\nvar lambda0$2;\nvar sinPhi0$1;\nvar cosPhi0$1;\n\nvar lengthStream = {\n sphere: noop$1,\n point: noop$1,\n lineStart: lengthLineStart,\n lineEnd: noop$1,\n polygonStart: noop$1,\n polygonEnd: noop$1\n};\n\nfunction lengthLineStart() {\n lengthStream.point = lengthPointFirst;\n lengthStream.lineEnd = lengthLineEnd;\n}\n\nfunction lengthLineEnd() {\n lengthStream.point = lengthStream.lineEnd = noop$1;\n}\n\nfunction lengthPointFirst(lambda, phi) {\n lambda *= radians, phi *= radians;\n lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);\n lengthStream.point = lengthPoint;\n}\n\nfunction lengthPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var sinPhi = sin$1(phi),\n cosPhi = cos$1(phi),\n delta = abs(lambda - lambda0$2),\n cosDelta = cos$1(delta),\n sinDelta = sin$1(delta),\n x = cosPhi * sinDelta,\n y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,\n z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;\n lengthSum.add(atan2(sqrt(x * x + y * y), z));\n lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;\n}\n\nfunction length$1(object) {\n lengthSum.reset();\n geoStream(object, lengthStream);\n return +lengthSum;\n}\n\nvar coordinates = [null, null];\nvar object$1 = {type: \"LineString\", coordinates: coordinates};\n\nfunction distance(a, b) {\n coordinates[0] = a;\n coordinates[1] = b;\n return length$1(object$1);\n}\n\nvar containsObjectType = {\n Feature: function(object, point) {\n return containsGeometry(object.geometry, point);\n },\n FeatureCollection: function(object, point) {\n var features = object.features, i = -1, n = features.length;\n while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;\n return false;\n }\n};\n\nvar containsGeometryType = {\n Sphere: function() {\n return true;\n },\n Point: function(object, point) {\n return containsPoint(object.coordinates, point);\n },\n MultiPoint: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsPoint(coordinates[i], point)) return true;\n return false;\n },\n LineString: function(object, point) {\n return containsLine(object.coordinates, point);\n },\n MultiLineString: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsLine(coordinates[i], point)) return true;\n return false;\n },\n Polygon: function(object, point) {\n return containsPolygon(object.coordinates, point);\n },\n MultiPolygon: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsPolygon(coordinates[i], point)) return true;\n return false;\n },\n GeometryCollection: function(object, point) {\n var geometries = object.geometries, i = -1, n = geometries.length;\n while (++i < n) if (containsGeometry(geometries[i], point)) return true;\n return false;\n }\n};\n\nfunction containsGeometry(geometry, point) {\n return geometry && containsGeometryType.hasOwnProperty(geometry.type)\n ? containsGeometryType[geometry.type](geometry, point)\n : false;\n}\n\nfunction containsPoint(coordinates, point) {\n return distance(coordinates, point) === 0;\n}\n\nfunction containsLine(coordinates, point) {\n var ab = distance(coordinates[0], coordinates[1]),\n ao = distance(coordinates[0], point),\n ob = distance(point, coordinates[1]);\n return ao + ob <= ab + epsilon$2;\n}\n\nfunction containsPolygon(coordinates, point) {\n return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));\n}\n\nfunction ringRadians(ring) {\n return ring = ring.map(pointRadians), ring.pop(), ring;\n}\n\nfunction pointRadians(point) {\n return [point[0] * radians, point[1] * radians];\n}\n\nfunction contains(object, point) {\n return (object && containsObjectType.hasOwnProperty(object.type)\n ? containsObjectType[object.type]\n : containsGeometry)(object, point);\n}\n\nfunction graticuleX(y0, y1, dy) {\n var y = sequence(y0, y1 - epsilon$2, dy).concat(y1);\n return function(x) { return y.map(function(y) { return [x, y]; }); };\n}\n\nfunction graticuleY(x0, x1, dx) {\n var x = sequence(x0, x1 - epsilon$2, dx).concat(x1);\n return function(y) { return x.map(function(x) { return [x, y]; }); };\n}\n\nfunction graticule() {\n var x1, x0, X1, X0,\n y1, y0, Y1, Y0,\n dx = 10, dy = dx, DX = 90, DY = 360,\n x, y, X, Y,\n precision = 2.5;\n\n function graticule() {\n return {type: \"MultiLineString\", coordinates: lines()};\n }\n\n function lines() {\n return sequence(ceil(X0 / DX) * DX, X1, DX).map(X)\n .concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y))\n .concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x))\n .concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y));\n }\n\n graticule.lines = function() {\n return lines().map(function(coordinates) { return {type: \"LineString\", coordinates: coordinates}; });\n };\n\n graticule.outline = function() {\n return {\n type: \"Polygon\",\n coordinates: [\n X(X0).concat(\n Y(Y1).slice(1),\n X(X1).reverse().slice(1),\n Y(Y0).reverse().slice(1))\n ]\n };\n };\n\n graticule.extent = function(_) {\n if (!arguments.length) return graticule.extentMinor();\n return graticule.extentMajor(_).extentMinor(_);\n };\n\n graticule.extentMajor = function(_) {\n if (!arguments.length) return [[X0, Y0], [X1, Y1]];\n X0 = +_[0][0], X1 = +_[1][0];\n Y0 = +_[0][1], Y1 = +_[1][1];\n if (X0 > X1) _ = X0, X0 = X1, X1 = _;\n if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;\n return graticule.precision(precision);\n };\n\n graticule.extentMinor = function(_) {\n if (!arguments.length) return [[x0, y0], [x1, y1]];\n x0 = +_[0][0], x1 = +_[1][0];\n y0 = +_[0][1], y1 = +_[1][1];\n if (x0 > x1) _ = x0, x0 = x1, x1 = _;\n if (y0 > y1) _ = y0, y0 = y1, y1 = _;\n return graticule.precision(precision);\n };\n\n graticule.step = function(_) {\n if (!arguments.length) return graticule.stepMinor();\n return graticule.stepMajor(_).stepMinor(_);\n };\n\n graticule.stepMajor = function(_) {\n if (!arguments.length) return [DX, DY];\n DX = +_[0], DY = +_[1];\n return graticule;\n };\n\n graticule.stepMinor = function(_) {\n if (!arguments.length) return [dx, dy];\n dx = +_[0], dy = +_[1];\n return graticule;\n };\n\n graticule.precision = function(_) {\n if (!arguments.length) return precision;\n precision = +_;\n x = graticuleX(y0, y1, 90);\n y = graticuleY(x0, x1, precision);\n X = graticuleX(Y0, Y1, 90);\n Y = graticuleY(X0, X1, precision);\n return graticule;\n };\n\n return graticule\n .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])\n .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);\n}\n\nfunction graticule10() {\n return graticule()();\n}\n\nfunction interpolate$1(a, b) {\n var x0 = a[0] * radians,\n y0 = a[1] * radians,\n x1 = b[0] * radians,\n y1 = b[1] * radians,\n cy0 = cos$1(y0),\n sy0 = sin$1(y0),\n cy1 = cos$1(y1),\n sy1 = sin$1(y1),\n kx0 = cy0 * cos$1(x0),\n ky0 = cy0 * sin$1(x0),\n kx1 = cy1 * cos$1(x1),\n ky1 = cy1 * sin$1(x1),\n d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),\n k = sin$1(d);\n\n var interpolate = d ? function(t) {\n var B = sin$1(t *= d) / k,\n A = sin$1(d - t) / k,\n x = A * kx0 + B * kx1,\n y = A * ky0 + B * ky1,\n z = A * sy0 + B * sy1;\n return [\n atan2(y, x) * degrees$1,\n atan2(z, sqrt(x * x + y * y)) * degrees$1\n ];\n } : function() {\n return [x0 * degrees$1, y0 * degrees$1];\n };\n\n interpolate.distance = d;\n\n return interpolate;\n}\n\nfunction identity$4(x) {\n return x;\n}\n\nvar areaSum$1 = adder();\nvar areaRingSum$1 = adder();\nvar x00;\nvar y00;\nvar x0$1;\nvar y0$1;\n\nvar areaStream$1 = {\n point: noop$1,\n lineStart: noop$1,\n lineEnd: noop$1,\n polygonStart: function() {\n areaStream$1.lineStart = areaRingStart$1;\n areaStream$1.lineEnd = areaRingEnd$1;\n },\n polygonEnd: function() {\n areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1;\n areaSum$1.add(abs(areaRingSum$1));\n areaRingSum$1.reset();\n },\n result: function() {\n var area = areaSum$1 / 2;\n areaSum$1.reset();\n return area;\n }\n};\n\nfunction areaRingStart$1() {\n areaStream$1.point = areaPointFirst$1;\n}\n\nfunction areaPointFirst$1(x, y) {\n areaStream$1.point = areaPoint$1;\n x00 = x0$1 = x, y00 = y0$1 = y;\n}\n\nfunction areaPoint$1(x, y) {\n areaRingSum$1.add(y0$1 * x - x0$1 * y);\n x0$1 = x, y0$1 = y;\n}\n\nfunction areaRingEnd$1() {\n areaPoint$1(x00, y00);\n}\n\nvar x0$2 = Infinity;\nvar y0$2 = x0$2;\nvar x1 = -x0$2;\nvar y1 = x1;\n\nvar boundsStream$1 = {\n point: boundsPoint$1,\n lineStart: noop$1,\n lineEnd: noop$1,\n polygonStart: noop$1,\n polygonEnd: noop$1,\n result: function() {\n var bounds = [[x0$2, y0$2], [x1, y1]];\n x1 = y1 = -(y0$2 = x0$2 = Infinity);\n return bounds;\n }\n};\n\nfunction boundsPoint$1(x, y) {\n if (x < x0$2) x0$2 = x;\n if (x > x1) x1 = x;\n if (y < y0$2) y0$2 = y;\n if (y > y1) y1 = y;\n}\n\n// TODO Enforce positive area for exterior, negative area for interior?\n\nvar X0$1 = 0;\nvar Y0$1 = 0;\nvar Z0$1 = 0;\nvar X1$1 = 0;\nvar Y1$1 = 0;\nvar Z1$1 = 0;\nvar X2$1 = 0;\nvar Y2$1 = 0;\nvar Z2$1 = 0;\nvar x00$1;\nvar y00$1;\nvar x0$3;\nvar y0$3;\n\nvar centroidStream$1 = {\n point: centroidPoint$1,\n lineStart: centroidLineStart$1,\n lineEnd: centroidLineEnd$1,\n polygonStart: function() {\n centroidStream$1.lineStart = centroidRingStart$1;\n centroidStream$1.lineEnd = centroidRingEnd$1;\n },\n polygonEnd: function() {\n centroidStream$1.point = centroidPoint$1;\n centroidStream$1.lineStart = centroidLineStart$1;\n centroidStream$1.lineEnd = centroidLineEnd$1;\n },\n result: function() {\n var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]\n : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]\n : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]\n : [NaN, NaN];\n X0$1 = Y0$1 = Z0$1 =\n X1$1 = Y1$1 = Z1$1 =\n X2$1 = Y2$1 = Z2$1 = 0;\n return centroid;\n }\n};\n\nfunction centroidPoint$1(x, y) {\n X0$1 += x;\n Y0$1 += y;\n ++Z0$1;\n}\n\nfunction centroidLineStart$1() {\n centroidStream$1.point = centroidPointFirstLine;\n}\n\nfunction centroidPointFirstLine(x, y) {\n centroidStream$1.point = centroidPointLine;\n centroidPoint$1(x0$3 = x, y0$3 = y);\n}\n\nfunction centroidPointLine(x, y) {\n var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);\n X1$1 += z * (x0$3 + x) / 2;\n Y1$1 += z * (y0$3 + y) / 2;\n Z1$1 += z;\n centroidPoint$1(x0$3 = x, y0$3 = y);\n}\n\nfunction centroidLineEnd$1() {\n centroidStream$1.point = centroidPoint$1;\n}\n\nfunction centroidRingStart$1() {\n centroidStream$1.point = centroidPointFirstRing;\n}\n\nfunction centroidRingEnd$1() {\n centroidPointRing(x00$1, y00$1);\n}\n\nfunction centroidPointFirstRing(x, y) {\n centroidStream$1.point = centroidPointRing;\n centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);\n}\n\nfunction centroidPointRing(x, y) {\n var dx = x - x0$3,\n dy = y - y0$3,\n z = sqrt(dx * dx + dy * dy);\n\n X1$1 += z * (x0$3 + x) / 2;\n Y1$1 += z * (y0$3 + y) / 2;\n Z1$1 += z;\n\n z = y0$3 * x - x0$3 * y;\n X2$1 += z * (x0$3 + x);\n Y2$1 += z * (y0$3 + y);\n Z2$1 += z * 3;\n centroidPoint$1(x0$3 = x, y0$3 = y);\n}\n\nfunction PathContext(context) {\n this._context = context;\n}\n\nPathContext.prototype = {\n _radius: 4.5,\n pointRadius: function(_) {\n return this._radius = _, this;\n },\n polygonStart: function() {\n this._line = 0;\n },\n polygonEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line === 0) this._context.closePath();\n this._point = NaN;\n },\n point: function(x, y) {\n switch (this._point) {\n case 0: {\n this._context.moveTo(x, y);\n this._point = 1;\n break;\n }\n case 1: {\n this._context.lineTo(x, y);\n break;\n }\n default: {\n this._context.moveTo(x + this._radius, y);\n this._context.arc(x, y, this._radius, 0, tau$3);\n break;\n }\n }\n },\n result: noop$1\n};\n\nvar lengthSum$1 = adder();\nvar lengthRing;\nvar x00$2;\nvar y00$2;\nvar x0$4;\nvar y0$4;\n\nvar lengthStream$1 = {\n point: noop$1,\n lineStart: function() {\n lengthStream$1.point = lengthPointFirst$1;\n },\n lineEnd: function() {\n if (lengthRing) lengthPoint$1(x00$2, y00$2);\n lengthStream$1.point = noop$1;\n },\n polygonStart: function() {\n lengthRing = true;\n },\n polygonEnd: function() {\n lengthRing = null;\n },\n result: function() {\n var length = +lengthSum$1;\n lengthSum$1.reset();\n return length;\n }\n};\n\nfunction lengthPointFirst$1(x, y) {\n lengthStream$1.point = lengthPoint$1;\n x00$2 = x0$4 = x, y00$2 = y0$4 = y;\n}\n\nfunction lengthPoint$1(x, y) {\n x0$4 -= x, y0$4 -= y;\n lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));\n x0$4 = x, y0$4 = y;\n}\n\nfunction PathString() {\n this._string = [];\n}\n\nPathString.prototype = {\n _radius: 4.5,\n _circle: circle$1(4.5),\n pointRadius: function(_) {\n if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;\n return this;\n },\n polygonStart: function() {\n this._line = 0;\n },\n polygonEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line === 0) this._string.push(\"Z\");\n this._point = NaN;\n },\n point: function(x, y) {\n switch (this._point) {\n case 0: {\n this._string.push(\"M\", x, \",\", y);\n this._point = 1;\n break;\n }\n case 1: {\n this._string.push(\"L\", x, \",\", y);\n break;\n }\n default: {\n if (this._circle == null) this._circle = circle$1(this._radius);\n this._string.push(\"M\", x, \",\", y, this._circle);\n break;\n }\n }\n },\n result: function() {\n if (this._string.length) {\n var result = this._string.join(\"\");\n this._string = [];\n return result;\n } else {\n return null;\n }\n }\n};\n\nfunction circle$1(radius) {\n return \"m0,\" + radius\n + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + -2 * radius\n + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + 2 * radius\n + \"z\";\n}\n\nfunction index$1(projection, context) {\n var pointRadius = 4.5,\n projectionStream,\n contextStream;\n\n function path(object) {\n if (object) {\n if (typeof pointRadius === \"function\") contextStream.pointRadius(+pointRadius.apply(this, arguments));\n geoStream(object, projectionStream(contextStream));\n }\n return contextStream.result();\n }\n\n path.area = function(object) {\n geoStream(object, projectionStream(areaStream$1));\n return areaStream$1.result();\n };\n\n path.measure = function(object) {\n geoStream(object, projectionStream(lengthStream$1));\n return lengthStream$1.result();\n };\n\n path.bounds = function(object) {\n geoStream(object, projectionStream(boundsStream$1));\n return boundsStream$1.result();\n };\n\n path.centroid = function(object) {\n geoStream(object, projectionStream(centroidStream$1));\n return centroidStream$1.result();\n };\n\n path.projection = function(_) {\n return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection;\n };\n\n path.context = function(_) {\n if (!arguments.length) return context;\n contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);\n if (typeof pointRadius !== \"function\") contextStream.pointRadius(pointRadius);\n return path;\n };\n\n path.pointRadius = function(_) {\n if (!arguments.length) return pointRadius;\n pointRadius = typeof _ === \"function\" ? _ : (contextStream.pointRadius(+_), +_);\n return path;\n };\n\n return path.projection(projection).context(context);\n}\n\nfunction transform(methods) {\n return {\n stream: transformer(methods)\n };\n}\n\nfunction transformer(methods) {\n return function(stream) {\n var s = new TransformStream;\n for (var key in methods) s[key] = methods[key];\n s.stream = stream;\n return s;\n };\n}\n\nfunction TransformStream() {}\n\nTransformStream.prototype = {\n constructor: TransformStream,\n point: function(x, y) { this.stream.point(x, y); },\n sphere: function() { this.stream.sphere(); },\n lineStart: function() { this.stream.lineStart(); },\n lineEnd: function() { this.stream.lineEnd(); },\n polygonStart: function() { this.stream.polygonStart(); },\n polygonEnd: function() { this.stream.polygonEnd(); }\n};\n\nfunction fit(projection, fitBounds, object) {\n var clip = projection.clipExtent && projection.clipExtent();\n projection.scale(150).translate([0, 0]);\n if (clip != null) projection.clipExtent(null);\n geoStream(object, projection.stream(boundsStream$1));\n fitBounds(boundsStream$1.result());\n if (clip != null) projection.clipExtent(clip);\n return projection;\n}\n\nfunction fitExtent(projection, extent, object) {\n return fit(projection, function(b) {\n var w = extent[1][0] - extent[0][0],\n h = extent[1][1] - extent[0][1],\n k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),\n x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,\n y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;\n projection.scale(150 * k).translate([x, y]);\n }, object);\n}\n\nfunction fitSize(projection, size, object) {\n return fitExtent(projection, [[0, 0], size], object);\n}\n\nfunction fitWidth(projection, width, object) {\n return fit(projection, function(b) {\n var w = +width,\n k = w / (b[1][0] - b[0][0]),\n x = (w - k * (b[1][0] + b[0][0])) / 2,\n y = -k * b[0][1];\n projection.scale(150 * k).translate([x, y]);\n }, object);\n}\n\nfunction fitHeight(projection, height, object) {\n return fit(projection, function(b) {\n var h = +height,\n k = h / (b[1][1] - b[0][1]),\n x = -k * b[0][0],\n y = (h - k * (b[1][1] + b[0][1])) / 2;\n projection.scale(150 * k).translate([x, y]);\n }, object);\n}\n\nvar maxDepth = 16;\nvar cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)\n\nfunction resample(project, delta2) {\n return +delta2 ? resample$1(project, delta2) : resampleNone(project);\n}\n\nfunction resampleNone(project) {\n return transformer({\n point: function(x, y) {\n x = project(x, y);\n this.stream.point(x[0], x[1]);\n }\n });\n}\n\nfunction resample$1(project, delta2) {\n\n function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {\n var dx = x1 - x0,\n dy = y1 - y0,\n d2 = dx * dx + dy * dy;\n if (d2 > 4 * delta2 && depth--) {\n var a = a0 + a1,\n b = b0 + b1,\n c = c0 + c1,\n m = sqrt(a * a + b * b + c * c),\n phi2 = asin(c /= m),\n lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),\n p = project(lambda2, phi2),\n x2 = p[0],\n y2 = p[1],\n dx2 = x2 - x0,\n dy2 = y2 - y0,\n dz = dy * dx2 - dx * dy2;\n if (dz * dz / d2 > delta2 // perpendicular projected distance\n || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end\n || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);\n stream.point(x2, y2);\n resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);\n }\n }\n }\n return function(stream) {\n var lambda00, x00, y00, a00, b00, c00, // first point\n lambda0, x0, y0, a0, b0, c0; // previous point\n\n var resampleStream = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },\n polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }\n };\n\n function point(x, y) {\n x = project(x, y);\n stream.point(x[0], x[1]);\n }\n\n function lineStart() {\n x0 = NaN;\n resampleStream.point = linePoint;\n stream.lineStart();\n }\n\n function linePoint(lambda, phi) {\n var c = cartesian([lambda, phi]), p = project(lambda, phi);\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);\n stream.point(x0, y0);\n }\n\n function lineEnd() {\n resampleStream.point = point;\n stream.lineEnd();\n }\n\n function ringStart() {\n lineStart();\n resampleStream.point = ringPoint;\n resampleStream.lineEnd = ringEnd;\n }\n\n function ringPoint(lambda, phi) {\n linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;\n resampleStream.point = linePoint;\n }\n\n function ringEnd() {\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);\n resampleStream.lineEnd = lineEnd;\n lineEnd();\n }\n\n return resampleStream;\n };\n}\n\nvar transformRadians = transformer({\n point: function(x, y) {\n this.stream.point(x * radians, y * radians);\n }\n});\n\nfunction transformRotate(rotate) {\n return transformer({\n point: function(x, y) {\n var r = rotate(x, y);\n return this.stream.point(r[0], r[1]);\n }\n });\n}\n\nfunction projection(project) {\n return projectionMutator(function() { return project; })();\n}\n\nfunction projectionMutator(projectAt) {\n var project,\n k = 150, // scale\n x = 480, y = 250, // translate\n dx, dy, lambda = 0, phi = 0, // center\n deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate\n theta = null, preclip = clipAntimeridian, // clip angle\n x0 = null, y0, x1, y1, postclip = identity$4, // clip extent\n delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision\n cache,\n cacheStream;\n\n function projection(point) {\n point = projectRotate(point[0] * radians, point[1] * radians);\n return [point[0] * k + dx, dy - point[1] * k];\n }\n\n function invert(point) {\n point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);\n return point && [point[0] * degrees$1, point[1] * degrees$1];\n }\n\n function projectTransform(x, y) {\n return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];\n }\n\n projection.stream = function(stream) {\n return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream)))));\n };\n\n projection.preclip = function(_) {\n return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip;\n };\n\n projection.postclip = function(_) {\n return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;\n };\n\n projection.clipAngle = function(_) {\n return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;\n };\n\n projection.clipExtent = function(_) {\n return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n };\n\n projection.scale = function(_) {\n return arguments.length ? (k = +_, recenter()) : k;\n };\n\n projection.translate = function(_) {\n return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];\n };\n\n projection.center = function(_) {\n return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];\n };\n\n projection.rotate = function(_) {\n return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1];\n };\n\n projection.precision = function(_) {\n return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);\n };\n\n projection.fitExtent = function(extent, object) {\n return fitExtent(projection, extent, object);\n };\n\n projection.fitSize = function(size, object) {\n return fitSize(projection, size, object);\n };\n\n projection.fitWidth = function(width, object) {\n return fitWidth(projection, width, object);\n };\n\n projection.fitHeight = function(height, object) {\n return fitHeight(projection, height, object);\n };\n\n function recenter() {\n projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);\n var center = project(lambda, phi);\n dx = x - center[0] * k;\n dy = y + center[1] * k;\n return reset();\n }\n\n function reset() {\n cache = cacheStream = null;\n return projection;\n }\n\n return function() {\n project = projectAt.apply(this, arguments);\n projection.invert = project.invert && invert;\n return recenter();\n };\n}\n\nfunction conicProjection(projectAt) {\n var phi0 = 0,\n phi1 = pi$3 / 3,\n m = projectionMutator(projectAt),\n p = m(phi0, phi1);\n\n p.parallels = function(_) {\n return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];\n };\n\n return p;\n}\n\nfunction cylindricalEqualAreaRaw(phi0) {\n var cosPhi0 = cos$1(phi0);\n\n function forward(lambda, phi) {\n return [lambda * cosPhi0, sin$1(phi) / cosPhi0];\n }\n\n forward.invert = function(x, y) {\n return [x / cosPhi0, asin(y * cosPhi0)];\n };\n\n return forward;\n}\n\nfunction conicEqualAreaRaw(y0, y1) {\n var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;\n\n // Are the parallels symmetrical around the Equator?\n if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);\n\n var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;\n\n function project(x, y) {\n var r = sqrt(c - 2 * n * sin$1(y)) / n;\n return [r * sin$1(x *= n), r0 - r * cos$1(x)];\n }\n\n project.invert = function(x, y) {\n var r0y = r0 - y;\n return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];\n };\n\n return project;\n}\n\nfunction conicEqualArea() {\n return conicProjection(conicEqualAreaRaw)\n .scale(155.424)\n .center([0, 33.6442]);\n}\n\nfunction albers() {\n return conicEqualArea()\n .parallels([29.5, 45.5])\n .scale(1070)\n .translate([480, 250])\n .rotate([96, 0])\n .center([-0.6, 38.7]);\n}\n\n// The projections must have mutually exclusive clip regions on the sphere,\n// as this will avoid emitting interleaving lines and polygons.\nfunction multiplex(streams) {\n var n = streams.length;\n return {\n point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },\n sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },\n lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },\n lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },\n polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },\n polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }\n };\n}\n\n// A composite projection for the United States, configured by default for\n// 960×500. The projection also works quite well at 960×600 if you change the\n// scale to 1285 and adjust the translate accordingly. The set of standard\n// parallels for each region comes from USGS, which is published here:\n// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers\nfunction albersUsa() {\n var cache,\n cacheStream,\n lower48 = albers(), lower48Point,\n alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338\n hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007\n point, pointStream = {point: function(x, y) { point = [x, y]; }};\n\n function albersUsa(coordinates) {\n var x = coordinates[0], y = coordinates[1];\n return point = null, (lower48Point.point(x, y), point)\n || (alaskaPoint.point(x, y), point)\n || (hawaiiPoint.point(x, y), point);\n }\n\n albersUsa.invert = function(coordinates) {\n var k = lower48.scale(),\n t = lower48.translate(),\n x = (coordinates[0] - t[0]) / k,\n y = (coordinates[1] - t[1]) / k;\n return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska\n : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii\n : lower48).invert(coordinates);\n };\n\n albersUsa.stream = function(stream) {\n return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);\n };\n\n albersUsa.precision = function(_) {\n if (!arguments.length) return lower48.precision();\n lower48.precision(_), alaska.precision(_), hawaii.precision(_);\n return reset();\n };\n\n albersUsa.scale = function(_) {\n if (!arguments.length) return lower48.scale();\n lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);\n return albersUsa.translate(lower48.translate());\n };\n\n albersUsa.translate = function(_) {\n if (!arguments.length) return lower48.translate();\n var k = lower48.scale(), x = +_[0], y = +_[1];\n\n lower48Point = lower48\n .translate(_)\n .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])\n .stream(pointStream);\n\n alaskaPoint = alaska\n .translate([x - 0.307 * k, y + 0.201 * k])\n .clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]])\n .stream(pointStream);\n\n hawaiiPoint = hawaii\n .translate([x - 0.205 * k, y + 0.212 * k])\n .clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]])\n .stream(pointStream);\n\n return reset();\n };\n\n albersUsa.fitExtent = function(extent, object) {\n return fitExtent(albersUsa, extent, object);\n };\n\n albersUsa.fitSize = function(size, object) {\n return fitSize(albersUsa, size, object);\n };\n\n albersUsa.fitWidth = function(width, object) {\n return fitWidth(albersUsa, width, object);\n };\n\n albersUsa.fitHeight = function(height, object) {\n return fitHeight(albersUsa, height, object);\n };\n\n function reset() {\n cache = cacheStream = null;\n return albersUsa;\n }\n\n return albersUsa.scale(1070);\n}\n\nfunction azimuthalRaw(scale) {\n return function(x, y) {\n var cx = cos$1(x),\n cy = cos$1(y),\n k = scale(cx * cy);\n return [\n k * cy * sin$1(x),\n k * sin$1(y)\n ];\n }\n}\n\nfunction azimuthalInvert(angle) {\n return function(x, y) {\n var z = sqrt(x * x + y * y),\n c = angle(z),\n sc = sin$1(c),\n cc = cos$1(c);\n return [\n atan2(x * sc, z * cc),\n asin(z && y * sc / z)\n ];\n }\n}\n\nvar azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {\n return sqrt(2 / (1 + cxcy));\n});\n\nazimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {\n return 2 * asin(z / 2);\n});\n\nfunction azimuthalEqualArea() {\n return projection(azimuthalEqualAreaRaw)\n .scale(124.75)\n .clipAngle(180 - 1e-3);\n}\n\nvar azimuthalEquidistantRaw = azimuthalRaw(function(c) {\n return (c = acos(c)) && c / sin$1(c);\n});\n\nazimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {\n return z;\n});\n\nfunction azimuthalEquidistant() {\n return projection(azimuthalEquidistantRaw)\n .scale(79.4188)\n .clipAngle(180 - 1e-3);\n}\n\nfunction mercatorRaw(lambda, phi) {\n return [lambda, log(tan((halfPi$2 + phi) / 2))];\n}\n\nmercatorRaw.invert = function(x, y) {\n return [x, 2 * atan(exp(y)) - halfPi$2];\n};\n\nfunction mercator() {\n return mercatorProjection(mercatorRaw)\n .scale(961 / tau$3);\n}\n\nfunction mercatorProjection(project) {\n var m = projection(project),\n center = m.center,\n scale = m.scale,\n translate = m.translate,\n clipExtent = m.clipExtent,\n x0 = null, y0, x1, y1; // clip extent\n\n m.scale = function(_) {\n return arguments.length ? (scale(_), reclip()) : scale();\n };\n\n m.translate = function(_) {\n return arguments.length ? (translate(_), reclip()) : translate();\n };\n\n m.center = function(_) {\n return arguments.length ? (center(_), reclip()) : center();\n };\n\n m.clipExtent = function(_) {\n return arguments.length ? (_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n };\n\n function reclip() {\n var k = pi$3 * scale(),\n t = m(rotation(m.rotate()).invert([0, 0]));\n return clipExtent(x0 == null\n ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw\n ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]\n : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);\n }\n\n return reclip();\n}\n\nfunction tany(y) {\n return tan((halfPi$2 + y) / 2);\n}\n\nfunction conicConformalRaw(y0, y1) {\n var cy0 = cos$1(y0),\n n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)),\n f = cy0 * pow(tany(y0), n) / n;\n\n if (!n) return mercatorRaw;\n\n function project(x, y) {\n if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; }\n else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; }\n var r = f / pow(tany(y), n);\n return [r * sin$1(n * x), f - r * cos$1(n * x)];\n }\n\n project.invert = function(x, y) {\n var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy);\n return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2];\n };\n\n return project;\n}\n\nfunction conicConformal() {\n return conicProjection(conicConformalRaw)\n .scale(109.5)\n .parallels([30, 30]);\n}\n\nfunction equirectangularRaw(lambda, phi) {\n return [lambda, phi];\n}\n\nequirectangularRaw.invert = equirectangularRaw;\n\nfunction equirectangular() {\n return projection(equirectangularRaw)\n .scale(152.63);\n}\n\nfunction conicEquidistantRaw(y0, y1) {\n var cy0 = cos$1(y0),\n n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),\n g = cy0 / n + y0;\n\n if (abs(n) < epsilon$2) return equirectangularRaw;\n\n function project(x, y) {\n var gy = g - y, nx = n * x;\n return [gy * sin$1(nx), g - gy * cos$1(nx)];\n }\n\n project.invert = function(x, y) {\n var gy = g - y;\n return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)];\n };\n\n return project;\n}\n\nfunction conicEquidistant() {\n return conicProjection(conicEquidistantRaw)\n .scale(131.154)\n .center([0, 13.9389]);\n}\n\nfunction gnomonicRaw(x, y) {\n var cy = cos$1(y), k = cos$1(x) * cy;\n return [cy * sin$1(x) / k, sin$1(y) / k];\n}\n\ngnomonicRaw.invert = azimuthalInvert(atan);\n\nfunction gnomonic() {\n return projection(gnomonicRaw)\n .scale(144.049)\n .clipAngle(60);\n}\n\nfunction scaleTranslate(kx, ky, tx, ty) {\n return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({\n point: function(x, y) {\n this.stream.point(x * kx + tx, y * ky + ty);\n }\n });\n}\n\nfunction identity$5() {\n var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform$$1 = identity$4, // scale, translate and reflect\n x0 = null, y0, x1, y1, // clip extent\n postclip = identity$4,\n cache,\n cacheStream,\n projection;\n\n function reset() {\n cache = cacheStream = null;\n return projection;\n }\n\n return projection = {\n stream: function(stream) {\n return cache && cacheStream === stream ? cache : cache = transform$$1(postclip(cacheStream = stream));\n },\n postclip: function(_) {\n return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;\n },\n clipExtent: function(_) {\n return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n },\n scale: function(_) {\n return arguments.length ? (transform$$1 = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;\n },\n translate: function(_) {\n return arguments.length ? (transform$$1 = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];\n },\n reflectX: function(_) {\n return arguments.length ? (transform$$1 = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;\n },\n reflectY: function(_) {\n return arguments.length ? (transform$$1 = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;\n },\n fitExtent: function(extent, object) {\n return fitExtent(projection, extent, object);\n },\n fitSize: function(size, object) {\n return fitSize(projection, size, object);\n },\n fitWidth: function(width, object) {\n return fitWidth(projection, width, object);\n },\n fitHeight: function(height, object) {\n return fitHeight(projection, height, object);\n }\n };\n}\n\nfunction naturalEarth1Raw(lambda, phi) {\n var phi2 = phi * phi, phi4 = phi2 * phi2;\n return [\n lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),\n phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))\n ];\n}\n\nnaturalEarth1Raw.invert = function(x, y) {\n var phi = y, i = 25, delta;\n do {\n var phi2 = phi * phi, phi4 = phi2 * phi2;\n phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /\n (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));\n } while (abs(delta) > epsilon$2 && --i > 0);\n return [\n x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),\n phi\n ];\n};\n\nfunction naturalEarth1() {\n return projection(naturalEarth1Raw)\n .scale(175.295);\n}\n\nfunction orthographicRaw(x, y) {\n return [cos$1(y) * sin$1(x), sin$1(y)];\n}\n\northographicRaw.invert = azimuthalInvert(asin);\n\nfunction orthographic() {\n return projection(orthographicRaw)\n .scale(249.5)\n .clipAngle(90 + epsilon$2);\n}\n\nfunction stereographicRaw(x, y) {\n var cy = cos$1(y), k = 1 + cos$1(x) * cy;\n return [cy * sin$1(x) / k, sin$1(y) / k];\n}\n\nstereographicRaw.invert = azimuthalInvert(function(z) {\n return 2 * atan(z);\n});\n\nfunction stereographic() {\n return projection(stereographicRaw)\n .scale(250)\n .clipAngle(142);\n}\n\nfunction transverseMercatorRaw(lambda, phi) {\n return [log(tan((halfPi$2 + phi) / 2)), -lambda];\n}\n\ntransverseMercatorRaw.invert = function(x, y) {\n return [-y, 2 * atan(exp(x)) - halfPi$2];\n};\n\nfunction transverseMercator() {\n var m = mercatorProjection(transverseMercatorRaw),\n center = m.center,\n rotate = m.rotate;\n\n m.center = function(_) {\n return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);\n };\n\n m.rotate = function(_) {\n return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);\n };\n\n return rotate([0, 0, 90])\n .scale(159.155);\n}\n\nfunction defaultSeparation(a, b) {\n return a.parent === b.parent ? 1 : 2;\n}\n\nfunction meanX(children) {\n return children.reduce(meanXReduce, 0) / children.length;\n}\n\nfunction meanXReduce(x, c) {\n return x + c.x;\n}\n\nfunction maxY(children) {\n return 1 + children.reduce(maxYReduce, 0);\n}\n\nfunction maxYReduce(y, c) {\n return Math.max(y, c.y);\n}\n\nfunction leafLeft(node) {\n var children;\n while (children = node.children) node = children[0];\n return node;\n}\n\nfunction leafRight(node) {\n var children;\n while (children = node.children) node = children[children.length - 1];\n return node;\n}\n\nfunction cluster() {\n var separation = defaultSeparation,\n dx = 1,\n dy = 1,\n nodeSize = false;\n\n function cluster(root) {\n var previousNode,\n x = 0;\n\n // First walk, computing the initial x & y values.\n root.eachAfter(function(node) {\n var children = node.children;\n if (children) {\n node.x = meanX(children);\n node.y = maxY(children);\n } else {\n node.x = previousNode ? x += separation(node, previousNode) : 0;\n node.y = 0;\n previousNode = node;\n }\n });\n\n var left = leafLeft(root),\n right = leafRight(root),\n x0 = left.x - separation(left, right) / 2,\n x1 = right.x + separation(right, left) / 2;\n\n // Second walk, normalizing x & y to the desired size.\n return root.eachAfter(nodeSize ? function(node) {\n node.x = (node.x - root.x) * dx;\n node.y = (root.y - node.y) * dy;\n } : function(node) {\n node.x = (node.x - x0) / (x1 - x0) * dx;\n node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;\n });\n }\n\n cluster.separation = function(x) {\n return arguments.length ? (separation = x, cluster) : separation;\n };\n\n cluster.size = function(x) {\n return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);\n };\n\n cluster.nodeSize = function(x) {\n return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);\n };\n\n return cluster;\n}\n\nfunction count(node) {\n var sum = 0,\n children = node.children,\n i = children && children.length;\n if (!i) sum = 1;\n else while (--i >= 0) sum += children[i].value;\n node.value = sum;\n}\n\nfunction node_count() {\n return this.eachAfter(count);\n}\n\nfunction node_each(callback) {\n var node = this, current, next = [node], children, i, n;\n do {\n current = next.reverse(), next = [];\n while (node = current.pop()) {\n callback(node), children = node.children;\n if (children) for (i = 0, n = children.length; i < n; ++i) {\n next.push(children[i]);\n }\n }\n } while (next.length);\n return this;\n}\n\nfunction node_eachBefore(callback) {\n var node = this, nodes = [node], children, i;\n while (node = nodes.pop()) {\n callback(node), children = node.children;\n if (children) for (i = children.length - 1; i >= 0; --i) {\n nodes.push(children[i]);\n }\n }\n return this;\n}\n\nfunction node_eachAfter(callback) {\n var node = this, nodes = [node], next = [], children, i, n;\n while (node = nodes.pop()) {\n next.push(node), children = node.children;\n if (children) for (i = 0, n = children.length; i < n; ++i) {\n nodes.push(children[i]);\n }\n }\n while (node = next.pop()) {\n callback(node);\n }\n return this;\n}\n\nfunction node_sum(value) {\n return this.eachAfter(function(node) {\n var sum = +value(node.data) || 0,\n children = node.children,\n i = children && children.length;\n while (--i >= 0) sum += children[i].value;\n node.value = sum;\n });\n}\n\nfunction node_sort(compare) {\n return this.eachBefore(function(node) {\n if (node.children) {\n node.children.sort(compare);\n }\n });\n}\n\nfunction node_path(end) {\n var start = this,\n ancestor = leastCommonAncestor(start, end),\n nodes = [start];\n while (start !== ancestor) {\n start = start.parent;\n nodes.push(start);\n }\n var k = nodes.length;\n while (end !== ancestor) {\n nodes.splice(k, 0, end);\n end = end.parent;\n }\n return nodes;\n}\n\nfunction leastCommonAncestor(a, b) {\n if (a === b) return a;\n var aNodes = a.ancestors(),\n bNodes = b.ancestors(),\n c = null;\n a = aNodes.pop();\n b = bNodes.pop();\n while (a === b) {\n c = a;\n a = aNodes.pop();\n b = bNodes.pop();\n }\n return c;\n}\n\nfunction node_ancestors() {\n var node = this, nodes = [node];\n while (node = node.parent) {\n nodes.push(node);\n }\n return nodes;\n}\n\nfunction node_descendants() {\n var nodes = [];\n this.each(function(node) {\n nodes.push(node);\n });\n return nodes;\n}\n\nfunction node_leaves() {\n var leaves = [];\n this.eachBefore(function(node) {\n if (!node.children) {\n leaves.push(node);\n }\n });\n return leaves;\n}\n\nfunction node_links() {\n var root = this, links = [];\n root.each(function(node) {\n if (node !== root) { // Don’t include the root’s parent, if any.\n links.push({source: node.parent, target: node});\n }\n });\n return links;\n}\n\nfunction hierarchy(data, children) {\n var root = new Node(data),\n valued = +data.value && (root.value = data.value),\n node,\n nodes = [root],\n child,\n childs,\n i,\n n;\n\n if (children == null) children = defaultChildren;\n\n while (node = nodes.pop()) {\n if (valued) node.value = +node.data.value;\n if ((childs = children(node.data)) && (n = childs.length)) {\n node.children = new Array(n);\n for (i = n - 1; i >= 0; --i) {\n nodes.push(child = node.children[i] = new Node(childs[i]));\n child.parent = node;\n child.depth = node.depth + 1;\n }\n }\n }\n\n return root.eachBefore(computeHeight);\n}\n\nfunction node_copy() {\n return hierarchy(this).eachBefore(copyData);\n}\n\nfunction defaultChildren(d) {\n return d.children;\n}\n\nfunction copyData(node) {\n node.data = node.data.data;\n}\n\nfunction computeHeight(node) {\n var height = 0;\n do node.height = height;\n while ((node = node.parent) && (node.height < ++height));\n}\n\nfunction Node(data) {\n this.data = data;\n this.depth =\n this.height = 0;\n this.parent = null;\n}\n\nNode.prototype = hierarchy.prototype = {\n constructor: Node,\n count: node_count,\n each: node_each,\n eachAfter: node_eachAfter,\n eachBefore: node_eachBefore,\n sum: node_sum,\n sort: node_sort,\n path: node_path,\n ancestors: node_ancestors,\n descendants: node_descendants,\n leaves: node_leaves,\n links: node_links,\n copy: node_copy\n};\n\nvar slice$3 = Array.prototype.slice;\n\nfunction shuffle$1(array) {\n var m = array.length,\n t,\n i;\n\n while (m) {\n i = Math.random() * m-- | 0;\n t = array[m];\n array[m] = array[i];\n array[i] = t;\n }\n\n return array;\n}\n\nfunction enclose(circles) {\n var i = 0, n = (circles = shuffle$1(slice$3.call(circles))).length, B = [], p, e;\n\n while (i < n) {\n p = circles[i];\n if (e && enclosesWeak(e, p)) ++i;\n else e = encloseBasis(B = extendBasis(B, p)), i = 0;\n }\n\n return e;\n}\n\nfunction extendBasis(B, p) {\n var i, j;\n\n if (enclosesWeakAll(p, B)) return [p];\n\n // If we get here then B must have at least one element.\n for (i = 0; i < B.length; ++i) {\n if (enclosesNot(p, B[i])\n && enclosesWeakAll(encloseBasis2(B[i], p), B)) {\n return [B[i], p];\n }\n }\n\n // If we get here then B must have at least two elements.\n for (i = 0; i < B.length - 1; ++i) {\n for (j = i + 1; j < B.length; ++j) {\n if (enclosesNot(encloseBasis2(B[i], B[j]), p)\n && enclosesNot(encloseBasis2(B[i], p), B[j])\n && enclosesNot(encloseBasis2(B[j], p), B[i])\n && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {\n return [B[i], B[j], p];\n }\n }\n }\n\n // If we get here then something is very wrong.\n throw new Error;\n}\n\nfunction enclosesNot(a, b) {\n var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;\n return dr < 0 || dr * dr < dx * dx + dy * dy;\n}\n\nfunction enclosesWeak(a, b) {\n var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y;\n return dr > 0 && dr * dr > dx * dx + dy * dy;\n}\n\nfunction enclosesWeakAll(a, B) {\n for (var i = 0; i < B.length; ++i) {\n if (!enclosesWeak(a, B[i])) {\n return false;\n }\n }\n return true;\n}\n\nfunction encloseBasis(B) {\n switch (B.length) {\n case 1: return encloseBasis1(B[0]);\n case 2: return encloseBasis2(B[0], B[1]);\n case 3: return encloseBasis3(B[0], B[1], B[2]);\n }\n}\n\nfunction encloseBasis1(a) {\n return {\n x: a.x,\n y: a.y,\n r: a.r\n };\n}\n\nfunction encloseBasis2(a, b) {\n var x1 = a.x, y1 = a.y, r1 = a.r,\n x2 = b.x, y2 = b.y, r2 = b.r,\n x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,\n l = Math.sqrt(x21 * x21 + y21 * y21);\n return {\n x: (x1 + x2 + x21 / l * r21) / 2,\n y: (y1 + y2 + y21 / l * r21) / 2,\n r: (l + r1 + r2) / 2\n };\n}\n\nfunction encloseBasis3(a, b, c) {\n var x1 = a.x, y1 = a.y, r1 = a.r,\n x2 = b.x, y2 = b.y, r2 = b.r,\n x3 = c.x, y3 = c.y, r3 = c.r,\n a2 = x1 - x2,\n a3 = x1 - x3,\n b2 = y1 - y2,\n b3 = y1 - y3,\n c2 = r2 - r1,\n c3 = r3 - r1,\n d1 = x1 * x1 + y1 * y1 - r1 * r1,\n d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,\n d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,\n ab = a3 * b2 - a2 * b3,\n xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,\n xb = (b3 * c2 - b2 * c3) / ab,\n ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,\n yb = (a2 * c3 - a3 * c2) / ab,\n A = xb * xb + yb * yb - 1,\n B = 2 * (r1 + xa * xb + ya * yb),\n C = xa * xa + ya * ya - r1 * r1,\n r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);\n return {\n x: x1 + xa + xb * r,\n y: y1 + ya + yb * r,\n r: r\n };\n}\n\nfunction place(a, b, c) {\n var ax = a.x,\n ay = a.y,\n da = b.r + c.r,\n db = a.r + c.r,\n dx = b.x - ax,\n dy = b.y - ay,\n dc = dx * dx + dy * dy;\n if (dc) {\n var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),\n y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);\n c.x = ax + x * dx + y * dy;\n c.y = ay + x * dy - y * dx;\n } else {\n c.x = ax + db;\n c.y = ay;\n }\n}\n\nfunction intersects(a, b) {\n var dx = b.x - a.x,\n dy = b.y - a.y,\n dr = a.r + b.r;\n return dr * dr - 1e-6 > dx * dx + dy * dy;\n}\n\nfunction score(node) {\n var a = node._,\n b = node.next._,\n ab = a.r + b.r,\n dx = (a.x * b.r + b.x * a.r) / ab,\n dy = (a.y * b.r + b.y * a.r) / ab;\n return dx * dx + dy * dy;\n}\n\nfunction Node$1(circle) {\n this._ = circle;\n this.next = null;\n this.previous = null;\n}\n\nfunction packEnclose(circles) {\n if (!(n = circles.length)) return 0;\n\n var a, b, c, n, aa, ca, i, j, k, sj, sk;\n\n // Place the first circle.\n a = circles[0], a.x = 0, a.y = 0;\n if (!(n > 1)) return a.r;\n\n // Place the second circle.\n b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;\n if (!(n > 2)) return a.r + b.r;\n\n // Place the third circle.\n place(b, a, c = circles[2]);\n\n // Initialize the front-chain using the first three circles a, b and c.\n a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);\n a.next = c.previous = b;\n b.next = a.previous = c;\n c.next = b.previous = a;\n\n // Attempt to place each remaining circle…\n pack: for (i = 3; i < n; ++i) {\n place(a._, b._, c = circles[i]), c = new Node$1(c);\n\n // Find the closest intersecting circle on the front-chain, if any.\n // “Closeness” is determined by linear distance along the front-chain.\n // “Ahead” or “behind” is likewise determined by linear distance.\n j = b.next, k = a.previous, sj = b._.r, sk = a._.r;\n do {\n if (sj <= sk) {\n if (intersects(j._, c._)) {\n b = j, a.next = b, b.previous = a, --i;\n continue pack;\n }\n sj += j._.r, j = j.next;\n } else {\n if (intersects(k._, c._)) {\n a = k, a.next = b, b.previous = a, --i;\n continue pack;\n }\n sk += k._.r, k = k.previous;\n }\n } while (j !== k.next);\n\n // Success! Insert the new circle c between a and b.\n c.previous = a, c.next = b, a.next = b.previous = b = c;\n\n // Compute the new closest circle pair to the centroid.\n aa = score(a);\n while ((c = c.next) !== b) {\n if ((ca = score(c)) < aa) {\n a = c, aa = ca;\n }\n }\n b = a.next;\n }\n\n // Compute the enclosing circle of the front chain.\n a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);\n\n // Translate the circles to put the enclosing circle around the origin.\n for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;\n\n return c.r;\n}\n\nfunction siblings(circles) {\n packEnclose(circles);\n return circles;\n}\n\nfunction optional(f) {\n return f == null ? null : required(f);\n}\n\nfunction required(f) {\n if (typeof f !== \"function\") throw new Error;\n return f;\n}\n\nfunction constantZero() {\n return 0;\n}\n\nfunction constant$8(x) {\n return function() {\n return x;\n };\n}\n\nfunction defaultRadius$1(d) {\n return Math.sqrt(d.value);\n}\n\nfunction index$2() {\n var radius = null,\n dx = 1,\n dy = 1,\n padding = constantZero;\n\n function pack(root) {\n root.x = dx / 2, root.y = dy / 2;\n if (radius) {\n root.eachBefore(radiusLeaf(radius))\n .eachAfter(packChildren(padding, 0.5))\n .eachBefore(translateChild(1));\n } else {\n root.eachBefore(radiusLeaf(defaultRadius$1))\n .eachAfter(packChildren(constantZero, 1))\n .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))\n .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));\n }\n return root;\n }\n\n pack.radius = function(x) {\n return arguments.length ? (radius = optional(x), pack) : radius;\n };\n\n pack.size = function(x) {\n return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];\n };\n\n pack.padding = function(x) {\n return arguments.length ? (padding = typeof x === \"function\" ? x : constant$8(+x), pack) : padding;\n };\n\n return pack;\n}\n\nfunction radiusLeaf(radius) {\n return function(node) {\n if (!node.children) {\n node.r = Math.max(0, +radius(node) || 0);\n }\n };\n}\n\nfunction packChildren(padding, k) {\n return function(node) {\n if (children = node.children) {\n var children,\n i,\n n = children.length,\n r = padding(node) * k || 0,\n e;\n\n if (r) for (i = 0; i < n; ++i) children[i].r += r;\n e = packEnclose(children);\n if (r) for (i = 0; i < n; ++i) children[i].r -= r;\n node.r = e + r;\n }\n };\n}\n\nfunction translateChild(k) {\n return function(node) {\n var parent = node.parent;\n node.r *= k;\n if (parent) {\n node.x = parent.x + k * node.x;\n node.y = parent.y + k * node.y;\n }\n };\n}\n\nfunction roundNode(node) {\n node.x0 = Math.round(node.x0);\n node.y0 = Math.round(node.y0);\n node.x1 = Math.round(node.x1);\n node.y1 = Math.round(node.y1);\n}\n\nfunction treemapDice(parent, x0, y0, x1, y1) {\n var nodes = parent.children,\n node,\n i = -1,\n n = nodes.length,\n k = parent.value && (x1 - x0) / parent.value;\n\n while (++i < n) {\n node = nodes[i], node.y0 = y0, node.y1 = y1;\n node.x0 = x0, node.x1 = x0 += node.value * k;\n }\n}\n\nfunction partition() {\n var dx = 1,\n dy = 1,\n padding = 0,\n round = false;\n\n function partition(root) {\n var n = root.height + 1;\n root.x0 =\n root.y0 = padding;\n root.x1 = dx;\n root.y1 = dy / n;\n root.eachBefore(positionNode(dy, n));\n if (round) root.eachBefore(roundNode);\n return root;\n }\n\n function positionNode(dy, n) {\n return function(node) {\n if (node.children) {\n treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);\n }\n var x0 = node.x0,\n y0 = node.y0,\n x1 = node.x1 - padding,\n y1 = node.y1 - padding;\n if (x1 < x0) x0 = x1 = (x0 + x1) / 2;\n if (y1 < y0) y0 = y1 = (y0 + y1) / 2;\n node.x0 = x0;\n node.y0 = y0;\n node.x1 = x1;\n node.y1 = y1;\n };\n }\n\n partition.round = function(x) {\n return arguments.length ? (round = !!x, partition) : round;\n };\n\n partition.size = function(x) {\n return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];\n };\n\n partition.padding = function(x) {\n return arguments.length ? (padding = +x, partition) : padding;\n };\n\n return partition;\n}\n\nvar keyPrefix$1 = \"$\";\nvar preroot = {depth: -1};\nvar ambiguous = {};\n\nfunction defaultId(d) {\n return d.id;\n}\n\nfunction defaultParentId(d) {\n return d.parentId;\n}\n\nfunction stratify() {\n var id = defaultId,\n parentId = defaultParentId;\n\n function stratify(data) {\n var d,\n i,\n n = data.length,\n root,\n parent,\n node,\n nodes = new Array(n),\n nodeId,\n nodeKey,\n nodeByKey = {};\n\n for (i = 0; i < n; ++i) {\n d = data[i], node = nodes[i] = new Node(d);\n if ((nodeId = id(d, i, data)) != null && (nodeId += \"\")) {\n nodeKey = keyPrefix$1 + (node.id = nodeId);\n nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;\n }\n }\n\n for (i = 0; i < n; ++i) {\n node = nodes[i], nodeId = parentId(data[i], i, data);\n if (nodeId == null || !(nodeId += \"\")) {\n if (root) throw new Error(\"multiple roots\");\n root = node;\n } else {\n parent = nodeByKey[keyPrefix$1 + nodeId];\n if (!parent) throw new Error(\"missing: \" + nodeId);\n if (parent === ambiguous) throw new Error(\"ambiguous: \" + nodeId);\n if (parent.children) parent.children.push(node);\n else parent.children = [node];\n node.parent = parent;\n }\n }\n\n if (!root) throw new Error(\"no root\");\n root.parent = preroot;\n root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);\n root.parent = null;\n if (n > 0) throw new Error(\"cycle\");\n\n return root;\n }\n\n stratify.id = function(x) {\n return arguments.length ? (id = required(x), stratify) : id;\n };\n\n stratify.parentId = function(x) {\n return arguments.length ? (parentId = required(x), stratify) : parentId;\n };\n\n return stratify;\n}\n\nfunction defaultSeparation$1(a, b) {\n return a.parent === b.parent ? 1 : 2;\n}\n\n// function radialSeparation(a, b) {\n// return (a.parent === b.parent ? 1 : 2) / a.depth;\n// }\n\n// This function is used to traverse the left contour of a subtree (or\n// subforest). It returns the successor of v on this contour. This successor is\n// either given by the leftmost child of v or by the thread of v. The function\n// returns null if and only if v is on the highest level of its subtree.\nfunction nextLeft(v) {\n var children = v.children;\n return children ? children[0] : v.t;\n}\n\n// This function works analogously to nextLeft.\nfunction nextRight(v) {\n var children = v.children;\n return children ? children[children.length - 1] : v.t;\n}\n\n// Shifts the current subtree rooted at w+. This is done by increasing\n// prelim(w+) and mod(w+) by shift.\nfunction moveSubtree(wm, wp, shift) {\n var change = shift / (wp.i - wm.i);\n wp.c -= change;\n wp.s += shift;\n wm.c += change;\n wp.z += shift;\n wp.m += shift;\n}\n\n// All other shifts, applied to the smaller subtrees between w- and w+, are\n// performed by this function. To prepare the shifts, we have to adjust\n// change(w+), shift(w+), and change(w-).\nfunction executeShifts(v) {\n var shift = 0,\n change = 0,\n children = v.children,\n i = children.length,\n w;\n while (--i >= 0) {\n w = children[i];\n w.z += shift;\n w.m += shift;\n shift += w.s + (change += w.c);\n }\n}\n\n// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,\n// returns the specified (default) ancestor.\nfunction nextAncestor(vim, v, ancestor) {\n return vim.a.parent === v.parent ? vim.a : ancestor;\n}\n\nfunction TreeNode(node, i) {\n this._ = node;\n this.parent = null;\n this.children = null;\n this.A = null; // default ancestor\n this.a = this; // ancestor\n this.z = 0; // prelim\n this.m = 0; // mod\n this.c = 0; // change\n this.s = 0; // shift\n this.t = null; // thread\n this.i = i; // number\n}\n\nTreeNode.prototype = Object.create(Node.prototype);\n\nfunction treeRoot(root) {\n var tree = new TreeNode(root, 0),\n node,\n nodes = [tree],\n child,\n children,\n i,\n n;\n\n while (node = nodes.pop()) {\n if (children = node._.children) {\n node.children = new Array(n = children.length);\n for (i = n - 1; i >= 0; --i) {\n nodes.push(child = node.children[i] = new TreeNode(children[i], i));\n child.parent = node;\n }\n }\n }\n\n (tree.parent = new TreeNode(null, 0)).children = [tree];\n return tree;\n}\n\n// Node-link tree diagram using the Reingold-Tilford \"tidy\" algorithm\nfunction tree() {\n var separation = defaultSeparation$1,\n dx = 1,\n dy = 1,\n nodeSize = null;\n\n function tree(root) {\n var t = treeRoot(root);\n\n // Compute the layout using Buchheim et al.’s algorithm.\n t.eachAfter(firstWalk), t.parent.m = -t.z;\n t.eachBefore(secondWalk);\n\n // If a fixed node size is specified, scale x and y.\n if (nodeSize) root.eachBefore(sizeNode);\n\n // If a fixed tree size is specified, scale x and y based on the extent.\n // Compute the left-most, right-most, and depth-most nodes for extents.\n else {\n var left = root,\n right = root,\n bottom = root;\n root.eachBefore(function(node) {\n if (node.x < left.x) left = node;\n if (node.x > right.x) right = node;\n if (node.depth > bottom.depth) bottom = node;\n });\n var s = left === right ? 1 : separation(left, right) / 2,\n tx = s - left.x,\n kx = dx / (right.x + s + tx),\n ky = dy / (bottom.depth || 1);\n root.eachBefore(function(node) {\n node.x = (node.x + tx) * kx;\n node.y = node.depth * ky;\n });\n }\n\n return root;\n }\n\n // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is\n // applied recursively to the children of v, as well as the function\n // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the\n // node v is placed to the midpoint of its outermost children.\n function firstWalk(v) {\n var children = v.children,\n siblings = v.parent.children,\n w = v.i ? siblings[v.i - 1] : null;\n if (children) {\n executeShifts(v);\n var midpoint = (children[0].z + children[children.length - 1].z) / 2;\n if (w) {\n v.z = w.z + separation(v._, w._);\n v.m = v.z - midpoint;\n } else {\n v.z = midpoint;\n }\n } else if (w) {\n v.z = w.z + separation(v._, w._);\n }\n v.parent.A = apportion(v, w, v.parent.A || siblings[0]);\n }\n\n // Computes all real x-coordinates by summing up the modifiers recursively.\n function secondWalk(v) {\n v._.x = v.z + v.parent.m;\n v.m += v.parent.m;\n }\n\n // The core of the algorithm. Here, a new subtree is combined with the\n // previous subtrees. Threads are used to traverse the inside and outside\n // contours of the left and right subtree up to the highest common level. The\n // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the\n // superscript o means outside and i means inside, the subscript - means left\n // subtree and + means right subtree. For summing up the modifiers along the\n // contour, we use respective variables si+, si-, so-, and so+. Whenever two\n // nodes of the inside contours conflict, we compute the left one of the\n // greatest uncommon ancestors using the function ANCESTOR and call MOVE\n // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.\n // Finally, we add a new thread (if necessary).\n function apportion(v, w, ancestor) {\n if (w) {\n var vip = v,\n vop = v,\n vim = w,\n vom = vip.parent.children[0],\n sip = vip.m,\n sop = vop.m,\n sim = vim.m,\n som = vom.m,\n shift;\n while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {\n vom = nextLeft(vom);\n vop = nextRight(vop);\n vop.a = v;\n shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);\n if (shift > 0) {\n moveSubtree(nextAncestor(vim, v, ancestor), v, shift);\n sip += shift;\n sop += shift;\n }\n sim += vim.m;\n sip += vip.m;\n som += vom.m;\n sop += vop.m;\n }\n if (vim && !nextRight(vop)) {\n vop.t = vim;\n vop.m += sim - sop;\n }\n if (vip && !nextLeft(vom)) {\n vom.t = vip;\n vom.m += sip - som;\n ancestor = v;\n }\n }\n return ancestor;\n }\n\n function sizeNode(node) {\n node.x *= dx;\n node.y = node.depth * dy;\n }\n\n tree.separation = function(x) {\n return arguments.length ? (separation = x, tree) : separation;\n };\n\n tree.size = function(x) {\n return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);\n };\n\n tree.nodeSize = function(x) {\n return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);\n };\n\n return tree;\n}\n\nfunction treemapSlice(parent, x0, y0, x1, y1) {\n var nodes = parent.children,\n node,\n i = -1,\n n = nodes.length,\n k = parent.value && (y1 - y0) / parent.value;\n\n while (++i < n) {\n node = nodes[i], node.x0 = x0, node.x1 = x1;\n node.y0 = y0, node.y1 = y0 += node.value * k;\n }\n}\n\nvar phi = (1 + Math.sqrt(5)) / 2;\n\nfunction squarifyRatio(ratio, parent, x0, y0, x1, y1) {\n var rows = [],\n nodes = parent.children,\n row,\n nodeValue,\n i0 = 0,\n i1 = 0,\n n = nodes.length,\n dx, dy,\n value = parent.value,\n sumValue,\n minValue,\n maxValue,\n newRatio,\n minRatio,\n alpha,\n beta;\n\n while (i0 < n) {\n dx = x1 - x0, dy = y1 - y0;\n\n // Find the next non-empty node.\n do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);\n minValue = maxValue = sumValue;\n alpha = Math.max(dy / dx, dx / dy) / (value * ratio);\n beta = sumValue * sumValue * alpha;\n minRatio = Math.max(maxValue / beta, beta / minValue);\n\n // Keep adding nodes while the aspect ratio maintains or improves.\n for (; i1 < n; ++i1) {\n sumValue += nodeValue = nodes[i1].value;\n if (nodeValue < minValue) minValue = nodeValue;\n if (nodeValue > maxValue) maxValue = nodeValue;\n beta = sumValue * sumValue * alpha;\n newRatio = Math.max(maxValue / beta, beta / minValue);\n if (newRatio > minRatio) { sumValue -= nodeValue; break; }\n minRatio = newRatio;\n }\n\n // Position and record the row orientation.\n rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});\n if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);\n else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);\n value -= sumValue, i0 = i1;\n }\n\n return rows;\n}\n\nvar squarify = (function custom(ratio) {\n\n function squarify(parent, x0, y0, x1, y1) {\n squarifyRatio(ratio, parent, x0, y0, x1, y1);\n }\n\n squarify.ratio = function(x) {\n return custom((x = +x) > 1 ? x : 1);\n };\n\n return squarify;\n})(phi);\n\nfunction index$3() {\n var tile = squarify,\n round = false,\n dx = 1,\n dy = 1,\n paddingStack = [0],\n paddingInner = constantZero,\n paddingTop = constantZero,\n paddingRight = constantZero,\n paddingBottom = constantZero,\n paddingLeft = constantZero;\n\n function treemap(root) {\n root.x0 =\n root.y0 = 0;\n root.x1 = dx;\n root.y1 = dy;\n root.eachBefore(positionNode);\n paddingStack = [0];\n if (round) root.eachBefore(roundNode);\n return root;\n }\n\n function positionNode(node) {\n var p = paddingStack[node.depth],\n x0 = node.x0 + p,\n y0 = node.y0 + p,\n x1 = node.x1 - p,\n y1 = node.y1 - p;\n if (x1 < x0) x0 = x1 = (x0 + x1) / 2;\n if (y1 < y0) y0 = y1 = (y0 + y1) / 2;\n node.x0 = x0;\n node.y0 = y0;\n node.x1 = x1;\n node.y1 = y1;\n if (node.children) {\n p = paddingStack[node.depth + 1] = paddingInner(node) / 2;\n x0 += paddingLeft(node) - p;\n y0 += paddingTop(node) - p;\n x1 -= paddingRight(node) - p;\n y1 -= paddingBottom(node) - p;\n if (x1 < x0) x0 = x1 = (x0 + x1) / 2;\n if (y1 < y0) y0 = y1 = (y0 + y1) / 2;\n tile(node, x0, y0, x1, y1);\n }\n }\n\n treemap.round = function(x) {\n return arguments.length ? (round = !!x, treemap) : round;\n };\n\n treemap.size = function(x) {\n return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];\n };\n\n treemap.tile = function(x) {\n return arguments.length ? (tile = required(x), treemap) : tile;\n };\n\n treemap.padding = function(x) {\n return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();\n };\n\n treemap.paddingInner = function(x) {\n return arguments.length ? (paddingInner = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingInner;\n };\n\n treemap.paddingOuter = function(x) {\n return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();\n };\n\n treemap.paddingTop = function(x) {\n return arguments.length ? (paddingTop = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingTop;\n };\n\n treemap.paddingRight = function(x) {\n return arguments.length ? (paddingRight = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingRight;\n };\n\n treemap.paddingBottom = function(x) {\n return arguments.length ? (paddingBottom = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingBottom;\n };\n\n treemap.paddingLeft = function(x) {\n return arguments.length ? (paddingLeft = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingLeft;\n };\n\n return treemap;\n}\n\nfunction binary(parent, x0, y0, x1, y1) {\n var nodes = parent.children,\n i, n = nodes.length,\n sum, sums = new Array(n + 1);\n\n for (sums[0] = sum = i = 0; i < n; ++i) {\n sums[i + 1] = sum += nodes[i].value;\n }\n\n partition(0, n, parent.value, x0, y0, x1, y1);\n\n function partition(i, j, value, x0, y0, x1, y1) {\n if (i >= j - 1) {\n var node = nodes[i];\n node.x0 = x0, node.y0 = y0;\n node.x1 = x1, node.y1 = y1;\n return;\n }\n\n var valueOffset = sums[i],\n valueTarget = (value / 2) + valueOffset,\n k = i + 1,\n hi = j - 1;\n\n while (k < hi) {\n var mid = k + hi >>> 1;\n if (sums[mid] < valueTarget) k = mid + 1;\n else hi = mid;\n }\n\n if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;\n\n var valueLeft = sums[k] - valueOffset,\n valueRight = value - valueLeft;\n\n if ((x1 - x0) > (y1 - y0)) {\n var xk = (x0 * valueRight + x1 * valueLeft) / value;\n partition(i, k, valueLeft, x0, y0, xk, y1);\n partition(k, j, valueRight, xk, y0, x1, y1);\n } else {\n var yk = (y0 * valueRight + y1 * valueLeft) / value;\n partition(i, k, valueLeft, x0, y0, x1, yk);\n partition(k, j, valueRight, x0, yk, x1, y1);\n }\n }\n}\n\nfunction sliceDice(parent, x0, y0, x1, y1) {\n (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);\n}\n\nvar resquarify = (function custom(ratio) {\n\n function resquarify(parent, x0, y0, x1, y1) {\n if ((rows = parent._squarify) && (rows.ratio === ratio)) {\n var rows,\n row,\n nodes,\n i,\n j = -1,\n n,\n m = rows.length,\n value = parent.value;\n\n while (++j < m) {\n row = rows[j], nodes = row.children;\n for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;\n if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);\n else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);\n value -= row.value;\n }\n } else {\n parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);\n rows.ratio = ratio;\n }\n }\n\n resquarify.ratio = function(x) {\n return custom((x = +x) > 1 ? x : 1);\n };\n\n return resquarify;\n})(phi);\n\nfunction area$1(polygon) {\n var i = -1,\n n = polygon.length,\n a,\n b = polygon[n - 1],\n area = 0;\n\n while (++i < n) {\n a = b;\n b = polygon[i];\n area += a[1] * b[0] - a[0] * b[1];\n }\n\n return area / 2;\n}\n\nfunction centroid$1(polygon) {\n var i = -1,\n n = polygon.length,\n x = 0,\n y = 0,\n a,\n b = polygon[n - 1],\n c,\n k = 0;\n\n while (++i < n) {\n a = b;\n b = polygon[i];\n k += c = a[0] * b[1] - b[0] * a[1];\n x += (a[0] + b[0]) * c;\n y += (a[1] + b[1]) * c;\n }\n\n return k *= 3, [x / k, y / k];\n}\n\n// Returns the 2D cross product of AB and AC vectors, i.e., the z-component of\n// the 3D cross product in a quadrant I Cartesian coordinate system (+x is\n// right, +y is up). Returns a positive value if ABC is counter-clockwise,\n// negative if clockwise, and zero if the points are collinear.\nfunction cross$1(a, b, c) {\n return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\n}\n\nfunction lexicographicOrder(a, b) {\n return a[0] - b[0] || a[1] - b[1];\n}\n\n// Computes the upper convex hull per the monotone chain algorithm.\n// Assumes points.length >= 3, is sorted by x, unique in y.\n// Returns an array of indices into points in left-to-right order.\nfunction computeUpperHullIndexes(points) {\n var n = points.length,\n indexes = [0, 1],\n size = 2;\n\n for (var i = 2; i < n; ++i) {\n while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;\n indexes[size++] = i;\n }\n\n return indexes.slice(0, size); // remove popped points\n}\n\nfunction hull(points) {\n if ((n = points.length) < 3) return null;\n\n var i,\n n,\n sortedPoints = new Array(n),\n flippedPoints = new Array(n);\n\n for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];\n sortedPoints.sort(lexicographicOrder);\n for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];\n\n var upperIndexes = computeUpperHullIndexes(sortedPoints),\n lowerIndexes = computeUpperHullIndexes(flippedPoints);\n\n // Construct the hull polygon, removing possible duplicate endpoints.\n var skipLeft = lowerIndexes[0] === upperIndexes[0],\n skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],\n hull = [];\n\n // Add upper hull in right-to-l order.\n // Then add lower hull in left-to-right order.\n for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);\n for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);\n\n return hull;\n}\n\nfunction contains$1(polygon, point) {\n var n = polygon.length,\n p = polygon[n - 1],\n x = point[0], y = point[1],\n x0 = p[0], y0 = p[1],\n x1, y1,\n inside = false;\n\n for (var i = 0; i < n; ++i) {\n p = polygon[i], x1 = p[0], y1 = p[1];\n if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;\n x0 = x1, y0 = y1;\n }\n\n return inside;\n}\n\nfunction length$2(polygon) {\n var i = -1,\n n = polygon.length,\n b = polygon[n - 1],\n xa,\n ya,\n xb = b[0],\n yb = b[1],\n perimeter = 0;\n\n while (++i < n) {\n xa = xb;\n ya = yb;\n b = polygon[i];\n xb = b[0];\n yb = b[1];\n xa -= xb;\n ya -= yb;\n perimeter += Math.sqrt(xa * xa + ya * ya);\n }\n\n return perimeter;\n}\n\nvar slice$4 = [].slice;\n\nvar noabort = {};\n\nfunction Queue(size) {\n this._size = size;\n this._call =\n this._error = null;\n this._tasks = [];\n this._data = [];\n this._waiting =\n this._active =\n this._ended =\n this._start = 0; // inside a synchronous task callback?\n}\n\nQueue.prototype = queue.prototype = {\n constructor: Queue,\n defer: function(callback) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback\");\n if (this._call) throw new Error(\"defer after await\");\n if (this._error != null) return this;\n var t = slice$4.call(arguments, 1);\n t.push(callback);\n ++this._waiting, this._tasks.push(t);\n poke$1(this);\n return this;\n },\n abort: function() {\n if (this._error == null) abort(this, new Error(\"abort\"));\n return this;\n },\n await: function(callback) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback\");\n if (this._call) throw new Error(\"multiple await\");\n this._call = function(error, results) { callback.apply(null, [error].concat(results)); };\n maybeNotify(this);\n return this;\n },\n awaitAll: function(callback) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback\");\n if (this._call) throw new Error(\"multiple await\");\n this._call = callback;\n maybeNotify(this);\n return this;\n }\n};\n\nfunction poke$1(q) {\n if (!q._start) {\n try { start$1(q); } // let the current task complete\n catch (e) {\n if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously\n else if (!q._data) throw e; // await callback errored synchronously\n }\n }\n}\n\nfunction start$1(q) {\n while (q._start = q._waiting && q._active < q._size) {\n var i = q._ended + q._active,\n t = q._tasks[i],\n j = t.length - 1,\n c = t[j];\n t[j] = end(q, i);\n --q._waiting, ++q._active;\n t = c.apply(null, t);\n if (!q._tasks[i]) continue; // task finished synchronously\n q._tasks[i] = t || noabort;\n }\n}\n\nfunction end(q, i) {\n return function(e, r) {\n if (!q._tasks[i]) return; // ignore multiple callbacks\n --q._active, ++q._ended;\n q._tasks[i] = null;\n if (q._error != null) return; // ignore secondary errors\n if (e != null) {\n abort(q, e);\n } else {\n q._data[i] = r;\n if (q._waiting) poke$1(q);\n else maybeNotify(q);\n }\n };\n}\n\nfunction abort(q, e) {\n var i = q._tasks.length, t;\n q._error = e; // ignore active callbacks\n q._data = undefined; // allow gc\n q._waiting = NaN; // prevent starting\n\n while (--i >= 0) {\n if (t = q._tasks[i]) {\n q._tasks[i] = null;\n if (t.abort) {\n try { t.abort(); }\n catch (e) { /* ignore */ }\n }\n }\n }\n\n q._active = NaN; // allow notification\n maybeNotify(q);\n}\n\nfunction maybeNotify(q) {\n if (!q._active && q._call) {\n var d = q._data;\n q._data = undefined; // allow gc\n q._call(q._error, d);\n }\n}\n\nfunction queue(concurrency) {\n if (concurrency == null) concurrency = Infinity;\n else if (!((concurrency = +concurrency) >= 1)) throw new Error(\"invalid concurrency\");\n return new Queue(concurrency);\n}\n\nfunction defaultSource$1() {\n return Math.random();\n}\n\nvar uniform = (function sourceRandomUniform(source) {\n function randomUniform(min, max) {\n min = min == null ? 0 : +min;\n max = max == null ? 1 : +max;\n if (arguments.length === 1) max = min, min = 0;\n else max -= min;\n return function() {\n return source() * max + min;\n };\n }\n\n randomUniform.source = sourceRandomUniform;\n\n return randomUniform;\n})(defaultSource$1);\n\nvar normal = (function sourceRandomNormal(source) {\n function randomNormal(mu, sigma) {\n var x, r;\n mu = mu == null ? 0 : +mu;\n sigma = sigma == null ? 1 : +sigma;\n return function() {\n var y;\n\n // If available, use the second previously-generated uniform random.\n if (x != null) y = x, x = null;\n\n // Otherwise, generate a new x and y.\n else do {\n x = source() * 2 - 1;\n y = source() * 2 - 1;\n r = x * x + y * y;\n } while (!r || r > 1);\n\n return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);\n };\n }\n\n randomNormal.source = sourceRandomNormal;\n\n return randomNormal;\n})(defaultSource$1);\n\nvar logNormal = (function sourceRandomLogNormal(source) {\n function randomLogNormal() {\n var randomNormal = normal.source(source).apply(this, arguments);\n return function() {\n return Math.exp(randomNormal());\n };\n }\n\n randomLogNormal.source = sourceRandomLogNormal;\n\n return randomLogNormal;\n})(defaultSource$1);\n\nvar irwinHall = (function sourceRandomIrwinHall(source) {\n function randomIrwinHall(n) {\n return function() {\n for (var sum = 0, i = 0; i < n; ++i) sum += source();\n return sum;\n };\n }\n\n randomIrwinHall.source = sourceRandomIrwinHall;\n\n return randomIrwinHall;\n})(defaultSource$1);\n\nvar bates = (function sourceRandomBates(source) {\n function randomBates(n) {\n var randomIrwinHall = irwinHall.source(source)(n);\n return function() {\n return randomIrwinHall() / n;\n };\n }\n\n randomBates.source = sourceRandomBates;\n\n return randomBates;\n})(defaultSource$1);\n\nvar exponential$1 = (function sourceRandomExponential(source) {\n function randomExponential(lambda) {\n return function() {\n return -Math.log(1 - source()) / lambda;\n };\n }\n\n randomExponential.source = sourceRandomExponential;\n\n return randomExponential;\n})(defaultSource$1);\n\nfunction request(url, callback) {\n var request,\n event = dispatch(\"beforesend\", \"progress\", \"load\", \"error\"),\n mimeType,\n headers = map$1(),\n xhr = new XMLHttpRequest,\n user = null,\n password = null,\n response,\n responseType,\n timeout = 0;\n\n // If IE does not support CORS, use XDomainRequest.\n if (typeof XDomainRequest !== \"undefined\"\n && !(\"withCredentials\" in xhr)\n && /^(http(s)?:)?\\/\\//.test(url)) xhr = new XDomainRequest;\n\n \"onload\" in xhr\n ? xhr.onload = xhr.onerror = xhr.ontimeout = respond\n : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };\n\n function respond(o) {\n var status = xhr.status, result;\n if (!status && hasResponse(xhr)\n || status >= 200 && status < 300\n || status === 304) {\n if (response) {\n try {\n result = response.call(request, xhr);\n } catch (e) {\n event.call(\"error\", request, e);\n return;\n }\n } else {\n result = xhr;\n }\n event.call(\"load\", request, result);\n } else {\n event.call(\"error\", request, o);\n }\n }\n\n xhr.onprogress = function(e) {\n event.call(\"progress\", request, e);\n };\n\n request = {\n header: function(name, value) {\n name = (name + \"\").toLowerCase();\n if (arguments.length < 2) return headers.get(name);\n if (value == null) headers.remove(name);\n else headers.set(name, value + \"\");\n return request;\n },\n\n // If mimeType is non-null and no Accept header is set, a default is used.\n mimeType: function(value) {\n if (!arguments.length) return mimeType;\n mimeType = value == null ? null : value + \"\";\n return request;\n },\n\n // Specifies what type the response value should take;\n // for instance, arraybuffer, blob, document, or text.\n responseType: function(value) {\n if (!arguments.length) return responseType;\n responseType = value;\n return request;\n },\n\n timeout: function(value) {\n if (!arguments.length) return timeout;\n timeout = +value;\n return request;\n },\n\n user: function(value) {\n return arguments.length < 1 ? user : (user = value == null ? null : value + \"\", request);\n },\n\n password: function(value) {\n return arguments.length < 1 ? password : (password = value == null ? null : value + \"\", request);\n },\n\n // Specify how to convert the response content to a specific type;\n // changes the callback value on \"load\" events.\n response: function(value) {\n response = value;\n return request;\n },\n\n // Alias for send(\"GET\", …).\n get: function(data, callback) {\n return request.send(\"GET\", data, callback);\n },\n\n // Alias for send(\"POST\", …).\n post: function(data, callback) {\n return request.send(\"POST\", data, callback);\n },\n\n // If callback is non-null, it will be used for error and load events.\n send: function(method, data, callback) {\n xhr.open(method, url, true, user, password);\n if (mimeType != null && !headers.has(\"accept\")) headers.set(\"accept\", mimeType + \",*/*\");\n if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });\n if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);\n if (responseType != null) xhr.responseType = responseType;\n if (timeout > 0) xhr.timeout = timeout;\n if (callback == null && typeof data === \"function\") callback = data, data = null;\n if (callback != null && callback.length === 1) callback = fixCallback(callback);\n if (callback != null) request.on(\"error\", callback).on(\"load\", function(xhr) { callback(null, xhr); });\n event.call(\"beforesend\", request, xhr);\n xhr.send(data == null ? null : data);\n return request;\n },\n\n abort: function() {\n xhr.abort();\n return request;\n },\n\n on: function() {\n var value = event.on.apply(event, arguments);\n return value === event ? request : value;\n }\n };\n\n if (callback != null) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n return request.get(callback);\n }\n\n return request;\n}\n\nfunction fixCallback(callback) {\n return function(error, xhr) {\n callback(error == null ? xhr : null);\n };\n}\n\nfunction hasResponse(xhr) {\n var type = xhr.responseType;\n return type && type !== \"text\"\n ? xhr.response // null on error\n : xhr.responseText; // \"\" on error\n}\n\nfunction type$1(defaultMimeType, response) {\n return function(url, callback) {\n var r = request(url).mimeType(defaultMimeType).response(response);\n if (callback != null) {\n if (typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n return r.get(callback);\n }\n return r;\n };\n}\n\nvar html = type$1(\"text/html\", function(xhr) {\n return document.createRange().createContextualFragment(xhr.responseText);\n});\n\nvar json = type$1(\"application/json\", function(xhr) {\n return JSON.parse(xhr.responseText);\n});\n\nvar text = type$1(\"text/plain\", function(xhr) {\n return xhr.responseText;\n});\n\nvar xml = type$1(\"application/xml\", function(xhr) {\n var xml = xhr.responseXML;\n if (!xml) throw new Error(\"parse error\");\n return xml;\n});\n\nfunction dsv$1(defaultMimeType, parse) {\n return function(url, row, callback) {\n if (arguments.length < 3) callback = row, row = null;\n var r = request(url).mimeType(defaultMimeType);\n r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };\n r.row(row);\n return callback ? r.get(callback) : r;\n };\n}\n\nfunction responseOf(parse, row) {\n return function(request$$1) {\n return parse(request$$1.responseText, row);\n };\n}\n\nvar csv$1 = dsv$1(\"text/csv\", csvParse);\n\nvar tsv$1 = dsv$1(\"text/tab-separated-values\", tsvParse);\n\nvar array$2 = Array.prototype;\n\nvar map$3 = array$2.map;\nvar slice$5 = array$2.slice;\n\nvar implicit = {name: \"implicit\"};\n\nfunction ordinal(range) {\n var index = map$1(),\n domain = [],\n unknown = implicit;\n\n range = range == null ? [] : slice$5.call(range);\n\n function scale(d) {\n var key = d + \"\", i = index.get(key);\n if (!i) {\n if (unknown !== implicit) return unknown;\n index.set(key, i = domain.push(d));\n }\n return range[(i - 1) % range.length];\n }\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [], index = map$1();\n var i = -1, n = _.length, d, key;\n while (++i < n) if (!index.has(key = (d = _[i]) + \"\")) index.set(key, domain.push(d));\n return scale;\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice$5.call(_), scale) : range.slice();\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.copy = function() {\n return ordinal()\n .domain(domain)\n .range(range)\n .unknown(unknown);\n };\n\n return scale;\n}\n\nfunction band() {\n var scale = ordinal().unknown(undefined),\n domain = scale.domain,\n ordinalRange = scale.range,\n range$$1 = [0, 1],\n step,\n bandwidth,\n round = false,\n paddingInner = 0,\n paddingOuter = 0,\n align = 0.5;\n\n delete scale.unknown;\n\n function rescale() {\n var n = domain().length,\n reverse = range$$1[1] < range$$1[0],\n start = range$$1[reverse - 0],\n stop = range$$1[1 - reverse];\n step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);\n if (round) step = Math.floor(step);\n start += (stop - start - step * (n - paddingInner)) * align;\n bandwidth = step * (1 - paddingInner);\n if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);\n var values = sequence(n).map(function(i) { return start + step * i; });\n return ordinalRange(reverse ? values.reverse() : values);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();\n };\n\n scale.rangeRound = function(_) {\n return range$$1 = [+_[0], +_[1]], round = true, rescale();\n };\n\n scale.bandwidth = function() {\n return bandwidth;\n };\n\n scale.step = function() {\n return step;\n };\n\n scale.round = function(_) {\n return arguments.length ? (round = !!_, rescale()) : round;\n };\n\n scale.padding = function(_) {\n return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n };\n\n scale.paddingInner = function(_) {\n return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n };\n\n scale.paddingOuter = function(_) {\n return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;\n };\n\n scale.align = function(_) {\n return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;\n };\n\n scale.copy = function() {\n return band()\n .domain(domain())\n .range(range$$1)\n .round(round)\n .paddingInner(paddingInner)\n .paddingOuter(paddingOuter)\n .align(align);\n };\n\n return rescale();\n}\n\nfunction pointish(scale) {\n var copy = scale.copy;\n\n scale.padding = scale.paddingOuter;\n delete scale.paddingInner;\n delete scale.paddingOuter;\n\n scale.copy = function() {\n return pointish(copy());\n };\n\n return scale;\n}\n\nfunction point$1() {\n return pointish(band().paddingInner(1));\n}\n\nfunction constant$9(x) {\n return function() {\n return x;\n };\n}\n\nfunction number$2(x) {\n return +x;\n}\n\nvar unit = [0, 1];\n\nfunction deinterpolateLinear(a, b) {\n return (b -= (a = +a))\n ? function(x) { return (x - a) / b; }\n : constant$9(b);\n}\n\nfunction deinterpolateClamp(deinterpolate) {\n return function(a, b) {\n var d = deinterpolate(a = +a, b = +b);\n return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };\n };\n}\n\nfunction reinterpolateClamp(reinterpolate) {\n return function(a, b) {\n var r = reinterpolate(a = +a, b = +b);\n return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };\n };\n}\n\nfunction bimap(domain, range, deinterpolate, reinterpolate) {\n var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];\n if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);\n else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);\n return function(x) { return r0(d0(x)); };\n}\n\nfunction polymap(domain, range, deinterpolate, reinterpolate) {\n var j = Math.min(domain.length, range.length) - 1,\n d = new Array(j),\n r = new Array(j),\n i = -1;\n\n // Reverse descending domains.\n if (domain[j] < domain[0]) {\n domain = domain.slice().reverse();\n range = range.slice().reverse();\n }\n\n while (++i < j) {\n d[i] = deinterpolate(domain[i], domain[i + 1]);\n r[i] = reinterpolate(range[i], range[i + 1]);\n }\n\n return function(x) {\n var i = bisectRight(domain, x, 1, j) - 1;\n return r[i](d[i](x));\n };\n}\n\nfunction copy(source, target) {\n return target\n .domain(source.domain())\n .range(source.range())\n .interpolate(source.interpolate())\n .clamp(source.clamp());\n}\n\n// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].\n// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].\nfunction continuous(deinterpolate, reinterpolate) {\n var domain = unit,\n range = unit,\n interpolate$$1 = interpolateValue,\n clamp = false,\n piecewise,\n output,\n input;\n\n function rescale() {\n piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap;\n output = input = null;\n return scale;\n }\n\n function scale(x) {\n return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);\n }\n\n scale.invert = function(y) {\n return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();\n };\n\n scale.rangeRound = function(_) {\n return range = slice$5.call(_), interpolate$$1 = interpolateRound, rescale();\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, rescale()) : clamp;\n };\n\n scale.interpolate = function(_) {\n return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;\n };\n\n return rescale();\n}\n\nfunction tickFormat(domain, count, specifier) {\n var start = domain[0],\n stop = domain[domain.length - 1],\n step = tickStep(start, stop, count == null ? 10 : count),\n precision;\n specifier = formatSpecifier(specifier == null ? \",f\" : specifier);\n switch (specifier.type) {\n case \"s\": {\n var value = Math.max(Math.abs(start), Math.abs(stop));\n if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n return exports.formatPrefix(specifier, value);\n }\n case \"\":\n case \"e\":\n case \"g\":\n case \"p\":\n case \"r\": {\n if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === \"e\");\n break;\n }\n case \"f\":\n case \"%\": {\n if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === \"%\") * 2;\n break;\n }\n }\n return exports.format(specifier);\n}\n\nfunction linearish(scale) {\n var domain = scale.domain;\n\n scale.ticks = function(count) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], count == null ? 10 : count);\n };\n\n scale.tickFormat = function(count, specifier) {\n return tickFormat(domain(), count, specifier);\n };\n\n scale.nice = function(count) {\n if (count == null) count = 10;\n\n var d = domain(),\n i0 = 0,\n i1 = d.length - 1,\n start = d[i0],\n stop = d[i1],\n step;\n\n if (stop < start) {\n step = start, start = stop, stop = step;\n step = i0, i0 = i1, i1 = step;\n }\n\n step = tickIncrement(start, stop, count);\n\n if (step > 0) {\n start = Math.floor(start / step) * step;\n stop = Math.ceil(stop / step) * step;\n step = tickIncrement(start, stop, count);\n } else if (step < 0) {\n start = Math.ceil(start * step) / step;\n stop = Math.floor(stop * step) / step;\n step = tickIncrement(start, stop, count);\n }\n\n if (step > 0) {\n d[i0] = Math.floor(start / step) * step;\n d[i1] = Math.ceil(stop / step) * step;\n domain(d);\n } else if (step < 0) {\n d[i0] = Math.ceil(start * step) / step;\n d[i1] = Math.floor(stop * step) / step;\n domain(d);\n }\n\n return scale;\n };\n\n return scale;\n}\n\nfunction linear$2() {\n var scale = continuous(deinterpolateLinear, reinterpolate);\n\n scale.copy = function() {\n return copy(scale, linear$2());\n };\n\n return linearish(scale);\n}\n\nfunction identity$6() {\n var domain = [0, 1];\n\n function scale(x) {\n return +x;\n }\n\n scale.invert = scale;\n\n scale.domain = scale.range = function(_) {\n return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice();\n };\n\n scale.copy = function() {\n return identity$6().domain(domain);\n };\n\n return linearish(scale);\n}\n\nfunction nice(domain, interval) {\n domain = domain.slice();\n\n var i0 = 0,\n i1 = domain.length - 1,\n x0 = domain[i0],\n x1 = domain[i1],\n t;\n\n if (x1 < x0) {\n t = i0, i0 = i1, i1 = t;\n t = x0, x0 = x1, x1 = t;\n }\n\n domain[i0] = interval.floor(x0);\n domain[i1] = interval.ceil(x1);\n return domain;\n}\n\nfunction deinterpolate(a, b) {\n return (b = Math.log(b / a))\n ? function(x) { return Math.log(x / a) / b; }\n : constant$9(b);\n}\n\nfunction reinterpolate$1(a, b) {\n return a < 0\n ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }\n : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };\n}\n\nfunction pow10(x) {\n return isFinite(x) ? +(\"1e\" + x) : x < 0 ? 0 : x;\n}\n\nfunction powp(base) {\n return base === 10 ? pow10\n : base === Math.E ? Math.exp\n : function(x) { return Math.pow(base, x); };\n}\n\nfunction logp(base) {\n return base === Math.E ? Math.log\n : base === 10 && Math.log10\n || base === 2 && Math.log2\n || (base = Math.log(base), function(x) { return Math.log(x) / base; });\n}\n\nfunction reflect(f) {\n return function(x) {\n return -f(-x);\n };\n}\n\nfunction log$1() {\n var scale = continuous(deinterpolate, reinterpolate$1).domain([1, 10]),\n domain = scale.domain,\n base = 10,\n logs = logp(10),\n pows = powp(10);\n\n function rescale() {\n logs = logp(base), pows = powp(base);\n if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);\n return scale;\n }\n\n scale.base = function(_) {\n return arguments.length ? (base = +_, rescale()) : base;\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.ticks = function(count) {\n var d = domain(),\n u = d[0],\n v = d[d.length - 1],\n r;\n\n if (r = v < u) i = u, u = v, v = i;\n\n var i = logs(u),\n j = logs(v),\n p,\n k,\n t,\n n = count == null ? 10 : +count,\n z = [];\n\n if (!(base % 1) && j - i < n) {\n i = Math.round(i) - 1, j = Math.round(j) + 1;\n if (u > 0) for (; i < j; ++i) {\n for (k = 1, p = pows(i); k < base; ++k) {\n t = p * k;\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n } else for (; i < j; ++i) {\n for (k = base - 1, p = pows(i); k >= 1; --k) {\n t = p * k;\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n }\n } else {\n z = ticks(i, j, Math.min(j - i, n)).map(pows);\n }\n\n return r ? z.reverse() : z;\n };\n\n scale.tickFormat = function(count, specifier) {\n if (specifier == null) specifier = base === 10 ? \".0e\" : \",\";\n if (typeof specifier !== \"function\") specifier = exports.format(specifier);\n if (count === Infinity) return specifier;\n if (count == null) count = 10;\n var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?\n return function(d) {\n var i = d / pows(Math.round(logs(d)));\n if (i * base < base - 0.5) i *= base;\n return i <= k ? specifier(d) : \"\";\n };\n };\n\n scale.nice = function() {\n return domain(nice(domain(), {\n floor: function(x) { return pows(Math.floor(logs(x))); },\n ceil: function(x) { return pows(Math.ceil(logs(x))); }\n }));\n };\n\n scale.copy = function() {\n return copy(scale, log$1().base(base));\n };\n\n return scale;\n}\n\nfunction raise$1(x, exponent) {\n return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);\n}\n\nfunction pow$1() {\n var exponent = 1,\n scale = continuous(deinterpolate, reinterpolate),\n domain = scale.domain;\n\n function deinterpolate(a, b) {\n return (b = raise$1(b, exponent) - (a = raise$1(a, exponent)))\n ? function(x) { return (raise$1(x, exponent) - a) / b; }\n : constant$9(b);\n }\n\n function reinterpolate(a, b) {\n b = raise$1(b, exponent) - (a = raise$1(a, exponent));\n return function(t) { return raise$1(a + b * t, 1 / exponent); };\n }\n\n scale.exponent = function(_) {\n return arguments.length ? (exponent = +_, domain(domain())) : exponent;\n };\n\n scale.copy = function() {\n return copy(scale, pow$1().exponent(exponent));\n };\n\n return linearish(scale);\n}\n\nfunction sqrt$1() {\n return pow$1().exponent(0.5);\n}\n\nfunction quantile$$1() {\n var domain = [],\n range = [],\n thresholds = [];\n\n function rescale() {\n var i = 0, n = Math.max(1, range.length);\n thresholds = new Array(n - 1);\n while (++i < n) thresholds[i - 1] = threshold(domain, i / n);\n return scale;\n }\n\n function scale(x) {\n if (!isNaN(x = +x)) return range[bisectRight(thresholds, x)];\n }\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN] : [\n i > 0 ? thresholds[i - 1] : domain[0],\n i < thresholds.length ? thresholds[i] : domain[domain.length - 1]\n ];\n };\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [];\n for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);\n domain.sort(ascending);\n return rescale();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();\n };\n\n scale.quantiles = function() {\n return thresholds.slice();\n };\n\n scale.copy = function() {\n return quantile$$1()\n .domain(domain)\n .range(range);\n };\n\n return scale;\n}\n\nfunction quantize$1() {\n var x0 = 0,\n x1 = 1,\n n = 1,\n domain = [0.5],\n range = [0, 1];\n\n function scale(x) {\n if (x <= x) return range[bisectRight(domain, x, 0, n)];\n }\n\n function rescale() {\n var i = -1;\n domain = new Array(n);\n while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);\n return scale;\n }\n\n scale.domain = function(_) {\n return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];\n };\n\n scale.range = function(_) {\n return arguments.length ? (n = (range = slice$5.call(_)).length - 1, rescale()) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN]\n : i < 1 ? [x0, domain[0]]\n : i >= n ? [domain[n - 1], x1]\n : [domain[i - 1], domain[i]];\n };\n\n scale.copy = function() {\n return quantize$1()\n .domain([x0, x1])\n .range(range);\n };\n\n return linearish(scale);\n}\n\nfunction threshold$1() {\n var domain = [0.5],\n range = [0, 1],\n n = 1;\n\n function scale(x) {\n if (x <= x) return range[bisectRight(domain, x, 0, n)];\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return [domain[i - 1], domain[i]];\n };\n\n scale.copy = function() {\n return threshold$1()\n .domain(domain)\n .range(range);\n };\n\n return scale;\n}\n\nvar t0$1 = new Date;\nvar t1$1 = new Date;\n\nfunction newInterval(floori, offseti, count, field) {\n\n function interval(date) {\n return floori(date = new Date(+date)), date;\n }\n\n interval.floor = interval;\n\n interval.ceil = function(date) {\n return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;\n };\n\n interval.round = function(date) {\n var d0 = interval(date),\n d1 = interval.ceil(date);\n return date - d0 < d1 - date ? d0 : d1;\n };\n\n interval.offset = function(date, step) {\n return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n };\n\n interval.range = function(start, stop, step) {\n var range = [], previous;\n start = interval.ceil(start);\n step = step == null ? 1 : Math.floor(step);\n if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n do range.push(previous = new Date(+start)), offseti(start, step), floori(start);\n while (previous < start && start < stop);\n return range;\n };\n\n interval.filter = function(test) {\n return newInterval(function(date) {\n if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);\n }, function(date, step) {\n if (date >= date) {\n if (step < 0) while (++step <= 0) {\n while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty\n } else while (--step >= 0) {\n while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty\n }\n }\n });\n };\n\n if (count) {\n interval.count = function(start, end) {\n t0$1.setTime(+start), t1$1.setTime(+end);\n floori(t0$1), floori(t1$1);\n return Math.floor(count(t0$1, t1$1));\n };\n\n interval.every = function(step) {\n step = Math.floor(step);\n return !isFinite(step) || !(step > 0) ? null\n : !(step > 1) ? interval\n : interval.filter(field\n ? function(d) { return field(d) % step === 0; }\n : function(d) { return interval.count(0, d) % step === 0; });\n };\n }\n\n return interval;\n}\n\nvar millisecond = newInterval(function() {\n // noop\n}, function(date, step) {\n date.setTime(+date + step);\n}, function(start, end) {\n return end - start;\n});\n\n// An optimized implementation for this simple case.\nmillisecond.every = function(k) {\n k = Math.floor(k);\n if (!isFinite(k) || !(k > 0)) return null;\n if (!(k > 1)) return millisecond;\n return newInterval(function(date) {\n date.setTime(Math.floor(date / k) * k);\n }, function(date, step) {\n date.setTime(+date + step * k);\n }, function(start, end) {\n return (end - start) / k;\n });\n};\n\nvar milliseconds = millisecond.range;\n\nvar durationSecond$1 = 1e3;\nvar durationMinute$1 = 6e4;\nvar durationHour$1 = 36e5;\nvar durationDay$1 = 864e5;\nvar durationWeek$1 = 6048e5;\n\nvar second = newInterval(function(date) {\n date.setTime(Math.floor(date / durationSecond$1) * durationSecond$1);\n}, function(date, step) {\n date.setTime(+date + step * durationSecond$1);\n}, function(start, end) {\n return (end - start) / durationSecond$1;\n}, function(date) {\n return date.getUTCSeconds();\n});\n\nvar seconds = second.range;\n\nvar minute = newInterval(function(date) {\n date.setTime(Math.floor(date / durationMinute$1) * durationMinute$1);\n}, function(date, step) {\n date.setTime(+date + step * durationMinute$1);\n}, function(start, end) {\n return (end - start) / durationMinute$1;\n}, function(date) {\n return date.getMinutes();\n});\n\nvar minutes = minute.range;\n\nvar hour = newInterval(function(date) {\n var offset = date.getTimezoneOffset() * durationMinute$1 % durationHour$1;\n if (offset < 0) offset += durationHour$1;\n date.setTime(Math.floor((+date - offset) / durationHour$1) * durationHour$1 + offset);\n}, function(date, step) {\n date.setTime(+date + step * durationHour$1);\n}, function(start, end) {\n return (end - start) / durationHour$1;\n}, function(date) {\n return date.getHours();\n});\n\nvar hours = hour.range;\n\nvar day = newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setDate(date.getDate() + step);\n}, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationDay$1;\n}, function(date) {\n return date.getDate() - 1;\n});\n\nvar days = day.range;\n\nfunction weekday(i) {\n return newInterval(function(date) {\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setDate(date.getDate() + step * 7);\n }, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationWeek$1;\n });\n}\n\nvar sunday = weekday(0);\nvar monday = weekday(1);\nvar tuesday = weekday(2);\nvar wednesday = weekday(3);\nvar thursday = weekday(4);\nvar friday = weekday(5);\nvar saturday = weekday(6);\n\nvar sundays = sunday.range;\nvar mondays = monday.range;\nvar tuesdays = tuesday.range;\nvar wednesdays = wednesday.range;\nvar thursdays = thursday.range;\nvar fridays = friday.range;\nvar saturdays = saturday.range;\n\nvar month = newInterval(function(date) {\n date.setDate(1);\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setMonth(date.getMonth() + step);\n}, function(start, end) {\n return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n}, function(date) {\n return date.getMonth();\n});\n\nvar months = month.range;\n\nvar year = newInterval(function(date) {\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setFullYear(date.getFullYear() + step);\n}, function(start, end) {\n return end.getFullYear() - start.getFullYear();\n}, function(date) {\n return date.getFullYear();\n});\n\n// An optimized implementation for this simple case.\nyear.every = function(k) {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {\n date.setFullYear(Math.floor(date.getFullYear() / k) * k);\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setFullYear(date.getFullYear() + step * k);\n });\n};\n\nvar years = year.range;\n\nvar utcMinute = newInterval(function(date) {\n date.setUTCSeconds(0, 0);\n}, function(date, step) {\n date.setTime(+date + step * durationMinute$1);\n}, function(start, end) {\n return (end - start) / durationMinute$1;\n}, function(date) {\n return date.getUTCMinutes();\n});\n\nvar utcMinutes = utcMinute.range;\n\nvar utcHour = newInterval(function(date) {\n date.setUTCMinutes(0, 0, 0);\n}, function(date, step) {\n date.setTime(+date + step * durationHour$1);\n}, function(start, end) {\n return (end - start) / durationHour$1;\n}, function(date) {\n return date.getUTCHours();\n});\n\nvar utcHours = utcHour.range;\n\nvar utcDay = newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step);\n}, function(start, end) {\n return (end - start) / durationDay$1;\n}, function(date) {\n return date.getUTCDate() - 1;\n});\n\nvar utcDays = utcDay.range;\n\nfunction utcWeekday(i) {\n return newInterval(function(date) {\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, function(start, end) {\n return (end - start) / durationWeek$1;\n });\n}\n\nvar utcSunday = utcWeekday(0);\nvar utcMonday = utcWeekday(1);\nvar utcTuesday = utcWeekday(2);\nvar utcWednesday = utcWeekday(3);\nvar utcThursday = utcWeekday(4);\nvar utcFriday = utcWeekday(5);\nvar utcSaturday = utcWeekday(6);\n\nvar utcSundays = utcSunday.range;\nvar utcMondays = utcMonday.range;\nvar utcTuesdays = utcTuesday.range;\nvar utcWednesdays = utcWednesday.range;\nvar utcThursdays = utcThursday.range;\nvar utcFridays = utcFriday.range;\nvar utcSaturdays = utcSaturday.range;\n\nvar utcMonth = newInterval(function(date) {\n date.setUTCDate(1);\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCMonth(date.getUTCMonth() + step);\n}, function(start, end) {\n return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n}, function(date) {\n return date.getUTCMonth();\n});\n\nvar utcMonths = utcMonth.range;\n\nvar utcYear = newInterval(function(date) {\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n}, function(start, end) {\n return end.getUTCFullYear() - start.getUTCFullYear();\n}, function(date) {\n return date.getUTCFullYear();\n});\n\n// An optimized implementation for this simple case.\nutcYear.every = function(k) {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {\n date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step * k);\n });\n};\n\nvar utcYears = utcYear.range;\n\nfunction localDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);\n date.setFullYear(d.y);\n return date;\n }\n return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);\n}\n\nfunction utcDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));\n date.setUTCFullYear(d.y);\n return date;\n }\n return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));\n}\n\nfunction newYear(y) {\n return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};\n}\n\nfunction formatLocale$1(locale) {\n var locale_dateTime = locale.dateTime,\n locale_date = locale.date,\n locale_time = locale.time,\n locale_periods = locale.periods,\n locale_weekdays = locale.days,\n locale_shortWeekdays = locale.shortDays,\n locale_months = locale.months,\n locale_shortMonths = locale.shortMonths;\n\n var periodRe = formatRe(locale_periods),\n periodLookup = formatLookup(locale_periods),\n weekdayRe = formatRe(locale_weekdays),\n weekdayLookup = formatLookup(locale_weekdays),\n shortWeekdayRe = formatRe(locale_shortWeekdays),\n shortWeekdayLookup = formatLookup(locale_shortWeekdays),\n monthRe = formatRe(locale_months),\n monthLookup = formatLookup(locale_months),\n shortMonthRe = formatRe(locale_shortMonths),\n shortMonthLookup = formatLookup(locale_shortMonths);\n\n var formats = {\n \"a\": formatShortWeekday,\n \"A\": formatWeekday,\n \"b\": formatShortMonth,\n \"B\": formatMonth,\n \"c\": null,\n \"d\": formatDayOfMonth,\n \"e\": formatDayOfMonth,\n \"f\": formatMicroseconds,\n \"H\": formatHour24,\n \"I\": formatHour12,\n \"j\": formatDayOfYear,\n \"L\": formatMilliseconds,\n \"m\": formatMonthNumber,\n \"M\": formatMinutes,\n \"p\": formatPeriod,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatSeconds,\n \"u\": formatWeekdayNumberMonday,\n \"U\": formatWeekNumberSunday,\n \"V\": formatWeekNumberISO,\n \"w\": formatWeekdayNumberSunday,\n \"W\": formatWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatYear,\n \"Y\": formatFullYear,\n \"Z\": formatZone,\n \"%\": formatLiteralPercent\n };\n\n var utcFormats = {\n \"a\": formatUTCShortWeekday,\n \"A\": formatUTCWeekday,\n \"b\": formatUTCShortMonth,\n \"B\": formatUTCMonth,\n \"c\": null,\n \"d\": formatUTCDayOfMonth,\n \"e\": formatUTCDayOfMonth,\n \"f\": formatUTCMicroseconds,\n \"H\": formatUTCHour24,\n \"I\": formatUTCHour12,\n \"j\": formatUTCDayOfYear,\n \"L\": formatUTCMilliseconds,\n \"m\": formatUTCMonthNumber,\n \"M\": formatUTCMinutes,\n \"p\": formatUTCPeriod,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatUTCSeconds,\n \"u\": formatUTCWeekdayNumberMonday,\n \"U\": formatUTCWeekNumberSunday,\n \"V\": formatUTCWeekNumberISO,\n \"w\": formatUTCWeekdayNumberSunday,\n \"W\": formatUTCWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatUTCYear,\n \"Y\": formatUTCFullYear,\n \"Z\": formatUTCZone,\n \"%\": formatLiteralPercent\n };\n\n var parses = {\n \"a\": parseShortWeekday,\n \"A\": parseWeekday,\n \"b\": parseShortMonth,\n \"B\": parseMonth,\n \"c\": parseLocaleDateTime,\n \"d\": parseDayOfMonth,\n \"e\": parseDayOfMonth,\n \"f\": parseMicroseconds,\n \"H\": parseHour24,\n \"I\": parseHour24,\n \"j\": parseDayOfYear,\n \"L\": parseMilliseconds,\n \"m\": parseMonthNumber,\n \"M\": parseMinutes,\n \"p\": parsePeriod,\n \"Q\": parseUnixTimestamp,\n \"s\": parseUnixTimestampSeconds,\n \"S\": parseSeconds,\n \"u\": parseWeekdayNumberMonday,\n \"U\": parseWeekNumberSunday,\n \"V\": parseWeekNumberISO,\n \"w\": parseWeekdayNumberSunday,\n \"W\": parseWeekNumberMonday,\n \"x\": parseLocaleDate,\n \"X\": parseLocaleTime,\n \"y\": parseYear,\n \"Y\": parseFullYear,\n \"Z\": parseZone,\n \"%\": parseLiteralPercent\n };\n\n // These recursive directive definitions must be deferred.\n formats.x = newFormat(locale_date, formats);\n formats.X = newFormat(locale_time, formats);\n formats.c = newFormat(locale_dateTime, formats);\n utcFormats.x = newFormat(locale_date, utcFormats);\n utcFormats.X = newFormat(locale_time, utcFormats);\n utcFormats.c = newFormat(locale_dateTime, utcFormats);\n\n function newFormat(specifier, formats) {\n return function(date) {\n var string = [],\n i = -1,\n j = 0,\n n = specifier.length,\n c,\n pad,\n format;\n\n if (!(date instanceof Date)) date = new Date(+date);\n\n while (++i < n) {\n if (specifier.charCodeAt(i) === 37) {\n string.push(specifier.slice(j, i));\n if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);\n else pad = c === \"e\" ? \" \" : \"0\";\n if (format = formats[c]) c = format(date, pad);\n string.push(c);\n j = i + 1;\n }\n }\n\n string.push(specifier.slice(j, i));\n return string.join(\"\");\n };\n }\n\n function newParse(specifier, newDate) {\n return function(string) {\n var d = newYear(1900),\n i = parseSpecifier(d, specifier, string += \"\", 0),\n week, day$$1;\n if (i != string.length) return null;\n\n // If a UNIX timestamp is specified, return it.\n if (\"Q\" in d) return new Date(d.Q);\n\n // The am-pm flag is 0 for AM, and 1 for PM.\n if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n\n // Convert day-of-week and week-of-year to day-of-year.\n if (\"V\" in d) {\n if (d.V < 1 || d.V > 53) return null;\n if (!(\"w\" in d)) d.w = 1;\n if (\"Z\" in d) {\n week = utcDate(newYear(d.y)), day$$1 = week.getUTCDay();\n week = day$$1 > 4 || day$$1 === 0 ? utcMonday.ceil(week) : utcMonday(week);\n week = utcDay.offset(week, (d.V - 1) * 7);\n d.y = week.getUTCFullYear();\n d.m = week.getUTCMonth();\n d.d = week.getUTCDate() + (d.w + 6) % 7;\n } else {\n week = newDate(newYear(d.y)), day$$1 = week.getDay();\n week = day$$1 > 4 || day$$1 === 0 ? monday.ceil(week) : monday(week);\n week = day.offset(week, (d.V - 1) * 7);\n d.y = week.getFullYear();\n d.m = week.getMonth();\n d.d = week.getDate() + (d.w + 6) % 7;\n }\n } else if (\"W\" in d || \"U\" in d) {\n if (!(\"w\" in d)) d.w = \"u\" in d ? d.u % 7 : \"W\" in d ? 1 : 0;\n day$$1 = \"Z\" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();\n d.m = 0;\n d.d = \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7;\n }\n\n // If a time zone is specified, all fields are interpreted as UTC and then\n // offset according to the specified time zone.\n if (\"Z\" in d) {\n d.H += d.Z / 100 | 0;\n d.M += d.Z % 100;\n return utcDate(d);\n }\n\n // Otherwise, all fields are in local time.\n return newDate(d);\n };\n }\n\n function parseSpecifier(d, specifier, string, j) {\n var i = 0,\n n = specifier.length,\n m = string.length,\n c,\n parse;\n\n while (i < n) {\n if (j >= m) return -1;\n c = specifier.charCodeAt(i++);\n if (c === 37) {\n c = specifier.charAt(i++);\n parse = parses[c in pads ? specifier.charAt(i++) : c];\n if (!parse || ((j = parse(d, string, j)) < 0)) return -1;\n } else if (c != string.charCodeAt(j++)) {\n return -1;\n }\n }\n\n return j;\n }\n\n function parsePeriod(d, string, i) {\n var n = periodRe.exec(string.slice(i));\n return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseShortWeekday(d, string, i) {\n var n = shortWeekdayRe.exec(string.slice(i));\n return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseWeekday(d, string, i) {\n var n = weekdayRe.exec(string.slice(i));\n return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseShortMonth(d, string, i) {\n var n = shortMonthRe.exec(string.slice(i));\n return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseMonth(d, string, i) {\n var n = monthRe.exec(string.slice(i));\n return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseLocaleDateTime(d, string, i) {\n return parseSpecifier(d, locale_dateTime, string, i);\n }\n\n function parseLocaleDate(d, string, i) {\n return parseSpecifier(d, locale_date, string, i);\n }\n\n function parseLocaleTime(d, string, i) {\n return parseSpecifier(d, locale_time, string, i);\n }\n\n function formatShortWeekday(d) {\n return locale_shortWeekdays[d.getDay()];\n }\n\n function formatWeekday(d) {\n return locale_weekdays[d.getDay()];\n }\n\n function formatShortMonth(d) {\n return locale_shortMonths[d.getMonth()];\n }\n\n function formatMonth(d) {\n return locale_months[d.getMonth()];\n }\n\n function formatPeriod(d) {\n return locale_periods[+(d.getHours() >= 12)];\n }\n\n function formatUTCShortWeekday(d) {\n return locale_shortWeekdays[d.getUTCDay()];\n }\n\n function formatUTCWeekday(d) {\n return locale_weekdays[d.getUTCDay()];\n }\n\n function formatUTCShortMonth(d) {\n return locale_shortMonths[d.getUTCMonth()];\n }\n\n function formatUTCMonth(d) {\n return locale_months[d.getUTCMonth()];\n }\n\n function formatUTCPeriod(d) {\n return locale_periods[+(d.getUTCHours() >= 12)];\n }\n\n return {\n format: function(specifier) {\n var f = newFormat(specifier += \"\", formats);\n f.toString = function() { return specifier; };\n return f;\n },\n parse: function(specifier) {\n var p = newParse(specifier += \"\", localDate);\n p.toString = function() { return specifier; };\n return p;\n },\n utcFormat: function(specifier) {\n var f = newFormat(specifier += \"\", utcFormats);\n f.toString = function() { return specifier; };\n return f;\n },\n utcParse: function(specifier) {\n var p = newParse(specifier, utcDate);\n p.toString = function() { return specifier; };\n return p;\n }\n };\n}\n\nvar pads = {\"-\": \"\", \"_\": \" \", \"0\": \"0\"};\nvar numberRe = /^\\s*\\d+/;\nvar percentRe = /^%/;\nvar requoteRe = /[\\\\^$*+?|[\\]().{}]/g;\n\nfunction pad(value, fill, width) {\n var sign = value < 0 ? \"-\" : \"\",\n string = (sign ? -value : value) + \"\",\n length = string.length;\n return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n}\n\nfunction requote(s) {\n return s.replace(requoteRe, \"\\\\$&\");\n}\n\nfunction formatRe(names) {\n return new RegExp(\"^(?:\" + names.map(requote).join(\"|\") + \")\", \"i\");\n}\n\nfunction formatLookup(names) {\n var map = {}, i = -1, n = names.length;\n while (++i < n) map[names[i].toLowerCase()] = i;\n return map;\n}\n\nfunction parseWeekdayNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.w = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekdayNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.u = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.U = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberISO(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.V = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.W = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseFullYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 4));\n return n ? (d.y = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;\n}\n\nfunction parseZone(d, string, i) {\n var n = /^(Z)|([+-]\\d\\d)(?::?(\\d\\d))?/.exec(string.slice(i, i + 6));\n return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || \"00\")), i + n[0].length) : -1;\n}\n\nfunction parseMonthNumber(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.m = n[0] - 1, i + n[0].length) : -1;\n}\n\nfunction parseDayOfMonth(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseDayOfYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseHour24(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.H = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMinutes(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.M = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.S = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMilliseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.L = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMicroseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 6));\n return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;\n}\n\nfunction parseLiteralPercent(d, string, i) {\n var n = percentRe.exec(string.slice(i, i + 1));\n return n ? i + n[0].length : -1;\n}\n\nfunction parseUnixTimestamp(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseUnixTimestampSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = (+n[0]) * 1000, i + n[0].length) : -1;\n}\n\nfunction formatDayOfMonth(d, p) {\n return pad(d.getDate(), p, 2);\n}\n\nfunction formatHour24(d, p) {\n return pad(d.getHours(), p, 2);\n}\n\nfunction formatHour12(d, p) {\n return pad(d.getHours() % 12 || 12, p, 2);\n}\n\nfunction formatDayOfYear(d, p) {\n return pad(1 + day.count(year(d), d), p, 3);\n}\n\nfunction formatMilliseconds(d, p) {\n return pad(d.getMilliseconds(), p, 3);\n}\n\nfunction formatMicroseconds(d, p) {\n return formatMilliseconds(d, p) + \"000\";\n}\n\nfunction formatMonthNumber(d, p) {\n return pad(d.getMonth() + 1, p, 2);\n}\n\nfunction formatMinutes(d, p) {\n return pad(d.getMinutes(), p, 2);\n}\n\nfunction formatSeconds(d, p) {\n return pad(d.getSeconds(), p, 2);\n}\n\nfunction formatWeekdayNumberMonday(d) {\n var day$$1 = d.getDay();\n return day$$1 === 0 ? 7 : day$$1;\n}\n\nfunction formatWeekNumberSunday(d, p) {\n return pad(sunday.count(year(d), d), p, 2);\n}\n\nfunction formatWeekNumberISO(d, p) {\n var day$$1 = d.getDay();\n d = (day$$1 >= 4 || day$$1 === 0) ? thursday(d) : thursday.ceil(d);\n return pad(thursday.count(year(d), d) + (year(d).getDay() === 4), p, 2);\n}\n\nfunction formatWeekdayNumberSunday(d) {\n return d.getDay();\n}\n\nfunction formatWeekNumberMonday(d, p) {\n return pad(monday.count(year(d), d), p, 2);\n}\n\nfunction formatYear(d, p) {\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatFullYear(d, p) {\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatZone(d) {\n var z = d.getTimezoneOffset();\n return (z > 0 ? \"-\" : (z *= -1, \"+\"))\n + pad(z / 60 | 0, \"0\", 2)\n + pad(z % 60, \"0\", 2);\n}\n\nfunction formatUTCDayOfMonth(d, p) {\n return pad(d.getUTCDate(), p, 2);\n}\n\nfunction formatUTCHour24(d, p) {\n return pad(d.getUTCHours(), p, 2);\n}\n\nfunction formatUTCHour12(d, p) {\n return pad(d.getUTCHours() % 12 || 12, p, 2);\n}\n\nfunction formatUTCDayOfYear(d, p) {\n return pad(1 + utcDay.count(utcYear(d), d), p, 3);\n}\n\nfunction formatUTCMilliseconds(d, p) {\n return pad(d.getUTCMilliseconds(), p, 3);\n}\n\nfunction formatUTCMicroseconds(d, p) {\n return formatUTCMilliseconds(d, p) + \"000\";\n}\n\nfunction formatUTCMonthNumber(d, p) {\n return pad(d.getUTCMonth() + 1, p, 2);\n}\n\nfunction formatUTCMinutes(d, p) {\n return pad(d.getUTCMinutes(), p, 2);\n}\n\nfunction formatUTCSeconds(d, p) {\n return pad(d.getUTCSeconds(), p, 2);\n}\n\nfunction formatUTCWeekdayNumberMonday(d) {\n var dow = d.getUTCDay();\n return dow === 0 ? 7 : dow;\n}\n\nfunction formatUTCWeekNumberSunday(d, p) {\n return pad(utcSunday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCWeekNumberISO(d, p) {\n var day$$1 = d.getUTCDay();\n d = (day$$1 >= 4 || day$$1 === 0) ? utcThursday(d) : utcThursday.ceil(d);\n return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);\n}\n\nfunction formatUTCWeekdayNumberSunday(d) {\n return d.getUTCDay();\n}\n\nfunction formatUTCWeekNumberMonday(d, p) {\n return pad(utcMonday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCYear(d, p) {\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCFullYear(d, p) {\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCZone() {\n return \"+0000\";\n}\n\nfunction formatLiteralPercent() {\n return \"%\";\n}\n\nfunction formatUnixTimestamp(d) {\n return +d;\n}\n\nfunction formatUnixTimestampSeconds(d) {\n return Math.floor(+d / 1000);\n}\n\nvar locale$1;\n\n\n\n\n\ndefaultLocale$1({\n dateTime: \"%x, %X\",\n date: \"%-m/%-d/%Y\",\n time: \"%-I:%M:%S %p\",\n periods: [\"AM\", \"PM\"],\n days: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n shortDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n shortMonths: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n});\n\nfunction defaultLocale$1(definition) {\n locale$1 = formatLocale$1(definition);\n exports.timeFormat = locale$1.format;\n exports.timeParse = locale$1.parse;\n exports.utcFormat = locale$1.utcFormat;\n exports.utcParse = locale$1.utcParse;\n return locale$1;\n}\n\nvar isoSpecifier = \"%Y-%m-%dT%H:%M:%S.%LZ\";\n\nfunction formatIsoNative(date) {\n return date.toISOString();\n}\n\nvar formatIso = Date.prototype.toISOString\n ? formatIsoNative\n : exports.utcFormat(isoSpecifier);\n\nfunction parseIsoNative(string) {\n var date = new Date(string);\n return isNaN(date) ? null : date;\n}\n\nvar parseIso = +new Date(\"2000-01-01T00:00:00.000Z\")\n ? parseIsoNative\n : exports.utcParse(isoSpecifier);\n\nvar durationSecond = 1000;\nvar durationMinute = durationSecond * 60;\nvar durationHour = durationMinute * 60;\nvar durationDay = durationHour * 24;\nvar durationWeek = durationDay * 7;\nvar durationMonth = durationDay * 30;\nvar durationYear = durationDay * 365;\n\nfunction date$1(t) {\n return new Date(t);\n}\n\nfunction number$3(t) {\n return t instanceof Date ? +t : +new Date(+t);\n}\n\nfunction calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {\n var scale = continuous(deinterpolateLinear, reinterpolate),\n invert = scale.invert,\n domain = scale.domain;\n\n var formatMillisecond = format(\".%L\"),\n formatSecond = format(\":%S\"),\n formatMinute = format(\"%I:%M\"),\n formatHour = format(\"%I %p\"),\n formatDay = format(\"%a %d\"),\n formatWeek = format(\"%b %d\"),\n formatMonth = format(\"%B\"),\n formatYear = format(\"%Y\");\n\n var tickIntervals = [\n [second$$1, 1, durationSecond],\n [second$$1, 5, 5 * durationSecond],\n [second$$1, 15, 15 * durationSecond],\n [second$$1, 30, 30 * durationSecond],\n [minute$$1, 1, durationMinute],\n [minute$$1, 5, 5 * durationMinute],\n [minute$$1, 15, 15 * durationMinute],\n [minute$$1, 30, 30 * durationMinute],\n [ hour$$1, 1, durationHour ],\n [ hour$$1, 3, 3 * durationHour ],\n [ hour$$1, 6, 6 * durationHour ],\n [ hour$$1, 12, 12 * durationHour ],\n [ day$$1, 1, durationDay ],\n [ day$$1, 2, 2 * durationDay ],\n [ week, 1, durationWeek ],\n [ month$$1, 1, durationMonth ],\n [ month$$1, 3, 3 * durationMonth ],\n [ year$$1, 1, durationYear ]\n ];\n\n function tickFormat(date) {\n return (second$$1(date) < date ? formatMillisecond\n : minute$$1(date) < date ? formatSecond\n : hour$$1(date) < date ? formatMinute\n : day$$1(date) < date ? formatHour\n : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)\n : year$$1(date) < date ? formatMonth\n : formatYear)(date);\n }\n\n function tickInterval(interval, start, stop, step) {\n if (interval == null) interval = 10;\n\n // If a desired tick count is specified, pick a reasonable tick interval\n // based on the extent of the domain and a rough estimate of tick size.\n // Otherwise, assume interval is already a time interval and use it.\n if (typeof interval === \"number\") {\n var target = Math.abs(stop - start) / interval,\n i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);\n if (i === tickIntervals.length) {\n step = tickStep(start / durationYear, stop / durationYear, interval);\n interval = year$$1;\n } else if (i) {\n i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];\n step = i[1];\n interval = i[0];\n } else {\n step = Math.max(tickStep(start, stop, interval), 1);\n interval = millisecond$$1;\n }\n }\n\n return step == null ? interval : interval.every(step);\n }\n\n scale.invert = function(y) {\n return new Date(invert(y));\n };\n\n scale.domain = function(_) {\n return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$1);\n };\n\n scale.ticks = function(interval, step) {\n var d = domain(),\n t0 = d[0],\n t1 = d[d.length - 1],\n r = t1 < t0,\n t;\n if (r) t = t0, t0 = t1, t1 = t;\n t = tickInterval(interval, t0, t1, step);\n t = t ? t.range(t0, t1 + 1) : []; // inclusive stop\n return r ? t.reverse() : t;\n };\n\n scale.tickFormat = function(count, specifier) {\n return specifier == null ? tickFormat : format(specifier);\n };\n\n scale.nice = function(interval, step) {\n var d = domain();\n return (interval = tickInterval(interval, d[0], d[d.length - 1], step))\n ? domain(nice(d, interval))\n : scale;\n };\n\n scale.copy = function() {\n return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));\n };\n\n return scale;\n}\n\nfunction time() {\n return calendar(year, month, sunday, day, hour, minute, second, millisecond, exports.timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);\n}\n\nfunction utcTime() {\n return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, exports.utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);\n}\n\nfunction colors(s) {\n return s.match(/.{6}/g).map(function(x) {\n return \"#\" + x;\n });\n}\n\nvar category10 = colors(\"1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf\");\n\nvar category20b = colors(\"393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6\");\n\nvar category20c = colors(\"3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9\");\n\nvar category20 = colors(\"1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5\");\n\nvar cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));\n\nvar warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));\n\nvar cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));\n\nvar rainbow = cubehelix();\n\nfunction rainbow$1(t) {\n if (t < 0 || t > 1) t -= Math.floor(t);\n var ts = Math.abs(t - 0.5);\n rainbow.h = 360 * t - 100;\n rainbow.s = 1.5 - 1.5 * ts;\n rainbow.l = 0.8 - 0.9 * ts;\n return rainbow + \"\";\n}\n\nfunction ramp(range) {\n var n = range.length;\n return function(t) {\n return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];\n };\n}\n\nvar viridis = ramp(colors(\"44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725\"));\n\nvar magma = ramp(colors(\"00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf\"));\n\nvar inferno = ramp(colors(\"00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4\"));\n\nvar plasma = ramp(colors(\"0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921\"));\n\nfunction sequential(interpolator) {\n var x0 = 0,\n x1 = 1,\n clamp = false;\n\n function scale(x) {\n var t = (x - x0) / (x1 - x0);\n return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, scale) : clamp;\n };\n\n scale.interpolator = function(_) {\n return arguments.length ? (interpolator = _, scale) : interpolator;\n };\n\n scale.copy = function() {\n return sequential(interpolator).domain([x0, x1]).clamp(clamp);\n };\n\n return linearish(scale);\n}\n\nfunction constant$10(x) {\n return function constant() {\n return x;\n };\n}\n\nvar abs$1 = Math.abs;\nvar atan2$1 = Math.atan2;\nvar cos$2 = Math.cos;\nvar max$2 = Math.max;\nvar min$1 = Math.min;\nvar sin$2 = Math.sin;\nvar sqrt$2 = Math.sqrt;\n\nvar epsilon$3 = 1e-12;\nvar pi$4 = Math.PI;\nvar halfPi$3 = pi$4 / 2;\nvar tau$4 = 2 * pi$4;\n\nfunction acos$1(x) {\n return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);\n}\n\nfunction asin$1(x) {\n return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x);\n}\n\nfunction arcInnerRadius(d) {\n return d.innerRadius;\n}\n\nfunction arcOuterRadius(d) {\n return d.outerRadius;\n}\n\nfunction arcStartAngle(d) {\n return d.startAngle;\n}\n\nfunction arcEndAngle(d) {\n return d.endAngle;\n}\n\nfunction arcPadAngle(d) {\n return d && d.padAngle; // Note: optional!\n}\n\nfunction intersect(x0, y0, x1, y1, x2, y2, x3, y3) {\n var x10 = x1 - x0, y10 = y1 - y0,\n x32 = x3 - x2, y32 = y3 - y2,\n t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);\n return [x0 + t * x10, y0 + t * y10];\n}\n\n// Compute perpendicular offset line of length rc.\n// http://mathworld.wolfram.com/Circle-LineIntersection.html\nfunction cornerTangents(x0, y0, x1, y1, r1, rc, cw) {\n var x01 = x0 - x1,\n y01 = y0 - y1,\n lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01),\n ox = lo * y01,\n oy = -lo * x01,\n x11 = x0 + ox,\n y11 = y0 + oy,\n x10 = x1 + ox,\n y10 = y1 + oy,\n x00 = (x11 + x10) / 2,\n y00 = (y11 + y10) / 2,\n dx = x10 - x11,\n dy = y10 - y11,\n d2 = dx * dx + dy * dy,\n r = r1 - rc,\n D = x11 * y10 - x10 * y11,\n d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)),\n cx0 = (D * dy - dx * d) / d2,\n cy0 = (-D * dx - dy * d) / d2,\n cx1 = (D * dy + dx * d) / d2,\n cy1 = (-D * dx + dy * d) / d2,\n dx0 = cx0 - x00,\n dy0 = cy0 - y00,\n dx1 = cx1 - x00,\n dy1 = cy1 - y00;\n\n // Pick the closer of the two intersection points.\n // TODO Is there a faster way to determine which intersection to use?\n if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n\n return {\n cx: cx0,\n cy: cy0,\n x01: -ox,\n y01: -oy,\n x11: cx0 * (r1 / r - 1),\n y11: cy0 * (r1 / r - 1)\n };\n}\n\nfunction arc() {\n var innerRadius = arcInnerRadius,\n outerRadius = arcOuterRadius,\n cornerRadius = constant$10(0),\n padRadius = null,\n startAngle = arcStartAngle,\n endAngle = arcEndAngle,\n padAngle = arcPadAngle,\n context = null;\n\n function arc() {\n var buffer,\n r,\n r0 = +innerRadius.apply(this, arguments),\n r1 = +outerRadius.apply(this, arguments),\n a0 = startAngle.apply(this, arguments) - halfPi$3,\n a1 = endAngle.apply(this, arguments) - halfPi$3,\n da = abs$1(a1 - a0),\n cw = a1 > a0;\n\n if (!context) context = buffer = path();\n\n // Ensure that the outer radius is always larger than the inner radius.\n if (r1 < r0) r = r1, r1 = r0, r0 = r;\n\n // Is it a point?\n if (!(r1 > epsilon$3)) context.moveTo(0, 0);\n\n // Or is it a circle or annulus?\n else if (da > tau$4 - epsilon$3) {\n context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0));\n context.arc(0, 0, r1, a0, a1, !cw);\n if (r0 > epsilon$3) {\n context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1));\n context.arc(0, 0, r0, a1, a0, cw);\n }\n }\n\n // Or is it a circular or annular sector?\n else {\n var a01 = a0,\n a11 = a1,\n a00 = a0,\n a10 = a1,\n da0 = da,\n da1 = da,\n ap = padAngle.apply(this, arguments) / 2,\n rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)),\n rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),\n rc0 = rc,\n rc1 = rc,\n t0,\n t1;\n\n // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.\n if (rp > epsilon$3) {\n var p0 = asin$1(rp / r0 * sin$2(ap)),\n p1 = asin$1(rp / r1 * sin$2(ap));\n if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;\n else da0 = 0, a00 = a10 = (a0 + a1) / 2;\n if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;\n else da1 = 0, a01 = a11 = (a0 + a1) / 2;\n }\n\n var x01 = r1 * cos$2(a01),\n y01 = r1 * sin$2(a01),\n x10 = r0 * cos$2(a10),\n y10 = r0 * sin$2(a10);\n\n // Apply rounded corners?\n if (rc > epsilon$3) {\n var x11 = r1 * cos$2(a11),\n y11 = r1 * sin$2(a11),\n x00 = r0 * cos$2(a00),\n y00 = r0 * sin$2(a00);\n\n // Restrict the corner radius according to the sector angle.\n if (da < pi$4) {\n var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],\n ax = x01 - oc[0],\n ay = y01 - oc[1],\n bx = x11 - oc[0],\n by = y11 - oc[1],\n kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2),\n lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]);\n rc0 = min$1(rc, (r0 - lc) / (kc - 1));\n rc1 = min$1(rc, (r1 - lc) / (kc + 1));\n }\n }\n\n // Is the sector collapsed to a line?\n if (!(da1 > epsilon$3)) context.moveTo(x01, y01);\n\n // Does the sector’s outer ring have rounded corners?\n else if (rc1 > epsilon$3) {\n t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);\n t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);\n\n context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r1, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), !cw);\n context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the outer ring just a circular arc?\n else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);\n\n // Is there no inner ring, and it’s a circular sector?\n // Or perhaps it’s an annular sector collapsed due to padding?\n if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);\n\n // Does the sector’s inner ring (or point) have rounded corners?\n else if (rc0 > epsilon$3) {\n t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);\n t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);\n\n context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r0, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), cw);\n context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the inner ring just a circular arc?\n else context.arc(0, 0, r0, a10, a00, cw);\n }\n\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n arc.centroid = function() {\n var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,\n a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2;\n return [cos$2(a) * r, sin$2(a) * r];\n };\n\n arc.innerRadius = function(_) {\n return arguments.length ? (innerRadius = typeof _ === \"function\" ? _ : constant$10(+_), arc) : innerRadius;\n };\n\n arc.outerRadius = function(_) {\n return arguments.length ? (outerRadius = typeof _ === \"function\" ? _ : constant$10(+_), arc) : outerRadius;\n };\n\n arc.cornerRadius = function(_) {\n return arguments.length ? (cornerRadius = typeof _ === \"function\" ? _ : constant$10(+_), arc) : cornerRadius;\n };\n\n arc.padRadius = function(_) {\n return arguments.length ? (padRadius = _ == null ? null : typeof _ === \"function\" ? _ : constant$10(+_), arc) : padRadius;\n };\n\n arc.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant$10(+_), arc) : startAngle;\n };\n\n arc.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant$10(+_), arc) : endAngle;\n };\n\n arc.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant$10(+_), arc) : padAngle;\n };\n\n arc.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, arc) : context;\n };\n\n return arc;\n}\n\nfunction Linear(context) {\n this._context = context;\n}\n\nLinear.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: this._context.lineTo(x, y); break;\n }\n }\n};\n\nfunction curveLinear(context) {\n return new Linear(context);\n}\n\nfunction x$3(p) {\n return p[0];\n}\n\nfunction y$3(p) {\n return p[1];\n}\n\nfunction line() {\n var x$$1 = x$3,\n y$$1 = y$3,\n defined = constant$10(true),\n context = null,\n curve = curveLinear,\n output = null;\n\n function line(data) {\n var i,\n n = data.length,\n d,\n defined0 = false,\n buffer;\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) output.lineStart();\n else output.lineEnd();\n }\n if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n line.x = function(_) {\n return arguments.length ? (x$$1 = typeof _ === \"function\" ? _ : constant$10(+_), line) : x$$1;\n };\n\n line.y = function(_) {\n return arguments.length ? (y$$1 = typeof _ === \"function\" ? _ : constant$10(+_), line) : y$$1;\n };\n\n line.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant$10(!!_), line) : defined;\n };\n\n line.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;\n };\n\n line.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;\n };\n\n return line;\n}\n\nfunction area$2() {\n var x0 = x$3,\n x1 = null,\n y0 = constant$10(0),\n y1 = y$3,\n defined = constant$10(true),\n context = null,\n curve = curveLinear,\n output = null;\n\n function area(data) {\n var i,\n j,\n k,\n n = data.length,\n d,\n defined0 = false,\n buffer,\n x0z = new Array(n),\n y0z = new Array(n);\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) {\n j = i;\n output.areaStart();\n output.lineStart();\n } else {\n output.lineEnd();\n output.lineStart();\n for (k = i - 1; k >= j; --k) {\n output.point(x0z[k], y0z[k]);\n }\n output.lineEnd();\n output.areaEnd();\n }\n }\n if (defined0) {\n x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);\n output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);\n }\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n function arealine() {\n return line().defined(defined).curve(curve).context(context);\n }\n\n area.x = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant$10(+_), x1 = null, area) : x0;\n };\n\n area.x0 = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant$10(+_), area) : x0;\n };\n\n area.x1 = function(_) {\n return arguments.length ? (x1 = _ == null ? null : typeof _ === \"function\" ? _ : constant$10(+_), area) : x1;\n };\n\n area.y = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant$10(+_), y1 = null, area) : y0;\n };\n\n area.y0 = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant$10(+_), area) : y0;\n };\n\n area.y1 = function(_) {\n return arguments.length ? (y1 = _ == null ? null : typeof _ === \"function\" ? _ : constant$10(+_), area) : y1;\n };\n\n area.lineX0 =\n area.lineY0 = function() {\n return arealine().x(x0).y(y0);\n };\n\n area.lineY1 = function() {\n return arealine().x(x0).y(y1);\n };\n\n area.lineX1 = function() {\n return arealine().x(x1).y(y0);\n };\n\n area.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant$10(!!_), area) : defined;\n };\n\n area.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;\n };\n\n area.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;\n };\n\n return area;\n}\n\nfunction descending$1(a, b) {\n return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n}\n\nfunction identity$7(d) {\n return d;\n}\n\nfunction pie() {\n var value = identity$7,\n sortValues = descending$1,\n sort = null,\n startAngle = constant$10(0),\n endAngle = constant$10(tau$4),\n padAngle = constant$10(0);\n\n function pie(data) {\n var i,\n n = data.length,\n j,\n k,\n sum = 0,\n index = new Array(n),\n arcs = new Array(n),\n a0 = +startAngle.apply(this, arguments),\n da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)),\n a1,\n p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),\n pa = p * (da < 0 ? -1 : 1),\n v;\n\n for (i = 0; i < n; ++i) {\n if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {\n sum += v;\n }\n }\n\n // Optionally sort the arcs by previously-computed values or by data.\n if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });\n else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });\n\n // Compute the arcs! They are stored in the original data's order.\n for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {\n j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {\n data: data[j],\n index: i,\n value: v,\n startAngle: a0,\n endAngle: a1,\n padAngle: p\n };\n }\n\n return arcs;\n }\n\n pie.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant$10(+_), pie) : value;\n };\n\n pie.sortValues = function(_) {\n return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;\n };\n\n pie.sort = function(_) {\n return arguments.length ? (sort = _, sortValues = null, pie) : sort;\n };\n\n pie.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant$10(+_), pie) : startAngle;\n };\n\n pie.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant$10(+_), pie) : endAngle;\n };\n\n pie.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant$10(+_), pie) : padAngle;\n };\n\n return pie;\n}\n\nvar curveRadialLinear = curveRadial(curveLinear);\n\nfunction Radial(curve) {\n this._curve = curve;\n}\n\nRadial.prototype = {\n areaStart: function() {\n this._curve.areaStart();\n },\n areaEnd: function() {\n this._curve.areaEnd();\n },\n lineStart: function() {\n this._curve.lineStart();\n },\n lineEnd: function() {\n this._curve.lineEnd();\n },\n point: function(a, r) {\n this._curve.point(r * Math.sin(a), r * -Math.cos(a));\n }\n};\n\nfunction curveRadial(curve) {\n\n function radial(context) {\n return new Radial(curve(context));\n }\n\n radial._curve = curve;\n\n return radial;\n}\n\nfunction lineRadial(l) {\n var c = l.curve;\n\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n\n l.curve = function(_) {\n return arguments.length ? c(curveRadial(_)) : c()._curve;\n };\n\n return l;\n}\n\nfunction lineRadial$1() {\n return lineRadial(line().curve(curveRadialLinear));\n}\n\nfunction areaRadial() {\n var a = area$2().curve(curveRadialLinear),\n c = a.curve,\n x0 = a.lineX0,\n x1 = a.lineX1,\n y0 = a.lineY0,\n y1 = a.lineY1;\n\n a.angle = a.x, delete a.x;\n a.startAngle = a.x0, delete a.x0;\n a.endAngle = a.x1, delete a.x1;\n a.radius = a.y, delete a.y;\n a.innerRadius = a.y0, delete a.y0;\n a.outerRadius = a.y1, delete a.y1;\n a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;\n a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;\n a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;\n a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;\n\n a.curve = function(_) {\n return arguments.length ? c(curveRadial(_)) : c()._curve;\n };\n\n return a;\n}\n\nfunction pointRadial(x, y) {\n return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];\n}\n\nvar slice$6 = Array.prototype.slice;\n\nfunction linkSource(d) {\n return d.source;\n}\n\nfunction linkTarget(d) {\n return d.target;\n}\n\nfunction link$2(curve) {\n var source = linkSource,\n target = linkTarget,\n x$$1 = x$3,\n y$$1 = y$3,\n context = null;\n\n function link() {\n var buffer, argv = slice$6.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n if (!context) context = buffer = path();\n curve(context, +x$$1.apply(this, (argv[0] = s, argv)), +y$$1.apply(this, argv), +x$$1.apply(this, (argv[0] = t, argv)), +y$$1.apply(this, argv));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n link.source = function(_) {\n return arguments.length ? (source = _, link) : source;\n };\n\n link.target = function(_) {\n return arguments.length ? (target = _, link) : target;\n };\n\n link.x = function(_) {\n return arguments.length ? (x$$1 = typeof _ === \"function\" ? _ : constant$10(+_), link) : x$$1;\n };\n\n link.y = function(_) {\n return arguments.length ? (y$$1 = typeof _ === \"function\" ? _ : constant$10(+_), link) : y$$1;\n };\n\n link.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, link) : context;\n };\n\n return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial$1(context, x0, y0, x1, y1) {\n var p0 = pointRadial(x0, y0),\n p1 = pointRadial(x0, y0 = (y0 + y1) / 2),\n p2 = pointRadial(x1, y0),\n p3 = pointRadial(x1, y1);\n context.moveTo(p0[0], p0[1]);\n context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nfunction linkHorizontal() {\n return link$2(curveHorizontal);\n}\n\nfunction linkVertical() {\n return link$2(curveVertical);\n}\n\nfunction linkRadial() {\n var l = link$2(curveRadial$1);\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n return l;\n}\n\nvar circle$2 = {\n draw: function(context, size) {\n var r = Math.sqrt(size / pi$4);\n context.moveTo(r, 0);\n context.arc(0, 0, r, 0, tau$4);\n }\n};\n\nvar cross$2 = {\n draw: function(context, size) {\n var r = Math.sqrt(size / 5) / 2;\n context.moveTo(-3 * r, -r);\n context.lineTo(-r, -r);\n context.lineTo(-r, -3 * r);\n context.lineTo(r, -3 * r);\n context.lineTo(r, -r);\n context.lineTo(3 * r, -r);\n context.lineTo(3 * r, r);\n context.lineTo(r, r);\n context.lineTo(r, 3 * r);\n context.lineTo(-r, 3 * r);\n context.lineTo(-r, r);\n context.lineTo(-3 * r, r);\n context.closePath();\n }\n};\n\nvar tan30 = Math.sqrt(1 / 3);\nvar tan30_2 = tan30 * 2;\n\nvar diamond = {\n draw: function(context, size) {\n var y = Math.sqrt(size / tan30_2),\n x = y * tan30;\n context.moveTo(0, -y);\n context.lineTo(x, 0);\n context.lineTo(0, y);\n context.lineTo(-x, 0);\n context.closePath();\n }\n};\n\nvar ka = 0.89081309152928522810;\nvar kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10);\nvar kx = Math.sin(tau$4 / 10) * kr;\nvar ky = -Math.cos(tau$4 / 10) * kr;\n\nvar star = {\n draw: function(context, size) {\n var r = Math.sqrt(size * ka),\n x = kx * r,\n y = ky * r;\n context.moveTo(0, -r);\n context.lineTo(x, y);\n for (var i = 1; i < 5; ++i) {\n var a = tau$4 * i / 5,\n c = Math.cos(a),\n s = Math.sin(a);\n context.lineTo(s * r, -c * r);\n context.lineTo(c * x - s * y, s * x + c * y);\n }\n context.closePath();\n }\n};\n\nvar square = {\n draw: function(context, size) {\n var w = Math.sqrt(size),\n x = -w / 2;\n context.rect(x, x, w, w);\n }\n};\n\nvar sqrt3 = Math.sqrt(3);\n\nvar triangle = {\n draw: function(context, size) {\n var y = -Math.sqrt(size / (sqrt3 * 3));\n context.moveTo(0, y * 2);\n context.lineTo(-sqrt3 * y, -y);\n context.lineTo(sqrt3 * y, -y);\n context.closePath();\n }\n};\n\nvar c = -0.5;\nvar s = Math.sqrt(3) / 2;\nvar k = 1 / Math.sqrt(12);\nvar a = (k / 2 + 1) * 3;\n\nvar wye = {\n draw: function(context, size) {\n var r = Math.sqrt(size / a),\n x0 = r / 2,\n y0 = r * k,\n x1 = x0,\n y1 = r * k + r,\n x2 = -x1,\n y2 = y1;\n context.moveTo(x0, y0);\n context.lineTo(x1, y1);\n context.lineTo(x2, y2);\n context.lineTo(c * x0 - s * y0, s * x0 + c * y0);\n context.lineTo(c * x1 - s * y1, s * x1 + c * y1);\n context.lineTo(c * x2 - s * y2, s * x2 + c * y2);\n context.lineTo(c * x0 + s * y0, c * y0 - s * x0);\n context.lineTo(c * x1 + s * y1, c * y1 - s * x1);\n context.lineTo(c * x2 + s * y2, c * y2 - s * x2);\n context.closePath();\n }\n};\n\nvar symbols = [\n circle$2,\n cross$2,\n diamond,\n square,\n star,\n triangle,\n wye\n];\n\nfunction symbol() {\n var type = constant$10(circle$2),\n size = constant$10(64),\n context = null;\n\n function symbol() {\n var buffer;\n if (!context) context = buffer = path();\n type.apply(this, arguments).draw(context, +size.apply(this, arguments));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n symbol.type = function(_) {\n return arguments.length ? (type = typeof _ === \"function\" ? _ : constant$10(_), symbol) : type;\n };\n\n symbol.size = function(_) {\n return arguments.length ? (size = typeof _ === \"function\" ? _ : constant$10(+_), symbol) : size;\n };\n\n symbol.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, symbol) : context;\n };\n\n return symbol;\n}\n\nfunction noop$2() {}\n\nfunction point$2(that, x, y) {\n that._context.bezierCurveTo(\n (2 * that._x0 + that._x1) / 3,\n (2 * that._y0 + that._y1) / 3,\n (that._x0 + 2 * that._x1) / 3,\n (that._y0 + 2 * that._y1) / 3,\n (that._x0 + 4 * that._x1 + x) / 6,\n (that._y0 + 4 * that._y1 + y) / 6\n );\n}\n\nfunction Basis(context) {\n this._context = context;\n}\n\nBasis.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 3: point$2(this, this._x1, this._y1); // proceed\n case 2: this._context.lineTo(this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed\n default: point$2(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nfunction basis$2(context) {\n return new Basis(context);\n}\n\nfunction BasisClosed(context) {\n this._context = context;\n}\n\nBasisClosed.prototype = {\n areaStart: noop$2,\n areaEnd: noop$2,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x2, this._y2);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);\n this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x2, this._y2);\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x2 = x, this._y2 = y; break;\n case 1: this._point = 2; this._x3 = x, this._y3 = y; break;\n case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;\n default: point$2(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nfunction basisClosed$1(context) {\n return new BasisClosed(context);\n}\n\nfunction BasisOpen(context) {\n this._context = context;\n}\n\nBasisOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;\n case 3: this._point = 4; // proceed\n default: point$2(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nfunction basisOpen(context) {\n return new BasisOpen(context);\n}\n\nfunction Bundle(context, beta) {\n this._basis = new Basis(context);\n this._beta = beta;\n}\n\nBundle.prototype = {\n lineStart: function() {\n this._x = [];\n this._y = [];\n this._basis.lineStart();\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n j = x.length - 1;\n\n if (j > 0) {\n var x0 = x[0],\n y0 = y[0],\n dx = x[j] - x0,\n dy = y[j] - y0,\n i = -1,\n t;\n\n while (++i <= j) {\n t = i / j;\n this._basis.point(\n this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),\n this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)\n );\n }\n }\n\n this._x = this._y = null;\n this._basis.lineEnd();\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\nvar bundle = (function custom(beta) {\n\n function bundle(context) {\n return beta === 1 ? new Basis(context) : new Bundle(context, beta);\n }\n\n bundle.beta = function(beta) {\n return custom(+beta);\n };\n\n return bundle;\n})(0.85);\n\nfunction point$3(that, x, y) {\n that._context.bezierCurveTo(\n that._x1 + that._k * (that._x2 - that._x0),\n that._y1 + that._k * (that._y2 - that._y0),\n that._x2 + that._k * (that._x1 - x),\n that._y2 + that._k * (that._y1 - y),\n that._x2,\n that._y2\n );\n}\n\nfunction Cardinal(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinal.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: point$3(this, this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; this._x1 = x, this._y1 = y; break;\n case 2: this._point = 3; // proceed\n default: point$3(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar cardinal = (function custom(tension) {\n\n function cardinal(context) {\n return new Cardinal(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n\nfunction CardinalClosed(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalClosed.prototype = {\n areaStart: noop$2,\n areaEnd: noop$2,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point$3(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar cardinalClosed = (function custom(tension) {\n\n function cardinal$$1(context) {\n return new CardinalClosed(context, tension);\n }\n\n cardinal$$1.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal$$1;\n})(0);\n\nfunction CardinalOpen(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point$3(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar cardinalOpen = (function custom(tension) {\n\n function cardinal$$1(context) {\n return new CardinalOpen(context, tension);\n }\n\n cardinal$$1.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal$$1;\n})(0);\n\nfunction point$4(that, x, y) {\n var x1 = that._x1,\n y1 = that._y1,\n x2 = that._x2,\n y2 = that._y2;\n\n if (that._l01_a > epsilon$3) {\n var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,\n n = 3 * that._l01_a * (that._l01_a + that._l12_a);\n x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;\n y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;\n }\n\n if (that._l23_a > epsilon$3) {\n var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,\n m = 3 * that._l23_a * (that._l23_a + that._l12_a);\n x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;\n y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;\n }\n\n that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);\n}\n\nfunction CatmullRom(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRom.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: this.point(this._x2, this._y2); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; // proceed\n default: point$4(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar catmullRom = (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n\nfunction CatmullRomClosed(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomClosed.prototype = {\n areaStart: noop$2,\n areaEnd: noop$2,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point$4(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar catmullRomClosed = (function custom(alpha) {\n\n function catmullRom$$1(context) {\n return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);\n }\n\n catmullRom$$1.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom$$1;\n})(0.5);\n\nfunction CatmullRomOpen(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point$4(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nvar catmullRomOpen = (function custom(alpha) {\n\n function catmullRom$$1(context) {\n return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);\n }\n\n catmullRom$$1.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom$$1;\n})(0.5);\n\nfunction LinearClosed(context) {\n this._context = context;\n}\n\nLinearClosed.prototype = {\n areaStart: noop$2,\n areaEnd: noop$2,\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._point) this._context.closePath();\n },\n point: function(x, y) {\n x = +x, y = +y;\n if (this._point) this._context.lineTo(x, y);\n else this._point = 1, this._context.moveTo(x, y);\n }\n};\n\nfunction linearClosed(context) {\n return new LinearClosed(context);\n}\n\nfunction sign$1(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point$5(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point$5(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point$5(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n};\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nfunction monotoneX(context) {\n return new MonotoneX(context);\n}\n\nfunction monotoneY(context) {\n return new MonotoneY(context);\n}\n\nfunction Natural(context) {\n this._context = context;\n}\n\nNatural.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = [];\n this._y = [];\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n n = x.length;\n\n if (n) {\n this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);\n if (n === 2) {\n this._context.lineTo(x[1], y[1]);\n } else {\n var px = controlPoints(x),\n py = controlPoints(y);\n for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {\n this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);\n }\n }\n }\n\n if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();\n this._line = 1 - this._line;\n this._x = this._y = null;\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\n// See https://www.particleincell.com/2012/bezier-splines/ for derivation.\nfunction controlPoints(x) {\n var i,\n n = x.length - 1,\n m,\n a = new Array(n),\n b = new Array(n),\n r = new Array(n);\n a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];\n for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];\n a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];\n for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];\n a[n - 1] = r[n - 1] / b[n - 1];\n for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];\n b[n - 1] = (x[n] + a[n - 1]) / 2;\n for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];\n return [a, b];\n}\n\nfunction natural(context) {\n return new Natural(context);\n}\n\nfunction Step(context, t) {\n this._context = context;\n this._t = t;\n}\n\nStep.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = this._y = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: {\n if (this._t <= 0) {\n this._context.lineTo(this._x, y);\n this._context.lineTo(x, y);\n } else {\n var x1 = this._x * (1 - this._t) + x * this._t;\n this._context.lineTo(x1, this._y);\n this._context.lineTo(x1, y);\n }\n break;\n }\n }\n this._x = x, this._y = y;\n }\n};\n\nfunction step(context) {\n return new Step(context, 0.5);\n}\n\nfunction stepBefore(context) {\n return new Step(context, 0);\n}\n\nfunction stepAfter(context) {\n return new Step(context, 1);\n}\n\nfunction none$1(series, order) {\n if (!((n = series.length) > 1)) return;\n for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {\n s0 = s1, s1 = series[order[i]];\n for (j = 0; j < m; ++j) {\n s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];\n }\n }\n}\n\nfunction none$2(series) {\n var n = series.length, o = new Array(n);\n while (--n >= 0) o[n] = n;\n return o;\n}\n\nfunction stackValue(d, key) {\n return d[key];\n}\n\nfunction stack() {\n var keys = constant$10([]),\n order = none$2,\n offset = none$1,\n value = stackValue;\n\n function stack(data) {\n var kz = keys.apply(this, arguments),\n i,\n m = data.length,\n n = kz.length,\n sz = new Array(n),\n oz;\n\n for (i = 0; i < n; ++i) {\n for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {\n si[j] = sij = [0, +value(data[j], ki, j, data)];\n sij.data = data[j];\n }\n si.key = ki;\n }\n\n for (i = 0, oz = order(sz); i < n; ++i) {\n sz[oz[i]].index = i;\n }\n\n offset(sz, oz);\n return sz;\n }\n\n stack.keys = function(_) {\n return arguments.length ? (keys = typeof _ === \"function\" ? _ : constant$10(slice$6.call(_)), stack) : keys;\n };\n\n stack.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant$10(+_), stack) : value;\n };\n\n stack.order = function(_) {\n return arguments.length ? (order = _ == null ? none$2 : typeof _ === \"function\" ? _ : constant$10(slice$6.call(_)), stack) : order;\n };\n\n stack.offset = function(_) {\n return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;\n };\n\n return stack;\n}\n\nfunction expand(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {\n for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;\n if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;\n }\n none$1(series, order);\n}\n\nfunction diverging(series, order) {\n if (!((n = series.length) > 1)) return;\n for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {\n for (yp = yn = 0, i = 0; i < n; ++i) {\n if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {\n d[0] = yp, d[1] = yp += dy;\n } else if (dy < 0) {\n d[1] = yn, d[0] = yn += dy;\n } else {\n d[0] = yp;\n }\n }\n }\n}\n\nfunction silhouette(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {\n for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;\n s0[j][1] += s0[j][0] = -y / 2;\n }\n none$1(series, order);\n}\n\nfunction wiggle(series, order) {\n if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;\n for (var y = 0, j = 1, s0, m, n; j < m; ++j) {\n for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {\n var si = series[order[i]],\n sij0 = si[j][1] || 0,\n sij1 = si[j - 1][1] || 0,\n s3 = (sij0 - sij1) / 2;\n for (var k = 0; k < i; ++k) {\n var sk = series[order[k]],\n skj0 = sk[j][1] || 0,\n skj1 = sk[j - 1][1] || 0;\n s3 += skj0 - skj1;\n }\n s1 += sij0, s2 += s3 * sij0;\n }\n s0[j - 1][1] += s0[j - 1][0] = y;\n if (s1) y -= s2 / s1;\n }\n s0[j - 1][1] += s0[j - 1][0] = y;\n none$1(series, order);\n}\n\nfunction ascending$2(series) {\n var sums = series.map(sum$2);\n return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });\n}\n\nfunction sum$2(series) {\n var s = 0, i = -1, n = series.length, v;\n while (++i < n) if (v = +series[i][1]) s += v;\n return s;\n}\n\nfunction descending$2(series) {\n return ascending$2(series).reverse();\n}\n\nfunction insideOut(series) {\n var n = series.length,\n i,\n j,\n sums = series.map(sum$2),\n order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }),\n top = 0,\n bottom = 0,\n tops = [],\n bottoms = [];\n\n for (i = 0; i < n; ++i) {\n j = order[i];\n if (top < bottom) {\n top += sums[j];\n tops.push(j);\n } else {\n bottom += sums[j];\n bottoms.push(j);\n }\n }\n\n return bottoms.reverse().concat(tops);\n}\n\nfunction reverse(series) {\n return none$2(series).reverse();\n}\n\nfunction constant$11(x) {\n return function() {\n return x;\n };\n}\n\nfunction x$4(d) {\n return d[0];\n}\n\nfunction y$4(d) {\n return d[1];\n}\n\nfunction RedBlackTree() {\n this._ = null; // root node\n}\n\nfunction RedBlackNode(node) {\n node.U = // parent node\n node.C = // color - true for red, false for black\n node.L = // left node\n node.R = // right node\n node.P = // previous node\n node.N = null; // next node\n}\n\nRedBlackTree.prototype = {\n constructor: RedBlackTree,\n\n insert: function(after, node) {\n var parent, grandpa, uncle;\n\n if (after) {\n node.P = after;\n node.N = after.N;\n if (after.N) after.N.P = node;\n after.N = node;\n if (after.R) {\n after = after.R;\n while (after.L) after = after.L;\n after.L = node;\n } else {\n after.R = node;\n }\n parent = after;\n } else if (this._) {\n after = RedBlackFirst(this._);\n node.P = null;\n node.N = after;\n after.P = after.L = node;\n parent = after;\n } else {\n node.P = node.N = null;\n this._ = node;\n parent = null;\n }\n node.L = node.R = null;\n node.U = parent;\n node.C = true;\n\n after = node;\n while (parent && parent.C) {\n grandpa = parent.U;\n if (parent === grandpa.L) {\n uncle = grandpa.R;\n if (uncle && uncle.C) {\n parent.C = uncle.C = false;\n grandpa.C = true;\n after = grandpa;\n } else {\n if (after === parent.R) {\n RedBlackRotateLeft(this, parent);\n after = parent;\n parent = after.U;\n }\n parent.C = false;\n grandpa.C = true;\n RedBlackRotateRight(this, grandpa);\n }\n } else {\n uncle = grandpa.L;\n if (uncle && uncle.C) {\n parent.C = uncle.C = false;\n grandpa.C = true;\n after = grandpa;\n } else {\n if (after === parent.L) {\n RedBlackRotateRight(this, parent);\n after = parent;\n parent = after.U;\n }\n parent.C = false;\n grandpa.C = true;\n RedBlackRotateLeft(this, grandpa);\n }\n }\n parent = after.U;\n }\n this._.C = false;\n },\n\n remove: function(node) {\n if (node.N) node.N.P = node.P;\n if (node.P) node.P.N = node.N;\n node.N = node.P = null;\n\n var parent = node.U,\n sibling,\n left = node.L,\n right = node.R,\n next,\n red;\n\n if (!left) next = right;\n else if (!right) next = left;\n else next = RedBlackFirst(right);\n\n if (parent) {\n if (parent.L === node) parent.L = next;\n else parent.R = next;\n } else {\n this._ = next;\n }\n\n if (left && right) {\n red = next.C;\n next.C = node.C;\n next.L = left;\n left.U = next;\n if (next !== right) {\n parent = next.U;\n next.U = node.U;\n node = next.R;\n parent.L = node;\n next.R = right;\n right.U = next;\n } else {\n next.U = parent;\n parent = next;\n node = next.R;\n }\n } else {\n red = node.C;\n node = next;\n }\n\n if (node) node.U = parent;\n if (red) return;\n if (node && node.C) { node.C = false; return; }\n\n do {\n if (node === this._) break;\n if (node === parent.L) {\n sibling = parent.R;\n if (sibling.C) {\n sibling.C = false;\n parent.C = true;\n RedBlackRotateLeft(this, parent);\n sibling = parent.R;\n }\n if ((sibling.L && sibling.L.C)\n || (sibling.R && sibling.R.C)) {\n if (!sibling.R || !sibling.R.C) {\n sibling.L.C = false;\n sibling.C = true;\n RedBlackRotateRight(this, sibling);\n sibling = parent.R;\n }\n sibling.C = parent.C;\n parent.C = sibling.R.C = false;\n RedBlackRotateLeft(this, parent);\n node = this._;\n break;\n }\n } else {\n sibling = parent.L;\n if (sibling.C) {\n sibling.C = false;\n parent.C = true;\n RedBlackRotateRight(this, parent);\n sibling = parent.L;\n }\n if ((sibling.L && sibling.L.C)\n || (sibling.R && sibling.R.C)) {\n if (!sibling.L || !sibling.L.C) {\n sibling.R.C = false;\n sibling.C = true;\n RedBlackRotateLeft(this, sibling);\n sibling = parent.L;\n }\n sibling.C = parent.C;\n parent.C = sibling.L.C = false;\n RedBlackRotateRight(this, parent);\n node = this._;\n break;\n }\n }\n sibling.C = true;\n node = parent;\n parent = parent.U;\n } while (!node.C);\n\n if (node) node.C = false;\n }\n};\n\nfunction RedBlackRotateLeft(tree, node) {\n var p = node,\n q = node.R,\n parent = p.U;\n\n if (parent) {\n if (parent.L === p) parent.L = q;\n else parent.R = q;\n } else {\n tree._ = q;\n }\n\n q.U = parent;\n p.U = q;\n p.R = q.L;\n if (p.R) p.R.U = p;\n q.L = p;\n}\n\nfunction RedBlackRotateRight(tree, node) {\n var p = node,\n q = node.L,\n parent = p.U;\n\n if (parent) {\n if (parent.L === p) parent.L = q;\n else parent.R = q;\n } else {\n tree._ = q;\n }\n\n q.U = parent;\n p.U = q;\n p.L = q.R;\n if (p.L) p.L.U = p;\n q.R = p;\n}\n\nfunction RedBlackFirst(node) {\n while (node.L) node = node.L;\n return node;\n}\n\nfunction createEdge(left, right, v0, v1) {\n var edge = [null, null],\n index = edges.push(edge) - 1;\n edge.left = left;\n edge.right = right;\n if (v0) setEdgeEnd(edge, left, right, v0);\n if (v1) setEdgeEnd(edge, right, left, v1);\n cells[left.index].halfedges.push(index);\n cells[right.index].halfedges.push(index);\n return edge;\n}\n\nfunction createBorderEdge(left, v0, v1) {\n var edge = [v0, v1];\n edge.left = left;\n return edge;\n}\n\nfunction setEdgeEnd(edge, left, right, vertex) {\n if (!edge[0] && !edge[1]) {\n edge[0] = vertex;\n edge.left = left;\n edge.right = right;\n } else if (edge.left === right) {\n edge[1] = vertex;\n } else {\n edge[0] = vertex;\n }\n}\n\n// Liang–Barsky line clipping.\nfunction clipEdge(edge, x0, y0, x1, y1) {\n var a = edge[0],\n b = edge[1],\n ax = a[0],\n ay = a[1],\n bx = b[0],\n by = b[1],\n t0 = 0,\n t1 = 1,\n dx = bx - ax,\n dy = by - ay,\n r;\n\n r = x0 - ax;\n if (!dx && r > 0) return;\n r /= dx;\n if (dx < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dx > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = x1 - ax;\n if (!dx && r < 0) return;\n r /= dx;\n if (dx < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dx > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n r = y0 - ay;\n if (!dy && r > 0) return;\n r /= dy;\n if (dy < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dy > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = y1 - ay;\n if (!dy && r < 0) return;\n r /= dy;\n if (dy < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dy > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?\n\n if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];\n if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];\n return true;\n}\n\nfunction connectEdge(edge, x0, y0, x1, y1) {\n var v1 = edge[1];\n if (v1) return true;\n\n var v0 = edge[0],\n left = edge.left,\n right = edge.right,\n lx = left[0],\n ly = left[1],\n rx = right[0],\n ry = right[1],\n fx = (lx + rx) / 2,\n fy = (ly + ry) / 2,\n fm,\n fb;\n\n if (ry === ly) {\n if (fx < x0 || fx >= x1) return;\n if (lx > rx) {\n if (!v0) v0 = [fx, y0];\n else if (v0[1] >= y1) return;\n v1 = [fx, y1];\n } else {\n if (!v0) v0 = [fx, y1];\n else if (v0[1] < y0) return;\n v1 = [fx, y0];\n }\n } else {\n fm = (lx - rx) / (ry - ly);\n fb = fy - fm * fx;\n if (fm < -1 || fm > 1) {\n if (lx > rx) {\n if (!v0) v0 = [(y0 - fb) / fm, y0];\n else if (v0[1] >= y1) return;\n v1 = [(y1 - fb) / fm, y1];\n } else {\n if (!v0) v0 = [(y1 - fb) / fm, y1];\n else if (v0[1] < y0) return;\n v1 = [(y0 - fb) / fm, y0];\n }\n } else {\n if (ly < ry) {\n if (!v0) v0 = [x0, fm * x0 + fb];\n else if (v0[0] >= x1) return;\n v1 = [x1, fm * x1 + fb];\n } else {\n if (!v0) v0 = [x1, fm * x1 + fb];\n else if (v0[0] < x0) return;\n v1 = [x0, fm * x0 + fb];\n }\n }\n }\n\n edge[0] = v0;\n edge[1] = v1;\n return true;\n}\n\nfunction clipEdges(x0, y0, x1, y1) {\n var i = edges.length,\n edge;\n\n while (i--) {\n if (!connectEdge(edge = edges[i], x0, y0, x1, y1)\n || !clipEdge(edge, x0, y0, x1, y1)\n || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4\n || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {\n delete edges[i];\n }\n }\n}\n\nfunction createCell(site) {\n return cells[site.index] = {\n site: site,\n halfedges: []\n };\n}\n\nfunction cellHalfedgeAngle(cell, edge) {\n var site = cell.site,\n va = edge.left,\n vb = edge.right;\n if (site === vb) vb = va, va = site;\n if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);\n if (site === va) va = edge[1], vb = edge[0];\n else va = edge[0], vb = edge[1];\n return Math.atan2(va[0] - vb[0], vb[1] - va[1]);\n}\n\nfunction cellHalfedgeStart(cell, edge) {\n return edge[+(edge.left !== cell.site)];\n}\n\nfunction cellHalfedgeEnd(cell, edge) {\n return edge[+(edge.left === cell.site)];\n}\n\nfunction sortCellHalfedges() {\n for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {\n if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {\n var index = new Array(m),\n array = new Array(m);\n for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);\n index.sort(function(i, j) { return array[j] - array[i]; });\n for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];\n for (j = 0; j < m; ++j) halfedges[j] = array[j];\n }\n }\n}\n\nfunction clipCells(x0, y0, x1, y1) {\n var nCells = cells.length,\n iCell,\n cell,\n site,\n iHalfedge,\n halfedges,\n nHalfedges,\n start,\n startX,\n startY,\n end,\n endX,\n endY,\n cover = true;\n\n for (iCell = 0; iCell < nCells; ++iCell) {\n if (cell = cells[iCell]) {\n site = cell.site;\n halfedges = cell.halfedges;\n iHalfedge = halfedges.length;\n\n // Remove any dangling clipped edges.\n while (iHalfedge--) {\n if (!edges[halfedges[iHalfedge]]) {\n halfedges.splice(iHalfedge, 1);\n }\n }\n\n // Insert any border edges as necessary.\n iHalfedge = 0, nHalfedges = halfedges.length;\n while (iHalfedge < nHalfedges) {\n end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];\n start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];\n if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) {\n halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,\n Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]\n : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]\n : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]\n : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]\n : null)) - 1);\n ++nHalfedges;\n }\n }\n\n if (nHalfedges) cover = false;\n }\n }\n\n // If there weren’t any edges, have the closest site cover the extent.\n // It doesn’t matter which corner of the extent we measure!\n if (cover) {\n var dx, dy, d2, dc = Infinity;\n\n for (iCell = 0, cover = null; iCell < nCells; ++iCell) {\n if (cell = cells[iCell]) {\n site = cell.site;\n dx = site[0] - x0;\n dy = site[1] - y0;\n d2 = dx * dx + dy * dy;\n if (d2 < dc) dc = d2, cover = cell;\n }\n }\n\n if (cover) {\n var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];\n cover.halfedges.push(\n edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,\n edges.push(createBorderEdge(site, v01, v11)) - 1,\n edges.push(createBorderEdge(site, v11, v10)) - 1,\n edges.push(createBorderEdge(site, v10, v00)) - 1\n );\n }\n }\n\n // Lastly delete any cells with no edges; these were entirely clipped.\n for (iCell = 0; iCell < nCells; ++iCell) {\n if (cell = cells[iCell]) {\n if (!cell.halfedges.length) {\n delete cells[iCell];\n }\n }\n }\n}\n\nvar circlePool = [];\n\nvar firstCircle;\n\nfunction Circle() {\n RedBlackNode(this);\n this.x =\n this.y =\n this.arc =\n this.site =\n this.cy = null;\n}\n\nfunction attachCircle(arc) {\n var lArc = arc.P,\n rArc = arc.N;\n\n if (!lArc || !rArc) return;\n\n var lSite = lArc.site,\n cSite = arc.site,\n rSite = rArc.site;\n\n if (lSite === rSite) return;\n\n var bx = cSite[0],\n by = cSite[1],\n ax = lSite[0] - bx,\n ay = lSite[1] - by,\n cx = rSite[0] - bx,\n cy = rSite[1] - by;\n\n var d = 2 * (ax * cy - ay * cx);\n if (d >= -epsilon2$2) return;\n\n var ha = ax * ax + ay * ay,\n hc = cx * cx + cy * cy,\n x = (cy * ha - ay * hc) / d,\n y = (ax * hc - cx * ha) / d;\n\n var circle = circlePool.pop() || new Circle;\n circle.arc = arc;\n circle.site = cSite;\n circle.x = x + bx;\n circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom\n\n arc.circle = circle;\n\n var before = null,\n node = circles._;\n\n while (node) {\n if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {\n if (node.L) node = node.L;\n else { before = node.P; break; }\n } else {\n if (node.R) node = node.R;\n else { before = node; break; }\n }\n }\n\n circles.insert(before, circle);\n if (!before) firstCircle = circle;\n}\n\nfunction detachCircle(arc) {\n var circle = arc.circle;\n if (circle) {\n if (!circle.P) firstCircle = circle.N;\n circles.remove(circle);\n circlePool.push(circle);\n RedBlackNode(circle);\n arc.circle = null;\n }\n}\n\nvar beachPool = [];\n\nfunction Beach() {\n RedBlackNode(this);\n this.edge =\n this.site =\n this.circle = null;\n}\n\nfunction createBeach(site) {\n var beach = beachPool.pop() || new Beach;\n beach.site = site;\n return beach;\n}\n\nfunction detachBeach(beach) {\n detachCircle(beach);\n beaches.remove(beach);\n beachPool.push(beach);\n RedBlackNode(beach);\n}\n\nfunction removeBeach(beach) {\n var circle = beach.circle,\n x = circle.x,\n y = circle.cy,\n vertex = [x, y],\n previous = beach.P,\n next = beach.N,\n disappearing = [beach];\n\n detachBeach(beach);\n\n var lArc = previous;\n while (lArc.circle\n && Math.abs(x - lArc.circle.x) < epsilon$4\n && Math.abs(y - lArc.circle.cy) < epsilon$4) {\n previous = lArc.P;\n disappearing.unshift(lArc);\n detachBeach(lArc);\n lArc = previous;\n }\n\n disappearing.unshift(lArc);\n detachCircle(lArc);\n\n var rArc = next;\n while (rArc.circle\n && Math.abs(x - rArc.circle.x) < epsilon$4\n && Math.abs(y - rArc.circle.cy) < epsilon$4) {\n next = rArc.N;\n disappearing.push(rArc);\n detachBeach(rArc);\n rArc = next;\n }\n\n disappearing.push(rArc);\n detachCircle(rArc);\n\n var nArcs = disappearing.length,\n iArc;\n for (iArc = 1; iArc < nArcs; ++iArc) {\n rArc = disappearing[iArc];\n lArc = disappearing[iArc - 1];\n setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);\n }\n\n lArc = disappearing[0];\n rArc = disappearing[nArcs - 1];\n rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);\n\n attachCircle(lArc);\n attachCircle(rArc);\n}\n\nfunction addBeach(site) {\n var x = site[0],\n directrix = site[1],\n lArc,\n rArc,\n dxl,\n dxr,\n node = beaches._;\n\n while (node) {\n dxl = leftBreakPoint(node, directrix) - x;\n if (dxl > epsilon$4) node = node.L; else {\n dxr = x - rightBreakPoint(node, directrix);\n if (dxr > epsilon$4) {\n if (!node.R) {\n lArc = node;\n break;\n }\n node = node.R;\n } else {\n if (dxl > -epsilon$4) {\n lArc = node.P;\n rArc = node;\n } else if (dxr > -epsilon$4) {\n lArc = node;\n rArc = node.N;\n } else {\n lArc = rArc = node;\n }\n break;\n }\n }\n }\n\n createCell(site);\n var newArc = createBeach(site);\n beaches.insert(lArc, newArc);\n\n if (!lArc && !rArc) return;\n\n if (lArc === rArc) {\n detachCircle(lArc);\n rArc = createBeach(lArc.site);\n beaches.insert(newArc, rArc);\n newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);\n attachCircle(lArc);\n attachCircle(rArc);\n return;\n }\n\n if (!rArc) { // && lArc\n newArc.edge = createEdge(lArc.site, newArc.site);\n return;\n }\n\n // else lArc !== rArc\n detachCircle(lArc);\n detachCircle(rArc);\n\n var lSite = lArc.site,\n ax = lSite[0],\n ay = lSite[1],\n bx = site[0] - ax,\n by = site[1] - ay,\n rSite = rArc.site,\n cx = rSite[0] - ax,\n cy = rSite[1] - ay,\n d = 2 * (bx * cy - by * cx),\n hb = bx * bx + by * by,\n hc = cx * cx + cy * cy,\n vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];\n\n setEdgeEnd(rArc.edge, lSite, rSite, vertex);\n newArc.edge = createEdge(lSite, site, null, vertex);\n rArc.edge = createEdge(site, rSite, null, vertex);\n attachCircle(lArc);\n attachCircle(rArc);\n}\n\nfunction leftBreakPoint(arc, directrix) {\n var site = arc.site,\n rfocx = site[0],\n rfocy = site[1],\n pby2 = rfocy - directrix;\n\n if (!pby2) return rfocx;\n\n var lArc = arc.P;\n if (!lArc) return -Infinity;\n\n site = lArc.site;\n var lfocx = site[0],\n lfocy = site[1],\n plby2 = lfocy - directrix;\n\n if (!plby2) return lfocx;\n\n var hl = lfocx - rfocx,\n aby2 = 1 / pby2 - 1 / plby2,\n b = hl / plby2;\n\n if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;\n\n return (rfocx + lfocx) / 2;\n}\n\nfunction rightBreakPoint(arc, directrix) {\n var rArc = arc.N;\n if (rArc) return leftBreakPoint(rArc, directrix);\n var site = arc.site;\n return site[1] === directrix ? site[0] : Infinity;\n}\n\nvar epsilon$4 = 1e-6;\nvar epsilon2$2 = 1e-12;\nvar beaches;\nvar cells;\nvar circles;\nvar edges;\n\nfunction triangleArea(a, b, c) {\n return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);\n}\n\nfunction lexicographic(a, b) {\n return b[1] - a[1]\n || b[0] - a[0];\n}\n\nfunction Diagram(sites, extent) {\n var site = sites.sort(lexicographic).pop(),\n x,\n y,\n circle;\n\n edges = [];\n cells = new Array(sites.length);\n beaches = new RedBlackTree;\n circles = new RedBlackTree;\n\n while (true) {\n circle = firstCircle;\n if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {\n if (site[0] !== x || site[1] !== y) {\n addBeach(site);\n x = site[0], y = site[1];\n }\n site = sites.pop();\n } else if (circle) {\n removeBeach(circle.arc);\n } else {\n break;\n }\n }\n\n sortCellHalfedges();\n\n if (extent) {\n var x0 = +extent[0][0],\n y0 = +extent[0][1],\n x1 = +extent[1][0],\n y1 = +extent[1][1];\n clipEdges(x0, y0, x1, y1);\n clipCells(x0, y0, x1, y1);\n }\n\n this.edges = edges;\n this.cells = cells;\n\n beaches =\n circles =\n edges =\n cells = null;\n}\n\nDiagram.prototype = {\n constructor: Diagram,\n\n polygons: function() {\n var edges = this.edges;\n\n return this.cells.map(function(cell) {\n var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });\n polygon.data = cell.site.data;\n return polygon;\n });\n },\n\n triangles: function() {\n var triangles = [],\n edges = this.edges;\n\n this.cells.forEach(function(cell, i) {\n if (!(m = (halfedges = cell.halfedges).length)) return;\n var site = cell.site,\n halfedges,\n j = -1,\n m,\n s0,\n e1 = edges[halfedges[m - 1]],\n s1 = e1.left === site ? e1.right : e1.left;\n\n while (++j < m) {\n s0 = s1;\n e1 = edges[halfedges[j]];\n s1 = e1.left === site ? e1.right : e1.left;\n if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {\n triangles.push([site.data, s0.data, s1.data]);\n }\n }\n });\n\n return triangles;\n },\n\n links: function() {\n return this.edges.filter(function(edge) {\n return edge.right;\n }).map(function(edge) {\n return {\n source: edge.left.data,\n target: edge.right.data\n };\n });\n },\n\n find: function(x, y, radius) {\n var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell;\n\n // Use the previously-found cell, or start with an arbitrary one.\n while (!(cell = that.cells[i1])) if (++i1 >= n) return null;\n var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy;\n\n // Traverse the half-edges to find a closer cell, if any.\n do {\n cell = that.cells[i0 = i1], i1 = null;\n cell.halfedges.forEach(function(e) {\n var edge = that.edges[e], v = edge.left;\n if ((v === cell.site || !v) && !(v = edge.right)) return;\n var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy;\n if (v2 < d2) d2 = v2, i1 = v.index;\n });\n } while (i1 !== null);\n\n that._found = i0;\n\n return radius == null || d2 <= radius * radius ? cell.site : null;\n }\n};\n\nfunction voronoi() {\n var x$$1 = x$4,\n y$$1 = y$4,\n extent = null;\n\n function voronoi(data) {\n return new Diagram(data.map(function(d, i) {\n var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4];\n s.index = i;\n s.data = d;\n return s;\n }), extent);\n }\n\n voronoi.polygons = function(data) {\n return voronoi(data).polygons();\n };\n\n voronoi.links = function(data) {\n return voronoi(data).links();\n };\n\n voronoi.triangles = function(data) {\n return voronoi(data).triangles();\n };\n\n voronoi.x = function(_) {\n return arguments.length ? (x$$1 = typeof _ === \"function\" ? _ : constant$11(+_), voronoi) : x$$1;\n };\n\n voronoi.y = function(_) {\n return arguments.length ? (y$$1 = typeof _ === \"function\" ? _ : constant$11(+_), voronoi) : y$$1;\n };\n\n voronoi.extent = function(_) {\n return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]];\n };\n\n voronoi.size = function(_) {\n return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];\n };\n\n return voronoi;\n}\n\nfunction constant$12(x) {\n return function() {\n return x;\n };\n}\n\nfunction ZoomEvent(target, type, transform) {\n this.target = target;\n this.type = type;\n this.transform = transform;\n}\n\nfunction Transform(k, x, y) {\n this.k = k;\n this.x = x;\n this.y = y;\n}\n\nTransform.prototype = {\n constructor: Transform,\n scale: function(k) {\n return k === 1 ? this : new Transform(this.k * k, this.x, this.y);\n },\n translate: function(x, y) {\n return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);\n },\n apply: function(point) {\n return [point[0] * this.k + this.x, point[1] * this.k + this.y];\n },\n applyX: function(x) {\n return x * this.k + this.x;\n },\n applyY: function(y) {\n return y * this.k + this.y;\n },\n invert: function(location) {\n return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];\n },\n invertX: function(x) {\n return (x - this.x) / this.k;\n },\n invertY: function(y) {\n return (y - this.y) / this.k;\n },\n rescaleX: function(x) {\n return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));\n },\n rescaleY: function(y) {\n return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));\n },\n toString: function() {\n return \"translate(\" + this.x + \",\" + this.y + \") scale(\" + this.k + \")\";\n }\n};\n\nvar identity$8 = new Transform(1, 0, 0);\n\ntransform$1.prototype = Transform.prototype;\n\nfunction transform$1(node) {\n return node.__zoom || identity$8;\n}\n\nfunction nopropagation$2() {\n exports.event.stopImmediatePropagation();\n}\n\nfunction noevent$2() {\n exports.event.preventDefault();\n exports.event.stopImmediatePropagation();\n}\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter$2() {\n return !exports.event.button;\n}\n\nfunction defaultExtent$1() {\n var e = this, w, h;\n if (e instanceof SVGElement) {\n e = e.ownerSVGElement || e;\n w = e.width.baseVal.value;\n h = e.height.baseVal.value;\n } else {\n w = e.clientWidth;\n h = e.clientHeight;\n }\n return [[0, 0], [w, h]];\n}\n\nfunction defaultTransform() {\n return this.__zoom || identity$8;\n}\n\nfunction defaultWheelDelta() {\n return -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500;\n}\n\nfunction defaultTouchable$1() {\n return \"ontouchstart\" in this;\n}\n\nfunction defaultConstrain(transform$$1, extent, translateExtent) {\n var dx0 = transform$$1.invertX(extent[0][0]) - translateExtent[0][0],\n dx1 = transform$$1.invertX(extent[1][0]) - translateExtent[1][0],\n dy0 = transform$$1.invertY(extent[0][1]) - translateExtent[0][1],\n dy1 = transform$$1.invertY(extent[1][1]) - translateExtent[1][1];\n return transform$$1.translate(\n dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),\n dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)\n );\n}\n\nfunction zoom() {\n var filter = defaultFilter$2,\n extent = defaultExtent$1,\n constrain = defaultConstrain,\n wheelDelta = defaultWheelDelta,\n touchable = defaultTouchable$1,\n scaleExtent = [0, Infinity],\n translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]],\n duration = 250,\n interpolate = interpolateZoom,\n gestures = [],\n listeners = dispatch(\"start\", \"zoom\", \"end\"),\n touchstarting,\n touchending,\n touchDelay = 500,\n wheelDelay = 150,\n clickDistance2 = 0;\n\n function zoom(selection) {\n selection\n .property(\"__zoom\", defaultTransform)\n .on(\"wheel.zoom\", wheeled)\n .on(\"mousedown.zoom\", mousedowned)\n .on(\"dblclick.zoom\", dblclicked)\n .filter(touchable)\n .on(\"touchstart.zoom\", touchstarted)\n .on(\"touchmove.zoom\", touchmoved)\n .on(\"touchend.zoom touchcancel.zoom\", touchended)\n .style(\"touch-action\", \"none\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\");\n }\n\n zoom.transform = function(collection, transform$$1) {\n var selection = collection.selection ? collection.selection() : collection;\n selection.property(\"__zoom\", defaultTransform);\n if (collection !== selection) {\n schedule(collection, transform$$1);\n } else {\n selection.interrupt().each(function() {\n gesture(this, arguments)\n .start()\n .zoom(null, typeof transform$$1 === \"function\" ? transform$$1.apply(this, arguments) : transform$$1)\n .end();\n });\n }\n };\n\n zoom.scaleBy = function(selection, k) {\n zoom.scaleTo(selection, function() {\n var k0 = this.__zoom.k,\n k1 = typeof k === \"function\" ? k.apply(this, arguments) : k;\n return k0 * k1;\n });\n };\n\n zoom.scaleTo = function(selection, k) {\n zoom.transform(selection, function() {\n var e = extent.apply(this, arguments),\n t0 = this.__zoom,\n p0 = centroid(e),\n p1 = t0.invert(p0),\n k1 = typeof k === \"function\" ? k.apply(this, arguments) : k;\n return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent);\n });\n };\n\n zoom.translateBy = function(selection, x, y) {\n zoom.transform(selection, function() {\n return constrain(this.__zoom.translate(\n typeof x === \"function\" ? x.apply(this, arguments) : x,\n typeof y === \"function\" ? y.apply(this, arguments) : y\n ), extent.apply(this, arguments), translateExtent);\n });\n };\n\n zoom.translateTo = function(selection, x, y) {\n zoom.transform(selection, function() {\n var e = extent.apply(this, arguments),\n t = this.__zoom,\n p = centroid(e);\n return constrain(identity$8.translate(p[0], p[1]).scale(t.k).translate(\n typeof x === \"function\" ? -x.apply(this, arguments) : -x,\n typeof y === \"function\" ? -y.apply(this, arguments) : -y\n ), e, translateExtent);\n });\n };\n\n function scale(transform$$1, k) {\n k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k));\n return k === transform$$1.k ? transform$$1 : new Transform(k, transform$$1.x, transform$$1.y);\n }\n\n function translate(transform$$1, p0, p1) {\n var x = p0[0] - p1[0] * transform$$1.k, y = p0[1] - p1[1] * transform$$1.k;\n return x === transform$$1.x && y === transform$$1.y ? transform$$1 : new Transform(transform$$1.k, x, y);\n }\n\n function centroid(extent) {\n return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];\n }\n\n function schedule(transition, transform$$1, center) {\n transition\n .on(\"start.zoom\", function() { gesture(this, arguments).start(); })\n .on(\"interrupt.zoom end.zoom\", function() { gesture(this, arguments).end(); })\n .tween(\"zoom\", function() {\n var that = this,\n args = arguments,\n g = gesture(that, args),\n e = extent.apply(that, args),\n p = center || centroid(e),\n w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),\n a = that.__zoom,\n b = typeof transform$$1 === \"function\" ? transform$$1.apply(that, args) : transform$$1,\n i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));\n return function(t) {\n if (t === 1) t = b; // Avoid rounding error on end.\n else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }\n g.zoom(null, t);\n };\n });\n }\n\n function gesture(that, args) {\n for (var i = 0, n = gestures.length, g; i < n; ++i) {\n if ((g = gestures[i]).that === that) {\n return g;\n }\n }\n return new Gesture(that, args);\n }\n\n function Gesture(that, args) {\n this.that = that;\n this.args = args;\n this.index = -1;\n this.active = 0;\n this.extent = extent.apply(that, args);\n }\n\n Gesture.prototype = {\n start: function() {\n if (++this.active === 1) {\n this.index = gestures.push(this) - 1;\n this.emit(\"start\");\n }\n return this;\n },\n zoom: function(key, transform$$1) {\n if (this.mouse && key !== \"mouse\") this.mouse[1] = transform$$1.invert(this.mouse[0]);\n if (this.touch0 && key !== \"touch\") this.touch0[1] = transform$$1.invert(this.touch0[0]);\n if (this.touch1 && key !== \"touch\") this.touch1[1] = transform$$1.invert(this.touch1[0]);\n this.that.__zoom = transform$$1;\n this.emit(\"zoom\");\n return this;\n },\n end: function() {\n if (--this.active === 0) {\n gestures.splice(this.index, 1);\n this.index = -1;\n this.emit(\"end\");\n }\n return this;\n },\n emit: function(type) {\n customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);\n }\n };\n\n function wheeled() {\n if (!filter.apply(this, arguments)) return;\n var g = gesture(this, arguments),\n t = this.__zoom,\n k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),\n p = mouse(this);\n\n // If the mouse is in the same location as before, reuse it.\n // If there were recent wheel events, reset the wheel idle timeout.\n if (g.wheel) {\n if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {\n g.mouse[1] = t.invert(g.mouse[0] = p);\n }\n clearTimeout(g.wheel);\n }\n\n // If this wheel event won’t trigger a transform change, ignore it.\n else if (t.k === k) return;\n\n // Otherwise, capture the mouse point and location at the start.\n else {\n g.mouse = [p, t.invert(p)];\n interrupt(this);\n g.start();\n }\n\n noevent$2();\n g.wheel = setTimeout(wheelidled, wheelDelay);\n g.zoom(\"mouse\", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));\n\n function wheelidled() {\n g.wheel = null;\n g.end();\n }\n }\n\n function mousedowned() {\n if (touchending || !filter.apply(this, arguments)) return;\n var g = gesture(this, arguments),\n v = select(exports.event.view).on(\"mousemove.zoom\", mousemoved, true).on(\"mouseup.zoom\", mouseupped, true),\n p = mouse(this),\n x0 = exports.event.clientX,\n y0 = exports.event.clientY;\n\n dragDisable(exports.event.view);\n nopropagation$2();\n g.mouse = [p, this.__zoom.invert(p)];\n interrupt(this);\n g.start();\n\n function mousemoved() {\n noevent$2();\n if (!g.moved) {\n var dx = exports.event.clientX - x0, dy = exports.event.clientY - y0;\n g.moved = dx * dx + dy * dy > clickDistance2;\n }\n g.zoom(\"mouse\", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent, translateExtent));\n }\n\n function mouseupped() {\n v.on(\"mousemove.zoom mouseup.zoom\", null);\n yesdrag(exports.event.view, g.moved);\n noevent$2();\n g.end();\n }\n }\n\n function dblclicked() {\n if (!filter.apply(this, arguments)) return;\n var t0 = this.__zoom,\n p0 = mouse(this),\n p1 = t0.invert(p0),\n k1 = t0.k * (exports.event.shiftKey ? 0.5 : 2),\n t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments), translateExtent);\n\n noevent$2();\n if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0);\n else select(this).call(zoom.transform, t1);\n }\n\n function touchstarted() {\n if (!filter.apply(this, arguments)) return;\n var g = gesture(this, arguments),\n touches = exports.event.changedTouches,\n started,\n n = touches.length, i, t, p;\n\n nopropagation$2();\n for (i = 0; i < n; ++i) {\n t = touches[i], p = touch(this, touches, t.identifier);\n p = [p, this.__zoom.invert(p), t.identifier];\n if (!g.touch0) g.touch0 = p, started = true;\n else if (!g.touch1) g.touch1 = p;\n }\n\n // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.\n if (touchstarting) {\n touchstarting = clearTimeout(touchstarting);\n if (!g.touch1) {\n g.end();\n p = select(this).on(\"dblclick.zoom\");\n if (p) p.apply(this, arguments);\n return;\n }\n }\n\n if (started) {\n touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);\n interrupt(this);\n g.start();\n }\n }\n\n function touchmoved() {\n var g = gesture(this, arguments),\n touches = exports.event.changedTouches,\n n = touches.length, i, t, p, l;\n\n noevent$2();\n if (touchstarting) touchstarting = clearTimeout(touchstarting);\n for (i = 0; i < n; ++i) {\n t = touches[i], p = touch(this, touches, t.identifier);\n if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;\n else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;\n }\n t = g.that.__zoom;\n if (g.touch1) {\n var p0 = g.touch0[0], l0 = g.touch0[1],\n p1 = g.touch1[0], l1 = g.touch1[1],\n dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,\n dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;\n t = scale(t, Math.sqrt(dp / dl));\n p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];\n l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];\n }\n else if (g.touch0) p = g.touch0[0], l = g.touch0[1];\n else return;\n g.zoom(\"touch\", constrain(translate(t, p, l), g.extent, translateExtent));\n }\n\n function touchended() {\n var g = gesture(this, arguments),\n touches = exports.event.changedTouches,\n n = touches.length, i, t;\n\n nopropagation$2();\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, touchDelay);\n for (i = 0; i < n; ++i) {\n t = touches[i];\n if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;\n else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;\n }\n if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;\n if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]);\n else g.end();\n }\n\n zoom.wheelDelta = function(_) {\n return arguments.length ? (wheelDelta = typeof _ === \"function\" ? _ : constant$12(+_), zoom) : wheelDelta;\n };\n\n zoom.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant$12(!!_), zoom) : filter;\n };\n\n zoom.touchable = function(_) {\n return arguments.length ? (touchable = typeof _ === \"function\" ? _ : constant$12(!!_), zoom) : touchable;\n };\n\n zoom.extent = function(_) {\n return arguments.length ? (extent = typeof _ === \"function\" ? _ : constant$12([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;\n };\n\n zoom.scaleExtent = function(_) {\n return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]];\n };\n\n zoom.translateExtent = function(_) {\n return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]];\n };\n\n zoom.constrain = function(_) {\n return arguments.length ? (constrain = _, zoom) : constrain;\n };\n\n zoom.duration = function(_) {\n return arguments.length ? (duration = +_, zoom) : duration;\n };\n\n zoom.interpolate = function(_) {\n return arguments.length ? (interpolate = _, zoom) : interpolate;\n };\n\n zoom.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? zoom : value;\n };\n\n zoom.clickDistance = function(_) {\n return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);\n };\n\n return zoom;\n}\n\nexports.version = version;\nexports.bisect = bisectRight;\nexports.bisectRight = bisectRight;\nexports.bisectLeft = bisectLeft;\nexports.ascending = ascending;\nexports.bisector = bisector;\nexports.cross = cross;\nexports.descending = descending;\nexports.deviation = deviation;\nexports.extent = extent;\nexports.histogram = histogram;\nexports.thresholdFreedmanDiaconis = freedmanDiaconis;\nexports.thresholdScott = scott;\nexports.thresholdSturges = sturges;\nexports.max = max;\nexports.mean = mean;\nexports.median = median;\nexports.merge = merge;\nexports.min = min;\nexports.pairs = pairs;\nexports.permute = permute;\nexports.quantile = threshold;\nexports.range = sequence;\nexports.scan = scan;\nexports.shuffle = shuffle;\nexports.sum = sum;\nexports.ticks = ticks;\nexports.tickIncrement = tickIncrement;\nexports.tickStep = tickStep;\nexports.transpose = transpose;\nexports.variance = variance;\nexports.zip = zip;\nexports.axisTop = axisTop;\nexports.axisRight = axisRight;\nexports.axisBottom = axisBottom;\nexports.axisLeft = axisLeft;\nexports.brush = brush;\nexports.brushX = brushX;\nexports.brushY = brushY;\nexports.brushSelection = brushSelection;\nexports.chord = chord;\nexports.ribbon = ribbon;\nexports.nest = nest;\nexports.set = set$2;\nexports.map = map$1;\nexports.keys = keys;\nexports.values = values;\nexports.entries = entries;\nexports.color = color;\nexports.rgb = rgb;\nexports.hsl = hsl;\nexports.lab = lab;\nexports.hcl = hcl;\nexports.cubehelix = cubehelix;\nexports.dispatch = dispatch;\nexports.drag = drag;\nexports.dragDisable = dragDisable;\nexports.dragEnable = yesdrag;\nexports.dsvFormat = dsv;\nexports.csvParse = csvParse;\nexports.csvParseRows = csvParseRows;\nexports.csvFormat = csvFormat;\nexports.csvFormatRows = csvFormatRows;\nexports.tsvParse = tsvParse;\nexports.tsvParseRows = tsvParseRows;\nexports.tsvFormat = tsvFormat;\nexports.tsvFormatRows = tsvFormatRows;\nexports.easeLinear = linear$1;\nexports.easeQuad = quadInOut;\nexports.easeQuadIn = quadIn;\nexports.easeQuadOut = quadOut;\nexports.easeQuadInOut = quadInOut;\nexports.easeCubic = cubicInOut;\nexports.easeCubicIn = cubicIn;\nexports.easeCubicOut = cubicOut;\nexports.easeCubicInOut = cubicInOut;\nexports.easePoly = polyInOut;\nexports.easePolyIn = polyIn;\nexports.easePolyOut = polyOut;\nexports.easePolyInOut = polyInOut;\nexports.easeSin = sinInOut;\nexports.easeSinIn = sinIn;\nexports.easeSinOut = sinOut;\nexports.easeSinInOut = sinInOut;\nexports.easeExp = expInOut;\nexports.easeExpIn = expIn;\nexports.easeExpOut = expOut;\nexports.easeExpInOut = expInOut;\nexports.easeCircle = circleInOut;\nexports.easeCircleIn = circleIn;\nexports.easeCircleOut = circleOut;\nexports.easeCircleInOut = circleInOut;\nexports.easeBounce = bounceOut;\nexports.easeBounceIn = bounceIn;\nexports.easeBounceOut = bounceOut;\nexports.easeBounceInOut = bounceInOut;\nexports.easeBack = backInOut;\nexports.easeBackIn = backIn;\nexports.easeBackOut = backOut;\nexports.easeBackInOut = backInOut;\nexports.easeElastic = elasticOut;\nexports.easeElasticIn = elasticIn;\nexports.easeElasticOut = elasticOut;\nexports.easeElasticInOut = elasticInOut;\nexports.forceCenter = center$1;\nexports.forceCollide = collide;\nexports.forceLink = link;\nexports.forceManyBody = manyBody;\nexports.forceRadial = radial;\nexports.forceSimulation = simulation;\nexports.forceX = x$2;\nexports.forceY = y$2;\nexports.formatDefaultLocale = defaultLocale;\nexports.formatLocale = formatLocale;\nexports.formatSpecifier = formatSpecifier;\nexports.precisionFixed = precisionFixed;\nexports.precisionPrefix = precisionPrefix;\nexports.precisionRound = precisionRound;\nexports.geoArea = area;\nexports.geoBounds = bounds;\nexports.geoCentroid = centroid;\nexports.geoCircle = circle;\nexports.geoClipAntimeridian = clipAntimeridian;\nexports.geoClipCircle = clipCircle;\nexports.geoClipExtent = extent$1;\nexports.geoClipRectangle = clipRectangle;\nexports.geoContains = contains;\nexports.geoDistance = distance;\nexports.geoGraticule = graticule;\nexports.geoGraticule10 = graticule10;\nexports.geoInterpolate = interpolate$1;\nexports.geoLength = length$1;\nexports.geoPath = index$1;\nexports.geoAlbers = albers;\nexports.geoAlbersUsa = albersUsa;\nexports.geoAzimuthalEqualArea = azimuthalEqualArea;\nexports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw;\nexports.geoAzimuthalEquidistant = azimuthalEquidistant;\nexports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw;\nexports.geoConicConformal = conicConformal;\nexports.geoConicConformalRaw = conicConformalRaw;\nexports.geoConicEqualArea = conicEqualArea;\nexports.geoConicEqualAreaRaw = conicEqualAreaRaw;\nexports.geoConicEquidistant = conicEquidistant;\nexports.geoConicEquidistantRaw = conicEquidistantRaw;\nexports.geoEquirectangular = equirectangular;\nexports.geoEquirectangularRaw = equirectangularRaw;\nexports.geoGnomonic = gnomonic;\nexports.geoGnomonicRaw = gnomonicRaw;\nexports.geoIdentity = identity$5;\nexports.geoProjection = projection;\nexports.geoProjectionMutator = projectionMutator;\nexports.geoMercator = mercator;\nexports.geoMercatorRaw = mercatorRaw;\nexports.geoNaturalEarth1 = naturalEarth1;\nexports.geoNaturalEarth1Raw = naturalEarth1Raw;\nexports.geoOrthographic = orthographic;\nexports.geoOrthographicRaw = orthographicRaw;\nexports.geoStereographic = stereographic;\nexports.geoStereographicRaw = stereographicRaw;\nexports.geoTransverseMercator = transverseMercator;\nexports.geoTransverseMercatorRaw = transverseMercatorRaw;\nexports.geoRotation = rotation;\nexports.geoStream = geoStream;\nexports.geoTransform = transform;\nexports.cluster = cluster;\nexports.hierarchy = hierarchy;\nexports.pack = index$2;\nexports.packSiblings = siblings;\nexports.packEnclose = enclose;\nexports.partition = partition;\nexports.stratify = stratify;\nexports.tree = tree;\nexports.treemap = index$3;\nexports.treemapBinary = binary;\nexports.treemapDice = treemapDice;\nexports.treemapSlice = treemapSlice;\nexports.treemapSliceDice = sliceDice;\nexports.treemapSquarify = squarify;\nexports.treemapResquarify = resquarify;\nexports.interpolate = interpolateValue;\nexports.interpolateArray = array$1;\nexports.interpolateBasis = basis$1;\nexports.interpolateBasisClosed = basisClosed;\nexports.interpolateDate = date;\nexports.interpolateNumber = reinterpolate;\nexports.interpolateObject = object;\nexports.interpolateRound = interpolateRound;\nexports.interpolateString = interpolateString;\nexports.interpolateTransformCss = interpolateTransformCss;\nexports.interpolateTransformSvg = interpolateTransformSvg;\nexports.interpolateZoom = interpolateZoom;\nexports.interpolateRgb = interpolateRgb;\nexports.interpolateRgbBasis = rgbBasis;\nexports.interpolateRgbBasisClosed = rgbBasisClosed;\nexports.interpolateHsl = hsl$2;\nexports.interpolateHslLong = hslLong;\nexports.interpolateLab = lab$1;\nexports.interpolateHcl = hcl$2;\nexports.interpolateHclLong = hclLong;\nexports.interpolateCubehelix = cubehelix$2;\nexports.interpolateCubehelixLong = cubehelixLong;\nexports.quantize = quantize;\nexports.path = path;\nexports.polygonArea = area$1;\nexports.polygonCentroid = centroid$1;\nexports.polygonHull = hull;\nexports.polygonContains = contains$1;\nexports.polygonLength = length$2;\nexports.quadtree = quadtree;\nexports.queue = queue;\nexports.randomUniform = uniform;\nexports.randomNormal = normal;\nexports.randomLogNormal = logNormal;\nexports.randomBates = bates;\nexports.randomIrwinHall = irwinHall;\nexports.randomExponential = exponential$1;\nexports.request = request;\nexports.html = html;\nexports.json = json;\nexports.text = text;\nexports.xml = xml;\nexports.csv = csv$1;\nexports.tsv = tsv$1;\nexports.scaleBand = band;\nexports.scalePoint = point$1;\nexports.scaleIdentity = identity$6;\nexports.scaleLinear = linear$2;\nexports.scaleLog = log$1;\nexports.scaleOrdinal = ordinal;\nexports.scaleImplicit = implicit;\nexports.scalePow = pow$1;\nexports.scaleSqrt = sqrt$1;\nexports.scaleQuantile = quantile$$1;\nexports.scaleQuantize = quantize$1;\nexports.scaleThreshold = threshold$1;\nexports.scaleTime = time;\nexports.scaleUtc = utcTime;\nexports.schemeCategory10 = category10;\nexports.schemeCategory20b = category20b;\nexports.schemeCategory20c = category20c;\nexports.schemeCategory20 = category20;\nexports.interpolateCubehelixDefault = cubehelix$3;\nexports.interpolateRainbow = rainbow$1;\nexports.interpolateWarm = warm;\nexports.interpolateCool = cool;\nexports.interpolateViridis = viridis;\nexports.interpolateMagma = magma;\nexports.interpolateInferno = inferno;\nexports.interpolatePlasma = plasma;\nexports.scaleSequential = sequential;\nexports.create = create;\nexports.creator = creator;\nexports.local = local$1;\nexports.matcher = matcher$1;\nexports.mouse = mouse;\nexports.namespace = namespace;\nexports.namespaces = namespaces;\nexports.clientPoint = point;\nexports.select = select;\nexports.selectAll = selectAll;\nexports.selection = selection;\nexports.selector = selector;\nexports.selectorAll = selectorAll;\nexports.style = styleValue;\nexports.touch = touch;\nexports.touches = touches;\nexports.window = defaultView;\nexports.customEvent = customEvent;\nexports.arc = arc;\nexports.area = area$2;\nexports.line = line;\nexports.pie = pie;\nexports.areaRadial = areaRadial;\nexports.radialArea = areaRadial;\nexports.lineRadial = lineRadial$1;\nexports.radialLine = lineRadial$1;\nexports.pointRadial = pointRadial;\nexports.linkHorizontal = linkHorizontal;\nexports.linkVertical = linkVertical;\nexports.linkRadial = linkRadial;\nexports.symbol = symbol;\nexports.symbols = symbols;\nexports.symbolCircle = circle$2;\nexports.symbolCross = cross$2;\nexports.symbolDiamond = diamond;\nexports.symbolSquare = square;\nexports.symbolStar = star;\nexports.symbolTriangle = triangle;\nexports.symbolWye = wye;\nexports.curveBasisClosed = basisClosed$1;\nexports.curveBasisOpen = basisOpen;\nexports.curveBasis = basis$2;\nexports.curveBundle = bundle;\nexports.curveCardinalClosed = cardinalClosed;\nexports.curveCardinalOpen = cardinalOpen;\nexports.curveCardinal = cardinal;\nexports.curveCatmullRomClosed = catmullRomClosed;\nexports.curveCatmullRomOpen = catmullRomOpen;\nexports.curveCatmullRom = catmullRom;\nexports.curveLinearClosed = linearClosed;\nexports.curveLinear = curveLinear;\nexports.curveMonotoneX = monotoneX;\nexports.curveMonotoneY = monotoneY;\nexports.curveNatural = natural;\nexports.curveStep = step;\nexports.curveStepAfter = stepAfter;\nexports.curveStepBefore = stepBefore;\nexports.stack = stack;\nexports.stackOffsetExpand = expand;\nexports.stackOffsetDiverging = diverging;\nexports.stackOffsetNone = none$1;\nexports.stackOffsetSilhouette = silhouette;\nexports.stackOffsetWiggle = wiggle;\nexports.stackOrderAscending = ascending$2;\nexports.stackOrderDescending = descending$2;\nexports.stackOrderInsideOut = insideOut;\nexports.stackOrderNone = none$2;\nexports.stackOrderReverse = reverse;\nexports.timeInterval = newInterval;\nexports.timeMillisecond = millisecond;\nexports.timeMilliseconds = milliseconds;\nexports.utcMillisecond = millisecond;\nexports.utcMilliseconds = milliseconds;\nexports.timeSecond = second;\nexports.timeSeconds = seconds;\nexports.utcSecond = second;\nexports.utcSeconds = seconds;\nexports.timeMinute = minute;\nexports.timeMinutes = minutes;\nexports.timeHour = hour;\nexports.timeHours = hours;\nexports.timeDay = day;\nexports.timeDays = days;\nexports.timeWeek = sunday;\nexports.timeWeeks = sundays;\nexports.timeSunday = sunday;\nexports.timeSundays = sundays;\nexports.timeMonday = monday;\nexports.timeMondays = mondays;\nexports.timeTuesday = tuesday;\nexports.timeTuesdays = tuesdays;\nexports.timeWednesday = wednesday;\nexports.timeWednesdays = wednesdays;\nexports.timeThursday = thursday;\nexports.timeThursdays = thursdays;\nexports.timeFriday = friday;\nexports.timeFridays = fridays;\nexports.timeSaturday = saturday;\nexports.timeSaturdays = saturdays;\nexports.timeMonth = month;\nexports.timeMonths = months;\nexports.timeYear = year;\nexports.timeYears = years;\nexports.utcMinute = utcMinute;\nexports.utcMinutes = utcMinutes;\nexports.utcHour = utcHour;\nexports.utcHours = utcHours;\nexports.utcDay = utcDay;\nexports.utcDays = utcDays;\nexports.utcWeek = utcSunday;\nexports.utcWeeks = utcSundays;\nexports.utcSunday = utcSunday;\nexports.utcSundays = utcSundays;\nexports.utcMonday = utcMonday;\nexports.utcMondays = utcMondays;\nexports.utcTuesday = utcTuesday;\nexports.utcTuesdays = utcTuesdays;\nexports.utcWednesday = utcWednesday;\nexports.utcWednesdays = utcWednesdays;\nexports.utcThursday = utcThursday;\nexports.utcThursdays = utcThursdays;\nexports.utcFriday = utcFriday;\nexports.utcFridays = utcFridays;\nexports.utcSaturday = utcSaturday;\nexports.utcSaturdays = utcSaturdays;\nexports.utcMonth = utcMonth;\nexports.utcMonths = utcMonths;\nexports.utcYear = utcYear;\nexports.utcYears = utcYears;\nexports.timeFormatDefaultLocale = defaultLocale$1;\nexports.timeFormatLocale = formatLocale$1;\nexports.isoFormat = formatIso;\nexports.isoParse = parseIso;\nexports.now = now;\nexports.timer = timer;\nexports.timerFlush = timerFlush;\nexports.timeout = timeout$1;\nexports.interval = interval$1;\nexports.transition = transition;\nexports.active = active;\nexports.interrupt = interrupt;\nexports.voronoi = voronoi;\nexports.zoom = zoom;\nexports.zoomTransform = transform$1;\nexports.zoomIdentity = identity$8;\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n"]} \ No newline at end of file diff --git a/lib/element-resize-detector/element-resize-detector.js b/lib/element-resize-detector/element-resize-detector.js index 9b0266f43cb..6ee98e02043 100644 --- a/lib/element-resize-detector/element-resize-detector.js +++ b/lib/element-resize-detector/element-resize-detector.js @@ -1,2 +1,2 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).elementResizeDetectorMaker=e()}}(function(){return function r(a,s,l){function d(t,e){if(!s[t]){if(!a[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(c)return c(t,!0);var i=new Error("Cannot find module '"+t+"'");throw i.code="MODULE_NOT_FOUND",i}var o=s[t]={exports:{}};a[t][0].call(o.exports,function(e){return d(a[t][1][e]||e)},o,o.exports,r,a,s,l)}return s[t].exports}for(var c="function"==typeof require&&require,e=0;e div::-webkit-scrollbar { display: none; }\n\n",o+="."+n+" { -webkit-animation-duration: 0.1s; animation-duration: 0.1s; -webkit-animation-name: "+t+"; animation-name: "+t+"; }\n",o+="@-webkit-keyframes "+t+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\n",function(e,t){t=t||function(e){document.head.appendChild(e)};var n=document.createElement("style");n.innerHTML=e,n.id=i,t(n)}(o+="@keyframes "+t+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }")}}("erd_scroll_detection_scrollbar_style",k),{makeDetectable:function(a,v,e){function m(){if(a.debug){var e=Array.prototype.slice.call(arguments);if(e.unshift(A.get(v),"Scroll: "),x.log.apply)x.log.apply(null,e);else for(var t=0;t div::-webkit-scrollbar { display: none; }\n\n",o+="."+n+" { -webkit-animation-duration: 0.1s; animation-duration: 0.1s; -webkit-animation-name: "+t+"; animation-name: "+t+"; }\n",o+="@-webkit-keyframes "+t+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\n",function(e,t){t=t||function(e){document.head.appendChild(e)};var n=document.createElement("style");n.innerHTML=e,n.id=i,t(n)}(o+="@keyframes "+t+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }")}}("erd_scroll_detection_scrollbar_style",k),{makeDetectable:function(a,v,e){function m(){if(a.debug){var e=Array.prototype.slice.call(arguments);if(e.unshift(A.get(v),"Scroll: "),x.log.apply)x.log.apply(null,e);else for(var t=0;t topLevel) {\n topLevel = level;\n } else if(level < bottomLevel) {\n bottomLevel = level;\n }\n\n if(!batch[level]) {\n batch[level] = [];\n }\n\n batch[level].push(fn);\n size++;\n }\n\n function process() {\n for(var level = bottomLevel; level <= topLevel; level++) {\n var fns = batch[level];\n\n for(var i = 0; i < fns.length; i++) {\n var fn = fns[i];\n fn();\n }\n }\n }\n\n function getSize() {\n return size;\n }\n\n return {\n add: add,\n process: process,\n size: getSize\n };\n}\n\n},{\"./utils\":2}],2:[function(require,module,exports){\n\"use strict\";\n\nvar utils = module.exports = {};\n\nutils.getOption = getOption;\n\nfunction getOption(options, name, defaultValue) {\n var value = options[name];\n\n if((value === undefined || value === null) && defaultValue !== undefined) {\n return defaultValue;\n }\n\n return value;\n}\n\n},{}],3:[function(require,module,exports){\n\"use strict\";\n\nvar detector = module.exports = {};\n\ndetector.isIE = function(version) {\n function isAnyIeVersion() {\n var agent = navigator.userAgent.toLowerCase();\n return agent.indexOf(\"msie\") !== -1 || agent.indexOf(\"trident\") !== -1 || agent.indexOf(\" edge/\") !== -1;\n }\n\n if(!isAnyIeVersion()) {\n return false;\n }\n\n if(!version) {\n return true;\n }\n\n //Shamelessly stolen from https://gist.github.com/padolsey/527683\n var ieVersion = (function(){\n var undef,\n v = 3,\n div = document.createElement(\"div\"),\n all = div.getElementsByTagName(\"i\");\n\n do {\n div.innerHTML = \"\";\n }\n while (all[0]);\n\n return v > 4 ? v : undef;\n }());\n\n return version === ieVersion;\n};\n\ndetector.isLegacyOpera = function() {\n return !!window.opera;\n};\n\n},{}],4:[function(require,module,exports){\n\"use strict\";\n\nvar utils = module.exports = {};\n\n/**\n * Loops through the collection and calls the callback for each element. if the callback returns truthy, the loop is broken and returns the same value.\n * @public\n * @param {*} collection The collection to loop through. Needs to have a length property set and have indices set from 0 to length - 1.\n * @param {function} callback The callback to be called for each element. The element will be given as a parameter to the callback. If this callback returns truthy, the loop is broken and the same value is returned.\n * @returns {*} The value that a callback has returned (if truthy). Otherwise nothing.\n */\nutils.forEach = function(collection, callback) {\n for(var i = 0; i < collection.length; i++) {\n var result = callback(collection[i]);\n if(result) {\n return result;\n }\n }\n};\n\n},{}],5:[function(require,module,exports){\n/**\n * Resize detection strategy that injects objects to elements in order to detect resize events.\n * Heavily inspired by: http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/\n */\n\n\"use strict\";\n\nvar browserDetector = require(\"../browser-detector\");\n\nmodule.exports = function(options) {\n options = options || {};\n var reporter = options.reporter;\n var batchProcessor = options.batchProcessor;\n var getState = options.stateHandler.getState;\n\n if(!reporter) {\n throw new Error(\"Missing required dependency: reporter.\");\n }\n\n /**\n * Adds a resize event listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The listener callback to be called for each resize event of the element. The element will be given as a parameter to the listener callback.\n */\n function addListener(element, listener) {\n if(!getObject(element)) {\n throw new Error(\"Element is not detectable by this strategy.\");\n }\n\n function listenerProxy() {\n listener(element);\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support object, but supports the resize event directly on elements.\n getState(element).object = {\n proxy: listenerProxy\n };\n element.attachEvent(\"onresize\", listenerProxy);\n } else {\n var object = getObject(element);\n object.contentDocument.defaultView.addEventListener(\"resize\", listenerProxy);\n }\n }\n\n /**\n * Makes an element detectable and ready to be listened for resize events. Will call the callback when the element is ready to be listened for resize changes.\n * @private\n * @param {object} options Optional options object.\n * @param {element} element The element to make detectable\n * @param {function} callback The callback to be called when the element is ready to be listened for resize changes. Will be called with the element as first parameter.\n */\n function makeDetectable(options, element, callback) {\n if (!callback) {\n callback = element;\n element = options;\n options = null;\n }\n\n options = options || {};\n var debug = options.debug;\n\n function injectObject(element, callback) {\n var OBJECT_STYLE = \"display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;\";\n\n //The target element needs to be positioned (everything except static) so the absolute positioned object will be positioned relative to the target element.\n\n // Position altering may be performed directly or on object load, depending on if style resolution is possible directly or not.\n var positionCheckPerformed = false;\n\n // The element may not yet be attached to the DOM, and therefore the style object may be empty in some browsers.\n // Since the style object is a reference, it will be updated as soon as the element is attached to the DOM.\n var style = window.getComputedStyle(element);\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n getState(element).startSize = {\n width: width,\n height: height\n };\n\n function mutateDom() {\n function alterPositionStyles() {\n if(style.position === \"static\") {\n element.style.position = \"relative\";\n\n var removeRelativeStyles = function(reporter, element, style, property) {\n function getNumericalValue(value) {\n return value.replace(/[^-\\d\\.]/g, \"\");\n }\n\n var value = style[property];\n\n if(value !== \"auto\" && getNumericalValue(value) !== \"0\") {\n reporter.warn(\"An element that is positioned static has style.\" + property + \"=\" + value + \" which is ignored due to the static positioning. The element will need to be positioned relative, so the style.\" + property + \" will be set to 0. Element: \", element);\n element.style[property] = 0;\n }\n };\n\n //Check so that there are no accidental styles that will make the element styled differently now that is is relative.\n //If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway).\n removeRelativeStyles(reporter, element, style, \"top\");\n removeRelativeStyles(reporter, element, style, \"right\");\n removeRelativeStyles(reporter, element, style, \"bottom\");\n removeRelativeStyles(reporter, element, style, \"left\");\n }\n }\n\n function onObjectLoad() {\n // The object has been loaded, which means that the element now is guaranteed to be attached to the DOM.\n if (!positionCheckPerformed) {\n alterPositionStyles();\n }\n\n /*jshint validthis: true */\n\n function getDocument(element, callback) {\n //Opera 12 seem to call the object.onload before the actual document has been created.\n //So if it is not present, poll it with an timeout until it is present.\n //TODO: Could maybe be handled better with object.onreadystatechange or similar.\n if(!element.contentDocument) {\n setTimeout(function checkForObjectDocument() {\n getDocument(element, callback);\n }, 100);\n\n return;\n }\n\n callback(element.contentDocument);\n }\n\n //Mutating the object element here seems to fire another load event.\n //Mutating the inner document of the object element is fine though.\n var objectElement = this;\n\n //Create the style element to be added to the object.\n getDocument(objectElement, function onObjectDocumentReady(objectDocument) {\n //Notify that the element is ready to be listened to.\n callback(element);\n });\n }\n\n // The element may be detached from the DOM, and some browsers does not support style resolving of detached elements.\n // The alterPositionStyles needs to be delayed until we know the element has been attached to the DOM (which we are sure of when the onObjectLoad has been fired), if style resolution is not possible.\n if (style.position !== \"\") {\n alterPositionStyles(style);\n positionCheckPerformed = true;\n }\n\n //Add an object element as a child to the target element that will be listened to for resize events.\n var object = document.createElement(\"object\");\n object.style.cssText = OBJECT_STYLE;\n object.tabIndex = -1;\n object.type = \"text/html\";\n object.setAttribute(\"aria-hidden\", \"true\");\n object.onload = onObjectLoad;\n\n //Safari: This must occur before adding the object to the DOM.\n //IE: Does not like that this happens before, even if it is also added after.\n if(!browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n\n element.appendChild(object);\n getState(element).object = object;\n\n //IE: This must occur after adding the object to the DOM.\n if(browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n }\n\n if(batchProcessor) {\n batchProcessor.add(mutateDom);\n } else {\n mutateDom();\n }\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support objects properly. Luckily they do support the resize event.\n //So do not inject the object and notify that the element is already ready to be listened to.\n //The event handler for the resize event is attached in the utils.addListener instead.\n callback(element);\n } else {\n injectObject(element, callback);\n }\n }\n\n /**\n * Returns the child object of the target element.\n * @private\n * @param {element} element The target element.\n * @returns The object element of the target.\n */\n function getObject(element) {\n return getState(element).object;\n }\n\n function uninstall(element) {\n if(browserDetector.isIE(8)) {\n element.detachEvent(\"onresize\", getState(element).object.proxy);\n } else {\n element.removeChild(getObject(element));\n }\n delete getState(element).object;\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall\n };\n};\n\n},{\"../browser-detector\":3}],6:[function(require,module,exports){\n/**\n * Resize detection strategy that injects divs to elements in order to detect resize events on scroll events.\n * Heavily inspired by: https://github.com/marcj/css-element-queries/blob/master/src/ResizeSensor.js\n */\n\n\"use strict\";\n\nvar forEach = require(\"../collection-utils\").forEach;\n\nmodule.exports = function(options) {\n options = options || {};\n var reporter = options.reporter;\n var batchProcessor = options.batchProcessor;\n var getState = options.stateHandler.getState;\n var hasState = options.stateHandler.hasState;\n var idHandler = options.idHandler;\n\n if (!batchProcessor) {\n throw new Error(\"Missing required dependency: batchProcessor\");\n }\n\n if (!reporter) {\n throw new Error(\"Missing required dependency: reporter.\");\n }\n\n //TODO: Could this perhaps be done at installation time?\n var scrollbarSizes = getScrollbarSizes();\n\n // Inject the scrollbar styling that prevents them from appearing sometimes in Chrome.\n // The injected container needs to have a class, so that it may be styled with CSS (pseudo elements).\n var styleId = \"erd_scroll_detection_scrollbar_style\";\n var detectionContainerClass = \"erd_scroll_detection_container\";\n injectScrollStyle(styleId, detectionContainerClass);\n\n function getScrollbarSizes() {\n var width = 500;\n var height = 500;\n\n var child = document.createElement(\"div\");\n child.style.cssText = \"position: absolute; width: \" + width*2 + \"px; height: \" + height*2 + \"px; visibility: hidden; margin: 0; padding: 0;\";\n\n var container = document.createElement(\"div\");\n container.style.cssText = \"position: absolute; width: \" + width + \"px; height: \" + height + \"px; overflow: scroll; visibility: none; top: \" + -width*3 + \"px; left: \" + -height*3 + \"px; visibility: hidden; margin: 0; padding: 0;\";\n\n container.appendChild(child);\n\n document.body.insertBefore(container, document.body.firstChild);\n\n var widthSize = width - container.clientWidth;\n var heightSize = height - container.clientHeight;\n\n document.body.removeChild(container);\n\n return {\n width: widthSize,\n height: heightSize\n };\n }\n\n function injectScrollStyle(styleId, containerClass) {\n function injectStyle(style, method) {\n method = method || function (element) {\n document.head.appendChild(element);\n };\n\n var styleElement = document.createElement(\"style\");\n styleElement.innerHTML = style;\n styleElement.id = styleId;\n method(styleElement);\n return styleElement;\n }\n\n if (!document.getElementById(styleId)) {\n var containerAnimationClass = containerClass + \"_animation\";\n var containerAnimationActiveClass = containerClass + \"_animation_active\";\n var style = \"/* Created by the element-resize-detector library. */\\n\";\n style += \".\" + containerClass + \" > div::-webkit-scrollbar { display: none; }\\n\\n\";\n style += \".\" + containerAnimationActiveClass + \" { -webkit-animation-duration: 0.1s; animation-duration: 0.1s; -webkit-animation-name: \" + containerAnimationClass + \"; animation-name: \" + containerAnimationClass + \"; }\\n\";\n style += \"@-webkit-keyframes \" + containerAnimationClass + \" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\\n\";\n style += \"@keyframes \" + containerAnimationClass + \" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\";\n injectStyle(style);\n }\n }\n\n function addAnimationClass(element) {\n element.className += \" \" + detectionContainerClass + \"_animation_active\";\n }\n\n function addEvent(el, name, cb) {\n if (el.addEventListener) {\n el.addEventListener(name, cb);\n } else if(el.attachEvent) {\n el.attachEvent(\"on\" + name, cb);\n } else {\n return reporter.error(\"[scroll] Don't know how to add event listeners.\");\n }\n }\n\n function removeEvent(el, name, cb) {\n if (el.removeEventListener) {\n el.removeEventListener(name, cb);\n } else if(el.detachEvent) {\n el.detachEvent(\"on\" + name, cb);\n } else {\n return reporter.error(\"[scroll] Don't know how to remove event listeners.\");\n }\n }\n\n function getExpandElement(element) {\n return getState(element).container.childNodes[0].childNodes[0].childNodes[0];\n }\n\n function getShrinkElement(element) {\n return getState(element).container.childNodes[0].childNodes[0].childNodes[1];\n }\n\n /**\n * Adds a resize event listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The listener callback to be called for each resize event of the element. The element will be given as a parameter to the listener callback.\n */\n function addListener(element, listener) {\n var listeners = getState(element).listeners;\n\n if (!listeners.push) {\n throw new Error(\"Cannot add listener to an element that is not detectable.\");\n }\n\n getState(element).listeners.push(listener);\n }\n\n /**\n * Makes an element detectable and ready to be listened for resize events. Will call the callback when the element is ready to be listened for resize changes.\n * @private\n * @param {object} options Optional options object.\n * @param {element} element The element to make detectable\n * @param {function} callback The callback to be called when the element is ready to be listened for resize changes. Will be called with the element as first parameter.\n */\n function makeDetectable(options, element, callback) {\n if (!callback) {\n callback = element;\n element = options;\n options = null;\n }\n\n options = options || {};\n\n function debug() {\n if (options.debug) {\n var args = Array.prototype.slice.call(arguments);\n args.unshift(idHandler.get(element), \"Scroll: \");\n if (reporter.log.apply) {\n reporter.log.apply(null, args);\n } else {\n for (var i = 0; i < args.length; i++) {\n reporter.log(args[i]);\n }\n }\n }\n }\n\n function isDetached(element) {\n function isInDocument(element) {\n return element === element.ownerDocument.body || element.ownerDocument.body.contains(element);\n }\n\n if (!isInDocument(element)) {\n return true;\n }\n\n // FireFox returns null style in hidden iframes. See https://github.com/wnr/element-resize-detector/issues/68 and https://bugzilla.mozilla.org/show_bug.cgi?id=795520\n if (window.getComputedStyle(element) === null) {\n return true;\n }\n\n return false;\n }\n\n function isUnrendered(element) {\n // Check the absolute positioned container since the top level container is display: inline.\n var container = getState(element).container.childNodes[0];\n var style = window.getComputedStyle(container);\n return !style.width || style.width.indexOf(\"px\") === -1; //Can only compute pixel value when rendered.\n }\n\n function getStyle() {\n // Some browsers only force layouts when actually reading the style properties of the style object, so make sure that they are all read here,\n // so that the user of the function can be sure that it will perform the layout here, instead of later (important for batching).\n var elementStyle = window.getComputedStyle(element);\n var style = {};\n style.position = elementStyle.position;\n style.width = element.offsetWidth;\n style.height = element.offsetHeight;\n style.top = elementStyle.top;\n style.right = elementStyle.right;\n style.bottom = elementStyle.bottom;\n style.left = elementStyle.left;\n style.widthCSS = elementStyle.width;\n style.heightCSS = elementStyle.height;\n return style;\n }\n\n function storeStartSize() {\n var style = getStyle();\n getState(element).startSize = {\n width: style.width,\n height: style.height\n };\n debug(\"Element start size\", getState(element).startSize);\n }\n\n function initListeners() {\n getState(element).listeners = [];\n }\n\n function storeStyle() {\n debug(\"storeStyle invoked.\");\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n var style = getStyle();\n getState(element).style = style;\n }\n\n function storeCurrentSize(element, width, height) {\n getState(element).lastWidth = width;\n getState(element).lastHeight = height;\n }\n\n function getExpandChildElement(element) {\n return getExpandElement(element).childNodes[0];\n }\n\n function getWidthOffset() {\n return 2 * scrollbarSizes.width + 1;\n }\n\n function getHeightOffset() {\n return 2 * scrollbarSizes.height + 1;\n }\n\n function getExpandWidth(width) {\n return width + 10 + getWidthOffset();\n }\n\n function getExpandHeight(height) {\n return height + 10 + getHeightOffset();\n }\n\n function getShrinkWidth(width) {\n return width * 2 + getWidthOffset();\n }\n\n function getShrinkHeight(height) {\n return height * 2 + getHeightOffset();\n }\n\n function positionScrollbars(element, width, height) {\n var expand = getExpandElement(element);\n var shrink = getShrinkElement(element);\n var expandWidth = getExpandWidth(width);\n var expandHeight = getExpandHeight(height);\n var shrinkWidth = getShrinkWidth(width);\n var shrinkHeight = getShrinkHeight(height);\n expand.scrollLeft = expandWidth;\n expand.scrollTop = expandHeight;\n shrink.scrollLeft = shrinkWidth;\n shrink.scrollTop = shrinkHeight;\n }\n\n function injectContainerElement() {\n var container = getState(element).container;\n\n if (!container) {\n container = document.createElement(\"div\");\n container.className = detectionContainerClass;\n container.style.cssText = \"visibility: hidden; display: inline; width: 0px; height: 0px; z-index: -1; overflow: hidden; margin: 0; padding: 0;\";\n getState(element).container = container;\n addAnimationClass(container);\n element.appendChild(container);\n\n var onAnimationStart = function () {\n getState(element).onRendered && getState(element).onRendered();\n };\n\n addEvent(container, \"animationstart\", onAnimationStart);\n\n // Store the event handler here so that they may be removed when uninstall is called.\n // See uninstall function for an explanation why it is needed.\n getState(element).onAnimationStart = onAnimationStart;\n }\n\n return container;\n }\n\n function injectScrollElements() {\n function alterPositionStyles() {\n var style = getState(element).style;\n\n if(style.position === \"static\") {\n element.style.position = \"relative\";\n\n var removeRelativeStyles = function(reporter, element, style, property) {\n function getNumericalValue(value) {\n return value.replace(/[^-\\d\\.]/g, \"\");\n }\n\n var value = style[property];\n\n if(value !== \"auto\" && getNumericalValue(value) !== \"0\") {\n reporter.warn(\"An element that is positioned static has style.\" + property + \"=\" + value + \" which is ignored due to the static positioning. The element will need to be positioned relative, so the style.\" + property + \" will be set to 0. Element: \", element);\n element.style[property] = 0;\n }\n };\n\n //Check so that there are no accidental styles that will make the element styled differently now that is is relative.\n //If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway).\n removeRelativeStyles(reporter, element, style, \"top\");\n removeRelativeStyles(reporter, element, style, \"right\");\n removeRelativeStyles(reporter, element, style, \"bottom\");\n removeRelativeStyles(reporter, element, style, \"left\");\n }\n }\n\n function getLeftTopBottomRightCssText(left, top, bottom, right) {\n left = (!left ? \"0\" : (left + \"px\"));\n top = (!top ? \"0\" : (top + \"px\"));\n bottom = (!bottom ? \"0\" : (bottom + \"px\"));\n right = (!right ? \"0\" : (right + \"px\"));\n\n return \"left: \" + left + \"; top: \" + top + \"; right: \" + right + \"; bottom: \" + bottom + \";\";\n }\n\n debug(\"Injecting elements\");\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n alterPositionStyles();\n\n var rootContainer = getState(element).container;\n\n if (!rootContainer) {\n rootContainer = injectContainerElement();\n }\n\n // Due to this WebKit bug https://bugs.webkit.org/show_bug.cgi?id=80808 (currently fixed in Blink, but still present in WebKit browsers such as Safari),\n // we need to inject two containers, one that is width/height 100% and another that is left/top -1px so that the final container always is 1x1 pixels bigger than\n // the targeted element.\n // When the bug is resolved, \"containerContainer\" may be removed.\n\n // The outer container can occasionally be less wide than the targeted when inside inline elements element in WebKit (see https://bugs.webkit.org/show_bug.cgi?id=152980).\n // This should be no problem since the inner container either way makes sure the injected scroll elements are at least 1x1 px.\n\n var scrollbarWidth = scrollbarSizes.width;\n var scrollbarHeight = scrollbarSizes.height;\n var containerContainerStyle = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; width: 100%; height: 100%; left: 0px; top: 0px;\";\n var containerStyle = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; \" + getLeftTopBottomRightCssText(-(1 + scrollbarWidth), -(1 + scrollbarHeight), -scrollbarHeight, -scrollbarWidth);\n var expandStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var shrinkStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var expandChildStyle = \"position: absolute; left: 0; top: 0;\";\n var shrinkChildStyle = \"position: absolute; width: 200%; height: 200%;\";\n\n var containerContainer = document.createElement(\"div\");\n var container = document.createElement(\"div\");\n var expand = document.createElement(\"div\");\n var expandChild = document.createElement(\"div\");\n var shrink = document.createElement(\"div\");\n var shrinkChild = document.createElement(\"div\");\n\n // Some browsers choke on the resize system being rtl, so force it to ltr. https://github.com/wnr/element-resize-detector/issues/56\n // However, dir should not be set on the top level container as it alters the dimensions of the target element in some browsers.\n containerContainer.dir = \"ltr\";\n\n containerContainer.style.cssText = containerContainerStyle;\n containerContainer.className = detectionContainerClass;\n container.className = detectionContainerClass;\n container.style.cssText = containerStyle;\n expand.style.cssText = expandStyle;\n expandChild.style.cssText = expandChildStyle;\n shrink.style.cssText = shrinkStyle;\n shrinkChild.style.cssText = shrinkChildStyle;\n\n expand.appendChild(expandChild);\n shrink.appendChild(shrinkChild);\n container.appendChild(expand);\n container.appendChild(shrink);\n containerContainer.appendChild(container);\n rootContainer.appendChild(containerContainer);\n\n function onExpandScroll() {\n getState(element).onExpand && getState(element).onExpand();\n }\n\n function onShrinkScroll() {\n getState(element).onShrink && getState(element).onShrink();\n }\n\n addEvent(expand, \"scroll\", onExpandScroll);\n addEvent(shrink, \"scroll\", onShrinkScroll);\n\n // Store the event handlers here so that they may be removed when uninstall is called.\n // See uninstall function for an explanation why it is needed.\n getState(element).onExpandScroll = onExpandScroll;\n getState(element).onShrinkScroll = onShrinkScroll;\n }\n\n function registerListenersAndPositionElements() {\n function updateChildSizes(element, width, height) {\n var expandChild = getExpandChildElement(element);\n var expandWidth = getExpandWidth(width);\n var expandHeight = getExpandHeight(height);\n expandChild.style.width = expandWidth + \"px\";\n expandChild.style.height = expandHeight + \"px\";\n }\n\n function updateDetectorElements(done) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n debug(\"Storing current size\", width, height);\n\n // Store the size of the element sync here, so that multiple scroll events may be ignored in the event listeners.\n // Otherwise the if-check in handleScroll is useless.\n storeCurrentSize(element, width, height);\n\n // Since we delay the processing of the batch, there is a risk that uninstall has been called before the batch gets to execute.\n // Since there is no way to cancel the fn executions, we need to add an uninstall guard to all fns of the batch.\n\n batchProcessor.add(0, function performUpdateChildSizes() {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n if (!areElementsInjected()) {\n debug(\"Aborting because element container has not been initialized\");\n return;\n }\n\n if (options.debug) {\n var w = element.offsetWidth;\n var h = element.offsetHeight;\n\n if (w !== width || h !== height) {\n reporter.warn(idHandler.get(element), \"Scroll: Size changed before updating detector elements.\");\n }\n }\n\n updateChildSizes(element, width, height);\n });\n\n batchProcessor.add(1, function updateScrollbars() {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n if (!areElementsInjected()) {\n debug(\"Aborting because element container has not been initialized\");\n return;\n }\n\n positionScrollbars(element, width, height);\n });\n\n if (done) {\n batchProcessor.add(2, function () {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n if (!areElementsInjected()) {\n debug(\"Aborting because element container has not been initialized\");\n return;\n }\n\n done();\n });\n }\n }\n\n function areElementsInjected() {\n return !!getState(element).container;\n }\n\n function notifyListenersIfNeeded() {\n function isFirstNotify() {\n return getState(element).lastNotifiedWidth === undefined;\n }\n\n debug(\"notifyListenersIfNeeded invoked\");\n\n var state = getState(element);\n\n // Don't notify the if the current size is the start size, and this is the first notification.\n if (isFirstNotify() && state.lastWidth === state.startSize.width && state.lastHeight === state.startSize.height) {\n return debug(\"Not notifying: Size is the same as the start size, and there has been no notification yet.\");\n }\n\n // Don't notify if the size already has been notified.\n if (state.lastWidth === state.lastNotifiedWidth && state.lastHeight === state.lastNotifiedHeight) {\n return debug(\"Not notifying: Size already notified\");\n }\n\n\n debug(\"Current size not notified, notifying...\");\n state.lastNotifiedWidth = state.lastWidth;\n state.lastNotifiedHeight = state.lastHeight;\n forEach(getState(element).listeners, function (listener) {\n listener(element);\n });\n }\n\n function handleRender() {\n debug(\"startanimation triggered.\");\n\n if (isUnrendered(element)) {\n debug(\"Ignoring since element is still unrendered...\");\n return;\n }\n\n debug(\"Element rendered.\");\n var expand = getExpandElement(element);\n var shrink = getShrinkElement(element);\n if (expand.scrollLeft === 0 || expand.scrollTop === 0 || shrink.scrollLeft === 0 || shrink.scrollTop === 0) {\n debug(\"Scrollbars out of sync. Updating detector elements...\");\n updateDetectorElements(notifyListenersIfNeeded);\n }\n }\n\n function handleScroll() {\n debug(\"Scroll detected.\");\n\n if (isUnrendered(element)) {\n // Element is still unrendered. Skip this scroll event.\n debug(\"Scroll event fired while unrendered. Ignoring...\");\n return;\n }\n\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (width !== getState(element).lastWidth || height !== getState(element).lastHeight) {\n debug(\"Element size changed.\");\n updateDetectorElements(notifyListenersIfNeeded);\n } else {\n debug(\"Element size has not changed (\" + width + \"x\" + height + \").\");\n }\n }\n\n debug(\"registerListenersAndPositionElements invoked.\");\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n getState(element).onRendered = handleRender;\n getState(element).onExpand = handleScroll;\n getState(element).onShrink = handleScroll;\n\n var style = getState(element).style;\n updateChildSizes(element, style.width, style.height);\n }\n\n function finalizeDomMutation() {\n debug(\"finalizeDomMutation invoked.\");\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n var style = getState(element).style;\n storeCurrentSize(element, style.width, style.height);\n positionScrollbars(element, style.width, style.height);\n }\n\n function ready() {\n callback(element);\n }\n\n function install() {\n debug(\"Installing...\");\n initListeners();\n storeStartSize();\n\n batchProcessor.add(0, storeStyle);\n batchProcessor.add(1, injectScrollElements);\n batchProcessor.add(2, registerListenersAndPositionElements);\n batchProcessor.add(3, finalizeDomMutation);\n batchProcessor.add(4, ready);\n }\n\n debug(\"Making detectable...\");\n\n if (isDetached(element)) {\n debug(\"Element is detached\");\n\n injectContainerElement();\n\n debug(\"Waiting until element is attached...\");\n\n getState(element).onRendered = function () {\n debug(\"Element is now attached\");\n install();\n };\n } else {\n install();\n }\n }\n\n function uninstall(element) {\n var state = getState(element);\n\n if (!state) {\n // Uninstall has been called on a non-erd element.\n return;\n }\n\n // Uninstall may have been called in the following scenarios:\n // (1) Right between the sync code and async batch (here state.busy = true, but nothing have been registered or injected).\n // (2) In the ready callback of the last level of the batch by another element (here, state.busy = true, but all the stuff has been injected).\n // (3) After the installation process (here, state.busy = false and all the stuff has been injected).\n // So to be on the safe side, let's check for each thing before removing.\n\n // We need to remove the event listeners, because otherwise the event might fire on an uninstall element which results in an error when trying to get the state of the element.\n state.onExpandScroll && removeEvent(getExpandElement(element), \"scroll\", state.onExpandScroll);\n state.onShrinkScroll && removeEvent(getShrinkElement(element), \"scroll\", state.onShrinkScroll);\n state.onAnimationStart && removeEvent(state.container, \"animationstart\", state.onAnimationStart);\n\n state.container && element.removeChild(state.container);\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall\n };\n};\n\n},{\"../collection-utils\":4}],7:[function(require,module,exports){\n\"use strict\";\n\nvar forEach = require(\"./collection-utils\").forEach;\nvar elementUtilsMaker = require(\"./element-utils\");\nvar listenerHandlerMaker = require(\"./listener-handler\");\nvar idGeneratorMaker = require(\"./id-generator\");\nvar idHandlerMaker = require(\"./id-handler\");\nvar reporterMaker = require(\"./reporter\");\nvar browserDetector = require(\"./browser-detector\");\nvar batchProcessorMaker = require(\"batch-processor\");\nvar stateHandler = require(\"./state-handler\");\n\n//Detection strategies.\nvar objectStrategyMaker = require(\"./detection-strategy/object.js\");\nvar scrollStrategyMaker = require(\"./detection-strategy/scroll.js\");\n\nfunction isCollection(obj) {\n return Array.isArray(obj) || obj.length !== undefined;\n}\n\nfunction toArray(collection) {\n if (!Array.isArray(collection)) {\n var array = [];\n forEach(collection, function (obj) {\n array.push(obj);\n });\n return array;\n } else {\n return collection;\n }\n}\n\nfunction isElement(obj) {\n return obj && obj.nodeType === 1;\n}\n\n/**\n * @typedef idHandler\n * @type {object}\n * @property {function} get Gets the resize detector id of the element.\n * @property {function} set Generate and sets the resize detector id of the element.\n */\n\n/**\n * @typedef Options\n * @type {object}\n * @property {boolean} callOnAdd Determines if listeners should be called when they are getting added.\n Default is true. If true, the listener is guaranteed to be called when it has been added.\n If false, the listener will not be guarenteed to be called when it has been added (does not prevent it from being called).\n * @property {idHandler} idHandler A custom id handler that is responsible for generating, setting and retrieving id's for elements.\n If not provided, a default id handler will be used.\n * @property {reporter} reporter A custom reporter that handles reporting logs, warnings and errors.\n If not provided, a default id handler will be used.\n If set to false, then nothing will be reported.\n * @property {boolean} debug If set to true, the the system will report debug messages as default for the listenTo method.\n */\n\n/**\n * Creates an element resize detector instance.\n * @public\n * @param {Options?} options Optional global options object that will decide how this instance will work.\n */\nmodule.exports = function(options) {\n options = options || {};\n\n //idHandler is currently not an option to the listenTo function, so it should not be added to globalOptions.\n var idHandler;\n\n if (options.idHandler) {\n // To maintain compatability with idHandler.get(element, readonly), make sure to wrap the given idHandler\n // so that readonly flag always is true when it's used here. This may be removed next major version bump.\n idHandler = {\n get: function (element) { return options.idHandler.get(element, true); },\n set: options.idHandler.set\n };\n } else {\n var idGenerator = idGeneratorMaker();\n var defaultIdHandler = idHandlerMaker({\n idGenerator: idGenerator,\n stateHandler: stateHandler\n });\n idHandler = defaultIdHandler;\n }\n\n //reporter is currently not an option to the listenTo function, so it should not be added to globalOptions.\n var reporter = options.reporter;\n\n if(!reporter) {\n //If options.reporter is false, then the reporter should be quiet.\n var quiet = reporter === false;\n reporter = reporterMaker(quiet);\n }\n\n //batchProcessor is currently not an option to the listenTo function, so it should not be added to globalOptions.\n var batchProcessor = getOption(options, \"batchProcessor\", batchProcessorMaker({ reporter: reporter }));\n\n //Options to be used as default for the listenTo function.\n var globalOptions = {};\n globalOptions.callOnAdd = !!getOption(options, \"callOnAdd\", true);\n globalOptions.debug = !!getOption(options, \"debug\", false);\n\n var eventListenerHandler = listenerHandlerMaker(idHandler);\n var elementUtils = elementUtilsMaker({\n stateHandler: stateHandler\n });\n\n //The detection strategy to be used.\n var detectionStrategy;\n var desiredStrategy = getOption(options, \"strategy\", \"object\");\n var strategyOptions = {\n reporter: reporter,\n batchProcessor: batchProcessor,\n stateHandler: stateHandler,\n idHandler: idHandler\n };\n\n if(desiredStrategy === \"scroll\") {\n if (browserDetector.isLegacyOpera()) {\n reporter.warn(\"Scroll strategy is not supported on legacy Opera. Changing to object strategy.\");\n desiredStrategy = \"object\";\n } else if (browserDetector.isIE(9)) {\n reporter.warn(\"Scroll strategy is not supported on IE9. Changing to object strategy.\");\n desiredStrategy = \"object\";\n }\n }\n\n if(desiredStrategy === \"scroll\") {\n detectionStrategy = scrollStrategyMaker(strategyOptions);\n } else if(desiredStrategy === \"object\") {\n detectionStrategy = objectStrategyMaker(strategyOptions);\n } else {\n throw new Error(\"Invalid strategy name: \" + desiredStrategy);\n }\n\n //Calls can be made to listenTo with elements that are still being installed.\n //Also, same elements can occur in the elements list in the listenTo function.\n //With this map, the ready callbacks can be synchronized between the calls\n //so that the ready callback can always be called when an element is ready - even if\n //it wasn't installed from the function itself.\n var onReadyCallbacks = {};\n\n /**\n * Makes the given elements resize-detectable and starts listening to resize events on the elements. Calls the event callback for each event for each element.\n * @public\n * @param {Options?} options Optional options object. These options will override the global options. Some options may not be overriden, such as idHandler.\n * @param {element[]|element} elements The given array of elements to detect resize events of. Single element is also valid.\n * @param {function} listener The callback to be executed for each resize event for each element.\n */\n function listenTo(options, elements, listener) {\n function onResizeCallback(element) {\n var listeners = eventListenerHandler.get(element);\n forEach(listeners, function callListenerProxy(listener) {\n listener(element);\n });\n }\n\n function addListener(callOnAdd, element, listener) {\n eventListenerHandler.add(element, listener);\n\n if(callOnAdd) {\n listener(element);\n }\n }\n\n //Options object may be omitted.\n if(!listener) {\n listener = elements;\n elements = options;\n options = {};\n }\n\n if(!elements) {\n throw new Error(\"At least one element required.\");\n }\n\n if(!listener) {\n throw new Error(\"Listener required.\");\n }\n\n if (isElement(elements)) {\n // A single element has been passed in.\n elements = [elements];\n } else if (isCollection(elements)) {\n // Convert collection to array for plugins.\n // TODO: May want to check so that all the elements in the collection are valid elements.\n elements = toArray(elements);\n } else {\n return reporter.error(\"Invalid arguments. Must be a DOM element or a collection of DOM elements.\");\n }\n\n var elementsReady = 0;\n\n var callOnAdd = getOption(options, \"callOnAdd\", globalOptions.callOnAdd);\n var onReadyCallback = getOption(options, \"onReady\", function noop() {});\n var debug = getOption(options, \"debug\", globalOptions.debug);\n\n forEach(elements, function attachListenerToElement(element) {\n if (!stateHandler.getState(element)) {\n stateHandler.initState(element);\n idHandler.set(element);\n }\n\n var id = idHandler.get(element);\n\n debug && reporter.log(\"Attaching listener to element\", id, element);\n\n if(!elementUtils.isDetectable(element)) {\n debug && reporter.log(id, \"Not detectable.\");\n if(elementUtils.isBusy(element)) {\n debug && reporter.log(id, \"System busy making it detectable\");\n\n //The element is being prepared to be detectable. Do not make it detectable.\n //Just add the listener, because the element will soon be detectable.\n addListener(callOnAdd, element, listener);\n onReadyCallbacks[id] = onReadyCallbacks[id] || [];\n onReadyCallbacks[id].push(function onReady() {\n elementsReady++;\n\n if(elementsReady === elements.length) {\n onReadyCallback();\n }\n });\n return;\n }\n\n debug && reporter.log(id, \"Making detectable...\");\n //The element is not prepared to be detectable, so do prepare it and add a listener to it.\n elementUtils.markBusy(element, true);\n return detectionStrategy.makeDetectable({ debug: debug }, element, function onElementDetectable(element) {\n debug && reporter.log(id, \"onElementDetectable\");\n\n if (stateHandler.getState(element)) {\n elementUtils.markAsDetectable(element);\n elementUtils.markBusy(element, false);\n detectionStrategy.addListener(element, onResizeCallback);\n addListener(callOnAdd, element, listener);\n\n // Since the element size might have changed since the call to \"listenTo\", we need to check for this change,\n // so that a resize event may be emitted.\n // Having the startSize object is optional (since it does not make sense in some cases such as unrendered elements), so check for its existance before.\n // Also, check the state existance before since the element may have been uninstalled in the installation process.\n var state = stateHandler.getState(element);\n if (state && state.startSize) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n if (state.startSize.width !== width || state.startSize.height !== height) {\n onResizeCallback(element);\n }\n }\n\n if(onReadyCallbacks[id]) {\n forEach(onReadyCallbacks[id], function(callback) {\n callback();\n });\n }\n } else {\n // The element has been unisntalled before being detectable.\n debug && reporter.log(id, \"Element uninstalled before being detectable.\");\n }\n\n delete onReadyCallbacks[id];\n\n elementsReady++;\n if(elementsReady === elements.length) {\n onReadyCallback();\n }\n });\n }\n\n debug && reporter.log(id, \"Already detecable, adding listener.\");\n\n //The element has been prepared to be detectable and is ready to be listened to.\n addListener(callOnAdd, element, listener);\n elementsReady++;\n });\n\n if(elementsReady === elements.length) {\n onReadyCallback();\n }\n }\n\n function uninstall(elements) {\n if(!elements) {\n return reporter.error(\"At least one element is required.\");\n }\n\n if (isElement(elements)) {\n // A single element has been passed in.\n elements = [elements];\n } else if (isCollection(elements)) {\n // Convert collection to array for plugins.\n // TODO: May want to check so that all the elements in the collection are valid elements.\n elements = toArray(elements);\n } else {\n return reporter.error(\"Invalid arguments. Must be a DOM element or a collection of DOM elements.\");\n }\n\n forEach(elements, function (element) {\n eventListenerHandler.removeAllListeners(element);\n detectionStrategy.uninstall(element);\n stateHandler.cleanState(element);\n });\n }\n\n return {\n listenTo: listenTo,\n removeListener: eventListenerHandler.removeListener,\n removeAllListeners: eventListenerHandler.removeAllListeners,\n uninstall: uninstall\n };\n};\n\nfunction getOption(options, name, defaultValue) {\n var value = options[name];\n\n if((value === undefined || value === null) && defaultValue !== undefined) {\n return defaultValue;\n }\n\n return value;\n}\n\n},{\"./browser-detector\":3,\"./collection-utils\":4,\"./detection-strategy/object.js\":5,\"./detection-strategy/scroll.js\":6,\"./element-utils\":8,\"./id-generator\":9,\"./id-handler\":10,\"./listener-handler\":11,\"./reporter\":12,\"./state-handler\":13,\"batch-processor\":1}],8:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function(options) {\n var getState = options.stateHandler.getState;\n\n /**\n * Tells if the element has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is detectable or not.\n */\n function isDetectable(element) {\n var state = getState(element);\n return state && !!state.isDetectable;\n }\n\n /**\n * Marks the element that it has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to mark.\n */\n function markAsDetectable(element) {\n getState(element).isDetectable = true;\n }\n\n /**\n * Tells if the element is busy or not.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is busy or not.\n */\n function isBusy(element) {\n return !!getState(element).busy;\n }\n\n /**\n * Marks the object is busy and should not be made detectable.\n * @public\n * @param {element} element The element to mark.\n * @param {boolean} busy If the element is busy or not.\n */\n function markBusy(element, busy) {\n getState(element).busy = !!busy;\n }\n\n return {\n isDetectable: isDetectable,\n markAsDetectable: markAsDetectable,\n isBusy: isBusy,\n markBusy: markBusy\n };\n};\n\n},{}],9:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function() {\n var idCount = 1;\n\n /**\n * Generates a new unique id in the context.\n * @public\n * @returns {number} A unique id in the context.\n */\n function generate() {\n return idCount++;\n }\n\n return {\n generate: generate\n };\n};\n\n},{}],10:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function(options) {\n var idGenerator = options.idGenerator;\n var getState = options.stateHandler.getState;\n\n /**\n * Gets the resize detector id of the element.\n * @public\n * @param {element} element The target element to get the id of.\n * @returns {string|number|null} The id of the element. Null if it has no id.\n */\n function getId(element) {\n var state = getState(element);\n\n if (state && state.id !== undefined) {\n return state.id;\n }\n\n return null;\n }\n\n /**\n * Sets the resize detector id of the element. Requires the element to have a resize detector state initialized.\n * @public\n * @param {element} element The target element to set the id of.\n * @returns {string|number|null} The id of the element.\n */\n function setId(element) {\n var state = getState(element);\n\n if (!state) {\n throw new Error(\"setId required the element to have a resize detection state.\");\n }\n\n var id = idGenerator.generate();\n\n state.id = id;\n\n return id;\n }\n\n return {\n get: getId,\n set: setId\n };\n};\n\n},{}],11:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function(idHandler) {\n var eventListeners = {};\n\n /**\n * Gets all listeners for the given element.\n * @public\n * @param {element} element The element to get all listeners for.\n * @returns All listeners for the given element.\n */\n function getListeners(element) {\n var id = idHandler.get(element);\n\n if (id === undefined) {\n return [];\n }\n\n return eventListeners[id] || [];\n }\n\n /**\n * Stores the given listener for the given element. Will not actually add the listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The callback that the element has added.\n */\n function addListener(element, listener) {\n var id = idHandler.get(element);\n\n if(!eventListeners[id]) {\n eventListeners[id] = [];\n }\n\n eventListeners[id].push(listener);\n }\n\n function removeListener(element, listener) {\n var listeners = getListeners(element);\n for (var i = 0, len = listeners.length; i < len; ++i) {\n if (listeners[i] === listener) {\n listeners.splice(i, 1);\n break;\n }\n }\n }\n\n function removeAllListeners(element) {\n var listeners = getListeners(element);\n if (!listeners) { return; }\n listeners.length = 0;\n }\n\n return {\n get: getListeners,\n add: addListener,\n removeListener: removeListener,\n removeAllListeners: removeAllListeners\n };\n};\n\n},{}],12:[function(require,module,exports){\n\"use strict\";\n\n/* global console: false */\n\n/**\n * Reporter that handles the reporting of logs, warnings and errors.\n * @public\n * @param {boolean} quiet Tells if the reporter should be quiet or not.\n */\nmodule.exports = function(quiet) {\n function noop() {\n //Does nothing.\n }\n\n var reporter = {\n log: noop,\n warn: noop,\n error: noop\n };\n\n if(!quiet && window.console) {\n var attachFunction = function(reporter, name) {\n //The proxy is needed to be able to call the method with the console context,\n //since we cannot use bind.\n reporter[name] = function reporterProxy() {\n var f = console[name];\n if (f.apply) { //IE9 does not support console.log.apply :)\n f.apply(console, arguments);\n } else {\n for (var i = 0; i < arguments.length; i++) {\n f(arguments[i]);\n }\n }\n };\n };\n\n attachFunction(reporter, \"log\");\n attachFunction(reporter, \"warn\");\n attachFunction(reporter, \"error\");\n }\n\n return reporter;\n};\n},{}],13:[function(require,module,exports){\n\"use strict\";\n\nvar prop = \"_erd\";\n\nfunction initState(element) {\n element[prop] = {};\n return getState(element);\n}\n\nfunction getState(element) {\n return element[prop];\n}\n\nfunction cleanState(element) {\n delete element[prop];\n}\n\nmodule.exports = {\n initState: initState,\n getState: getState,\n cleanState: cleanState\n};\n\n},{}]},{},[7])(7)\n});\n"]} \ No newline at end of file +{"version":3,"sources":["element-resize-detector.js"],"names":["f","exports","module","define","amd","window","global","self","this","elementResizeDetectorMaker","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","1","utils","Batch","batch","size","topLevel","bottomLevel","add","level","fn","push","process","fns","options","reporter","asyncProcess","getOption","autoProcess","warn","asyncFrameHandler","isProcessing","processBatch","processingBatch","processBatchAsync","callback","setTimeout","raf","requestFrame","force","localAsyncProcess","undefined","listener","clearTimeout","cancelFrame","./utils","2","name","defaultValue","value","3","detector","isIE","version","agent","navigator","userAgent","toLowerCase","indexOf","v","div","document","createElement","all","getElementsByTagName","innerHTML","undef","isLegacyOpera","opera","4","forEach","collection","result","5","browserDetector","batchProcessor","getState","stateHandler","getObject","element","object","makeDetectable","positionCheckPerformed","style","width","height","mutateDom","alterPositionStyles","position","removeRelativeStyles","property","replace","cssText","tabIndex","type","setAttribute","onload","getDocument","contentDocument","objectDocument","data","appendChild","debug","getComputedStyle","offsetWidth","offsetHeight","startSize","addListener","listenerProxy","proxy","attachEvent","defaultView","addEventListener","uninstall","detachEvent","removeChild","../browser-detector","6","idHandler","hasState","scrollbarSizes","child","container","body","insertBefore","firstChild","widthSize","clientWidth","heightSize","clientHeight","getScrollbarSizes","detectionContainerClass","addEvent","el","cb","error","removeEvent","removeEventListener","getExpandElement","childNodes","getShrinkElement","styleId","containerClass","getElementById","containerAnimationClass","containerAnimationActiveClass","method","head","styleElement","id","injectStyle","injectScrollStyle","args","Array","prototype","slice","arguments","unshift","get","log","apply","isUnrendered","getStyle","elementStyle","top","right","bottom","left","widthCSS","heightCSS","storeStyle","storeCurrentSize","lastWidth","lastHeight","getWidthOffset","getHeightOffset","getExpandWidth","getExpandHeight","positionScrollbars","expand","shrink","expandWidth","expandHeight","shrinkWidth","getShrinkWidth","shrinkHeight","getShrinkHeight","scrollLeft","scrollTop","injectContainerElement","className","addAnimationClass","onAnimationStart","onRendered","injectScrollElements","rootContainer","scrollbarWidth","scrollbarHeight","containerStyle","containerContainer","expandChild","shrinkChild","dir","onExpandScroll","onShrinkScroll","onExpand","onShrink","registerListenersAndPositionElements","updateChildSizes","getExpandChildElement","updateDetectorElements","done","areElementsInjected","w","h","notifyListenersIfNeeded","state","lastNotifiedWidth","lastNotifiedHeight","listeners","handleScroll","finalizeDomMutation","ready","install","storeStartSize","ownerDocument","contains","../collection-utils","7","elementUtilsMaker","listenerHandlerMaker","idGeneratorMaker","idHandlerMaker","reporterMaker","batchProcessorMaker","objectStrategyMaker","scrollStrategyMaker","isCollection","obj","isArray","toArray","array","isElement","nodeType","set","idGenerator","defaultIdHandler","globalOptions","callOnAdd","detectionStrategy","eventListenerHandler","elementUtils","desiredStrategy","strategyOptions","onReadyCallbacks","listenTo","elements","onResizeCallback","elementsReady","onReadyCallback","initState","isDetectable","isBusy","markBusy","markAsDetectable","removeListener","removeAllListeners","cleanState","./browser-detector","./collection-utils","./detection-strategy/object.js","./detection-strategy/scroll.js","./element-utils","./id-generator","./id-handler","./listener-handler","./reporter","./state-handler","batch-processor","8","busy","9","idCount","generate","10","11","eventListeners","getListeners","len","splice","12","quiet","noop","console","attachFunction","13","prop"],"mappings":"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","file":"element-resize-detector.js","sourcesContent":["/*!\n * element-resize-detector 1.1.15\n * Copyright (c) 2016 Lucas Wiener\n * https://github.com/wnr/element-resize-detector\n * Licensed under MIT\n */\n\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.elementResizeDetectorMaker = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i topLevel) {\n topLevel = level;\n } else if(level < bottomLevel) {\n bottomLevel = level;\n }\n\n if(!batch[level]) {\n batch[level] = [];\n }\n\n batch[level].push(fn);\n size++;\n }\n\n function process() {\n for(var level = bottomLevel; level <= topLevel; level++) {\n var fns = batch[level];\n\n for(var i = 0; i < fns.length; i++) {\n var fn = fns[i];\n fn();\n }\n }\n }\n\n function getSize() {\n return size;\n }\n\n return {\n add: add,\n process: process,\n size: getSize\n };\n}\n\n},{\"./utils\":2}],2:[function(require,module,exports){\n\"use strict\";\n\nvar utils = module.exports = {};\n\nutils.getOption = getOption;\n\nfunction getOption(options, name, defaultValue) {\n var value = options[name];\n\n if((value === undefined || value === null) && defaultValue !== undefined) {\n return defaultValue;\n }\n\n return value;\n}\n\n},{}],3:[function(require,module,exports){\n\"use strict\";\n\nvar detector = module.exports = {};\n\ndetector.isIE = function(version) {\n function isAnyIeVersion() {\n var agent = navigator.userAgent.toLowerCase();\n return agent.indexOf(\"msie\") !== -1 || agent.indexOf(\"trident\") !== -1 || agent.indexOf(\" edge/\") !== -1;\n }\n\n if(!isAnyIeVersion()) {\n return false;\n }\n\n if(!version) {\n return true;\n }\n\n //Shamelessly stolen from https://gist.github.com/padolsey/527683\n var ieVersion = (function(){\n var undef,\n v = 3,\n div = document.createElement(\"div\"),\n all = div.getElementsByTagName(\"i\");\n\n do {\n div.innerHTML = \"\";\n }\n while (all[0]);\n\n return v > 4 ? v : undef;\n }());\n\n return version === ieVersion;\n};\n\ndetector.isLegacyOpera = function() {\n return !!window.opera;\n};\n\n},{}],4:[function(require,module,exports){\n\"use strict\";\n\nvar utils = module.exports = {};\n\n/**\n * Loops through the collection and calls the callback for each element. if the callback returns truthy, the loop is broken and returns the same value.\n * @public\n * @param {*} collection The collection to loop through. Needs to have a length property set and have indices set from 0 to length - 1.\n * @param {function} callback The callback to be called for each element. The element will be given as a parameter to the callback. If this callback returns truthy, the loop is broken and the same value is returned.\n * @returns {*} The value that a callback has returned (if truthy). Otherwise nothing.\n */\nutils.forEach = function(collection, callback) {\n for(var i = 0; i < collection.length; i++) {\n var result = callback(collection[i]);\n if(result) {\n return result;\n }\n }\n};\n\n},{}],5:[function(require,module,exports){\n/**\n * Resize detection strategy that injects objects to elements in order to detect resize events.\n * Heavily inspired by: http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/\n */\n\n\"use strict\";\n\nvar browserDetector = require(\"../browser-detector\");\n\nmodule.exports = function(options) {\n options = options || {};\n var reporter = options.reporter;\n var batchProcessor = options.batchProcessor;\n var getState = options.stateHandler.getState;\n\n if(!reporter) {\n throw new Error(\"Missing required dependency: reporter.\");\n }\n\n /**\n * Adds a resize event listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The listener callback to be called for each resize event of the element. The element will be given as a parameter to the listener callback.\n */\n function addListener(element, listener) {\n if(!getObject(element)) {\n throw new Error(\"Element is not detectable by this strategy.\");\n }\n\n function listenerProxy() {\n listener(element);\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support object, but supports the resize event directly on elements.\n getState(element).object = {\n proxy: listenerProxy\n };\n element.attachEvent(\"onresize\", listenerProxy);\n } else {\n var object = getObject(element);\n object.contentDocument.defaultView.addEventListener(\"resize\", listenerProxy);\n }\n }\n\n /**\n * Makes an element detectable and ready to be listened for resize events. Will call the callback when the element is ready to be listened for resize changes.\n * @private\n * @param {object} options Optional options object.\n * @param {element} element The element to make detectable\n * @param {function} callback The callback to be called when the element is ready to be listened for resize changes. Will be called with the element as first parameter.\n */\n function makeDetectable(options, element, callback) {\n if (!callback) {\n callback = element;\n element = options;\n options = null;\n }\n\n options = options || {};\n var debug = options.debug;\n\n function injectObject(element, callback) {\n var OBJECT_STYLE = \"display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;\";\n\n //The target element needs to be positioned (everything except static) so the absolute positioned object will be positioned relative to the target element.\n\n // Position altering may be performed directly or on object load, depending on if style resolution is possible directly or not.\n var positionCheckPerformed = false;\n\n // The element may not yet be attached to the DOM, and therefore the style object may be empty in some browsers.\n // Since the style object is a reference, it will be updated as soon as the element is attached to the DOM.\n var style = window.getComputedStyle(element);\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n getState(element).startSize = {\n width: width,\n height: height\n };\n\n function mutateDom() {\n function alterPositionStyles() {\n if(style.position === \"static\") {\n element.style.position = \"relative\";\n\n var removeRelativeStyles = function(reporter, element, style, property) {\n function getNumericalValue(value) {\n return value.replace(/[^-\\d\\.]/g, \"\");\n }\n\n var value = style[property];\n\n if(value !== \"auto\" && getNumericalValue(value) !== \"0\") {\n reporter.warn(\"An element that is positioned static has style.\" + property + \"=\" + value + \" which is ignored due to the static positioning. The element will need to be positioned relative, so the style.\" + property + \" will be set to 0. Element: \", element);\n element.style[property] = 0;\n }\n };\n\n //Check so that there are no accidental styles that will make the element styled differently now that is is relative.\n //If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway).\n removeRelativeStyles(reporter, element, style, \"top\");\n removeRelativeStyles(reporter, element, style, \"right\");\n removeRelativeStyles(reporter, element, style, \"bottom\");\n removeRelativeStyles(reporter, element, style, \"left\");\n }\n }\n\n function onObjectLoad() {\n // The object has been loaded, which means that the element now is guaranteed to be attached to the DOM.\n if (!positionCheckPerformed) {\n alterPositionStyles();\n }\n\n /*jshint validthis: true */\n\n function getDocument(element, callback) {\n //Opera 12 seem to call the object.onload before the actual document has been created.\n //So if it is not present, poll it with an timeout until it is present.\n //TODO: Could maybe be handled better with object.onreadystatechange or similar.\n if(!element.contentDocument) {\n setTimeout(function checkForObjectDocument() {\n getDocument(element, callback);\n }, 100);\n\n return;\n }\n\n callback(element.contentDocument);\n }\n\n //Mutating the object element here seems to fire another load event.\n //Mutating the inner document of the object element is fine though.\n var objectElement = this;\n\n //Create the style element to be added to the object.\n getDocument(objectElement, function onObjectDocumentReady(objectDocument) {\n //Notify that the element is ready to be listened to.\n callback(element);\n });\n }\n\n // The element may be detached from the DOM, and some browsers does not support style resolving of detached elements.\n // The alterPositionStyles needs to be delayed until we know the element has been attached to the DOM (which we are sure of when the onObjectLoad has been fired), if style resolution is not possible.\n if (style.position !== \"\") {\n alterPositionStyles(style);\n positionCheckPerformed = true;\n }\n\n //Add an object element as a child to the target element that will be listened to for resize events.\n var object = document.createElement(\"object\");\n object.style.cssText = OBJECT_STYLE;\n object.tabIndex = -1;\n object.type = \"text/html\";\n object.setAttribute(\"aria-hidden\", \"true\");\n object.onload = onObjectLoad;\n\n //Safari: This must occur before adding the object to the DOM.\n //IE: Does not like that this happens before, even if it is also added after.\n if(!browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n\n element.appendChild(object);\n getState(element).object = object;\n\n //IE: This must occur after adding the object to the DOM.\n if(browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n }\n\n if(batchProcessor) {\n batchProcessor.add(mutateDom);\n } else {\n mutateDom();\n }\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support objects properly. Luckily they do support the resize event.\n //So do not inject the object and notify that the element is already ready to be listened to.\n //The event handler for the resize event is attached in the utils.addListener instead.\n callback(element);\n } else {\n injectObject(element, callback);\n }\n }\n\n /**\n * Returns the child object of the target element.\n * @private\n * @param {element} element The target element.\n * @returns The object element of the target.\n */\n function getObject(element) {\n return getState(element).object;\n }\n\n function uninstall(element) {\n if(browserDetector.isIE(8)) {\n element.detachEvent(\"onresize\", getState(element).object.proxy);\n } else {\n element.removeChild(getObject(element));\n }\n delete getState(element).object;\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall\n };\n};\n\n},{\"../browser-detector\":3}],6:[function(require,module,exports){\n/**\n * Resize detection strategy that injects divs to elements in order to detect resize events on scroll events.\n * Heavily inspired by: https://github.com/marcj/css-element-queries/blob/master/src/ResizeSensor.js\n */\n\n\"use strict\";\n\nvar forEach = require(\"../collection-utils\").forEach;\n\nmodule.exports = function(options) {\n options = options || {};\n var reporter = options.reporter;\n var batchProcessor = options.batchProcessor;\n var getState = options.stateHandler.getState;\n var hasState = options.stateHandler.hasState;\n var idHandler = options.idHandler;\n\n if (!batchProcessor) {\n throw new Error(\"Missing required dependency: batchProcessor\");\n }\n\n if (!reporter) {\n throw new Error(\"Missing required dependency: reporter.\");\n }\n\n //TODO: Could this perhaps be done at installation time?\n var scrollbarSizes = getScrollbarSizes();\n\n // Inject the scrollbar styling that prevents them from appearing sometimes in Chrome.\n // The injected container needs to have a class, so that it may be styled with CSS (pseudo elements).\n var styleId = \"erd_scroll_detection_scrollbar_style\";\n var detectionContainerClass = \"erd_scroll_detection_container\";\n injectScrollStyle(styleId, detectionContainerClass);\n\n function getScrollbarSizes() {\n var width = 500;\n var height = 500;\n\n var child = document.createElement(\"div\");\n child.style.cssText = \"position: absolute; width: \" + width*2 + \"px; height: \" + height*2 + \"px; visibility: hidden; margin: 0; padding: 0;\";\n\n var container = document.createElement(\"div\");\n container.style.cssText = \"position: absolute; width: \" + width + \"px; height: \" + height + \"px; overflow: scroll; visibility: none; top: \" + -width*3 + \"px; left: \" + -height*3 + \"px; visibility: hidden; margin: 0; padding: 0;\";\n\n container.appendChild(child);\n\n document.body.insertBefore(container, document.body.firstChild);\n\n var widthSize = width - container.clientWidth;\n var heightSize = height - container.clientHeight;\n\n document.body.removeChild(container);\n\n return {\n width: widthSize,\n height: heightSize\n };\n }\n\n function injectScrollStyle(styleId, containerClass) {\n function injectStyle(style, method) {\n method = method || function (element) {\n document.head.appendChild(element);\n };\n\n var styleElement = document.createElement(\"style\");\n styleElement.innerHTML = style;\n styleElement.id = styleId;\n method(styleElement);\n return styleElement;\n }\n\n if (!document.getElementById(styleId)) {\n var containerAnimationClass = containerClass + \"_animation\";\n var containerAnimationActiveClass = containerClass + \"_animation_active\";\n var style = \"/* Created by the element-resize-detector library. */\\n\";\n style += \".\" + containerClass + \" > div::-webkit-scrollbar { display: none; }\\n\\n\";\n style += \".\" + containerAnimationActiveClass + \" { -webkit-animation-duration: 0.1s; animation-duration: 0.1s; -webkit-animation-name: \" + containerAnimationClass + \"; animation-name: \" + containerAnimationClass + \"; }\\n\";\n style += \"@-webkit-keyframes \" + containerAnimationClass + \" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\\n\";\n style += \"@keyframes \" + containerAnimationClass + \" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\";\n injectStyle(style);\n }\n }\n\n function addAnimationClass(element) {\n element.className += \" \" + detectionContainerClass + \"_animation_active\";\n }\n\n function addEvent(el, name, cb) {\n if (el.addEventListener) {\n el.addEventListener(name, cb);\n } else if(el.attachEvent) {\n el.attachEvent(\"on\" + name, cb);\n } else {\n return reporter.error(\"[scroll] Don't know how to add event listeners.\");\n }\n }\n\n function removeEvent(el, name, cb) {\n if (el.removeEventListener) {\n el.removeEventListener(name, cb);\n } else if(el.detachEvent) {\n el.detachEvent(\"on\" + name, cb);\n } else {\n return reporter.error(\"[scroll] Don't know how to remove event listeners.\");\n }\n }\n\n function getExpandElement(element) {\n return getState(element).container.childNodes[0].childNodes[0].childNodes[0];\n }\n\n function getShrinkElement(element) {\n return getState(element).container.childNodes[0].childNodes[0].childNodes[1];\n }\n\n /**\n * Adds a resize event listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The listener callback to be called for each resize event of the element. The element will be given as a parameter to the listener callback.\n */\n function addListener(element, listener) {\n var listeners = getState(element).listeners;\n\n if (!listeners.push) {\n throw new Error(\"Cannot add listener to an element that is not detectable.\");\n }\n\n getState(element).listeners.push(listener);\n }\n\n /**\n * Makes an element detectable and ready to be listened for resize events. Will call the callback when the element is ready to be listened for resize changes.\n * @private\n * @param {object} options Optional options object.\n * @param {element} element The element to make detectable\n * @param {function} callback The callback to be called when the element is ready to be listened for resize changes. Will be called with the element as first parameter.\n */\n function makeDetectable(options, element, callback) {\n if (!callback) {\n callback = element;\n element = options;\n options = null;\n }\n\n options = options || {};\n\n function debug() {\n if (options.debug) {\n var args = Array.prototype.slice.call(arguments);\n args.unshift(idHandler.get(element), \"Scroll: \");\n if (reporter.log.apply) {\n reporter.log.apply(null, args);\n } else {\n for (var i = 0; i < args.length; i++) {\n reporter.log(args[i]);\n }\n }\n }\n }\n\n function isDetached(element) {\n function isInDocument(element) {\n return element === element.ownerDocument.body || element.ownerDocument.body.contains(element);\n }\n\n if (!isInDocument(element)) {\n return true;\n }\n\n // FireFox returns null style in hidden iframes. See https://github.com/wnr/element-resize-detector/issues/68 and https://bugzilla.mozilla.org/show_bug.cgi?id=795520\n if (window.getComputedStyle(element) === null) {\n return true;\n }\n\n return false;\n }\n\n function isUnrendered(element) {\n // Check the absolute positioned container since the top level container is display: inline.\n var container = getState(element).container.childNodes[0];\n var style = window.getComputedStyle(container);\n return !style.width || style.width.indexOf(\"px\") === -1; //Can only compute pixel value when rendered.\n }\n\n function getStyle() {\n // Some browsers only force layouts when actually reading the style properties of the style object, so make sure that they are all read here,\n // so that the user of the function can be sure that it will perform the layout here, instead of later (important for batching).\n var elementStyle = window.getComputedStyle(element);\n var style = {};\n style.position = elementStyle.position;\n style.width = element.offsetWidth;\n style.height = element.offsetHeight;\n style.top = elementStyle.top;\n style.right = elementStyle.right;\n style.bottom = elementStyle.bottom;\n style.left = elementStyle.left;\n style.widthCSS = elementStyle.width;\n style.heightCSS = elementStyle.height;\n return style;\n }\n\n function storeStartSize() {\n var style = getStyle();\n getState(element).startSize = {\n width: style.width,\n height: style.height\n };\n debug(\"Element start size\", getState(element).startSize);\n }\n\n function initListeners() {\n getState(element).listeners = [];\n }\n\n function storeStyle() {\n debug(\"storeStyle invoked.\");\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n var style = getStyle();\n getState(element).style = style;\n }\n\n function storeCurrentSize(element, width, height) {\n getState(element).lastWidth = width;\n getState(element).lastHeight = height;\n }\n\n function getExpandChildElement(element) {\n return getExpandElement(element).childNodes[0];\n }\n\n function getWidthOffset() {\n return 2 * scrollbarSizes.width + 1;\n }\n\n function getHeightOffset() {\n return 2 * scrollbarSizes.height + 1;\n }\n\n function getExpandWidth(width) {\n return width + 10 + getWidthOffset();\n }\n\n function getExpandHeight(height) {\n return height + 10 + getHeightOffset();\n }\n\n function getShrinkWidth(width) {\n return width * 2 + getWidthOffset();\n }\n\n function getShrinkHeight(height) {\n return height * 2 + getHeightOffset();\n }\n\n function positionScrollbars(element, width, height) {\n var expand = getExpandElement(element);\n var shrink = getShrinkElement(element);\n var expandWidth = getExpandWidth(width);\n var expandHeight = getExpandHeight(height);\n var shrinkWidth = getShrinkWidth(width);\n var shrinkHeight = getShrinkHeight(height);\n expand.scrollLeft = expandWidth;\n expand.scrollTop = expandHeight;\n shrink.scrollLeft = shrinkWidth;\n shrink.scrollTop = shrinkHeight;\n }\n\n function injectContainerElement() {\n var container = getState(element).container;\n\n if (!container) {\n container = document.createElement(\"div\");\n container.className = detectionContainerClass;\n container.style.cssText = \"visibility: hidden; display: inline; width: 0px; height: 0px; z-index: -1; overflow: hidden; margin: 0; padding: 0;\";\n getState(element).container = container;\n addAnimationClass(container);\n element.appendChild(container);\n\n var onAnimationStart = function () {\n getState(element).onRendered && getState(element).onRendered();\n };\n\n addEvent(container, \"animationstart\", onAnimationStart);\n\n // Store the event handler here so that they may be removed when uninstall is called.\n // See uninstall function for an explanation why it is needed.\n getState(element).onAnimationStart = onAnimationStart;\n }\n\n return container;\n }\n\n function injectScrollElements() {\n function alterPositionStyles() {\n var style = getState(element).style;\n\n if(style.position === \"static\") {\n element.style.position = \"relative\";\n\n var removeRelativeStyles = function(reporter, element, style, property) {\n function getNumericalValue(value) {\n return value.replace(/[^-\\d\\.]/g, \"\");\n }\n\n var value = style[property];\n\n if(value !== \"auto\" && getNumericalValue(value) !== \"0\") {\n reporter.warn(\"An element that is positioned static has style.\" + property + \"=\" + value + \" which is ignored due to the static positioning. The element will need to be positioned relative, so the style.\" + property + \" will be set to 0. Element: \", element);\n element.style[property] = 0;\n }\n };\n\n //Check so that there are no accidental styles that will make the element styled differently now that is is relative.\n //If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway).\n removeRelativeStyles(reporter, element, style, \"top\");\n removeRelativeStyles(reporter, element, style, \"right\");\n removeRelativeStyles(reporter, element, style, \"bottom\");\n removeRelativeStyles(reporter, element, style, \"left\");\n }\n }\n\n function getLeftTopBottomRightCssText(left, top, bottom, right) {\n left = (!left ? \"0\" : (left + \"px\"));\n top = (!top ? \"0\" : (top + \"px\"));\n bottom = (!bottom ? \"0\" : (bottom + \"px\"));\n right = (!right ? \"0\" : (right + \"px\"));\n\n return \"left: \" + left + \"; top: \" + top + \"; right: \" + right + \"; bottom: \" + bottom + \";\";\n }\n\n debug(\"Injecting elements\");\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n alterPositionStyles();\n\n var rootContainer = getState(element).container;\n\n if (!rootContainer) {\n rootContainer = injectContainerElement();\n }\n\n // Due to this WebKit bug https://bugs.webkit.org/show_bug.cgi?id=80808 (currently fixed in Blink, but still present in WebKit browsers such as Safari),\n // we need to inject two containers, one that is width/height 100% and another that is left/top -1px so that the final container always is 1x1 pixels bigger than\n // the targeted element.\n // When the bug is resolved, \"containerContainer\" may be removed.\n\n // The outer container can occasionally be less wide than the targeted when inside inline elements element in WebKit (see https://bugs.webkit.org/show_bug.cgi?id=152980).\n // This should be no problem since the inner container either way makes sure the injected scroll elements are at least 1x1 px.\n\n var scrollbarWidth = scrollbarSizes.width;\n var scrollbarHeight = scrollbarSizes.height;\n var containerContainerStyle = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; width: 100%; height: 100%; left: 0px; top: 0px;\";\n var containerStyle = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; \" + getLeftTopBottomRightCssText(-(1 + scrollbarWidth), -(1 + scrollbarHeight), -scrollbarHeight, -scrollbarWidth);\n var expandStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var shrinkStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var expandChildStyle = \"position: absolute; left: 0; top: 0;\";\n var shrinkChildStyle = \"position: absolute; width: 200%; height: 200%;\";\n\n var containerContainer = document.createElement(\"div\");\n var container = document.createElement(\"div\");\n var expand = document.createElement(\"div\");\n var expandChild = document.createElement(\"div\");\n var shrink = document.createElement(\"div\");\n var shrinkChild = document.createElement(\"div\");\n\n // Some browsers choke on the resize system being rtl, so force it to ltr. https://github.com/wnr/element-resize-detector/issues/56\n // However, dir should not be set on the top level container as it alters the dimensions of the target element in some browsers.\n containerContainer.dir = \"ltr\";\n\n containerContainer.style.cssText = containerContainerStyle;\n containerContainer.className = detectionContainerClass;\n container.className = detectionContainerClass;\n container.style.cssText = containerStyle;\n expand.style.cssText = expandStyle;\n expandChild.style.cssText = expandChildStyle;\n shrink.style.cssText = shrinkStyle;\n shrinkChild.style.cssText = shrinkChildStyle;\n\n expand.appendChild(expandChild);\n shrink.appendChild(shrinkChild);\n container.appendChild(expand);\n container.appendChild(shrink);\n containerContainer.appendChild(container);\n rootContainer.appendChild(containerContainer);\n\n function onExpandScroll() {\n getState(element).onExpand && getState(element).onExpand();\n }\n\n function onShrinkScroll() {\n getState(element).onShrink && getState(element).onShrink();\n }\n\n addEvent(expand, \"scroll\", onExpandScroll);\n addEvent(shrink, \"scroll\", onShrinkScroll);\n\n // Store the event handlers here so that they may be removed when uninstall is called.\n // See uninstall function for an explanation why it is needed.\n getState(element).onExpandScroll = onExpandScroll;\n getState(element).onShrinkScroll = onShrinkScroll;\n }\n\n function registerListenersAndPositionElements() {\n function updateChildSizes(element, width, height) {\n var expandChild = getExpandChildElement(element);\n var expandWidth = getExpandWidth(width);\n var expandHeight = getExpandHeight(height);\n expandChild.style.width = expandWidth + \"px\";\n expandChild.style.height = expandHeight + \"px\";\n }\n\n function updateDetectorElements(done) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n debug(\"Storing current size\", width, height);\n\n // Store the size of the element sync here, so that multiple scroll events may be ignored in the event listeners.\n // Otherwise the if-check in handleScroll is useless.\n storeCurrentSize(element, width, height);\n\n // Since we delay the processing of the batch, there is a risk that uninstall has been called before the batch gets to execute.\n // Since there is no way to cancel the fn executions, we need to add an uninstall guard to all fns of the batch.\n\n batchProcessor.add(0, function performUpdateChildSizes() {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n if (!areElementsInjected()) {\n debug(\"Aborting because element container has not been initialized\");\n return;\n }\n\n if (options.debug) {\n var w = element.offsetWidth;\n var h = element.offsetHeight;\n\n if (w !== width || h !== height) {\n reporter.warn(idHandler.get(element), \"Scroll: Size changed before updating detector elements.\");\n }\n }\n\n updateChildSizes(element, width, height);\n });\n\n batchProcessor.add(1, function updateScrollbars() {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n if (!areElementsInjected()) {\n debug(\"Aborting because element container has not been initialized\");\n return;\n }\n\n positionScrollbars(element, width, height);\n });\n\n if (done) {\n batchProcessor.add(2, function () {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n if (!areElementsInjected()) {\n debug(\"Aborting because element container has not been initialized\");\n return;\n }\n\n done();\n });\n }\n }\n\n function areElementsInjected() {\n return !!getState(element).container;\n }\n\n function notifyListenersIfNeeded() {\n function isFirstNotify() {\n return getState(element).lastNotifiedWidth === undefined;\n }\n\n debug(\"notifyListenersIfNeeded invoked\");\n\n var state = getState(element);\n\n // Don't notify the if the current size is the start size, and this is the first notification.\n if (isFirstNotify() && state.lastWidth === state.startSize.width && state.lastHeight === state.startSize.height) {\n return debug(\"Not notifying: Size is the same as the start size, and there has been no notification yet.\");\n }\n\n // Don't notify if the size already has been notified.\n if (state.lastWidth === state.lastNotifiedWidth && state.lastHeight === state.lastNotifiedHeight) {\n return debug(\"Not notifying: Size already notified\");\n }\n\n\n debug(\"Current size not notified, notifying...\");\n state.lastNotifiedWidth = state.lastWidth;\n state.lastNotifiedHeight = state.lastHeight;\n forEach(getState(element).listeners, function (listener) {\n listener(element);\n });\n }\n\n function handleRender() {\n debug(\"startanimation triggered.\");\n\n if (isUnrendered(element)) {\n debug(\"Ignoring since element is still unrendered...\");\n return;\n }\n\n debug(\"Element rendered.\");\n var expand = getExpandElement(element);\n var shrink = getShrinkElement(element);\n if (expand.scrollLeft === 0 || expand.scrollTop === 0 || shrink.scrollLeft === 0 || shrink.scrollTop === 0) {\n debug(\"Scrollbars out of sync. Updating detector elements...\");\n updateDetectorElements(notifyListenersIfNeeded);\n }\n }\n\n function handleScroll() {\n debug(\"Scroll detected.\");\n\n if (isUnrendered(element)) {\n // Element is still unrendered. Skip this scroll event.\n debug(\"Scroll event fired while unrendered. Ignoring...\");\n return;\n }\n\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (width !== getState(element).lastWidth || height !== getState(element).lastHeight) {\n debug(\"Element size changed.\");\n updateDetectorElements(notifyListenersIfNeeded);\n } else {\n debug(\"Element size has not changed (\" + width + \"x\" + height + \").\");\n }\n }\n\n debug(\"registerListenersAndPositionElements invoked.\");\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n getState(element).onRendered = handleRender;\n getState(element).onExpand = handleScroll;\n getState(element).onShrink = handleScroll;\n\n var style = getState(element).style;\n updateChildSizes(element, style.width, style.height);\n }\n\n function finalizeDomMutation() {\n debug(\"finalizeDomMutation invoked.\");\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n var style = getState(element).style;\n storeCurrentSize(element, style.width, style.height);\n positionScrollbars(element, style.width, style.height);\n }\n\n function ready() {\n callback(element);\n }\n\n function install() {\n debug(\"Installing...\");\n initListeners();\n storeStartSize();\n\n batchProcessor.add(0, storeStyle);\n batchProcessor.add(1, injectScrollElements);\n batchProcessor.add(2, registerListenersAndPositionElements);\n batchProcessor.add(3, finalizeDomMutation);\n batchProcessor.add(4, ready);\n }\n\n debug(\"Making detectable...\");\n\n if (isDetached(element)) {\n debug(\"Element is detached\");\n\n injectContainerElement();\n\n debug(\"Waiting until element is attached...\");\n\n getState(element).onRendered = function () {\n debug(\"Element is now attached\");\n install();\n };\n } else {\n install();\n }\n }\n\n function uninstall(element) {\n var state = getState(element);\n\n if (!state) {\n // Uninstall has been called on a non-erd element.\n return;\n }\n\n // Uninstall may have been called in the following scenarios:\n // (1) Right between the sync code and async batch (here state.busy = true, but nothing have been registered or injected).\n // (2) In the ready callback of the last level of the batch by another element (here, state.busy = true, but all the stuff has been injected).\n // (3) After the installation process (here, state.busy = false and all the stuff has been injected).\n // So to be on the safe side, let's check for each thing before removing.\n\n // We need to remove the event listeners, because otherwise the event might fire on an uninstall element which results in an error when trying to get the state of the element.\n state.onExpandScroll && removeEvent(getExpandElement(element), \"scroll\", state.onExpandScroll);\n state.onShrinkScroll && removeEvent(getShrinkElement(element), \"scroll\", state.onShrinkScroll);\n state.onAnimationStart && removeEvent(state.container, \"animationstart\", state.onAnimationStart);\n\n state.container && element.removeChild(state.container);\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall\n };\n};\n\n},{\"../collection-utils\":4}],7:[function(require,module,exports){\n\"use strict\";\n\nvar forEach = require(\"./collection-utils\").forEach;\nvar elementUtilsMaker = require(\"./element-utils\");\nvar listenerHandlerMaker = require(\"./listener-handler\");\nvar idGeneratorMaker = require(\"./id-generator\");\nvar idHandlerMaker = require(\"./id-handler\");\nvar reporterMaker = require(\"./reporter\");\nvar browserDetector = require(\"./browser-detector\");\nvar batchProcessorMaker = require(\"batch-processor\");\nvar stateHandler = require(\"./state-handler\");\n\n//Detection strategies.\nvar objectStrategyMaker = require(\"./detection-strategy/object.js\");\nvar scrollStrategyMaker = require(\"./detection-strategy/scroll.js\");\n\nfunction isCollection(obj) {\n return Array.isArray(obj) || obj.length !== undefined;\n}\n\nfunction toArray(collection) {\n if (!Array.isArray(collection)) {\n var array = [];\n forEach(collection, function (obj) {\n array.push(obj);\n });\n return array;\n } else {\n return collection;\n }\n}\n\nfunction isElement(obj) {\n return obj && obj.nodeType === 1;\n}\n\n/**\n * @typedef idHandler\n * @type {object}\n * @property {function} get Gets the resize detector id of the element.\n * @property {function} set Generate and sets the resize detector id of the element.\n */\n\n/**\n * @typedef Options\n * @type {object}\n * @property {boolean} callOnAdd Determines if listeners should be called when they are getting added.\n Default is true. If true, the listener is guaranteed to be called when it has been added.\n If false, the listener will not be guarenteed to be called when it has been added (does not prevent it from being called).\n * @property {idHandler} idHandler A custom id handler that is responsible for generating, setting and retrieving id's for elements.\n If not provided, a default id handler will be used.\n * @property {reporter} reporter A custom reporter that handles reporting logs, warnings and errors.\n If not provided, a default id handler will be used.\n If set to false, then nothing will be reported.\n * @property {boolean} debug If set to true, the the system will report debug messages as default for the listenTo method.\n */\n\n/**\n * Creates an element resize detector instance.\n * @public\n * @param {Options?} options Optional global options object that will decide how this instance will work.\n */\nmodule.exports = function(options) {\n options = options || {};\n\n //idHandler is currently not an option to the listenTo function, so it should not be added to globalOptions.\n var idHandler;\n\n if (options.idHandler) {\n // To maintain compatability with idHandler.get(element, readonly), make sure to wrap the given idHandler\n // so that readonly flag always is true when it's used here. This may be removed next major version bump.\n idHandler = {\n get: function (element) { return options.idHandler.get(element, true); },\n set: options.idHandler.set\n };\n } else {\n var idGenerator = idGeneratorMaker();\n var defaultIdHandler = idHandlerMaker({\n idGenerator: idGenerator,\n stateHandler: stateHandler\n });\n idHandler = defaultIdHandler;\n }\n\n //reporter is currently not an option to the listenTo function, so it should not be added to globalOptions.\n var reporter = options.reporter;\n\n if(!reporter) {\n //If options.reporter is false, then the reporter should be quiet.\n var quiet = reporter === false;\n reporter = reporterMaker(quiet);\n }\n\n //batchProcessor is currently not an option to the listenTo function, so it should not be added to globalOptions.\n var batchProcessor = getOption(options, \"batchProcessor\", batchProcessorMaker({ reporter: reporter }));\n\n //Options to be used as default for the listenTo function.\n var globalOptions = {};\n globalOptions.callOnAdd = !!getOption(options, \"callOnAdd\", true);\n globalOptions.debug = !!getOption(options, \"debug\", false);\n\n var eventListenerHandler = listenerHandlerMaker(idHandler);\n var elementUtils = elementUtilsMaker({\n stateHandler: stateHandler\n });\n\n //The detection strategy to be used.\n var detectionStrategy;\n var desiredStrategy = getOption(options, \"strategy\", \"object\");\n var strategyOptions = {\n reporter: reporter,\n batchProcessor: batchProcessor,\n stateHandler: stateHandler,\n idHandler: idHandler\n };\n\n if(desiredStrategy === \"scroll\") {\n if (browserDetector.isLegacyOpera()) {\n reporter.warn(\"Scroll strategy is not supported on legacy Opera. Changing to object strategy.\");\n desiredStrategy = \"object\";\n } else if (browserDetector.isIE(9)) {\n reporter.warn(\"Scroll strategy is not supported on IE9. Changing to object strategy.\");\n desiredStrategy = \"object\";\n }\n }\n\n if(desiredStrategy === \"scroll\") {\n detectionStrategy = scrollStrategyMaker(strategyOptions);\n } else if(desiredStrategy === \"object\") {\n detectionStrategy = objectStrategyMaker(strategyOptions);\n } else {\n throw new Error(\"Invalid strategy name: \" + desiredStrategy);\n }\n\n //Calls can be made to listenTo with elements that are still being installed.\n //Also, same elements can occur in the elements list in the listenTo function.\n //With this map, the ready callbacks can be synchronized between the calls\n //so that the ready callback can always be called when an element is ready - even if\n //it wasn't installed from the function itself.\n var onReadyCallbacks = {};\n\n /**\n * Makes the given elements resize-detectable and starts listening to resize events on the elements. Calls the event callback for each event for each element.\n * @public\n * @param {Options?} options Optional options object. These options will override the global options. Some options may not be overriden, such as idHandler.\n * @param {element[]|element} elements The given array of elements to detect resize events of. Single element is also valid.\n * @param {function} listener The callback to be executed for each resize event for each element.\n */\n function listenTo(options, elements, listener) {\n function onResizeCallback(element) {\n var listeners = eventListenerHandler.get(element);\n forEach(listeners, function callListenerProxy(listener) {\n listener(element);\n });\n }\n\n function addListener(callOnAdd, element, listener) {\n eventListenerHandler.add(element, listener);\n\n if(callOnAdd) {\n listener(element);\n }\n }\n\n //Options object may be omitted.\n if(!listener) {\n listener = elements;\n elements = options;\n options = {};\n }\n\n if(!elements) {\n throw new Error(\"At least one element required.\");\n }\n\n if(!listener) {\n throw new Error(\"Listener required.\");\n }\n\n if (isElement(elements)) {\n // A single element has been passed in.\n elements = [elements];\n } else if (isCollection(elements)) {\n // Convert collection to array for plugins.\n // TODO: May want to check so that all the elements in the collection are valid elements.\n elements = toArray(elements);\n } else {\n return reporter.error(\"Invalid arguments. Must be a DOM element or a collection of DOM elements.\");\n }\n\n var elementsReady = 0;\n\n var callOnAdd = getOption(options, \"callOnAdd\", globalOptions.callOnAdd);\n var onReadyCallback = getOption(options, \"onReady\", function noop() {});\n var debug = getOption(options, \"debug\", globalOptions.debug);\n\n forEach(elements, function attachListenerToElement(element) {\n if (!stateHandler.getState(element)) {\n stateHandler.initState(element);\n idHandler.set(element);\n }\n\n var id = idHandler.get(element);\n\n debug && reporter.log(\"Attaching listener to element\", id, element);\n\n if(!elementUtils.isDetectable(element)) {\n debug && reporter.log(id, \"Not detectable.\");\n if(elementUtils.isBusy(element)) {\n debug && reporter.log(id, \"System busy making it detectable\");\n\n //The element is being prepared to be detectable. Do not make it detectable.\n //Just add the listener, because the element will soon be detectable.\n addListener(callOnAdd, element, listener);\n onReadyCallbacks[id] = onReadyCallbacks[id] || [];\n onReadyCallbacks[id].push(function onReady() {\n elementsReady++;\n\n if(elementsReady === elements.length) {\n onReadyCallback();\n }\n });\n return;\n }\n\n debug && reporter.log(id, \"Making detectable...\");\n //The element is not prepared to be detectable, so do prepare it and add a listener to it.\n elementUtils.markBusy(element, true);\n return detectionStrategy.makeDetectable({ debug: debug }, element, function onElementDetectable(element) {\n debug && reporter.log(id, \"onElementDetectable\");\n\n if (stateHandler.getState(element)) {\n elementUtils.markAsDetectable(element);\n elementUtils.markBusy(element, false);\n detectionStrategy.addListener(element, onResizeCallback);\n addListener(callOnAdd, element, listener);\n\n // Since the element size might have changed since the call to \"listenTo\", we need to check for this change,\n // so that a resize event may be emitted.\n // Having the startSize object is optional (since it does not make sense in some cases such as unrendered elements), so check for its existance before.\n // Also, check the state existance before since the element may have been uninstalled in the installation process.\n var state = stateHandler.getState(element);\n if (state && state.startSize) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n if (state.startSize.width !== width || state.startSize.height !== height) {\n onResizeCallback(element);\n }\n }\n\n if(onReadyCallbacks[id]) {\n forEach(onReadyCallbacks[id], function(callback) {\n callback();\n });\n }\n } else {\n // The element has been unisntalled before being detectable.\n debug && reporter.log(id, \"Element uninstalled before being detectable.\");\n }\n\n delete onReadyCallbacks[id];\n\n elementsReady++;\n if(elementsReady === elements.length) {\n onReadyCallback();\n }\n });\n }\n\n debug && reporter.log(id, \"Already detecable, adding listener.\");\n\n //The element has been prepared to be detectable and is ready to be listened to.\n addListener(callOnAdd, element, listener);\n elementsReady++;\n });\n\n if(elementsReady === elements.length) {\n onReadyCallback();\n }\n }\n\n function uninstall(elements) {\n if(!elements) {\n return reporter.error(\"At least one element is required.\");\n }\n\n if (isElement(elements)) {\n // A single element has been passed in.\n elements = [elements];\n } else if (isCollection(elements)) {\n // Convert collection to array for plugins.\n // TODO: May want to check so that all the elements in the collection are valid elements.\n elements = toArray(elements);\n } else {\n return reporter.error(\"Invalid arguments. Must be a DOM element or a collection of DOM elements.\");\n }\n\n forEach(elements, function (element) {\n eventListenerHandler.removeAllListeners(element);\n detectionStrategy.uninstall(element);\n stateHandler.cleanState(element);\n });\n }\n\n return {\n listenTo: listenTo,\n removeListener: eventListenerHandler.removeListener,\n removeAllListeners: eventListenerHandler.removeAllListeners,\n uninstall: uninstall\n };\n};\n\nfunction getOption(options, name, defaultValue) {\n var value = options[name];\n\n if((value === undefined || value === null) && defaultValue !== undefined) {\n return defaultValue;\n }\n\n return value;\n}\n\n},{\"./browser-detector\":3,\"./collection-utils\":4,\"./detection-strategy/object.js\":5,\"./detection-strategy/scroll.js\":6,\"./element-utils\":8,\"./id-generator\":9,\"./id-handler\":10,\"./listener-handler\":11,\"./reporter\":12,\"./state-handler\":13,\"batch-processor\":1}],8:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function(options) {\n var getState = options.stateHandler.getState;\n\n /**\n * Tells if the element has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is detectable or not.\n */\n function isDetectable(element) {\n var state = getState(element);\n return state && !!state.isDetectable;\n }\n\n /**\n * Marks the element that it has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to mark.\n */\n function markAsDetectable(element) {\n getState(element).isDetectable = true;\n }\n\n /**\n * Tells if the element is busy or not.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is busy or not.\n */\n function isBusy(element) {\n return !!getState(element).busy;\n }\n\n /**\n * Marks the object is busy and should not be made detectable.\n * @public\n * @param {element} element The element to mark.\n * @param {boolean} busy If the element is busy or not.\n */\n function markBusy(element, busy) {\n getState(element).busy = !!busy;\n }\n\n return {\n isDetectable: isDetectable,\n markAsDetectable: markAsDetectable,\n isBusy: isBusy,\n markBusy: markBusy\n };\n};\n\n},{}],9:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function() {\n var idCount = 1;\n\n /**\n * Generates a new unique id in the context.\n * @public\n * @returns {number} A unique id in the context.\n */\n function generate() {\n return idCount++;\n }\n\n return {\n generate: generate\n };\n};\n\n},{}],10:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function(options) {\n var idGenerator = options.idGenerator;\n var getState = options.stateHandler.getState;\n\n /**\n * Gets the resize detector id of the element.\n * @public\n * @param {element} element The target element to get the id of.\n * @returns {string|number|null} The id of the element. Null if it has no id.\n */\n function getId(element) {\n var state = getState(element);\n\n if (state && state.id !== undefined) {\n return state.id;\n }\n\n return null;\n }\n\n /**\n * Sets the resize detector id of the element. Requires the element to have a resize detector state initialized.\n * @public\n * @param {element} element The target element to set the id of.\n * @returns {string|number|null} The id of the element.\n */\n function setId(element) {\n var state = getState(element);\n\n if (!state) {\n throw new Error(\"setId required the element to have a resize detection state.\");\n }\n\n var id = idGenerator.generate();\n\n state.id = id;\n\n return id;\n }\n\n return {\n get: getId,\n set: setId\n };\n};\n\n},{}],11:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function(idHandler) {\n var eventListeners = {};\n\n /**\n * Gets all listeners for the given element.\n * @public\n * @param {element} element The element to get all listeners for.\n * @returns All listeners for the given element.\n */\n function getListeners(element) {\n var id = idHandler.get(element);\n\n if (id === undefined) {\n return [];\n }\n\n return eventListeners[id] || [];\n }\n\n /**\n * Stores the given listener for the given element. Will not actually add the listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The callback that the element has added.\n */\n function addListener(element, listener) {\n var id = idHandler.get(element);\n\n if(!eventListeners[id]) {\n eventListeners[id] = [];\n }\n\n eventListeners[id].push(listener);\n }\n\n function removeListener(element, listener) {\n var listeners = getListeners(element);\n for (var i = 0, len = listeners.length; i < len; ++i) {\n if (listeners[i] === listener) {\n listeners.splice(i, 1);\n break;\n }\n }\n }\n\n function removeAllListeners(element) {\n var listeners = getListeners(element);\n if (!listeners) { return; }\n listeners.length = 0;\n }\n\n return {\n get: getListeners,\n add: addListener,\n removeListener: removeListener,\n removeAllListeners: removeAllListeners\n };\n};\n\n},{}],12:[function(require,module,exports){\n\"use strict\";\n\n/* global console: false */\n\n/**\n * Reporter that handles the reporting of logs, warnings and errors.\n * @public\n * @param {boolean} quiet Tells if the reporter should be quiet or not.\n */\nmodule.exports = function(quiet) {\n function noop() {\n //Does nothing.\n }\n\n var reporter = {\n log: noop,\n warn: noop,\n error: noop\n };\n\n if(!quiet && window.console) {\n var attachFunction = function(reporter, name) {\n //The proxy is needed to be able to call the method with the console context,\n //since we cannot use bind.\n reporter[name] = function reporterProxy() {\n var f = console[name];\n if (f.apply) { //IE9 does not support console.log.apply :)\n f.apply(console, arguments);\n } else {\n for (var i = 0; i < arguments.length; i++) {\n f(arguments[i]);\n }\n }\n };\n };\n\n attachFunction(reporter, \"log\");\n attachFunction(reporter, \"warn\");\n attachFunction(reporter, \"error\");\n }\n\n return reporter;\n};\n},{}],13:[function(require,module,exports){\n\"use strict\";\n\nvar prop = \"_erd\";\n\nfunction initState(element) {\n element[prop] = {};\n return getState(element);\n}\n\nfunction getState(element) {\n return element[prop];\n}\n\nfunction cleanState(element) {\n delete element[prop];\n}\n\nmodule.exports = {\n initState: initState,\n getState: getState,\n cleanState: cleanState\n};\n\n},{}]},{},[7])(7)\n});\n"]} \ No newline at end of file diff --git a/lib/fabric/fabric.js b/lib/fabric/fabric.js index bd1fb52d10e..b952b8fa2b6 100644 --- a/lib/fabric/fabric.js +++ b/lib/fabric/fabric.js @@ -1,2 +1,2 @@ -var fabric=fabric||{version:"1.7.22"};"undefined"!=typeof exports&&(exports.fabric=fabric),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window,window.fabric=fabric):(fabric.document=require("jsdom").jsdom(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E")),fabric.document.createWindow?fabric.window=fabric.document.createWindow():fabric.window=fabric.document.parentWindow),fabric.isTouchSupported="ontouchstart"in fabric.window,fabric.isLikelyNode="undefined"!=typeof Buffer&&"undefined"==typeof window,fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.iMatrix=[1,0,0,1,0,0],fabric.canvasModule="canvas",fabric.perfLimitSizeTotal=2097152,fabric.maxCacheSideLimit=4096,fabric.minCacheSideLimit=256,fabric.charWidthsCache={},fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,function(){function r(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.util.array.fill(i,!1)}}function t(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 e(t,e){if(this.__eventListeners){if(0===arguments.length)for(t in this.__eventListeners)r.call(this,t);else if(1===arguments.length&&"object"==typeof t)for(var i in t)r.call(this,i,t[i]);else r.call(this,t,e);return this}}function i(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,s=i.length;r>>0;if(0===i)return-1;var r=0;if(0>>0;i>>0;r>>0;i>>0;i>>0;s>>0,r=0;if(1=i)throw new TypeError}for(;r/g,">")}},function(){var s=Array.prototype.slice,n=Function.prototype.apply,o=function(){};Function.prototype.bind||(Function.prototype.bind=function(t){var e,i=this,r=s.call(arguments,1);return e=r.length?function(){return n.call(i,this instanceof o?this:t,r.concat(s.call(arguments)))}:function(){return n.call(i,this instanceof o?this:t,arguments)},o.prototype=this.prototype,e.prototype=new o,e})}(),function(){var n=Array.prototype.slice,o=function(){},i=function(){for(var t in{toString:1})if("toString"===t)return!1;return!0}(),a=function(t,r,s){for(var e in r)e in t.prototype&&"function"==typeof t.prototype[e]&&-1<(r[e]+"").indexOf("callSuper")?t.prototype[e]=function(i){return function(){var t=this.constructor.superclass;this.constructor.superclass=s;var e=r[i].apply(this,arguments);if(this.constructor.superclass=t,"initialize"!==i)return e}}(e):t.prototype[e]=r[e],i&&(r.toString!==Object.prototype.toString&&(t.prototype.toString=r.toString),r.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=r.valueOf))};function h(){}function c(t){for(var e=null,i=this;i.constructor.superclass;){var r=i.constructor.superclass.prototype[t];if(i[t]!==r){e=r;break}i=i.constructor.superclass.prototype}return e?1/i,"")));e&&e.documentElement||i&&i(null);x.parseSVGDocument(e.documentElement,function(t,e){i&&i(t,e)},r,s)}})},loadSVGFromString:function(t,i,e,r){var s;if(t=t.trim(),"undefined"!=typeof DOMParser){var n=new DOMParser;n&&n.parseFromString&&(s=n.parseFromString(t,"text/xml"))}else x.window.ActiveXObject&&((s=new ActiveXObject("Microsoft.XMLDOM")).async="false",s.loadXML(t.replace(//i,"")));x.parseSVGDocument(s.documentElement,function(t,e){i(t,e)},e,r)}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r,s){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0,this.parsingOptions=s},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;tt.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,e){return void 0===e&&(e=.5),e=Math.max(Math.min(1,e),0),new i(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new i(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new i(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new i(this.x,this.y)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var f=t.fabric||(t.fabric={});function d(t){this.status=t,this.points=[]}f.Intersection?f.warn("fabric.Intersection is already defined"):(f.Intersection=d,f.Intersection.prototype={constructor:d,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},f.Intersection.intersectLineLine=function(t,e,i,r){var s,n=(r.x-i.x)*(t.y-i.y)-(r.y-i.y)*(t.x-i.x),o=(e.x-t.x)*(t.y-i.y)-(e.y-t.y)*(t.x-i.x),a=(r.y-i.y)*(e.x-t.x)-(r.x-i.x)*(e.y-t.y);if(0!==a){var h=n/a,c=o/a;0<=h&&h<=1&&0<=c&&c<=1?(s=new d("Intersection")).appendPoint(new f.Point(t.x+h*(e.x-t.x),t.y+h*(e.y-t.y))):s=new d}else s=new d(0===n||0===o?"Coincident":"Parallel");return s},f.Intersection.intersectLinePolygon=function(t,e,i){for(var r,s,n,o=new d,a=i.length,h=0;hr.r2;if(s.sort(function(t,e){return t.offset-e.offset}),!t.group||"path-group"!==t.group.type)for(var o in r)"x1"===o||"x2"===o?r[o]+=this.offsetX-t.width/2:"y1"!==o&&"y2"!==o||(r[o]+=this.offsetY-t.height/2);if(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']),"radial"===this.type){if(n){(s=s.concat()).reverse();for(var a=0;a\n')}return e.push("linear"===this.type?"\n":"\n"),e.join("")},toLive:function(t,e){var i,r,s=fabric.util.object.clone(this.coords);if(this.type){if(e.group&&"path-group"===e.group.type)for(r in s)"x1"===r||"x2"===r?s[r]+=-this.offsetX+e.width/2:"y1"!==r&&"y2"!==r||(s[r]+=-this.offsetY+e.height/2);"linear"===this.type?i=t.createLinearGradient(s.x1,s.y1,s.x2,s.y2):"radial"===this.type&&(i=t.createRadialGradient(s.x1,s.y1,s.r1,s.x2,s.y2,s.r2));for(var n=0,o=this.colorStops.length;n\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if(void 0!==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 n=t.fabric||(t.fabric={}),o=n.util.toFixed;n.Shadow?n.warn("fabric.Shadow is already defined."):(n.Shadow=n.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){for(var e in"string"==typeof t&&(t=this._parseShadow(t)),t)this[e]=t[e];this.id=n.Object.__uid++},_parseShadow:function(t){var e=t.trim(),i=n.Shadow.reOffsetsAndBlur.exec(e)||[];return{color:(e.replace(n.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)").trim(),offsetX:parseInt(i[1],10)||0,offsetY:parseInt(i[2],10)||0,blur:parseInt(i[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var e=40,i=40,r=n.Object.NUM_FRACTION_DIGITS,s=n.util.rotateVector({x:this.offsetX,y:this.offsetY},n.util.degreesToRadians(-t.angle));return t.width&&t.height&&(e=100*o((Math.abs(s.x)+this.blur)/t.width,r)+20,i=100*o((Math.abs(s.y)+this.blur)/t.height,r)+20),t.flipX&&(s.x*=-1),t.flipY&&(s.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var e={},i=n.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(t){this[t]!==i[t]&&(e[t]=this[t])},this),e}}),n.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/)}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)fabric.warn("fabric.StaticCanvas is already defined.");else{var r=fabric.util.object.extend,t=fabric.util.getElementOffset,c=fabric.util.removeFromArray,a=fabric.util.toFixed,n=fabric.util.transformPoint,o=fabric.util.invertTransform,i=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!1,_initStatic:function(t,e){var i=fabric.StaticCanvas.prototype.renderAll.bind(this);this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio))},calcOffset:function(){return this._offset=t(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(e,t,i,r){return"string"==typeof t?fabric.util.loadImage(t,function(t){t&&(this[e]=new fabric.Image(t,r)),i&&i(t)},this,r&&r.crossOrigin):(r&&t.setOptions(r),this[e]=t,i&&i(t)),this},__setBgOverlayColor:function(t,e,i){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(t){var e=fabric.util.createCanvasElement(t);if(e.style||(e.style={}),!e)throw i;if(void 0===e.getContext)throw i;return e},_initOptions:function(t){this._setOptions(t),this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(t),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;for(var r in e=e||{},t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.renderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return this.viewportTransform[0]},setViewportTransform:function(t){var e,i=this._activeGroup;this.viewportTransform=t;for(var r=0,s=this._objects.length;r"),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,r=e.width||this.width,s=e.height||this.height,n='viewBox="0 0 '+this.width+" "+this.height+'" ',o=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?n='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,n='viewBox="'+a(-i[4]/i[0],o)+" "+a(-i[5]/i[3],o)+" "+a(this.width/i[0],o)+" "+a(this.height/i[3],o)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),"\n")},createSVGRefElementsMarkup:function(){var i=this;return["backgroundColor","overlayColor"].map(function(t){var e=i[t];if(e&&e.toLive)return e.toSVG(i,!1)}).join("")},createSVGFontFacesMarkup:function(){for(var t,e,i,r,s,n,o="",a={},h=fabric.fontPaths,c=this.getObjects(),l=0,u=c.length;l',"\n",o,"","\n"].join("")),o},_setSVGObjects:function(t,e){for(var i,r=0,s=this.getObjects(),n=s.length;r\n")}else t.push('\n")},sendToBack:function(t){if(!t)return this;var e,i,r,s=this._activeGroup;if(t===s)for(e=(r=s._objects).length;e--;)i=r[e],c(this._objects,i),this._objects.unshift(i);else c(this._objects,t),this._objects.unshift(t);return this.renderAll&&this.renderAll()},bringToFront:function(t){if(!t)return this;var e,i,r,s=this._activeGroup;if(t===s)for(r=s._objects,e=0;e"}}),r(fabric.StaticCanvas.prototype,fabric.Observable),r(fabric.StaticCanvas.prototype,fabric.Collection),r(fabric.StaticCanvas.prototype,fabric.DataURLExporter),r(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 void 0!==i.getImageData;case"setLineDash":return void 0!==i.setLineDash;case"toDataURL":return void 0!==e.toDataURL;case"toDataURLWithQuality":try{return e.toDataURL("image/jpeg",0),!0}catch(t){}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,e=this.canvas.getZoom();t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*e,t.shadowOffsetX=this.shadow.offsetX*e,t.shadowOffsetY=this.shadow.offsetY*e}},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}}),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){1t[e-2].x?1:s.x===t[e-2].x?0:-1,h=s.y>t[e-2].y?1:s.y===t[e-2].y?0:-1),i.push("L ",s.x+a*r," ",s.y+h*r),i},createPath:function(t){var e=new fabric.Path(t,{fill:null,stroke:this.color,strokeWidth:this.width,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeDashArray:this.strokeDashArray,originX:"center",originY:"center"}),i=new fabric.Point(e.left,e.top);return e.originX=fabric.Object.prototype.originX,e.originY=fabric.Object.prototype.originY,i=e.translateToGivenOrigin(i,"center","center",e.originX,e.originY),e.top=i.y,e.left=i.x,this.shadow&&(this.shadow.affectStroke=!0,e.setShadow(this.shadow)),e},_finalizeAndAddPath:function(){this.canvas.contextTop.closePath();var t=this.convertPointsToSVGPath(this._points).join("");if("M 0 0 Q 0 0 0 0 L 0 0"!==t){var e=this.createPath(t);this.canvas.add(e),e.setCoords(),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderAll(),this.canvas.fire("path:created",{path:e})}else this.canvas.renderAll()}}),fabric.CircleBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,initialize:function(t){this.canvas=t,this.points=[]},drawDot:function(t){var e=this.addPoint(t),i=this.canvas.contextTop,r=this.canvas.viewportTransform;i.save(),i.transform(r[0],r[1],r[2],r[3],r[4],r[5]),i.fillStyle=e.fill,i.beginPath(),i.arc(e.x,e.y,e.radius,0,2*Math.PI,!1),i.closePath(),i.fill(),i.restore()},onMouseDown:function(t){this.points.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.drawDot(t)},onMouseMove:function(t){this.drawDot(t)},onMouseUp:function(){var t=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;for(var e=[],i=0,r=this.points.length;is?t.x<0?t.x+=s:t.x-=s:t.x=0,c(t.y)>s?t.y<0?t.y+=s:t.y-=s:t.y=0},_rotateObject:function(t,e){var i=this._currentTransform;if(i.target.get("lockRotation"))return!1;var r=f(i.ey-i.top,i.ex-i.left),s=f(e-i.top,t-i.left),n=u(s-r+i.theta),o=!0;if(0"},getObjectScaling:function(){var t=this.scaleX,e=this.scaleY;if(this.group){var i=this.group.getObjectScaling();t*=i.scaleX,e*=i.scaleY}return{scaleX:t,scaleY:e}},_set:function(t,e){var i="scaleX"===t||"scaleY"===t,r=this[t]!==e;return i&&(e=this._constrainScale(e)),"scaleX"===t&&e<0?(this.flipX=!this.flipX,e*=-1):"scaleY"===t&&e<0?(this.flipY=!this.flipY,e*=-1):"shadow"!==t||!e||e instanceof y.Shadow?"dirty"===t&&this.group&&this.group.set("dirty",e):e=new y.Shadow(e),this[t]=e,r&&-1=t.x&&s.left+s.width<=e.x&&s.top>=t.y&&s.top+s.height<=e.y},containsPoint:function(t,e,i,r){e=e||this._getImageLines(r?this.calcCoords(i):i?this.aCoords:this.oCoords);var s=this._findCrossPoints(t,e);return 0!==s&&s%2==1},isOnScreen:function(t){if(!this.canvas)return!1;for(var e,i=this.canvas.vptCoords.tl,r=this.canvas.vptCoords.br,s=this.getCoords(!0,t),n=0;n<4;n++)if((e=s[n]).x<=r.x&&e.x>=i.x&&e.y<=r.y&&e.y>=i.y)return!0;if(this.intersectsWithRect(i,r,!0))return!0;var o={x:(i.x+r.x)/2,y:(i.y+r.y)/2};return!!this.containsPoint(o,null,!0)},_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,s=0;for(var n in e)if(!((r=e[n]).o.y=t.y&&r.d.y>=t.y||((r.o.x===r.d.x&&r.o.x>=t.x?r.o.x:(0,i=(r.d.y-r.o.y)/(r.d.x-r.o.x),-(t.y-0*t.x-(r.o.y-i*r.o.x))/(0-i)))>=t.x&&(s+=1),2!==s)))break;return s},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(t,e){var i=this.getCoords(t,e);return fabric.util.makeBoundingBoxFromPoints(i)},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)\n'),t?t(e.join("")):e.join("")}}),n.Line.ATTRIBUTE_NAMES=n.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),n.Line.fromElement=function(t,e){e=e||{};var i=n.parseAttributes(t,n.Line.ATTRIBUTE_NAMES),r=[i.x1||0,i.y1||0,i.x2||0,i.y2||0];return e.originX="left",e.originY="top",new n.Line(r,s(i,e))},n.Line.fromObject=function(t,e,i){var r=o(t,!0);r.points=[t.x1,t.y1,t.x2,t.y2];var s=n.Object._fromObject("Line",r,function(t){delete t.points,e&&e(t)},i,"points");return s&&delete s.points,s})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var n=t.fabric||(t.fabric={}),l=Math.PI,o=n.util.object.extend;n.Circle?n.warn("fabric.Circle is already defined."):(n.Circle=n.util.createClass(n.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*l,cacheProperties:n.Object.prototype.cacheProperties.concat("radius"),initialize:function(t){this.callSuper("initialize",t),this.set("radius",t&&t.radius||0)},_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return this.callSuper("toObject",["radius","startAngle","endAngle"].concat(t))},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,r=0,s=(this.endAngle-this.startAngle)%(2*l);if(0===s)this.group&&"path-group"===this.group.type&&(i=this.left+this.radius,r=this.top+this.radius),e.push("\n');else{var n=Math.cos(this.startAngle)*this.radius,o=Math.sin(this.startAngle)*this.radius,a=Math.cos(this.endAngle)*this.radius,h=Math.sin(this.endAngle)*this.radius,c=l\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)}}),n.Circle.ATTRIBUTE_NAMES=n.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),n.Circle.fromElement=function(t,e){e||(e={});var i,r=n.parseAttributes(t,n.Circle.ATTRIBUTE_NAMES);if(!("radius"in(i=r)&&0<=i.radius))throw new Error("value of `r` attribute is required and can not be negative");r.left=r.left||0,r.top=r.top||0;var s=new n.Circle(o(r,e));return s.left-=s.radius,s.top-=s.radius,s},n.Circle.fromObject=function(t,e,i){return n.Object._fromObject("Circle",t,e,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var r=t.fabric||(t.fabric={});r.Triangle?r.warn("fabric.Triangle is already defined"):(r.Triangle=r.util.createClass(r.Object,{type:"triangle",initialize:function(t){this.callSuper("initialize",t),this.set("width",t&&t.width||100).set("height",t&&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 e=this.width/2,i=this.height/2;t.beginPath(),r.util.drawDashedLine(t,-e,i,0,-i,this.strokeDashArray),r.util.drawDashedLine(t,0,-i,e,i,this.strokeDashArray),r.util.drawDashedLine(t,e,i,-e,i,this.strokeDashArray),t.closePath()},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.width/2,r=this.height/2,s=[-i+" "+r,"0 "+-r,i+" "+r].join(",");return e.push("'),t?t(e.join("")):e.join("")}}),r.Triangle.fromObject=function(t,e,i){return r.Object._fromObject("Triangle",t,e,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var s=t.fabric||(t.fabric={}),i=2*Math.PI,n=s.util.object.extend;s.Ellipse?s.warn("fabric.Ellipse is already defined."):(s.Ellipse=s.util.createClass(s.Object,{type:"ellipse",rx:0,ry:0,cacheProperties:s.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this.set("rx",t&&t.rx||0),this.set("ry",t&&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 this.callSuper("toObject",["rx","ry"].concat(t))},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)}}),s.Ellipse.ATTRIBUTE_NAMES=s.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),s.Ellipse.fromElement=function(t,e){e||(e={});var i=s.parseAttributes(t,s.Ellipse.ATTRIBUTE_NAMES);i.left=i.left||0,i.top=i.top||0;var r=new s.Ellipse(n(i,e));return r.top-=r.ry,r.left-=r.rx,r},s.Ellipse.fromObject=function(t,e,i){return s.Object._fromObject("Ellipse",t,e,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var n=t.fabric||(t.fabric={}),s=n.util.object.extend;n.Rect?n.warn("fabric.Rect is already defined"):(n.Rect=n.util.createClass(n.Object,{stateProperties:n.Object.prototype.stateProperties.concat("rx","ry"),type:"rect",rx:0,ry:0,cacheProperties:n.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(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){var i=this.rx?Math.min(this.rx,this.width/2):0,r=this.ry?Math.min(this.ry,this.height/2):0,s=this.width,n=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+s-i,a),h&&t.bezierCurveTo(o+s-c*i,a,o+s,a+c*r,o+s,a+r),t.lineTo(o+s,a+n-r),h&&t.bezierCurveTo(o+s,a+n-c*r,o+s-c*i,a+n,o+s-i,a+n),t.lineTo(o+i,a+n),h&&t.bezierCurveTo(o+c*i,a+n,o,a+n-c*r,o,a+n-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)}else t.fillRect(-.5,-.5,1,1)},_renderDashedStroke:function(t){var e=-this.width/2,i=-this.height/2,r=this.width,s=this.height;t.beginPath(),n.util.drawDashedLine(t,e,i,e+r,i,this.strokeDashArray),n.util.drawDashedLine(t,e+r,i,e+r,i+s,this.strokeDashArray),n.util.drawDashedLine(t,e+r,i+s,e,i+s,this.strokeDashArray),n.util.drawDashedLine(t,e,i+s,e,i,this.strokeDashArray),t.closePath()},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},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("")}}),n.Rect.ATTRIBUTE_NAMES=n.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),n.Rect.fromElement=function(t,e){if(!t)return null;e=e||{};var i=n.parseAttributes(t,n.Rect.ATTRIBUTE_NAMES);i.left=i.left||0,i.top=i.top||0;var r=new n.Rect(s(e?n.util.object.clone(e):{},i));return r.visible=r.visible&&0\n'),t?t(s.join("")):s.join("")},commonRender:function(t,e){var i,r=this.points.length,s=e?0:this.pathOffset.x,n=e?0:this.pathOffset.y;if(!r||isNaN(this.points[r-1].y))return!1;t.beginPath(),t.moveTo(this.points[0].x-s,this.points[0].y-n);for(var o=0;o"},toObject:function(t){return s(this.callSuper("toObject",["sourcePath","pathOffset"].concat(t)),{path:this.path.map(function(t){return t.slice()}),top:this.top,left:this.left})},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="",s=0,n=this.path.length;s\n"),t?t(i.join("")):i.join("")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,s,n=[],o=[],a=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,h=0,c=this.path.length;hd)for(var p=1,v=s.length;p\n");for(var n=0,o=e.length;n\n"),t?t(s.join("")):s.join("")},toString:function(){return"#"},isSameColor:function(){var i=this.getObjects()[0].get("fill")||"";return"string"==typeof i&&(i=i.toLowerCase(),this.getObjects().every(function(t){var e=t.get("fill")||"";return"string"==typeof e&&e.toLowerCase()===i}))},complexity:function(){return this.paths.reduce(function(t,e){return t+(e&&e.complexity?e.complexity():0)},0)},getObjects:function(){return this.paths}}),u.PathGroup.fromObject=function(r,s){var n=r.paths;delete r.paths,"string"==typeof n?u.loadSVGFromURL(n,function(t){var e=n,i=u.util.groupSVGElements(t,r,e);r.paths=n,s(i)}):u.util.enlivenObjects(n,function(t){var e=new u.PathGroup(t,r);r.paths=n,s(e)})},u.PathGroup.async=!0)}("undefined"!=typeof exports?exports:this),function(t){"use strict";var o=t.fabric||(t.fabric={}),e=o.util.object.extend,a=o.util.array.min,h=o.util.array.max;if(!o.Group){var r={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};o.Group=o.util.createClass(o.Object,o.Collection,{type:"group",strokeWidth:0,subTargetCheck:!1,cacheProperties:[],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;e.originX&&(this.originX=e.originX),e.originY&&(this.originY=e.originY),i?(this._updateObjectsCoords(!0),this._updateObjectsACoords()):(this._calcBounds(),this._updateObjectsCoords(),this.callSuper("initialize",e)),this.setCoords(),this.saveCoords()},_updateObjectsACoords:function(){for(var t=this._objects.length;t--;)this._objects[t].setCoords(!0,!0)},_updateObjectsCoords:function(t){for(var e=this.getCenterPoint(),i=this._objects.length;i--;)this._updateObjectCoords(this._objects[i],e,t)},_updateObjectCoords:function(t,e,i){if(t.__origHasControls=t.hasControls,t.hasControls=!1,!i){var r=t.getLeft(),s=t.getTop();t.set({left:r-e.x,top:s-e.y}),t.setCoords(!0,!0)}},toString:function(){return"#"},addWithUpdate:function(t){return this._restoreObjectsState(),o.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.setCoords(),this.dirty=!0,this},_setObjectActive:function(t){t.set("active",!0),t.group=this},removeWithUpdate:function(t){return this._restoreObjectsState(),o.util.resetObjectTransform(this),this.forEachObject(this._setObjectActive,this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},_onObjectAdded:function(t){this.dirty=!0,t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){this.dirty=!0,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(r){var t=this.getObjects().map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=t.group.includeDefaultValues;var i=t.toObject(r);return t.includeDefaultValues=e,i});return e(this.callSuper("toObject",r),{objects:t})},toDatalessObject:function(r){var t=this.getObjects().map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=t.group.includeDefaultValues;var i=t.toDatalessObject(r);return t.includeDefaultValues=e,i});return e(this.callSuper("toDatalessObject",r),{objects:t})},render:function(t){this._transformDone=!0,this.callSuper("render",t),this._transformDone=!1},shouldCache:function(){var t=this.objectCaching&&(!this.group||this.needsItsOwnCache()||!this.group.isCaching());if(this.caching=t)for(var e=0,i=this._objects.length;e\n');for(var i=0,r=this._objects.length;i\n"),t?t(e.join("")):e.join("")},get:function(t){if(t in r){if(this[t])return this[t];for(var e=0,i=this._objects.length;e\n',"\n"),this.stroke||this.strokeDashArray){var n=this.fill;this.fill=null,e.push("\n'),this.fill=n}return e.push("\n"),t?t(e.join("")):e.join("")},getSrc:function(t){var e=t?this._element:this._originalElement;return e?fabric.isLikelyNode?e._src:e.src:this.src||""},setSrc:function(t,e,i){fabric.util.loadImage(t,function(t){return this.setElement(t,e,i)},this,i&&i.crossOrigin)},toString:function(){return'#'},applyFilters:function(t,e,i,r){if(e=e||this.filters,i=i||this._originalElement){var s,n,o=fabric.util.createImage(),a=this.canvas?this.canvas.getRetinaScaling():fabric.devicePixelRatio,h=this.minimumScaleTrigger/a,c=this;if(0===e.length)return this._element=i,t&&t(this),i;var l=fabric.util.createCanvasElement();return l.width=i.width,l.height=i.height,l.getContext("2d").drawImage(i,0,0,i.width,i.height),e.forEach(function(t){t&&(r?(s=c.scaleX'},_getCacheCanvasDimensions:function(){var t=this.callSuper("_getCacheCanvasDimensions"),e=this.fontSize;return t.width+=e*t.zoomX,t.height+=e*t.zoomY,t},_render:function(t){this._setTextStyles(t),this.group&&"path-group"===this.group.type&&t.translate(this.left,this.top),this._renderTextLinesBackground(t),this._renderText(t),this._renderTextDecoration(t)},_renderText:function(t){this._renderTextFill(t),this._renderTextStroke(t)},_setTextStyles:function(t){t.textBaseline="alphabetic",t.font=this._getFontDeclaration()},_getTextHeight:function(){return this._getHeightOfSingleLine()+(this._textLines.length-1)*this._getHeightOfLine()},_getTextWidth:function(t){for(var e=this._getLineWidth(t,0),i=1,r=this._textLines.length;i\n",e.textBgRects.join(""),'\t\t\n',e.textSpans.join(""),"\t\t\n","\t\n")},getSvgStyles:function(t){return d.Object.prototype.getSvgStyles.call(this,t)+" white-space: pre;"},_getSVGTextAndBg:function(t,e){var i=[],r=[],s=0;this._setSVGBg(r);for(var n=0,o=this._textLines.length;n",d.util.string.escapeXml(this._textLines[t]),"\n"):this._setSVGTextLineJustifed(t,e,n,r)},_setSVGTextLineJustifed:function(t,e,i,r){var s=d.util.createCanvasElement().getContext("2d");this._setTextStyles(s);var n,o,a=this._textLines[t].split(/\s+/),h=this._getWidthOfWords(s,a.join("")),c=this.width-h,l=a.length-1,u=0",d.util.string.escapeXml(n),"\n"),r+=this._getWidthOfWords(s,n)+u},_setSVGTextLineBg:function(t,e,i,r,s){t.push("\t\t\n')},_setSVGBg:function(t){this.backgroundColor&&t.push("\t\t\n')},_getFillAttributes:function(t){var e=t&&"string"==typeof t?new d.Color(t):"";return e&&e.getSource()&&1!==e.getAlpha()?'opacity="'+e.getAlpha()+'" fill="'+e.setAlpha(1).toRgb()+'"':'fill="'+t+'"'},_set:function(t,e){this.callSuper("_set",t,e),-1=r.charIndex&&(a!==o||dthis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=e):(this.selectionStart=e,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this.restartCursorIfNeeded(),this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}},_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.cursorOffsetCache={},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.left,this.hiddenTextarea.style.top=t.top,this.hiddenTextarea.style.fontSize=t.fontSize}},_calcTextareaPosition:function(){if(!this.canvas)return{x:1,y:1};var t=this.text.split(""),e=this._getCursorBoundaries(t,"cursor"),i=this.get2DCursorLocation(),r=i.lineIndex,s=i.charIndex,n=this.getCurrentCharFontSize(r,s),o=e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+n},c=this.canvas.upperCanvasEl,l=c.width-n,u=c.height-n;return h=fabric.util.transformPoint(h,a),(h=fabric.util.transformPoint(h,this.canvas.viewportTransform)).x<0&&(h.x=0),h.x>l&&(h.x=l),h.y<0&&(h.y=0),h.y>u&&(h.y=u),h.x+=this.canvas._offset.left,h.y+=this.canvas._offset.top,{left:h.x+"px",top:h.y+"px",fontSize:n}},_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(){var t=this._textBeforeEdit!==this.text;return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&(this.hiddenTextarea.blur&&this.hiddenTextarea.blur(),this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null),this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.off("mouse:move",this.mouseMoveHandler),this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{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.selectionStart=t,this.selectionEnd=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(1t?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),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,t.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.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&&(!t.e.button||1===t.e.button)){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())}})},_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)||t.e.button&&1!==t.e.button||(this.__lastSelected&&!this.__corner&&(this.enterEditing(t.e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()),this.selected=!0)})},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t),i=this.selectionStart,r=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(i,r,e):(this.selectionStart=e,this.selectionEnd=e),this.isEditing&&(this._fireSelectionChanged(),this._updateTextarea())},getSelectionStartFromPointer:function(t){for(var e,i=this.getLocalPointer(t),r=0,s=0,n=0,o=0,a=0,h=this._textLines.length;athis.text.length&&(n=this.text.length),n}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.setAttribute("autocorrect","off"),this.hiddenTextarea.setAttribute("autocomplete","off"),this.hiddenTextarea.setAttribute("spellcheck","false"),this.hiddenTextarea.setAttribute("data-fabric-hiddentextarea",""),this.hiddenTextarea.setAttribute("wrap","off");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="position: absolute; top: "+t.top+"; left: "+t.left+"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; line-height: 1px; paddingーtop: "+t.fontSize+";",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"},ctrlKeysMapUp:{67:"copy",88:"cut"},ctrlKeysMapDown:{65:"selectAll"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing){if(t.keyCode in this.keysMap)this[this.keysMap[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),33<=t.keyCode&&t.keyCode<=40?(this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.renderAll()}},onKeyUp:function(t){this.isEditing&&!this._copyDone?t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()):this._copyDone=!1},onInput:function(t){if(this.isEditing&&!this.inCompositionMode){var e,i,r,s=this.selectionStart||0,n=this.selectionEnd||0,o=this.text.length,a=this.hiddenTextarea.value.length;i=o=this.text.length&&this.selectionEnd>=this.text.length||this._moveCursorUpOrDown("Down",t)},moveCursorUp:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)},_moveCursorUpOrDown:function(t,e){var i=this["get"+t+"CursorOffset"](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(i):this.moveCursorWithoutShift(i),0!==i&&(this.setSelectionInBoundaries(),this.abortCursorAnimation(),this._currentCursorOpacity=1,this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorWithShift:function(t){var e="left"===this._selectionDirection?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t},moveCursorWithoutShift:function(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t},moveCursorLeft:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)},_move:function(t,e,i){var r;if(t.altKey)r=this["findWordBoundary"+i](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;r=this["findLineBoundary"+i](this[e])}if(void 0!==typeof r&&this[e]!==r)return this[e]=r,!0},_moveLeft:function(t,e){return this._move(t,e,"Left")},_moveRight:function(t,e){return this._move(t,e,"Right")},moveCursorLeftWithoutShift:function(t){var e=!0;return this._selectionDirection="left",this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e},moveCursorLeftWithShift:function(t){return"right"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection="left",this._moveLeft(t,"selectionStart")):void 0},moveCursorRight:function(t){this.selectionStart>=this.text.length&&this.selectionEnd>=this.text.length||this._moveCursorLeftOrRight("Right",t)},_moveCursorLeftOrRight:function(t,e){var i="moveCursor"+t+"With";this._currentCursorOpacity=1,e.shiftKey?i+="Shift":i+="outShift",this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorRightWithShift:function(t){return"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this.text.length?(this._selectionDirection="right",this._moveRight(t,"selectionEnd")):void 0},moveCursorRightWithoutShift:function(t){var e=!0;return this._selectionDirection="right",this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e},removeChars:function(t){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.set("dirty",!0),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 o=fabric.util.toFixed,a=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(t,e,i,r,s,n){this._getLineStyle(t)?this._setSVGTextLineChars(t,e,i,r,n):fabric.Text.prototype._setSVGTextLineText.call(this,t,e,i,r,s)},_setSVGTextLineChars:function(t,e,i,r,s){for(var n=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=n.length;l\n'].join("")},_createTextCharSpan:function(t,e,i,r,s){var n=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},e));return['\t\t\t',fabric.util.string.escapeXml(t),"\n"].join("")}})}(),function(t){"use strict";var r=t.fabric||(t.fabric={});r.Textbox=r.util.createClass(r.IText,r.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:2,__cachedLines:null,lockScalingY:!0,lockScalingFlip:!0,noScaleCache:!1,_dimensionAffectingProps:r.Text.prototype._dimensionAffectingProps.concat("width"),initialize:function(t,e){this.callSuper("initialize",t,e),this.setControlsVisibility(r.Textbox.getTextboxControlVisibility()),this.ctx=this.objectCaching?this._cacheContext:r.util.createCanvasElement().getContext("2d")},_initDimensions:function(t){this.__skipDimension||(t||(t=r.util.createCanvasElement().getContext("2d"),this._setTextStyles(t),this.clearContextTop()),this.dynamicMinWidth=0,this._textLines=this._splitTextIntoLines(t),this.dynamicMinWidth>this.width&&this._set("width",this.dynamicMinWidth),this._clearCache(),this.height=this._getTextHeight(t),this.setCoords())},_generateStyleMap:function(){for(var t=0,e=0,i=0,r={},s=0;s=this.width&&!f?(s.push(n),r=c,f=!(n="")):r+=d,f||(n+=" "),n+=a,l=this._measureText(t," ",i,h),h++,f=!1,uthis.dynamicMinWidth&&(this.dynamicMinWidth=u-d),s},_splitTextIntoLines:function(t){t=t||this.ctx;var e=this.textAlign;this._styleMap=null,t.save(),this._setTextStyles(t),this.textAlign="left";var i=this._wrapText(t,this.text);return this.textAlign=e,t.restore(),this._textLines=i,this._styleMap=this._generateStyleMap(),i},setOnGroup:function(t,e){"scaleX"===t&&(this.set("scaleX",Math.abs(1/e)),this.set("width",this.get("width")*e/(void 0===this.__oldScaleX?1:this.__oldScaleX)),this.__oldScaleX=e)},get2DCursorLocation:function(t){void 0===t&&(t=this.selectionStart);for(var e=this._textLines.length,i=0,r=0;r=a.getMinWidth()?(a.set("width",h),!0):void 0},fabric.Group.prototype._refreshControlsVisibility=function(){if(void 0!==fabric.Textbox)for(var t=this._objects.length;t--;)if(this._objects[t]instanceof fabric.Textbox)return void this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility())},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,e){t=this._styleMap[t].line,fabric.IText.prototype.shiftLineStyles.call(this,t,e)},_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],s=r.line,n=r.offset+i.charIndex;this._removeStyleObject(t,i,s,n)}})}(),function(){var h=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(t,e,i,r,s){r=h.call(this,t,e,i,r,s);for(var n=0,o=0,a=0;a>>0;if(0==i)return-1;var r=0;if(0>>0;i>>0;r>>0;i>>0;i>>0;n>>0,r=0;if(1=i)throw new TypeError}for(;r/g,">")}},function(){function n(){}var s=Array.prototype.slice,o=Function.prototype.apply;Function.prototype.bind||(Function.prototype.bind=function(t){var e,i=this,r=s.call(arguments,1);return e=r.length?function(){return o.call(i,this instanceof n?this:t,r.concat(s.call(arguments)))}:function(){return o.call(i,this instanceof n?this:t,arguments)},n.prototype=this.prototype,e.prototype=new n,e})}(),function(){function s(){}function o(t,r,n){for(var e in r)e in t.prototype&&"function"==typeof t.prototype[e]&&-1<(r[e]+"").indexOf("callSuper")?t.prototype[e]=function(i){return function(){var t=this.constructor.superclass;this.constructor.superclass=n;var e=r[i].apply(this,arguments);if(this.constructor.superclass=t,"initialize"!==i)return e}}(e):t.prototype[e]=r[e],i&&(r.toString!==Object.prototype.toString&&(t.prototype.toString=r.toString),r.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=r.valueOf))}var a=Array.prototype.slice,i=function(){for(var t in{toString:1})if("toString"===t)return!1;return!0}();function h(){}function c(t){for(var e=null,i=this;i.constructor.superclass;){var r=i.constructor.superclass.prototype[t];if(i[t]!==r){e=r;break}i=i.constructor.superclass.prototype}return e?1/i,"")));e&&e.documentElement||i&&i(null);y.parseSVGDocument(e.documentElement,function(t,e){i&&i(t,e)},r,n)}})},loadSVGFromString:function(t,i,e,r){var n;if(t=t.trim(),"undefined"!=typeof DOMParser){var s=new DOMParser;s&&s.parseFromString&&(n=s.parseFromString(t,"text/xml"))}else y.window.ActiveXObject&&((n=new ActiveXObject("Microsoft.XMLDOM")).async="false",n.loadXML(t.replace(//i,"")));y.parseSVGDocument(n.documentElement,function(t,e){i(t,e)},e,r)}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r,n){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0,this.parsingOptions=n},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;tt.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,e){return void 0===e&&(e=.5),e=Math.max(Math.min(1,e),0),new i(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new i(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new i(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new i(this.x,this.y)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var f=t.fabric||(t.fabric={});function d(t){this.status=t,this.points=[]}f.Intersection?f.warn("fabric.Intersection is already defined"):(f.Intersection=d,f.Intersection.prototype={constructor:d,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},f.Intersection.intersectLineLine=function(t,e,i,r){var n,s=(r.x-i.x)*(t.y-i.y)-(r.y-i.y)*(t.x-i.x),o=(e.x-t.x)*(t.y-i.y)-(e.y-t.y)*(t.x-i.x),a=(r.y-i.y)*(e.x-t.x)-(r.x-i.x)*(e.y-t.y);if(0!=a){var h=s/a,c=o/a;0<=h&&h<=1&&0<=c&&c<=1?(n=new d("Intersection")).appendPoint(new f.Point(t.x+h*(e.x-t.x),t.y+h*(e.y-t.y))):n=new d}else n=new d(0==s||0==o?"Coincident":"Parallel");return n},f.Intersection.intersectLinePolygon=function(t,e,i){for(var r,n,s,o=new d,a=i.length,h=0;hr.r2;if(n.sort(function(t,e){return t.offset-e.offset}),!t.group||"path-group"!==t.group.type)for(var o in r)"x1"===o||"x2"===o?r[o]+=this.offsetX-t.width/2:"y1"!==o&&"y2"!==o||(r[o]+=this.offsetY-t.height/2);if(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']),"radial"===this.type){if(s){(n=n.concat()).reverse();for(var a=0;a\n')}return e.push("linear"===this.type?"\n":"\n"),e.join("")},toLive:function(t,e){var i,r,n=fabric.util.object.clone(this.coords);if(this.type){if(e.group&&"path-group"===e.group.type)for(r in n)"x1"===r||"x2"===r?n[r]+=-this.offsetX+e.width/2:"y1"!==r&&"y2"!==r||(n[r]+=-this.offsetY+e.height/2);"linear"===this.type?i=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(i=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2));for(var s=0,o=this.colorStops.length;s\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if(void 0!==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 s=t.fabric||(t.fabric={}),o=s.util.toFixed;s.Shadow?s.warn("fabric.Shadow is already defined."):(s.Shadow=s.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){for(var e in"string"==typeof t&&(t=this._parseShadow(t)),t)this[e]=t[e];this.id=s.Object.__uid++},_parseShadow:function(t){var e=t.trim(),i=s.Shadow.reOffsetsAndBlur.exec(e)||[];return{color:(e.replace(s.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)").trim(),offsetX:parseInt(i[1],10)||0,offsetY:parseInt(i[2],10)||0,blur:parseInt(i[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var e=40,i=40,r=s.Object.NUM_FRACTION_DIGITS,n=s.util.rotateVector({x:this.offsetX,y:this.offsetY},s.util.degreesToRadians(-t.angle));return t.width&&t.height&&(e=100*o((Math.abs(n.x)+this.blur)/t.width,r)+20,i=100*o((Math.abs(n.y)+this.blur)/t.height,r)+20),t.flipX&&(n.x*=-1),t.flipY&&(n.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var e={},i=s.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(t){this[t]!==i[t]&&(e[t]=this[t])},this),e}}),s.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/)}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)fabric.warn("fabric.StaticCanvas is already defined.");else{var r=fabric.util.object.extend,t=fabric.util.getElementOffset,c=fabric.util.removeFromArray,a=fabric.util.toFixed,s=fabric.util.transformPoint,o=fabric.util.invertTransform,i=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!1,_initStatic:function(t,e){var i=fabric.StaticCanvas.prototype.renderAll.bind(this);this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio))},calcOffset:function(){return this._offset=t(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(e,t,i,r){return"string"==typeof t?fabric.util.loadImage(t,function(t){t&&(this[e]=new fabric.Image(t,r)),i&&i(t)},this,r&&r.crossOrigin):(r&&t.setOptions(r),this[e]=t,i&&i(t)),this},__setBgOverlayColor:function(t,e,i){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(t){var e=fabric.util.createCanvasElement(t);if(e.style||(e.style={}),!e)throw i;if(void 0===e.getContext)throw i;return e},_initOptions:function(t){this._setOptions(t),this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(t),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;for(var r in e=e||{},t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.renderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return this.viewportTransform[0]},setViewportTransform:function(t){var e,i=this._activeGroup;this.viewportTransform=t;for(var r=0,n=this._objects.length;r"),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,r=e.width||this.width,n=e.height||this.height,s='viewBox="0 0 '+this.width+" "+this.height+'" ',o=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?s='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,s='viewBox="'+a(-i[4]/i[0],o)+" "+a(-i[5]/i[3],o)+" "+a(this.width/i[0],o)+" "+a(this.height/i[3],o)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),"\n")},createSVGRefElementsMarkup:function(){var i=this;return["backgroundColor","overlayColor"].map(function(t){var e=i[t];if(e&&e.toLive)return e.toSVG(i,!1)}).join("")},createSVGFontFacesMarkup:function(){for(var t,e,i,r,n,s,o="",a={},h=fabric.fontPaths,c=this.getObjects(),l=0,u=c.length;l',"\n",o,"","\n"].join("")),o},_setSVGObjects:function(t,e){for(var i,r=0,n=this.getObjects(),s=n.length;r\n")}else t.push('\n")},sendToBack:function(t){if(!t)return this;var e,i,r,n=this._activeGroup;if(t===n)for(e=(r=n._objects).length;e--;)i=r[e],c(this._objects,i),this._objects.unshift(i);else c(this._objects,t),this._objects.unshift(t);return this.renderAll&&this.renderAll()},bringToFront:function(t){if(!t)return this;var e,i,r,n=this._activeGroup;if(t===n)for(r=n._objects,e=0;e"}}),r(fabric.StaticCanvas.prototype,fabric.Observable),r(fabric.StaticCanvas.prototype,fabric.Collection),r(fabric.StaticCanvas.prototype,fabric.DataURLExporter),r(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 void 0!==i.getImageData;case"setLineDash":return void 0!==i.setLineDash;case"toDataURL":return void 0!==e.toDataURL;case"toDataURLWithQuality":try{return e.toDataURL("image/jpeg",0),!0}catch(t){}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,e=this.canvas.getZoom();t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*e,t.shadowOffsetX=this.shadow.offsetX*e,t.shadowOffsetY=this.shadow.offsetY*e}},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}}),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){1t[e-2].x?1:n.x===t[e-2].x?0:-1,h=n.y>t[e-2].y?1:n.y===t[e-2].y?0:-1),i.push("L ",n.x+a*r," ",n.y+h*r),i},createPath:function(t){var e=new fabric.Path(t,{fill:null,stroke:this.color,strokeWidth:this.width,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeDashArray:this.strokeDashArray,originX:"center",originY:"center"}),i=new fabric.Point(e.left,e.top);return e.originX=fabric.Object.prototype.originX,e.originY=fabric.Object.prototype.originY,i=e.translateToGivenOrigin(i,"center","center",e.originX,e.originY),e.top=i.y,e.left=i.x,this.shadow&&(this.shadow.affectStroke=!0,e.setShadow(this.shadow)),e},_finalizeAndAddPath:function(){this.canvas.contextTop.closePath();var t=this.convertPointsToSVGPath(this._points).join("");if("M 0 0 Q 0 0 0 0 L 0 0"!==t){var e=this.createPath(t);this.canvas.add(e),e.setCoords(),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderAll(),this.canvas.fire("path:created",{path:e})}else this.canvas.renderAll()}}),fabric.CircleBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,initialize:function(t){this.canvas=t,this.points=[]},drawDot:function(t){var e=this.addPoint(t),i=this.canvas.contextTop,r=this.canvas.viewportTransform;i.save(),i.transform(r[0],r[1],r[2],r[3],r[4],r[5]),i.fillStyle=e.fill,i.beginPath(),i.arc(e.x,e.y,e.radius,0,2*Math.PI,!1),i.closePath(),i.fill(),i.restore()},onMouseDown:function(t){this.points.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.drawDot(t)},onMouseMove:function(t){this.drawDot(t)},onMouseUp:function(){var t=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;for(var e=[],i=0,r=this.points.length;in?t.x<0?t.x+=n:t.x-=n:t.x=0,c(t.y)>n?t.y<0?t.y+=n:t.y-=n:t.y=0},_rotateObject:function(t,e){var i=this._currentTransform;if(i.target.get("lockRotation"))return!1;var r=f(i.ey-i.top,i.ex-i.left),n=f(e-i.top,t-i.left),s=u(n-r+i.theta),o=!0;if(0"},getObjectScaling:function(){var t=this.scaleX,e=this.scaleY;if(this.group){var i=this.group.getObjectScaling();t*=i.scaleX,e*=i.scaleY}return{scaleX:t,scaleY:e}},_set:function(t,e){var i="scaleX"===t||"scaleY"===t,r=this[t]!==e;return i&&(e=this._constrainScale(e)),"scaleX"===t&&e<0?(this.flipX=!this.flipX,e*=-1):"scaleY"===t&&e<0?(this.flipY=!this.flipY,e*=-1):"shadow"!==t||!e||e instanceof y.Shadow?"dirty"===t&&this.group&&this.group.set("dirty",e):e=new y.Shadow(e),this[t]=e,r&&-1=t.x&&n.left+n.width<=e.x&&n.top>=t.y&&n.top+n.height<=e.y},containsPoint:function(t,e,i,r){e=e||this._getImageLines(r?this.calcCoords(i):i?this.aCoords:this.oCoords);var n=this._findCrossPoints(t,e);return 0!==n&&n%2==1},isOnScreen:function(t){if(!this.canvas)return!1;for(var e,i=this.canvas.vptCoords.tl,r=this.canvas.vptCoords.br,n=this.getCoords(!0,t),s=0;s<4;s++)if((e=n[s]).x<=r.x&&e.x>=i.x&&e.y<=r.y&&e.y>=i.y)return!0;if(this.intersectsWithRect(i,r,!0))return!0;var o={x:(i.x+r.x)/2,y:(i.y+r.y)/2};return!!this.containsPoint(o,null,!0)},_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=0;for(var s in e)if(!((r=e[s]).o.y=t.y&&r.d.y>=t.y||((r.o.x===r.d.x&&r.o.x>=t.x?r.o.x:(0,i=(r.d.y-r.o.y)/(r.d.x-r.o.x),-(t.y-0*t.x-(r.o.y-i*r.o.x))/(0-i)))>=t.x&&(n+=1),2!==n)))break;return n},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(t,e){var i=this.getCoords(t,e);return fabric.util.makeBoundingBoxFromPoints(i)},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)\n'),t?t(e.join("")):e.join("")}}),s.Line.ATTRIBUTE_NAMES=s.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),s.Line.fromElement=function(t,e){e=e||{};var i=s.parseAttributes(t,s.Line.ATTRIBUTE_NAMES),r=[i.x1||0,i.y1||0,i.x2||0,i.y2||0];return e.originX="left",e.originY="top",new s.Line(r,n(i,e))},s.Line.fromObject=function(t,e,i){var r=o(t,!0);r.points=[t.x1,t.y1,t.x2,t.y2];var n=s.Object._fromObject("Line",r,function(t){delete t.points,e&&e(t)},i,"points");return n&&delete n.points,n})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var n=t.fabric||(t.fabric={}),l=Math.PI,s=n.util.object.extend;n.Circle?n.warn("fabric.Circle is already defined."):(n.Circle=n.util.createClass(n.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*l,cacheProperties:n.Object.prototype.cacheProperties.concat("radius"),initialize:function(t){this.callSuper("initialize",t),this.set("radius",t&&t.radius||0)},_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return this.callSuper("toObject",["radius","startAngle","endAngle"].concat(t))},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,r=0,n=(this.endAngle-this.startAngle)%(2*l);if(0==n)this.group&&"path-group"===this.group.type&&(i=this.left+this.radius,r=this.top+this.radius),e.push("\n');else{var s=Math.cos(this.startAngle)*this.radius,o=Math.sin(this.startAngle)*this.radius,a=Math.cos(this.endAngle)*this.radius,h=Math.sin(this.endAngle)*this.radius,c=l\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)}}),n.Circle.ATTRIBUTE_NAMES=n.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),n.Circle.fromElement=function(t,e){e||(e={});var i=n.parseAttributes(t,n.Circle.ATTRIBUTE_NAMES);if(!function(t){return"radius"in t&&0<=t.radius}(i))throw new Error("value of `r` attribute is required and can not be negative");i.left=i.left||0,i.top=i.top||0;var r=new n.Circle(s(i,e));return r.left-=r.radius,r.top-=r.radius,r},n.Circle.fromObject=function(t,e,i){return n.Object._fromObject("Circle",t,e,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var r=t.fabric||(t.fabric={});r.Triangle?r.warn("fabric.Triangle is already defined"):(r.Triangle=r.util.createClass(r.Object,{type:"triangle",initialize:function(t){this.callSuper("initialize",t),this.set("width",t&&t.width||100).set("height",t&&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 e=this.width/2,i=this.height/2;t.beginPath(),r.util.drawDashedLine(t,-e,i,0,-i,this.strokeDashArray),r.util.drawDashedLine(t,0,-i,e,i,this.strokeDashArray),r.util.drawDashedLine(t,e,i,-e,i,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("")}}),r.Triangle.fromObject=function(t,e,i){return r.Object._fromObject("Triangle",t,e,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var n=t.fabric||(t.fabric={}),i=2*Math.PI,s=n.util.object.extend;n.Ellipse?n.warn("fabric.Ellipse is already defined."):(n.Ellipse=n.util.createClass(n.Object,{type:"ellipse",rx:0,ry:0,cacheProperties:n.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this.set("rx",t&&t.rx||0),this.set("ry",t&&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 this.callSuper("toObject",["rx","ry"].concat(t))},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)}}),n.Ellipse.ATTRIBUTE_NAMES=n.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),n.Ellipse.fromElement=function(t,e){e||(e={});var i=n.parseAttributes(t,n.Ellipse.ATTRIBUTE_NAMES);i.left=i.left||0,i.top=i.top||0;var r=new n.Ellipse(s(i,e));return r.top-=r.ry,r.left-=r.rx,r},n.Ellipse.fromObject=function(t,e,i){return n.Object._fromObject("Ellipse",t,e,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var s=t.fabric||(t.fabric={}),n=s.util.object.extend;s.Rect?s.warn("fabric.Rect is already defined"):(s.Rect=s.util.createClass(s.Object,{stateProperties:s.Object.prototype.stateProperties.concat("rx","ry"),type:"rect",rx:0,ry:0,cacheProperties:s.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(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){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)}else t.fillRect(-.5,-.5,1,1)},_renderDashedStroke:function(t){var e=-this.width/2,i=-this.height/2,r=this.width,n=this.height;t.beginPath(),s.util.drawDashedLine(t,e,i,e+r,i,this.strokeDashArray),s.util.drawDashedLine(t,e+r,i,e+r,i+n,this.strokeDashArray),s.util.drawDashedLine(t,e+r,i+n,e,i+n,this.strokeDashArray),s.util.drawDashedLine(t,e,i+n,e,i,this.strokeDashArray),t.closePath()},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},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("")}}),s.Rect.ATTRIBUTE_NAMES=s.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),s.Rect.fromElement=function(t,e){if(!t)return null;e=e||{};var i=s.parseAttributes(t,s.Rect.ATTRIBUTE_NAMES);i.left=i.left||0,i.top=i.top||0;var r=new s.Rect(n(e?s.util.object.clone(e):{},i));return r.visible=r.visible&&0\n'),t?t(n.join("")):n.join("")},commonRender:function(t,e){var i,r=this.points.length,n=e?0:this.pathOffset.x,s=e?0:this.pathOffset.y;if(!r||isNaN(this.points[r-1].y))return!1;t.beginPath(),t.moveTo(this.points[0].x-n,this.points[0].y-s);for(var o=0;o"},toObject:function(t){return n(this.callSuper("toObject",["sourcePath","pathOffset"].concat(t)),{path:this.path.map(function(t){return t.slice()}),top:this.top,left:this.left})},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;n\n"),t?t(i.join("")):i.join("")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,n,s=[],o=[],a=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,h=0,c=this.path.length;hd)for(var p=1,v=n.length;p\n");for(var s=0,o=e.length;s\n"),t?t(n.join("")):n.join("")},toString:function(){return"#"},isSameColor:function(){var i=this.getObjects()[0].get("fill")||"";return"string"==typeof i&&(i=i.toLowerCase(),this.getObjects().every(function(t){var e=t.get("fill")||"";return"string"==typeof e&&e.toLowerCase()===i}))},complexity:function(){return this.paths.reduce(function(t,e){return t+(e&&e.complexity?e.complexity():0)},0)},getObjects:function(){return this.paths}}),u.PathGroup.fromObject=function(r,n){var s=r.paths;delete r.paths,"string"==typeof s?u.loadSVGFromURL(s,function(t){var e=s,i=u.util.groupSVGElements(t,r,e);r.paths=s,n(i)}):u.util.enlivenObjects(s,function(t){var e=new u.PathGroup(t,r);r.paths=s,n(e)})},u.PathGroup.async=!0)}("undefined"!=typeof exports?exports:this),function(t){"use strict";var o=t.fabric||(t.fabric={}),e=o.util.object.extend,a=o.util.array.min,h=o.util.array.max;if(!o.Group){var r={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};o.Group=o.util.createClass(o.Object,o.Collection,{type:"group",strokeWidth:0,subTargetCheck:!1,cacheProperties:[],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;e.originX&&(this.originX=e.originX),e.originY&&(this.originY=e.originY),i?(this._updateObjectsCoords(!0),this._updateObjectsACoords()):(this._calcBounds(),this._updateObjectsCoords(),this.callSuper("initialize",e)),this.setCoords(),this.saveCoords()},_updateObjectsACoords:function(){for(var t=this._objects.length;t--;)this._objects[t].setCoords(!0,!0)},_updateObjectsCoords:function(t){for(var e=this.getCenterPoint(),i=this._objects.length;i--;)this._updateObjectCoords(this._objects[i],e,t)},_updateObjectCoords:function(t,e,i){if(t.__origHasControls=t.hasControls,t.hasControls=!1,!i){var r=t.getLeft(),n=t.getTop();t.set({left:r-e.x,top:n-e.y}),t.setCoords(!0,!0)}},toString:function(){return"#"},addWithUpdate:function(t){return this._restoreObjectsState(),o.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.setCoords(),this.dirty=!0,this},_setObjectActive:function(t){t.set("active",!0),t.group=this},removeWithUpdate:function(t){return this._restoreObjectsState(),o.util.resetObjectTransform(this),this.forEachObject(this._setObjectActive,this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},_onObjectAdded:function(t){this.dirty=!0,t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){this.dirty=!0,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(r){var t=this.getObjects().map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=t.group.includeDefaultValues;var i=t.toObject(r);return t.includeDefaultValues=e,i});return e(this.callSuper("toObject",r),{objects:t})},toDatalessObject:function(r){var t=this.getObjects().map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=t.group.includeDefaultValues;var i=t.toDatalessObject(r);return t.includeDefaultValues=e,i});return e(this.callSuper("toDatalessObject",r),{objects:t})},render:function(t){this._transformDone=!0,this.callSuper("render",t),this._transformDone=!1},shouldCache:function(){var t=this.objectCaching&&(!this.group||this.needsItsOwnCache()||!this.group.isCaching());if(this.caching=t)for(var e=0,i=this._objects.length;e\n');for(var i=0,r=this._objects.length;i\n"),t?t(e.join("")):e.join("")},get:function(t){if(t in r){if(this[t])return this[t];for(var e=0,i=this._objects.length;e\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(t){var e=t?this._element:this._originalElement;return e?fabric.isLikelyNode?e._src:e.src:this.src||""},setSrc:function(t,e,i){fabric.util.loadImage(t,function(t){return this.setElement(t,e,i)},this,i&&i.crossOrigin)},toString:function(){return'#'},applyFilters:function(t,e,i,r){if(e=e||this.filters,i=i||this._originalElement){var n,s,o=fabric.util.createImage(),a=this.canvas?this.canvas.getRetinaScaling():fabric.devicePixelRatio,h=this.minimumScaleTrigger/a,c=this;if(0===e.length)return this._element=i,t&&t(this),i;var l=fabric.util.createCanvasElement();return l.width=i.width,l.height=i.height,l.getContext("2d").drawImage(i,0,0,i.width,i.height),e.forEach(function(t){t&&(r?(n=c.scaleX'},_getCacheCanvasDimensions:function(){var t=this.callSuper("_getCacheCanvasDimensions"),e=this.fontSize;return t.width+=e*t.zoomX,t.height+=e*t.zoomY,t},_render:function(t){this._setTextStyles(t),this.group&&"path-group"===this.group.type&&t.translate(this.left,this.top),this._renderTextLinesBackground(t),this._renderText(t),this._renderTextDecoration(t)},_renderText:function(t){this._renderTextFill(t),this._renderTextStroke(t)},_setTextStyles:function(t){t.textBaseline="alphabetic",t.font=this._getFontDeclaration()},_getTextHeight:function(){return this._getHeightOfSingleLine()+(this._textLines.length-1)*this._getHeightOfLine()},_getTextWidth:function(t){for(var e=this._getLineWidth(t,0),i=1,r=this._textLines.length;i\n",e.textBgRects.join(""),'\t\t\n',e.textSpans.join(""),"\t\t\n","\t\n")},getSvgStyles:function(t){return d.Object.prototype.getSvgStyles.call(this,t)+" white-space: pre;"},_getSVGTextAndBg:function(t,e){var i=[],r=[],n=0;this._setSVGBg(r);for(var s=0,o=this._textLines.length;s",d.util.string.escapeXml(this._textLines[t]),"\n"):this._setSVGTextLineJustifed(t,e,s,r)},_setSVGTextLineJustifed:function(t,e,i,r){var n=d.util.createCanvasElement().getContext("2d");this._setTextStyles(n);var s,o,a=this._textLines[t].split(/\s+/),h=this._getWidthOfWords(n,a.join("")),c=this.width-h,l=a.length-1,u=0",d.util.string.escapeXml(s),"\n"),r+=this._getWidthOfWords(n,s)+u},_setSVGTextLineBg:function(t,e,i,r,n){t.push("\t\t\n')},_setSVGBg:function(t){this.backgroundColor&&t.push("\t\t\n')},_getFillAttributes:function(t){var e=t&&"string"==typeof t?new d.Color(t):"";return e&&e.getSource()&&1!==e.getAlpha()?'opacity="'+e.getAlpha()+'" fill="'+e.setAlpha(1).toRgb()+'"':'fill="'+t+'"'},_set:function(t,e){this.callSuper("_set",t,e),-1=r.charIndex&&(a!==o||dthis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=e):(this.selectionStart=e,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this.restartCursorIfNeeded(),this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}},_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.cursorOffsetCache={},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.left,this.hiddenTextarea.style.top=t.top,this.hiddenTextarea.style.fontSize=t.fontSize}},_calcTextareaPosition:function(){if(!this.canvas)return{x:1,y:1};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=e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s},c=this.canvas.upperCanvasEl,l=c.width-s,u=c.height-s;return h=fabric.util.transformPoint(h,a),(h=fabric.util.transformPoint(h,this.canvas.viewportTransform)).x<0&&(h.x=0),h.x>l&&(h.x=l),h.y<0&&(h.y=0),h.y>u&&(h.y=u),h.x+=this.canvas._offset.left,h.y+=this.canvas._offset.top,{left:h.x+"px",top:h.y+"px",fontSize:s}},_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(){var t=this._textBeforeEdit!==this.text;return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&(this.hiddenTextarea.blur&&this.hiddenTextarea.blur(),this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null),this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.off("mouse:move",this.mouseMoveHandler),this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{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.selectionStart=t,this.selectionEnd=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(1t?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),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,t.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.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&&(!t.e.button||1===t.e.button)){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())}})},_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)||t.e.button&&1!==t.e.button||(this.__lastSelected&&!this.__corner&&(this.enterEditing(t.e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()),this.selected=!0)})},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t),i=this.selectionStart,r=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(i,r,e):(this.selectionStart=e,this.selectionEnd=e),this.isEditing&&(this._fireSelectionChanged(),this._updateTextarea())},getSelectionStartFromPointer:function(t){for(var e,i=this.getLocalPointer(t),r=0,n=0,s=0,o=0,a=0,h=this._textLines.length;athis.text.length&&(s=this.text.length),s}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.setAttribute("autocorrect","off"),this.hiddenTextarea.setAttribute("autocomplete","off"),this.hiddenTextarea.setAttribute("spellcheck","false"),this.hiddenTextarea.setAttribute("data-fabric-hiddentextarea",""),this.hiddenTextarea.setAttribute("wrap","off");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="position: absolute; top: "+t.top+"; left: "+t.left+"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; line-height: 1px; paddingーtop: "+t.fontSize+";",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"},ctrlKeysMapUp:{67:"copy",88:"cut"},ctrlKeysMapDown:{65:"selectAll"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing){if(t.keyCode in this.keysMap)this[this.keysMap[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),33<=t.keyCode&&t.keyCode<=40?(this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.renderAll()}},onKeyUp:function(t){this.isEditing&&!this._copyDone?t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()):this._copyDone=!1},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;i=o=this.text.length&&this.selectionEnd>=this.text.length||this._moveCursorUpOrDown("Down",t)},moveCursorUp:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)},_moveCursorUpOrDown:function(t,e){var i=this["get"+t+"CursorOffset"](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(i):this.moveCursorWithoutShift(i),0!==i&&(this.setSelectionInBoundaries(),this.abortCursorAnimation(),this._currentCursorOpacity=1,this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorWithShift:function(t){var e="left"===this._selectionDirection?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t},moveCursorWithoutShift:function(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t},moveCursorLeft:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)},_move:function(t,e,i){var r;if(t.altKey)r=this["findWordBoundary"+i](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;r=this["findLineBoundary"+i](this[e])}if(this[e]!==r)return this[e]=r,!0},_moveLeft:function(t,e){return this._move(t,e,"Left")},_moveRight:function(t,e){return this._move(t,e,"Right")},moveCursorLeftWithoutShift:function(t){var e=!0;return this._selectionDirection="left",this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e},moveCursorLeftWithShift:function(t){return"right"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection="left",this._moveLeft(t,"selectionStart")):void 0},moveCursorRight:function(t){this.selectionStart>=this.text.length&&this.selectionEnd>=this.text.length||this._moveCursorLeftOrRight("Right",t)},_moveCursorLeftOrRight:function(t,e){var i="moveCursor"+t+"With";this._currentCursorOpacity=1,e.shiftKey?i+="Shift":i+="outShift",this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorRightWithShift:function(t){return"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this.text.length?(this._selectionDirection="right",this._moveRight(t,"selectionEnd")):void 0},moveCursorRightWithoutShift:function(t){var e=!0;return this._selectionDirection="right",this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e},removeChars:function(t){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.set("dirty",!0),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 o=fabric.util.toFixed,a=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;l\n'].join("")},_createTextCharSpan:function(t,e,i,r,n){var s=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},e));return['\t\t\t',fabric.util.string.escapeXml(t),"\n"].join("")}})}(),function(t){"use strict";var r=t.fabric||(t.fabric={});r.Textbox=r.util.createClass(r.IText,r.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:2,__cachedLines:null,lockScalingY:!0,lockScalingFlip:!0,noScaleCache:!1,_dimensionAffectingProps:r.Text.prototype._dimensionAffectingProps.concat("width"),initialize:function(t,e){this.callSuper("initialize",t,e),this.setControlsVisibility(r.Textbox.getTextboxControlVisibility()),this.ctx=this.objectCaching?this._cacheContext:r.util.createCanvasElement().getContext("2d")},_initDimensions:function(t){this.__skipDimension||(t||(t=r.util.createCanvasElement().getContext("2d"),this._setTextStyles(t),this.clearContextTop()),this.dynamicMinWidth=0,this._textLines=this._splitTextIntoLines(t),this.dynamicMinWidth>this.width&&this._set("width",this.dynamicMinWidth),this._clearCache(),this.height=this._getTextHeight(t),this.setCoords())},_generateStyleMap:function(){for(var t=0,e=0,i=0,r={},n=0;n=this.width&&!f?(n.push(s),r=c,f=!(s="")):r+=d,f||(s+=" "),s+=a,l=this._measureText(t," ",i,h),h++,f=!1,uthis.dynamicMinWidth&&(this.dynamicMinWidth=u-d),n},_splitTextIntoLines:function(t){t=t||this.ctx;var e=this.textAlign;this._styleMap=null,t.save(),this._setTextStyles(t),this.textAlign="left";var i=this._wrapText(t,this.text);return this.textAlign=e,t.restore(),this._textLines=i,this._styleMap=this._generateStyleMap(),i},setOnGroup:function(t,e){"scaleX"===t&&(this.set("scaleX",Math.abs(1/e)),this.set("width",this.get("width")*e/(void 0===this.__oldScaleX?1:this.__oldScaleX)),this.__oldScaleX=e)},get2DCursorLocation:function(t){void 0===t&&(t=this.selectionStart);for(var e=this._textLines.length,i=0,r=0;r=a.getMinWidth()?(a.set("width",h),!0):void 0},fabric.Group.prototype._refreshControlsVisibility=function(){if(void 0!==fabric.Textbox)for(var t=this._objects.length;t--;)if(this._objects[t]instanceof fabric.Textbox)return void this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility())},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,e){t=this._styleMap[t].line,fabric.IText.prototype.shiftLineStyles.call(this,t,e)},_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 h=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(t,e,i,r,n){r=h.call(this,t,e,i,r,n);for(var s=0,o=0,a=0;a event handler)\n if (arguments.length === 0) {\n for (eventName in this.__eventListeners) {\n _removeEventListener.call(this, eventName);\n }\n }\n // one object with key/value pairs was passed\n else if (arguments.length === 1 && typeof arguments[0] === 'object') {\n for (var prop in eventName) {\n _removeEventListener.call(this, prop, eventName[prop]);\n }\n }\n else {\n _removeEventListener.call(this, eventName, handler);\n }\n return this;\n }\n\n /**\n * Fires event with an optional options object\n * @deprecated `fire` deprecated since 1.0.7 (use `trigger` instead)\n * @memberOf fabric.Observable\n * @alias trigger\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n * @return {Self} thisArg\n * @chainable\n */\n function fire(eventName, options) {\n if (!this.__eventListeners) {\n return;\n }\n\n var listenersForEvent = this.__eventListeners[eventName];\n if (!listenersForEvent) {\n return;\n }\n\n for (var i = 0, len = listenersForEvent.length; i < len; i++) {\n listenersForEvent[i] && listenersForEvent[i].call(this, options || { });\n }\n this.__eventListeners[eventName] = listenersForEvent.filter(function(value) {\n return value !== false;\n });\n return this;\n }\n\n /**\n * @namespace fabric.Observable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n * @see {@link http://fabricjs.com/events|Events demo}\n */\n fabric.Observable = {\n observe: observe,\n stopObserving: stopObserving,\n fire: fire,\n\n on: observe,\n off: stopObserving,\n trigger: fire\n };\n})();\n\n\n/**\n * @namespace fabric.Collection\n */\nfabric.Collection = {\n\n _objects: [],\n\n /**\n * Adds objects to collection, Canvas or Group, then renders canvas\n * (if `renderOnAddRemove` is not `false`).\n * in case of Group no changes to bounding box are made.\n * Objects should be instances of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the add method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n add: function () {\n this._objects.push.apply(this._objects, arguments);\n if (this._onObjectAdded) {\n for (var i = 0, length = arguments.length; i < length; i++) {\n this._onObjectAdded(arguments[i]);\n }\n }\n this.renderOnAddRemove && this.renderAll();\n return this;\n },\n\n /**\n * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`)\n * An object should be an instance of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the insertAt method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {Object} object Object to insert\n * @param {Number} index Index to insert object at\n * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs\n * @return {Self} thisArg\n * @chainable\n */\n insertAt: function (object, index, nonSplicing) {\n var objects = this.getObjects();\n if (nonSplicing) {\n objects[index] = object;\n }\n else {\n objects.splice(index, 0, object);\n }\n this._onObjectAdded && this._onObjectAdded(object);\n this.renderOnAddRemove && this.renderAll();\n return this;\n },\n\n /**\n * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n remove: function() {\n var objects = this.getObjects(),\n index, somethingRemoved = false;\n\n for (var i = 0, length = arguments.length; i < length; i++) {\n index = objects.indexOf(arguments[i]);\n\n // only call onObjectRemoved if an object was actually removed\n if (index !== -1) {\n somethingRemoved = true;\n objects.splice(index, 1);\n this._onObjectRemoved && this._onObjectRemoved(arguments[i]);\n }\n }\n\n this.renderOnAddRemove && somethingRemoved && this.renderAll();\n return this;\n },\n\n /**\n * Executes given function for each object in this group\n * @param {Function} callback\n * Callback invoked with current object as first argument,\n * index - as second and an array of all objects - as third.\n * Callback is invoked in a context of Global Object (e.g. `window`)\n * when no `context` argument is given\n *\n * @param {Object} context Context (aka thisObject)\n * @return {Self} thisArg\n * @chainable\n */\n forEachObject: function(callback, context) {\n var objects = this.getObjects();\n for (var i = 0, len = objects.length; i < len; i++) {\n callback.call(context, objects[i], i, objects);\n }\n return this;\n },\n\n /**\n * Returns an array of children objects of this instance\n * Type parameter introduced in 1.3.10\n * @param {String} [type] When specified, only objects of this type are returned\n * @return {Array}\n */\n getObjects: function(type) {\n if (typeof type === 'undefined') {\n return this._objects;\n }\n return this._objects.filter(function(o) {\n return o.type === type;\n });\n },\n\n /**\n * Returns object at specified index\n * @param {Number} index\n * @return {Self} thisArg\n */\n item: function (index) {\n return this.getObjects()[index];\n },\n\n /**\n * Returns true if collection contains no objects\n * @return {Boolean} true if collection is empty\n */\n isEmpty: function () {\n return this.getObjects().length === 0;\n },\n\n /**\n * Returns a size of a collection (i.e: length of an array containing its objects)\n * @return {Number} Collection size\n */\n size: function() {\n return this.getObjects().length;\n },\n\n /**\n * Returns true if collection contains an object\n * @param {Object} object Object to check against\n * @return {Boolean} `true` if collection contains an object\n */\n contains: function(object) {\n return this.getObjects().indexOf(object) > -1;\n },\n\n /**\n * Returns number representation of a collection complexity\n * @return {Number} complexity\n */\n complexity: function () {\n return this.getObjects().reduce(function (memo, current) {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n};\n\n\n/**\n * @namespace fabric.CommonMethods\n */\nfabric.CommonMethods = {\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n _setOptions: function(options) {\n for (var prop in options) {\n this.set(prop, options[prop]);\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Gradient to\n */\n _initGradient: function(filler, property) {\n if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) {\n this.set(property, new fabric.Gradient(filler));\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Pattern to\n * @param {Function} [callback] callback to invoke after pattern load\n */\n _initPattern: function(filler, property, callback) {\n if (filler && filler.source && !(filler instanceof fabric.Pattern)) {\n this.set(property, new fabric.Pattern(filler, callback));\n }\n else {\n callback && callback();\n }\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initClipping: function(options) {\n if (!options.clipTo || typeof options.clipTo !== 'string') {\n return;\n }\n\n var functionBody = fabric.util.getFunctionBody(options.clipTo);\n if (typeof functionBody !== 'undefined') {\n this.clipTo = new Function('ctx', functionBody);\n }\n },\n\n /**\n * @private\n */\n _setObject: function(obj) {\n for (var prop in obj) {\n this._set(prop, obj[prop]);\n }\n },\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n set: function(key, value) {\n if (typeof key === 'object') {\n this._setObject(key);\n }\n else {\n if (typeof value === 'function' && key !== 'clipTo') {\n this._set(key, value(this.get(key)));\n }\n else {\n this._set(key, value);\n }\n }\n return this;\n },\n\n _set: function(key, value) {\n this[key] = value;\n },\n\n /**\n * Toggles specified property from `true` to `false` or from `false` to `true`\n * @param {String} property Property to toggle\n * @return {fabric.Object} thisArg\n * @chainable\n */\n toggle: function(property) {\n var value = this.get(property);\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\n return this;\n },\n\n /**\n * Basic getter\n * @param {String} property Property name\n * @return {*} value of a property\n */\n get: function(property) {\n return this[property];\n }\n};\n\n\n(function(global) {\n\n var sqrt = Math.sqrt,\n atan2 = Math.atan2,\n pow = Math.pow,\n abs = Math.abs,\n PiBy180 = Math.PI / 180;\n\n /**\n * @namespace fabric.util\n */\n fabric.util = {\n\n /**\n * Removes value from an array.\n * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n * @static\n * @memberOf fabric.util\n * @param {Array} array\n * @param {*} value\n * @return {Array} original array\n */\n removeFromArray: function(array, value) {\n var idx = array.indexOf(value);\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n return array;\n },\n\n /**\n * Returns random number between 2 specified ones.\n * @static\n * @memberOf fabric.util\n * @param {Number} min lower limit\n * @param {Number} max upper limit\n * @return {Number} random value (between min and max)\n */\n getRandomInt: function(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n },\n\n /**\n * Transforms degrees to radians.\n * @static\n * @memberOf fabric.util\n * @param {Number} degrees value in degrees\n * @return {Number} value in radians\n */\n degreesToRadians: function(degrees) {\n return degrees * PiBy180;\n },\n\n /**\n * Transforms radians to degrees.\n * @static\n * @memberOf fabric.util\n * @param {Number} radians value in radians\n * @return {Number} value in degrees\n */\n radiansToDegrees: function(radians) {\n return radians / PiBy180;\n },\n\n /**\n * Rotates `point` around `origin` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} point The point to rotate\n * @param {fabric.Point} origin The origin of the rotation\n * @param {Number} radians The radians of the angle for the rotation\n * @return {fabric.Point} The new rotated point\n */\n rotatePoint: function(point, origin, radians) {\n point.subtractEquals(origin);\n var v = fabric.util.rotateVector(point, radians);\n return new fabric.Point(v.x, v.y).addEquals(origin);\n },\n\n /**\n * Rotates `vector` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {Object} vector The vector to rotate (x and y)\n * @param {Number} radians The radians of the angle for the rotation\n * @return {Object} The new rotated point\n */\n rotateVector: function(vector, radians) {\n var sin = Math.sin(radians),\n cos = Math.cos(radians),\n rx = vector.x * cos - vector.y * sin,\n ry = vector.x * sin + vector.y * cos;\n return {\n x: rx,\n y: ry\n };\n },\n\n /**\n * Apply transform t to point p\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} p The point to transform\n * @param {Array} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {fabric.Point} The transformed point\n */\n transformPoint: function(p, t, ignoreOffset) {\n if (ignoreOffset) {\n return new fabric.Point(\n t[0] * p.x + t[2] * p.y,\n t[1] * p.x + t[3] * p.y\n );\n }\n return new fabric.Point(\n t[0] * p.x + t[2] * p.y + t[4],\n t[1] * p.x + t[3] * p.y + t[5]\n );\n },\n\n /**\n * Returns coordinates of points's bounding rectangle (left, top, width, height)\n * @param {Array} points 4 points array\n * @return {Object} Object with left, top, width, height properties\n */\n makeBoundingBoxFromPoints: function(points) {\n var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x],\n minX = fabric.util.array.min(xPoints),\n maxX = fabric.util.array.max(xPoints),\n width = Math.abs(minX - maxX),\n yPoints = [points[0].y, points[1].y, points[2].y, points[3].y],\n minY = fabric.util.array.min(yPoints),\n maxY = fabric.util.array.max(yPoints),\n height = Math.abs(minY - maxY);\n\n return {\n left: minX,\n top: minY,\n width: width,\n height: height\n };\n },\n\n /**\n * Invert transformation t\n * @static\n * @memberOf fabric.util\n * @param {Array} t The transform\n * @return {Array} The inverted transform\n */\n invertTransform: function(t) {\n var a = 1 / (t[0] * t[3] - t[1] * t[2]),\n r = [a * t[3], -a * t[1], -a * t[2], a * t[0]],\n o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r, true);\n r[4] = -o.x;\n r[5] = -o.y;\n return r;\n },\n\n /**\n * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n * @static\n * @memberOf fabric.util\n * @param {Number|String} number number to operate on\n * @param {Number} fractionDigits number of fraction digits to \"leave\"\n * @return {Number}\n */\n toFixed: function(number, fractionDigits) {\n return parseFloat(Number(number).toFixed(fractionDigits));\n },\n\n /**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {Number|String} value number to operate on\n * @param {Number} fontSize\n * @return {Number|String}\n */\n parseUnit: function(value, fontSize) {\n var unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n if (!fontSize) {\n fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n switch (unit[0]) {\n case 'mm':\n return number * fabric.DPI / 25.4;\n\n case 'cm':\n return number * fabric.DPI / 2.54;\n\n case 'in':\n return number * fabric.DPI;\n\n case 'pt':\n return number * fabric.DPI / 72; // or * 4 / 3\n\n case 'pc':\n return number * fabric.DPI / 72 * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n },\n\n /**\n * Function which always returns `false`.\n * @static\n * @memberOf fabric.util\n * @return {Boolean}\n */\n falseFunction: function() {\n return false;\n },\n\n /**\n * Returns klass \"Class\" object of given namespace\n * @memberOf fabric.util\n * @param {String} type Type of object (eg. 'circle')\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @return {Object} klass \"Class\"\n */\n getKlass: function(type, namespace) {\n // capitalize first letter only\n type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1));\n return fabric.util.resolveNamespace(namespace)[type];\n },\n\n /**\n * Returns object of given namespace\n * @memberOf fabric.util\n * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric'\n * @return {Object} Object for given namespace (default fabric)\n */\n resolveNamespace: function(namespace) {\n if (!namespace) {\n return fabric;\n }\n\n var parts = namespace.split('.'),\n len = parts.length, i,\n obj = global || fabric.window;\n\n for (i = 0; i < len; ++i) {\n obj = obj[parts[i]];\n }\n\n return obj;\n },\n\n /**\n * Loads image element from given url and passes it to a callback\n * @memberOf fabric.util\n * @param {String} url URL representing an image\n * @param {Function} callback Callback; invoked with loaded image\n * @param {*} [context] Context to invoke callback in\n * @param {Object} [crossOrigin] crossOrigin value to set image element to\n */\n loadImage: function(url, callback, context, crossOrigin) {\n if (!url) {\n callback && callback.call(context, url);\n return;\n }\n\n var img = fabric.util.createImage();\n\n /** @ignore */\n img.onload = function () {\n callback && callback.call(context, img);\n img = img.onload = img.onerror = null;\n };\n\n /** @ignore */\n img.onerror = function() {\n fabric.log('Error loading ' + img.src);\n callback && callback.call(context, null, true);\n img = img.onload = img.onerror = null;\n };\n\n // data-urls appear to be buggy with crossOrigin\n // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767\n // see https://code.google.com/p/chromium/issues/detail?id=315152\n // https://bugzilla.mozilla.org/show_bug.cgi?id=935069\n if (url.indexOf('data') !== 0 && crossOrigin) {\n img.crossOrigin = crossOrigin;\n }\n\n img.src = url;\n },\n\n /**\n * Creates corresponding fabric instances from their object representations\n * @static\n * @memberOf fabric.util\n * @param {Array} objects Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @param {Function} reviver Method for further parsing of object elements,\n * called after each fabric object created.\n */\n enlivenObjects: function(objects, callback, namespace, reviver) {\n objects = objects || [];\n\n function onLoaded() {\n if (++numLoadedObjects === numTotalObjects) {\n callback && callback(enlivenedObjects);\n }\n }\n\n var enlivenedObjects = [],\n numLoadedObjects = 0,\n numTotalObjects = objects.length,\n forceAsync = true;\n\n if (!numTotalObjects) {\n callback && callback(enlivenedObjects);\n return;\n }\n\n objects.forEach(function (o, index) {\n // if sparse array\n if (!o || !o.type) {\n onLoaded();\n return;\n }\n var klass = fabric.util.getKlass(o.type, namespace);\n klass.fromObject(o, function (obj, error) {\n error || (enlivenedObjects[index] = obj);\n reviver && reviver(o, obj, error);\n onLoaded();\n }, forceAsync);\n });\n },\n\n /**\n * Create and wait for loading of patterns\n * @static\n * @memberOf fabric.util\n * @param {Array} objects Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @param {Function} reviver Method for further parsing of object elements,\n * called after each fabric object created.\n */\n enlivenPatterns: function(patterns, callback) {\n patterns = patterns || [];\n\n function onLoaded() {\n if (++numLoadedPatterns === numPatterns) {\n callback && callback(enlivenedPatterns);\n }\n }\n\n var enlivenedPatterns = [],\n numLoadedPatterns = 0,\n numPatterns = patterns.length;\n\n if (!numPatterns) {\n callback && callback(enlivenedPatterns);\n return;\n }\n\n patterns.forEach(function (p, index) {\n if (p && p.source) {\n new fabric.Pattern(p, function(pattern) {\n enlivenedPatterns[index] = pattern;\n onLoaded();\n });\n }\n else {\n enlivenedPatterns[index] = p;\n onLoaded();\n }\n });\n },\n\n /**\n * Groups SVG elements (usually those retrieved from SVG document)\n * @static\n * @memberOf fabric.util\n * @param {Array} elements SVG elements to group\n * @param {Object} [options] Options object\n * @param {String} path Value to set sourcePath to\n * @return {fabric.Object|fabric.PathGroup}\n */\n groupSVGElements: function(elements, options, path) {\n var object;\n\n object = new fabric.PathGroup(elements, options);\n\n if (typeof path !== 'undefined') {\n object.sourcePath = path;\n }\n return object;\n },\n\n /**\n * Populates an object with properties of another object\n * @static\n * @memberOf fabric.util\n * @param {Object} source Source object\n * @param {Object} destination Destination object\n * @return {Array} properties Propertie names to include\n */\n populateWithProperties: function(source, destination, properties) {\n if (properties && Object.prototype.toString.call(properties) === '[object Array]') {\n for (var i = 0, len = properties.length; i < len; i++) {\n if (properties[i] in source) {\n destination[properties[i]] = source[properties[i]];\n }\n }\n }\n },\n\n /**\n * Draws a dashed line between two points\n *\n * This method is used to draw dashed line around selection area.\n * See dotted stroke in canvas\n *\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x start x coordinate\n * @param {Number} y start y coordinate\n * @param {Number} x2 end x coordinate\n * @param {Number} y2 end y coordinate\n * @param {Array} da dash array pattern\n */\n drawDashedLine: function(ctx, x, y, x2, y2, da) {\n var dx = x2 - x,\n dy = y2 - y,\n len = sqrt(dx * dx + dy * dy),\n rot = atan2(dy, dx),\n dc = da.length,\n di = 0,\n draw = true;\n\n ctx.save();\n ctx.translate(x, y);\n ctx.moveTo(0, 0);\n ctx.rotate(rot);\n\n x = 0;\n while (len > x) {\n x += da[di++ % dc];\n if (x > len) {\n x = len;\n }\n ctx[draw ? 'lineTo' : 'moveTo'](x, 0);\n draw = !draw;\n }\n\n ctx.restore();\n },\n\n /**\n * Creates canvas element and initializes it via excanvas if necessary\n * @static\n * @memberOf fabric.util\n * @param {CanvasElement} [canvasEl] optional canvas element to initialize;\n * when not given, element is created implicitly\n * @return {CanvasElement} initialized canvas element\n */\n createCanvasElement: function(canvasEl) {\n canvasEl || (canvasEl = fabric.document.createElement('canvas'));\n /* eslint-disable camelcase */\n if (!canvasEl.getContext && typeof G_vmlCanvasManager !== 'undefined') {\n G_vmlCanvasManager.initElement(canvasEl);\n }\n /* eslint-enable camelcase */\n return canvasEl;\n },\n\n /**\n * Creates image element (works on client and node)\n * @static\n * @memberOf fabric.util\n * @return {HTMLImageElement} HTML image element\n */\n createImage: function() {\n return fabric.isLikelyNode\n ? new (require('canvas').Image)()\n : fabric.document.createElement('img');\n },\n\n /**\n * Creates accessors (getXXX, setXXX) for a \"class\", based on \"stateProperties\" array\n * @static\n * @memberOf fabric.util\n * @param {Object} klass \"Class\" to create accessors for\n */\n createAccessors: function(klass) {\n var proto = klass.prototype, i, propName,\n capitalizedPropName, setterName, getterName;\n\n for (i = proto.stateProperties.length; i--; ) {\n\n propName = proto.stateProperties[i];\n capitalizedPropName = propName.charAt(0).toUpperCase() + propName.slice(1);\n setterName = 'set' + capitalizedPropName;\n getterName = 'get' + capitalizedPropName;\n\n // using `new Function` for better introspection\n if (!proto[getterName]) {\n proto[getterName] = (function(property) {\n return new Function('return this.get(\"' + property + '\")');\n })(propName);\n }\n if (!proto[setterName]) {\n proto[setterName] = (function(property) {\n return new Function('value', 'return this.set(\"' + property + '\", value)');\n })(propName);\n }\n }\n },\n\n /**\n * @static\n * @memberOf fabric.util\n * @param {fabric.Object} receiver Object implementing `clipTo` method\n * @param {CanvasRenderingContext2D} ctx Context to clip\n */\n clipContext: function(receiver, ctx) {\n ctx.save();\n ctx.beginPath();\n receiver.clipTo(ctx);\n ctx.clip();\n },\n\n /**\n * Multiply matrix A by matrix B to nest transformations\n * @static\n * @memberOf fabric.util\n * @param {Array} a First transformMatrix\n * @param {Array} b Second transformMatrix\n * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n * @return {Array} The product of the two transform matrices\n */\n multiplyTransformMatrices: function(a, b, is2x2) {\n // Matrix multiply a * b\n return [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]\n ];\n },\n\n /**\n * Decomposes standard 2x2 matrix into transform componentes\n * @static\n * @memberOf fabric.util\n * @param {Array} a transformMatrix\n * @return {Object} Components of transform\n */\n qrDecompose: function(a) {\n var angle = atan2(a[1], a[0]),\n denom = pow(a[0], 2) + pow(a[1], 2),\n scaleX = sqrt(denom),\n scaleY = (a[0] * a[3] - a[2] * a [1]) / scaleX,\n skewX = atan2(a[0] * a[2] + a[1] * a [3], denom);\n return {\n angle: angle / PiBy180,\n scaleX: scaleX,\n scaleY: scaleY,\n skewX: skewX / PiBy180,\n skewY: 0,\n translateX: a[4],\n translateY: a[5]\n };\n },\n\n customTransformMatrix: function(scaleX, scaleY, skewX) {\n var skewMatrixX = [1, 0, abs(Math.tan(skewX * PiBy180)), 1],\n scaleMatrix = [abs(scaleX), 0, 0, abs(scaleY)];\n return fabric.util.multiplyTransformMatrices(scaleMatrix, skewMatrixX, true);\n },\n\n resetObjectTransform: function (target) {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.flipX = false;\n target.flipY = false;\n target.setAngle(0);\n },\n\n /**\n * Returns string representation of function body\n * @param {Function} fn Function to get body of\n * @return {String} Function body\n */\n getFunctionBody: function(fn) {\n return (String(fn).match(/function[^{]*\\{([\\s\\S]*)\\}/) || {})[1];\n },\n\n /**\n * Returns true if context has transparent pixel\n * at specified location (taking tolerance into account)\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x x coordinate\n * @param {Number} y y coordinate\n * @param {Number} tolerance Tolerance\n */\n isTransparent: function(ctx, x, y, tolerance) {\n\n // If tolerance is > 0 adjust start coords to take into account.\n // If moves off Canvas fix to 0\n if (tolerance > 0) {\n if (x > tolerance) {\n x -= tolerance;\n }\n else {\n x = 0;\n }\n if (y > tolerance) {\n y -= tolerance;\n }\n else {\n y = 0;\n }\n }\n\n var _isTransparent = true, i, temp,\n imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1),\n l = imageData.data.length;\n\n // Split image data - for tolerance > 1, pixelDataSize = 4;\n for (i = 3; i < l; i += 4) {\n temp = imageData.data[i];\n _isTransparent = temp <= 0;\n if (_isTransparent === false) {\n break; // Stop if colour found\n }\n }\n\n imageData = null;\n\n return _isTransparent;\n },\n\n /**\n * Parse preserveAspectRatio attribute from element\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\n parsePreserveAspectRatioAttribute: function(attribute) {\n var meetOrSlice = 'meet', alignX = 'Mid', alignY = 'Mid',\n aspectRatioAttrs = attribute.split(' '), align;\n\n if (aspectRatioAttrs && aspectRatioAttrs.length) {\n meetOrSlice = aspectRatioAttrs.pop();\n if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') {\n align = meetOrSlice;\n meetOrSlice = 'meet';\n }\n else if (aspectRatioAttrs.length) {\n align = aspectRatioAttrs.pop();\n }\n }\n //divide align in alignX and alignY\n alignX = align !== 'none' ? align.slice(1, 4) : 'none';\n alignY = align !== 'none' ? align.slice(5, 8) : 'none';\n return {\n meetOrSlice: meetOrSlice,\n alignX: alignX,\n alignY: alignY\n };\n },\n\n /**\n * Clear char widths cache for a font family.\n * @memberOf fabric.util\n * @param {String} [fontFamily] font family to clear\n */\n clearFabricFontCache: function(fontFamily) {\n if (!fontFamily) {\n fabric.charWidthsCache = { };\n }\n else if (fabric.charWidthsCache[fontFamily]) {\n delete fabric.charWidthsCache[fontFamily];\n }\n },\n\n /**\n * Clear char widths cache for a font family.\n * @memberOf fabric.util\n * @param {Number} ar aspect ratio\n * @param {Number} maximumArea Maximum area you want to achieve\n * @param {Number} maximumSide biggest side allowed\n * @return {Object.x} Limited dimensions by X\n * @return {Object.y} Limited dimensions by Y\n */\n limitDimsByArea: function(ar, maximumArea) {\n var roughWidth = Math.sqrt(maximumArea * ar),\n perfLimitSizeY = Math.floor(maximumArea / roughWidth);\n return { x: Math.floor(roughWidth), y: perfLimitSizeY };\n },\n\n capValue: function(min, value, max) {\n return Math.max(min, Math.min(value, max));\n }\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var arcToSegmentsCache = { },\n segmentToBezierCache = { },\n boundsOfCurveCache = { },\n _join = Array.prototype.join;\n\n /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n */\n function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {\n var argsString = _join.call(arguments);\n if (arcToSegmentsCache[argsString]) {\n return arcToSegmentsCache[argsString];\n }\n\n var PI = Math.PI, th = rotateX * PI / 180,\n sinTh = Math.sin(th),\n cosTh = Math.cos(th),\n fromX = 0, fromY = 0;\n\n rx = Math.abs(rx);\n ry = Math.abs(ry);\n\n var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5,\n py = -cosTh * toY * 0.5 + sinTh * toX * 0.5,\n rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2,\n root = 0;\n\n if (pl < 0) {\n var s = Math.sqrt(1 - pl / (rx2 * ry2));\n rx *= s;\n ry *= s;\n }\n else {\n root = (large === sweep ? -1.0 : 1.0) *\n Math.sqrt( pl / (rx2 * py2 + ry2 * px2));\n }\n\n var cx = root * rx * py / ry,\n cy = -root * ry * px / rx,\n cx1 = cosTh * cx - sinTh * cy + toX * 0.5,\n cy1 = sinTh * cx + cosTh * cy + toY * 0.5,\n mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),\n dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry);\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n }\n else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n var segments = Math.ceil(Math.abs(dtheta / PI * 2)),\n result = [], mDelta = dtheta / segments,\n mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),\n th3 = mTheta + mDelta;\n\n for (var i = 0; i < segments; i++) {\n result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);\n fromX = result[i][4];\n fromY = result[i][5];\n mTheta = th3;\n th3 += mDelta;\n }\n arcToSegmentsCache[argsString] = result;\n return result;\n }\n\n function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {\n var argsString2 = _join.call(arguments);\n if (segmentToBezierCache[argsString2]) {\n return segmentToBezierCache[argsString2];\n }\n\n var costh2 = Math.cos(th2),\n sinth2 = Math.sin(th2),\n costh3 = Math.cos(th3),\n sinth3 = Math.sin(th3),\n toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1,\n toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1,\n cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2),\n cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2),\n cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),\n cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);\n\n segmentToBezierCache[argsString2] = [\n cp1X, cp1Y,\n cp2X, cp2Y,\n toX, toY\n ];\n return segmentToBezierCache[argsString2];\n }\n\n /*\n * Private\n */\n function calcVectorAngle(ux, uy, vx, vy) {\n var ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n }\n else {\n return 2 * Math.PI - (ta - tb);\n }\n }\n\n /**\n * Draws arc\n * @param {CanvasRenderingContext2D} ctx\n * @param {Number} fx\n * @param {Number} fy\n * @param {Array} coords\n */\n fabric.util.drawArc = function(ctx, fx, fy, coords) {\n var rx = coords[0],\n ry = coords[1],\n rot = coords[2],\n large = coords[3],\n sweep = coords[4],\n tx = coords[5],\n ty = coords[6],\n segs = [[], [], [], []],\n segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segsNorm.length; i < len; i++) {\n segs[i][0] = segsNorm[i][0] + fx;\n segs[i][1] = segsNorm[i][1] + fy;\n segs[i][2] = segsNorm[i][2] + fx;\n segs[i][3] = segsNorm[i][3] + fy;\n segs[i][4] = segsNorm[i][4] + fx;\n segs[i][5] = segsNorm[i][5] + fy;\n ctx.bezierCurveTo.apply(ctx, segs[i]);\n }\n };\n\n /**\n * Calculate bounding box of a elliptic-arc\n * @param {Number} fx start point of arc\n * @param {Number} fy\n * @param {Number} rx horizontal radius\n * @param {Number} ry vertical radius\n * @param {Number} rot angle of horizontal axe\n * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points\n * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction\n * @param {Number} tx end point of arc\n * @param {Number} ty\n */\n fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) {\n\n var fromX = 0, fromY = 0, bound, bounds = [],\n segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segs.length; i < len; i++) {\n bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]);\n bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy });\n bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy });\n fromX = segs[i][4];\n fromY = segs[i][5];\n }\n return bounds;\n };\n\n /**\n * Calculate bounding box of a beziercurve\n * @param {Number} x0 starting point\n * @param {Number} y0\n * @param {Number} x1 first control point\n * @param {Number} y1\n * @param {Number} x2 secondo control point\n * @param {Number} y2\n * @param {Number} x3 end of beizer\n * @param {Number} y3\n */\n // taken from http://jsbin.com/ivomiq/56/edit no credits available for that.\n function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {\n var argsString = _join.call(arguments);\n if (boundsOfCurveCache[argsString]) {\n return boundsOfCurveCache[argsString];\n }\n\n var sqrt = Math.sqrt,\n min = Math.min, max = Math.max,\n abs = Math.abs, tvalues = [],\n bounds = [[], []],\n a, b, c, t, t1, t2, b2ac, sqrtb2ac;\n\n b = 6 * x0 - 12 * x1 + 6 * x2;\n a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n c = 3 * x1 - 3 * x0;\n\n for (var i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * y0 - 12 * y1 + 6 * y2;\n a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n c = 3 * y1 - 3 * y0;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n sqrtb2ac = sqrt(b2ac);\n t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n var x, y, j = tvalues.length, jlen = j, mt;\n while (j--) {\n t = tvalues[j];\n mt = 1 - t;\n x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);\n bounds[0][j] = x;\n\n y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = x0;\n bounds[1][jlen] = y0;\n bounds[0][jlen + 1] = x3;\n bounds[1][jlen + 1] = y3;\n var result = [\n {\n x: min.apply(null, bounds[0]),\n y: min.apply(null, bounds[1])\n },\n {\n x: max.apply(null, bounds[0]),\n y: max.apply(null, bounds[1])\n }\n ];\n boundsOfCurveCache[argsString] = result;\n return result;\n }\n\n fabric.util.getBoundsOfCurve = getBoundsOfCurve;\n\n})();\n\n\n(function() {\n\n var slice = Array.prototype.slice;\n\n /* _ES5_COMPAT_START_ */\n\n if (!Array.prototype.indexOf) {\n /**\n * Finds index of an element in an array\n * @param {*} searchElement\n * @return {Number}\n */\n Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {\n if (this === void 0 || this === null) {\n throw new TypeError();\n }\n var t = Object(this), len = t.length >>> 0;\n if (len === 0) {\n return -1;\n }\n var n = 0;\n if (arguments.length > 0) {\n n = Number(arguments[1]);\n if (n !== n) { // shortcut for verifying if it's NaN\n n = 0;\n }\n else if (n !== 0 && n !== Number.POSITIVE_INFINITY && n !== Number.NEGATIVE_INFINITY) {\n n = (n > 0 || -1) * Math.floor(Math.abs(n));\n }\n }\n if (n >= len) {\n return -1;\n }\n var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);\n for (; k < len; k++) {\n if (k in t && t[k] === searchElement) {\n return k;\n }\n }\n return -1;\n };\n }\n\n if (!Array.prototype.forEach) {\n /**\n * Iterates an array, invoking callback for each element\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Array}\n */\n Array.prototype.forEach = function(fn, context) {\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this) {\n fn.call(context, this[i], i, this);\n }\n }\n };\n }\n\n if (!Array.prototype.map) {\n /**\n * Returns a result of iterating over an array, invoking callback for each element\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Array}\n */\n Array.prototype.map = function(fn, context) {\n var result = [];\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this) {\n result[i] = fn.call(context, this[i], i, this);\n }\n }\n return result;\n };\n }\n\n if (!Array.prototype.every) {\n /**\n * Returns true if a callback returns truthy value for all elements in an array\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Boolean}\n */\n Array.prototype.every = function(fn, context) {\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this && !fn.call(context, this[i], i, this)) {\n return false;\n }\n }\n return true;\n };\n }\n\n if (!Array.prototype.some) {\n /**\n * Returns true if a callback returns truthy value for at least one element in an array\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Boolean}\n */\n Array.prototype.some = function(fn, context) {\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this && fn.call(context, this[i], i, this)) {\n return true;\n }\n }\n return false;\n };\n }\n\n if (!Array.prototype.filter) {\n /**\n * Returns the result of iterating over elements in an array\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Array}\n */\n Array.prototype.filter = function(fn, context) {\n var result = [], val;\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this) {\n val = this[i]; // in case fn mutates this\n if (fn.call(context, val, i, this)) {\n result.push(val);\n }\n }\n }\n return result;\n };\n }\n\n if (!Array.prototype.reduce) {\n /**\n * Returns \"folded\" (reduced) result of iterating over elements in an array\n * @param {Function} fn Callback to invoke for each element\n * @return {*}\n */\n Array.prototype.reduce = function(fn /*, initial*/) {\n var len = this.length >>> 0,\n i = 0,\n rv;\n\n if (arguments.length > 1) {\n rv = arguments[1];\n }\n else {\n do {\n if (i in this) {\n rv = this[i++];\n break;\n }\n // if array contains no values, no initial value to return\n if (++i >= len) {\n throw new TypeError();\n }\n }\n while (true);\n }\n for (; i < len; i++) {\n if (i in this) {\n rv = fn.call(null, rv, this[i], i, this);\n }\n }\n return rv;\n };\n }\n\n /* _ES5_COMPAT_END_ */\n\n /**\n * Invokes method on all items in a given array\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} method Name of a method to invoke\n * @return {Array}\n */\n function invoke(array, method) {\n var args = slice.call(arguments, 2), result = [];\n for (var i = 0, len = array.length; i < len; i++) {\n result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);\n }\n return result;\n }\n\n /**\n * Finds maximum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n function max(array, byProperty) {\n return find(array, byProperty, function(value1, value2) {\n return value1 >= value2;\n });\n }\n\n /**\n * Finds minimum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n function min(array, byProperty) {\n return find(array, byProperty, function(value1, value2) {\n return value1 < value2;\n });\n }\n\n /**\n * @private\n */\n function fill(array, value) {\n var k = array.length;\n while (k--) {\n array[k] = value;\n }\n return array;\n }\n\n /**\n * @private\n */\n function find(array, byProperty, condition) {\n if (!array || array.length === 0) {\n return;\n }\n\n var i = array.length - 1,\n result = byProperty ? array[i][byProperty] : array[i];\n if (byProperty) {\n while (i--) {\n if (condition(array[i][byProperty], result)) {\n result = array[i][byProperty];\n }\n }\n }\n else {\n while (i--) {\n if (condition(array[i], result)) {\n result = array[i];\n }\n }\n }\n return result;\n }\n\n /**\n * @namespace fabric.util.array\n */\n fabric.util.array = {\n fill: fill,\n invoke: invoke,\n min: min,\n max: max\n };\n\n})();\n\n\n(function() {\n /**\n * Copies all enumerable properties of one js object to another\n * Does not clone or extend fabric.Object subclasses.\n * @memberOf fabric.util.object\n * @param {Object} destination Where to copy to\n * @param {Object} source Where to copy from\n * @return {Object}\n */\n\n function extend(destination, source, deep) {\n // JScript DontEnum bug is not taken care of\n // the deep clone is for internal use, is not meant to avoid\n // javascript traps or cloning html element or self referenced objects.\n if (deep) {\n if (!fabric.isLikelyNode && source instanceof Element) {\n // avoid cloning deep images, canvases,\n destination = source;\n }\n else if (source instanceof Array) {\n destination = [];\n for (var i = 0, len = source.length; i < len; i++) {\n destination[i] = extend({ }, source[i], deep);\n }\n }\n else if (source && typeof source === 'object') {\n for (var property in source) {\n if (source.hasOwnProperty(property)) {\n destination[property] = extend({ }, source[property], deep);\n }\n }\n }\n else {\n // this sounds odd for an extend but is ok for recursive use\n destination = source;\n }\n }\n else {\n for (var property in source) {\n destination[property] = source[property];\n }\n }\n return destination;\n }\n\n /**\n * Creates an empty object and copies all enumerable properties of another object to it\n * @memberOf fabric.util.object\n * @param {Object} object Object to clone\n * @return {Object}\n */\n function clone(object, deep) {\n return extend({ }, object, deep);\n }\n\n /** @namespace fabric.util.object */\n fabric.util.object = {\n extend: extend,\n clone: clone\n };\n\n})();\n\n\n(function() {\n\n /* _ES5_COMPAT_START_ */\n if (!String.prototype.trim) {\n /**\n * Trims a string (removing whitespace from the beginning and the end)\n * @function external:String#trim\n * @see String#trim on MDN\n */\n String.prototype.trim = function () {\n // this trim is not fully ES3 or ES5 compliant, but it should cover most cases for now\n return this.replace(/^[\\s\\xA0]+/, '').replace(/[\\s\\xA0]+$/, '');\n };\n }\n /* _ES5_COMPAT_END_ */\n\n /**\n * Camelizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to camelize\n * @return {String} Camelized version of a string\n */\n function camelize(string) {\n return string.replace(/-+(.)?/g, function(match, character) {\n return character ? character.toUpperCase() : '';\n });\n }\n\n /**\n * Capitalizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to capitalize\n * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n * and other letters stay untouched, if false first letter is capitalized\n * and other letters are converted to lowercase.\n * @return {String} Capitalized version of a string\n */\n function capitalize(string, firstLetterOnly) {\n return string.charAt(0).toUpperCase() +\n (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());\n }\n\n /**\n * Escapes XML in a string\n * @memberOf fabric.util.string\n * @param {String} string String to escape\n * @return {String} Escaped version of a string\n */\n function escapeXml(string) {\n return string.replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(//g, '>');\n }\n\n /**\n * String utilities\n * @namespace fabric.util.string\n */\n fabric.util.string = {\n camelize: camelize,\n capitalize: capitalize,\n escapeXml: escapeXml\n };\n})();\n\n\n/* _ES5_COMPAT_START_ */\n(function() {\n\n var slice = Array.prototype.slice,\n apply = Function.prototype.apply,\n Dummy = function() { };\n\n if (!Function.prototype.bind) {\n /**\n * Cross-browser approximation of ES5 Function.prototype.bind (not fully spec conforming)\n * @see Function#bind on MDN\n * @param {Object} thisArg Object to bind function to\n * @param {Any[]} Values to pass to a bound function\n * @return {Function}\n */\n Function.prototype.bind = function(thisArg) {\n var _this = this, args = slice.call(arguments, 1), bound;\n if (args.length) {\n bound = function() {\n return apply.call(_this, this instanceof Dummy ? this : thisArg, args.concat(slice.call(arguments)));\n };\n }\n else {\n /** @ignore */\n bound = function() {\n return apply.call(_this, this instanceof Dummy ? this : thisArg, arguments);\n };\n }\n Dummy.prototype = this.prototype;\n bound.prototype = new Dummy();\n\n return bound;\n };\n }\n\n})();\n/* _ES5_COMPAT_END_ */\n\n\n(function() {\n\n var slice = Array.prototype.slice, emptyFunction = function() { },\n\n IS_DONTENUM_BUGGY = (function() {\n for (var p in { toString: 1 }) {\n if (p === 'toString') {\n return false;\n }\n }\n return true;\n })(),\n\n /** @ignore */\n addMethods = function(klass, source, parent) {\n for (var property in source) {\n\n if (property in klass.prototype &&\n typeof klass.prototype[property] === 'function' &&\n (source[property] + '').indexOf('callSuper') > -1) {\n\n klass.prototype[property] = (function(property) {\n return function() {\n\n var superclass = this.constructor.superclass;\n this.constructor.superclass = parent;\n var returnValue = source[property].apply(this, arguments);\n this.constructor.superclass = superclass;\n\n if (property !== 'initialize') {\n return returnValue;\n }\n };\n })(property);\n }\n else {\n klass.prototype[property] = source[property];\n }\n\n if (IS_DONTENUM_BUGGY) {\n if (source.toString !== Object.prototype.toString) {\n klass.prototype.toString = source.toString;\n }\n if (source.valueOf !== Object.prototype.valueOf) {\n klass.prototype.valueOf = source.valueOf;\n }\n }\n }\n };\n\n function Subclass() { }\n\n function callSuper(methodName) {\n var parentMethod = null,\n _this = this;\n\n // climb prototype chain to find method not equal to callee's method\n while (_this.constructor.superclass) {\n var superClassMethod = _this.constructor.superclass.prototype[methodName];\n if (_this[methodName] !== superClassMethod) {\n parentMethod = superClassMethod;\n break;\n }\n // eslint-disable-next-line\n _this = _this.constructor.superclass.prototype;\n }\n\n if (!parentMethod) {\n return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this);\n }\n\n return (arguments.length > 1)\n ? parentMethod.apply(this, slice.call(arguments, 1))\n : parentMethod.call(this);\n }\n\n /**\n * Helper for creation of \"classes\".\n * @memberOf fabric.util\n * @param {Function} [parent] optional \"Class\" to inherit from\n * @param {Object} [properties] Properties shared by all instances of this class\n * (be careful modifying objects defined here as this would affect all instances)\n */\n function createClass() {\n var parent = null,\n properties = slice.call(arguments, 0);\n\n if (typeof properties[0] === 'function') {\n parent = properties.shift();\n }\n function klass() {\n this.initialize.apply(this, arguments);\n }\n\n klass.superclass = parent;\n klass.subclasses = [];\n\n if (parent) {\n Subclass.prototype = parent.prototype;\n klass.prototype = new Subclass();\n parent.subclasses.push(klass);\n }\n for (var i = 0, length = properties.length; i < length; i++) {\n addMethods(klass, properties[i], parent);\n }\n if (!klass.prototype.initialize) {\n klass.prototype.initialize = emptyFunction;\n }\n klass.prototype.constructor = klass;\n klass.prototype.callSuper = callSuper;\n return klass;\n }\n\n fabric.util.createClass = createClass;\n})();\n\n\n(function () {\n\n var unknown = 'unknown';\n\n /* EVENT HANDLING */\n\n function areHostMethods(object) {\n var methodNames = Array.prototype.slice.call(arguments, 1),\n t, i, len = methodNames.length;\n for (i = 0; i < len; i++) {\n t = typeof object[methodNames[i]];\n if (!(/^(?:function|object|unknown)$/).test(t)) {\n return false;\n }\n }\n return true;\n }\n\n /** @ignore */\n var getElement,\n setElement,\n getUniqueId = (function () {\n var uid = 0;\n return function (element) {\n return element.__uniqueID || (element.__uniqueID = 'uniqueID__' + uid++);\n };\n })();\n\n (function () {\n var elements = { };\n /** @ignore */\n getElement = function (uid) {\n return elements[uid];\n };\n /** @ignore */\n setElement = function (uid, element) {\n elements[uid] = element;\n };\n })();\n\n function createListener(uid, handler) {\n return {\n handler: handler,\n wrappedHandler: createWrappedHandler(uid, handler)\n };\n }\n\n function createWrappedHandler(uid, handler) {\n return function (e) {\n handler.call(getElement(uid), e || fabric.window.event);\n };\n }\n\n function createDispatcher(uid, eventName) {\n return function (e) {\n if (handlers[uid] && handlers[uid][eventName]) {\n var handlersForEvent = handlers[uid][eventName];\n for (var i = 0, len = handlersForEvent.length; i < len; i++) {\n handlersForEvent[i].call(this, e || fabric.window.event);\n }\n }\n };\n }\n\n var shouldUseAddListenerRemoveListener = (\n areHostMethods(fabric.document.documentElement, 'addEventListener', 'removeEventListener') &&\n areHostMethods(fabric.window, 'addEventListener', 'removeEventListener')),\n\n shouldUseAttachEventDetachEvent = (\n areHostMethods(fabric.document.documentElement, 'attachEvent', 'detachEvent') &&\n areHostMethods(fabric.window, 'attachEvent', 'detachEvent')),\n\n // IE branch\n listeners = { },\n\n // DOM L0 branch\n handlers = { },\n\n addListener, removeListener;\n\n if (shouldUseAddListenerRemoveListener) {\n /** @ignore */\n addListener = function (element, eventName, handler, options) {\n // since ie10 or ie9 can use addEventListener but they do not support options, i need to check\n element && element.addEventListener(eventName, handler, shouldUseAttachEventDetachEvent ? false : options);\n };\n /** @ignore */\n removeListener = function (element, eventName, handler, options) {\n element && element.removeEventListener(eventName, handler, shouldUseAttachEventDetachEvent ? false : options);\n };\n }\n\n else if (shouldUseAttachEventDetachEvent) {\n /** @ignore */\n addListener = function (element, eventName, handler) {\n if (!element) {\n return;\n }\n var uid = getUniqueId(element);\n setElement(uid, element);\n if (!listeners[uid]) {\n listeners[uid] = { };\n }\n if (!listeners[uid][eventName]) {\n listeners[uid][eventName] = [];\n\n }\n var listener = createListener(uid, handler);\n listeners[uid][eventName].push(listener);\n element.attachEvent('on' + eventName, listener.wrappedHandler);\n };\n /** @ignore */\n removeListener = function (element, eventName, handler) {\n if (!element) {\n return;\n }\n var uid = getUniqueId(element), listener;\n if (listeners[uid] && listeners[uid][eventName]) {\n for (var i = 0, len = listeners[uid][eventName].length; i < len; i++) {\n listener = listeners[uid][eventName][i];\n if (listener && listener.handler === handler) {\n element.detachEvent('on' + eventName, listener.wrappedHandler);\n listeners[uid][eventName][i] = null;\n }\n }\n }\n };\n }\n else {\n /** @ignore */\n addListener = function (element, eventName, handler) {\n if (!element) {\n return;\n }\n var uid = getUniqueId(element);\n if (!handlers[uid]) {\n handlers[uid] = { };\n }\n if (!handlers[uid][eventName]) {\n handlers[uid][eventName] = [];\n var existingHandler = element['on' + eventName];\n if (existingHandler) {\n handlers[uid][eventName].push(existingHandler);\n }\n element['on' + eventName] = createDispatcher(uid, eventName);\n }\n handlers[uid][eventName].push(handler);\n };\n /** @ignore */\n removeListener = function (element, eventName, handler) {\n if (!element) {\n return;\n }\n var uid = getUniqueId(element);\n if (handlers[uid] && handlers[uid][eventName]) {\n var handlersForEvent = handlers[uid][eventName];\n for (var i = 0, len = handlersForEvent.length; i < len; i++) {\n if (handlersForEvent[i] === handler) {\n handlersForEvent.splice(i, 1);\n }\n }\n }\n };\n }\n\n /**\n * Adds an event listener to an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n fabric.util.addListener = addListener;\n\n /**\n * Removes an event listener from an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n fabric.util.removeListener = removeListener;\n\n /**\n * Cross-browser wrapper for getting event's coordinates\n * @memberOf fabric.util\n * @param {Event} event Event object\n */\n function getPointer(event) {\n event || (event = fabric.window.event);\n\n var element = event.target ||\n (typeof event.srcElement !== unknown ? event.srcElement : null),\n\n scroll = fabric.util.getScrollLeftTop(element);\n\n return {\n x: pointerX(event) + scroll.left,\n y: pointerY(event) + scroll.top\n };\n }\n\n var pointerX = function(event) {\n // looks like in IE (<9) clientX at certain point (apparently when mouseup fires on VML element)\n // is represented as COM object, with all the consequences, like \"unknown\" type and error on [[Get]]\n // need to investigate later\n return (typeof event.clientX !== unknown ? event.clientX : 0);\n },\n\n pointerY = function(event) {\n return (typeof event.clientY !== unknown ? event.clientY : 0);\n };\n\n function _getPointer(event, pageProp, clientProp) {\n var touchProp = event.type === 'touchend' ? 'changedTouches' : 'touches';\n\n return (event[touchProp] && event[touchProp][0]\n ? (event[touchProp][0][pageProp] - (event[touchProp][0][pageProp] - event[touchProp][0][clientProp]))\n || event[clientProp]\n : event[clientProp]);\n }\n\n if (fabric.isTouchSupported) {\n pointerX = function(event) {\n return _getPointer(event, 'pageX', 'clientX');\n };\n pointerY = function(event) {\n return _getPointer(event, 'pageY', 'clientY');\n };\n }\n\n fabric.util.getPointer = getPointer;\n\n fabric.util.object.extend(fabric.util, fabric.Observable);\n\n})();\n\n\n(function () {\n\n /**\n * Cross-browser wrapper for setting element's style\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {Object} styles\n * @return {HTMLElement} Element that was passed as a first argument\n */\n function setStyle(element, styles) {\n var elementStyle = element.style;\n if (!elementStyle) {\n return element;\n }\n if (typeof styles === 'string') {\n element.style.cssText += ';' + styles;\n return styles.indexOf('opacity') > -1\n ? setOpacity(element, styles.match(/opacity:\\s*(\\d?\\.?\\d*)/)[1])\n : element;\n }\n for (var property in styles) {\n if (property === 'opacity') {\n setOpacity(element, styles[property]);\n }\n else {\n var normalizedProperty = (property === 'float' || property === 'cssFloat')\n ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')\n : property;\n elementStyle[normalizedProperty] = styles[property];\n }\n }\n return element;\n }\n\n var parseEl = fabric.document.createElement('div'),\n supportsOpacity = typeof parseEl.style.opacity === 'string',\n supportsFilters = typeof parseEl.style.filter === 'string',\n reOpacity = /alpha\\s*\\(\\s*opacity\\s*=\\s*([^\\)]+)\\)/,\n\n /** @ignore */\n setOpacity = function (element) { return element; };\n\n if (supportsOpacity) {\n /** @ignore */\n setOpacity = function(element, value) {\n element.style.opacity = value;\n return element;\n };\n }\n else if (supportsFilters) {\n /** @ignore */\n setOpacity = function(element, value) {\n var es = element.style;\n if (element.currentStyle && !element.currentStyle.hasLayout) {\n es.zoom = 1;\n }\n if (reOpacity.test(es.filter)) {\n value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')');\n es.filter = es.filter.replace(reOpacity, value);\n }\n else {\n es.filter += ' alpha(opacity=' + (value * 100) + ')';\n }\n return element;\n };\n }\n\n fabric.util.setStyle = setStyle;\n\n})();\n\n\n(function() {\n\n var _slice = Array.prototype.slice;\n\n /**\n * Takes id and returns an element with that id (if one exists in a document)\n * @memberOf fabric.util\n * @param {String|HTMLElement} id\n * @return {HTMLElement|null}\n */\n function getById(id) {\n return typeof id === 'string' ? fabric.document.getElementById(id) : id;\n }\n\n var sliceCanConvertNodelists,\n /**\n * Converts an array-like object (e.g. arguments or NodeList) to an array\n * @memberOf fabric.util\n * @param {Object} arrayLike\n * @return {Array}\n */\n toArray = function(arrayLike) {\n return _slice.call(arrayLike, 0);\n };\n\n try {\n sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;\n }\n catch (err) { }\n\n if (!sliceCanConvertNodelists) {\n toArray = function(arrayLike) {\n var arr = new Array(arrayLike.length), i = arrayLike.length;\n while (i--) {\n arr[i] = arrayLike[i];\n }\n return arr;\n };\n }\n\n /**\n * Creates specified element with specified attributes\n * @memberOf fabric.util\n * @param {String} tagName Type of an element to create\n * @param {Object} [attributes] Attributes to set on an element\n * @return {HTMLElement} Newly created element\n */\n function makeElement(tagName, attributes) {\n var el = fabric.document.createElement(tagName);\n for (var prop in attributes) {\n if (prop === 'class') {\n el.className = attributes[prop];\n }\n else if (prop === 'for') {\n el.htmlFor = attributes[prop];\n }\n else {\n el.setAttribute(prop, attributes[prop]);\n }\n }\n return el;\n }\n\n /**\n * Adds class to an element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to add class to\n * @param {String} className Class to add to an element\n */\n function addClass(element, className) {\n if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {\n element.className += (element.className ? ' ' : '') + className;\n }\n }\n\n /**\n * Wraps element with another element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to wrap\n * @param {HTMLElement|String} wrapper Element to wrap with\n * @param {Object} [attributes] Attributes to set on a wrapper\n * @return {HTMLElement} wrapper\n */\n function wrapElement(element, wrapper, attributes) {\n if (typeof wrapper === 'string') {\n wrapper = makeElement(wrapper, attributes);\n }\n if (element.parentNode) {\n element.parentNode.replaceChild(wrapper, element);\n }\n wrapper.appendChild(element);\n return wrapper;\n }\n\n /**\n * Returns element scroll offsets\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to operate on\n * @return {Object} Object with left/top values\n */\n function getScrollLeftTop(element) {\n\n var left = 0,\n top = 0,\n docElement = fabric.document.documentElement,\n body = fabric.document.body || {\n scrollLeft: 0, scrollTop: 0\n };\n\n // While loop checks (and then sets element to) .parentNode OR .host\n // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n // but the .parentNode of a root ShadowDOM node will always be null, instead\n // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n while (element && (element.parentNode || element.host)) {\n\n // Set element to element parent, or 'host' in case of ShadowDOM\n element = element.parentNode || element.host;\n\n if (element === fabric.document) {\n left = body.scrollLeft || docElement.scrollLeft || 0;\n top = body.scrollTop || docElement.scrollTop || 0;\n }\n else {\n left += element.scrollLeft || 0;\n top += element.scrollTop || 0;\n }\n\n if (element.nodeType === 1 &&\n fabric.util.getElementStyle(element, 'position') === 'fixed') {\n break;\n }\n }\n\n return { left: left, top: top };\n }\n\n /**\n * Returns offset for a given element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get offset for\n * @return {Object} Object with \"left\" and \"top\" properties\n */\n function getElementOffset(element) {\n var docElem,\n doc = element && element.ownerDocument,\n box = { left: 0, top: 0 },\n offset = { left: 0, top: 0 },\n scrollLeftTop,\n offsetAttributes = {\n borderLeftWidth: 'left',\n borderTopWidth: 'top',\n paddingLeft: 'left',\n paddingTop: 'top'\n };\n\n if (!doc) {\n return offset;\n }\n\n for (var attr in offsetAttributes) {\n offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0;\n }\n\n docElem = doc.documentElement;\n if ( typeof element.getBoundingClientRect !== 'undefined' ) {\n box = element.getBoundingClientRect();\n }\n\n scrollLeftTop = getScrollLeftTop(element);\n\n return {\n left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top\n };\n }\n\n /**\n * Returns style attribute value of a given element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get style attribute for\n * @param {String} attr Style attribute to get for element\n * @return {String} Style attribute value of the given element.\n */\n var getElementStyle;\n if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {\n getElementStyle = function(element, attr) {\n var style = fabric.document.defaultView.getComputedStyle(element, null);\n return style ? style[attr] : undefined;\n };\n }\n else {\n getElementStyle = function(element, attr) {\n var value = element.style[attr];\n if (!value && element.currentStyle) {\n value = element.currentStyle[attr];\n }\n return value;\n };\n }\n\n (function () {\n var style = fabric.document.documentElement.style,\n selectProp = 'userSelect' in style\n ? 'userSelect'\n : 'MozUserSelect' in style\n ? 'MozUserSelect'\n : 'WebkitUserSelect' in style\n ? 'WebkitUserSelect'\n : 'KhtmlUserSelect' in style\n ? 'KhtmlUserSelect'\n : '';\n\n /**\n * Makes element unselectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make unselectable\n * @return {HTMLElement} Element that was passed in\n */\n function makeElementUnselectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = fabric.util.falseFunction;\n }\n if (selectProp) {\n element.style[selectProp] = 'none';\n }\n else if (typeof element.unselectable === 'string') {\n element.unselectable = 'on';\n }\n return element;\n }\n\n /**\n * Makes element selectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make selectable\n * @return {HTMLElement} Element that was passed in\n */\n function makeElementSelectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = null;\n }\n if (selectProp) {\n element.style[selectProp] = '';\n }\n else if (typeof element.unselectable === 'string') {\n element.unselectable = '';\n }\n return element;\n }\n\n fabric.util.makeElementUnselectable = makeElementUnselectable;\n fabric.util.makeElementSelectable = makeElementSelectable;\n })();\n\n (function() {\n\n /**\n * Inserts a script element with a given url into a document; invokes callback, when that script is finished loading\n * @memberOf fabric.util\n * @param {String} url URL of a script to load\n * @param {Function} callback Callback to execute when script is finished loading\n */\n function getScript(url, callback) {\n var headEl = fabric.document.getElementsByTagName('head')[0],\n scriptEl = fabric.document.createElement('script'),\n loading = true;\n\n /** @ignore */\n scriptEl.onload = /** @ignore */ scriptEl.onreadystatechange = function(e) {\n if (loading) {\n if (typeof this.readyState === 'string' &&\n this.readyState !== 'loaded' &&\n this.readyState !== 'complete') {\n return;\n }\n loading = false;\n callback(e || fabric.window.event);\n scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null;\n }\n };\n scriptEl.src = url;\n headEl.appendChild(scriptEl);\n // causes issue in Opera\n // headEl.removeChild(scriptEl);\n }\n\n fabric.util.getScript = getScript;\n })();\n\n fabric.util.getById = getById;\n fabric.util.toArray = toArray;\n fabric.util.makeElement = makeElement;\n fabric.util.addClass = addClass;\n fabric.util.wrapElement = wrapElement;\n fabric.util.getScrollLeftTop = getScrollLeftTop;\n fabric.util.getElementOffset = getElementOffset;\n fabric.util.getElementStyle = getElementStyle;\n\n})();\n\n\n(function() {\n\n function addParamToUrl(url, param) {\n return url + (/\\?/.test(url) ? '&' : '?') + param;\n }\n\n var makeXHR = (function() {\n var factories = [\n function() { return new ActiveXObject('Microsoft.XMLHTTP'); },\n function() { return new ActiveXObject('Msxml2.XMLHTTP'); },\n function() { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); },\n function() { return new XMLHttpRequest(); }\n ];\n for (var i = factories.length; i--; ) {\n try {\n var req = factories[i]();\n if (req) {\n return factories[i];\n }\n }\n catch (err) { }\n }\n })();\n\n function emptyFn() { }\n\n /**\n * Cross-browser abstraction for sending XMLHttpRequest\n * @memberOf fabric.util\n * @param {String} url URL to send XMLHttpRequest to\n * @param {Object} [options] Options object\n * @param {String} [options.method=\"GET\"]\n * @param {String} [options.parameters] parameters to append to url in GET or in body\n * @param {String} [options.body] body to send with POST or PUT request\n * @param {Function} options.onComplete Callback to invoke when request is completed\n * @return {XMLHttpRequest} request\n */\n function request(url, options) {\n\n options || (options = { });\n\n var method = options.method ? options.method.toUpperCase() : 'GET',\n onComplete = options.onComplete || function() { },\n xhr = makeXHR(),\n body = options.body || options.parameters;\n\n /** @ignore */\n xhr.onreadystatechange = function() {\n if (xhr.readyState === 4) {\n onComplete(xhr);\n xhr.onreadystatechange = emptyFn;\n }\n };\n\n if (method === 'GET') {\n body = null;\n if (typeof options.parameters === 'string') {\n url = addParamToUrl(url, options.parameters);\n }\n }\n\n xhr.open(method, url, true);\n\n if (method === 'POST' || method === 'PUT') {\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n }\n\n xhr.send(body);\n return xhr;\n }\n\n fabric.util.request = request;\n})();\n\n\n/**\n * Wrapper around `console.log` (when available)\n * @param {*} [values] Values to log\n */\nfabric.log = function() { };\n\n/**\n * Wrapper around `console.warn` (when available)\n * @param {*} [values] Values to log as a warning\n */\nfabric.warn = function() { };\n\n/* eslint-disable */\nif (typeof console !== 'undefined') {\n\n ['log', 'warn'].forEach(function(methodName) {\n\n if (typeof console[methodName] !== 'undefined' &&\n typeof console[methodName].apply === 'function') {\n\n fabric[methodName] = function() {\n return console[methodName].apply(console, arguments);\n };\n }\n });\n}\n/* eslint-enable */\n\n\n(function() {\n\n function noop() {\n return false;\n }\n\n /**\n * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Number} [options.startValue=0] Starting value\n * @param {Number} [options.endValue=100] Ending value\n * @param {Number} [options.byValue=100] Value to modify the property by\n * @param {Function} [options.easing] Easing function\n * @param {Number} [options.duration=500] Duration of change (in ms)\n */\n function animate(options) {\n\n requestAnimFrame(function(timestamp) {\n options || (options = { });\n\n var start = timestamp || +new Date(),\n duration = options.duration || 500,\n finish = start + duration, time,\n onChange = options.onChange || noop,\n abort = options.abort || noop,\n onComplete = options.onComplete || noop,\n easing = options.easing || function(t, b, c, d) {return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;},\n startValue = 'startValue' in options ? options.startValue : 0,\n endValue = 'endValue' in options ? options.endValue : 100,\n byValue = options.byValue || endValue - startValue;\n\n options.onStart && options.onStart();\n\n (function tick(ticktime) {\n if (abort()) {\n onComplete(endValue, 1, 1);\n return;\n }\n time = ticktime || +new Date();\n var currentTime = time > finish ? duration : (time - start),\n timePerc = currentTime / duration,\n current = easing(currentTime, startValue, byValue, duration),\n valuePerc = Math.abs((current - startValue) / byValue);\n onChange(current, valuePerc, timePerc);\n if (time > finish) {\n options.onComplete && options.onComplete();\n return;\n }\n requestAnimFrame(tick);\n })(start);\n });\n\n }\n\n var _requestAnimFrame = fabric.window.requestAnimationFrame ||\n fabric.window.webkitRequestAnimationFrame ||\n fabric.window.mozRequestAnimationFrame ||\n fabric.window.oRequestAnimationFrame ||\n fabric.window.msRequestAnimationFrame ||\n function(callback) {\n fabric.window.setTimeout(callback, 1000 / 60);\n };\n\n /**\n * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method\n * @memberOf fabric.util\n * @param {Function} callback Callback to invoke\n * @param {DOMElement} element optional Element to associate with animation\n */\n function requestAnimFrame() {\n return _requestAnimFrame.apply(fabric.window, arguments);\n }\n\n fabric.util.animate = animate;\n fabric.util.requestAnimFrame = requestAnimFrame;\n\n})();\n\n\n(function() {\n // Calculate an in-between color. Returns a \"rgba()\" string.\n // Credit: Edwin Martin \n // http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js\n function calculateColor(begin, end, pos) {\n var color = 'rgba('\n + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ','\n + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ','\n + parseInt((begin[2] + pos * (end[2] - begin[2])), 10);\n\n color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1);\n color += ')';\n return color;\n }\n\n /**\n * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {String} fromColor The starting color in hex or rgb(a) format.\n * @param {String} toColor The starting color in hex or rgb(a) format.\n * @param {Number} [duration] Duration of change (in ms).\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used.\n */\n function animateColor(fromColor, toColor, duration, options) {\n var startColor = new fabric.Color(fromColor).getSource(),\n endColor = new fabric.Color(toColor).getSource();\n\n options = options || {};\n\n fabric.util.animate(fabric.util.object.extend(options, {\n duration: duration || 500,\n startValue: startColor,\n endValue: endColor,\n byValue: endColor,\n easing: function (currentTime, startValue, byValue, duration) {\n var posValue = options.colorEasing\n ? options.colorEasing(currentTime, duration)\n : 1 - Math.cos(currentTime / duration * (Math.PI / 2));\n return calculateColor(startValue, byValue, posValue);\n }\n }));\n }\n\n fabric.util.animateColor = animateColor;\n\n})();\n\n\n(function() {\n\n function normalize(a, c, p, s) {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n }\n else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = p / (2 * Math.PI) * Math.asin(1);\n }\n else {\n s = p / (2 * Math.PI) * Math.asin(c / a);\n }\n }\n return { a: a, c: c, p: p, s: s };\n }\n\n function elastic(opts, t, d) {\n return opts.a *\n Math.pow(2, 10 * (t -= 1)) *\n Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p );\n }\n\n /**\n * Cubic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutCubic(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t + 1) + b;\n }\n\n /**\n * Cubic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutCubic(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t + b;\n }\n return c / 2 * ((t -= 2) * t * t + 2) + b;\n }\n\n /**\n * Quartic easing in\n * @memberOf fabric.util.ease\n */\n function easeInQuart(t, b, c, d) {\n return c * (t /= d) * t * t * t + b;\n }\n\n /**\n * Quartic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutQuart(t, b, c, d) {\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n }\n\n /**\n * Quartic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutQuart(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t * t + b;\n }\n return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\n }\n\n /**\n * Quintic easing in\n * @memberOf fabric.util.ease\n */\n function easeInQuint(t, b, c, d) {\n return c * (t /= d) * t * t * t * t + b;\n }\n\n /**\n * Quintic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutQuint(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\n }\n\n /**\n * Quintic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutQuint(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t * t * t + b;\n }\n return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\n }\n\n /**\n * Sinusoidal easing in\n * @memberOf fabric.util.ease\n */\n function easeInSine(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n }\n\n /**\n * Sinusoidal easing out\n * @memberOf fabric.util.ease\n */\n function easeOutSine(t, b, c, d) {\n return c * Math.sin(t / d * (Math.PI / 2)) + b;\n }\n\n /**\n * Sinusoidal easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutSine(t, b, c, d) {\n return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n }\n\n /**\n * Exponential easing in\n * @memberOf fabric.util.ease\n */\n function easeInExpo(t, b, c, d) {\n return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;\n }\n\n /**\n * Exponential easing out\n * @memberOf fabric.util.ease\n */\n function easeOutExpo(t, b, c, d) {\n return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;\n }\n\n /**\n * Exponential easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutExpo(t, b, c, d) {\n if (t === 0) {\n return b;\n }\n if (t === d) {\n return b + c;\n }\n t /= d / 2;\n if (t < 1) {\n return c / 2 * Math.pow(2, 10 * (t - 1)) + b;\n }\n return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;\n }\n\n /**\n * Circular easing in\n * @memberOf fabric.util.ease\n */\n function easeInCirc(t, b, c, d) {\n return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n }\n\n /**\n * Circular easing out\n * @memberOf fabric.util.ease\n */\n function easeOutCirc(t, b, c, d) {\n return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n }\n\n /**\n * Circular easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutCirc(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;\n }\n return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n }\n\n /**\n * Elastic easing in\n * @memberOf fabric.util.ease\n */\n function easeInElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n var opts = normalize(a, c, p, s);\n return -elastic(opts, t, d) + b;\n }\n\n /**\n * Elastic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n var opts = normalize(a, c, p, s);\n return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b;\n }\n\n /**\n * Elastic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d / 2;\n if (t === 2) {\n return b + c;\n }\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n var opts = normalize(a, c, p, s);\n if (t < 1) {\n return -0.5 * elastic(opts, t, d) + b;\n }\n return opts.a * Math.pow(2, -10 * (t -= 1)) *\n Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b;\n }\n\n /**\n * Backwards easing in\n * @memberOf fabric.util.ease\n */\n function easeInBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\n }\n\n /**\n * Backwards easing out\n * @memberOf fabric.util.ease\n */\n function easeOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n }\n\n /**\n * Backwards easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n t /= d / 2;\n if (t < 1) {\n return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;\n }\n return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\n }\n\n /**\n * Bouncing easing in\n * @memberOf fabric.util.ease\n */\n function easeInBounce(t, b, c, d) {\n return c - easeOutBounce (d - t, 0, c, d) + b;\n }\n\n /**\n * Bouncing easing out\n * @memberOf fabric.util.ease\n */\n function easeOutBounce(t, b, c, d) {\n if ((t /= d) < (1 / 2.75)) {\n return c * (7.5625 * t * t) + b;\n }\n else if (t < (2 / 2.75)) {\n return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;\n }\n else if (t < (2.5 / 2.75)) {\n return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;\n }\n else {\n return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;\n }\n }\n\n /**\n * Bouncing easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutBounce(t, b, c, d) {\n if (t < d / 2) {\n return easeInBounce (t * 2, 0, c, d) * 0.5 + b;\n }\n return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n }\n\n /**\n * Easing functions\n * See Easing Equations by Robert Penner\n * @namespace fabric.util.ease\n */\n fabric.util.ease = {\n\n /**\n * Quadratic easing in\n * @memberOf fabric.util.ease\n */\n easeInQuad: function(t, b, c, d) {\n return c * (t /= d) * t + b;\n },\n\n /**\n * Quadratic easing out\n * @memberOf fabric.util.ease\n */\n easeOutQuad: function(t, b, c, d) {\n return -c * (t /= d) * (t - 2) + b;\n },\n\n /**\n * Quadratic easing in and out\n * @memberOf fabric.util.ease\n */\n easeInOutQuad: function(t, b, c, d) {\n t /= (d / 2);\n if (t < 1) {\n return c / 2 * t * t + b;\n }\n return -c / 2 * ((--t) * (t - 2) - 1) + b;\n },\n\n /**\n * Cubic easing in\n * @memberOf fabric.util.ease\n */\n easeInCubic: function(t, b, c, d) {\n return c * (t /= d) * t * t + b;\n },\n\n easeOutCubic: easeOutCubic,\n easeInOutCubic: easeInOutCubic,\n easeInQuart: easeInQuart,\n easeOutQuart: easeOutQuart,\n easeInOutQuart: easeInOutQuart,\n easeInQuint: easeInQuint,\n easeOutQuint: easeOutQuint,\n easeInOutQuint: easeInOutQuint,\n easeInSine: easeInSine,\n easeOutSine: easeOutSine,\n easeInOutSine: easeInOutSine,\n easeInExpo: easeInExpo,\n easeOutExpo: easeOutExpo,\n easeInOutExpo: easeInOutExpo,\n easeInCirc: easeInCirc,\n easeOutCirc: easeOutCirc,\n easeInOutCirc: easeInOutCirc,\n easeInElastic: easeInElastic,\n easeOutElastic: easeOutElastic,\n easeInOutElastic: easeInOutElastic,\n easeInBack: easeInBack,\n easeOutBack: easeOutBack,\n easeInOutBack: easeInOutBack,\n easeInBounce: easeInBounce,\n easeOutBounce: easeOutBounce,\n easeInOutBounce: easeInOutBounce\n };\n\n})();\n\n\n(function(global) {\n\n 'use strict';\n\n /**\n * @name fabric\n * @namespace\n */\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n parseUnit = fabric.util.parseUnit,\n multiplyTransformMatrices = fabric.util.multiplyTransformMatrices,\n\n reAllowedSVGTagNames = /^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,\n reViewBoxTagNames = /^(symbol|image|marker|pattern|view|svg)$/i,\n reNotAllowedAncestors = /^(?:pattern|defs|symbol|metadata|clipPath|mask)$/i,\n reAllowedParents = /^(symbol|g|a|svg)$/i,\n\n attributesMap = {\n cx: 'left',\n x: 'left',\n r: 'radius',\n cy: 'top',\n y: 'top',\n display: 'visible',\n visibility: 'visible',\n transform: 'transformMatrix',\n 'fill-opacity': 'fillOpacity',\n 'fill-rule': 'fillRule',\n 'font-family': 'fontFamily',\n 'font-size': 'fontSize',\n 'font-style': 'fontStyle',\n 'font-weight': 'fontWeight',\n 'stroke-dasharray': 'strokeDashArray',\n 'stroke-linecap': 'strokeLineCap',\n 'stroke-linejoin': 'strokeLineJoin',\n 'stroke-miterlimit': 'strokeMiterLimit',\n 'stroke-opacity': 'strokeOpacity',\n 'stroke-width': 'strokeWidth',\n 'text-decoration': 'textDecoration',\n 'text-anchor': 'originX',\n opacity: 'opacity'\n },\n\n colorAttributes = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity'\n };\n\n fabric.cssRules = { };\n fabric.gradientDefs = { };\n\n function normalizeAttr(attr) {\n // transform attribute names\n if (attr in attributesMap) {\n return attributesMap[attr];\n }\n return attr;\n }\n\n function normalizeValue(attr, value, parentAttributes, fontSize) {\n var isArray = Object.prototype.toString.call(value) === '[object Array]',\n parsed;\n\n if ((attr === 'fill' || attr === 'stroke') && value === 'none') {\n value = '';\n }\n else if (attr === 'strokeDashArray') {\n if (value === 'none') {\n value = null;\n }\n else {\n value = value.replace(/,/g, ' ').split(/\\s+/).map(function(n) {\n return parseFloat(n);\n });\n }\n }\n else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n value = multiplyTransformMatrices(\n parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));\n }\n else {\n value = fabric.parseTransformAttribute(value);\n }\n }\n else if (attr === 'visible') {\n value = (value === 'none' || value === 'hidden') ? false : true;\n // display=none on parent element always takes precedence over child element\n if (parentAttributes && parentAttributes.visible === false) {\n value = false;\n }\n }\n else if (attr === 'opacity') {\n value = parseFloat(value);\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n value *= parentAttributes.opacity;\n }\n }\n else if (attr === 'originX' /* text-anchor */) {\n value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';\n }\n else {\n parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);\n }\n\n return (!isArray && isNaN(parsed) ? value : parsed);\n }\n\n /**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n function _setStrokeFillOpacity(attributes) {\n for (var attr in colorAttributes) {\n\n if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') {\n continue;\n }\n\n if (typeof attributes[attr] === 'undefined') {\n if (!fabric.Object.prototype[attr]) {\n continue;\n }\n attributes[attr] = fabric.Object.prototype[attr];\n }\n\n if (attributes[attr].indexOf('url(') === 0) {\n continue;\n }\n\n var color = new fabric.Color(attributes[attr]);\n attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba();\n }\n return attributes;\n }\n\n /**\n * @private\n */\n function _getMultipleNodes(doc, nodeNames) {\n var nodeName, nodeArray = [], nodeList;\n for (var i = 0; i < nodeNames.length; i++) {\n nodeName = nodeNames[i];\n nodeList = doc.getElementsByTagName(nodeName);\n nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList));\n }\n return nodeArray;\n }\n\n /**\n * Parses \"transform\" attribute, returning an array of values\n * @static\n * @function\n * @memberOf fabric\n * @param {String} attributeValue String containing attribute value\n * @return {Array} Array of 6 elements representing transformation matrix\n */\n fabric.parseTransformAttribute = (function() {\n function rotateMatrix(matrix, args) {\n var cos = Math.cos(args[0]), sin = Math.sin(args[0]),\n x = 0, y = 0;\n if (args.length === 3) {\n x = args[1];\n y = args[2];\n }\n\n matrix[0] = cos;\n matrix[1] = sin;\n matrix[2] = -sin;\n matrix[3] = cos;\n matrix[4] = x - (cos * x - sin * y);\n matrix[5] = y - (sin * x + cos * y);\n }\n\n function scaleMatrix(matrix, args) {\n var multiplierX = args[0],\n multiplierY = (args.length === 2) ? args[1] : args[0];\n\n matrix[0] = multiplierX;\n matrix[3] = multiplierY;\n }\n\n function skewMatrix(matrix, args, pos) {\n matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0]));\n }\n\n function translateMatrix(matrix, args) {\n matrix[4] = args[0];\n if (args.length === 2) {\n matrix[5] = args[1];\n }\n }\n\n // identity matrix\n var iMatrix = [\n 1, // a\n 0, // b\n 0, // c\n 1, // d\n 0, // e\n 0 // f\n ],\n\n // == begin transform regexp\n number = fabric.reNum,\n\n commaWsp = '(?:\\\\s+,?\\\\s*|,\\\\s*)',\n\n skewX = '(?:(skewX)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n skewY = '(?:(skewY)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n rotate = '(?:(rotate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + ')' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n scale = '(?:(scale)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n translate = '(?:(translate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n matrix = '(?:(matrix)\\\\s*\\\\(\\\\s*' +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' +\n '\\\\s*\\\\))',\n\n transform = '(?:' +\n matrix + '|' +\n translate + '|' +\n scale + '|' +\n rotate + '|' +\n skewX + '|' +\n skewY +\n ')',\n\n transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',\n\n transformList = '^\\\\s*(?:' + transforms + '?)\\\\s*$',\n\n // http://www.w3.org/TR/SVG/coords.html#TransformAttribute\n reTransformList = new RegExp(transformList),\n // == end transform regexp\n\n reTransform = new RegExp(transform, 'g');\n\n return function(attributeValue) {\n\n // start with identity matrix\n var matrix = iMatrix.concat(),\n matrices = [];\n\n // return if no argument was given or\n // an argument does not match transform attribute regexp\n if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) {\n return matrix;\n }\n\n attributeValue.replace(reTransform, function(match) {\n\n var m = new RegExp(transform).exec(match).filter(function (match) {\n // match !== '' && match != null\n return (!!match);\n }),\n operation = m[1],\n args = m.slice(2).map(parseFloat);\n\n switch (operation) {\n case 'translate':\n translateMatrix(matrix, args);\n break;\n case 'rotate':\n args[0] = fabric.util.degreesToRadians(args[0]);\n rotateMatrix(matrix, args);\n break;\n case 'scale':\n scaleMatrix(matrix, args);\n break;\n case 'skewX':\n skewMatrix(matrix, args, 2);\n break;\n case 'skewY':\n skewMatrix(matrix, args, 1);\n break;\n case 'matrix':\n matrix = args;\n break;\n }\n\n // snapshot current matrix into matrices array\n matrices.push(matrix.concat());\n // reset\n matrix = iMatrix.concat();\n });\n\n var combinedMatrix = matrices[0];\n while (matrices.length > 1) {\n matrices.shift();\n combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);\n }\n return combinedMatrix;\n };\n })();\n\n /**\n * @private\n */\n function parseStyleString(style, oStyle) {\n var attr, value;\n style.replace(/;\\s*$/, '').split(';').forEach(function (chunk) {\n var pair = chunk.split(':');\n\n attr = pair[0].trim().toLowerCase();\n value = pair[1].trim();\n\n oStyle[attr] = value;\n });\n }\n\n /**\n * @private\n */\n function parseStyleObject(style, oStyle) {\n var attr, value;\n for (var prop in style) {\n if (typeof style[prop] === 'undefined') {\n continue;\n }\n\n attr = prop.toLowerCase();\n value = style[prop];\n\n oStyle[attr] = value;\n }\n }\n\n /**\n * @private\n */\n function getGlobalStylesForElement(element, svgUid) {\n var styles = { };\n for (var rule in fabric.cssRules[svgUid]) {\n if (elementMatchesRule(element, rule.split(' '))) {\n for (var property in fabric.cssRules[svgUid][rule]) {\n styles[property] = fabric.cssRules[svgUid][rule][property];\n }\n }\n }\n return styles;\n }\n\n /**\n * @private\n */\n function elementMatchesRule(element, selectors) {\n var firstMatching, parentMatching = true;\n //start from rightmost selector.\n firstMatching = selectorMatches(element, selectors.pop());\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n return firstMatching && parentMatching && (selectors.length === 0);\n }\n\n function doesSomeParentMatch(element, selectors) {\n var selector, parentMatching = true;\n while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {\n if (parentMatching) {\n selector = selectors.pop();\n }\n element = element.parentNode;\n parentMatching = selectorMatches(element, selector);\n }\n return selectors.length === 0;\n }\n\n /**\n * @private\n */\n function selectorMatches(element, selector) {\n var nodeName = element.nodeName,\n classNames = element.getAttribute('class'),\n id = element.getAttribute('id'), matcher;\n // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n if (id && selector.length) {\n matcher = new RegExp('#' + id + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n if (classNames && selector.length) {\n classNames = classNames.split(' ');\n for (var i = classNames.length; i--;) {\n matcher = new RegExp('\\\\.' + classNames[i] + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n }\n return selector.length === 0;\n }\n\n /**\n * @private\n * to support IE8 missing getElementById on SVGdocument\n */\n function elementById(doc, id) {\n var el;\n doc.getElementById && (el = doc.getElementById(id));\n if (el) {\n return el;\n }\n var node, i, nodelist = doc.getElementsByTagName('*');\n for (i = 0; i < nodelist.length; i++) {\n node = nodelist[i];\n if (id === node.getAttribute('id')) {\n return node;\n }\n }\n }\n\n /**\n * @private\n */\n function parseUseDirectives(doc) {\n var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']), i = 0;\n\n while (nodelist.length && i < nodelist.length) {\n var el = nodelist[i],\n xlink = el.getAttribute('xlink:href').substr(1),\n x = el.getAttribute('x') || 0,\n y = el.getAttribute('y') || 0,\n el2 = elementById(doc, xlink).cloneNode(true),\n currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')',\n parentNode, oldLength = nodelist.length, attr, j, attrs, l;\n\n applyViewboxTransform(el2);\n if (/^svg$/i.test(el2.nodeName)) {\n var el3 = el2.ownerDocument.createElement('g');\n for (j = 0, attrs = el2.attributes, l = attrs.length; j < l; j++) {\n attr = attrs.item(j);\n el3.setAttribute(attr.nodeName, attr.nodeValue);\n }\n // el2.firstChild != null\n while (el2.firstChild) {\n el3.appendChild(el2.firstChild);\n }\n el2 = el3;\n }\n\n for (j = 0, attrs = el.attributes, l = attrs.length; j < l; j++) {\n attr = attrs.item(j);\n if (attr.nodeName === 'x' || attr.nodeName === 'y' || attr.nodeName === 'xlink:href') {\n continue;\n }\n\n if (attr.nodeName === 'transform') {\n currentTrans = attr.nodeValue + ' ' + currentTrans;\n }\n else {\n el2.setAttribute(attr.nodeName, attr.nodeValue);\n }\n }\n\n el2.setAttribute('transform', currentTrans);\n el2.setAttribute('instantiated_by_use', '1');\n el2.removeAttribute('id');\n parentNode = el.parentNode;\n parentNode.replaceChild(el2, el);\n // some browsers do not shorten nodelist after replaceChild (IE8)\n if (nodelist.length === oldLength) {\n i++;\n }\n }\n }\n\n // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n // matches, e.g.: +14.56e-12, etc.\n var reViewBoxAttrValue = new RegExp(\n '^' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*' +\n '$'\n );\n\n /**\n * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\n function applyViewboxTransform(element) {\n\n var viewBoxAttr = element.getAttribute('viewBox'),\n scaleX = 1,\n scaleY = 1,\n minX = 0,\n minY = 0,\n viewBoxWidth, viewBoxHeight, matrix, el,\n widthAttr = element.getAttribute('width'),\n heightAttr = element.getAttribute('height'),\n x = element.getAttribute('x') || 0,\n y = element.getAttribute('y') || 0,\n preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '',\n missingViewBox = (!viewBoxAttr || !reViewBoxTagNames.test(element.nodeName)\n || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))),\n missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'),\n toBeParsed = missingViewBox && missingDimAttr,\n parsedDim = { }, translateMatrix = '';\n\n parsedDim.width = 0;\n parsedDim.height = 0;\n parsedDim.toBeParsed = toBeParsed;\n\n if (toBeParsed) {\n return parsedDim;\n }\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n return parsedDim;\n }\n\n minX = -parseFloat(viewBoxAttr[1]);\n minY = -parseFloat(viewBoxAttr[2]);\n viewBoxWidth = parseFloat(viewBoxAttr[3]);\n viewBoxHeight = parseFloat(viewBoxAttr[4]);\n\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n }\n else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n }\n\n // default is to preserve aspect ratio\n preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);\n if (preserveAspectRatio.alignX !== 'none') {\n //translate all container for the effect of Mid, Min, Max\n scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX);\n }\n\n if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) {\n return parsedDim;\n }\n\n if (x || y) {\n translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n }\n\n matrix = translateMatrix + ' matrix(' + scaleX +\n ' 0' +\n ' 0 ' +\n scaleY + ' ' +\n (minX * scaleX) + ' ' +\n (minY * scaleY) + ') ';\n\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElement('g');\n // element.firstChild != null\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n element.appendChild(el);\n }\n else {\n el = element;\n matrix = el.getAttribute('transform') + matrix;\n }\n\n el.setAttribute('transform', matrix);\n return parsedDim;\n }\n\n function hasAncestorWithNodeName(element, nodeName) {\n while (element && (element = element.parentNode)) {\n if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', ''))\n && !element.getAttribute('instantiated_by_use')) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @param {Function} callback Callback to call when parsing is finished;\n * It's being passed an array of elements (parsed from a document).\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [parsingOptions] options for parsing document\n * @param {String} [parsingOptions.crossOrigin] crossOrigin settings\n */\n fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {\n if (!doc) {\n return;\n }\n\n parseUseDirectives(doc);\n\n var svgUid = fabric.Object.__uid++,\n options = applyViewboxTransform(doc),\n descendants = fabric.util.toArray(doc.getElementsByTagName('*'));\n options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;\n options.svgUid = svgUid;\n\n if (descendants.length === 0 && fabric.isLikelyNode) {\n // we're likely in node, where \"o3-xml\" library fails to gEBTN(\"*\")\n // https://github.com/ajaxorg/node-o3-xml/issues/21\n descendants = doc.selectNodes('//*[name(.)!=\"svg\"]');\n var arr = [];\n for (var i = 0, len = descendants.length; i < len; i++) {\n arr[i] = descendants[i];\n }\n descendants = arr;\n }\n\n var elements = descendants.filter(function(el) {\n applyViewboxTransform(el);\n return reAllowedSVGTagNames.test(el.nodeName.replace('svg:', '')) &&\n !hasAncestorWithNodeName(el, reNotAllowedAncestors); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n });\n\n if (!elements || (elements && !elements.length)) {\n callback && callback([], {});\n return;\n }\n\n fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc);\n fabric.cssRules[svgUid] = fabric.getCSSRules(doc);\n // Precedence of rules: style > class > attribute\n fabric.parseElements(elements, function(instances) {\n if (callback) {\n callback(instances, options);\n }\n }, clone(options), reviver, parsingOptions);\n };\n\n var reFontDeclaration = new RegExp(\n '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n fabric.reNum +\n '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' + fabric.reNum + '))?\\\\s+(.*)');\n\n extend(fabric, {\n /**\n * Parses a short font declaration, building adding its properties to a style object\n * @static\n * @function\n * @memberOf fabric\n * @param {String} value font declaration\n * @param {Object} oStyle definition\n */\n parseFontDeclaration: function(value, oStyle) {\n var match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\n var fontStyle = match[1],\n // font variant is not used\n // fontVariant = match[2],\n fontWeight = match[3],\n fontSize = match[4],\n lineHeight = match[5],\n fontFamily = match[6];\n\n if (fontStyle) {\n oStyle.fontStyle = fontStyle;\n }\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);\n }\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\n if (lineHeight) {\n oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n }\n },\n\n /**\n * Parses an SVG document, returning all of the gradient declarations found in it\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n */\n getGradientDefs: function(doc) {\n var tagArray = [\n 'linearGradient',\n 'radialGradient',\n 'svg:linearGradient',\n 'svg:radialGradient'],\n elList = _getMultipleNodes(doc, tagArray),\n el, j = 0, id, xlink,\n gradientDefs = { }, idsToXlinkMap = { };\n\n j = elList.length;\n\n while (j--) {\n el = elList[j];\n xlink = el.getAttribute('xlink:href');\n id = el.getAttribute('id');\n if (xlink) {\n idsToXlinkMap[id] = xlink.substr(1);\n }\n gradientDefs[id] = el;\n }\n\n for (id in idsToXlinkMap) {\n var el2 = gradientDefs[idsToXlinkMap[id]].cloneNode(true);\n el = gradientDefs[id];\n while (el2.firstChild) {\n el.appendChild(el2.firstChild);\n }\n }\n return gradientDefs;\n },\n\n /**\n * Returns an object of attributes' name/value, given element and an array of attribute names;\n * Parses parent \"g\" nodes recursively upwards.\n * @static\n * @memberOf fabric\n * @param {DOMElement} element Element to parse\n * @param {Array} attributes Array of attributes to parse\n * @return {Object} object containing parsed attributes' names/values\n */\n parseAttributes: function(element, attributes, svgUid) {\n\n if (!element) {\n return;\n }\n\n var value,\n parentAttributes = { },\n fontSize;\n\n if (typeof svgUid === 'undefined') {\n svgUid = element.getAttribute('svgUid');\n }\n // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n if (element.parentNode && reAllowedParents.test(element.parentNode.nodeName)) {\n parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);\n }\n fontSize = (parentAttributes && parentAttributes.fontSize ) ||\n element.getAttribute('font-size') || fabric.Text.DEFAULT_SVG_FONT_SIZE;\n\n var ownAttributes = attributes.reduce(function(memo, attr) {\n value = element.getAttribute(attr);\n if (value) { // eslint-disable-line\n memo[attr] = value;\n }\n return memo;\n }, { });\n // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n ownAttributes = extend(ownAttributes,\n extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element)));\n\n var normalizedAttr, normalizedValue, normalizedStyle = {};\n for (var attr in ownAttributes) {\n normalizedAttr = normalizeAttr(attr);\n normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n if (normalizedStyle && normalizedStyle.font) {\n fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);\n }\n var mergedAttrs = extend(parentAttributes, normalizedStyle);\n return reAllowedParents.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);\n },\n\n /**\n * Transforms an array of svg elements to corresponding fabric.* instances\n * @static\n * @memberOf fabric\n * @param {Array} elements Array of elements to parse\n * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements)\n * @param {Object} [options] Options object\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n */\n parseElements: function(elements, callback, options, reviver, parsingOptions) {\n new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();\n },\n\n /**\n * Parses \"style\" attribute, retuning an object with values\n * @static\n * @memberOf fabric\n * @param {SVGElement} element Element to parse\n * @return {Object} Objects with values parsed from style attribute of an element\n */\n parseStyleAttribute: function(element) {\n var oStyle = { },\n style = element.getAttribute('style');\n\n if (!style) {\n return oStyle;\n }\n\n if (typeof style === 'string') {\n parseStyleString(style, oStyle);\n }\n else {\n parseStyleObject(style, oStyle);\n }\n\n return oStyle;\n },\n\n /**\n * Parses \"points\" attribute, returning an array of values\n * @static\n * @memberOf fabric\n * @param {String} points points attribute string\n * @return {Array} array of points\n */\n parsePointsAttribute: function(points) {\n\n // points attribute is required and must not be empty\n if (!points) {\n return null;\n }\n\n // replace commas with whitespace and remove bookending whitespace\n points = points.replace(/,/g, ' ').trim();\n\n points = points.split(/\\s+/);\n var parsedPoints = [], i, len;\n\n i = 0;\n len = points.length;\n for (; i < len; i += 2) {\n parsedPoints.push({\n x: parseFloat(points[i]),\n y: parseFloat(points[i + 1])\n });\n }\n\n // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\n\n return parsedPoints;\n },\n\n /**\n * Returns CSS rules for a given SVG document\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} CSS rules of this document\n */\n getCSSRules: function(doc) {\n var styles = doc.getElementsByTagName('style'),\n allRules = { }, rules;\n\n // very crude parsing of style contents\n for (var i = 0, len = styles.length; i < len; i++) {\n // IE9 doesn't support textContent, but provides text instead.\n var styleContents = styles[i].textContent || styles[i].text;\n\n // remove comments\n styleContents = styleContents.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n if (styleContents.trim() === '') {\n continue;\n }\n rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n rules = rules.map(function(rule) { return rule.trim(); });\n rules.forEach(function(rule) {\n\n var match = rule.match(/([\\s\\S]*?)\\s*\\{([^}]*)\\}/),\n ruleObj = { }, declaration = match[2].trim(),\n propertyValuePairs = declaration.replace(/;$/, '').split(/\\s*;\\s*/);\n\n for (var i = 0, len = propertyValuePairs.length; i < len; i++) {\n var pair = propertyValuePairs[i].split(/\\s*:\\s*/),\n property = pair[0],\n value = pair[1];\n ruleObj[property] = value;\n }\n rule = match[1];\n rule.split(',').forEach(function(_rule) {\n _rule = _rule.replace(/^svg/i, '').trim();\n if (_rule === '') {\n return;\n }\n if (allRules[_rule]) {\n fabric.util.object.extend(allRules[_rule], ruleObj);\n }\n else {\n allRules[_rule] = fabric.util.object.clone(ruleObj);\n }\n });\n });\n }\n return allRules;\n },\n\n /**\n * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n * @memberOf fabric\n * @param {String} url\n * @param {Function} callback\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n */\n loadSVGFromURL: function(url, callback, reviver, options) {\n\n url = url.replace(/^\\n\\s*/, '').trim();\n new fabric.util.request(url, {\n method: 'get',\n onComplete: onComplete\n });\n\n function onComplete(r) {\n\n var xml = r.responseXML;\n if (xml && !xml.documentElement && fabric.window.ActiveXObject && r.responseText) {\n xml = new ActiveXObject('Microsoft.XMLDOM');\n xml.async = 'false';\n //IE chokes on DOCTYPE\n xml.loadXML(r.responseText.replace(//i, ''));\n }\n if (!xml || !xml.documentElement) {\n callback && callback(null);\n }\n\n fabric.parseSVGDocument(xml.documentElement, function (results, _options) {\n callback && callback(results, _options);\n }, reviver, options);\n }\n },\n\n /**\n * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n * @memberOf fabric\n * @param {String} string\n * @param {Function} callback\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n */\n loadSVGFromString: function(string, callback, reviver, options) {\n string = string.trim();\n var doc;\n if (typeof DOMParser !== 'undefined') {\n var parser = new DOMParser();\n if (parser && parser.parseFromString) {\n doc = parser.parseFromString(string, 'text/xml');\n }\n }\n else if (fabric.window.ActiveXObject) {\n doc = new ActiveXObject('Microsoft.XMLDOM');\n doc.async = 'false';\n // IE chokes on DOCTYPE\n doc.loadXML(string.replace(//i, ''));\n }\n\n fabric.parseSVGDocument(doc.documentElement, function (results, _options) {\n callback(results, _options);\n }, reviver, options);\n }\n });\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {\n this.elements = elements;\n this.callback = callback;\n this.options = options;\n this.reviver = reviver;\n this.svgUid = (options && options.svgUid) || 0;\n this.parsingOptions = parsingOptions;\n};\n\nfabric.ElementsParser.prototype.parse = function() {\n this.instances = new Array(this.elements.length);\n this.numElements = this.elements.length;\n\n this.createObjects();\n};\n\nfabric.ElementsParser.prototype.createObjects = function() {\n for (var i = 0, len = this.elements.length; i < len; i++) {\n this.elements[i].setAttribute('svgUid', this.svgUid);\n (function(_obj, i) {\n setTimeout(function() {\n _obj.createObject(_obj.elements[i], i);\n }, 0);\n })(this, i);\n }\n};\n\nfabric.ElementsParser.prototype.createObject = function(el, index) {\n var klass = fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))];\n if (klass && klass.fromElement) {\n try {\n this._createObject(klass, el, index);\n }\n catch (err) {\n fabric.log(err);\n }\n }\n else {\n this.checkIfDone();\n }\n};\n\nfabric.ElementsParser.prototype._createObject = function(klass, el, index) {\n if (klass.async) {\n klass.fromElement(el, this.createCallback(index, el), this.options);\n }\n else {\n var obj = klass.fromElement(el, this.options);\n this.resolveGradient(obj, 'fill');\n this.resolveGradient(obj, 'stroke');\n this.reviver && this.reviver(el, obj);\n this.instances[index] = obj;\n this.checkIfDone();\n }\n};\n\nfabric.ElementsParser.prototype.createCallback = function(index, el) {\n var _this = this;\n return function(obj) {\n _this.resolveGradient(obj, 'fill');\n _this.resolveGradient(obj, 'stroke');\n _this.reviver && _this.reviver(el, obj);\n _this.instances[index] = obj;\n _this.checkIfDone();\n };\n};\n\nfabric.ElementsParser.prototype.resolveGradient = function(obj, property) {\n\n var instanceFillValue = obj.get(property);\n if (!(/^url\\(/).test(instanceFillValue)) {\n return;\n }\n var gradientId = instanceFillValue.slice(5, instanceFillValue.length - 1);\n if (fabric.gradientDefs[this.svgUid][gradientId]) {\n obj.set(property,\n fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][gradientId], obj));\n }\n};\n\nfabric.ElementsParser.prototype.checkIfDone = function() {\n if (--this.numElements === 0) {\n this.instances = this.instances.filter(function(el) {\n // eslint-disable-next-line no-eq-null, eqeqeq\n return el != null;\n });\n this.callback(this.instances);\n }\n};\n\n\n(function(global) {\n\n 'use strict';\n\n /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Point) {\n fabric.warn('fabric.Point is already defined');\n return;\n }\n\n fabric.Point = Point;\n\n /**\n * Point class\n * @class fabric.Point\n * @memberOf fabric\n * @constructor\n * @param {Number} x\n * @param {Number} y\n * @return {fabric.Point} thisArg\n */\n function Point(x, y) {\n this.x = x;\n this.y = y;\n }\n\n Point.prototype = /** @lends fabric.Point.prototype */ {\n\n type: 'point',\n\n constructor: Point,\n\n /**\n * Adds another point to this one and returns another one\n * @param {fabric.Point} that\n * @return {fabric.Point} new Point instance with added values\n */\n add: function (that) {\n return new Point(this.x + that.x, this.y + that.y);\n },\n\n /**\n * Adds another point to this one\n * @param {fabric.Point} that\n * @return {fabric.Point} thisArg\n * @chainable\n */\n addEquals: function (that) {\n this.x += that.x;\n this.y += that.y;\n return this;\n },\n\n /**\n * Adds value to this point and returns a new one\n * @param {Number} scalar\n * @return {fabric.Point} new Point with added value\n */\n scalarAdd: function (scalar) {\n return new Point(this.x + scalar, this.y + scalar);\n },\n\n /**\n * Adds value to this point\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n scalarAddEquals: function (scalar) {\n this.x += scalar;\n this.y += scalar;\n return this;\n },\n\n /**\n * Subtracts another point from this point and returns a new one\n * @param {fabric.Point} that\n * @return {fabric.Point} new Point object with subtracted values\n */\n subtract: function (that) {\n return new Point(this.x - that.x, this.y - that.y);\n },\n\n /**\n * Subtracts another point from this point\n * @param {fabric.Point} that\n * @return {fabric.Point} thisArg\n * @chainable\n */\n subtractEquals: function (that) {\n this.x -= that.x;\n this.y -= that.y;\n return this;\n },\n\n /**\n * Subtracts value from this point and returns a new one\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n scalarSubtract: function (scalar) {\n return new Point(this.x - scalar, this.y - scalar);\n },\n\n /**\n * Subtracts value from this point\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n scalarSubtractEquals: function (scalar) {\n this.x -= scalar;\n this.y -= scalar;\n return this;\n },\n\n /**\n * Miltiplies this point by a value and returns a new one\n * TODO: rename in scalarMultiply in 2.0\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n multiply: function (scalar) {\n return new Point(this.x * scalar, this.y * scalar);\n },\n\n /**\n * Miltiplies this point by a value\n * TODO: rename in scalarMultiplyEquals in 2.0\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n multiplyEquals: function (scalar) {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n },\n\n /**\n * Divides this point by a value and returns a new one\n * TODO: rename in scalarDivide in 2.0\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n divide: function (scalar) {\n return new Point(this.x / scalar, this.y / scalar);\n },\n\n /**\n * Divides this point by a value\n * TODO: rename in scalarDivideEquals in 2.0\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n divideEquals: function (scalar) {\n this.x /= scalar;\n this.y /= scalar;\n return this;\n },\n\n /**\n * Returns true if this point is equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n eq: function (that) {\n return (this.x === that.x && this.y === that.y);\n },\n\n /**\n * Returns true if this point is less than another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n lt: function (that) {\n return (this.x < that.x && this.y < that.y);\n },\n\n /**\n * Returns true if this point is less than or equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n lte: function (that) {\n return (this.x <= that.x && this.y <= that.y);\n },\n\n /**\n\n * Returns true if this point is greater another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n gt: function (that) {\n return (this.x > that.x && this.y > that.y);\n },\n\n /**\n * Returns true if this point is greater than or equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n gte: function (that) {\n return (this.x >= that.x && this.y >= that.y);\n },\n\n /**\n * Returns new point which is the result of linear interpolation with this one and another one\n * @param {fabric.Point} that\n * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n * @return {fabric.Point}\n */\n lerp: function (that, t) {\n if (typeof t === 'undefined') {\n t = 0.5;\n }\n t = Math.max(Math.min(1, t), 0);\n return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);\n },\n\n /**\n * Returns distance from this point and another one\n * @param {fabric.Point} that\n * @return {Number}\n */\n distanceFrom: function (that) {\n var dx = this.x - that.x,\n dy = this.y - that.y;\n return Math.sqrt(dx * dx + dy * dy);\n },\n\n /**\n * Returns the point between this point and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n midPointFrom: function (that) {\n return this.lerp(that);\n },\n\n /**\n * Returns a new point which is the min of this and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n min: function (that) {\n return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n },\n\n /**\n * Returns a new point which is the max of this and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n max: function (that) {\n return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n },\n\n /**\n * Returns string representation of this point\n * @return {String}\n */\n toString: function () {\n return this.x + ',' + this.y;\n },\n\n /**\n * Sets x/y of this point\n * @param {Number} x\n * @param {Number} y\n * @chainable\n */\n setXY: function (x, y) {\n this.x = x;\n this.y = y;\n return this;\n },\n\n /**\n * Sets x of this point\n * @param {Number} x\n * @chainable\n */\n setX: function (x) {\n this.x = x;\n return this;\n },\n\n /**\n * Sets y of this point\n * @param {Number} y\n * @chainable\n */\n setY: function (y) {\n this.y = y;\n return this;\n },\n\n /**\n * Sets x/y of this point from another point\n * @param {fabric.Point} that\n * @chainable\n */\n setFromPoint: function (that) {\n this.x = that.x;\n this.y = that.y;\n return this;\n },\n\n /**\n * Swaps x/y of this point and another point\n * @param {fabric.Point} that\n */\n swap: function (that) {\n var x = this.x,\n y = this.y;\n this.x = that.x;\n this.y = that.y;\n that.x = x;\n that.y = y;\n },\n\n /**\n * return a cloned instance of the point\n * @return {fabric.Point}\n */\n clone: function () {\n return new Point(this.x, this.y);\n }\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Intersection) {\n fabric.warn('fabric.Intersection is already defined');\n return;\n }\n\n /**\n * Intersection class\n * @class fabric.Intersection\n * @memberOf fabric\n * @constructor\n */\n function Intersection(status) {\n this.status = status;\n this.points = [];\n }\n\n fabric.Intersection = Intersection;\n\n fabric.Intersection.prototype = /** @lends fabric.Intersection.prototype */ {\n\n constructor: Intersection,\n\n /**\n * Appends a point to intersection\n * @param {fabric.Point} point\n * @return {fabric.Intersection} thisArg\n * @chainable\n */\n appendPoint: function (point) {\n this.points.push(point);\n return this;\n },\n\n /**\n * Appends points to intersection\n * @param {Array} points\n * @return {fabric.Intersection} thisArg\n * @chainable\n */\n appendPoints: function (points) {\n this.points = this.points.concat(points);\n return this;\n }\n };\n\n /**\n * Checks if one line intersects another\n * TODO: rename in intersectSegmentSegment\n * @static\n * @param {fabric.Point} a1\n * @param {fabric.Point} a2\n * @param {fabric.Point} b1\n * @param {fabric.Point} b2\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) {\n var result,\n uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),\n ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),\n uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);\n if (uB !== 0) {\n var ua = uaT / uB,\n ub = ubT / uB;\n if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n result = new Intersection('Intersection');\n result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)));\n }\n else {\n result = new Intersection();\n }\n }\n else {\n if (uaT === 0 || ubT === 0) {\n result = new Intersection('Coincident');\n }\n else {\n result = new Intersection('Parallel');\n }\n }\n return result;\n };\n\n /**\n * Checks if line intersects polygon\n * TODO: rename in intersectSegmentPolygon\n * fix detection of coincident\n * @static\n * @param {fabric.Point} a1\n * @param {fabric.Point} a2\n * @param {Array} points\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectLinePolygon = function(a1, a2, points) {\n var result = new Intersection(),\n length = points.length,\n b1, b2, inter;\n\n for (var i = 0; i < length; i++) {\n b1 = points[i];\n b2 = points[(i + 1) % length];\n inter = Intersection.intersectLineLine(a1, a2, b1, b2);\n\n result.appendPoints(inter.points);\n }\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n return result;\n };\n\n /**\n * Checks if polygon intersects another polygon\n * @static\n * @param {Array} points1\n * @param {Array} points2\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectPolygonPolygon = function (points1, points2) {\n var result = new Intersection(),\n length = points1.length;\n\n for (var i = 0; i < length; i++) {\n var a1 = points1[i],\n a2 = points1[(i + 1) % length],\n inter = Intersection.intersectLinePolygon(a1, a2, points2);\n\n result.appendPoints(inter.points);\n }\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n return result;\n };\n\n /**\n * Checks if polygon intersects rectangle\n * @static\n * @param {Array} points\n * @param {fabric.Point} r1\n * @param {fabric.Point} r2\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) {\n var min = r1.min(r2),\n max = r1.max(r2),\n topRight = new fabric.Point(max.x, min.y),\n bottomLeft = new fabric.Point(min.x, max.y),\n inter1 = Intersection.intersectLinePolygon(min, topRight, points),\n inter2 = Intersection.intersectLinePolygon(topRight, max, points),\n inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points),\n inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points),\n result = new Intersection();\n\n result.appendPoints(inter1.points);\n result.appendPoints(inter2.points);\n result.appendPoints(inter3.points);\n result.appendPoints(inter4.points);\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n return result;\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Color) {\n fabric.warn('fabric.Color is already defined.');\n return;\n }\n\n /**\n * Color class\n * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;\n * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.\n *\n * @class fabric.Color\n * @param {String} color optional in hex or rgb(a) or hsl format or from known color list\n * @return {fabric.Color} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors}\n */\n function Color(color) {\n if (!color) {\n this.setSource([0, 0, 0, 1]);\n }\n else {\n this._tryParsingColor(color);\n }\n }\n\n fabric.Color = Color;\n\n fabric.Color.prototype = /** @lends fabric.Color.prototype */ {\n\n /**\n * @private\n * @param {String|Array} color Color value to parse\n */\n _tryParsingColor: function(color) {\n var source;\n\n if (color in Color.colorNameMap) {\n color = Color.colorNameMap[color];\n }\n\n if (color === 'transparent') {\n source = [255, 255, 255, 0];\n }\n\n if (!source) {\n source = Color.sourceFromHex(color);\n }\n if (!source) {\n source = Color.sourceFromRgb(color);\n }\n if (!source) {\n source = Color.sourceFromHsl(color);\n }\n if (!source) {\n //if color is not recognize let's make black as canvas does\n source = [0, 0, 0, 1];\n }\n if (source) {\n this.setSource(source);\n }\n },\n\n /**\n * Adapted from https://github.com/mjijackson\n * @private\n * @param {Number} r Red color value\n * @param {Number} g Green color value\n * @param {Number} b Blue color value\n * @return {Array} Hsl color\n */\n _rgbToHsl: function(r, g, b) {\n r /= 255; g /= 255; b /= 255;\n\n var h, s, l,\n max = fabric.util.array.max([r, g, b]),\n min = fabric.util.array.min([r, g, b]);\n\n l = (max + min) / 2;\n\n if (max === min) {\n h = s = 0; // achromatic\n }\n else {\n var d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n\n return [\n Math.round(h * 360),\n Math.round(s * 100),\n Math.round(l * 100)\n ];\n },\n\n /**\n * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @return {Array}\n */\n getSource: function() {\n return this._source;\n },\n\n /**\n * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @param {Array} source\n */\n setSource: function(source) {\n this._source = source;\n },\n\n /**\n * Returns color representation in RGB format\n * @return {String} ex: rgb(0-255,0-255,0-255)\n */\n toRgb: function() {\n var source = this.getSource();\n return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')';\n },\n\n /**\n * Returns color representation in RGBA format\n * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n */\n toRgba: function() {\n var source = this.getSource();\n return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')';\n },\n\n /**\n * Returns color representation in HSL format\n * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n */\n toHsl: function() {\n var source = this.getSource(),\n hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)';\n },\n\n /**\n * Returns color representation in HSLA format\n * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n */\n toHsla: function() {\n var source = this.getSource(),\n hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')';\n },\n\n /**\n * Returns color representation in HEX format\n * @return {String} ex: FF5555\n */\n toHex: function() {\n var source = this.getSource(), r, g, b;\n\n r = source[0].toString(16);\n r = (r.length === 1) ? ('0' + r) : r;\n\n g = source[1].toString(16);\n g = (g.length === 1) ? ('0' + g) : g;\n\n b = source[2].toString(16);\n b = (b.length === 1) ? ('0' + b) : b;\n\n return r.toUpperCase() + g.toUpperCase() + b.toUpperCase();\n },\n\n /**\n * Returns color representation in HEXA format\n * @return {String} ex: FF5555CC\n */\n toHexa: function() {\n var source = this.getSource(), a;\n\n a = source[3] * 255;\n a = a.toString(16);\n a = (a.length === 1) ? ('0' + a) : a;\n\n return this.toHex() + a.toUpperCase();\n },\n\n /**\n * Gets value of alpha channel for this color\n * @return {Number} 0-1\n */\n getAlpha: function() {\n return this.getSource()[3];\n },\n\n /**\n * Sets value of alpha channel for this color\n * @param {Number} alpha Alpha value 0-1\n * @return {fabric.Color} thisArg\n */\n setAlpha: function(alpha) {\n var source = this.getSource();\n source[3] = alpha;\n this.setSource(source);\n return this;\n },\n\n /**\n * Transforms color to its grayscale representation\n * @return {fabric.Color} thisArg\n */\n toGrayscale: function() {\n var source = this.getSource(),\n average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10),\n currentAlpha = source[3];\n this.setSource([average, average, average, currentAlpha]);\n return this;\n },\n\n /**\n * Transforms color to its black and white representation\n * @param {Number} threshold\n * @return {fabric.Color} thisArg\n */\n toBlackWhite: function(threshold) {\n var source = this.getSource(),\n average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0),\n currentAlpha = source[3];\n\n threshold = threshold || 127;\n\n average = (Number(average) < Number(threshold)) ? 0 : 255;\n this.setSource([average, average, average, currentAlpha]);\n return this;\n },\n\n /**\n * Overlays color with another color\n * @param {String|fabric.Color} otherColor\n * @return {fabric.Color} thisArg\n */\n overlayWith: function(otherColor) {\n if (!(otherColor instanceof Color)) {\n otherColor = new Color(otherColor);\n }\n\n var result = [],\n alpha = this.getAlpha(),\n otherAlpha = 0.5,\n source = this.getSource(),\n otherSource = otherColor.getSource();\n\n for (var i = 0; i < 3; i++) {\n result.push(Math.round((source[i] * (1 - otherAlpha)) + (otherSource[i] * otherAlpha)));\n }\n\n result[3] = alpha;\n this.setSource(result);\n return this;\n }\n };\n\n /**\n * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))\n * @static\n * @field\n * @memberOf fabric.Color\n */\n // eslint-disable-next-line max-len\n 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*)?\\)$/;\n\n /**\n * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 ))\n * @static\n * @field\n * @memberOf fabric.Color\n */\n fabric.Color.reHSLa = /^hsla?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}\\%)\\s*,\\s*(\\d{1,3}\\%)\\s*(?:\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)$/;\n\n /**\n * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n * @static\n * @field\n * @memberOf fabric.Color\n */\n fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i;\n\n /**\n * Map of the 17 basic color names with HEX code\n * @static\n * @field\n * @memberOf fabric.Color\n * @see: http://www.w3.org/TR/CSS2/syndata.html#color-units\n */\n fabric.Color.colorNameMap = {\n aqua: '#00FFFF',\n black: '#000000',\n blue: '#0000FF',\n fuchsia: '#FF00FF',\n gray: '#808080',\n grey: '#808080',\n green: '#008000',\n lime: '#00FF00',\n maroon: '#800000',\n navy: '#000080',\n olive: '#808000',\n orange: '#FFA500',\n purple: '#800080',\n red: '#FF0000',\n silver: '#C0C0C0',\n teal: '#008080',\n white: '#FFFFFF',\n yellow: '#FFFF00'\n };\n\n /**\n * @private\n * @param {Number} p\n * @param {Number} q\n * @param {Number} t\n * @return {Number}\n */\n function hue2rgb(p, q, t) {\n if (t < 0) {\n t += 1;\n }\n if (t > 1) {\n t -= 1;\n }\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n if (t < 1 / 2) {\n return q;\n }\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n return p;\n }\n\n /**\n * Returns new color object, when given a color in RGB format\n * @memberOf fabric.Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n * @return {fabric.Color}\n */\n fabric.Color.fromRgb = function(color) {\n return Color.fromSource(Color.sourceFromRgb(color));\n };\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n * @memberOf fabric.Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n * @return {Array} source\n */\n fabric.Color.sourceFromRgb = function(color) {\n var match = color.match(Color.reRGBa);\n if (match) {\n var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1),\n g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1),\n b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1);\n\n return [\n parseInt(r, 10),\n parseInt(g, 10),\n parseInt(b, 10),\n match[4] ? parseFloat(match[4]) : 1\n ];\n }\n };\n\n /**\n * Returns new color object, when given a color in RGBA format\n * @static\n * @function\n * @memberOf fabric.Color\n * @param {String} color\n * @return {fabric.Color}\n */\n fabric.Color.fromRgba = Color.fromRgb;\n\n /**\n * Returns new color object, when given a color in HSL format\n * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n * @memberOf fabric.Color\n * @return {fabric.Color}\n */\n fabric.Color.fromHsl = function(color) {\n return Color.fromSource(Color.sourceFromHsl(color));\n };\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n * Adapted from https://github.com/mjijackson\n * @memberOf fabric.Color\n * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n * @return {Array} source\n * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n */\n fabric.Color.sourceFromHsl = function(color) {\n var match = color.match(Color.reHSLa);\n if (!match) {\n return;\n }\n\n var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360,\n s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1),\n l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1),\n r, g, b;\n\n if (s === 0) {\n r = g = b = l;\n }\n else {\n var q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n p = l * 2 - q;\n\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n match[4] ? parseFloat(match[4]) : 1\n ];\n };\n\n /**\n * Returns new color object, when given a color in HSLA format\n * @static\n * @function\n * @memberOf fabric.Color\n * @param {String} color\n * @return {fabric.Color}\n */\n fabric.Color.fromHsla = Color.fromHsl;\n\n /**\n * Returns new color object, when given a color in HEX format\n * @static\n * @memberOf fabric.Color\n * @param {String} color Color value ex: FF5555\n * @return {fabric.Color}\n */\n fabric.Color.fromHex = function(color) {\n return Color.fromSource(Color.sourceFromHex(color));\n };\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n * @static\n * @memberOf fabric.Color\n * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n * @return {Array} source\n */\n fabric.Color.sourceFromHex = function(color) {\n if (color.match(Color.reHex)) {\n var value = color.slice(color.indexOf('#') + 1),\n isShortNotation = (value.length === 3 || value.length === 4),\n isRGBa = (value.length === 8 || value.length === 4),\n r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2),\n g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4),\n b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6),\n a = isRGBa ? (isShortNotation ? (value.charAt(3) + value.charAt(3)) : value.substring(6, 8)) : 'FF';\n\n return [\n parseInt(r, 16),\n parseInt(g, 16),\n parseInt(b, 16),\n parseFloat((parseInt(a, 16) / 255).toFixed(2))\n ];\n }\n };\n\n /**\n * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5])\n * @static\n * @memberOf fabric.Color\n * @param {Array} source\n * @return {fabric.Color}\n */\n fabric.Color.fromSource = function(source) {\n var oColor = new Color();\n oColor.setSource(source);\n return oColor;\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n /* _FROM_SVG_START_ */\n function getColorStop(el) {\n var style = el.getAttribute('style'),\n offset = el.getAttribute('offset') || 0,\n color, colorAlpha, opacity;\n\n // convert percents to absolute values\n offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);\n offset = offset < 0 ? 0 : offset > 1 ? 1 : offset;\n if (style) {\n var keyValuePairs = style.split(/\\s*;\\s*/);\n\n if (keyValuePairs[keyValuePairs.length - 1] === '') {\n keyValuePairs.pop();\n }\n\n for (var i = keyValuePairs.length; i--; ) {\n\n var split = keyValuePairs[i].split(/\\s*:\\s*/),\n key = split[0].trim(),\n value = split[1].trim();\n\n if (key === 'stop-color') {\n color = value;\n }\n else if (key === 'stop-opacity') {\n opacity = value;\n }\n }\n }\n\n if (!color) {\n color = el.getAttribute('stop-color') || 'rgb(0,0,0)';\n }\n if (!opacity) {\n opacity = el.getAttribute('stop-opacity');\n }\n\n color = new fabric.Color(color);\n colorAlpha = color.getAlpha();\n opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);\n opacity *= colorAlpha;\n\n return {\n offset: offset,\n color: color.toRgb(),\n opacity: opacity\n };\n }\n\n function getLinearCoords(el) {\n return {\n x1: el.getAttribute('x1') || 0,\n y1: el.getAttribute('y1') || 0,\n x2: el.getAttribute('x2') || '100%',\n y2: el.getAttribute('y2') || 0\n };\n }\n\n function getRadialCoords(el) {\n return {\n x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',\n y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',\n r1: 0,\n x2: el.getAttribute('cx') || '50%',\n y2: el.getAttribute('cy') || '50%',\n r2: el.getAttribute('r') || '50%'\n };\n }\n /* _FROM_SVG_END_ */\n\n var clone = fabric.util.object.clone;\n\n /**\n * Gradient class\n * @class fabric.Gradient\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n * @see {@link fabric.Gradient#initialize} for constructor definition\n */\n fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {\n\n /**\n * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n offsetX: 0,\n\n /**\n * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n offsetY: 0,\n\n /**\n * Constructor\n * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops\n * @return {fabric.Gradient} thisArg\n */\n initialize: function(options) {\n options || (options = { });\n\n var coords = { };\n\n this.id = fabric.Object.__uid++;\n this.type = options.type || 'linear';\n\n coords = {\n x1: options.coords.x1 || 0,\n y1: options.coords.y1 || 0,\n x2: options.coords.x2 || 0,\n y2: options.coords.y2 || 0\n };\n\n if (this.type === 'radial') {\n coords.r1 = options.coords.r1 || 0;\n coords.r2 = options.coords.r2 || 0;\n }\n this.coords = coords;\n this.colorStops = options.colorStops.slice();\n if (options.gradientTransform) {\n this.gradientTransform = options.gradientTransform;\n }\n this.offsetX = options.offsetX || this.offsetX;\n this.offsetY = options.offsetY || this.offsetY;\n },\n\n /**\n * Adds another colorStop\n * @param {Object} colorStop Object with offset and color\n * @return {fabric.Gradient} thisArg\n */\n addColorStop: function(colorStops) {\n for (var position in colorStops) {\n var color = new fabric.Color(colorStops[position]);\n this.colorStops.push({\n offset: parseFloat(position),\n color: color.toRgb(),\n opacity: color.getAlpha()\n });\n }\n return this;\n },\n\n /**\n * Returns object representation of a gradient\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object}\n */\n toObject: function(propertiesToInclude) {\n var object = {\n type: this.type,\n coords: this.coords,\n colorStops: this.colorStops,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform\n };\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n return object;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an gradient\n * @param {Object} object Object to create a gradient for\n * @return {String} SVG representation of an gradient (linear/radial)\n */\n toSVG: function(object) {\n var coords = clone(this.coords, true),\n markup, commonAttributes, colorStops = clone(this.colorStops, true),\n needsSwap = coords.r1 > coords.r2;\n // colorStops must be sorted ascending\n colorStops.sort(function(a, b) {\n return a.offset - b.offset;\n });\n\n if (!(object.group && object.group.type === 'path-group')) {\n for (var prop in coords) {\n if (prop === 'x1' || prop === 'x2') {\n coords[prop] += this.offsetX - object.width / 2;\n }\n else if (prop === 'y1' || prop === 'y2') {\n coords[prop] += this.offsetY - object.height / 2;\n }\n }\n }\n\n commonAttributes = 'id=\"SVGID_' + this.id +\n '\" gradientUnits=\"userSpaceOnUse\"';\n if (this.gradientTransform) {\n commonAttributes += ' gradientTransform=\"matrix(' + this.gradientTransform.join(' ') + ')\" ';\n }\n if (this.type === 'linear') {\n markup = [\n '\\n'\n ];\n }\n else if (this.type === 'radial') {\n // svg radial gradient has just 1 radius. the biggest.\n markup = [\n '\\n'\n ];\n }\n\n if (this.type === 'radial') {\n if (needsSwap) {\n // svg goes from internal to external radius. if radius are inverted, swap color stops.\n colorStops = colorStops.concat();\n colorStops.reverse();\n for (var i = 0; i < colorStops.length; i++) {\n colorStops[i].offset = 1 - colorStops[i].offset;\n }\n }\n var minRadius = Math.min(coords.r1, coords.r2);\n if (minRadius > 0) {\n // i have to shift all colorStops and add new one in 0.\n var maxRadius = Math.max(coords.r1, coords.r2),\n percentageShift = minRadius / maxRadius;\n for (var i = 0; i < colorStops.length; i++) {\n colorStops[i].offset += percentageShift * (1 - colorStops[i].offset);\n }\n }\n }\n\n for (var i = 0; i < colorStops.length; i++) {\n var colorStop = colorStops[i];\n markup.push(\n '\\n'\n );\n }\n\n markup.push((this.type === 'linear' ? '\\n' : '\\n'));\n\n return markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns an instance of CanvasGradient\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} object\n * @return {CanvasGradient}\n */\n toLive: function(ctx, object) {\n var gradient, prop, coords = fabric.util.object.clone(this.coords);\n\n if (!this.type) {\n return;\n }\n\n if (object.group && object.group.type === 'path-group') {\n for (prop in coords) {\n if (prop === 'x1' || prop === 'x2') {\n coords[prop] += -this.offsetX + object.width / 2;\n }\n else if (prop === 'y1' || prop === 'y2') {\n coords[prop] += -this.offsetY + object.height / 2;\n }\n }\n }\n\n if (this.type === 'linear') {\n gradient = ctx.createLinearGradient(\n coords.x1, coords.y1, coords.x2, coords.y2);\n }\n else if (this.type === 'radial') {\n gradient = ctx.createRadialGradient(\n coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);\n }\n\n for (var i = 0, len = this.colorStops.length; i < len; i++) {\n var color = this.colorStops[i].color,\n opacity = this.colorStops[i].opacity,\n offset = this.colorStops[i].offset;\n\n if (typeof opacity !== 'undefined') {\n color = new fabric.Color(color).setAlpha(opacity).toRgba();\n }\n gradient.addColorStop(offset, color);\n }\n\n return gradient;\n }\n });\n\n fabric.util.object.extend(fabric.Gradient, {\n\n /* _FROM_SVG_START_ */\n /**\n * Returns {@link fabric.Gradient} instance from an SVG element\n * @static\n * @memberOf fabric.Gradient\n * @param {SVGGradientElement} el SVG gradient element\n * @param {fabric.Object} instance\n * @return {fabric.Gradient} Gradient instance\n * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n */\n fromElement: function(el, instance) {\n\n /**\n * @example:\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n */\n\n var colorStopEls = el.getElementsByTagName('stop'),\n type,\n gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',\n gradientTransform = el.getAttribute('gradientTransform'),\n colorStops = [],\n coords, ellipseMatrix;\n\n if (el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT') {\n type = 'linear';\n }\n else {\n type = 'radial';\n }\n\n if (type === 'linear') {\n coords = getLinearCoords(el);\n }\n else if (type === 'radial') {\n coords = getRadialCoords(el);\n }\n\n for (var i = colorStopEls.length; i--; ) {\n colorStops.push(getColorStop(colorStopEls[i]));\n }\n\n ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits);\n\n var gradient = new fabric.Gradient({\n type: type,\n coords: coords,\n colorStops: colorStops,\n offsetX: -instance.left,\n offsetY: -instance.top\n });\n\n if (gradientTransform || ellipseMatrix !== '') {\n gradient.gradientTransform = fabric.parseTransformAttribute((gradientTransform || '') + ellipseMatrix);\n }\n return gradient;\n },\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Gradient} instance from its object representation\n * @static\n * @memberOf fabric.Gradient\n * @param {Object} obj\n * @param {Object} [options] Options object\n */\n forObject: function(obj, options) {\n options || (options = { });\n _convertPercentUnitsToValues(obj, options.coords, 'userSpaceOnUse');\n return new fabric.Gradient(options);\n }\n });\n\n /**\n * @private\n */\n function _convertPercentUnitsToValues(object, options, gradientUnits) {\n var propValue, addFactor = 0, multFactor = 1, ellipseMatrix = '';\n for (var prop in options) {\n if (options[prop] === 'Infinity') {\n options[prop] = 1;\n }\n else if (options[prop] === '-Infinity') {\n options[prop] = 0;\n }\n propValue = parseFloat(options[prop], 10);\n if (typeof options[prop] === 'string' && /^\\d+%$/.test(options[prop])) {\n multFactor = 0.01;\n }\n else {\n multFactor = 1;\n }\n if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n multFactor *= gradientUnits === 'objectBoundingBox' ? object.width : 1;\n addFactor = gradientUnits === 'objectBoundingBox' ? object.left || 0 : 0;\n }\n else if (prop === 'y1' || prop === 'y2') {\n multFactor *= gradientUnits === 'objectBoundingBox' ? object.height : 1;\n addFactor = gradientUnits === 'objectBoundingBox' ? object.top || 0 : 0;\n }\n options[prop] = propValue * multFactor + addFactor;\n }\n if (object.type === 'ellipse' &&\n options.r2 !== null &&\n gradientUnits === 'objectBoundingBox' &&\n object.rx !== object.ry) {\n\n var scaleFactor = object.ry / object.rx;\n ellipseMatrix = ' scale(1, ' + scaleFactor + ')';\n if (options.y1) {\n options.y1 /= scaleFactor;\n }\n if (options.y2) {\n options.y2 /= scaleFactor;\n }\n }\n return ellipseMatrix;\n }\n})();\n\n\n(function() {\n\n 'use strict';\n\n var toFixed = fabric.util.toFixed;\n\n /**\n * Pattern class\n * @class fabric.Pattern\n * @see {@link http://fabricjs.com/patterns|Pattern demo}\n * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo}\n * @see {@link fabric.Pattern#initialize} for constructor definition\n */\n\n\n fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ {\n\n /**\n * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n * @type String\n * @default\n */\n repeat: 'repeat',\n\n /**\n * Pattern horizontal offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetX: 0,\n\n /**\n * Pattern vertical offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetY: 0,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @param {Function} [callback] function to invoke after callback init.\n * @return {fabric.Pattern} thisArg\n */\n initialize: function(options, callback) {\n options || (options = { });\n\n this.id = fabric.Object.__uid++;\n this.setOptions(options);\n if (!options.source || (options.source && typeof options.source !== 'string')) {\n callback && callback(this);\n return;\n }\n // function string\n if (typeof fabric.util.getFunctionBody(options.source) !== 'undefined') {\n this.source = new Function(fabric.util.getFunctionBody(options.source));\n callback && callback(this);\n }\n else {\n // img src string\n var _this = this;\n this.source = fabric.util.createImage();\n fabric.util.loadImage(options.source, function(img) {\n _this.source = img;\n callback && callback(_this);\n });\n }\n },\n\n /**\n * Returns object representation of a pattern\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of a pattern instance\n */\n toObject: function(propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n source, object;\n\n // callback\n if (typeof this.source === 'function') {\n source = String(this.source);\n }\n // element\n else if (typeof this.source.src === 'string') {\n source = this.source.src;\n }\n // element\n else if (typeof this.source === 'object' && this.source.toDataURL) {\n source = this.source.toDataURL();\n }\n\n object = {\n type: 'pattern',\n source: source,\n repeat: this.repeat,\n offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS),\n offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS),\n };\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n return object;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a pattern\n * @param {fabric.Object} object\n * @return {String} SVG representation of a pattern\n */\n toSVG: function(object) {\n var patternSource = typeof this.source === 'function' ? this.source() : this.source,\n patternWidth = patternSource.width / object.width,\n patternHeight = patternSource.height / object.height,\n patternOffsetX = this.offsetX / object.width,\n patternOffsetY = this.offsetY / object.height,\n patternImgSrc = '';\n if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') {\n patternHeight = 1;\n }\n if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') {\n patternWidth = 1;\n }\n if (patternSource.src) {\n patternImgSrc = patternSource.src;\n }\n else if (patternSource.toDataURL) {\n patternImgSrc = patternSource.toDataURL();\n }\n\n return '\\n' +\n '\\n' +\n '\\n';\n },\n /* _TO_SVG_END_ */\n\n setOptions: function(options) {\n for (var prop in options) {\n this[prop] = options[prop];\n }\n },\n\n /**\n * Returns an instance of CanvasPattern\n * @param {CanvasRenderingContext2D} ctx Context to create pattern\n * @return {CanvasPattern}\n */\n toLive: function(ctx) {\n var source = typeof this.source === 'function' ? this.source() : this.source;\n\n // if the image failed to load, return, and allow rest to continue loading\n if (!source) {\n return '';\n }\n\n // if an image\n if (typeof source.src !== 'undefined') {\n if (!source.complete) {\n return '';\n }\n if (source.naturalWidth === 0 || source.naturalHeight === 0) {\n return '';\n }\n }\n return ctx.createPattern(source, this.repeat);\n }\n });\n})();\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n toFixed = fabric.util.toFixed;\n\n if (fabric.Shadow) {\n fabric.warn('fabric.Shadow is already defined.');\n return;\n }\n\n /**\n * Shadow class\n * @class fabric.Shadow\n * @see {@link http://fabricjs.com/shadows|Shadow demo}\n * @see {@link fabric.Shadow#initialize} for constructor definition\n */\n fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ {\n\n /**\n * Shadow color\n * @type String\n * @default\n */\n color: 'rgb(0,0,0)',\n\n /**\n * Shadow blur\n * @type Number\n */\n blur: 0,\n\n /**\n * Shadow horizontal offset\n * @type Number\n * @default\n */\n offsetX: 0,\n\n /**\n * Shadow vertical offset\n * @type Number\n * @default\n */\n offsetY: 0,\n\n /**\n * Whether the shadow should affect stroke operations\n * @type Boolean\n * @default\n */\n affectStroke: false,\n\n /**\n * Indicates whether toObject should include default values\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * Constructor\n * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetX properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px, \"2px 2px 10px rgba(0,0,0,0.2)\")\n * @return {fabric.Shadow} thisArg\n */\n initialize: function(options) {\n\n if (typeof options === 'string') {\n options = this._parseShadow(options);\n }\n\n for (var prop in options) {\n this[prop] = options[prop];\n }\n\n this.id = fabric.Object.__uid++;\n },\n\n /**\n * @private\n * @param {String} shadow Shadow value to parse\n * @return {Object} Shadow object with color, offsetX, offsetY and blur\n */\n _parseShadow: function(shadow) {\n var shadowStr = shadow.trim(),\n offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [],\n color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)';\n\n return {\n color: color.trim(),\n offsetX: parseInt(offsetsAndBlur[1], 10) || 0,\n offsetY: parseInt(offsetsAndBlur[2], 10) || 0,\n blur: parseInt(offsetsAndBlur[3], 10) || 0\n };\n },\n\n /**\n * Returns a string representation of an instance\n * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n * @return {String} Returns CSS3 text-shadow declaration\n */\n toString: function() {\n return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a shadow\n * @param {fabric.Object} object\n * @return {String} SVG representation of a shadow\n */\n toSVG: function(object) {\n var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n offset = fabric.util.rotateVector(\n { x: this.offsetX, y: this.offsetY },\n fabric.util.degreesToRadians(-object.angle)),\n BLUR_BOX = 20;\n\n if (object.width && object.height) {\n //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n // we add some extra space to filter box to contain the blur ( 20 )\n fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n }\n if (object.flipX) {\n offset.x *= -1;\n }\n if (object.flipY) {\n offset.y *= -1;\n }\n return (\n '\\n' +\n '\\t\\n' +\n '\\t\\n' +\n '\\t\\n' +\n '\\t\\n' +\n '\\t\\n' +\n '\\t\\t\\n' +\n '\\t\\t\\n' +\n '\\t\\n' +\n '\\n');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns object representation of a shadow\n * @return {Object} Object representation of a shadow instance\n */\n toObject: function() {\n if (this.includeDefaultValues) {\n return {\n color: this.color,\n blur: this.blur,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n affectStroke: this.affectStroke\n };\n }\n var obj = { }, proto = fabric.Shadow.prototype;\n\n ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke'].forEach(function(prop) {\n if (this[prop] !== proto[prop]) {\n obj[prop] = this[prop];\n }\n }, this);\n\n return obj;\n }\n });\n\n /**\n * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n * @static\n * @field\n * @memberOf fabric.Shadow\n */\n // eslint-disable-next-line max-len\n fabric.Shadow.reOffsetsAndBlur = /(?:\\s|^)(-?\\d+(?:px)?(?:\\s?|$))?(-?\\d+(?:px)?(?:\\s?|$))?(\\d+(?:px)?)?(?:\\s?|$)(?:$|\\s)/;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function () {\n\n 'use strict';\n\n if (fabric.StaticCanvas) {\n fabric.warn('fabric.StaticCanvas is already defined.');\n return;\n }\n\n // aliases for faster resolution\n var extend = fabric.util.object.extend,\n getElementOffset = fabric.util.getElementOffset,\n removeFromArray = fabric.util.removeFromArray,\n toFixed = fabric.util.toFixed,\n transformPoint = fabric.util.transformPoint,\n invertTransform = fabric.util.invertTransform,\n\n CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element');\n\n /**\n * Static canvas class\n * @class fabric.StaticCanvas\n * @mixes fabric.Collection\n * @mixes fabric.Observable\n * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n * @see {@link fabric.StaticCanvas#initialize} for constructor definition\n * @fires before:render\n * @fires after:render\n * @fires canvas:cleared\n * @fires object:added\n * @fires object:removed\n */\n fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(el, options) {\n options || (options = { });\n\n this._initStatic(el, options);\n },\n\n /**\n * Background color of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}.\n * @type {(String|fabric.Pattern)}\n * @default\n */\n backgroundColor: '',\n\n /**\n * Background image of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setBackgroundImage}.\n * Backwards incompatibility note: The \"backgroundImageOpacity\"\n * and \"backgroundImageStretch\" properties are deprecated since 1.3.9.\n * Use {@link fabric.Image#opacity}, {@link fabric.Image#width} and {@link fabric.Image#height}.\n * @type fabric.Image\n * @default\n */\n backgroundImage: null,\n\n /**\n * Overlay color of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setOverlayColor}\n * @since 1.3.9\n * @type {(String|fabric.Pattern)}\n * @default\n */\n overlayColor: '',\n\n /**\n * Overlay image of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setOverlayImage}.\n * Backwards incompatibility note: The \"overlayImageLeft\"\n * and \"overlayImageTop\" properties are deprecated since 1.3.9.\n * Use {@link fabric.Image#left} and {@link fabric.Image#top}.\n * @type fabric.Image\n * @default\n */\n overlayImage: null,\n\n /**\n * Indicates whether toObject/toDatalessObject should include default values\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * Indicates whether objects' state should be saved\n * @type Boolean\n * @default\n */\n stateful: false,\n\n /**\n * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove} should also re-render canvas.\n * Disabling this option could give a great performance boost when adding/removing a lot of objects to/from canvas at once\n * (followed by a manual rendering after addition/deletion)\n * @type Boolean\n * @default\n */\n renderOnAddRemove: true,\n\n /**\n * Function that determines clipping of entire canvas area\n * Being passed context as first argument. See clipping canvas area in {@link https://github.com/kangax/fabric.js/wiki/FAQ}\n * @type Function\n * @default\n */\n clipTo: null,\n\n /**\n * Indicates whether object controls (borders/controls) are rendered above overlay image\n * @type Boolean\n * @default\n */\n controlsAboveOverlay: false,\n\n /**\n * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n * @type Boolean\n * @default\n */\n allowTouchScrolling: false,\n\n /**\n * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n * @type Boolean\n * @default\n */\n imageSmoothingEnabled: true,\n\n /**\n * The transformation (in the format of Canvas transform) which focuses the viewport\n * @type Array\n * @default\n */\n viewportTransform: fabric.iMatrix.concat(),\n\n /**\n * if set to false background image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n backgroundVpt: true,\n\n /**\n * if set to false overlya image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n overlayVpt: true,\n\n /**\n * Callback; invoked right before object is about to be scaled/rotated\n */\n onBeforeScaleRotate: function () {\n /* NOOP */\n },\n\n /**\n * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n */\n enableRetinaScaling: true,\n\n /**\n * Describe canvas element extension over design\n * properties are tl,tr,bl,br.\n * if canvas is not zoomed/panned those points are the four corner of canvas\n * if canvas is viewportTransformed you those points indicate the extension\n * of canvas element in plain untrasformed coordinates\n * The coordinates get updated with @method calcViewportBoundaries.\n * @memberOf fabric.StaticCanvas.prototype\n */\n vptCoords: { },\n\n /**\n * Based on vptCoords and object.aCoords, skip rendering of objects that\n * are not included in current viewport.\n * May greatly help in applications with crowded canvas and use of zoom/pan\n * If One of the corner of the bounding box of the object is on the canvas\n * the objects get rendered.\n * @memberOf fabric.StaticCanvas.prototype\n */\n skipOffscreen: false,\n\n /**\n * @private\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n */\n _initStatic: function(el, options) {\n var cb = fabric.StaticCanvas.prototype.renderAll.bind(this);\n this._objects = [];\n this._createLowerCanvas(el);\n this._initOptions(options);\n this._setImageSmoothing();\n // only initialize retina scaling once\n if (!this.interactive) {\n this._initRetinaScaling();\n }\n\n if (options.overlayImage) {\n this.setOverlayImage(options.overlayImage, cb);\n }\n if (options.backgroundImage) {\n this.setBackgroundImage(options.backgroundImage, cb);\n }\n if (options.backgroundColor) {\n this.setBackgroundColor(options.backgroundColor, cb);\n }\n if (options.overlayColor) {\n this.setOverlayColor(options.overlayColor, cb);\n }\n this.calcOffset();\n },\n\n /**\n * @private\n */\n _isRetinaScaling: function() {\n return (fabric.devicePixelRatio !== 1 && this.enableRetinaScaling);\n },\n\n /**\n * @private\n * @return {Number} retinaScaling if applied, otherwise 1;\n */\n getRetinaScaling: function() {\n return this._isRetinaScaling() ? fabric.devicePixelRatio : 1;\n },\n\n /**\n * @private\n */\n _initRetinaScaling: function() {\n if (!this._isRetinaScaling()) {\n return;\n }\n this.lowerCanvasEl.setAttribute('width', this.width * fabric.devicePixelRatio);\n this.lowerCanvasEl.setAttribute('height', this.height * fabric.devicePixelRatio);\n\n this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio);\n },\n\n /**\n * Calculates canvas element offset relative to the document\n * This method is also attached as \"resize\" event handler of window\n * @return {fabric.Canvas} instance\n * @chainable\n */\n calcOffset: function () {\n this._offset = getElementOffset(this.lowerCanvasEl);\n return this;\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas\n * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to\n * @param {Function} callback callback to invoke when image is loaded and set as an overlay\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}.\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo}\n * @example Normal overlayImage with left/top = 0\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * // Needed to position overlayImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example overlayImage with different properties\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top'\n * });\n * @example Stretched overlayImage #1 - width/height correspond to canvas width/height\n * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img) {\n * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n * canvas.setOverlayImage(img, canvas.renderAll.bind(canvas));\n * });\n * @example Stretched overlayImage #2 - width/height correspond to canvas width/height\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * width: canvas.width,\n * height: canvas.height,\n * // Needed to position overlayImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example overlayImage loaded from cross-origin\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top',\n * crossOrigin: 'anonymous'\n * });\n */\n setOverlayImage: function (image, callback, options) {\n return this.__setBgOverlayImage('overlayImage', image, callback, options);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas\n * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to\n * @param {Function} callback Callback to invoke when image is loaded and set as background\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}.\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/YH9yD/|jsFiddle demo}\n * @example Normal backgroundImage with left/top = 0\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * // Needed to position backgroundImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example backgroundImage with different properties\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top'\n * });\n * @example Stretched backgroundImage #1 - width/height correspond to canvas width/height\n * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img) {\n * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n * canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));\n * });\n * @example Stretched backgroundImage #2 - width/height correspond to canvas width/height\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * width: canvas.width,\n * height: canvas.height,\n * // Needed to position backgroundImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example backgroundImage loaded from cross-origin\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top',\n * crossOrigin: 'anonymous'\n * });\n */\n setBackgroundImage: function (image, callback, options) {\n return this.__setBgOverlayImage('backgroundImage', image, callback, options);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#overlayColor|background color} for this canvas\n * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set background color to\n * @param {Function} callback Callback to invoke when background color is set\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo}\n * @example Normal overlayColor - color value\n * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n * @example fabric.Pattern used as overlayColor\n * canvas.setOverlayColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png'\n * }, canvas.renderAll.bind(canvas));\n * @example fabric.Pattern used as overlayColor with repeat and offset\n * canvas.setOverlayColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png',\n * repeat: 'repeat',\n * offsetX: 200,\n * offsetY: 100\n * }, canvas.renderAll.bind(canvas));\n */\n setOverlayColor: function(overlayColor, callback) {\n return this.__setBgOverlayColor('overlayColor', overlayColor, callback);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas\n * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to\n * @param {Function} callback Callback to invoke when background color is set\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo}\n * @example Normal backgroundColor - color value\n * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n * @example fabric.Pattern used as backgroundColor\n * canvas.setBackgroundColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png'\n * }, canvas.renderAll.bind(canvas));\n * @example fabric.Pattern used as backgroundColor with repeat and offset\n * canvas.setBackgroundColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png',\n * repeat: 'repeat',\n * offsetX: 200,\n * offsetY: 100\n * }, canvas.renderAll.bind(canvas));\n */\n setBackgroundColor: function(backgroundColor, callback) {\n return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback);\n },\n\n /**\n * @private\n * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-imagesmoothingenabled|WhatWG Canvas Standard}\n */\n _setImageSmoothing: function() {\n var ctx = this.getContext();\n\n ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled\n || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;\n ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;\n },\n\n /**\n * @private\n * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage}\n * or {@link fabric.StaticCanvas#overlayImage|overlayImage})\n * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to\n * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}.\n */\n __setBgOverlayImage: function(property, image, callback, options) {\n if (typeof image === 'string') {\n fabric.util.loadImage(image, function(img) {\n img && (this[property] = new fabric.Image(img, options));\n callback && callback(img);\n }, this, options && options.crossOrigin);\n }\n else {\n options && image.setOptions(options);\n this[property] = image;\n callback && callback(image);\n }\n\n return this;\n },\n\n /**\n * @private\n * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor}\n * or {@link fabric.StaticCanvas#overlayColor|overlayColor})\n * @param {(Object|String|null)} color Object with pattern information, color value or null\n * @param {Function} [callback] Callback is invoked when color is set\n */\n __setBgOverlayColor: function(property, color, callback) {\n this[property] = color;\n this._initGradient(color, property);\n this._initPattern(color, property, callback);\n return this;\n },\n\n /**\n * @private\n */\n _createCanvasElement: function(canvasEl) {\n var element = fabric.util.createCanvasElement(canvasEl);\n if (!element.style) {\n element.style = { };\n }\n if (!element) {\n throw CANVAS_INIT_ERROR;\n }\n if (typeof element.getContext === 'undefined') {\n throw CANVAS_INIT_ERROR;\n }\n return element;\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initOptions: function (options) {\n this._setOptions(options);\n\n this.width = this.width || parseInt(this.lowerCanvasEl.width, 10) || 0;\n this.height = this.height || parseInt(this.lowerCanvasEl.height, 10) || 0;\n\n if (!this.lowerCanvasEl.style) {\n return;\n }\n\n this.lowerCanvasEl.width = this.width;\n this.lowerCanvasEl.height = this.height;\n\n this.lowerCanvasEl.style.width = this.width + 'px';\n this.lowerCanvasEl.style.height = this.height + 'px';\n\n this.viewportTransform = this.viewportTransform.slice();\n },\n\n /**\n * Creates a bottom canvas\n * @private\n * @param {HTMLElement} [canvasEl]\n */\n _createLowerCanvas: function (canvasEl) {\n this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(canvasEl);\n\n fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas');\n\n if (this.interactive) {\n this._applyCanvasStyle(this.lowerCanvasEl);\n }\n\n this.contextContainer = this.lowerCanvasEl.getContext('2d');\n },\n\n /**\n * Returns canvas width (in px)\n * @return {Number}\n */\n getWidth: function () {\n return this.width;\n },\n\n /**\n * Returns canvas height (in px)\n * @return {Number}\n */\n getHeight: function () {\n return this.height;\n },\n\n /**\n * Sets width of this canvas instance\n * @param {Number|String} value Value to set width to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setWidth: function (value, options) {\n return this.setDimensions({ width: value }, options);\n },\n\n /**\n * Sets height of this canvas instance\n * @param {Number|String} value Value to set height to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setHeight: function (value, options) {\n return this.setDimensions({ height: value }, options);\n },\n\n /**\n * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n * @param {Object} dimensions Object with width/height properties\n * @param {Number|String} [dimensions.width] Width of canvas element\n * @param {Number|String} [dimensions.height] Height of canvas element\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setDimensions: function (dimensions, options) {\n var cssValue;\n\n options = options || {};\n\n for (var prop in dimensions) {\n cssValue = dimensions[prop];\n\n if (!options.cssOnly) {\n this._setBackstoreDimension(prop, dimensions[prop]);\n cssValue += 'px';\n }\n\n if (!options.backstoreOnly) {\n this._setCssDimension(prop, cssValue);\n }\n }\n this._initRetinaScaling();\n this._setImageSmoothing();\n this.calcOffset();\n\n if (!options.cssOnly) {\n this.renderAll();\n }\n\n return this;\n },\n\n /**\n * Helper for setting width/height\n * @private\n * @param {String} prop property (width|height)\n * @param {Number} value value to set property to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n _setBackstoreDimension: function (prop, value) {\n this.lowerCanvasEl[prop] = value;\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl[prop] = value;\n }\n\n if (this.cacheCanvasEl) {\n this.cacheCanvasEl[prop] = value;\n }\n\n this[prop] = value;\n\n return this;\n },\n\n /**\n * Helper for setting css width/height\n * @private\n * @param {String} prop property (width|height)\n * @param {String} value value to set property to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n _setCssDimension: function (prop, value) {\n this.lowerCanvasEl.style[prop] = value;\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl.style[prop] = value;\n }\n\n if (this.wrapperEl) {\n this.wrapperEl.style[prop] = value;\n }\n\n return this;\n },\n\n /**\n * Returns canvas zoom level\n * @return {Number}\n */\n getZoom: function () {\n return this.viewportTransform[0];\n },\n\n /**\n * Sets viewport transform of this canvas instance\n * @param {Array} vpt the transform in the form of context.transform\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setViewportTransform: function (vpt) {\n var activeGroup = this._activeGroup, object, ignoreVpt = false, skipAbsolute = true;\n this.viewportTransform = vpt;\n for (var i = 0, len = this._objects.length; i < len; i++) {\n object = this._objects[i];\n object.group || object.setCoords(ignoreVpt, skipAbsolute);\n }\n if (activeGroup) {\n activeGroup.setCoords(ignoreVpt, skipAbsolute);\n }\n this.calcViewportBoundaries();\n this.renderAll();\n return this;\n },\n\n /**\n * Sets zoom level of this canvas instance, zoom centered around point\n * @param {fabric.Point} point to zoom with respect to\n * @param {Number} value to set zoom to, less than 1 zooms out\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n zoomToPoint: function (point, value) {\n // TODO: just change the scale, preserve other transformations\n var before = point, vpt = this.viewportTransform.slice(0);\n point = transformPoint(point, invertTransform(this.viewportTransform));\n vpt[0] = value;\n vpt[3] = value;\n var after = transformPoint(point, vpt);\n vpt[4] += before.x - after.x;\n vpt[5] += before.y - after.y;\n return this.setViewportTransform(vpt);\n },\n\n /**\n * Sets zoom level of this canvas instance\n * @param {Number} value to set zoom to, less than 1 zooms out\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setZoom: function (value) {\n this.zoomToPoint(new fabric.Point(0, 0), value);\n return this;\n },\n\n /**\n * Pan viewport so as to place point at top left corner of canvas\n * @param {fabric.Point} point to move to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n absolutePan: function (point) {\n var vpt = this.viewportTransform.slice(0);\n vpt[4] = -point.x;\n vpt[5] = -point.y;\n return this.setViewportTransform(vpt);\n },\n\n /**\n * Pans viewpoint relatively\n * @param {fabric.Point} point (position vector) to move by\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n relativePan: function (point) {\n return this.absolutePan(new fabric.Point(\n -point.x - this.viewportTransform[4],\n -point.y - this.viewportTransform[5]\n ));\n },\n\n /**\n * Returns <canvas> element corresponding to this instance\n * @return {HTMLCanvasElement}\n */\n getElement: function () {\n return this.lowerCanvasEl;\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was added\n */\n _onObjectAdded: function(obj) {\n this.stateful && obj.setupState();\n obj._set('canvas', this);\n obj.setCoords();\n this.fire('object:added', { target: obj });\n obj.fire('added');\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function(obj) {\n this.fire('object:removed', { target: obj });\n obj.fire('removed');\n delete obj.canvas;\n },\n\n /**\n * Clears specified context of canvas element\n * @param {CanvasRenderingContext2D} ctx Context to clear\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clearContext: function(ctx) {\n ctx.clearRect(0, 0, this.width, this.height);\n return this;\n },\n\n /**\n * Returns context of canvas where objects are drawn\n * @return {CanvasRenderingContext2D}\n */\n getContext: function () {\n return this.contextContainer;\n },\n\n /**\n * Clears all contexts (background, main, top) of an instance\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clear: function () {\n this._objects.length = 0;\n this.backgroundImage = null;\n this.overlayImage = null;\n this.backgroundColor = '';\n this.overlayColor = '';\n if (this._hasITextHandlers) {\n this.off('mouse:up', this._mouseUpITextHandler);\n this._iTextInstances = null;\n this._hasITextHandlers = false;\n }\n this.clearContext(this.contextContainer);\n this.fire('canvas:cleared');\n this.renderAll();\n return this;\n },\n\n /**\n * Renders the canvas\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAll: function () {\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._objects);\n return this;\n },\n\n /**\n * Calculate the position of the 4 corner of canvas with current viewportTransform.\n * helps to determinate when an object is in the current rendering viewport using\n * object absolute coordinates ( aCoords )\n * @return {Object} points.tl\n * @chainable\n */\n calcViewportBoundaries: function() {\n var points = { }, width = this.getWidth(), height = this.getHeight(),\n iVpt = invertTransform(this.viewportTransform);\n points.tl = transformPoint({ x: 0, y: 0 }, iVpt);\n points.br = transformPoint({ x: width, y: height }, iVpt);\n points.tr = new fabric.Point(points.br.x, points.tl.y);\n points.bl = new fabric.Point(points.tl.x, points.br.y);\n this.vptCoords = points;\n return points;\n },\n\n /**\n * Renders background, objects, overlay and controls.\n * @param {CanvasRenderingContext2D} ctx\n * @param {Array} objects to render\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderCanvas: function(ctx, objects) {\n this.calcViewportBoundaries();\n this.clearContext(ctx);\n this.fire('before:render');\n if (this.clipTo) {\n fabric.util.clipContext(this, ctx);\n }\n this._renderBackground(ctx);\n\n ctx.save();\n //apply viewport transform once for all rendering process\n ctx.transform.apply(ctx, this.viewportTransform);\n this._renderObjects(ctx, objects);\n ctx.restore();\n if (!this.controlsAboveOverlay && this.interactive) {\n this.drawControls(ctx);\n }\n if (this.clipTo) {\n ctx.restore();\n }\n this._renderOverlay(ctx);\n if (this.controlsAboveOverlay && this.interactive) {\n this.drawControls(ctx);\n }\n this.fire('after:render');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} objects to render\n */\n _renderObjects: function(ctx, objects) {\n for (var i = 0, length = objects.length; i < length; ++i) {\n objects[i] && objects[i].render(ctx);\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {string} property 'background' or 'overlay'\n */\n _renderBackgroundOrOverlay: function(ctx, property) {\n var object = this[property + 'Color'];\n if (object) {\n ctx.fillStyle = object.toLive\n ? object.toLive(ctx, this)\n : object;\n\n ctx.fillRect(\n object.offsetX || 0,\n object.offsetY || 0,\n this.width,\n this.height);\n }\n object = this[property + 'Image'];\n if (object) {\n if (this[property + 'Vpt']) {\n ctx.save();\n ctx.transform.apply(ctx, this.viewportTransform);\n }\n object.render(ctx);\n this[property + 'Vpt'] && ctx.restore();\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground: function(ctx) {\n this._renderBackgroundOrOverlay(ctx, 'background');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderOverlay: function(ctx) {\n this._renderBackgroundOrOverlay(ctx, 'overlay');\n },\n\n /**\n * Returns coordinates of a center of canvas.\n * Returned value is an object with top and left properties\n * @return {Object} object with \"top\" and \"left\" number values\n */\n getCenter: function () {\n return {\n top: this.getHeight() / 2,\n left: this.getWidth() / 2\n };\n },\n\n /**\n * Centers object horizontally in the canvas\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center horizontally\n * @return {fabric.Canvas} thisArg\n */\n centerObjectH: function (object) {\n return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y));\n },\n\n /**\n * Centers object vertically in the canvas\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n centerObjectV: function (object) {\n return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top));\n },\n\n /**\n * Centers object vertically and horizontally in the canvas\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n centerObject: function(object) {\n var center = this.getCenter();\n\n return this._centerObject(object, new fabric.Point(center.left, center.top));\n },\n\n /**\n * Centers object vertically and horizontally in the viewport\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObject: function(object) {\n var vpCenter = this.getVpCenter();\n\n return this._centerObject(object, vpCenter);\n },\n\n /**\n * Centers object horizontally in the viewport, object.top is unchanged\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObjectH: function(object) {\n var vpCenter = this.getVpCenter();\n this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y));\n return this;\n },\n\n /**\n * Centers object Vertically in the viewport, object.top is unchanged\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObjectV: function(object) {\n var vpCenter = this.getVpCenter();\n\n return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y));\n },\n\n /**\n * Calculate the point in canvas that correspond to the center of actual viewport.\n * @return {fabric.Point} vpCenter, viewport center\n * @chainable\n */\n getVpCenter: function() {\n var center = this.getCenter(),\n iVpt = invertTransform(this.viewportTransform);\n return transformPoint({ x: center.left, y: center.top }, iVpt);\n },\n\n /**\n * @private\n * @param {fabric.Object} object Object to center\n * @param {fabric.Point} center Center point\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n _centerObject: function(object, center) {\n object.setPositionByOrigin(center, 'center', 'center');\n this.renderAll();\n return this;\n },\n\n /**\n * Returs dataless JSON representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} json string\n */\n toDatalessJSON: function (propertiesToInclude) {\n return this.toDatalessObject(propertiesToInclude);\n },\n\n /**\n * Returns object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return this._toObjectMethod('toObject', propertiesToInclude);\n },\n\n /**\n * Returns dataless object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function (propertiesToInclude) {\n return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n },\n\n /**\n * @private\n */\n _toObjectMethod: function (methodName, propertiesToInclude) {\n\n var data = {\n objects: this._toObjects(methodName, propertiesToInclude)\n };\n\n extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));\n\n fabric.util.populateWithProperties(this, data, propertiesToInclude);\n\n return data;\n },\n\n /**\n * @private\n */\n _toObjects: function(methodName, propertiesToInclude) {\n return this.getObjects().filter(function(object) {\n return !object.excludeFromExport;\n }).map(function(instance) {\n return this._toObject(instance, methodName, propertiesToInclude);\n }, this);\n },\n\n /**\n * @private\n */\n _toObject: function(instance, methodName, propertiesToInclude) {\n var originalValue;\n\n if (!this.includeDefaultValues) {\n originalValue = instance.includeDefaultValues;\n instance.includeDefaultValues = false;\n }\n\n var object = instance[methodName](propertiesToInclude);\n if (!this.includeDefaultValues) {\n instance.includeDefaultValues = originalValue;\n }\n return object;\n },\n\n /**\n * @private\n */\n __serializeBgOverlay: function(methodName, propertiesToInclude) {\n var data = { }, bgImage = this.backgroundImage, overlay = this.overlayImage;\n\n if (this.backgroundColor) {\n data.background = this.backgroundColor.toObject\n ? this.backgroundColor.toObject(propertiesToInclude)\n : this.backgroundColor;\n }\n\n if (this.overlayColor) {\n data.overlay = this.overlayColor.toObject\n ? this.overlayColor.toObject(propertiesToInclude)\n : this.overlayColor;\n }\n if (bgImage && !bgImage.excludeFromExport) {\n data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude);\n }\n if (overlay && !overlay.excludeFromExport) {\n data.overlayImage = this._toObject(overlay, methodName, propertiesToInclude);\n }\n\n return data;\n },\n\n /* _TO_SVG_START_ */\n /**\n * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n * a zoomed canvas will then produce zoomed SVG output.\n * @type Boolean\n * @default\n */\n svgViewportTransformation: true,\n\n /**\n * Returns SVG representation of canvas\n * @function\n * @param {Object} [options] Options object for SVG output\n * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n * @param {Object} [options.viewBox] SVG viewbox object\n * @param {Number} [options.viewBox.x] x-cooridnate of viewbox\n * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n * @param {Number} [options.viewBox.width] Width of viewbox\n * @param {Number} [options.viewBox.height] Height of viewbox\n * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n * @param {String} [options.width] desired width of svg with or without units\n * @param {String} [options.height] desired height of svg with or without units\n * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n * @return {String} SVG string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n * @example Normal SVG output\n * var svg = canvas.toSVG();\n * @example SVG output without preamble (without <?xml ../>)\n * var svg = canvas.toSVG({suppressPreamble: true});\n * @example SVG output with viewBox attribute\n * var svg = canvas.toSVG({\n * viewBox: {\n * x: 100,\n * y: 100,\n * width: 200,\n * height: 300\n * }\n * });\n * @example SVG output with different encoding (default: UTF-8)\n * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n * @example Modify SVG output with reviver function\n * var svg = canvas.toSVG(null, function(svg) {\n * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n * });\n */\n toSVG: function(options, reviver) {\n options || (options = { });\n\n var markup = [];\n\n this._setSVGPreamble(markup, options);\n this._setSVGHeader(markup, options);\n\n this._setSVGBgOverlayColor(markup, 'backgroundColor');\n this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n\n this._setSVGObjects(markup, reviver);\n\n this._setSVGBgOverlayColor(markup, 'overlayColor');\n this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n markup.push('');\n\n return markup.join('');\n },\n\n /**\n * @private\n */\n _setSVGPreamble: function(markup, options) {\n if (options.suppressPreamble) {\n return;\n }\n markup.push(\n '\\n',\n '\\n'\n );\n },\n\n /**\n * @private\n */\n _setSVGHeader: function(markup, options) {\n var width = options.width || this.width,\n height = options.height || this.height,\n vpt, viewBox = 'viewBox=\"0 0 ' + this.width + ' ' + this.height + '\" ',\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n if (options.viewBox) {\n viewBox = 'viewBox=\"' +\n options.viewBox.x + ' ' +\n options.viewBox.y + ' ' +\n options.viewBox.width + ' ' +\n options.viewBox.height + '\" ';\n }\n else {\n if (this.svgViewportTransformation) {\n vpt = this.viewportTransform;\n viewBox = 'viewBox=\"' +\n toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' +\n toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '\" ';\n }\n }\n\n markup.push(\n '\\n',\n 'Created with Fabric.js ', fabric.version, '\\n',\n '\\n',\n this.createSVGFontFacesMarkup(),\n this.createSVGRefElementsMarkup(),\n '\\n'\n );\n },\n\n /**\n * Creates markup containing SVG referenced elements like patterns, gradients etc.\n * @return {String}\n */\n createSVGRefElementsMarkup: function() {\n var _this = this,\n markup = ['backgroundColor', 'overlayColor'].map(function(prop) {\n var fill = _this[prop];\n if (fill && fill.toLive) {\n return fill.toSVG(_this, false);\n }\n });\n return markup.join('');\n },\n\n /**\n * Creates markup containing SVG font faces,\n * font URLs for font faces must be collected by developers\n * and are not extracted from the DOM by fabricjs\n * @param {Array} objects Array of fabric objects\n * @return {String}\n */\n createSVGFontFacesMarkup: function() {\n var markup = '', fontList = { }, obj, fontFamily,\n style, row, rowIndex, _char, charIndex,\n fontPaths = fabric.fontPaths, objects = this.getObjects();\n\n for (var i = 0, len = objects.length; i < len; i++) {\n obj = objects[i];\n fontFamily = obj.fontFamily;\n if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) {\n continue;\n }\n fontList[fontFamily] = true;\n if (!obj.styles) {\n continue;\n }\n style = obj.styles;\n for (rowIndex in style) {\n row = style[rowIndex];\n for (charIndex in row) {\n _char = row[charIndex];\n fontFamily = _char.fontFamily;\n if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n fontList[fontFamily] = true;\n }\n }\n }\n }\n\n for (var j in fontList) {\n markup += [\n '\\t\\t@font-face {\\n',\n '\\t\\t\\tfont-family: \\'', j, '\\';\\n',\n '\\t\\t\\tsrc: url(\\'', fontPaths[j], '\\');\\n',\n '\\t\\t}\\n'\n ].join('');\n }\n\n if (markup) {\n markup = [\n '\\t\\n'\n ].join('');\n }\n\n return markup;\n },\n\n /**\n * @private\n */\n _setSVGObjects: function(markup, reviver) {\n var instance;\n for (var i = 0, objects = this.getObjects(), len = objects.length; i < len; i++) {\n instance = objects[i];\n if (instance.excludeFromExport) {\n continue;\n }\n this._setSVGObject(markup, instance, reviver);\n }\n },\n\n /**\n * push single object svg representation in the markup\n * @private\n */\n _setSVGObject: function(markup, instance, reviver) {\n markup.push(instance.toSVG(reviver));\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayImage: function(markup, property, reviver) {\n if (this[property] && this[property].toSVG) {\n markup.push(this[property].toSVG(reviver));\n }\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayColor: function(markup, property) {\n var filler = this[property];\n if (!filler) {\n return;\n }\n if (filler.toLive) {\n var repeat = filler.repeat;\n markup.push(\n '\\n'\n );\n }\n else {\n markup.push(\n '\\n'\n );\n }\n },\n /* _TO_SVG_END_ */\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the bottom of the stack of drawn objects\n * @param {fabric.Object} object Object to send to back\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendToBack: function (object) {\n if (!object) {\n return this;\n }\n var activeGroup = this._activeGroup,\n i, obj, objs;\n if (object === activeGroup) {\n objs = activeGroup._objects;\n for (i = objs.length; i--;) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n this._objects.unshift(obj);\n }\n }\n else {\n removeFromArray(this._objects, object);\n this._objects.unshift(object);\n }\n return this.renderAll && this.renderAll();\n },\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the top of the stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringToFront: function (object) {\n if (!object) {\n return this;\n }\n var activeGroup = this._activeGroup,\n i, obj, objs;\n if (object === activeGroup) {\n objs = activeGroup._objects;\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n this._objects.push(obj);\n }\n }\n else {\n removeFromArray(this._objects, object);\n this._objects.push(object);\n }\n return this.renderAll && this.renderAll();\n },\n\n /**\n * Moves an object or a selection down in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendBackwards: function (object, intersecting) {\n if (!object) {\n return this;\n }\n\n var activeGroup = this._activeGroup,\n i, obj, idx, newIdx, objs, objsMoved = 0;\n\n if (object === activeGroup) {\n objs = activeGroup._objects;\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n if (idx > 0 + objsMoved) {\n newIdx = idx - 1;\n removeFromArray(this._objects, obj);\n this._objects.splice(newIdx, 0, obj);\n }\n objsMoved++;\n }\n }\n else {\n idx = this._objects.indexOf(object);\n if (idx !== 0) {\n // if object is not on the bottom of stack\n newIdx = this._findNewLowerIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n }\n }\n this.renderAll && this.renderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewLowerIndex: function(object, idx, intersecting) {\n var newIdx;\n\n if (intersecting) {\n newIdx = idx;\n\n // traverse down the stack looking for the nearest intersecting object\n for (var i = idx - 1; i >= 0; --i) {\n\n var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n object.isContainedWithinObject(this._objects[i]) ||\n this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n }\n else {\n newIdx = idx - 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object or a selection up in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringForward: function (object, intersecting) {\n if (!object) {\n return this;\n }\n\n var activeGroup = this._activeGroup,\n i, obj, idx, newIdx, objs, objsMoved = 0;\n\n if (object === activeGroup) {\n objs = activeGroup._objects;\n for (i = objs.length; i--;) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n if (idx < this._objects.length - 1 - objsMoved) {\n newIdx = idx + 1;\n removeFromArray(this._objects, obj);\n this._objects.splice(newIdx, 0, obj);\n }\n objsMoved++;\n }\n }\n else {\n idx = this._objects.indexOf(object);\n if (idx !== this._objects.length - 1) {\n // if object is not on top of stack (last item in an array)\n newIdx = this._findNewUpperIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n }\n }\n this.renderAll && this.renderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewUpperIndex: function(object, idx, intersecting) {\n var newIdx;\n\n if (intersecting) {\n newIdx = idx;\n\n // traverse up the stack looking for the nearest intersecting object\n for (var i = idx + 1; i < this._objects.length; ++i) {\n\n var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n object.isContainedWithinObject(this._objects[i]) ||\n this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n }\n else {\n newIdx = idx + 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {Number} index Position to move to\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n moveTo: function (object, index) {\n removeFromArray(this._objects, object);\n this._objects.splice(index, 0, object);\n return this.renderAll && this.renderAll();\n },\n\n /**\n * Clears a canvas element and removes all event listeners\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n this.clear();\n return this;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function () {\n return '#';\n }\n });\n\n extend(fabric.StaticCanvas.prototype, fabric.Observable);\n extend(fabric.StaticCanvas.prototype, fabric.Collection);\n extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);\n\n extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ {\n\n /**\n * @static\n * @type String\n * @default\n */\n EMPTY_JSON: '{\"objects\": [], \"background\": \"white\"}',\n\n /**\n * Provides a way to check support of some of the canvas methods\n * (either those of HTMLCanvasElement itself, or rendering context)\n *\n * @param {String} methodName Method to check support for;\n * Could be one of \"getImageData\", \"toDataURL\", \"toDataURLWithQuality\" or \"setLineDash\"\n * @return {Boolean | null} `true` if method is supported (or at least exists),\n * `null` if canvas element or context can not be initialized\n */\n supports: function (methodName) {\n var el = fabric.util.createCanvasElement();\n\n if (!el || !el.getContext) {\n return null;\n }\n\n var ctx = el.getContext('2d');\n if (!ctx) {\n return null;\n }\n\n switch (methodName) {\n\n case 'getImageData':\n return typeof ctx.getImageData !== 'undefined';\n\n case 'setLineDash':\n return typeof ctx.setLineDash !== 'undefined';\n\n case 'toDataURL':\n return typeof el.toDataURL !== 'undefined';\n\n case 'toDataURLWithQuality':\n try {\n el.toDataURL('image/jpeg', 0);\n return true;\n }\n catch (e) { }\n return false;\n\n default:\n return null;\n }\n }\n });\n\n /**\n * Returns JSON representation of canvas\n * @function\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} JSON string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n * @example JSON without additional properties\n * var json = canvas.toJSON();\n * @example JSON with additional properties included\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY', 'lockUniScaling']);\n * @example JSON without default values\n * canvas.includeDefaultValues = false;\n * var json = canvas.toJSON();\n */\n fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;\n\n})();\n\n\n/**\n * BaseBrush class\n * @class fabric.BaseBrush\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nfabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ {\n\n /**\n * Color of a brush\n * @type String\n * @default\n */\n color: 'rgb(0, 0, 0)',\n\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width: 1,\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'round',\n\n /**\n * Corner style of a brush (one of \"bevil\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'round',\n\n /**\n * Stroke Dash Array.\n * @type Array\n * @default\n */\n strokeDashArray: null,\n\n /**\n * Sets shadow of an object\n * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setShadow: function(options) {\n this.shadow = new fabric.Shadow(options);\n return this;\n },\n\n /**\n * Sets brush styles\n * @private\n */\n _setBrushStyles: function() {\n var ctx = this.canvas.contextTop;\n\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = this.strokeLineCap;\n ctx.lineJoin = this.strokeLineJoin;\n if (this.strokeDashArray && fabric.StaticCanvas.supports('setLineDash')) {\n ctx.setLineDash(this.strokeDashArray);\n }\n },\n\n /**\n * Sets brush shadow styles\n * @private\n */\n _setShadow: function() {\n if (!this.shadow) {\n return;\n }\n\n var ctx = this.canvas.contextTop,\n zoom = this.canvas.getZoom();\n\n ctx.shadowColor = this.shadow.color;\n ctx.shadowBlur = this.shadow.blur * zoom;\n ctx.shadowOffsetX = this.shadow.offsetX * zoom;\n ctx.shadowOffsetY = this.shadow.offsetY * zoom;\n },\n\n /**\n * Removes brush shadow styles\n * @private\n */\n _resetShadow: function() {\n var ctx = this.canvas.contextTop;\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n});\n\n\n(function() {\n\n /**\n * PencilBrush class\n * @class fabric.PencilBrush\n * @extends fabric.BaseBrush\n */\n fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ {\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.PencilBrush} Instance of a pencil brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this._points = [];\n },\n\n /**\n * Inovoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function(pointer) {\n this._prepareForDrawing(pointer);\n // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n this._captureDrawingPath(pointer);\n this._render();\n },\n\n /**\n * Inovoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n this._captureDrawingPath(pointer);\n // redraw curve\n // clear top canvas\n this.canvas.clearContext(this.canvas.contextTop);\n this._render();\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n this._finalizeAndAddPath();\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing: function(pointer) {\n\n var p = new fabric.Point(pointer.x, pointer.y);\n\n this._reset();\n this._addPoint(p);\n\n this.canvas.contextTop.moveTo(p.x, p.y);\n },\n\n /**\n * @private\n * @param {fabric.Point} point Point to be added to points array\n */\n _addPoint: function(point) {\n if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) {\n return;\n }\n this._points.push(point);\n },\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset: function() {\n this._points.length = 0;\n\n this._setBrushStyles();\n this._setShadow();\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _captureDrawingPath: function(pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y);\n this._addPoint(pointerPoint);\n },\n\n /**\n * Draw a smooth path on the topCanvas using quadraticCurveTo\n * @private\n */\n _render: function() {\n var ctx = this.canvas.contextTop, i, len,\n v = this.canvas.viewportTransform,\n p1 = this._points[0],\n p2 = this._points[1];\n\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n ctx.beginPath();\n\n //if we only have 2 points in the path and they are the same\n //it means that the user only clicked the canvas without moving the mouse\n //then we should be drawing a dot. A path isn't drawn between two identical dots\n //that's why we set them apart a bit\n if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n var width = this.width / 1000;\n p1 = new fabric.Point(p1.x, p1.y);\n p2 = new fabric.Point(p2.x, p2.y);\n p1.x -= width;\n p2.x += width;\n }\n ctx.moveTo(p1.x, p1.y);\n\n for (i = 1, len = this._points.length; i < len; i++) {\n // we pick the point between pi + 1 & pi + 2 as the\n // end point and p1 as our control point.\n var midPoint = p1.midPointFrom(p2);\n ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n\n p1 = this._points[i];\n p2 = this._points[i + 1];\n }\n // Draw last line as a straight line while\n // we wait for the next point to be able to calculate\n // the bezier control point\n ctx.lineTo(p1.x, p1.y);\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * Converts points to SVG path\n * @param {Array} points Array of points\n * @return {String} SVG path\n */\n convertPointsToSVGPath: function(points) {\n var path = [], i, width = this.width / 1000,\n p1 = new fabric.Point(points[0].x, points[0].y),\n p2 = new fabric.Point(points[1].x, points[1].y),\n len = points.length, multSignX = 1, multSignY = 1, manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' ');\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n var midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');\n }\n p1 = points[i];\n if ((i + 1) < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push('L ', p1.x + multSignX * width, ' ', p1.y + multSignY * width);\n return path;\n },\n\n /**\n * Creates fabric.Path object to add on canvas\n * @param {String} pathData Path data\n * @return {fabric.Path} Path to add on canvas\n */\n createPath: function(pathData) {\n var path = new fabric.Path(pathData, {\n fill: null,\n stroke: this.color,\n strokeWidth: this.width,\n strokeLineCap: this.strokeLineCap,\n strokeLineJoin: this.strokeLineJoin,\n strokeDashArray: this.strokeDashArray,\n originX: 'center',\n originY: 'center'\n });\n var position = new fabric.Point(path.left, path.top);\n path.originX = fabric.Object.prototype.originX;\n path.originY = fabric.Object.prototype.originY;\n position = path.translateToGivenOrigin(\n position, 'center', 'center', path.originX, path.originY);\n path.top = position.y;\n path.left = position.x;\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.setShadow(this.shadow);\n }\n\n return path;\n },\n\n /**\n * On mouseup after drawing the path on contextTop canvas\n * we use the points captured to create an new fabric path object\n * and add it to the fabric canvas.\n */\n _finalizeAndAddPath: function() {\n var ctx = this.canvas.contextTop;\n ctx.closePath();\n\n var pathData = this.convertPointsToSVGPath(this._points).join('');\n if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') {\n // do not create 0 width/height paths, as they are\n // rendered inconsistently across browsers\n // Firefox 4, for example, renders a dot,\n // whereas Chrome 10 renders nothing\n this.canvas.renderAll();\n return;\n }\n\n var path = this.createPath(pathData);\n\n this.canvas.add(path);\n path.setCoords();\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderAll();\n\n // fire event 'path' created\n this.canvas.fire('path:created', { path: path });\n }\n });\n})();\n\n\n/**\n * CircleBrush class\n * @class fabric.CircleBrush\n */\nfabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ {\n\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.CircleBrush} Instance of a circle brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this.points = [];\n },\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Object} pointer\n */\n drawDot: function(pointer) {\n var point = this.addPoint(pointer),\n ctx = this.canvas.contextTop,\n v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n\n ctx.fillStyle = point.fill;\n ctx.beginPath();\n ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n ctx.closePath();\n ctx.fill();\n\n ctx.restore();\n },\n\n /**\n * Invoked on mouse down\n */\n onMouseDown: function(pointer) {\n this.points.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n this.drawDot(pointer);\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n this.drawDot(pointer);\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n var circles = [];\n\n for (var i = 0, len = this.points.length; i < len; i++) {\n var point = this.points[i],\n circle = new fabric.Circle({\n radius: point.radius,\n left: point.x,\n top: point.y,\n originX: 'center',\n originY: 'center',\n fill: point.fill\n });\n\n this.shadow && circle.setShadow(this.shadow);\n\n circles.push(circle);\n }\n var group = new fabric.Group(circles, { originX: 'center', originY: 'center' });\n group.canvas = this.canvas;\n\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.renderAll();\n },\n\n /**\n * @param {Object} pointer\n * @return {fabric.Point} Just added pointer point\n */\n addPoint: function(pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y),\n\n circleRadius = fabric.util.getRandomInt(\n Math.max(0, this.width - 20), this.width + 20) / 2,\n\n circleColor = new fabric.Color(this.color)\n .setAlpha(fabric.util.getRandomInt(0, 100) / 100)\n .toRgba();\n\n pointerPoint.radius = circleRadius;\n pointerPoint.fill = circleColor;\n\n this.points.push(pointerPoint);\n\n return pointerPoint;\n }\n});\n\n\n/**\n * SprayBrush class\n * @class fabric.SprayBrush\n */\nfabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ {\n\n /**\n * Width of a spray\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Density of a spray (number of dots per chunk)\n * @type Number\n * @default\n */\n density: 20,\n\n /**\n * Width of spray dots\n * @type Number\n * @default\n */\n dotWidth: 1,\n\n /**\n * Width variance of spray dots\n * @type Number\n * @default\n */\n dotWidthVariance: 1,\n\n /**\n * Whether opacity of a dot should be random\n * @type Boolean\n * @default\n */\n randomOpacity: false,\n\n /**\n * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n * @type Boolean\n * @default\n */\n optimizeOverlapping: true,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.SprayBrush} Instance of a spray brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this.sprayChunks = [];\n },\n\n /**\n * Invoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function(pointer) {\n this.sprayChunks.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n\n this.addSprayChunk(pointer);\n this.render();\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n this.addSprayChunk(pointer);\n this.render();\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n var rects = [];\n\n for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n var sprayChunk = this.sprayChunks[i];\n\n for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {\n\n var rect = new fabric.Rect({\n width: sprayChunk[j].width,\n height: sprayChunk[j].width,\n left: sprayChunk[j].x + 1,\n top: sprayChunk[j].y + 1,\n originX: 'center',\n originY: 'center',\n fill: this.color\n });\n\n this.shadow && rect.setShadow(this.shadow);\n rects.push(rect);\n }\n }\n\n if (this.optimizeOverlapping) {\n rects = this._getOptimizedRects(rects);\n }\n\n var group = new fabric.Group(rects, { originX: 'center', originY: 'center' });\n group.canvas = this.canvas;\n\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.renderAll();\n },\n\n /**\n * @private\n * @param {Array} rects\n */\n _getOptimizedRects: function(rects) {\n\n // avoid creating duplicate rects at the same coordinates\n var uniqueRects = { }, key;\n\n for (var i = 0, len = rects.length; i < len; i++) {\n key = rects[i].left + '' + rects[i].top;\n if (!uniqueRects[key]) {\n uniqueRects[key] = rects[i];\n }\n }\n var uniqueRectsArray = [];\n for (key in uniqueRects) {\n uniqueRectsArray.push(uniqueRects[key]);\n }\n\n return uniqueRectsArray;\n },\n\n /**\n * Renders brush\n */\n render: function() {\n var ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n var v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n\n for (var i = 0, len = this.sprayChunkPoints.length; i < len; i++) {\n var point = this.sprayChunkPoints[i];\n if (typeof point.opacity !== 'undefined') {\n ctx.globalAlpha = point.opacity;\n }\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n ctx.restore();\n },\n\n /**\n * @param {Object} pointer\n */\n addSprayChunk: function(pointer) {\n this.sprayChunkPoints = [];\n\n var x, y, width, radius = this.width / 2;\n\n for (var i = 0; i < this.density; i++) {\n\n x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);\n y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);\n\n if (this.dotWidthVariance) {\n width = fabric.util.getRandomInt(\n // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance),\n this.dotWidth + this.dotWidthVariance);\n }\n else {\n width = this.dotWidth;\n }\n\n var point = new fabric.Point(x, y);\n point.width = width;\n\n if (this.randomOpacity) {\n point.opacity = fabric.util.getRandomInt(0, 100) / 100;\n }\n\n this.sprayChunkPoints.push(point);\n }\n\n this.sprayChunks.push(this.sprayChunkPoints);\n }\n});\n\n\n/**\n * PatternBrush class\n * @class fabric.PatternBrush\n * @extends fabric.BaseBrush\n */\nfabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ {\n\n getPatternSrc: function() {\n\n var dotWidth = 20,\n dotDistance = 5,\n patternCanvas = fabric.document.createElement('canvas'),\n patternCtx = patternCanvas.getContext('2d');\n\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n\n patternCtx.fillStyle = this.color;\n patternCtx.beginPath();\n patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);\n patternCtx.closePath();\n patternCtx.fill();\n\n return patternCanvas;\n },\n\n getPatternSrcFunction: function() {\n return String(this.getPatternSrc).replace('this.color', '\"' + this.color + '\"');\n },\n\n /**\n * Creates \"pattern\" instance property\n */\n getPattern: function() {\n return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat');\n },\n\n /**\n * Sets brush styles\n */\n _setBrushStyles: function() {\n this.callSuper('_setBrushStyles');\n this.canvas.contextTop.strokeStyle = this.getPattern();\n },\n\n /**\n * Creates path\n */\n createPath: function(pathData) {\n var path = this.callSuper('createPath', pathData),\n topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n path.stroke = new fabric.Pattern({\n source: this.source || this.getPatternSrcFunction(),\n offsetX: -topLeft.x,\n offsetY: -topLeft.y\n });\n return path;\n }\n});\n\n\n(function() {\n\n var getPointer = fabric.util.getPointer,\n degreesToRadians = fabric.util.degreesToRadians,\n radiansToDegrees = fabric.util.radiansToDegrees,\n atan2 = Math.atan2,\n abs = Math.abs,\n supportLineDash = fabric.StaticCanvas.supports('setLineDash'),\n\n STROKE_OFFSET = 0.5;\n\n /**\n * Canvas class\n * @class fabric.Canvas\n * @extends fabric.StaticCanvas\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n * @see {@link fabric.Canvas#initialize} for constructor definition\n *\n * @fires object:added\n * @fires object:modified\n * @fires object:rotating\n * @fires object:scaling\n * @fires object:moving\n * @fires object:selected\n *\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:created\n *\n * @fires path:created\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:over\n * @fires mouse:out\n *\n */\n fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(el, options) {\n options || (options = { });\n\n this._initStatic(el, options);\n this._initInteractive();\n this._createCacheCanvas();\n },\n\n /**\n * When true, objects can be transformed by one side (unproportionally)\n * @type Boolean\n * @default\n */\n uniScaleTransform: false,\n\n /**\n * Indicates which key enable unproportional scaling\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n uniScaleKey: 'shiftKey',\n\n /**\n * When true, objects use center point as the origin of scale transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, objects use center point as the origin of rotate transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: false,\n\n /**\n * Indicates which key enable centered Transfrom\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n centeredKey: 'altKey',\n\n /**\n * Indicates which key enable alternate action on corner\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n altActionKey: 'shiftKey',\n\n /**\n * Indicates that canvas is interactive. This property should not be changed.\n * @type Boolean\n * @default\n */\n interactive: true,\n\n /**\n * Indicates whether group selection should be enabled\n * @type Boolean\n * @default\n */\n selection: true,\n\n /**\n * Indicates which key enable multiple click selection\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n selectionKey: 'shiftKey',\n\n /**\n * Indicates which key enable alternative selection\n * in case of target overlapping with active object\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.5\n * @type null|String\n * @default\n */\n altSelectionKey: null,\n\n /**\n * Color of selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(100, 100, 255, 0.3)', // blue\n\n /**\n * Default dash array pattern\n * If not empty the selection border is dashed\n * @type Array\n */\n selectionDashArray: [],\n\n /**\n * Color of the border of selection (usually slightly darker than color of selection itself)\n * @type String\n * @default\n */\n selectionBorderColor: 'rgba(255, 255, 255, 0.3)',\n\n /**\n * Width of a line used in object/group selection\n * @type Number\n * @default\n */\n selectionLineWidth: 1,\n\n /**\n * Default cursor value used when hovering over an object on canvas\n * @type String\n * @default\n */\n hoverCursor: 'move',\n\n /**\n * Default cursor value used when moving an object on canvas\n * @type String\n * @default\n */\n moveCursor: 'move',\n\n /**\n * Default cursor value used for the entire canvas\n * @type String\n * @default\n */\n defaultCursor: 'default',\n\n /**\n * Cursor value used during free drawing\n * @type String\n * @default\n */\n freeDrawingCursor: 'crosshair',\n\n /**\n * Cursor value used for rotation point\n * @type String\n * @default\n */\n rotationCursor: 'crosshair',\n\n /**\n * Default element class that's given to wrapper (div) element of canvas\n * @type String\n * @default\n */\n containerClass: 'canvas-container',\n\n /**\n * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * Number of pixels around target pixel to tolerate (consider active) during object detection\n * @type Number\n * @default\n */\n targetFindTolerance: 0,\n\n /**\n * When true, target detection is skipped when hovering over canvas. This can be used to improve performance.\n * @type Boolean\n * @default\n */\n skipTargetFind: false,\n\n /**\n * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n * After mousedown, mousemove creates a shape,\n * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n * @type Boolean\n * @default\n */\n isDrawingMode: false,\n\n /**\n * Indicates whether objects should remain in current stack position when selected.\n * When false objects are brought to top and rendered as part of the selection group\n * @type Boolean\n * @default\n */\n preserveObjectStacking: false,\n\n /**\n * Indicates the angle that an object will lock to while rotating.\n * @type Number\n * @since 1.6.7\n * @default\n */\n snapAngle: 0,\n\n /**\n * Indicates the distance from the snapAngle the rotation will lock to the snapAngle.\n * When `null`, the snapThreshold will default to the snapAngle.\n * @type null|Number\n * @since 1.6.7\n * @default\n */\n snapThreshold: null,\n\n /**\n * Indicates if the right click on canvas can output the context menu or not\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n stopContextMenu: false,\n\n /**\n * Indicates if the canvas can fire right click events\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n fireRightClick: false,\n\n /**\n * Indicates if the canvas can fire middle click events\n * @type Boolean\n * @since 1.7.8\n * @default\n */\n fireMiddleClick: false,\n\n /**\n * @private\n */\n _initInteractive: function() {\n this._currentTransform = null;\n this._groupSelector = null;\n this._initWrapperElement();\n this._createUpperCanvas();\n this._initEventListeners();\n\n this._initRetinaScaling();\n\n this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);\n\n this.calcOffset();\n },\n\n /**\n * Divides objects in two groups, one to render immediately\n * and one to render as activeGroup.\n * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n */\n _chooseObjectsToRender: function() {\n var activeGroup = this.getActiveGroup(),\n activeObject = this.getActiveObject(),\n object, objsToRender = [], activeGroupObjects = [];\n\n if ((activeGroup || activeObject) && !this.preserveObjectStacking) {\n for (var i = 0, length = this._objects.length; i < length; i++) {\n object = this._objects[i];\n if ((!activeGroup || !activeGroup.contains(object)) && object !== activeObject) {\n objsToRender.push(object);\n }\n else {\n activeGroupObjects.push(object);\n }\n }\n if (activeGroup) {\n activeGroup._set('_objects', activeGroupObjects);\n objsToRender.push(activeGroup);\n }\n activeObject && objsToRender.push(activeObject);\n }\n else {\n objsToRender = this._objects;\n }\n return objsToRender;\n },\n\n /**\n * Renders both the top canvas and the secondary container canvas.\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAll: function () {\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());\n return this;\n },\n\n /**\n * Method to render only the top canvas.\n * Also used to render the group selection box.\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n renderTop: function () {\n var ctx = this.contextTop;\n this.clearContext(ctx);\n\n // we render the top context - last object\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n }\n\n this.fire('after:render');\n this.contextTopDirty = true;\n return this;\n },\n\n /**\n * Resets the current transform to its original values and chooses the type of resizing based on the event\n * @private\n */\n _resetCurrentTransform: function() {\n var t = this._currentTransform;\n\n t.target.set({\n scaleX: t.original.scaleX,\n scaleY: t.original.scaleY,\n skewX: t.original.skewX,\n skewY: t.original.skewY,\n left: t.original.left,\n top: t.original.top\n });\n\n if (this._shouldCenterTransform(t.target)) {\n if (t.action === 'rotate') {\n this._setOriginToCenter(t.target);\n }\n else {\n if (t.originX !== 'center') {\n if (t.originX === 'right') {\n t.mouseXSign = -1;\n }\n else {\n t.mouseXSign = 1;\n }\n }\n if (t.originY !== 'center') {\n if (t.originY === 'bottom') {\n t.mouseYSign = -1;\n }\n else {\n t.mouseYSign = 1;\n }\n }\n\n t.originX = 'center';\n t.originY = 'center';\n }\n }\n else {\n t.originX = t.original.originX;\n t.originY = t.original.originY;\n }\n },\n\n /**\n * Checks if point is contained within an area of given object\n * @param {Event} e Event object\n * @param {fabric.Object} target Object to test against\n * @param {Object} [point] x,y object of point coordinates we want to check.\n * @return {Boolean} true if point is contained within an area of given object\n */\n containsPoint: function (e, target, point) {\n var ignoreZoom = true,\n pointer = point || this.getPointer(e, ignoreZoom),\n xy;\n\n if (target.group && target.group === this.getActiveGroup()) {\n xy = this._normalizePointer(target.group, pointer);\n }\n else {\n xy = { x: pointer.x, y: pointer.y };\n }\n // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html\n // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html\n return (target.containsPoint(xy) || target._findTargetCorner(pointer));\n },\n\n /**\n * @private\n */\n _normalizePointer: function (object, pointer) {\n var m = object.calcTransformMatrix(),\n invertedM = fabric.util.invertTransform(m),\n vptPointer = this.restorePointerVpt(pointer);\n return fabric.util.transformPoint(vptPointer, invertedM);\n },\n\n /**\n * Returns true if object is transparent at a certain location\n * @param {fabric.Object} target Object to check\n * @param {Number} x Left coordinate\n * @param {Number} y Top coordinate\n * @return {Boolean}\n */\n isTargetTransparent: function (target, x, y) {\n var hasBorders = target.hasBorders,\n transparentCorners = target.transparentCorners,\n ctx = this.contextCache,\n originalColor = target.selectionBackgroundColor;\n\n target.hasBorders = target.transparentCorners = false;\n target.selectionBackgroundColor = '';\n\n ctx.save();\n ctx.transform.apply(ctx, this.viewportTransform);\n target.render(ctx);\n ctx.restore();\n\n target.active && target._renderControls(ctx);\n\n target.hasBorders = hasBorders;\n target.transparentCorners = transparentCorners;\n target.selectionBackgroundColor = originalColor;\n\n var isTransparent = fabric.util.isTransparent(\n ctx, x, y, this.targetFindTolerance);\n\n this.clearContext(ctx);\n\n return isTransparent;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _shouldClearSelection: function (e, target) {\n var activeGroup = this.getActiveGroup(),\n activeObject = this.getActiveObject();\n\n return (\n !target\n ||\n (target &&\n activeGroup &&\n !activeGroup.contains(target) &&\n activeGroup !== target &&\n !e[this.selectionKey])\n ||\n (target && !target.evented)\n ||\n (target &&\n !target.selectable &&\n activeObject &&\n activeObject !== target)\n );\n },\n\n /**\n * @private\n * @param {fabric.Object} target\n */\n _shouldCenterTransform: function (target) {\n if (!target) {\n return;\n }\n\n var t = this._currentTransform,\n centerTransform;\n\n if (t.action === 'scale' || t.action === 'scaleX' || t.action === 'scaleY') {\n centerTransform = this.centeredScaling || target.centeredScaling;\n }\n else if (t.action === 'rotate') {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !t.altKey : t.altKey;\n },\n\n /**\n * @private\n */\n _getOriginFromCorner: function(target, corner) {\n var origin = {\n x: target.originX,\n y: target.originY\n };\n\n if (corner === 'ml' || corner === 'tl' || corner === 'bl') {\n origin.x = 'right';\n }\n else if (corner === 'mr' || corner === 'tr' || corner === 'br') {\n origin.x = 'left';\n }\n\n if (corner === 'tl' || corner === 'mt' || corner === 'tr') {\n origin.y = 'bottom';\n }\n else if (corner === 'bl' || corner === 'mb' || corner === 'br') {\n origin.y = 'top';\n }\n\n return origin;\n },\n\n /**\n * @private\n */\n _getActionFromCorner: function(target, corner, e) {\n if (!corner) {\n return 'drag';\n }\n\n switch (corner) {\n case 'mtr':\n return 'rotate';\n case 'ml':\n case 'mr':\n return e[this.altActionKey] ? 'skewY' : 'scaleX';\n case 'mt':\n case 'mb':\n return e[this.altActionKey] ? 'skewX' : 'scaleY';\n default:\n return 'scale';\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _setupCurrentTransform: function (e, target) {\n if (!target) {\n return;\n }\n\n var pointer = this.getPointer(e),\n corner = target._findTargetCorner(this.getPointer(e, true)),\n action = this._getActionFromCorner(target, corner, e),\n origin = this._getOriginFromCorner(target, corner);\n\n this._currentTransform = {\n target: target,\n action: action,\n corner: corner,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n offsetX: pointer.x - target.left,\n offsetY: pointer.y - target.top,\n originX: origin.x,\n originY: origin.y,\n ex: pointer.x,\n ey: pointer.y,\n lastX: pointer.x,\n lastY: pointer.y,\n left: target.left,\n top: target.top,\n theta: degreesToRadians(target.angle),\n width: target.width * target.scaleX,\n mouseXSign: 1,\n mouseYSign: 1,\n shiftKey: e.shiftKey,\n altKey: e[this.centeredKey]\n };\n\n this._currentTransform.original = {\n left: target.left,\n top: target.top,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n originX: origin.x,\n originY: origin.y\n };\n\n this._resetCurrentTransform();\n },\n\n /**\n * Translates object by \"setting\" its left/top\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @return {Boolean} true if the translation occurred\n */\n _translateObject: function (x, y) {\n var transform = this._currentTransform,\n target = transform.target,\n newLeft = x - transform.offsetX,\n newTop = y - transform.offsetY,\n moveX = !target.get('lockMovementX') && target.left !== newLeft,\n moveY = !target.get('lockMovementY') && target.top !== newTop;\n\n moveX && target.set('left', newLeft);\n moveY && target.set('top', newTop);\n return moveX || moveY;\n },\n\n /**\n * Check if we are increasing a positive skew or lower it,\n * checking mouse direction and pressed corner.\n * @private\n */\n _changeSkewTransformOrigin: function(mouseMove, t, by) {\n var property = 'originX', origins = { 0: 'center' },\n skew = t.target.skewX, originA = 'left', originB = 'right',\n corner = t.corner === 'mt' || t.corner === 'ml' ? 1 : -1,\n flipSign = 1;\n\n mouseMove = mouseMove > 0 ? 1 : -1;\n if (by === 'y') {\n skew = t.target.skewY;\n originA = 'top';\n originB = 'bottom';\n property = 'originY';\n }\n origins[-1] = originA;\n origins[1] = originB;\n\n t.target.flipX && (flipSign *= -1);\n t.target.flipY && (flipSign *= -1);\n\n if (skew === 0) {\n t.skewSign = -corner * mouseMove * flipSign;\n t[property] = origins[-mouseMove];\n }\n else {\n skew = skew > 0 ? 1 : -1;\n t.skewSign = skew;\n t[property] = origins[skew * corner * flipSign];\n }\n },\n\n /**\n * Skew object by mouse events\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @param {String} by Either 'x' or 'y'\n * @return {Boolean} true if the skewing occurred\n */\n _skewObject: function (x, y, by) {\n var t = this._currentTransform,\n target = t.target, skewed = false,\n lockSkewingX = target.get('lockSkewingX'),\n lockSkewingY = target.get('lockSkewingY');\n\n if ((lockSkewingX && by === 'x') || (lockSkewingY && by === 'y')) {\n return false;\n }\n\n // Get the constraint point\n var center = target.getCenterPoint(),\n actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), 'center', 'center')[by],\n lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), 'center', 'center')[by],\n actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions();\n\n this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by);\n actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by];\n constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY);\n // Actually skew the object\n skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim);\n t.lastX = x;\n t.lastY = y;\n // Make sure the constraints apply\n target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n return skewed;\n },\n\n /**\n * Set object skew\n * @private\n * @return {Boolean} true if the skewing occurred\n */\n _setObjectSkew: function(localMouse, transform, by, _dim) {\n var target = transform.target, newValue, skewed = false,\n skewSign = transform.skewSign, newDim, dimNoSkew,\n otherBy, _otherBy, _by, newDimMouse, skewX, skewY;\n\n if (by === 'x') {\n otherBy = 'y';\n _otherBy = 'Y';\n _by = 'X';\n skewX = 0;\n skewY = target.skewY;\n }\n else {\n otherBy = 'x';\n _otherBy = 'X';\n _by = 'Y';\n skewX = target.skewX;\n skewY = 0;\n }\n\n dimNoSkew = target._getTransformedDimensions(skewX, skewY);\n newDimMouse = 2 * Math.abs(localMouse) - dimNoSkew[by];\n if (newDimMouse <= 2) {\n newValue = 0;\n }\n else {\n newValue = skewSign * Math.atan((newDimMouse / target['scale' + _by]) /\n (dimNoSkew[otherBy] / target['scale' + _otherBy]));\n newValue = fabric.util.radiansToDegrees(newValue);\n }\n skewed = target['skew' + _by] !== newValue;\n target.set('skew' + _by, newValue);\n if (target['skew' + _otherBy] !== 0) {\n newDim = target._getTransformedDimensions();\n newValue = (_dim[otherBy] / newDim[otherBy]) * target['scale' + _otherBy];\n target.set('scale' + _otherBy, newValue);\n }\n return skewed;\n },\n\n /**\n * Scales object by invoking its scaleX/scaleY methods\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @param {String} by Either 'x' or 'y' - specifies dimension constraint by which to scale an object.\n * When not provided, an object is scaled by both dimensions equally\n * @return {Boolean} true if the scaling occurred\n */\n _scaleObject: function (x, y, by) {\n var t = this._currentTransform,\n target = t.target,\n lockScalingX = target.get('lockScalingX'),\n lockScalingY = target.get('lockScalingY'),\n lockScalingFlip = target.get('lockScalingFlip');\n\n if (lockScalingX && lockScalingY) {\n return false;\n }\n\n // Get the constraint point\n var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY),\n localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY),\n dim = target._getTransformedDimensions(), scaled = false;\n\n this._setLocalMouse(localMouse, t);\n\n // Actually scale the object\n scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim);\n\n // Make sure the constraints apply\n target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n return scaled;\n },\n\n /**\n * @private\n * @return {Boolean} true if the scaling occurred\n */\n _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {\n var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false,\n changeX, changeY, scaleX, scaleY;\n\n scaleX = localMouse.x * target.scaleX / _dim.x;\n scaleY = localMouse.y * target.scaleY / _dim.y;\n changeX = target.scaleX !== scaleX;\n changeY = target.scaleY !== scaleY;\n\n if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) {\n forbidScalingX = true;\n }\n\n if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) {\n forbidScalingY = true;\n }\n\n if (by === 'equally' && !lockScalingX && !lockScalingY) {\n forbidScalingX || forbidScalingY || (scaled = this._scaleObjectEqually(localMouse, target, transform, _dim));\n }\n else if (!by) {\n forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));\n forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));\n }\n else if (by === 'x' && !target.get('lockUniScaling')) {\n forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));\n }\n else if (by === 'y' && !target.get('lockUniScaling')) {\n forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));\n }\n transform.newScaleX = scaleX;\n transform.newScaleY = scaleY;\n forbidScalingX || forbidScalingY || this._flipObject(transform, by);\n return scaled;\n },\n\n /**\n * @private\n * @return {Boolean} true if the scaling occurred\n */\n _scaleObjectEqually: function(localMouse, target, transform, _dim) {\n\n var dist = localMouse.y + localMouse.x,\n lastDist = _dim.y * transform.original.scaleY / target.scaleY +\n _dim.x * transform.original.scaleX / target.scaleX,\n scaled, signX = localMouse.x / Math.abs(localMouse.x),\n signY = localMouse.y / Math.abs(localMouse.y);\n\n // We use transform.scaleX/Y instead of target.scaleX/Y\n // because the object may have a min scale and we'll loose the proportions\n transform.newScaleX = signX * Math.abs(transform.original.scaleX * dist / lastDist);\n transform.newScaleY = signY * Math.abs(transform.original.scaleY * dist / lastDist);\n scaled = transform.newScaleX !== target.scaleX || transform.newScaleY !== target.scaleY;\n target.set('scaleX', transform.newScaleX);\n target.set('scaleY', transform.newScaleY);\n return scaled;\n },\n\n /**\n * @private\n */\n _flipObject: function(transform, by) {\n if (transform.newScaleX < 0 && by !== 'y') {\n if (transform.originX === 'left') {\n transform.originX = 'right';\n }\n else if (transform.originX === 'right') {\n transform.originX = 'left';\n }\n }\n\n if (transform.newScaleY < 0 && by !== 'x') {\n if (transform.originY === 'top') {\n transform.originY = 'bottom';\n }\n else if (transform.originY === 'bottom') {\n transform.originY = 'top';\n }\n }\n },\n\n /**\n * @private\n */\n _setLocalMouse: function(localMouse, t) {\n var target = t.target, zoom = this.getZoom(),\n padding = target.padding / zoom;\n\n if (t.originX === 'right') {\n localMouse.x *= -1;\n }\n else if (t.originX === 'center') {\n localMouse.x *= t.mouseXSign * 2;\n if (localMouse.x < 0) {\n t.mouseXSign = -t.mouseXSign;\n }\n }\n\n if (t.originY === 'bottom') {\n localMouse.y *= -1;\n }\n else if (t.originY === 'center') {\n localMouse.y *= t.mouseYSign * 2;\n if (localMouse.y < 0) {\n t.mouseYSign = -t.mouseYSign;\n }\n }\n\n // adjust the mouse coordinates when dealing with padding\n if (abs(localMouse.x) > padding) {\n if (localMouse.x < 0) {\n localMouse.x += padding;\n }\n else {\n localMouse.x -= padding;\n }\n }\n else { // mouse is within the padding, set to 0\n localMouse.x = 0;\n }\n\n if (abs(localMouse.y) > padding) {\n if (localMouse.y < 0) {\n localMouse.y += padding;\n }\n else {\n localMouse.y -= padding;\n }\n }\n else {\n localMouse.y = 0;\n }\n },\n\n /**\n * Rotates object by invoking its rotate method\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @return {Boolean} true if the rotation occurred\n */\n _rotateObject: function (x, y) {\n\n var t = this._currentTransform;\n\n if (t.target.get('lockRotation')) {\n return false;\n }\n\n var lastAngle = atan2(t.ey - t.top, t.ex - t.left),\n curAngle = atan2(y - t.top, x - t.left),\n angle = radiansToDegrees(curAngle - lastAngle + t.theta),\n hasRoated = true;\n\n if (t.target.snapAngle > 0) {\n var snapAngle = t.target.snapAngle,\n snapThreshold = t.target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n }\n else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n }\n\n // normalize angle to positive value\n if (angle < 0) {\n angle = 360 + angle;\n }\n angle %= 360;\n\n if (t.target.angle === angle) {\n hasRoated = false;\n }\n else {\n t.target.angle = angle;\n }\n\n return hasRoated;\n },\n\n /**\n * Set the cursor type of the canvas element\n * @param {String} value Cursor type of the canvas element.\n * @see http://www.w3.org/TR/css3-ui/#cursor\n */\n setCursor: function (value) {\n this.upperCanvasEl.style.cursor = value;\n },\n\n /**\n * @param {fabric.Object} target to reset transform\n * @private\n */\n _resetObjectTransform: function (target) {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.setAngle(0);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx to draw the selection on\n */\n _drawSelection: function (ctx) {\n var groupSelector = this._groupSelector,\n left = groupSelector.left,\n top = groupSelector.top,\n aleft = abs(left),\n atop = abs(top);\n\n if (this.selectionColor) {\n ctx.fillStyle = this.selectionColor;\n\n ctx.fillRect(\n groupSelector.ex - ((left > 0) ? 0 : -left),\n groupSelector.ey - ((top > 0) ? 0 : -top),\n aleft,\n atop\n );\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor;\n\n // selection border\n if (this.selectionDashArray.length > 1 && !supportLineDash) {\n\n var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop);\n\n ctx.beginPath();\n\n fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray);\n\n ctx.closePath();\n ctx.stroke();\n }\n else {\n fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);\n ctx.strokeRect(\n groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop),\n aleft,\n atop\n );\n }\n },\n\n /**\n * Method that determines what object we are clicking on\n * the skipGroup parameter is for internal use, is needed for shift+click action\n * @param {Event} e mouse event\n * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through\n */\n findTarget: function (e, skipGroup) {\n if (this.skipTargetFind) {\n return;\n }\n\n var ignoreZoom = true,\n pointer = this.getPointer(e, ignoreZoom),\n activeGroup = this.getActiveGroup(),\n activeObject = this.getActiveObject(),\n activeTarget, activeTargetSubs;\n // first check current group (if one exists)\n // active group does not check sub targets like normal groups.\n // if active group just exits.\n this.targets = [];\n if (activeGroup && !skipGroup && activeGroup === this._searchPossibleTargets([activeGroup], pointer)) {\n this._fireOverOutEvents(activeGroup, e);\n return activeGroup;\n }\n // if we hit the corner of an activeObject, let's return that.\n if (activeObject && activeObject._findTargetCorner(pointer)) {\n this._fireOverOutEvents(activeObject, e);\n return activeObject;\n }\n if (activeObject && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n if (!this.preserveObjectStacking) {\n this._fireOverOutEvents(activeObject, e);\n return activeObject;\n }\n else {\n activeTarget = activeObject;\n activeTargetSubs = this.targets;\n this.targets = [];\n }\n }\n\n var target = this._searchPossibleTargets(this._objects, pointer);\n if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {\n target = activeTarget;\n this.targets = activeTargetSubs;\n }\n this._fireOverOutEvents(target, e);\n return target;\n },\n\n /**\n * @private\n */\n _fireOverOutEvents: function(target, e) {\n var overOpt, outOpt, hoveredTarget = this._hoveredTarget;\n if (hoveredTarget !== target) {\n overOpt = { e: e, target: target, previousTarget: this._hoveredTarget };\n outOpt = { e: e, target: this._hoveredTarget, nextTarget: target };\n this._hoveredTarget = target;\n }\n if (target) {\n if (hoveredTarget !== target) {\n if (hoveredTarget) {\n this.fire('mouse:out', outOpt);\n hoveredTarget.fire('mouseout', outOpt);\n }\n this.fire('mouse:over', overOpt);\n target.fire('mouseover', overOpt);\n }\n }\n else if (hoveredTarget) {\n this.fire('mouse:out', outOpt);\n hoveredTarget.fire('mouseout', outOpt);\n }\n },\n\n /**\n * @private\n */\n _checkTarget: function(pointer, obj) {\n if (obj &&\n obj.visible &&\n obj.evented &&\n this.containsPoint(null, obj, pointer)){\n if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {\n var isTransparent = this.isTargetTransparent(obj, pointer.x, pointer.y);\n if (!isTransparent) {\n return true;\n }\n }\n else {\n return true;\n }\n }\n },\n\n /**\n * @private\n */\n _searchPossibleTargets: function(objects, pointer) {\n\n // Cache all targets where their bounding box contains point.\n var target, i = objects.length, normalizedPointer, subTarget;\n // Do not check for currently grouped objects, since we check the parent group itself.\n // untill we call this function specifically to search inside the activeGroup\n while (i--) {\n if (this._checkTarget(pointer, objects[i])) {\n target = objects[i];\n if (target.type === 'group' && target.subTargetCheck) {\n normalizedPointer = this._normalizePointer(target, pointer);\n subTarget = this._searchPossibleTargets(target._objects, normalizedPointer);\n subTarget && this.targets.push(subTarget);\n }\n break;\n }\n }\n return target;\n },\n\n /**\n * Returns pointer coordinates without the effect of the viewport\n * @param {Object} pointer with \"x\" and \"y\" number values\n * @return {Object} object with \"x\" and \"y\" number values\n */\n restorePointerVpt: function(pointer) {\n return fabric.util.transformPoint(\n pointer,\n fabric.util.invertTransform(this.viewportTransform)\n );\n },\n\n /**\n * Returns pointer coordinates relative to canvas.\n * Can return coordinates with or without viewportTransform.\n * ignoreZoom false gives back coordinates that represent\n * the point clicked on canvas element.\n * ignoreZoom true gives back coordinates after being processed\n * by the viewportTransform ( sort of coordinates of what is displayed\n * on the canvas where you are clicking.\n * To interact with your shapes top and left you want to use ignoreZoom true\n * most of the time, while ignoreZoom false will give you coordinates\n * compatible with the object.oCoords system.\n * of the time.\n * @param {Event} e\n * @param {Boolean} ignoreZoom\n * @return {Object} object with \"x\" and \"y\" number values\n */\n getPointer: function (e, ignoreZoom, upperCanvasEl) {\n if (!upperCanvasEl) {\n upperCanvasEl = this.upperCanvasEl;\n }\n var pointer = getPointer(e),\n bounds = upperCanvasEl.getBoundingClientRect(),\n boundsWidth = bounds.width || 0,\n boundsHeight = bounds.height || 0,\n cssScale;\n\n if (!boundsWidth || !boundsHeight ) {\n if ('top' in bounds && 'bottom' in bounds) {\n boundsHeight = Math.abs( bounds.top - bounds.bottom );\n }\n if ('right' in bounds && 'left' in bounds) {\n boundsWidth = Math.abs( bounds.right - bounds.left );\n }\n }\n\n this.calcOffset();\n\n pointer.x = pointer.x - this._offset.left;\n pointer.y = pointer.y - this._offset.top;\n if (!ignoreZoom) {\n pointer = this.restorePointerVpt(pointer);\n }\n\n if (boundsWidth === 0 || boundsHeight === 0) {\n // If bounds are not available (i.e. not visible), do not apply scale.\n cssScale = { width: 1, height: 1 };\n }\n else {\n cssScale = {\n width: upperCanvasEl.width / boundsWidth,\n height: upperCanvasEl.height / boundsHeight\n };\n }\n\n return {\n x: pointer.x * cssScale.width,\n y: pointer.y * cssScale.height\n };\n },\n\n /**\n * @private\n * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized\n */\n _createUpperCanvas: function () {\n var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\\s*lower-canvas\\s*/, '');\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl.className = '';\n }\n else {\n this.upperCanvasEl = this._createCanvasElement();\n }\n fabric.util.addClass(this.upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);\n\n this.wrapperEl.appendChild(this.upperCanvasEl);\n\n this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl);\n this._applyCanvasStyle(this.upperCanvasEl);\n this.contextTop = this.upperCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _createCacheCanvas: function () {\n this.cacheCanvasEl = this._createCanvasElement();\n this.cacheCanvasEl.setAttribute('width', this.width);\n this.cacheCanvasEl.setAttribute('height', this.height);\n this.contextCache = this.cacheCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _initWrapperElement: function () {\n this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', {\n 'class': this.containerClass\n });\n fabric.util.setStyle(this.wrapperEl, {\n width: this.getWidth() + 'px',\n height: this.getHeight() + 'px',\n position: 'relative'\n });\n fabric.util.makeElementUnselectable(this.wrapperEl);\n },\n\n /**\n * @private\n * @param {HTMLElement} element canvas element to apply styles on\n */\n _applyCanvasStyle: function (element) {\n var width = this.getWidth() || element.width,\n height = this.getHeight() || element.height;\n\n fabric.util.setStyle(element, {\n position: 'absolute',\n width: width + 'px',\n height: height + 'px',\n left: 0,\n top: 0,\n 'touch-action': 'none'\n });\n element.width = width;\n element.height = height;\n fabric.util.makeElementUnselectable(element);\n },\n\n /**\n * Copys the the entire inline style from one element (fromEl) to another (toEl)\n * @private\n * @param {Element} fromEl Element style is copied from\n * @param {Element} toEl Element copied style is applied to\n */\n _copyCanvasStyle: function (fromEl, toEl) {\n toEl.style.cssText = fromEl.style.cssText;\n },\n\n /**\n * Returns context of canvas where object selection is drawn\n * @return {CanvasRenderingContext2D}\n */\n getSelectionContext: function() {\n return this.contextTop;\n },\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement: function () {\n return this.upperCanvasEl;\n },\n\n /**\n * @private\n * @param {Object} object\n */\n _setActiveObject: function(object) {\n var obj = this._activeObject;\n if (obj) {\n obj.set('active', false);\n if (object !== obj && obj.onDeselect && typeof obj.onDeselect === 'function') {\n obj.onDeselect();\n }\n }\n this._activeObject = object;\n object.set('active', true);\n },\n\n /**\n * Sets given object as the only active object on canvas\n * @param {fabric.Object} object Object to set as an active one\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setActiveObject: function (object, e) {\n var currentActiveObject = this.getActiveObject();\n if (currentActiveObject && currentActiveObject !== object) {\n currentActiveObject.fire('deselected', { e: e });\n }\n this._setActiveObject(object);\n this.fire('object:selected', { target: object, e: e });\n object.fire('selected', { e: e });\n this.renderAll();\n return this;\n },\n\n /**\n * Returns currently active object\n * @return {fabric.Object} active object\n */\n getActiveObject: function () {\n return this._activeObject;\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function(obj) {\n // removing active object should fire \"selection:cleared\" events\n if (this.getActiveObject() === obj) {\n this.fire('before:selection:cleared', { target: obj });\n this._discardActiveObject();\n this.fire('selection:cleared', { target: obj });\n obj.fire('deselected');\n }\n if (this._hoveredTarget === obj) {\n this._hoveredTarget = null;\n }\n this.callSuper('_onObjectRemoved', obj);\n },\n\n /**\n * @private\n */\n _discardActiveObject: function() {\n var obj = this._activeObject;\n if (obj) {\n obj.set('active', false);\n if (obj.onDeselect && typeof obj.onDeselect === 'function') {\n obj.onDeselect();\n }\n }\n this._activeObject = null;\n },\n\n /**\n * Discards currently active object and fire events. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parmater and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {event} e\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n discardActiveObject: function (e) {\n var activeObject = this._activeObject;\n if (activeObject) {\n this.fire('before:selection:cleared', { target: activeObject, e: e });\n this._discardActiveObject();\n this.fire('selection:cleared', { e: e });\n activeObject.fire('deselected', { e: e });\n }\n return this;\n },\n\n /**\n * @private\n * @param {fabric.Group} group\n */\n _setActiveGroup: function(group) {\n this._activeGroup = group;\n if (group) {\n group.set('active', true);\n }\n },\n\n /**\n * Sets active group to a specified one. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parmater and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {fabric.Group} group Group to set as a current one\n * @param {Event} e Event object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setActiveGroup: function (group, e) {\n this._setActiveGroup(group);\n if (group) {\n this.fire('object:selected', { target: group, e: e });\n group.fire('selected', { e: e });\n }\n return this;\n },\n\n /**\n * Returns currently active group\n * @return {fabric.Group} Current group\n */\n getActiveGroup: function () {\n return this._activeGroup;\n },\n\n /**\n * @private\n */\n _discardActiveGroup: function() {\n var g = this.getActiveGroup();\n if (g) {\n g.destroy();\n }\n this.setActiveGroup(null);\n },\n\n /**\n * Discards currently active group and fire events If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parmater and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n discardActiveGroup: function (e) {\n var g = this.getActiveGroup();\n if (g) {\n this.fire('before:selection:cleared', { e: e, target: g });\n this._discardActiveGroup();\n this.fire('selection:cleared', { e: e });\n }\n return this;\n },\n\n /**\n * Deactivates all objects on canvas, removing any active group or object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n deactivateAll: function () {\n var allObjects = this.getObjects(),\n i = 0,\n len = allObjects.length,\n obj;\n for ( ; i < len; i++) {\n obj = allObjects[i];\n obj && obj.set('active', false);\n }\n this._discardActiveGroup();\n this._discardActiveObject();\n return this;\n },\n\n /**\n * Deactivates all objects and dispatches appropriate events If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parmater and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n deactivateAllWithDispatch: function (e) {\n var allObjects = this.getObjects(),\n i = 0,\n len = allObjects.length,\n obj;\n for ( ; i < len; i++) {\n obj = allObjects[i];\n obj && obj.set('active', false);\n }\n this.discardActiveGroup(e);\n this.discardActiveObject(e);\n return this;\n },\n\n /**\n * Clears a canvas element and removes all event listeners\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n fabric.StaticCanvas.prototype.dispose.call(this);\n var wrapper = this.wrapperEl;\n this.removeListeners();\n wrapper.removeChild(this.upperCanvasEl);\n wrapper.removeChild(this.lowerCanvasEl);\n delete this.upperCanvasEl;\n if (wrapper.parentNode) {\n wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);\n }\n delete this.wrapperEl;\n return this;\n },\n\n /**\n * Clears all contexts (background, main, top) of an instance\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clear: function () {\n this.discardActiveGroup();\n this.discardActiveObject();\n this.clearContext(this.contextTop);\n return this.callSuper('clear');\n },\n\n /**\n * Draws objects' controls (borders/controls)\n * @param {CanvasRenderingContext2D} ctx Context to render controls on\n */\n drawControls: function(ctx) {\n var activeGroup = this.getActiveGroup();\n\n if (activeGroup) {\n activeGroup._renderControls(ctx);\n }\n else {\n this._drawObjectsControls(ctx);\n }\n },\n\n /**\n * @private\n */\n _drawObjectsControls: function(ctx) {\n for (var i = 0, len = this._objects.length; i < len; ++i) {\n if (!this._objects[i] || !this._objects[i].active) {\n continue;\n }\n this._objects[i]._renderControls(ctx);\n }\n },\n\n /**\n * @private\n */\n _toObject: function(instance, methodName, propertiesToInclude) {\n //If the object is part of the current selection group, it should\n //be transformed appropriately\n //i.e. it should be serialised as it would appear if the selection group\n //were to be destroyed.\n var originalProperties = this._realizeGroupTransformOnObject(instance),\n object = this.callSuper('_toObject', instance, methodName, propertiesToInclude);\n //Undo the damage we did by changing all of its properties\n this._unwindGroupTransformOnObject(instance, originalProperties);\n return object;\n },\n\n /**\n * Realises an object's group transformation on it\n * @private\n * @param {fabric.Object} [instance] the object to transform (gets mutated)\n * @returns the original values of instance which were changed\n */\n _realizeGroupTransformOnObject: function(instance) {\n if (instance.group && instance.group === this.getActiveGroup()) {\n //Copy all the positionally relevant properties across now\n var originalValues = {},\n layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top'];\n layoutProps.forEach(function(prop) {\n originalValues[prop] = instance[prop];\n });\n this.getActiveGroup().realizeTransform(instance);\n return originalValues;\n }\n else {\n return null;\n }\n },\n\n /**\n * Restores the changed properties of instance\n * @private\n * @param {fabric.Object} [instance] the object to un-transform (gets mutated)\n * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject\n */\n _unwindGroupTransformOnObject: function(instance, originalValues) {\n if (originalValues) {\n instance.set(originalValues);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function(markup, instance, reviver) {\n var originalProperties;\n //If the object is in a selection group, simulate what would happen to that\n //object when the group is deselected\n originalProperties = this._realizeGroupTransformOnObject(instance);\n this.callSuper('_setSVGObject', markup, instance, reviver);\n this._unwindGroupTransformOnObject(instance, originalProperties);\n },\n });\n\n // copying static properties manually to work around Opera's bug,\n // where \"prototype\" property is enumerable and overrides existing prototype\n for (var prop in fabric.StaticCanvas) {\n if (prop !== 'prototype') {\n fabric.Canvas[prop] = fabric.StaticCanvas[prop];\n }\n }\n\n if (fabric.isTouchSupported) {\n /** @ignore */\n fabric.Canvas.prototype._setCursorFromEvent = function() { };\n }\n\n /**\n * @ignore\n * @class fabric.Element\n * @alias fabric.Canvas\n * @deprecated Use {@link fabric.Canvas} instead.\n * @constructor\n */\n fabric.Element = fabric.Canvas;\n})();\n\n\n(function() {\n\n var cursorOffset = {\n mt: 0, // n\n tr: 1, // ne\n mr: 2, // e\n br: 3, // se\n mb: 4, // s\n bl: 5, // sw\n ml: 6, // w\n tl: 7 // nw\n },\n addListener = fabric.util.addListener,\n removeListener = fabric.util.removeListener,\n RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1;\n\n function checkClick(e, value) {\n return 'which' in e ? e.which === value : e.button === value - 1;\n }\n\n fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * Map of cursor style values for each of the object controls\n * @private\n */\n cursorMap: [\n 'n-resize',\n 'ne-resize',\n 'e-resize',\n 'se-resize',\n 's-resize',\n 'sw-resize',\n 'w-resize',\n 'nw-resize'\n ],\n\n /**\n * Adds mouse listeners to canvas\n * @private\n */\n _initEventListeners: function () {\n // in case we initialized the class twice. This should not happen normally\n // but in some kind of applications where the canvas element may be changed\n // this is a workaround to having double listeners.\n this.removeListeners();\n this._bindEvents();\n\n addListener(fabric.window, 'resize', this._onResize);\n\n // mouse events\n addListener(this.upperCanvasEl, 'mousedown', this._onMouseDown);\n addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove);\n addListener(this.upperCanvasEl, 'mouseout', this._onMouseOut);\n addListener(this.upperCanvasEl, 'mouseenter', this._onMouseEnter);\n addListener(this.upperCanvasEl, 'wheel', this._onMouseWheel);\n addListener(this.upperCanvasEl, 'contextmenu', this._onContextMenu);\n\n // touch events\n addListener(this.upperCanvasEl, 'touchstart', this._onMouseDown, { passive: false });\n addListener(this.upperCanvasEl, 'touchmove', this._onMouseMove, { passive: false });\n\n if (typeof eventjs !== 'undefined' && 'add' in eventjs) {\n eventjs.add(this.upperCanvasEl, 'gesture', this._onGesture);\n eventjs.add(this.upperCanvasEl, 'drag', this._onDrag);\n eventjs.add(this.upperCanvasEl, 'orientation', this._onOrientationChange);\n eventjs.add(this.upperCanvasEl, 'shake', this._onShake);\n eventjs.add(this.upperCanvasEl, 'longpress', this._onLongPress);\n }\n },\n\n /**\n * @private\n */\n _bindEvents: function() {\n if (this.eventsBinded) {\n // for any reason we pass here twice we do not want to bind events twice.\n return;\n }\n this._onMouseDown = this._onMouseDown.bind(this);\n this._onMouseMove = this._onMouseMove.bind(this);\n this._onMouseUp = this._onMouseUp.bind(this);\n this._onResize = this._onResize.bind(this);\n this._onGesture = this._onGesture.bind(this);\n this._onDrag = this._onDrag.bind(this);\n this._onShake = this._onShake.bind(this);\n this._onLongPress = this._onLongPress.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n this._onMouseWheel = this._onMouseWheel.bind(this);\n this._onMouseOut = this._onMouseOut.bind(this);\n this._onMouseEnter = this._onMouseEnter.bind(this);\n this._onContextMenu = this._onContextMenu.bind(this);\n this.eventsBinded = true;\n },\n\n /**\n * Removes all event listeners\n */\n removeListeners: function() {\n removeListener(fabric.window, 'resize', this._onResize);\n\n removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown);\n removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove);\n removeListener(this.upperCanvasEl, 'mouseout', this._onMouseOut);\n removeListener(this.upperCanvasEl, 'mouseenter', this._onMouseEnter);\n removeListener(this.upperCanvasEl, 'wheel', this._onMouseWheel);\n removeListener(this.upperCanvasEl, 'contextmenu', this._onContextMenu);\n\n removeListener(this.upperCanvasEl, 'touchstart', this._onMouseDown);\n removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove);\n\n if (typeof eventjs !== 'undefined' && 'remove' in eventjs) {\n eventjs.remove(this.upperCanvasEl, 'gesture', this._onGesture);\n eventjs.remove(this.upperCanvasEl, 'drag', this._onDrag);\n eventjs.remove(this.upperCanvasEl, 'orientation', this._onOrientationChange);\n eventjs.remove(this.upperCanvasEl, 'shake', this._onShake);\n eventjs.remove(this.upperCanvasEl, 'longpress', this._onLongPress);\n }\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js gesture\n * @param {Event} [self] Inner Event object\n */\n _onGesture: function(e, self) {\n this.__onTransformGesture && this.__onTransformGesture(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js drag\n * @param {Event} [self] Inner Event object\n */\n _onDrag: function(e, self) {\n this.__onDrag && this.__onDrag(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on wheel event\n */\n _onMouseWheel: function(e) {\n this.__onMouseWheel(e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseOut: function(e) {\n var target = this._hoveredTarget;\n this.fire('mouse:out', { target: target, e: e });\n this._hoveredTarget = null;\n target && target.fire('mouseout', { e: e });\n if (this._iTextInstances) {\n this._iTextInstances.forEach(function(obj) {\n if (obj.isEditing) {\n obj.hiddenTextarea.focus();\n }\n });\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseenter\n */\n _onMouseEnter: function(e) {\n if (!this.findTarget(e)) {\n this.fire('mouse:over', { target: null, e: e });\n this._hoveredTarget = null;\n }\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js orientation change\n * @param {Event} [self] Inner Event object\n */\n _onOrientationChange: function(e, self) {\n this.__onOrientationChange && this.__onOrientationChange(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onShake: function(e, self) {\n this.__onShake && this.__onShake(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onLongPress: function(e, self) {\n this.__onLongPress && this.__onLongPress(e, self);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onContextMenu: function (e) {\n if (this.stopContextMenu) {\n e.stopPropagation();\n e.preventDefault();\n }\n return false;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDown: function (e) {\n this.__onMouseDown(e);\n\n addListener(fabric.document, 'touchend', this._onMouseUp, { passive: false });\n addListener(fabric.document, 'touchmove', this._onMouseMove, { passive: false });\n\n removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove);\n removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove);\n\n if (e.type === 'touchstart') {\n // Unbind mousedown to prevent double triggers from touch devices\n removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown);\n }\n else {\n addListener(fabric.document, 'mouseup', this._onMouseUp);\n addListener(fabric.document, 'mousemove', this._onMouseMove);\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUp: function (e) {\n this.__onMouseUp(e);\n\n removeListener(fabric.document, 'mouseup', this._onMouseUp);\n removeListener(fabric.document, 'touchend', this._onMouseUp);\n\n removeListener(fabric.document, 'mousemove', this._onMouseMove);\n removeListener(fabric.document, 'touchmove', this._onMouseMove);\n\n addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove);\n addListener(this.upperCanvasEl, 'touchmove', this._onMouseMove, { passive: false });\n\n if (e.type === 'touchend') {\n // Wait 400ms before rebinding mousedown to prevent double triggers\n // from touch devices\n var _this = this;\n setTimeout(function() {\n addListener(_this.upperCanvasEl, 'mousedown', _this._onMouseDown);\n }, 400);\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMove: function (e) {\n !this.allowTouchScrolling && e.preventDefault && e.preventDefault();\n this.__onMouseMove(e);\n },\n\n /**\n * @private\n */\n _onResize: function () {\n this.calcOffset();\n },\n\n /**\n * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n * @private\n * @param {Object} target\n * @param {Object} pointer\n */\n _shouldRender: function(target, pointer) {\n var activeObject = this.getActiveGroup() || this.getActiveObject();\n\n if (activeObject && activeObject.isEditing && target === activeObject) {\n // if we mouse up/down over a editing textbox a cursor change,\n // there is no need to re render\n return false;\n }\n return !!(\n (target && (\n target.isMoving ||\n target !== activeObject))\n ||\n (!target && !!activeObject)\n ||\n (!target && !activeObject && !this._groupSelector)\n ||\n (pointer &&\n this._previousPointer &&\n this.selection && (\n pointer.x !== this._previousPointer.x ||\n pointer.y !== this._previousPointer.y))\n );\n },\n\n /**\n * Method that defines the actions when mouse is released on canvas.\n * The method resets the currentTransform parameters, store the image corner\n * position in the image object and render the canvas on top.\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseUp: function (e) {\n\n var target;\n // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'up', target, RIGHT_CLICK);\n }\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'up', target, MIDDLE_CLICK);\n }\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n return;\n }\n\n var searchTarget = true, transform = this._currentTransform,\n groupSelector = this._groupSelector,\n isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0));\n\n if (transform) {\n this._finalizeCurrentTransform(e);\n searchTarget = !transform.actionPerformed;\n }\n\n target = searchTarget ? this.findTarget(e, true) : transform.target;\n\n var shouldRender = this._shouldRender(target, this.getPointer(e));\n\n if (target || !isClick) {\n this._maybeGroupObjects(e);\n }\n else {\n // those are done by default on mouse up\n // by _maybeGroupObjects, we are skipping it in case of no target find\n this._groupSelector = null;\n this._currentTransform = null;\n }\n\n if (target) {\n target.isMoving = false;\n }\n this._setCursorFromEvent(e, target);\n this._handleEvent(e, 'up', target ? target : null, LEFT_CLICK, isClick);\n target && (target.__corner = 0);\n shouldRender && this.renderAll();\n },\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {Event} e event from mouse\n * @param {String} eventType event to fire (up, down or move)\n * @param {fabric.Object} targetObj receiving event\n * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right\n * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move.\n */\n _handleEvent: function(e, eventType, targetObj, button, isClick) {\n var target = typeof targetObj === 'undefined' ? this.findTarget(e) : targetObj,\n targets = this.targets || [],\n options = {\n e: e,\n target: target,\n subTargets: targets,\n button: button || LEFT_CLICK,\n isClick: isClick || false\n };\n this.fire('mouse:' + eventType, options);\n target && target.fire('mouse' + eventType, options);\n for (var i = 0; i < targets.length; i++) {\n targets[i].fire('mouse' + eventType, options);\n }\n },\n\n /**\n * @private\n * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n */\n _finalizeCurrentTransform: function(e) {\n\n var transform = this._currentTransform,\n target = transform.target;\n\n if (target._scaling) {\n target._scaling = false;\n }\n\n target.setCoords();\n this._restoreOriginXY(target);\n\n if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {\n this.fire('object:modified', { target: target, e: e });\n target.fire('modified', { e: e });\n }\n },\n\n /**\n * @private\n * @param {Object} target Object to restore\n */\n _restoreOriginXY: function(target) {\n if (this._previousOriginX && this._previousOriginY) {\n\n var originPoint = target.translateToOriginPoint(\n target.getCenterPoint(),\n this._previousOriginX,\n this._previousOriginY);\n\n target.originX = this._previousOriginX;\n target.originY = this._previousOriginY;\n\n target.left = originPoint.x;\n target.top = originPoint.y;\n\n this._previousOriginX = null;\n this._previousOriginY = null;\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDownInDrawingMode: function(e) {\n this._isCurrentlyDrawing = true;\n this.discardActiveObject(e).renderAll();\n if (this.clipTo) {\n fabric.util.clipContext(this, this.contextTop);\n }\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseDown(pointer);\n this._handleEvent(e, 'down');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode: function(e) {\n if (this._isCurrentlyDrawing) {\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseMove(pointer);\n }\n this.setCursor(this.freeDrawingCursor);\n this._handleEvent(e, 'move');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode: function(e) {\n this._isCurrentlyDrawing = false;\n if (this.clipTo) {\n this.contextTop.restore();\n }\n this.freeDrawingBrush.onMouseUp();\n this._handleEvent(e, 'up');\n },\n\n /**\n * Method that defines the actions when mouse is clicked on canvas.\n * The method inits the currentTransform parameters and renders all the\n * canvas so the current image can be placed on the top canvas and the rest\n * in on the container one.\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n __onMouseDown: function (e) {\n\n var target = this.findTarget(e);\n\n // if right click just fire events\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'down', target ? target : null, RIGHT_CLICK);\n }\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'down', target ? target : null, MIDDLE_CLICK);\n }\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n return;\n }\n\n // ignore if some object is being transformed at this moment\n if (this._currentTransform) {\n return;\n }\n\n // save pointer for check in __onMouseUp event\n var pointer = this.getPointer(e, true);\n this._previousPointer = pointer;\n\n var shouldRender = this._shouldRender(target, pointer),\n shouldGroup = this._shouldGroup(e, target);\n\n if (this._shouldClearSelection(e, target)) {\n this.deactivateAllWithDispatch(e);\n }\n else if (shouldGroup) {\n this._handleGrouping(e, target);\n target = this.getActiveGroup();\n }\n\n if (this.selection && (!target || (!target.selectable && !target.isEditing))) {\n this._groupSelector = {\n ex: pointer.x,\n ey: pointer.y,\n top: 0,\n left: 0\n };\n }\n\n if (target) {\n if (target.selectable && (target.__corner || !shouldGroup)) {\n this._beforeTransform(e, target);\n this._setupCurrentTransform(e, target);\n }\n var activeObject = this.getActiveObject();\n if (target !== this.getActiveGroup() && target !== activeObject) {\n this.deactivateAll();\n if (target.selectable) {\n activeObject && activeObject.fire('deselected', { e: e });\n this.setActiveObject(target, e);\n }\n }\n }\n this._handleEvent(e, 'down', target ? target : null);\n // we must renderAll so that we update the visuals\n shouldRender && this.renderAll();\n },\n\n /**\n * @private\n */\n _beforeTransform: function(e, target) {\n this.stateful && target.saveState();\n\n // determine if it's a drag or rotate case\n if (target._findTargetCorner(this.getPointer(e))) {\n this.onBeforeScaleRotate(target);\n }\n\n },\n\n /**\n * @private\n * @param {Object} target Object for that origin is set to center\n */\n _setOriginToCenter: function(target) {\n this._previousOriginX = this._currentTransform.target.originX;\n this._previousOriginY = this._currentTransform.target.originY;\n\n var center = target.getCenterPoint();\n\n target.originX = 'center';\n target.originY = 'center';\n\n target.left = center.x;\n target.top = center.y;\n\n this._currentTransform.left = target.left;\n this._currentTransform.top = target.top;\n },\n\n /**\n * @private\n * @param {Object} target Object for that center is set to origin\n */\n _setCenterToOrigin: function(target) {\n var originPoint = target.translateToOriginPoint(\n target.getCenterPoint(),\n this._previousOriginX,\n this._previousOriginY);\n\n target.originX = this._previousOriginX;\n target.originY = this._previousOriginY;\n\n target.left = originPoint.x;\n target.top = originPoint.y;\n\n this._previousOriginX = null;\n this._previousOriginY = null;\n },\n\n /**\n * Method that defines the actions when mouse is hovering the canvas.\n * The currentTransform parameter will definde whether the user is rotating/scaling/translating\n * an image or neither of them (only hovering). A group selection is also possible and would cancel\n * all any other type of action.\n * In case of an image transformation only the top canvas will be rendered.\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n __onMouseMove: function (e) {\n\n var target, pointer;\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n return;\n }\n if (typeof e.touches !== 'undefined' && e.touches.length > 1) {\n return;\n }\n\n var groupSelector = this._groupSelector;\n\n // We initially clicked in an empty area, so we draw a box for multiple selection\n if (groupSelector) {\n pointer = this.getPointer(e, true);\n\n groupSelector.left = pointer.x - groupSelector.ex;\n groupSelector.top = pointer.y - groupSelector.ey;\n\n this.renderTop();\n }\n else if (!this._currentTransform) {\n target = this.findTarget(e);\n this._setCursorFromEvent(e, target);\n }\n else {\n this._transformObject(e);\n }\n this._handleEvent(e, 'move', target ? target : null);\n },\n\n /**\n * Method that defines actions when an Event Mouse Wheel\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseWheel: function(e) {\n this._handleEvent(e, 'wheel');\n },\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject: function(e) {\n var pointer = this.getPointer(e),\n transform = this._currentTransform;\n\n transform.reset = false;\n transform.target.isMoving = true;\n transform.shiftKey = e.shiftKey;\n transform.altKey = e[this.centeredKey];\n\n this._beforeScaleTransform(e, transform);\n this._performTransformAction(e, transform, pointer);\n\n transform.actionPerformed && this.renderAll();\n },\n\n /**\n * @private\n */\n _performTransformAction: function(e, transform, pointer) {\n var x = pointer.x,\n y = pointer.y,\n target = transform.target,\n action = transform.action,\n actionPerformed = false;\n\n if (action === 'rotate') {\n (actionPerformed = this._rotateObject(x, y)) && this._fire('rotating', target, e);\n }\n else if (action === 'scale') {\n (actionPerformed = this._onScale(e, transform, x, y)) && this._fire('scaling', target, e);\n }\n else if (action === 'scaleX') {\n (actionPerformed = this._scaleObject(x, y, 'x')) && this._fire('scaling', target, e);\n }\n else if (action === 'scaleY') {\n (actionPerformed = this._scaleObject(x, y, 'y')) && this._fire('scaling', target, e);\n }\n else if (action === 'skewX') {\n (actionPerformed = this._skewObject(x, y, 'x')) && this._fire('skewing', target, e);\n }\n else if (action === 'skewY') {\n (actionPerformed = this._skewObject(x, y, 'y')) && this._fire('skewing', target, e);\n }\n else {\n actionPerformed = this._translateObject(x, y);\n if (actionPerformed) {\n this._fire('moving', target, e);\n this.setCursor(target.moveCursor || this.moveCursor);\n }\n }\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n },\n\n /**\n * @private\n */\n _fire: function(eventName, target, e) {\n this.fire('object:' + eventName, { target: target, e: e });\n target.fire(eventName, { e: e });\n },\n\n /**\n * @private\n */\n _beforeScaleTransform: function(e, transform) {\n if (transform.action === 'scale' || transform.action === 'scaleX' || transform.action === 'scaleY') {\n var centerTransform = this._shouldCenterTransform(transform.target);\n\n // Switch from a normal resize to center-based\n if ((centerTransform && (transform.originX !== 'center' || transform.originY !== 'center')) ||\n // Switch from center-based resize to normal one\n (!centerTransform && transform.originX === 'center' && transform.originY === 'center')\n ) {\n this._resetCurrentTransform();\n transform.reset = true;\n }\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {Object} transform current tranform\n * @param {Number} x mouse position x from origin\n * @param {Number} y mouse poistion y from origin\n * @return {Boolean} true if the scaling occurred\n */\n _onScale: function(e, transform, x, y) {\n if ((e[this.uniScaleKey] || this.uniScaleTransform) && !transform.target.get('lockUniScaling')) {\n transform.currentAction = 'scale';\n return this._scaleObject(x, y);\n }\n else {\n // Switch from a normal resize to proportional\n if (!transform.reset && transform.currentAction === 'scale') {\n this._resetCurrentTransform();\n }\n\n transform.currentAction = 'scaleEqually';\n return this._scaleObject(x, y, 'equally');\n }\n },\n\n /**\n * Sets the cursor depending on where the canvas is being hovered.\n * Note: very buggy in Opera\n * @param {Event} e Event object\n * @param {Object} target Object that the mouse is hovering, if so.\n */\n _setCursorFromEvent: function (e, target) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return false;\n }\n\n var hoverCursor = target.hoverCursor || this.hoverCursor,\n activeGroup = this.getActiveGroup(),\n // only show proper corner when group selection is not active\n corner = target._findTargetCorner\n && (!activeGroup || !activeGroup.contains(target))\n && target._findTargetCorner(this.getPointer(e, true));\n\n if (!corner) {\n this.setCursor(hoverCursor);\n }\n else {\n this._setCornerCursor(corner, target, e);\n }\n //actually unclear why it should return something\n //is never evaluated\n return true;\n },\n\n /**\n * @private\n */\n _setCornerCursor: function(corner, target, e) {\n if (corner in cursorOffset) {\n this.setCursor(this._getRotatedCornerCursor(corner, target, e));\n }\n else if (corner === 'mtr' && target.hasRotatingPoint) {\n this.setCursor(this.rotationCursor);\n }\n else {\n this.setCursor(this.defaultCursor);\n return false;\n }\n },\n\n /**\n * @private\n */\n _getRotatedCornerCursor: function(corner, target, e) {\n var n = Math.round((target.getAngle() % 360) / 45);\n\n if (n < 0) {\n n += 8; // full circle ahead\n }\n n += cursorOffset[corner];\n if (e[this.altActionKey] && cursorOffset[corner] % 2 === 0) {\n //if we are holding shift and we are on a mx corner...\n n += 2;\n }\n // normalize n to be from 0 to 7\n n %= 8;\n\n return this.cursorMap[n];\n }\n });\n})();\n\n\n(function() {\n\n var min = Math.min,\n max = Math.max;\n\n fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n * @return {Boolean}\n */\n _shouldGroup: function(e, target) {\n var activeObject = this.getActiveObject();\n return e[this.selectionKey] && target && target.selectable &&\n (this.getActiveGroup() || (activeObject && activeObject !== target))\n && this.selection;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _handleGrouping: function (e, target) {\n var activeGroup = this.getActiveGroup();\n\n if (target === activeGroup) {\n // if it's a group, find target again, using activeGroup objects\n target = this.findTarget(e, true);\n // if even object is not found, bail out\n if (!target) {\n return;\n }\n }\n if (activeGroup) {\n this._updateActiveGroup(target, e);\n }\n else {\n this._createActiveGroup(target, e);\n }\n\n if (this._activeGroup) {\n this._activeGroup.saveCoords();\n }\n },\n\n /**\n * @private\n */\n _updateActiveGroup: function(target, e) {\n var activeGroup = this.getActiveGroup();\n\n if (activeGroup.contains(target)) {\n\n activeGroup.removeWithUpdate(target);\n target.set('active', false);\n\n if (activeGroup.size() === 1) {\n // remove group alltogether if after removal it only contains 1 object\n this.discardActiveGroup(e);\n // activate last remaining object\n this.setActiveObject(activeGroup.item(0), e);\n return;\n }\n }\n else {\n activeGroup.addWithUpdate(target);\n }\n this.fire('selection:created', { target: activeGroup, e: e });\n activeGroup.set('active', true);\n },\n\n /**\n * @private\n */\n _createActiveGroup: function(target, e) {\n\n if (this._activeObject && target !== this._activeObject) {\n\n var group = this._createGroup(target);\n group.addWithUpdate();\n\n this.setActiveGroup(group, e);\n this._activeObject = null;\n\n this.fire('selection:created', { target: group, e: e });\n }\n\n target.set('active', true);\n },\n\n /**\n * @private\n * @param {Object} target\n */\n _createGroup: function(target) {\n\n var objects = this.getObjects(),\n isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),\n groupObjects = isActiveLower\n ? [this._activeObject, target]\n : [target, this._activeObject];\n this._activeObject.isEditing && this._activeObject.exitEditing();\n return new fabric.Group(groupObjects, {\n canvas: this\n });\n },\n\n /**\n * @private\n * @param {Event} e mouse event\n */\n _groupSelectedObjects: function (e) {\n\n var group = this._collectObjects();\n\n // do not create group for 1 element only\n if (group.length === 1) {\n this.setActiveObject(group[0], e);\n }\n else if (group.length > 1) {\n group = new fabric.Group(group.reverse(), {\n canvas: this\n });\n group.addWithUpdate();\n this.setActiveGroup(group, e);\n group.saveCoords();\n this.fire('selection:created', { target: group, e: e });\n this.renderAll();\n }\n },\n\n /**\n * @private\n */\n _collectObjects: function() {\n var group = [],\n currentObject,\n x1 = this._groupSelector.ex,\n y1 = this._groupSelector.ey,\n x2 = x1 + this._groupSelector.left,\n y2 = y1 + this._groupSelector.top,\n selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),\n selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),\n isClick = x1 === x2 && y1 === y2;\n\n for (var i = this._objects.length; i--; ) {\n currentObject = this._objects[i];\n\n if (!currentObject || !currentObject.selectable || !currentObject.visible) {\n continue;\n }\n\n if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) ||\n currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) ||\n currentObject.containsPoint(selectionX1Y1) ||\n currentObject.containsPoint(selectionX2Y2)\n ) {\n currentObject.set('active', true);\n group.push(currentObject);\n\n // only add one object if it's a click\n if (isClick) {\n break;\n }\n }\n }\n\n return group;\n },\n\n /**\n * @private\n */\n _maybeGroupObjects: function(e) {\n if (this.selection && this._groupSelector) {\n this._groupSelectedObjects(e);\n }\n\n var activeGroup = this.getActiveGroup();\n if (activeGroup) {\n activeGroup.setObjectsCoords().setCoords();\n activeGroup.isMoving = false;\n this.setCursor(this.defaultCursor);\n }\n\n // clear selection and current transformation\n this._groupSelector = null;\n this._currentTransform = null;\n }\n });\n\n})();\n\n\n(function () {\n\n var supportQuality = fabric.StaticCanvas.supports('toDataURLWithQuality');\n\n fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n * @param {Object} [options] Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo}\n * @example Generate jpeg dataURL with lower quality\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example Generate cropped png dataURL (clipping of canvas)\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example Generate double scaled png dataURL\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n */\n toDataURL: function (options) {\n options || (options = { });\n\n var format = options.format || 'png',\n quality = options.quality || 1,\n multiplier = options.multiplier || 1,\n cropping = {\n left: options.left || 0,\n top: options.top || 0,\n width: options.width || 0,\n height: options.height || 0,\n };\n return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier);\n },\n\n /**\n * @private\n */\n __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) {\n\n var origWidth = this.getWidth(),\n origHeight = this.getHeight(),\n scaledWidth = (cropping.width || this.getWidth()) * multiplier,\n scaledHeight = (cropping.height || this.getHeight()) * multiplier,\n zoom = this.getZoom(),\n newZoom = zoom * multiplier,\n vp = this.viewportTransform,\n translateX = (vp[4] - cropping.left) * multiplier,\n translateY = (vp[5] - cropping.top) * multiplier,\n newVp = [newZoom, 0, 0, newZoom, translateX, translateY],\n originalInteractive = this.interactive;\n\n this.viewportTransform = newVp;\n // setting interactive to false avoid exporting controls\n this.interactive && (this.interactive = false);\n if (origWidth !== scaledWidth || origHeight !== scaledHeight) {\n // this.setDimensions is going to renderAll also;\n this.setDimensions({ width: scaledWidth, height: scaledHeight }, { backstoreOnly: true });\n }\n else {\n this.renderAll();\n }\n var data = this.__toDataURL(format, quality, cropping);\n originalInteractive && (this.interactive = originalInteractive);\n this.viewportTransform = vp;\n //setDimensions with no option object is taking care of:\n //this.width, this.height, this.renderAll()\n this.setDimensions({ width: origWidth, height: origHeight }, { backstoreOnly: true });\n return data;\n },\n\n /**\n * @private\n */\n __toDataURL: function(format, quality) {\n\n var canvasEl = this.contextContainer.canvas;\n // to avoid common confusion https://github.com/kangax/fabric.js/issues/806\n if (format === 'jpg') {\n format = 'jpeg';\n }\n\n var data = supportQuality\n ? canvasEl.toDataURL('image/' + format, quality)\n : canvasEl.toDataURL('image/' + format);\n\n return data;\n },\n\n /**\n * Exports canvas element to a dataurl image (allowing to change image size via multiplier).\n * @deprecated since 1.0.13\n * @param {String} format (png|jpeg)\n * @param {Number} multiplier\n * @param {Number} quality (0..1)\n * @return {String}\n */\n toDataURLWithMultiplier: function (format, multiplier, quality) {\n return this.toDataURL({\n format: format,\n multiplier: multiplier,\n quality: quality\n });\n },\n });\n\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Populates canvas with data from the specified dataless JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toDatalessJSON}\n * @deprecated since 1.2.2\n * @param {String|Object} json JSON string or object\n * @param {Function} callback Callback, invoked when json is parsed\n * and corresponding objects (e.g: {@link fabric.Image})\n * are initialized\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @return {fabric.Canvas} instance\n * @chainable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n */\n loadFromDatalessJSON: function (json, callback, reviver) {\n return this.loadFromJSON(json, callback, reviver);\n },\n\n /**\n * Populates canvas with data from the specified JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n * @param {String|Object} json JSON string or object\n * @param {Function} callback Callback, invoked when json is parsed\n * and corresponding objects (e.g: {@link fabric.Image})\n * are initialized\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @return {fabric.Canvas} instance\n * @chainable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n * @example loadFromJSON\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));\n * @example loadFromJSON with reviver\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) {\n * // `o` = json object\n * // `object` = fabric.Object instance\n * // ... do some stuff ...\n * });\n */\n loadFromJSON: function (json, callback, reviver) {\n if (!json) {\n return;\n }\n\n // serialize if it wasn't already\n var serialized = (typeof json === 'string')\n ? JSON.parse(json)\n : fabric.util.object.clone(json);\n\n var _this = this,\n renderOnAddRemove = this.renderOnAddRemove;\n this.renderOnAddRemove = false;\n\n this._enlivenObjects(serialized.objects, function (enlivenedObjects) {\n _this.clear();\n _this._setBgOverlay(serialized, function () {\n enlivenedObjects.forEach(function(obj, index) {\n // we splice the array just in case some custom classes restored from JSON\n // will add more object to canvas at canvas init.\n _this.insertAt(obj, index);\n });\n _this.renderOnAddRemove = renderOnAddRemove;\n // remove parts i cannot set as options\n delete serialized.objects;\n delete serialized.backgroundImage;\n delete serialized.overlayImage;\n delete serialized.background;\n delete serialized.overlay;\n // this._initOptions does too many things to just\n // call it. Normally loading an Object from JSON\n // create the Object instance. Here the Canvas is\n // already an instance and we are just loading things over it\n _this._setOptions(serialized);\n _this.renderAll();\n callback && callback();\n });\n }, reviver);\n return this;\n },\n\n /**\n * @private\n * @param {Object} serialized Object with background and overlay information\n * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n */\n _setBgOverlay: function(serialized, callback) {\n var loaded = {\n backgroundColor: false,\n overlayColor: false,\n backgroundImage: false,\n overlayImage: false\n };\n\n if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) {\n callback && callback();\n return;\n }\n\n var cbIfLoaded = function () {\n if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) {\n callback && callback();\n }\n };\n\n this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded);\n this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded);\n this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded);\n this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded);\n },\n\n /**\n * @private\n * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor)\n * @param {(Object|String)} value Value to set\n * @param {Object} loaded Set loaded property to true if property is set\n * @param {Object} callback Callback function to invoke after property is set\n */\n __setBgOverlay: function(property, value, loaded, callback) {\n var _this = this;\n\n if (!value) {\n loaded[property] = true;\n callback && callback();\n return;\n }\n\n if (property === 'backgroundImage' || property === 'overlayImage') {\n fabric.util.enlivenObjects([value], function(enlivedObject){\n _this[property] = enlivedObject[0];\n loaded[property] = true;\n callback && callback();\n });\n }\n else {\n this['set' + fabric.util.string.capitalize(property, true)](value, function() {\n loaded[property] = true;\n callback && callback();\n });\n }\n },\n\n /**\n * @private\n * @param {Array} objects\n * @param {Function} callback\n * @param {Function} [reviver]\n */\n _enlivenObjects: function (objects, callback, reviver) {\n if (!objects || objects.length === 0) {\n callback && callback([]);\n return;\n }\n\n fabric.util.enlivenObjects(objects, function(enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, null, reviver);\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Function} callback\n */\n _toDataURL: function (format, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURL(format));\n });\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Number} multiplier\n * @param {Function} callback\n */\n _toDataURLWithMultiplier: function (format, multiplier, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURLWithMultiplier(format, multiplier));\n });\n },\n\n /**\n * Clones canvas instance\n * @param {Object} [callback] Receives cloned instance as a first argument\n * @param {Array} [properties] Array of properties to include in the cloned canvas and children\n */\n clone: function (callback, properties) {\n var data = JSON.stringify(this.toJSON(properties));\n this.cloneWithoutData(function(clone) {\n clone.loadFromJSON(data, function() {\n callback && callback(clone);\n });\n });\n },\n\n /**\n * Clones canvas instance without cloning existing data.\n * This essentially copies canvas dimensions, clipping properties, etc.\n * but leaves data empty (so that you can populate it with your own)\n * @param {Object} [callback] Receives cloned instance as a first argument\n */\n cloneWithoutData: function(callback) {\n var el = fabric.document.createElement('canvas');\n\n el.width = this.getWidth();\n el.height = this.getHeight();\n\n var clone = new fabric.Canvas(el);\n clone.clipTo = this.clipTo;\n if (this.backgroundImage) {\n clone.setBackgroundImage(this.backgroundImage.src, function() {\n clone.renderAll();\n callback && callback(clone);\n });\n clone.backgroundImageOpacity = this.backgroundImageOpacity;\n clone.backgroundImageStretch = this.backgroundImageStretch;\n }\n else {\n callback && callback(clone);\n }\n }\n});\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n capitalize = fabric.util.string.capitalize,\n degreesToRadians = fabric.util.degreesToRadians,\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash'),\n objectCaching = !fabric.isLikelyNode,\n ALIASING_LIMIT = 2;\n\n if (fabric.Object) {\n return;\n }\n\n /**\n * Root object class from which all 2d shape classes inherit from\n * @class fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n * @see {@link fabric.Object#initialize} for constructor definition\n *\n * @fires added\n * @fires removed\n *\n * @fires selected\n * @fires deselected\n * @fires modified\n * @fires rotating\n * @fires scaling\n * @fires moving\n * @fires skewing\n *\n * @fires mousedown\n * @fires mouseup\n * @fires mouseover\n * @fires mouseout\n * @fires mousewheel\n */\n fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ {\n\n /**\n * Retrieves object's {@link fabric.Object#clipTo|clipping function}\n * @method getClipTo\n * @memberOf fabric.Object.prototype\n * @return {Function}\n */\n\n /**\n * Sets object's {@link fabric.Object#clipTo|clipping function}\n * @method setClipTo\n * @memberOf fabric.Object.prototype\n * @param {Function} clipTo Clipping function\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#transformMatrix|transformMatrix}\n * @method getTransformMatrix\n * @memberOf fabric.Object.prototype\n * @return {Array} transformMatrix\n */\n\n /**\n * Sets object's {@link fabric.Object#transformMatrix|transformMatrix}\n * @method setTransformMatrix\n * @memberOf fabric.Object.prototype\n * @param {Array} transformMatrix\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#visible|visible} state\n * @method getVisible\n * @memberOf fabric.Object.prototype\n * @return {Boolean} True if visible\n */\n\n /**\n * Sets object's {@link fabric.Object#visible|visible} state\n * @method setVisible\n * @memberOf fabric.Object.prototype\n * @param {Boolean} value visible value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#shadow|shadow}\n * @method getShadow\n * @memberOf fabric.Object.prototype\n * @return {Object} Shadow instance\n */\n\n /**\n * Retrieves object's {@link fabric.Object#stroke|stroke}\n * @method getStroke\n * @memberOf fabric.Object.prototype\n * @return {String} stroke value\n */\n\n /**\n * Sets object's {@link fabric.Object#stroke|stroke}\n * @method setStroke\n * @memberOf fabric.Object.prototype\n * @param {String} value stroke value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#strokeWidth|strokeWidth}\n * @method getStrokeWidth\n * @memberOf fabric.Object.prototype\n * @return {Number} strokeWidth value\n */\n\n /**\n * Sets object's {@link fabric.Object#strokeWidth|strokeWidth}\n * @method setStrokeWidth\n * @memberOf fabric.Object.prototype\n * @param {Number} value strokeWidth value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#originX|originX}\n * @method getOriginX\n * @memberOf fabric.Object.prototype\n * @return {String} originX value\n */\n\n /**\n * Sets object's {@link fabric.Object#originX|originX}\n * @method setOriginX\n * @memberOf fabric.Object.prototype\n * @param {String} value originX value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#originY|originY}\n * @method getOriginY\n * @memberOf fabric.Object.prototype\n * @return {String} originY value\n */\n\n /**\n * Sets object's {@link fabric.Object#originY|originY}\n * @method setOriginY\n * @memberOf fabric.Object.prototype\n * @param {String} value originY value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#fill|fill}\n * @method getFill\n * @memberOf fabric.Object.prototype\n * @return {String} Fill value\n */\n\n /**\n * Sets object's {@link fabric.Object#fill|fill}\n * @method setFill\n * @memberOf fabric.Object.prototype\n * @param {String} value Fill value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#opacity|opacity}\n * @method getOpacity\n * @memberOf fabric.Object.prototype\n * @return {Number} Opacity value (0-1)\n */\n\n /**\n * Sets object's {@link fabric.Object#opacity|opacity}\n * @method setOpacity\n * @memberOf fabric.Object.prototype\n * @param {Number} value Opacity value (0-1)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#angle|angle} (in degrees)\n * @method getAngle\n * @memberOf fabric.Object.prototype\n * @return {Number}\n */\n\n /**\n * Retrieves object's {@link fabric.Object#top|top position}\n * @method getTop\n * @memberOf fabric.Object.prototype\n * @return {Number} Top value (in pixels)\n */\n\n /**\n * Sets object's {@link fabric.Object#top|top position}\n * @method setTop\n * @memberOf fabric.Object.prototype\n * @param {Number} value Top value (in pixels)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#left|left position}\n * @method getLeft\n * @memberOf fabric.Object.prototype\n * @return {Number} Left value (in pixels)\n */\n\n /**\n * Sets object's {@link fabric.Object#left|left position}\n * @method setLeft\n * @memberOf fabric.Object.prototype\n * @param {Number} value Left value (in pixels)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#scaleX|scaleX} value\n * @method getScaleX\n * @memberOf fabric.Object.prototype\n * @return {Number} scaleX value\n */\n\n /**\n * Sets object's {@link fabric.Object#scaleX|scaleX} value\n * @method setScaleX\n * @memberOf fabric.Object.prototype\n * @param {Number} value scaleX value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#scaleY|scaleY} value\n * @method getScaleY\n * @memberOf fabric.Object.prototype\n * @return {Number} scaleY value\n */\n\n /**\n * Sets object's {@link fabric.Object#scaleY|scaleY} value\n * @method setScaleY\n * @memberOf fabric.Object.prototype\n * @param {Number} value scaleY value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#flipX|flipX} value\n * @method getFlipX\n * @memberOf fabric.Object.prototype\n * @return {Boolean} flipX value\n */\n\n /**\n * Sets object's {@link fabric.Object#flipX|flipX} value\n * @method setFlipX\n * @memberOf fabric.Object.prototype\n * @param {Boolean} value flipX value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#flipY|flipY} value\n * @method getFlipY\n * @memberOf fabric.Object.prototype\n * @return {Boolean} flipY value\n */\n\n /**\n * Sets object's {@link fabric.Object#flipY|flipY} value\n * @method setFlipY\n * @memberOf fabric.Object.prototype\n * @param {Boolean} value flipY value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Type of an object (rect, circle, path, etc.).\n * Note that this property is meant to be read-only and not meant to be modified.\n * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly.\n * @type String\n * @default\n */\n type: 'object',\n\n /**\n * Horizontal origin of transformation of an object (one of \"left\", \"right\", \"center\")\n * See http://jsfiddle.net/1ow02gea/40/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originX: 'left',\n\n /**\n * Vertical origin of transformation of an object (one of \"top\", \"bottom\", \"center\")\n * See http://jsfiddle.net/1ow02gea/40/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originY: 'top',\n\n /**\n * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom}\n * @type Number\n * @default\n */\n top: 0,\n\n /**\n * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right}\n * @type Number\n * @default\n */\n left: 0,\n\n /**\n * Object width\n * @type Number\n * @default\n */\n width: 0,\n\n /**\n * Object height\n * @type Number\n * @default\n */\n height: 0,\n\n /**\n * Object scale factor (horizontal)\n * @type Number\n * @default\n */\n scaleX: 1,\n\n /**\n * Object scale factor (vertical)\n * @type Number\n * @default\n */\n scaleY: 1,\n\n /**\n * When true, an object is rendered as flipped horizontally\n * @type Boolean\n * @default\n */\n flipX: false,\n\n /**\n * When true, an object is rendered as flipped vertically\n * @type Boolean\n * @default\n */\n flipY: false,\n\n /**\n * Opacity of an object\n * @type Number\n * @default\n */\n opacity: 1,\n\n /**\n * Angle of rotation of an object (in degrees)\n * @type Number\n * @default\n */\n angle: 0,\n\n /**\n * Angle of skew on x axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewX: 0,\n\n /**\n * Angle of skew on y axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewY: 0,\n\n /**\n * Size of object's controlling corners (in pixels)\n * @type Number\n * @default\n */\n cornerSize: 13,\n\n /**\n * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill)\n * @type Boolean\n * @default\n */\n transparentCorners: true,\n\n /**\n * Default cursor value used when hovering over this object on canvas\n * @type String\n * @default\n */\n hoverCursor: null,\n\n /**\n * Default cursor value used when moving this object on canvas\n * @type String\n * @default\n */\n moveCursor: null,\n\n /**\n * Padding between object and its controlling borders (in pixels)\n * @type Number\n * @default\n */\n padding: 0,\n\n /**\n * Color of controlling borders of an object (when it's active)\n * @type String\n * @default\n */\n borderColor: 'rgba(102,153,255,0.75)',\n\n /**\n * Array specifying dash pattern of an object's borders (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n borderDashArray: null,\n\n /**\n * Color of controlling corners of an object (when it's active)\n * @type String\n * @default\n */\n cornerColor: 'rgba(102,153,255,0.5)',\n\n /**\n * Color of controlling corners of an object (when it's active and transparentCorners false)\n * @since 1.6.2\n * @type String\n * @default\n */\n cornerStrokeColor: null,\n\n /**\n * Specify style of control, 'rect' or 'circle'\n * @since 1.6.2\n * @type String\n */\n cornerStyle: 'rect',\n\n /**\n * Array specifying dash pattern of an object's control (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n cornerDashArray: null,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being scaled via the controls.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being rotated via the controls.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: true,\n\n /**\n * Color of object's fill\n * @type String\n * @default\n */\n fill: 'rgb(0,0,0)',\n\n /**\n * Fill rule used to fill an object\n * accepted values are nonzero, evenodd\n * Backwards incompatibility note: This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead)\n * @type String\n * @default\n */\n fillRule: 'nonzero',\n\n /**\n * Composite rule used for canvas globalCompositeOperation\n * @type String\n * @default\n */\n globalCompositeOperation: 'source-over',\n\n /**\n * Background color of an object.\n * @type String\n * @default\n */\n backgroundColor: '',\n\n /**\n * Selection Background color of an object. colored layer behind the object when it is active.\n * does not mix good with globalCompositeOperation methods.\n * @type String\n * @default\n */\n selectionBackgroundColor: '',\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Width of a stroke used to render this object\n * @type Number\n * @default\n */\n strokeWidth: 1,\n\n /**\n * Array specifying dash pattern of an object's stroke (stroke must be defined)\n * @type Array\n */\n strokeDashArray: null,\n\n /**\n * Line endings style of an object's stroke (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'butt',\n\n /**\n * Corner style of an object's stroke (one of \"bevil\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'miter',\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of an object's stroke\n * @type Number\n * @default\n */\n strokeMiterLimit: 10,\n\n /**\n * Shadow object representing shadow of this shape\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Opacity of object's controlling borders when object is active and moving\n * @type Number\n * @default\n */\n borderOpacityWhenMoving: 0.4,\n\n /**\n * Scale factor of object's controlling borders\n * @type Number\n * @default\n */\n borderScaleFactor: 1,\n\n /**\n * Transform matrix (similar to SVG's transform matrix)\n * @type Array\n */\n transformMatrix: null,\n\n /**\n * Minimum allowed scale value of an object\n * @type Number\n * @default\n */\n minScaleLimit: 0.01,\n\n /**\n * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection).\n * But events still fire on it.\n * @type Boolean\n * @default\n */\n selectable: true,\n\n /**\n * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4\n * @type Boolean\n * @default\n */\n evented: true,\n\n /**\n * When set to `false`, an object is not rendered on canvas\n * @type Boolean\n * @default\n */\n visible: true,\n\n /**\n * When set to `false`, object's controls are not displayed and can not be used to manipulate object\n * @type Boolean\n * @default\n */\n hasControls: true,\n\n /**\n * When set to `false`, object's controlling borders are not rendered\n * @type Boolean\n * @default\n */\n hasBorders: true,\n\n /**\n * When set to `false`, object's controlling rotating point will not be visible or selectable\n * @type Boolean\n * @default\n */\n hasRotatingPoint: true,\n\n /**\n * Offset for object's controlling rotating point (when enabled via `hasRotatingPoint`)\n * @type Number\n * @default\n */\n rotatingPointOffset: 40,\n\n /**\n * When set to `true`, objects are \"found\" on canvas on per-pixel basis rather than according to bounding box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * When `false`, default object's values are not included in its serialization\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * Function that determines clipping of an object (context is passed as a first argument)\n * Note that context origin is at the object's center point (not left/top corner)\n * @type Function\n */\n clipTo: null,\n\n /**\n * When `true`, object horizontal movement is locked\n * @type Boolean\n * @default\n */\n lockMovementX: false,\n\n /**\n * When `true`, object vertical movement is locked\n * @type Boolean\n * @default\n */\n lockMovementY: false,\n\n /**\n * When `true`, object rotation is locked\n * @type Boolean\n * @default\n */\n lockRotation: false,\n\n /**\n * When `true`, object horizontal scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingX: false,\n\n /**\n * When `true`, object vertical scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingY: false,\n\n /**\n * When `true`, object non-uniform scaling is locked\n * @type Boolean\n * @default\n */\n lockUniScaling: false,\n\n /**\n * When `true`, object horizontal skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingX: false,\n\n /**\n * When `true`, object vertical skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingY: false,\n\n /**\n * When `true`, object cannot be flipped by scaling into negative values\n * @type Boolean\n * @default\n */\n lockScalingFlip: false,\n\n /**\n * When `true`, object is not exported in SVG or OBJECT/JSON\n * since 1.6.3\n * @type Boolean\n * @default\n */\n excludeFromExport: false,\n\n /**\n * When `true`, object is cached on an additional canvas.\n * default to true\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n objectCaching: objectCaching,\n\n /**\n * When `true`, object properties are checked for cache invalidation. In some particular\n * situation you may want this to be disabled ( spray brush, very big pathgroups, groups)\n * or if your application does not allow you to modify properties for groups child you want\n * to disable it for groups.\n * default to false\n * since 1.7.0\n * @type Boolean\n * @default false\n */\n statefullCache: false,\n\n /**\n * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled\n * too much and will be redrawn with correct details at the end of scaling.\n * this setting is performance and application dependant.\n * default to true\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n noScaleCache: true,\n\n /**\n * When set to `true`, object's cache will be rerendered next render call.\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n dirty: true,\n\n /**\n * List of properties to consider when checking if state\n * of an object is changed (fabric.Object#hasStateChanged)\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: (\n 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' +\n 'stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit ' +\n 'angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor ' +\n 'skewX skewY fillRule'\n ).split(' '),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * @type Array\n */\n cacheProperties: (\n 'fill stroke strokeWidth strokeDashArray width height' +\n ' strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor'\n ).split(' '),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n options = options || { };\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Create a the canvas used to keep the cached copy of the object\n * @private\n */\n _createCacheCanvas: function() {\n this._cacheProperties = {};\n this._cacheCanvas = fabric.document.createElement('canvas');\n this._cacheContext = this._cacheCanvas.getContext('2d');\n this._updateCacheCanvas();\n },\n\n /**\n * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal\n * and each side do not cross fabric.cacheSideLimit\n * those numbers are configurable so that you can get as much detail as you want\n * making bargain with performances.\n * @param {Object} dims\n * @param {Object} dims.width width of canvas\n * @param {Object} dims.height height of canvas\n * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _limitCacheSize: function(dims) {\n var perfLimitSizeTotal = fabric.perfLimitSizeTotal,\n width = dims.width, height = dims.height,\n max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit;\n if (width <= max && height <= max && width * height <= perfLimitSizeTotal) {\n if (width < min) {\n dims.width = min;\n }\n if (height < min) {\n dims.height = min;\n }\n return dims;\n }\n var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal),\n capValue = fabric.util.capValue,\n x = capValue(min, limitedDims.x, max),\n y = capValue(min, limitedDims.y, max);\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\n return dims;\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function() {\n var zoom = this.canvas && this.canvas.getZoom() || 1,\n objectScale = this.getObjectScaling(),\n retina = this.canvas && this.canvas._isRetinaScaling() ? fabric.devicePixelRatio : 1,\n dim = this._getNonTransformedDimensions(),\n zoomX = objectScale.scaleX * zoom * retina,\n zoomY = objectScale.scaleY * zoom * retina,\n width = dim.x * zoomX,\n height = dim.y * zoomY;\n return {\n width: width + ALIASING_LIMIT,\n height: height + ALIASING_LIMIT,\n zoomX: zoomX,\n zoomY: zoomY,\n x: dim.x,\n y: dim.y\n };\n },\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas: function() {\n if (this.noScaleCache && this.canvas && this.canvas._currentTransform) {\n var target = this.canvas._currentTransform.target,\n action = this.canvas._currentTransform.action;\n if (this === target && action.slice && action.slice(0, 5) === 'scale') {\n return false;\n }\n }\n var canvas = this._cacheCanvas,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = fabric.minCacheSideLimit,\n width = dims.width, height = dims.height, drawingWidth, drawingHeight,\n zoomX = dims.zoomX, zoomY = dims.zoomY,\n dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,\n zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,\n shouldRedraw = dimensionsChanged || zoomChanged,\n additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false;\n if (dimensionsChanged) {\n var canvasWidth = this._cacheCanvas.width,\n canvasHeight = this._cacheCanvas.height,\n sizeGrowing = width > canvasWidth || height > canvasHeight,\n sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n canvasWidth > minCacheSize && canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n }\n else {\n this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);\n this._cacheContext.clearRect(0, 0, canvas.width, canvas.height);\n }\n drawingWidth = dims.x * zoomX / 2;\n drawingHeight = dims.y * zoomY / 2;\n this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n this.cacheWidth = width;\n this.cacheHeight = height;\n this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY);\n this._cacheContext.scale(zoomX, zoomY);\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n return false;\n },\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function(options) {\n this._setOptions(options);\n this._initGradient(options.fill, 'fill');\n this._initGradient(options.stroke, 'stroke');\n this._initClipping(options);\n this._initPattern(options.fill, 'fill');\n this._initPattern(options.stroke, 'stroke');\n },\n\n /**\n * Transforms context when rendering an object\n * @param {CanvasRenderingContext2D} ctx Context\n * @param {Boolean} fromLeft When true, context is transformed to object's top/left corner. This is used when rendering text on Node\n */\n transform: function(ctx, fromLeft) {\n if (this.group && !this.group._transformDone && this.group === this.canvas._activeGroup) {\n this.group.transform(ctx);\n }\n var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint();\n ctx.translate(center.x, center.y);\n this.angle && ctx.rotate(degreesToRadians(this.angle));\n ctx.scale(\n this.scaleX * (this.flipX ? -1 : 1),\n this.scaleY * (this.flipY ? -1 : 1)\n );\n this.skewX && ctx.transform(1, 0, Math.tan(degreesToRadians(this.skewX)), 1, 0, 0);\n this.skewY && ctx.transform(1, Math.tan(degreesToRadians(this.skewY)), 0, 1, 0, 0);\n },\n\n /**\n * Returns an object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n\n object = {\n type: this.type,\n originX: this.originX,\n originY: this.originY,\n left: toFixed(this.left, NUM_FRACTION_DIGITS),\n top: toFixed(this.top, NUM_FRACTION_DIGITS),\n width: toFixed(this.width, NUM_FRACTION_DIGITS),\n height: toFixed(this.height, NUM_FRACTION_DIGITS),\n fill: (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill,\n stroke: (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke,\n strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),\n strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,\n strokeLineCap: this.strokeLineCap,\n strokeLineJoin: this.strokeLineJoin,\n strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),\n scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS),\n scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS),\n angle: toFixed(this.getAngle(), NUM_FRACTION_DIGITS),\n flipX: this.flipX,\n flipY: this.flipY,\n opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS),\n shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow,\n visible: this.visible,\n clipTo: this.clipTo && String(this.clipTo),\n backgroundColor: this.backgroundColor,\n fillRule: this.fillRule,\n globalCompositeOperation: this.globalCompositeOperation,\n transformMatrix: this.transformMatrix ? this.transformMatrix.concat() : null,\n skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS),\n skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS)\n };\n\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n if (!this.includeDefaultValues) {\n object = this._removeDefaultValues(object);\n }\n\n return object;\n },\n\n /**\n * Returns (dataless) object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n // will be overwritten by subclasses\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * @private\n * @param {Object} object\n */\n _removeDefaultValues: function(object) {\n var prototype = fabric.util.getKlass(object.type).prototype,\n stateProperties = prototype.stateProperties;\n stateProperties.forEach(function(prop) {\n if (object[prop] === prototype[prop]) {\n delete object[prop];\n }\n var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' &&\n Object.prototype.toString.call(prototype[prop]) === '[object Array]';\n\n // basically a check for [] === []\n if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {\n delete object[prop];\n }\n });\n\n return object;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Return the object scale factor counting also the group scaling\n * @return {Object} object with scaleX and scaleY properties\n */\n getObjectScaling: function() {\n var scaleX = this.scaleX, scaleY = this.scaleY;\n if (this.group) {\n var scaling = this.group.getObjectScaling();\n scaleX *= scaling.scaleX;\n scaleY *= scaling.scaleY;\n }\n return { scaleX: scaleX, scaleY: scaleY };\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Object} thisArg\n */\n _set: function(key, value) {\n var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'),\n isChanged = this[key] !== value;\n\n if (shouldConstrainValue) {\n value = this._constrainScale(value);\n }\n if (key === 'scaleX' && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n }\n else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n }\n else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) {\n value = new fabric.Shadow(value);\n }\n else if (key === 'dirty' && this.group) {\n this.group.set('dirty', value);\n }\n\n this[key] = value;\n\n if (isChanged && this.cacheProperties.indexOf(key) > -1) {\n if (this.group) {\n this.group.set('dirty', true);\n }\n this.dirty = true;\n }\n\n if (isChanged && this.group && this.stateProperties.indexOf(key) > -1) {\n this.group.set('dirty', true);\n }\n\n if (key === 'width' || key === 'height') {\n this.minScaleLimit = Math.min(0.1, 1 / Math.max(this.width, this.height));\n }\n\n return this;\n },\n\n /**\n * This callback function is called by the parent group of an object every\n * time a non-delegated property changes on the group. It is passed the key\n * and value as parameters. Not adding in this function's signature to avoid\n * Travis build error about unused variables.\n */\n setOnGroup: function() {\n // implemented by sub-classes, as needed.\n },\n\n /**\n * Sets sourcePath of an object\n * @param {String} value Value to set sourcePath to\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setSourcePath: function(value) {\n this.sourcePath = value;\n return this;\n },\n\n /**\n * Retrieves viewportTransform from Object's canvas if possible\n * @method getViewportTransform\n * @memberOf fabric.Object.prototype\n * @return {Boolean}\n */\n getViewportTransform: function() {\n if (this.canvas && this.canvas.viewportTransform) {\n return this.canvas.viewportTransform;\n }\n return fabric.iMatrix.concat();\n },\n\n /*\n * @private\n * return if the object would be visible in rendering\n * @memberOf fabric.Object.prototype\n * @return {Boolean}\n */\n isNotVisible: function() {\n return this.opacity === 0 || (this.width === 0 && this.height === 0) || !this.visible;\n },\n\n /**\n * Renders an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n render: function(ctx, noTransform) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n ctx.save();\n //setup fill rule for current object\n this._setupCompositeOperation(ctx);\n this.drawSelectionBackground(ctx);\n if (!noTransform) {\n this.transform(ctx);\n }\n this._setOpacity(ctx);\n this._setShadow(ctx);\n if (this.transformMatrix) {\n ctx.transform.apply(ctx, this.transformMatrix);\n }\n this.clipTo && fabric.util.clipContext(this, ctx);\n if (this.shouldCache(noTransform)) {\n if (!this._cacheCanvas) {\n this._createCacheCanvas();\n }\n if (this.isCacheDirty(noTransform)) {\n this.statefullCache && this.saveState({ propertySet: 'cacheProperties' });\n this.drawObject(this._cacheContext, noTransform);\n this.dirty = false;\n }\n this.drawCacheOnCanvas(ctx);\n }\n else {\n this._removeCacheCanvas();\n this.dirty = false;\n this.drawObject(ctx, noTransform);\n if (noTransform && this.objectCaching && this.statefullCache) {\n this.saveState({ propertySet: 'cacheProperties' });\n }\n }\n this.clipTo && ctx.restore();\n ctx.restore();\n },\n\n /**\n * Remove cacheCanvas and its dimensions from the objects\n */\n _removeCacheCanvas: function() {\n this._cacheCanvas = null;\n this.cacheWidth = 0;\n this.cacheHeight = 0;\n },\n\n /**\n * When set to `true`, force the object to have its own cache, even if it is inside a group\n * it may be needed when your object behave in a particular way on the cache and always needs\n * its own isolated canvas to render correctly.\n * This function is created to be subclassed by custom classes.\n * since 1.7.12\n * @type function\n * @return false\n */\n needsItsOwnCache: function() {\n return false;\n },\n\n /**\n * Decide if the object should cache or not.\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @param {Boolean} noTransform if rendereing in pathGroup, caching is not supported at object level\n * @return {Boolean}\n */\n shouldCache: function(noTransform) {\n return !noTransform && this.objectCaching &&\n (!this.group || this.needsItsOwnCache() || !this.group.isCaching());\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * used by Group.shouldCache to know if child has a shadow recursively\n * @return {Boolean}\n */\n willDrawShadow: function() {\n return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0);\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n drawObject: function(ctx, noTransform) {\n this._renderBackground(ctx);\n this._setStrokeStyles(ctx);\n this._setFillStyles(ctx);\n this._render(ctx, noTransform);\n },\n\n /**\n * Paint the cached copy of the object on the target context.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas: function(ctx) {\n ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY);\n },\n\n /**\n * Check if cache is dirty\n * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n * on parent canvas.\n */\n isCacheDirty: function(skipCanvas) {\n if (this.isNotVisible()) {\n return false;\n }\n if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n }\n else {\n if (this.dirty || (this.statefullCache && this.hasStateChanged('cacheProperties'))) {\n if (this._cacheCanvas && !skipCanvas) {\n var width = this.cacheWidth / this.zoomX;\n var height = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-width / 2, -height / 2, width, height);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Draws a background for the object big as its untrasformed dimensions\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground: function(ctx) {\n if (!this.backgroundColor) {\n return;\n }\n var dim = this._getNonTransformedDimensions();\n ctx.fillStyle = this.backgroundColor;\n\n ctx.fillRect(\n -dim.x / 2,\n -dim.y / 2,\n dim.x,\n dim.y\n );\n // if there is background color no other shadows\n // should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity: function(ctx) {\n ctx.globalAlpha *= this.opacity;\n },\n\n _setStrokeStyles: function(ctx) {\n if (this.stroke) {\n ctx.lineWidth = this.strokeWidth;\n ctx.lineCap = this.strokeLineCap;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.miterLimit = this.strokeMiterLimit;\n ctx.strokeStyle = this.stroke.toLive\n ? this.stroke.toLive(ctx, this)\n : this.stroke;\n }\n },\n\n _setFillStyles: function(ctx) {\n if (this.fill) {\n ctx.fillStyle = this.fill.toLive\n ? this.fill.toLive(ctx, this)\n : this.fill;\n }\n },\n\n /**\n * @private\n * Sets line dash\n * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n * @param {Array} dashArray array representing dashes\n * @param {Function} alternative function to call if browaser does not support lineDash\n */\n _setLineDash: function(ctx, dashArray, alternative) {\n if (!dashArray) {\n return;\n }\n // Spec requires the concatenation of two copies the dash list when the number of elements is odd\n if (1 & dashArray.length) {\n dashArray.push.apply(dashArray, dashArray);\n }\n if (supportsLineDash) {\n ctx.setLineDash(dashArray);\n }\n else {\n alternative && alternative(ctx);\n }\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderControls: function(ctx) {\n if (!this.active || (this.group && this.group !== this.canvas.getActiveGroup())) {\n return;\n }\n\n var vpt = this.getViewportTransform(),\n matrix = this.calcTransformMatrix(),\n options;\n matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);\n options = fabric.util.qrDecompose(matrix);\n\n ctx.save();\n ctx.translate(options.translateX, options.translateY);\n ctx.lineWidth = 1 * this.borderScaleFactor;\n if (!this.group) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n if (this.group && this.group === this.canvas.getActiveGroup()) {\n ctx.rotate(degreesToRadians(options.angle));\n this.drawBordersInGroup(ctx, options);\n }\n else {\n ctx.rotate(degreesToRadians(this.angle));\n this.drawBorders(ctx);\n }\n this.drawControls(ctx);\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setShadow: function(ctx) {\n if (!this.shadow) {\n return;\n }\n\n var multX = (this.canvas && this.canvas.viewportTransform[0]) || 1,\n multY = (this.canvas && this.canvas.viewportTransform[3]) || 1,\n scaling = this.getObjectScaling();\n if (this.canvas && this.canvas._isRetinaScaling()) {\n multX *= fabric.devicePixelRatio;\n multY *= fabric.devicePixelRatio;\n }\n ctx.shadowColor = this.shadow.color;\n ctx.shadowBlur = this.shadow.blur * (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;\n ctx.shadowOffsetX = this.shadow.offsetX * multX * scaling.scaleX;\n ctx.shadowOffsetY = this.shadow.offsetY * multY * scaling.scaleY;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _removeShadow: function(ctx) {\n if (!this.shadow) {\n return;\n }\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} filler fabric.Pattern or fabric.Gradient\n */\n _applyPatternGradientTransform: function(ctx, filler) {\n if (!filler.toLive) {\n return;\n }\n var transform = filler.gradientTransform || filler.patternTransform;\n if (transform) {\n ctx.transform.apply(ctx, transform);\n }\n var offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n ctx.translate(offsetX, offsetY);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill: function(ctx) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n this._applyPatternGradientTransform(ctx, this.fill);\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n }\n else {\n ctx.fill();\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke: function(ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);\n this._applyPatternGradientTransform(ctx, this.stroke);\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * Clones an instance, some objects are async, so using callback method will work for every object.\n * Using the direct return does not work for images and groups.\n * @param {Function} callback Callback is invoked with a clone as a first argument\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {fabric.Object} clone of an instance\n */\n clone: function(callback, propertiesToInclude) {\n if (this.constructor.fromObject) {\n return this.constructor.fromObject(this.toObject(propertiesToInclude), callback);\n }\n return new fabric.Object(this.toObject(propertiesToInclude));\n },\n\n /**\n * Creates an instance of fabric.Image out of an object\n * @param {Function} callback callback, invoked with an instance as a first argument\n * @param {Object} [options] for clone as image, passed to toDataURL\n * @param {Boolean} [options.enableRetinaScaling] enable retina scaling for the cloned image\n * @return {fabric.Object} thisArg\n */\n cloneAsImage: function(callback, options) {\n var dataUrl = this.toDataURL(options);\n fabric.util.loadImage(dataUrl, function(img) {\n if (callback) {\n callback(new fabric.Image(img));\n }\n });\n return this;\n },\n\n /**\n * Converts an object into a data-url-like string\n * @param {Object} options Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetina] Enable retina scaling for clone image. Introduce in 1.6.4\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n */\n toDataURL: function(options) {\n options || (options = { });\n\n var el = fabric.util.createCanvasElement(),\n boundingRect = this.getBoundingRect();\n\n el.width = boundingRect.width;\n el.height = boundingRect.height;\n fabric.util.wrapElement(el, 'div');\n var canvas = new fabric.StaticCanvas(el, { enableRetinaScaling: options.enableRetinaScaling });\n // to avoid common confusion https://github.com/kangax/fabric.js/issues/806\n if (options.format === 'jpg') {\n options.format = 'jpeg';\n }\n\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n\n var origParams = {\n active: this.get('active'),\n left: this.getLeft(),\n top: this.getTop()\n };\n\n this.set('active', false);\n this.setPositionByOrigin(new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2), 'center', 'center');\n\n var originalCanvas = this.canvas;\n canvas.add(this);\n var data = canvas.toDataURL(options);\n\n this.set(origParams).setCoords();\n this.canvas = originalCanvas;\n\n canvas.dispose();\n canvas = null;\n\n return data;\n },\n\n /**\n * Returns true if specified type is identical to the type of an instance\n * @param {String} type Type to check against\n * @return {Boolean}\n */\n isType: function(type) {\n return this.type === type;\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance (is 1 unless subclassed)\n */\n complexity: function() {\n return 1;\n },\n\n /**\n * Returns a JSON representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} JSON\n */\n toJSON: function(propertiesToInclude) {\n // delegate, not alias\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * Sets gradient (fill or stroke) of an object\n * Backwards incompatibility note: This method was named \"setGradientFill\" until v1.1.0\n * @param {String} property Property name 'stroke' or 'fill'\n * @param {Object} [options] Options object\n * @param {String} [options.type] Type of gradient 'radial' or 'linear'\n * @param {Number} [options.x1=0] x-coordinate of start point\n * @param {Number} [options.y1=0] y-coordinate of start point\n * @param {Number} [options.x2=0] x-coordinate of end point\n * @param {Number} [options.y2=0] y-coordinate of end point\n * @param {Number} [options.r1=0] Radius of start point (only for radial gradients)\n * @param {Number} [options.r2=0] Radius of end point (only for radial gradients)\n * @param {Object} [options.colorStops] Color stops object eg. {0: 'ff0000', 1: '000000'}\n * @param {Object} [options.gradientTransform] transforMatrix for gradient\n * @return {fabric.Object} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/58y8b/|jsFiddle demo}\n * @example Set linear gradient\n * object.setGradient('fill', {\n * type: 'linear',\n * x1: -object.width / 2,\n * y1: 0,\n * x2: object.width / 2,\n * y2: 0,\n * colorStops: {\n * 0: 'red',\n * 0.5: '#005555',\n * 1: 'rgba(0,0,255,0.5)'\n * }\n * });\n * canvas.renderAll();\n * @example Set radial gradient\n * object.setGradient('fill', {\n * type: 'radial',\n * x1: 0,\n * y1: 0,\n * x2: 0,\n * y2: 0,\n * r1: object.width / 2,\n * r2: 10,\n * colorStops: {\n * 0: 'red',\n * 0.5: '#005555',\n * 1: 'rgba(0,0,255,0.5)'\n * }\n * });\n * canvas.renderAll();\n */\n setGradient: function(property, options) {\n options || (options = { });\n\n var gradient = { colorStops: [] };\n\n gradient.type = options.type || (options.r1 || options.r2 ? 'radial' : 'linear');\n gradient.coords = {\n x1: options.x1,\n y1: options.y1,\n x2: options.x2,\n y2: options.y2\n };\n\n if (options.r1 || options.r2) {\n gradient.coords.r1 = options.r1;\n gradient.coords.r2 = options.r2;\n }\n\n gradient.gradientTransform = options.gradientTransform;\n fabric.Gradient.prototype.addColorStop.call(gradient, options.colorStops);\n\n return this.set(property, fabric.Gradient.forObject(this, gradient));\n },\n\n /**\n * Sets pattern fill of an object\n * @param {Object} options Options object\n * @param {(String|HTMLImageElement)} options.source Pattern source\n * @param {String} [options.repeat=repeat] Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n * @param {Number} [options.offsetX=0] Pattern horizontal offset from object's left/top corner\n * @param {Number} [options.offsetY=0] Pattern vertical offset from object's left/top corner\n * @return {fabric.Object} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/QT3pa/|jsFiddle demo}\n * @example Set pattern\n * fabric.util.loadImage('http://fabricjs.com/assets/escheresque_ste.png', function(img) {\n * object.setPatternFill({\n * source: img,\n * repeat: 'repeat'\n * });\n * canvas.renderAll();\n * });\n */\n setPatternFill: function(options) {\n return this.set('fill', new fabric.Pattern(options));\n },\n\n /**\n * Sets {@link fabric.Object#shadow|shadow} of an object\n * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n * @param {String} [options.color=rgb(0,0,0)] Shadow color\n * @param {Number} [options.blur=0] Shadow blur\n * @param {Number} [options.offsetX=0] Shadow horizontal offset\n * @param {Number} [options.offsetY=0] Shadow vertical offset\n * @return {fabric.Object} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/7gvJG/|jsFiddle demo}\n * @example Set shadow with string notation\n * object.setShadow('2px 2px 10px rgba(0,0,0,0.2)');\n * canvas.renderAll();\n * @example Set shadow with object notation\n * object.setShadow({\n * color: 'red',\n * blur: 10,\n * offsetX: 20,\n * offsetY: 20\n * });\n * canvas.renderAll();\n */\n setShadow: function(options) {\n return this.set('shadow', options ? new fabric.Shadow(options) : null);\n },\n\n /**\n * Sets \"color\" of an instance (alias of `set('fill', …)`)\n * @param {String} color Color value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setColor: function(color) {\n this.set('fill', color);\n return this;\n },\n\n /**\n * Sets \"angle\" of an instance\n * @param {Number} angle Angle value (in degrees)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setAngle: function(angle) {\n var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation;\n\n if (shouldCenterOrigin) {\n this._setOriginToCenter();\n }\n\n this.set('angle', angle);\n\n if (shouldCenterOrigin) {\n this._resetOrigin();\n }\n\n return this;\n },\n\n /**\n * Centers object horizontally on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerH: function () {\n this.canvas && this.canvas.centerObjectH(this);\n return this;\n },\n\n /**\n * Centers object horizontally on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterH: function () {\n this.canvas && this.canvas.viewportCenterObjectH(this);\n return this;\n },\n\n /**\n * Centers object vertically on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerV: function () {\n this.canvas && this.canvas.centerObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterV: function () {\n this.canvas && this.canvas.viewportCenterObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically and horizontally on canvas to which is was added last\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n center: function () {\n this.canvas && this.canvas.centerObject(this);\n return this;\n },\n\n /**\n * Centers object on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenter: function () {\n this.canvas && this.canvas.viewportCenterObject(this);\n return this;\n },\n\n /**\n * Removes object from canvas to which it was added last\n * @return {fabric.Object} thisArg\n * @chainable\n */\n remove: function() {\n if (this.canvas) {\n if (this.group && this.group === this.canvas._activeGroup) {\n this.group.remove(this);\n }\n this.canvas.remove(this);\n }\n return this;\n },\n\n /**\n * Returns coordinates of a pointer relative to an object\n * @param {Event} e Event to operate upon\n * @param {Object} [pointer] Pointer to operate upon (instead of event)\n * @return {Object} Coordinates of a pointer (x, y)\n */\n getLocalPointer: function(e, pointer) {\n pointer = pointer || this.canvas.getPointer(e);\n var pClicked = new fabric.Point(pointer.x, pointer.y),\n objectLeftTop = this._getLeftTopCoords();\n if (this.angle) {\n pClicked = fabric.util.rotatePoint(\n pClicked, objectLeftTop, degreesToRadians(-this.angle));\n }\n return {\n x: pClicked.x - objectLeftTop.x,\n y: pClicked.y - objectLeftTop.y\n };\n },\n\n /**\n * Sets canvas globalCompositeOperation for specific object\n * custom composition operation for the particular object can be specifed using globalCompositeOperation property\n * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n */\n _setupCompositeOperation: function (ctx) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n });\n\n fabric.util.createAccessors(fabric.Object);\n\n /**\n * Alias for {@link fabric.Object.prototype.setAngle}\n * @alias rotate -> setAngle\n * @memberOf fabric.Object\n */\n fabric.Object.prototype.rotate = fabric.Object.prototype.setAngle;\n\n extend(fabric.Object.prototype, fabric.Observable);\n\n /**\n * Defines the number of fraction digits to use when serializing object values.\n * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n * @static\n * @memberOf fabric.Object\n * @constant\n * @type Number\n */\n fabric.Object.NUM_FRACTION_DIGITS = 2;\n\n fabric.Object._fromObject = function(className, object, callback, forceAsync, extraParam) {\n var klass = fabric[className];\n object = clone(object, true);\n if (forceAsync) {\n fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) {\n if (typeof patterns[0] !== 'undefined') {\n object.fill = patterns[0];\n }\n if (typeof patterns[1] !== 'undefined') {\n object.stroke = patterns[1];\n }\n var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);\n callback && callback(instance);\n });\n }\n else {\n var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);\n callback && callback(instance);\n return instance;\n }\n };\n\n /**\n * Unique id used internally when creating SVG elements\n * @static\n * @memberOf fabric.Object\n * @type Number\n */\n fabric.Object.__uid = 0;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var degreesToRadians = fabric.util.degreesToRadians,\n originXOffset = {\n left: -0.5,\n center: 0,\n right: 0.5\n },\n originYOffset = {\n top: -0.5,\n center: 0,\n bottom: 0.5\n };\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) {\n var x = point.x,\n y = point.y,\n offsetX, offsetY, dim;\n\n if (typeof fromOriginX === 'string') {\n fromOriginX = originXOffset[fromOriginX];\n }\n else {\n fromOriginX -= 0.5;\n }\n\n if (typeof toOriginX === 'string') {\n toOriginX = originXOffset[toOriginX];\n }\n else {\n toOriginX -= 0.5;\n }\n\n offsetX = toOriginX - fromOriginX;\n\n if (typeof fromOriginY === 'string') {\n fromOriginY = originYOffset[fromOriginY];\n }\n else {\n fromOriginY -= 0.5;\n }\n\n if (typeof toOriginY === 'string') {\n toOriginY = originYOffset[toOriginY];\n }\n else {\n toOriginY -= 0.5;\n }\n\n offsetY = toOriginY - fromOriginY;\n\n if (offsetX || offsetY) {\n dim = this._getTransformedDimensions();\n x = point.x + offsetX * dim.x;\n y = point.y + offsetY * dim.y;\n }\n\n return new fabric.Point(x, y);\n },\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToCenterPoint: function(point, originX, originY) {\n var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center');\n if (this.angle) {\n return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));\n }\n return p;\n },\n\n /**\n * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n * @param {fabric.Point} center The point which corresponds to center of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToOriginPoint: function(center, originX, originY) {\n var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n if (this.angle) {\n return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));\n }\n return p;\n },\n\n /**\n * Returns the real center coordinates of the object\n * @return {fabric.Point}\n */\n getCenterPoint: function() {\n var leftTop = new fabric.Point(this.left, this.top);\n return this.translateToCenterPoint(leftTop, this.originX, this.originY);\n },\n\n /**\n * Returns the coordinates of the object based on center coordinates\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @return {fabric.Point}\n */\n // getOriginPoint: function(center) {\n // return this.translateToOriginPoint(center, this.originX, this.originY);\n // },\n\n /**\n * Returns the coordinates of the object as if it has a different origin\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n getPointByOrigin: function(originX, originY) {\n var center = this.getCenterPoint();\n return this.translateToOriginPoint(center, originX, originY);\n },\n\n /**\n * Returns the point in local coordinates\n * @param {fabric.Point} point The point relative to the global coordinate system\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n toLocalPoint: function(point, originX, originY) {\n var center = this.getCenterPoint(),\n p, p2;\n\n if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) {\n p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n }\n else {\n p = new fabric.Point(this.left, this.top);\n }\n\n p2 = new fabric.Point(point.x, point.y);\n if (this.angle) {\n p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));\n }\n return p2.subtractEquals(p);\n },\n\n /**\n * Returns the point in global coordinates\n * @param {fabric.Point} The point relative to the local coordinate system\n * @return {fabric.Point}\n */\n // toGlobalPoint: function(point) {\n // return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top));\n // },\n\n /**\n * Sets the position of the object taking into consideration the object's origin\n * @param {fabric.Point} pos The new position of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {void}\n */\n setPositionByOrigin: function(pos, originX, originY) {\n var center = this.translateToCenterPoint(pos, originX, originY),\n position = this.translateToOriginPoint(center, this.originX, this.originY);\n\n this.set('left', position.x);\n this.set('top', position.y);\n },\n\n /**\n * @param {String} to One of 'left', 'center', 'right'\n */\n adjustPosition: function(to) {\n var angle = degreesToRadians(this.angle),\n hypotFull = this.getWidth(),\n xFull = Math.cos(angle) * hypotFull,\n yFull = Math.sin(angle) * hypotFull,\n offsetFrom, offsetTo;\n\n //TODO: this function does not consider mixed situation like top, center.\n if (typeof this.originX === 'string') {\n offsetFrom = originXOffset[this.originX];\n }\n else {\n offsetFrom = this.originX - 0.5;\n }\n if (typeof to === 'string') {\n offsetTo = originXOffset[to];\n }\n else {\n offsetTo = to - 0.5;\n }\n this.left += xFull * (offsetTo - offsetFrom);\n this.top += yFull * (offsetTo - offsetFrom);\n this.setCoords();\n this.originX = to;\n },\n\n /**\n * Sets the origin/position of the object to it's center point\n * @private\n * @return {void}\n */\n _setOriginToCenter: function() {\n this._originalOriginX = this.originX;\n this._originalOriginY = this.originY;\n\n var center = this.getCenterPoint();\n\n this.originX = 'center';\n this.originY = 'center';\n\n this.left = center.x;\n this.top = center.y;\n },\n\n /**\n * Resets the origin/position of the object to it's original origin\n * @private\n * @return {void}\n */\n _resetOrigin: function() {\n var originPoint = this.translateToOriginPoint(\n this.getCenterPoint(),\n this._originalOriginX,\n this._originalOriginY);\n\n this.originX = this._originalOriginX;\n this.originY = this._originalOriginY;\n\n this.left = originPoint.x;\n this.top = originPoint.y;\n\n this._originalOriginX = null;\n this._originalOriginY = null;\n },\n\n /**\n * @private\n */\n _getLeftTopCoords: function() {\n return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');\n },\n\n /**\n * Callback; invoked right before object is about to go from active to inactive\n */\n onDeselect: function() {\n /* NOOP */\n }\n });\n\n})();\n\n\n(function() {\n\n function getCoords(coords) {\n return [\n new fabric.Point(coords.tl.x, coords.tl.y),\n new fabric.Point(coords.tr.x, coords.tr.y),\n new fabric.Point(coords.br.x, coords.br.y),\n new fabric.Point(coords.bl.x, coords.bl.y)\n ];\n }\n\n var degreesToRadians = fabric.util.degreesToRadians,\n multiplyMatrices = fabric.util.multiplyTransformMatrices;\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Describe object's corner position in canvas element coordinates.\n * properties are tl,mt,tr,ml,mr,bl,mb,br,mtr for the main controls.\n * each property is an object with x, y and corner.\n * The `corner` property contains in a similar manner the 4 points of the\n * interactive area of the corner.\n * The coordinates depends from this properties: width, height, scaleX, scaleY\n * skewX, skewY, angle, strokeWidth, viewportTransform, top, left, padding.\n * The coordinates get updated with @method setCoords.\n * You can calculate them without updating with @method calcCoords;\n * @memberOf fabric.Object.prototype\n */\n oCoords: null,\n\n /**\n * Describe object's corner position in canvas object absolute coordinates\n * properties are tl,tr,bl,br and describe the four main corner.\n * each property is an object with x, y, instance of Fabric.Point.\n * The coordinates depends from this properties: width, height, scaleX, scaleY\n * skewX, skewY, angle, strokeWidth, top, left.\n * Those coordinates are usefull to understand where an object is. They get updated\n * with oCoords but they do not need to be updated when zoom or panning change.\n * The coordinates get updated with @method setCoords.\n * You can calculate them without updating with @method calcCoords(true);\n * @memberOf fabric.Object.prototype\n */\n aCoords: null,\n\n /**\n * return correct set of coordinates for intersection\n */\n getCoords: function(absolute, calculate) {\n if (!this.oCoords) {\n this.setCoords();\n }\n var coords = absolute ? this.aCoords : this.oCoords;\n return getCoords(calculate ? this.calcCoords(absolute) : coords);\n },\n\n /**\n * Checks if object intersects with an area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with an area formed by 2 points\n */\n intersectsWithRect: function(pointTL, pointBR, absolute, calculate) {\n var coords = this.getCoords(absolute, calculate),\n intersection = fabric.Intersection.intersectPolygonRectangle(\n coords,\n pointTL,\n pointBR\n );\n return intersection.status === 'Intersection';\n },\n\n /**\n * Checks if object intersects with another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with another object\n */\n intersectsWithObject: function(other, absolute, calculate) {\n var intersection = fabric.Intersection.intersectPolygonPolygon(\n this.getCoords(absolute, calculate),\n other.getCoords(absolute, calculate)\n );\n\n return intersection.status === 'Intersection'\n || other.isContainedWithinObject(this, absolute, calculate)\n || this.isContainedWithinObject(other, absolute, calculate);\n },\n\n /**\n * Checks if object is fully contained within area of another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area of another object\n */\n isContainedWithinObject: function(other, absolute, calculate) {\n var points = this.getCoords(absolute, calculate),\n i = 0, lines = other._getImageLines(\n calculate ? other.calcCoords(absolute) : absolute ? other.aCoords : other.oCoords\n );\n for (; i < 4; i++) {\n if (!other.containsPoint(points[i], lines)) {\n return false;\n }\n }\n return true;\n },\n\n /**\n * Checks if object is fully contained within area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area formed by 2 points\n */\n isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) {\n var boundingRect = this.getBoundingRect(absolute, calculate);\n\n return (\n boundingRect.left >= pointTL.x &&\n boundingRect.left + boundingRect.width <= pointBR.x &&\n boundingRect.top >= pointTL.y &&\n boundingRect.top + boundingRect.height <= pointBR.y\n );\n },\n\n /**\n * Checks if point is inside the object\n * @param {fabric.Point} point Point to check against\n * @param {Object} [lines] object returned from @method _getImageLines\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if point is inside the object\n */\n containsPoint: function(point, lines, absolute, calculate) {\n var lines = lines || this._getImageLines(\n calculate ? this.calcCoords(absolute) : absolute ? this.aCoords : this.oCoords\n ),\n xPoints = this._findCrossPoints(point, lines);\n\n // if xPoints is odd then point is inside the object\n return (xPoints !== 0 && xPoints % 2 === 1);\n },\n\n /**\n * Checks if object is contained within the canvas with current viewportTransform\n * the check is done stopping at first point that appear on screen\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within canvas\n */\n isOnScreen: function(calculate) {\n if (!this.canvas) {\n return false;\n }\n var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n var points = this.getCoords(true, calculate), point;\n for (var i = 0; i < 4; i++) {\n point = points[i];\n if (point.x <= pointBR.x && point.x >= pointTL.x && point.y <= pointBR.y && point.y >= pointTL.y) {\n return true;\n }\n }\n // no points on screen, check intersection with absolute coordinates\n if (this.intersectsWithRect(pointTL, pointBR, true)) {\n return true;\n }\n // worst case scenario the object is so big that contanins the screen\n var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 };\n if (this.containsPoint(centerPoint, null, true)) {\n return true;\n }\n return false;\n },\n\n /**\n * Method that returns an object with the object edges in it, given the coordinates of the corners\n * @private\n * @param {Object} oCoords Coordinates of the object corners\n */\n _getImageLines: function(oCoords) {\n return {\n topline: {\n o: oCoords.tl,\n d: oCoords.tr\n },\n rightline: {\n o: oCoords.tr,\n d: oCoords.br\n },\n bottomline: {\n o: oCoords.br,\n d: oCoords.bl\n },\n leftline: {\n o: oCoords.bl,\n d: oCoords.tl\n }\n };\n },\n\n /**\n * Helper method to determine how many cross points are between the 4 object edges\n * and the horizontal line determined by a point on canvas\n * @private\n * @param {fabric.Point} point Point to check\n * @param {Object} lines Coordinates of the object being evaluated\n */\n // remove yi, not used but left code here just in case.\n _findCrossPoints: function(point, lines) {\n var b1, b2, a1, a2, xi, // yi,\n xcount = 0,\n iLine;\n\n for (var lineKey in lines) {\n iLine = lines[lineKey];\n // optimisation 1: line below point. no cross\n if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) {\n continue;\n }\n // optimisation 2: line above point. no cross\n if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) {\n continue;\n }\n // optimisation 3: vertical line case\n if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) {\n xi = iLine.o.x;\n // yi = point.y;\n }\n // calculate the intersection point\n else {\n b1 = 0;\n b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);\n a1 = point.y - b1 * point.x;\n a2 = iLine.o.y - b2 * iLine.o.x;\n\n xi = -(a1 - a2) / (b1 - b2);\n // yi = a1 + b1 * xi;\n }\n // dont count xi < point.x cases\n if (xi >= point.x) {\n xcount += 1;\n }\n // optimisation 4: specific for square images\n if (xcount === 2) {\n break;\n }\n }\n return xcount;\n },\n\n /**\n * Returns width of an object's bounding rectangle\n * @deprecated since 1.0.4\n * @return {Number} width value\n */\n getBoundingRectWidth: function() {\n return this.getBoundingRect().width;\n },\n\n /**\n * Returns height of an object's bounding rectangle\n * @deprecated since 1.0.4\n * @return {Number} height value\n */\n getBoundingRectHeight: function() {\n return this.getBoundingRect().height;\n },\n\n /**\n * Returns coordinates of object's bounding rectangle (left, top, width, height)\n * the box is intented as aligned to axis of canvas.\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Object} Object with left, top, width, height properties\n */\n getBoundingRect: function(absolute, calculate) {\n var coords = this.getCoords(absolute, calculate);\n return fabric.util.makeBoundingBoxFromPoints(coords);\n },\n\n /**\n * Returns width of an object bounding box counting transformations\n * @return {Number} width value\n */\n getWidth: function() {\n return this._getTransformedDimensions().x;\n },\n\n /**\n * Returns height of an object bounding box counting transformations\n * to be renamed in 2.0\n * @return {Number} height value\n */\n getHeight: function() {\n return this._getTransformedDimensions().y;\n },\n\n /**\n * Makes sure the scale is valid and modifies it if necessary\n * @private\n * @param {Number} value\n * @return {Number}\n */\n _constrainScale: function(value) {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n }\n else {\n return this.minScaleLimit;\n }\n }\n return value;\n },\n\n /**\n * Scales an object (equally by x and y)\n * @param {Number} value Scale factor\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scale: function(value) {\n value = this._constrainScale(value);\n\n if (value < 0) {\n this.flipX = !this.flipX;\n this.flipY = !this.flipY;\n value *= -1;\n }\n\n this.scaleX = value;\n this.scaleY = value;\n return this.setCoords();\n },\n\n /**\n * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New width value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToWidth: function(value) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect().width / this.getWidth();\n return this.scale(value / this.width / boundingRectFactor);\n },\n\n /**\n * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New height value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToHeight: function(value) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect().height / this.getHeight();\n return this.scale(value / this.height / boundingRectFactor);\n },\n\n /**\n * Calculate and returns the .coords of an object.\n * @return {Object} Object with tl, tr, br, bl ....\n * @chainable\n */\n calcCoords: function(absolute) {\n var theta = degreesToRadians(this.angle),\n vpt = this.getViewportTransform(),\n dim = absolute ? this._getTransformedDimensions() : this._calculateCurrentDimensions(),\n currentWidth = dim.x, currentHeight = dim.y,\n sinTh = Math.sin(theta),\n cosTh = Math.cos(theta),\n _angle = currentWidth > 0 ? Math.atan(currentHeight / currentWidth) : 0,\n _hypotenuse = (currentWidth / Math.cos(_angle)) / 2,\n offsetX = Math.cos(_angle + theta) * _hypotenuse,\n offsetY = Math.sin(_angle + theta) * _hypotenuse,\n center = this.getCenterPoint(),\n // offset added for rotate and scale actions\n coords = absolute ? center : fabric.util.transformPoint(center, vpt),\n tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY),\n tr = new fabric.Point(tl.x + (currentWidth * cosTh), tl.y + (currentWidth * sinTh)),\n bl = new fabric.Point(tl.x - (currentHeight * sinTh), tl.y + (currentHeight * cosTh)),\n br = new fabric.Point(coords.x + offsetX, coords.y + offsetY);\n if (!absolute) {\n var ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2),\n mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2),\n mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2),\n mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2),\n mtr = new fabric.Point(mt.x + sinTh * this.rotatingPointOffset, mt.y - cosTh * this.rotatingPointOffset);\n }\n\n // debugging\n\n /* setTimeout(function() {\n canvas.contextTop.fillStyle = 'green';\n canvas.contextTop.fillRect(mb.x, mb.y, 3, 3);\n canvas.contextTop.fillRect(bl.x, bl.y, 3, 3);\n canvas.contextTop.fillRect(br.x, br.y, 3, 3);\n canvas.contextTop.fillRect(tl.x, tl.y, 3, 3);\n canvas.contextTop.fillRect(tr.x, tr.y, 3, 3);\n canvas.contextTop.fillRect(ml.x, ml.y, 3, 3);\n canvas.contextTop.fillRect(mr.x, mr.y, 3, 3);\n canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);\n canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3);\n }, 50); */\n\n var coords = {\n // corners\n tl: tl, tr: tr, br: br, bl: bl,\n };\n if (!absolute) {\n // middle\n coords.ml = ml;\n coords.mt = mt;\n coords.mr = mr;\n coords.mb = mb;\n // rotating point\n coords.mtr = mtr;\n }\n return coords;\n },\n\n /**\n * Sets corner position coordinates based on current angle, width and height\n * See https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords\n * @param {Boolean} [ignoreZoom] set oCoords with or without the viewport transform.\n * @param {Boolean} [skipAbsolute] skip calculation of aCoords, usefull in setViewportTransform\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setCoords: function(ignoreZoom, skipAbsolute) {\n this.oCoords = this.calcCoords(ignoreZoom);\n if (!skipAbsolute) {\n this.aCoords = this.calcCoords(true);\n }\n\n // set coordinates of the draggable boxes in the corners used to scale/rotate the image\n ignoreZoom || (this._setCornerCoords && this._setCornerCoords());\n\n return this;\n },\n\n /**\n * calculate rotation matrix of an object\n * @return {Array} rotation matrix for the object\n */\n _calcRotateMatrix: function() {\n if (this.angle) {\n var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta);\n // trying to keep rounding error small, ugly but it works.\n if (cos === 6.123233995736766e-17 || cos === -1.8369701987210297e-16) {\n cos = 0;\n }\n return [cos, sin, -sin, cos, 0, 0];\n }\n return fabric.iMatrix.concat();\n },\n\n /**\n * calculate trasform Matrix that represent current transformation from\n * object properties.\n * @param {Boolean} [skipGroup] return transformMatrix for object and not go upward with parents\n * @return {Array} matrix Transform Matrix for the object\n */\n calcTransformMatrix: function(skipGroup) {\n var center = this.getCenterPoint(),\n translateMatrix = [1, 0, 0, 1, center.x, center.y],\n rotateMatrix,\n dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true),\n matrix;\n if (this.group && !skipGroup) {\n matrix = multiplyMatrices(this.group.calcTransformMatrix(), translateMatrix);\n }\n else {\n matrix = translateMatrix;\n }\n if (this.angle) {\n rotateMatrix = this._calcRotateMatrix();\n matrix = multiplyMatrices(matrix, rotateMatrix);\n }\n matrix = multiplyMatrices(matrix, dimensionMatrix);\n return matrix;\n },\n\n _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) {\n var skewMatrix,\n scaleX = this.scaleX * (flipping && this.flipX ? -1 : 1),\n scaleY = this.scaleY * (flipping && this.flipY ? -1 : 1),\n scaleMatrix = [scaleX, 0, 0, scaleY, 0, 0];\n if (skewX) {\n skewMatrix = [1, 0, Math.tan(degreesToRadians(skewX)), 1];\n scaleMatrix = multiplyMatrices(scaleMatrix, skewMatrix, true);\n }\n if (skewY) {\n skewMatrix = [1, Math.tan(degreesToRadians(skewY)), 0, 1];\n scaleMatrix = multiplyMatrices(scaleMatrix, skewMatrix, true);\n }\n return scaleMatrix;\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getNonTransformedDimensions: function() {\n var strokeWidth = this.strokeWidth,\n w = this.width + strokeWidth,\n h = this.height + strokeWidth;\n return { x: w, y: h };\n },\n\n /*\n * Calculate object bounding boxdimensions from its properties scale, skew.\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getTransformedDimensions: function(skewX, skewY) {\n if (typeof skewX === 'undefined') {\n skewX = this.skewX;\n }\n if (typeof skewY === 'undefined') {\n skewY = this.skewY;\n }\n var dimensions = this._getNonTransformedDimensions(),\n dimX = dimensions.x / 2, dimY = dimensions.y / 2,\n points = [\n {\n x: -dimX,\n y: -dimY\n },\n {\n x: dimX,\n y: -dimY\n },\n {\n x: -dimX,\n y: dimY\n },\n {\n x: dimX,\n y: dimY\n }],\n i, transformMatrix = this._calcDimensionsTransformMatrix(skewX, skewY, false),\n bbox;\n for (i = 0; i < points.length; i++) {\n points[i] = fabric.util.transformPoint(points[i], transformMatrix);\n }\n bbox = fabric.util.makeBoundingBoxFromPoints(points);\n return { x: bbox.width, y: bbox.height };\n },\n\n /*\n * Calculate object dimensions for controls. include padding and canvas zoom\n * private\n */\n _calculateCurrentDimensions: function() {\n var vpt = this.getViewportTransform(),\n dim = this._getTransformedDimensions(),\n p = fabric.util.transformPoint(dim, vpt, true);\n\n return p.scalarAdd(2 * this.padding);\n },\n });\n})();\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Moves an object to the bottom of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendToBack: function() {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);\n }\n else {\n this.canvas.sendToBack(this);\n }\n return this;\n },\n\n /**\n * Moves an object to the top of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringToFront: function() {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);\n }\n else {\n this.canvas.bringToFront(this);\n }\n return this;\n },\n\n /**\n * Moves an object down in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendBackwards: function(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);\n }\n else {\n this.canvas.sendBackwards(this, intersecting);\n }\n return this;\n },\n\n /**\n * Moves an object up in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringForward: function(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);\n }\n else {\n this.canvas.bringForward(this, intersecting);\n }\n return this;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {Number} index New position of object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n moveTo: function(index) {\n if (this.group) {\n fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);\n }\n else {\n this.canvas.moveTo(this, index);\n }\n return this;\n }\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n\n function getSvgColorString(prop, value) {\n if (!value) {\n return prop + ': none; ';\n }\n else if (value.toLive) {\n return prop + ': url(#SVGID_' + value.id + '); ';\n }\n else {\n var color = new fabric.Color(value),\n str = prop + ': ' + color.toRgb() + '; ',\n opacity = color.getAlpha();\n if (opacity !== 1) {\n //change the color in rgb + opacity\n str += prop + '-opacity: ' + opacity.toString() + '; ';\n }\n return str;\n }\n }\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles: function(skipShadow) {\n\n var fillRule = this.fillRule,\n strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',\n strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n visibility = this.visible ? '' : ' visibility: hidden;',\n filter = skipShadow ? '' : this.getSvgFilter(),\n fill = getSvgColorString('fill', this.fill),\n stroke = getSvgColorString('stroke', this.stroke);\n\n return [\n stroke,\n 'stroke-width: ', strokeWidth, '; ',\n 'stroke-dasharray: ', strokeDashArray, '; ',\n 'stroke-linecap: ', strokeLineCap, '; ',\n 'stroke-linejoin: ', strokeLineJoin, '; ',\n 'stroke-miterlimit: ', strokeMiterLimit, '; ',\n fill,\n 'fill-rule: ', fillRule, '; ',\n 'opacity: ', opacity, ';',\n filter,\n visibility\n ].join('');\n },\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter: function() {\n return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';\n },\n\n /**\n * Returns id attribute for svg output\n * @return {String}\n */\n getSvgId: function() {\n return this.id ? 'id=\"' + this.id + '\" ' : '';\n },\n\n /**\n * Returns transform-string for svg-export\n * @return {String}\n */\n getSvgTransform: function() {\n if (this.group && this.group.type === 'path-group') {\n return '';\n }\n var toFixed = fabric.util.toFixed,\n angle = this.getAngle(),\n skewX = (this.getSkewX() % 360),\n skewY = (this.getSkewY() % 360),\n center = this.getCenterPoint(),\n\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n\n translatePart = this.type === 'path-group' ? '' : 'translate(' +\n toFixed(center.x, NUM_FRACTION_DIGITS) +\n ' ' +\n toFixed(center.y, NUM_FRACTION_DIGITS) +\n ')',\n\n anglePart = angle !== 0\n ? (' rotate(' + toFixed(angle, NUM_FRACTION_DIGITS) + ')')\n : '',\n\n scalePart = (this.scaleX === 1 && this.scaleY === 1)\n ? '' :\n (' scale(' +\n toFixed(this.scaleX, NUM_FRACTION_DIGITS) +\n ' ' +\n toFixed(this.scaleY, NUM_FRACTION_DIGITS) +\n ')'),\n\n skewXPart = skewX !== 0 ? ' skewX(' + toFixed(skewX, NUM_FRACTION_DIGITS) + ')' : '',\n\n skewYPart = skewY !== 0 ? ' skewY(' + toFixed(skewY, NUM_FRACTION_DIGITS) + ')' : '',\n\n addTranslateX = this.type === 'path-group' ? this.width : 0,\n\n flipXPart = this.flipX ? ' matrix(-1 0 0 1 ' + addTranslateX + ' 0) ' : '',\n\n addTranslateY = this.type === 'path-group' ? this.height : 0,\n\n flipYPart = this.flipY ? ' matrix(1 0 0 -1 0 ' + addTranslateY + ')' : '';\n\n return [\n translatePart, anglePart, scalePart, flipXPart, flipYPart, skewXPart, skewYPart\n ].join('');\n },\n\n /**\n * Returns transform-string for svg-export from the transform matrix of single elements\n * @return {String}\n */\n getSvgTransformMatrix: function() {\n return this.transformMatrix ? ' matrix(' + this.transformMatrix.join(' ') + ') ' : '';\n },\n\n /**\n * @private\n */\n _createBaseSVGMarkup: function() {\n var markup = [];\n\n if (this.fill && this.fill.toLive) {\n markup.push(this.fill.toSVG(this, false));\n }\n if (this.stroke && this.stroke.toLive) {\n markup.push(this.stroke.toSVG(this, false));\n }\n if (this.shadow) {\n markup.push(this.shadow.toSVG(this));\n }\n return markup;\n }\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function() {\n\n var extend = fabric.util.object.extend,\n originalSet = 'stateProperties';\n\n /*\n Depends on `stateProperties`\n */\n function saveProps(origin, destination, props) {\n var tmpObj = { }, deep = true;\n props.forEach(function(prop) {\n tmpObj[prop] = origin[prop];\n });\n extend(origin[destination], tmpObj, deep);\n }\n\n function _isEqual(origValue, currentValue, firstPass) {\n if (origValue === currentValue) {\n // if the objects are identical, return\n return true;\n }\n else if (Array.isArray(origValue)) {\n if (origValue.length !== currentValue.length) {\n return false;\n }\n for (var i = 0, len = origValue.length; i < len; i++) {\n if (!_isEqual(origValue[i], currentValue[i])) {\n return false;\n }\n }\n return true;\n }\n else if (origValue && typeof origValue === 'object') {\n var keys = Object.keys(origValue), key;\n if (!firstPass && keys.length !== Object.keys(currentValue).length) {\n return false;\n }\n for (var i = 0, len = keys.length; i < len; i++) {\n key = keys[i];\n if (!_isEqual(origValue[key], currentValue[key])) {\n return false;\n }\n }\n return true;\n }\n }\n\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Returns true if object state (one of its state properties) was changed\n * @param {String} [propertySet] optional name for the set of property we want to save\n * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called\n */\n hasStateChanged: function(propertySet) {\n propertySet = propertySet || originalSet;\n var dashedPropertySet = '_' + propertySet;\n if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) {\n return true;\n }\n return !_isEqual(this[dashedPropertySet], this, true);\n },\n\n /**\n * Saves state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n saveState: function(options) {\n var propertySet = options && options.propertySet || originalSet,\n destination = '_' + propertySet;\n if (!this[destination]) {\n return this.setupState(options);\n }\n saveProps(this, destination, this[propertySet]);\n if (options && options.stateProperties) {\n saveProps(this, destination, options.stateProperties);\n }\n return this;\n },\n\n /**\n * Setups state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n setupState: function(options) {\n options = options || { };\n var propertySet = options.propertySet || originalSet;\n options.propertySet = propertySet;\n this['_' + propertySet] = { };\n this.saveState(options);\n return this;\n }\n });\n})();\n\n\n(function() {\n\n var degreesToRadians = fabric.util.degreesToRadians,\n /* eslint-disable camelcase */\n isVML = function() { return typeof G_vmlCanvasManager !== 'undefined'; };\n /* eslint-enable camelcase */\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * The object interactivity controls.\n * @private\n */\n _controlsVisibility: null,\n\n /**\n * Determines which corner has been clicked\n * @private\n * @param {Object} pointer The pointer indicating the mouse position\n * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found\n */\n _findTargetCorner: function(pointer) {\n if (!this.hasControls || !this.active) {\n return false;\n }\n\n var ex = pointer.x,\n ey = pointer.y,\n xPoints,\n lines;\n this.__corner = 0;\n for (var i in this.oCoords) {\n\n if (!this.isControlVisible(i)) {\n continue;\n }\n\n if (i === 'mtr' && !this.hasRotatingPoint) {\n continue;\n }\n\n if (this.get('lockUniScaling') &&\n (i === 'mt' || i === 'mr' || i === 'mb' || i === 'ml')) {\n continue;\n }\n\n lines = this._getImageLines(this.oCoords[i].corner);\n\n // debugging\n\n // canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n\n // canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n\n // canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n\n // canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n\n xPoints = this._findCrossPoints({ x: ex, y: ey }, lines);\n if (xPoints !== 0 && xPoints % 2 === 1) {\n this.__corner = i;\n return i;\n }\n }\n return false;\n },\n\n /**\n * Sets the coordinates of the draggable boxes in the corners of\n * the image used to scale/rotate it.\n * @private\n */\n _setCornerCoords: function() {\n var coords = this.oCoords,\n newTheta = degreesToRadians(45 - this.angle),\n /* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */\n /* 0.707106 stands for sqrt(2)/2 */\n cornerHypotenuse = this.cornerSize * 0.707106,\n cosHalfOffset = cornerHypotenuse * Math.cos(newTheta),\n sinHalfOffset = cornerHypotenuse * Math.sin(newTheta),\n x, y;\n\n for (var point in coords) {\n x = coords[point].x;\n y = coords[point].y;\n coords[point].corner = {\n tl: {\n x: x - sinHalfOffset,\n y: y - cosHalfOffset\n },\n tr: {\n x: x + cosHalfOffset,\n y: y - sinHalfOffset\n },\n bl: {\n x: x - cosHalfOffset,\n y: y + sinHalfOffset\n },\n br: {\n x: x + sinHalfOffset,\n y: y + cosHalfOffset\n }\n };\n }\n },\n\n /**\n * Draws a colored layer behind the object, inside its selection borders.\n * Requires public options: padding, selectionBackgroundColor\n * this function is called when the context is transformed\n * has checks to be skipped when the object is on a staticCanvas\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawSelectionBackground: function(ctx) {\n if (!this.selectionBackgroundColor || this.group || !this.active ||\n (this.canvas && !this.canvas.interactive)) {\n return this;\n }\n ctx.save();\n var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(),\n vpt = this.canvas.viewportTransform;\n ctx.translate(center.x, center.y);\n ctx.scale(1 / vpt[0], 1 / vpt[3]);\n ctx.rotate(degreesToRadians(this.angle));\n ctx.fillStyle = this.selectionBackgroundColor;\n ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBorders: function(ctx) {\n if (!this.hasBorders) {\n return this;\n }\n\n var wh = this._calculateCurrentDimensions(),\n strokeWidth = 1 / this.borderScaleFactor,\n width = wh.x + strokeWidth,\n height = wh.y + strokeWidth;\n\n ctx.save();\n ctx.strokeStyle = this.borderColor;\n this._setLineDash(ctx, this.borderDashArray, null);\n\n ctx.strokeRect(\n -width / 2,\n -height / 2,\n width,\n height\n );\n\n if (this.hasRotatingPoint && this.isControlVisible('mtr') && !this.get('lockRotation') && this.hasControls) {\n\n var rotateHeight = -height / 2;\n\n ctx.beginPath();\n ctx.moveTo(0, rotateHeight);\n ctx.lineTo(0, rotateHeight - this.rotatingPointOffset);\n ctx.closePath();\n ctx.stroke();\n }\n\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box when it is inside a group.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {object} options object representing current object parameters\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBordersInGroup: function(ctx, options) {\n if (!this.hasBorders) {\n return this;\n }\n\n var p = this._getNonTransformedDimensions(),\n matrix = fabric.util.customTransformMatrix(options.scaleX, options.scaleY, options.skewX),\n wh = fabric.util.transformPoint(p, matrix),\n strokeWidth = 1 / this.borderScaleFactor,\n width = wh.x + strokeWidth,\n height = wh.y + strokeWidth;\n\n ctx.save();\n this._setLineDash(ctx, this.borderDashArray, null);\n ctx.strokeStyle = this.borderColor;\n\n ctx.strokeRect(\n -width / 2,\n -height / 2,\n width,\n height\n );\n\n ctx.restore();\n return this;\n },\n\n /**\n * Draws corners of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: cornerSize, padding\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawControls: function(ctx) {\n if (!this.hasControls) {\n return this;\n }\n\n var wh = this._calculateCurrentDimensions(),\n width = wh.x,\n height = wh.y,\n scaleOffset = this.cornerSize,\n left = -(width + scaleOffset) / 2,\n top = -(height + scaleOffset) / 2,\n methodName = this.transparentCorners ? 'stroke' : 'fill';\n\n ctx.save();\n ctx.strokeStyle = ctx.fillStyle = this.cornerColor;\n if (!this.transparentCorners) {\n ctx.strokeStyle = this.cornerStrokeColor;\n }\n this._setLineDash(ctx, this.cornerDashArray, null);\n\n // top-left\n this._drawControl('tl', ctx, methodName,\n left,\n top);\n\n // top-right\n this._drawControl('tr', ctx, methodName,\n left + width,\n top);\n\n // bottom-left\n this._drawControl('bl', ctx, methodName,\n left,\n top + height);\n\n // bottom-right\n this._drawControl('br', ctx, methodName,\n left + width,\n top + height);\n\n if (!this.get('lockUniScaling')) {\n\n // middle-top\n this._drawControl('mt', ctx, methodName,\n left + width / 2,\n top);\n\n // middle-bottom\n this._drawControl('mb', ctx, methodName,\n left + width / 2,\n top + height);\n\n // middle-right\n this._drawControl('mr', ctx, methodName,\n left + width,\n top + height / 2);\n\n // middle-left\n this._drawControl('ml', ctx, methodName,\n left,\n top + height / 2);\n }\n\n // middle-top-rotate\n if (this.hasRotatingPoint) {\n this._drawControl('mtr', ctx, methodName,\n left + width / 2,\n top - this.rotatingPointOffset);\n }\n\n ctx.restore();\n\n return this;\n },\n\n /**\n * @private\n */\n _drawControl: function(control, ctx, methodName, left, top) {\n if (!this.isControlVisible(control)) {\n return;\n }\n var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor;\n switch (this.cornerStyle) {\n case 'circle':\n ctx.beginPath();\n ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false);\n ctx[methodName]();\n if (stroke) {\n ctx.stroke();\n }\n break;\n default:\n isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size);\n ctx[methodName + 'Rect'](left, top, size, size);\n if (stroke) {\n ctx.strokeRect(left, top, size, size);\n }\n }\n },\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @returns {Boolean} true if the specified control is visible, false otherwise\n */\n isControlVisible: function(controlName) {\n return this._getControlsVisibility()[controlName];\n },\n\n /**\n * Sets the visibility of the specified control.\n * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @param {Boolean} visible true to set the specified control visible, false otherwise\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlVisible: function(controlName, visible) {\n this._getControlsVisibility()[controlName] = visible;\n return this;\n },\n\n /**\n * Sets the visibility state of object controls.\n * @param {Object} [options] Options object\n * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it\n * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it\n * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it\n * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it\n * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it\n * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it\n * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it\n * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlsVisibility: function(options) {\n options || (options = { });\n\n for (var p in options) {\n this.setControlVisible(p, options[p]);\n }\n return this;\n },\n\n /**\n * Returns the instance of the control visibility set for this object.\n * @private\n * @returns {Object}\n */\n _getControlsVisibility: function() {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {\n tl: true,\n tr: true,\n br: true,\n bl: true,\n ml: true,\n mt: true,\n mr: true,\n mb: true,\n mtr: true\n };\n }\n return this._controlsVisibility;\n }\n });\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Animation duration (in ms) for fx* methods\n * @type Number\n * @default\n */\n FX_DURATION: 500,\n\n /**\n * Centers object horizontally with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectH: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.get('left'),\n endValue: this.getCenter().left,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('left', value);\n _this.renderAll();\n onChange();\n },\n onComplete: function() {\n object.setCoords();\n onComplete();\n }\n });\n\n return this;\n },\n\n /**\n * Centers object vertically with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectV: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.get('top'),\n endValue: this.getCenter().top,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('top', value);\n _this.renderAll();\n onChange();\n },\n onComplete: function() {\n object.setCoords();\n onComplete();\n }\n });\n\n return this;\n },\n\n /**\n * Same as `fabric.Canvas#remove` but animated\n * @param {fabric.Object} object Object to remove\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxRemove: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.get('opacity'),\n endValue: 0,\n duration: this.FX_DURATION,\n onStart: function() {\n object.set('active', false);\n },\n onChange: function(value) {\n object.set('opacity', value);\n _this.renderAll();\n onChange();\n },\n onComplete: function () {\n _this.remove(object);\n onComplete();\n }\n });\n\n return this;\n }\n});\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n /**\n * Animates object's properties\n * @param {String|Object} property Property to animate (if string) or properties to animate (if object)\n * @param {Number|Object} value Value to animate property to (if string was given first) or options object\n * @return {fabric.Object} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n * @chainable\n *\n * As object — multiple properties\n *\n * object.animate({ left: ..., top: ... });\n * object.animate({ left: ..., top: ... }, { duration: ... });\n *\n * As string — one property\n *\n * object.animate('left', ...);\n * object.animate('left', { duration: ... });\n *\n */\n animate: function() {\n if (arguments[0] && typeof arguments[0] === 'object') {\n var propsToAnimate = [], prop, skipCallbacks;\n for (prop in arguments[0]) {\n propsToAnimate.push(prop);\n }\n for (var i = 0, len = propsToAnimate.length; i < len; i++) {\n prop = propsToAnimate[i];\n skipCallbacks = i !== len - 1;\n this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);\n }\n }\n else {\n this._animate.apply(this, arguments);\n }\n return this;\n },\n\n /**\n * @private\n * @param {String} property Property to animate\n * @param {String} to Value to animate to\n * @param {Object} [options] Options object\n * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked\n */\n _animate: function(property, to, options, skipCallbacks) {\n var _this = this, propPair;\n\n to = to.toString();\n\n if (!options) {\n options = { };\n }\n else {\n options = fabric.util.object.clone(options);\n }\n\n if (~property.indexOf('.')) {\n propPair = property.split('.');\n }\n\n var currentValue = propPair\n ? this.get(propPair[0])[propPair[1]]\n : this.get(property);\n\n if (!('from' in options)) {\n options.from = currentValue;\n }\n\n if (~to.indexOf('=')) {\n to = currentValue + parseFloat(to.replace('=', ''));\n }\n else {\n to = parseFloat(to);\n }\n\n fabric.util.animate({\n startValue: options.from,\n endValue: to,\n byValue: options.by,\n easing: options.easing,\n duration: options.duration,\n abort: options.abort && function() {\n return options.abort.call(_this);\n },\n onChange: function(value, valueProgress, timeProgress) {\n if (propPair) {\n _this[propPair[0]][propPair[1]] = value;\n }\n else {\n _this.set(property, value);\n }\n if (skipCallbacks) {\n return;\n }\n options.onChange && options.onChange(value, valueProgress, timeProgress);\n },\n onComplete: function(value, valueProgress, timeProgress) {\n if (skipCallbacks) {\n return;\n }\n\n _this.setCoords();\n options.onComplete && options.onComplete(value, valueProgress, timeProgress);\n }\n });\n }\n});\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 },\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash');\n\n if (fabric.Line) {\n fabric.warn('fabric.Line is already defined');\n return;\n }\n\n /**\n * Line class\n * @class fabric.Line\n * @extends fabric.Object\n * @see {@link fabric.Line#initialize} for constructor definition\n */\n fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'line',\n\n /**\n * x value or first line edge\n * @type Number\n * @default\n */\n x1: 0,\n\n /**\n * y value or first line edge\n * @type Number\n * @default\n */\n y1: 0,\n\n /**\n * x value or second line edge\n * @type Number\n * @default\n */\n x2: 0,\n\n /**\n * y value or second line edge\n * @type Number\n * @default\n */\n y2: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'),\n\n /**\n * Constructor\n * @param {Array} [points] Array of points\n * @param {Object} [options] Options object\n * @return {fabric.Line} thisArg\n */\n initialize: function(points, options) {\n if (!points) {\n points = [0, 0, 0, 0];\n }\n\n this.callSuper('initialize', options);\n\n this.set('x1', points[0]);\n this.set('y1', points[1]);\n this.set('x2', points[2]);\n this.set('y2', points[3]);\n\n this._setWidthHeight(options);\n },\n\n /**\n * @private\n * @param {Object} [options] Options\n */\n _setWidthHeight: function(options) {\n options || (options = { });\n\n this.width = Math.abs(this.x2 - this.x1);\n this.height = Math.abs(this.y2 - this.y1);\n\n this.left = 'left' in options\n ? options.left\n : this._getLeftToOriginX();\n\n this.top = 'top' in options\n ? options.top\n : this._getTopToOriginY();\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n if (typeof coordProps[key] !== 'undefined') {\n this._setWidthHeight();\n }\n return this;\n },\n\n /**\n * @private\n * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.\n */\n _getLeftToOriginX: makeEdgeToOriginGetter(\n { // property names\n origin: 'originX',\n axis1: 'x1',\n axis2: 'x2',\n dimension: 'width'\n },\n { // possible values of origin\n nearest: 'left',\n center: 'center',\n farthest: 'right'\n }\n ),\n\n /**\n * @private\n * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line.\n */\n _getTopToOriginY: makeEdgeToOriginGetter(\n { // property names\n origin: 'originY',\n axis1: 'y1',\n axis2: 'y2',\n dimension: 'height'\n },\n { // possible values of origin\n nearest: 'top',\n center: 'center',\n farthest: 'bottom'\n }\n ),\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n ctx.beginPath();\n\n if (noTransform) {\n // Line coords are distances from left-top of canvas to origin of line.\n // To render line in a path-group, we need to translate them to\n // distances from center of path-group to center of line.\n var cp = this.getCenterPoint(),\n offset = this.strokeWidth / 2;\n ctx.translate(\n cp.x - (this.strokeLineCap === 'butt' && this.height === 0 ? 0 : offset),\n cp.y - (this.strokeLineCap === 'butt' && this.width === 0 ? 0 : offset)\n );\n }\n\n if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {\n // move from center (of virtual box) to its left/top corner\n // we can't assume x1, y1 is top left and x2, y2 is bottom right\n var p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n }\n\n ctx.lineWidth = this.strokeWidth;\n\n // TODO: test this\n // make sure setting \"fill\" changes color of a line\n // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n var origStrokeStyle = ctx.strokeStyle;\n ctx.strokeStyle = this.stroke || ctx.fillStyle;\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var p = this.calcLinePoints();\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * Returns object representation of an instance\n * @methd toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints());\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n */\n _getNonTransformedDimensions: function() {\n var dim = this.callSuper('_getNonTransformedDimensions');\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n return dim;\n },\n\n /**\n * Recalculates line points given width and height\n * @private\n */\n calcLinePoints: function() {\n var xMult = this.x1 <= this.x2 ? -1 : 1,\n yMult = this.y1 <= this.y2 ? -1 : 1,\n x1 = (xMult * this.width * 0.5),\n y1 = (yMult * this.height * 0.5),\n x2 = (xMult * this.width * -0.5),\n y2 = (yMult * this.height * -0.5);\n\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2\n };\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(),\n p = { x1: this.x1, x2: this.x2, y1: this.y1, y2: this.y2 };\n\n if (!(this.group && this.group.type === 'path-group')) {\n p = this.calcLinePoints();\n }\n markup.push(\n '\\n'\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})\n * @static\n * @memberOf fabric.Line\n * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n */\n fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));\n\n /**\n * Returns fabric.Line instance from an SVG element\n * @static\n * @memberOf fabric.Line\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Line} instance of fabric.Line\n */\n fabric.Line.fromElement = function(element, options) {\n options = options || { };\n var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES),\n points = [\n parsedAttributes.x1 || 0,\n parsedAttributes.y1 || 0,\n parsedAttributes.x2 || 0,\n parsedAttributes.y2 || 0\n ];\n options.originX = 'left';\n options.originY = 'top';\n return new fabric.Line(points, extend(parsedAttributes, options));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Line instance from an object representation\n * @static\n * @memberOf fabric.Line\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Line} instance of fabric.Line\n */\n fabric.Line.fromObject = function(object, callback, forceAsync) {\n function _callback(instance) {\n delete instance.points;\n callback && callback(instance);\n };\n var options = clone(object, true);\n options.points = [object.x1, object.y1, object.x2, object.y2];\n var line = fabric.Object._fromObject('Line', options, _callback, forceAsync, 'points');\n if (line) {\n delete line.points;\n }\n return line;\n };\n\n /**\n * Produces a function that calculates distance from canvas edge to Line origin.\n */\n function makeEdgeToOriginGetter(propertyNames, originValues) {\n var origin = propertyNames.origin,\n axis1 = propertyNames.axis1,\n axis2 = propertyNames.axis2,\n dimension = propertyNames.dimension,\n nearest = originValues.nearest,\n center = originValues.center,\n farthest = originValues.farthest;\n\n return function() {\n switch (this.get(origin)) {\n case nearest:\n return Math.min(this.get(axis1), this.get(axis2));\n case center:\n return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension));\n case farthest:\n return Math.max(this.get(axis1), this.get(axis2));\n }\n };\n\n }\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n pi = Math.PI,\n extend = fabric.util.object.extend;\n\n if (fabric.Circle) {\n fabric.warn('fabric.Circle is already defined.');\n return;\n }\n\n /**\n * Circle class\n * @class fabric.Circle\n * @extends fabric.Object\n * @see {@link fabric.Circle#initialize} for constructor definition\n */\n fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'circle',\n\n /**\n * Radius of this circle\n * @type Number\n * @default\n */\n radius: 0,\n\n /**\n * Start angle of the circle, moving clockwise\n * @type Number\n * @default 0\n */\n startAngle: 0,\n\n /**\n * End angle of the circle\n * @type Number\n * @default 2Pi\n */\n endAngle: pi * 2,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {fabric.Circle} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this.set('radius', options && options.radius || 0);\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Circle} thisArg\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n\n if (key === 'radius') {\n this.setRadius(value);\n }\n\n return this;\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(), x = 0, y = 0,\n angle = (this.endAngle - this.startAngle) % ( 2 * pi);\n\n if (angle === 0) {\n if (this.group && this.group.type === 'path-group') {\n x = this.left + this.radius;\n y = this.top + this.radius;\n }\n markup.push(\n '\\n'\n );\n }\n else {\n var startX = Math.cos(this.startAngle) * this.radius,\n startY = Math.sin(this.startAngle) * this.radius,\n endX = Math.cos(this.endAngle) * this.radius,\n endY = Math.sin(this.endAngle) * this.radius,\n largeFlag = angle > pi ? '1' : '0';\n\n markup.push(\n '\\n'\n );\n }\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n _render: function(ctx, noTransform) {\n ctx.beginPath();\n ctx.arc(noTransform ? this.left + this.radius : 0,\n noTransform ? this.top + this.radius : 0,\n this.radius,\n this.startAngle,\n this.endAngle, false);\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusX: function() {\n return this.get('radius') * this.get('scaleX');\n },\n\n /**\n * Returns vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusY: function() {\n return this.get('radius') * this.get('scaleY');\n },\n\n /**\n * Sets radius of an object (and updates width accordingly)\n * @return {fabric.Circle} thisArg\n */\n setRadius: function(value) {\n this.radius = value;\n return this.set('width', value * 2).set('height', value * 2);\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement})\n * @static\n * @memberOf fabric.Circle\n * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n */\n fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '));\n\n /**\n * Returns {@link fabric.Circle} instance from an SVG element\n * @static\n * @memberOf fabric.Circle\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @throws {Error} If value of `r` attribute is missing or invalid\n * @return {fabric.Circle} Instance of fabric.Circle\n */\n fabric.Circle.fromElement = function(element, options) {\n options || (options = { });\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);\n\n if (!isValidRadius(parsedAttributes)) {\n throw new Error('value of `r` attribute is required and can not be negative');\n }\n\n parsedAttributes.left = parsedAttributes.left || 0;\n parsedAttributes.top = parsedAttributes.top || 0;\n\n var obj = new fabric.Circle(extend(parsedAttributes, options));\n\n obj.left -= obj.radius;\n obj.top -= obj.radius;\n return obj;\n };\n\n /**\n * @private\n */\n function isValidRadius(attributes) {\n return (('radius' in attributes) && (attributes.radius >= 0));\n }\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Circle} instance from an object representation\n * @static\n * @memberOf fabric.Circle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {Object} Instance of fabric.Circle\n */\n fabric.Circle.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Circle', object, callback, forceAsync);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Triangle) {\n fabric.warn('fabric.Triangle is already defined');\n return;\n }\n\n /**\n * Triangle class\n * @class fabric.Triangle\n * @extends fabric.Object\n * @return {fabric.Triangle} thisArg\n * @see {@link fabric.Triangle#initialize} for constructor definition\n */\n fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'triangle',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this.set('width', options && options.width || 100)\n .set('height', options && options.height || 100);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n ctx.moveTo(-widthBy2, heightBy2);\n ctx.lineTo(0, -heightBy2);\n ctx.lineTo(widthBy2, heightBy2);\n ctx.closePath();\n\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(),\n widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = [\n -widthBy2 + ' ' + heightBy2,\n '0 ' + -heightBy2,\n widthBy2 + ' ' + heightBy2\n ]\n .join(',');\n\n markup.push(\n ''\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n });\n\n /**\n * Returns {@link fabric.Triangle} instance from an object representation\n * @static\n * @memberOf fabric.Triangle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Triangle}\n */\n fabric.Triangle.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Triangle', object, callback, forceAsync);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n piBy2 = Math.PI * 2,\n extend = fabric.util.object.extend;\n\n if (fabric.Ellipse) {\n fabric.warn('fabric.Ellipse is already defined.');\n return;\n }\n\n /**\n * Ellipse class\n * @class fabric.Ellipse\n * @extends fabric.Object\n * @return {fabric.Ellipse} thisArg\n * @see {@link fabric.Ellipse#initialize} for constructor definition\n */\n fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'ellipse',\n\n /**\n * Horizontal radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical radius\n * @type Number\n * @default\n */\n ry: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {fabric.Ellipse} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this.set('rx', options && options.rx || 0);\n this.set('ry', options && options.ry || 0);\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Ellipse} thisArg\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n switch (key) {\n\n case 'rx':\n this.rx = value;\n this.set('width', value * 2);\n break;\n\n case 'ry':\n this.ry = value;\n this.set('height', value * 2);\n break;\n\n }\n return this;\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRx: function() {\n return this.get('rx') * this.get('scaleX');\n },\n\n /**\n * Returns Vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRy: function() {\n return this.get('ry') * this.get('scaleY');\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(), x = 0, y = 0;\n if (this.group && this.group.type === 'path-group') {\n x = this.left + this.rx;\n y = this.top + this.ry;\n }\n markup.push(\n '\\n'\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n _render: function(ctx, noTransform) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(\n noTransform ? this.left + this.rx : 0,\n noTransform ? (this.top + this.ry) * this.rx / this.ry : 0,\n this.rx,\n 0,\n piBy2,\n false);\n ctx.restore();\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement})\n * @static\n * @memberOf fabric.Ellipse\n * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n */\n fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '));\n\n /**\n * Returns {@link fabric.Ellipse} instance from an SVG element\n * @static\n * @memberOf fabric.Ellipse\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Ellipse}\n */\n fabric.Ellipse.fromElement = function(element, options) {\n options || (options = { });\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);\n\n parsedAttributes.left = parsedAttributes.left || 0;\n parsedAttributes.top = parsedAttributes.top || 0;\n\n var ellipse = new fabric.Ellipse(extend(parsedAttributes, options));\n\n ellipse.top -= ellipse.ry;\n ellipse.left -= ellipse.rx;\n return ellipse;\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Ellipse} instance from an object representation\n * @static\n * @memberOf fabric.Ellipse\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Ellipse}\n */\n fabric.Ellipse.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Ellipse', object, callback, forceAsync);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend;\n\n if (fabric.Rect) {\n fabric.warn('fabric.Rect is already defined');\n return;\n }\n\n /**\n * Rectangle class\n * @class fabric.Rect\n * @extends fabric.Object\n * @return {fabric.Rect} thisArg\n * @see {@link fabric.Rect#initialize} for constructor definition\n */\n fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ {\n\n /**\n * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'),\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'rect',\n\n /**\n * Horizontal border radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical border radius\n * @type Number\n * @default\n */\n ry: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this._initRxRy();\n },\n\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy: function() {\n if (this.rx && !this.ry) {\n this.ry = this.rx;\n }\n else if (this.ry && !this.rx) {\n this.rx = this.ry;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n\n // optimize 1x1 case (used in spray brush)\n if (this.width === 1 && this.height === 1) {\n ctx.fillRect(-0.5, -0.5, 1, 1);\n return;\n }\n\n var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0,\n ry = this.ry ? Math.min(this.ry, this.height / 2) : 0,\n w = this.width,\n h = this.height,\n x = noTransform ? this.left : -this.width / 2,\n y = noTransform ? this.top : -this.height / 2,\n isRounded = rx !== 0 || ry !== 0,\n /* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\n k = 1 - 0.5522847498;\n ctx.beginPath();\n\n ctx.moveTo(x + rx, y);\n\n ctx.lineTo(x + w - rx, y);\n isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);\n\n ctx.lineTo(x + w, y + h - ry);\n isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);\n\n ctx.lineTo(x + rx, y + h);\n isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);\n\n ctx.lineTo(x, y + ry);\n isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);\n\n ctx.closePath();\n\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(), x = this.left, y = this.top;\n if (!(this.group && this.group.type === 'path-group')) {\n x = -this.width / 2;\n y = -this.height / 2;\n }\n markup.push(\n '\\n');\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)\n * @static\n * @memberOf fabric.Rect\n * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n */\n fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '));\n\n /**\n * Returns {@link fabric.Rect} instance from an SVG element\n * @static\n * @memberOf fabric.Rect\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Rect} Instance of fabric.Rect\n */\n fabric.Rect.fromElement = function(element, options) {\n if (!element) {\n return null;\n }\n options = options || { };\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);\n\n parsedAttributes.left = parsedAttributes.left || 0;\n parsedAttributes.top = parsedAttributes.top || 0;\n var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n rect.visible = rect.visible && rect.width > 0 && rect.height > 0;\n return rect;\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Rect} instance from an object representation\n * @static\n * @memberOf fabric.Rect\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {Object} instance of fabric.Rect\n */\n fabric.Rect.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Rect', object, callback, forceAsync);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n toFixed = fabric.util.toFixed,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n if (fabric.Polyline) {\n fabric.warn('fabric.Polyline is already defined');\n return;\n }\n\n /**\n * Polyline class\n * @class fabric.Polyline\n * @extends fabric.Object\n * @see {@link fabric.Polyline#initialize} for constructor definition\n */\n fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polyline',\n\n /**\n * Points array\n * @type Array\n * @default\n */\n points: null,\n\n /**\n * Minimum X from points values, necessary to offset points\n * @type Number\n * @default\n */\n minX: 0,\n\n /**\n * Minimum Y from points values, necessary to offset points\n * @type Number\n * @default\n */\n minY: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'),\n\n /**\n * Constructor\n * @param {Array} points Array of points (where each point is an object with x and y)\n * @param {Object} [options] Options object\n * @return {fabric.Polyline} thisArg\n * @example\n * var poly = new fabric.Polyline([\n * { x: 10, y: 10 },\n * { x: 50, y: 30 },\n * { x: 40, y: 70 },\n * { x: 60, y: 50 },\n * { x: 100, y: 150 },\n * { x: 40, y: 100 }\n * ], {\n * stroke: 'red',\n * left: 100,\n * top: 100\n * });\n */\n initialize: function(points, options) {\n options = options || {};\n this.points = points || [];\n this.callSuper('initialize', options);\n this._calcDimensions();\n if (!('top' in options)) {\n this.top = this.minY;\n }\n if (!('left' in options)) {\n this.left = this.minX;\n }\n this.pathOffset = {\n x: this.minX + this.width / 2,\n y: this.minY + this.height / 2\n };\n },\n\n /**\n * @private\n */\n _calcDimensions: function() {\n\n var points = this.points,\n minX = min(points, 'x'),\n minY = min(points, 'y'),\n maxX = max(points, 'x'),\n maxY = max(points, 'y');\n\n this.width = (maxX - minX) || 0;\n this.height = (maxY - minY) || 0;\n this.minX = minX || 0;\n this.minY = minY || 0;\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n points: this.points.concat()\n });\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var points = [],\n diffX = 0,\n diffY = 0,\n markup = this._createBaseSVGMarkup();\n\n if (!(this.group && this.group.type === 'path-group')) {\n diffX = this.pathOffset.x;\n diffY = this.pathOffset.y;\n }\n\n for (var i = 0, len = this.points.length; i < len; i++) {\n points.push(\n toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',',\n toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '\n );\n }\n markup.push(\n '<', this.type, ' ', this.getSvgId(),\n 'points=\"', points.join(''),\n '\" style=\"', this.getSvgStyles(),\n '\" transform=\"', this.getSvgTransform(),\n ' ', this.getSvgTransformMatrix(),\n '\"/>\\n'\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n commonRender: function(ctx, noTransform) {\n var point, len = this.points.length,\n x = noTransform ? 0 : this.pathOffset.x,\n y = noTransform ? 0 : this.pathOffset.y;\n\n if (!len || isNaN(this.points[len - 1].y)) {\n // do not draw if no points or odd points\n // NaN comes from parseFloat of a empty string in parser\n return false;\n }\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n for (var i = 0; i < len; i++) {\n point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n return true;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n if (!this.commonRender(ctx, noTransform)) {\n return;\n }\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var p1, p2;\n\n ctx.beginPath();\n for (var i = 0, len = this.points.length; i < len; i++) {\n p1 = this.points[i];\n p2 = this.points[i + 1] || p1;\n fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray);\n }\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance\n */\n complexity: function() {\n return this.get('points').length;\n }\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement})\n * @static\n * @memberOf fabric.Polyline\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n */\n fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n /**\n * Returns fabric.Polyline instance from an SVG element\n * @static\n * @memberOf fabric.Polyline\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Polyline} Instance of fabric.Polyline\n */\n fabric.Polyline.fromElement = function(element, options) {\n if (!element) {\n return null;\n }\n options || (options = { });\n\n var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES);\n\n return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polyline instance from an object representation\n * @static\n * @memberOf fabric.Polyline\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Polyline} Instance of fabric.Polyline\n */\n fabric.Polyline.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Polyline', object, callback, forceAsync, 'points');\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend;\n\n if (fabric.Polygon) {\n fabric.warn('fabric.Polygon is already defined');\n return;\n }\n\n /**\n * Polygon class\n * @class fabric.Polygon\n * @extends fabric.Polyline\n * @see {@link fabric.Polygon#initialize} for constructor definition\n */\n fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polygon',\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n if (!this.commonRender(ctx, noTransform)) {\n return;\n }\n ctx.closePath();\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n this.callSuper('_renderDashedStroke', ctx);\n ctx.closePath();\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)\n * @static\n * @memberOf fabric.Polygon\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement\n */\n fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n /**\n * Returns {@link fabric.Polygon} instance from an SVG element\n * @static\n * @memberOf fabric.Polygon\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Polygon} Instance of fabric.Polygon\n */\n fabric.Polygon.fromElement = function(element, options) {\n if (!element) {\n return null;\n }\n\n options || (options = { });\n\n var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES);\n\n return new fabric.Polygon(points, extend(parsedAttributes, options));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polygon instance from an object representation\n * @static\n * @memberOf fabric.Polygon\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Polygon} Instance of fabric.Polygon\n */\n fabric.Polygon.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Polygon', object, callback, forceAsync, 'points');\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n extend = fabric.util.object.extend,\n _toString = Object.prototype.toString,\n drawArc = fabric.util.drawArc,\n commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7\n },\n repeatedCommands = {\n m: 'l',\n M: 'L'\n };\n\n if (fabric.Path) {\n fabric.warn('fabric.Path is already defined');\n return;\n }\n\n /**\n * Path class\n * @class fabric.Path\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}\n * @see {@link fabric.Path#initialize} for constructor definition\n */\n fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'path',\n\n /**\n * Array of path points\n * @type Array\n * @default\n */\n path: null,\n\n /**\n * Minimum X from points values, necessary to offset points\n * @type Number\n * @default\n */\n minX: 0,\n\n /**\n * Minimum Y from points values, necessary to offset points\n * @type Number\n * @default\n */\n minY: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'),\n\n stateProperties: fabric.Object.prototype.stateProperties.concat('path'),\n\n /**\n * Constructor\n * @param {Array|String} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {Object} [options] Options object\n * @return {fabric.Path} thisArg\n */\n initialize: function(path, options) {\n options = options || { };\n this.callSuper('initialize', options);\n\n if (!path) {\n path = [];\n }\n\n var fromArray = _toString.call(path) === '[object Array]';\n\n this.path = fromArray\n ? path\n // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values)\n : path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);\n\n if (!this.path) {\n return;\n }\n\n if (!fromArray) {\n this.path = this._parsePath();\n }\n\n this._setPositionDimensions(options);\n },\n\n /**\n * @private\n * @param {Object} options Options object\n */\n _setPositionDimensions: function(options) {\n var calcDim = this._parseDimensions();\n\n this.minX = calcDim.left;\n this.minY = calcDim.top;\n this.width = calcDim.width;\n this.height = calcDim.height;\n\n if (typeof options.left === 'undefined') {\n this.left = calcDim.left + (this.originX === 'center'\n ? this.width / 2\n : this.originX === 'right'\n ? this.width\n : 0);\n }\n\n if (typeof options.top === 'undefined') {\n this.top = calcDim.top + (this.originY === 'center'\n ? this.height / 2\n : this.originY === 'bottom'\n ? this.height\n : 0);\n }\n\n this.pathOffset = this.pathOffset || {\n x: this.minX + this.width / 2,\n y: this.minY + this.height / 2\n };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _renderPathCommands: function(ctx) {\n var current, // current instruction\n previous = null,\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0, // current y\n controlX = 0, // current control point x\n controlY = 0, // current control point y\n tempX,\n tempY,\n l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n\n if (this.group && this.group.type === 'path-group') {\n l = 0;\n t = 0;\n }\n\n ctx.beginPath();\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n\n current = this.path[i];\n\n switch (current[0]) { // first letter\n\n case 'l': // lineto, relative\n x += current[1];\n y += current[2];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'L': // lineto, absolute\n x = current[1];\n y = current[2];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'h': // horizontal lineto, relative\n x += current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'H': // horizontal lineto, absolute\n x = current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'v': // vertical lineto, relative\n y += current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'V': // verical lineto, absolute\n y = current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'm': // moveTo, relative\n x += current[1];\n y += current[2];\n subpathStartX = x;\n subpathStartY = y;\n ctx.moveTo(x + l, y + t);\n break;\n\n case 'M': // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n ctx.moveTo(x + l, y + t);\n break;\n\n case 'c': // bezierCurveTo, relative\n tempX = x + current[5];\n tempY = y + current[6];\n controlX = x + current[3];\n controlY = y + current[4];\n ctx.bezierCurveTo(\n x + current[1] + l, // x1\n y + current[2] + t, // y1\n controlX + l, // x2\n controlY + t, // y2\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'C': // bezierCurveTo, absolute\n x = current[5];\n y = current[6];\n controlX = current[3];\n controlY = current[4];\n ctx.bezierCurveTo(\n current[1] + l,\n current[2] + t,\n controlX + l,\n controlY + t,\n x + l,\n y + t\n );\n break;\n\n case 's': // shorthand cubic bezierCurveTo, relative\n\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n ctx.bezierCurveTo(\n controlX + l,\n controlY + t,\n x + current[1] + l,\n y + current[2] + t,\n tempX + l,\n tempY + t\n );\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = x + current[1];\n controlY = y + current[2];\n\n x = tempX;\n y = tempY;\n break;\n\n case 'S': // shorthand cubic bezierCurveTo, absolute\n tempX = current[3];\n tempY = current[4];\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n ctx.bezierCurveTo(\n controlX + l,\n controlY + t,\n current[1] + l,\n current[2] + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = current[1];\n controlY = current[2];\n\n break;\n\n case 'q': // quadraticCurveTo, relative\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n\n controlX = x + current[1];\n controlY = y + current[2];\n\n ctx.quadraticCurveTo(\n controlX + l,\n controlY + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n tempX = current[3];\n tempY = current[4];\n\n ctx.quadraticCurveTo(\n current[1] + l,\n current[2] + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n controlX = current[1];\n controlY = current[2];\n break;\n\n case 't': // shorthand quadraticCurveTo, relative\n\n // transform to absolute x,y\n tempX = x + current[1];\n tempY = y + current[2];\n\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n ctx.quadraticCurveTo(\n controlX + l,\n controlY + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n\n break;\n\n case 'T':\n tempX = current[1];\n tempY = current[2];\n\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n ctx.quadraticCurveTo(\n controlX + l,\n controlY + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'a':\n // TODO: optimize this\n drawArc(ctx, x + l, y + t, [\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6] + x + l,\n current[7] + y + t\n ]);\n x += current[6];\n y += current[7];\n break;\n\n case 'A':\n // TODO: optimize this\n drawArc(ctx, x + l, y + t, [\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6] + l,\n current[7] + t\n ]);\n x = current[6];\n y = current[7];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n ctx.closePath();\n break;\n }\n previous = current;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render: function(ctx) {\n this._renderPathCommands(ctx);\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var o = extend(this.callSuper('toObject', ['sourcePath', 'pathOffset'].concat(propertiesToInclude)), {\n path: this.path.map(function(item) { return item.slice(); }),\n top: this.top,\n left: this.left,\n });\n return o;\n },\n\n /**\n * Returns dataless object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var o = this.toObject(propertiesToInclude);\n if (this.sourcePath) {\n o.path = this.sourcePath;\n }\n delete o.sourcePath;\n return o;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var chunks = [],\n markup = this._createBaseSVGMarkup(), addTransform = '';\n\n for (var i = 0, len = this.path.length; i < len; i++) {\n chunks.push(this.path[i].join(' '));\n }\n var path = chunks.join(' ');\n if (!(this.group && this.group.type === 'path-group')) {\n addTransform = ' translate(' + (-this.pathOffset.x) + ', ' + (-this.pathOffset.y) + ') ';\n }\n markup.push(\n '\\n'\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns number representation of an instance complexity\n * @return {Number} complexity of this instance\n */\n complexity: function() {\n return this.path.length;\n },\n\n /**\n * @private\n */\n _parsePath: function() {\n var result = [],\n coords = [],\n currentPath,\n parsed,\n re = /([-+]?((\\d+\\.\\d+)|((\\d+)|(\\.\\d+)))(?:e[-+]?\\d+)?)/ig,\n match,\n coordsStr;\n\n for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) {\n currentPath = this.path[i];\n\n coordsStr = currentPath.slice(1).trim();\n coords.length = 0;\n\n while ((match = re.exec(coordsStr))) {\n coords.push(match[0]);\n }\n\n coordsParsed = [currentPath.charAt(0)];\n\n for (var j = 0, jlen = coords.length; j < jlen; j++) {\n parsed = parseFloat(coords[j]);\n if (!isNaN(parsed)) {\n coordsParsed.push(parsed);\n }\n }\n\n var command = coordsParsed[0],\n commandLength = commandLengths[command.toLowerCase()],\n repeatedCommand = repeatedCommands[command] || command;\n\n if (coordsParsed.length - 1 > commandLength) {\n for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) {\n result.push([command].concat(coordsParsed.slice(k, k + commandLength)));\n command = repeatedCommand;\n }\n }\n else {\n result.push(coordsParsed);\n }\n }\n\n return result;\n },\n\n /**\n * @private\n */\n _parseDimensions: function() {\n\n var aX = [],\n aY = [],\n current, // current instruction\n previous = null,\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0, // current y\n controlX = 0, // current control point x\n controlY = 0, // current control point y\n tempX,\n tempY,\n bounds;\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n\n current = this.path[i];\n\n switch (current[0]) { // first letter\n\n case 'l': // lineto, relative\n x += current[1];\n y += current[2];\n bounds = [];\n break;\n\n case 'L': // lineto, absolute\n x = current[1];\n y = current[2];\n bounds = [];\n break;\n\n case 'h': // horizontal lineto, relative\n x += current[1];\n bounds = [];\n break;\n\n case 'H': // horizontal lineto, absolute\n x = current[1];\n bounds = [];\n break;\n\n case 'v': // vertical lineto, relative\n y += current[1];\n bounds = [];\n break;\n\n case 'V': // verical lineto, absolute\n y = current[1];\n bounds = [];\n break;\n\n case 'm': // moveTo, relative\n x += current[1];\n y += current[2];\n subpathStartX = x;\n subpathStartY = y;\n bounds = [];\n break;\n\n case 'M': // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n bounds = [];\n break;\n\n case 'c': // bezierCurveTo, relative\n tempX = x + current[5];\n tempY = y + current[6];\n controlX = x + current[3];\n controlY = y + current[4];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n x + current[1], // x1\n y + current[2], // y1\n controlX, // x2\n controlY, // y2\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'C': // bezierCurveTo, absolute\n controlX = current[3];\n controlY = current[4];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n current[1],\n current[2],\n controlX,\n controlY,\n current[5],\n current[6]\n );\n x = current[5];\n y = current[6];\n break;\n\n case 's': // shorthand cubic bezierCurveTo, relative\n\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n x + current[1],\n y + current[2],\n tempX,\n tempY\n );\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = x + current[1];\n controlY = y + current[2];\n x = tempX;\n y = tempY;\n break;\n\n case 'S': // shorthand cubic bezierCurveTo, absolute\n tempX = current[3];\n tempY = current[4];\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n current[1],\n current[2],\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = current[1];\n controlY = current[2];\n break;\n\n case 'q': // quadraticCurveTo, relative\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n controlX = x + current[1];\n controlY = y + current[2];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n controlX = current[1];\n controlY = current[2];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n current[3],\n current[4]\n );\n x = current[3];\n y = current[4];\n break;\n\n case 't': // shorthand quadraticCurveTo, relative\n // transform to absolute x,y\n tempX = x + current[1];\n tempY = y + current[2];\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n\n break;\n\n case 'T':\n tempX = current[1];\n tempY = current[2];\n\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'a':\n // TODO: optimize this\n bounds = fabric.util.getBoundsOfArc(x, y,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6] + x,\n current[7] + y\n );\n x += current[6];\n y += current[7];\n break;\n\n case 'A':\n // TODO: optimize this\n bounds = fabric.util.getBoundsOfArc(x, y,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n current[7]\n );\n x = current[6];\n y = current[7];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n previous = current;\n bounds.forEach(function (point) {\n aX.push(point.x);\n aY.push(point.y);\n });\n aX.push(x);\n aY.push(y);\n }\n\n var minX = min(aX) || 0,\n minY = min(aY) || 0,\n maxX = max(aX) || 0,\n maxY = max(aY) || 0,\n deltaX = maxX - minX,\n deltaY = maxY - minY,\n\n o = {\n left: minX,\n top: minY,\n width: deltaX,\n height: deltaY\n };\n\n return o;\n }\n });\n\n /**\n * Creates an instance of fabric.Path from an object\n * @static\n * @memberOf fabric.Path\n * @param {Object} object\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n */\n fabric.Path.fromObject = function(object, callback, forceAsync) {\n // remove this pattern rom 2.0, accept just object.\n var path;\n if (typeof object.path === 'string') {\n fabric.loadSVGFromURL(object.path, function (elements) {\n var pathUrl = object.path;\n path = elements[0];\n delete object.path;\n\n path.setOptions(object);\n path.setSourcePath(pathUrl);\n\n callback && callback(path);\n });\n }\n else {\n return fabric.Object._fromObject('Path', object, callback, forceAsync, 'path');\n }\n };\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`)\n * @static\n * @memberOf fabric.Path\n * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n */\n fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']);\n\n /**\n * Creates an instance of fabric.Path from an SVG element\n * @static\n * @memberOf fabric.Path\n * @param {SVGElement} element to parse\n * @param {Function} callback Callback to invoke when an fabric.Path instance is created\n * @param {Object} [options] Options object\n */\n fabric.Path.fromElement = function(element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);\n callback && callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @memberOf fabric.Path\n * @type Boolean\n * @default\n */\n fabric.Path.async = true;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend;\n\n if (fabric.PathGroup) {\n fabric.warn('fabric.PathGroup is already defined');\n return;\n }\n\n /**\n * Path group class\n * @class fabric.PathGroup\n * @extends fabric.Path\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}\n * @see {@link fabric.PathGroup#initialize} for constructor definition\n */\n fabric.PathGroup = fabric.util.createClass(fabric.Object, /** @lends fabric.PathGroup.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'path-group',\n\n /**\n * Fill value\n * @type String\n * @default\n */\n fill: '',\n\n /**\n * Pathgroups are container, do not render anything on theyr own, ence no cache properties\n * @type Boolean\n * @default\n */\n cacheProperties: [],\n\n /**\n * Constructor\n * @param {Array} paths\n * @param {Object} [options] Options object\n * @return {fabric.PathGroup} thisArg\n */\n initialize: function(paths, options) {\n\n options = options || { };\n this.paths = paths || [];\n\n for (var i = this.paths.length; i--;) {\n this.paths[i].group = this;\n }\n\n if (options.toBeParsed) {\n this.parseDimensionsFromPaths(options);\n delete options.toBeParsed;\n }\n this.setOptions(options);\n this.setCoords();\n },\n\n /**\n * Calculate width and height based on paths contained\n */\n parseDimensionsFromPaths: function(options) {\n var points, p, xC = [], yC = [], path, height, width,\n m;\n for (var j = this.paths.length; j--;) {\n path = this.paths[j];\n height = path.height + path.strokeWidth;\n width = path.width + path.strokeWidth;\n points = [\n { x: path.left, y: path.top },\n { x: path.left + width, y: path.top },\n { x: path.left, y: path.top + height },\n { x: path.left + width, y: path.top + height }\n ];\n m = this.paths[j].transformMatrix;\n for (var i = 0; i < points.length; i++) {\n p = points[i];\n if (m) {\n p = fabric.util.transformPoint(p, m, false);\n }\n xC.push(p.x);\n yC.push(p.y);\n }\n }\n options.width = Math.max.apply(null, xC);\n options.height = Math.max.apply(null, yC);\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n drawObject: function(ctx) {\n ctx.save();\n ctx.translate(-this.width / 2, -this.height / 2);\n for (var i = 0, l = this.paths.length; i < l; ++i) {\n this.paths[i].render(ctx, true);\n }\n ctx.restore();\n },\n\n /**\n * Decide if the object should cache or not.\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache: function() {\n var parentCache = this.objectCaching && (!this.group || this.needsItsOwnCache() || !this.group.isCaching());\n this.caching = parentCache;\n if (parentCache) {\n for (var i = 0, len = this.paths.length; i < len; i++) {\n if (this.paths[i].willDrawShadow()) {\n this.caching = false;\n return false;\n }\n }\n }\n return parentCache;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow: function() {\n if (this.shadow) {\n return true;\n }\n for (var i = 0, len = this.paths.length; i < len; i++) {\n if (this.paths[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isCaching: function() {\n return this.caching || this.group && this.group.isCaching();\n },\n\n /**\n * Check if cache is dirty\n */\n isCacheDirty: function() {\n if (this.callSuper('isCacheDirty')) {\n return true;\n }\n if (!this.statefullCache) {\n return false;\n }\n for (var i = 0, len = this.paths.length; i < len; i++) {\n if (this.paths[i].isCacheDirty(true)) {\n if (this._cacheCanvas) {\n var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Sets certain property to a certain value\n * @param {String} prop\n * @param {*} value\n * @return {fabric.PathGroup} thisArg\n */\n _set: function(prop, value) {\n\n if (prop === 'fill' && value && this.isSameColor()) {\n var i = this.paths.length;\n while (i--) {\n this.paths[i]._set(prop, value);\n }\n }\n\n return this.callSuper('_set', prop, value);\n },\n\n /**\n * Returns object representation of this path group\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var pathsToObject = this.paths.map(function(path) {\n var originalDefaults = path.includeDefaultValues;\n path.includeDefaultValues = path.group.includeDefaultValues;\n var obj = path.toObject(propertiesToInclude);\n path.includeDefaultValues = originalDefaults;\n return obj;\n });\n var o = extend(this.callSuper('toObject', ['sourcePath'].concat(propertiesToInclude)), {\n paths: pathsToObject\n });\n return o;\n },\n\n /**\n * Returns dataless object representation of this path group\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} dataless object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var o = this.toObject(propertiesToInclude);\n if (this.sourcePath) {\n o.paths = this.sourcePath;\n }\n return o;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var objects = this.getObjects(),\n p = this.getPointByOrigin('left', 'top'),\n translatePart = 'translate(' + p.x + ' ' + p.y + ')',\n markup = this._createBaseSVGMarkup();\n markup.push(\n '\\n'\n );\n\n for (var i = 0, len = objects.length; i < len; i++) {\n markup.push('\\t', objects[i].toSVG(reviver));\n }\n markup.push('\\n');\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns a string representation of this path group\n * @return {String} string representation of an object\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Returns true if all paths in this group are of same color\n * @return {Boolean} true if all paths are of the same color (`fill`)\n */\n isSameColor: function() {\n var firstPathFill = this.getObjects()[0].get('fill') || '';\n if (typeof firstPathFill !== 'string') {\n return false;\n }\n firstPathFill = firstPathFill.toLowerCase();\n return this.getObjects().every(function(path) {\n var pathFill = path.get('fill') || '';\n return typeof pathFill === 'string' && (pathFill).toLowerCase() === firstPathFill;\n });\n },\n\n /**\n * Returns number representation of object's complexity\n * @return {Number} complexity\n */\n complexity: function() {\n return this.paths.reduce(function(total, path) {\n return total + ((path && path.complexity) ? path.complexity() : 0);\n }, 0);\n },\n\n /**\n * Returns all paths in this path group\n * @return {Array} array of path objects included in this path group\n */\n getObjects: function() {\n return this.paths;\n }\n });\n\n /**\n * Creates fabric.PathGroup instance from an object representation\n * @static\n * @memberOf fabric.PathGroup\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.PathGroup instance is created\n */\n fabric.PathGroup.fromObject = function(object, callback) {\n var originalPaths = object.paths;\n delete object.paths;\n if (typeof originalPaths === 'string') {\n fabric.loadSVGFromURL(originalPaths, function (elements) {\n var pathUrl = originalPaths;\n var pathGroup = fabric.util.groupSVGElements(elements, object, pathUrl);\n object.paths = originalPaths;\n callback(pathGroup);\n });\n }\n else {\n fabric.util.enlivenObjects(originalPaths, function(enlivenedObjects) {\n var pathGroup = new fabric.PathGroup(enlivenedObjects, object);\n object.paths = originalPaths;\n callback(pathGroup);\n });\n }\n };\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @memberOf fabric.PathGroup\n * @type Boolean\n * @default\n */\n fabric.PathGroup.async = true;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n min = fabric.util.array.min,\n max = fabric.util.array.max;\n\n if (fabric.Group) {\n return;\n }\n\n // lock-related properties, for use in fabric.Group#get\n // to enable locking behavior on group\n // when one of its objects has lock-related properties set\n var _lockProperties = {\n lockMovementX: true,\n lockMovementY: true,\n lockRotation: true,\n lockScalingX: true,\n lockScalingY: true,\n lockUniScaling: true\n };\n\n /**\n * Group class\n * @class fabric.Group\n * @extends fabric.Object\n * @mixes fabric.Collection\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n * @see {@link fabric.Group#initialize} for constructor definition\n */\n fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'group',\n\n /**\n * Width of stroke\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * Indicates if click events should also check for subtargets\n * @type Boolean\n * @default\n */\n subTargetCheck: false,\n\n /**\n * Groups are container, do not render anything on theyr own, ence no cache properties\n * @type Boolean\n * @default\n */\n cacheProperties: [],\n\n /**\n * Constructor\n * @param {Object} objects Group objects\n * @param {Object} [options] Options object\n * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already.\n * @return {Object} thisArg\n */\n initialize: function(objects, options, isAlreadyGrouped) {\n options = options || { };\n\n this._objects = [];\n // if objects enclosed in a group have been grouped already,\n // we cannot change properties of objects.\n // Thus we need to set options to group without objects,\n // because delegatedProperties propagate to objects.\n isAlreadyGrouped && this.callSuper('initialize', options);\n\n this._objects = objects || [];\n for (var i = this._objects.length; i--; ) {\n this._objects[i].group = this;\n }\n\n if (options.originX) {\n this.originX = options.originX;\n }\n if (options.originY) {\n this.originY = options.originY;\n }\n\n if (isAlreadyGrouped) {\n // do not change coordinate of objects enclosed in a group,\n // because objects coordinate system have been group coodinate system already.\n this._updateObjectsCoords(true);\n this._updateObjectsACoords();\n }\n else {\n this._calcBounds();\n this._updateObjectsCoords();\n this.callSuper('initialize', options);\n }\n\n this.setCoords();\n this.saveCoords();\n },\n\n _updateObjectsACoords: function() {\n var ignoreZoom = true, skipAbsolute = true;\n for (var i = this._objects.length; i--; ){\n this._objects[i].setCoords(ignoreZoom, skipAbsolute);\n }\n },\n\n /**\n * @private\n * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n */\n _updateObjectsCoords: function(skipCoordsChange) {\n var center = this.getCenterPoint();\n for (var i = this._objects.length; i--; ){\n this._updateObjectCoords(this._objects[i], center, skipCoordsChange);\n }\n },\n\n /**\n * @private\n * @param {Object} object\n * @param {fabric.Point} center, current center of group.\n * @param {Boolean} [skipCoordsChange] if true, coordinates of object dose not change\n */\n _updateObjectCoords: function(object, center, skipCoordsChange) {\n // do not display corners of objects enclosed in a group\n object.__origHasControls = object.hasControls;\n object.hasControls = false;\n\n if (skipCoordsChange) {\n return;\n }\n\n var objectLeft = object.getLeft(),\n objectTop = object.getTop(),\n ignoreZoom = true, skipAbsolute = true;\n\n object.set({\n left: objectLeft - center.x,\n top: objectTop - center.y\n });\n object.setCoords(ignoreZoom, skipAbsolute);\n },\n\n /**\n * Returns string represenation of a group\n * @return {String}\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Adds an object to a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n addWithUpdate: function(object) {\n this._restoreObjectsState();\n fabric.util.resetObjectTransform(this);\n if (object) {\n this._objects.push(object);\n object.group = this;\n object._set('canvas', this.canvas);\n }\n // since _restoreObjectsState set objects inactive\n this.forEachObject(this._setObjectActive, this);\n this._calcBounds();\n this._updateObjectsCoords();\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * @private\n */\n _setObjectActive: function(object) {\n object.set('active', true);\n object.group = this;\n },\n\n /**\n * Removes an object from a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n removeWithUpdate: function(object) {\n this._restoreObjectsState();\n fabric.util.resetObjectTransform(this);\n // since _restoreObjectsState set objects inactive\n this.forEachObject(this._setObjectActive, this);\n\n this.remove(object);\n this._calcBounds();\n this._updateObjectsCoords();\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * @private\n */\n _onObjectAdded: function(object) {\n this.dirty = true;\n object.group = this;\n object._set('canvas', this.canvas);\n },\n\n /**\n * @private\n */\n _onObjectRemoved: function(object) {\n this.dirty = true;\n delete object.group;\n object.set('active', false);\n },\n\n /**\n * Properties that are delegated to group objects when reading/writing\n * @param {Object} delegatedProperties\n */\n delegatedProperties: {\n fill: true,\n stroke: true,\n strokeWidth: true,\n fontFamily: true,\n fontWeight: true,\n fontSize: true,\n fontStyle: true,\n lineHeight: true,\n textDecoration: true,\n textAlign: true,\n backgroundColor: true\n },\n\n /**\n * @private\n */\n _set: function(key, value) {\n var i = this._objects.length;\n\n if (this.delegatedProperties[key] || key === 'canvas') {\n while (i--) {\n this._objects[i].set(key, value);\n }\n }\n else {\n while (i--) {\n this._objects[i].setOnGroup(key, value);\n }\n }\n\n this.callSuper('_set', key, value);\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var objsToObject = this.getObjects().map(function(obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = obj.group.includeDefaultValues;\n var _obj = obj.toObject(propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n return extend(this.callSuper('toObject', propertiesToInclude), {\n objects: objsToObject\n });\n },\n\n /**\n * Returns object representation of an instance, in dataless mode.\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var objsToObject = this.getObjects().map(function(obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = obj.group.includeDefaultValues;\n var _obj = obj.toDatalessObject(propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n return extend(this.callSuper('toDatalessObject', propertiesToInclude), {\n objects: objsToObject\n });\n },\n\n /**\n * Renders instance on a given context\n * @param {CanvasRenderingContext2D} ctx context to render instance on\n */\n render: function(ctx) {\n this._transformDone = true;\n this.callSuper('render', ctx);\n this._transformDone = false;\n },\n\n /**\n * Decide if the object should cache or not.\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache: function() {\n var parentCache = this.objectCaching && (!this.group || this.needsItsOwnCache() || !this.group.isCaching());\n this.caching = parentCache;\n if (parentCache) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n this.caching = false;\n return false;\n }\n }\n }\n return parentCache;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow: function() {\n if (this.callSuper('willDrawShadow')) {\n return true;\n }\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isCaching: function() {\n return this.caching || this.group && this.group.isCaching();\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n drawObject: function(ctx) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._renderObject(this._objects[i], ctx);\n }\n },\n\n /**\n * Check if cache is dirty\n */\n isCacheDirty: function() {\n if (this.callSuper('isCacheDirty')) {\n return true;\n }\n if (!this.statefullCache) {\n return false;\n }\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].isCacheDirty(true)) {\n if (this._cacheCanvas) {\n // if this group has not a cache canvas there is nothing to clean\n var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n _renderControls: function(ctx, noTransform) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n this.callSuper('_renderControls', ctx, noTransform);\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i]._renderControls(ctx);\n }\n ctx.restore();\n },\n\n /**\n * @private\n */\n _renderObject: function(object, ctx) {\n // do not render if object is not visible\n if (!object.visible) {\n return;\n }\n\n var originalHasRotatingPoint = object.hasRotatingPoint;\n object.hasRotatingPoint = false;\n object.render(ctx);\n object.hasRotatingPoint = originalHasRotatingPoint;\n },\n\n /**\n * Retores original state of each of group objects (original state is that which was before group was created).\n * @private\n * @return {fabric.Group} thisArg\n * @chainable\n */\n _restoreObjectsState: function() {\n this._objects.forEach(this._restoreObjectState, this);\n return this;\n },\n\n /**\n * Realises the transform from this group onto the supplied object\n * i.e. it tells you what would happen if the supplied object was in\n * the group, and then the group was destroyed. It mutates the supplied\n * object.\n * @param {fabric.Object} object\n * @return {fabric.Object} transformedObject\n */\n realizeTransform: function(object) {\n var matrix = object.calcTransformMatrix(),\n options = fabric.util.qrDecompose(matrix),\n center = new fabric.Point(options.translateX, options.translateY);\n object.flipX = false;\n object.flipY = false;\n object.set('scaleX', options.scaleX);\n object.set('scaleY', options.scaleY);\n object.skewX = options.skewX;\n object.skewY = options.skewY;\n object.angle = options.angle;\n object.setPositionByOrigin(center, 'center', 'center');\n return object;\n },\n\n /**\n * Restores original state of a specified object in group\n * @private\n * @param {fabric.Object} object\n * @return {fabric.Group} thisArg\n */\n _restoreObjectState: function(object) {\n this.realizeTransform(object);\n object.setCoords();\n object.hasControls = object.__origHasControls;\n delete object.__origHasControls;\n object.set('active', false);\n delete object.group;\n\n return this;\n },\n\n /**\n * Destroys a group (restoring state of its objects)\n * @return {fabric.Group} thisArg\n * @chainable\n */\n destroy: function() {\n // when group is destroyed objects needs to get a repaint to be eventually\n // displayed on canvas.\n this._objects.forEach(function(object) {\n object.set('dirty', true);\n });\n return this._restoreObjectsState();\n },\n\n /**\n * Saves coordinates of this instance (to be used together with `hasMoved`)\n * @saveCoords\n * @return {fabric.Group} thisArg\n * @chainable\n */\n saveCoords: function() {\n this._originalLeft = this.get('left');\n this._originalTop = this.get('top');\n return this;\n },\n\n /**\n * Checks whether this group was moved (since `saveCoords` was called last)\n * @return {Boolean} true if an object was moved (since fabric.Group#saveCoords was called)\n */\n hasMoved: function() {\n return this._originalLeft !== this.get('left') ||\n this._originalTop !== this.get('top');\n },\n\n /**\n * Sets coordinates of all objects inside group\n * @return {fabric.Group} thisArg\n * @chainable\n */\n setObjectsCoords: function() {\n var ignoreZoom = true, skipAbsolute = true;\n this.forEachObject(function(object) {\n object.setCoords(ignoreZoom, skipAbsolute);\n });\n return this;\n },\n\n /**\n * @private\n */\n _calcBounds: function(onlyWidthHeight) {\n var aX = [],\n aY = [],\n o, prop,\n props = ['tr', 'br', 'bl', 'tl'],\n i = 0, iLen = this._objects.length,\n j, jLen = props.length,\n ignoreZoom = true;\n\n for ( ; i < iLen; ++i) {\n o = this._objects[i];\n o.setCoords(ignoreZoom);\n for (j = 0; j < jLen; j++) {\n prop = props[j];\n aX.push(o.oCoords[prop].x);\n aY.push(o.oCoords[prop].y);\n }\n }\n\n this.set(this._getBounds(aX, aY, onlyWidthHeight));\n },\n\n /**\n * @private\n */\n _getBounds: function(aX, aY, onlyWidthHeight) {\n var minXY = new fabric.Point(min(aX), min(aY)),\n maxXY = new fabric.Point(max(aX), max(aY)),\n obj = {\n width: (maxXY.x - minXY.x) || 0,\n height: (maxXY.y - minXY.y) || 0\n };\n\n if (!onlyWidthHeight) {\n obj.left = minXY.x || 0;\n obj.top = minXY.y || 0;\n if (this.originX === 'center') {\n obj.left += obj.width / 2;\n }\n if (this.originX === 'right') {\n obj.left += obj.width;\n }\n if (this.originY === 'center') {\n obj.top += obj.height / 2;\n }\n if (this.originY === 'bottom') {\n obj.top += obj.height;\n }\n }\n return obj;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup();\n markup.push(\n '\\n'\n );\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n markup.push('\\t', this._objects[i].toSVG(reviver));\n }\n\n markup.push('\\n');\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns requested property\n * @param {String} prop Property to get\n * @return {*}\n */\n get: function(prop) {\n if (prop in _lockProperties) {\n if (this[prop]) {\n return this[prop];\n }\n else {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i][prop]) {\n return true;\n }\n }\n return false;\n }\n }\n else {\n if (prop in this.delegatedProperties) {\n return this._objects[0] && this._objects[0].get(prop);\n }\n return this[prop];\n }\n }\n });\n\n /**\n * Returns {@link fabric.Group} instance from an object representation\n * @static\n * @memberOf fabric.Group\n * @param {Object} object Object to create a group from\n * @param {Function} [callback] Callback to invoke when an group instance is created\n */\n fabric.Group.fromObject = function(object, callback) {\n fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {\n var options = fabric.util.object.clone(object, true);\n delete options.objects;\n callback && callback(new fabric.Group(enlivenedObjects, options, true));\n });\n };\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @memberOf fabric.Group\n * @type Boolean\n * @default\n */\n fabric.Group.async = true;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var extend = fabric.util.object.extend;\n\n if (!global.fabric) {\n global.fabric = { };\n }\n\n if (global.fabric.Image) {\n fabric.warn('fabric.Image is already defined.');\n return;\n }\n\n /**\n * Image class\n * @class fabric.Image\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n * @see {@link fabric.Image#initialize} for constructor definition\n */\n fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'image',\n\n /**\n * crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n * @type String\n * @default\n */\n crossOrigin: '',\n\n /**\n * AlignX value, part of preserveAspectRatio (one of \"none\", \"mid\", \"min\", \"max\")\n * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute\n * This parameter defines how the picture is aligned to its viewport when image element width differs from image width.\n * @type String\n * @default\n */\n alignX: 'none',\n\n /**\n * AlignY value, part of preserveAspectRatio (one of \"none\", \"mid\", \"min\", \"max\")\n * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute\n * This parameter defines how the picture is aligned to its viewport when image element height differs from image height.\n * @type String\n * @default\n */\n alignY: 'none',\n\n /**\n * meetOrSlice value, part of preserveAspectRatio (one of \"meet\", \"slice\").\n * if meet the image is always fully visibile, if slice the viewport is always filled with image.\n * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute\n * @type String\n * @default\n */\n meetOrSlice: 'meet',\n\n /**\n * Width of a stroke.\n * For image quality a stroke multiple of 2 gives better results.\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * private\n * contains last value of scaleX to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleX: 1,\n\n /**\n * private\n * contains last value of scaleY to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleY: 1,\n\n /**\n * minimum scale factor under which any resizeFilter is triggered to resize the image\n * 0 will disable the automatic resize. 1 will trigger automatically always.\n * number bigger than 1 can be used in case we want to scale with some filter above\n * the natural image dimensions\n * @type Number\n */\n minimumScaleTrigger: 0.5,\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat(\n 'alignX',\n 'alignY',\n 'meetOrSlice'),\n\n /**\n * When `true`, object is cached on an additional canvas.\n * default to false for images\n * since 1.7.0\n * @type Boolean\n * @default\n */\n objectCaching: false,\n\n /**\n * Constructor\n * @param {HTMLImageElement | String} element Image element\n * @param {Object} [options] Options object\n * @param {function} [callback] callback function to call after eventual filters applied.\n * @return {fabric.Image} thisArg\n */\n initialize: function(element, options, callback) {\n options || (options = { });\n this.filters = [];\n this.resizeFilters = [];\n this.callSuper('initialize', options);\n this._initElement(element, options, callback);\n },\n\n /**\n * Returns image element which this instance if based on\n * @return {HTMLImageElement} Image element\n */\n getElement: function() {\n return this._element;\n },\n\n /**\n * Sets image element for this instance to a specified one.\n * If filters defined they are applied to new image.\n * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n * @param {HTMLImageElement} element\n * @param {Function} [callback] Callback is invoked when all filters have been applied and new image is generated\n * @param {Object} [options] Options object\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setElement: function(element, callback, options) {\n\n var _callback, _this;\n\n this._element = element;\n this._originalElement = element;\n this._initConfig(options);\n\n if (this.resizeFilters.length === 0) {\n _callback = callback;\n }\n else {\n _this = this;\n _callback = function() {\n _this.applyFilters(callback, _this.resizeFilters, _this._filteredEl || _this._originalElement, true);\n };\n }\n\n if (this.filters.length !== 0) {\n this.applyFilters(_callback);\n }\n else if (_callback) {\n _callback(this);\n }\n\n return this;\n },\n\n /**\n * Sets crossOrigin value (on an instance and corresponding image element)\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setCrossOrigin: function(value) {\n this.crossOrigin = value;\n this._element.crossOrigin = value;\n\n return this;\n },\n\n /**\n * Returns original size of an image\n * @return {Object} Object with \"width\" and \"height\" properties\n */\n getOriginalSize: function() {\n var element = this.getElement();\n return {\n width: element.width,\n height: element.height\n };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _stroke: function(ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n var w = this.width / 2, h = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-w, -h);\n ctx.lineTo(w, -h);\n ctx.lineTo(w, h);\n ctx.lineTo(-w, h);\n ctx.lineTo(-w, -h);\n ctx.closePath();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n\n ctx.save();\n this._setStrokeStyles(ctx);\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var filters = [], resizeFilters = [],\n scaleX = 1, scaleY = 1;\n\n this.filters.forEach(function(filterObj) {\n if (filterObj) {\n if (filterObj.type === 'Resize') {\n scaleX *= filterObj.scaleX;\n scaleY *= filterObj.scaleY;\n }\n filters.push(filterObj.toObject());\n }\n });\n\n this.resizeFilters.forEach(function(filterObj) {\n filterObj && resizeFilters.push(filterObj.toObject());\n });\n var object = extend(\n this.callSuper(\n 'toObject',\n ['crossOrigin', 'alignX', 'alignY', 'meetOrSlice'].concat(propertiesToInclude)\n ), {\n src: this.getSrc(),\n filters: filters,\n resizeFilters: resizeFilters,\n });\n\n object.width /= scaleX;\n object.height /= scaleY;\n\n return object;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2,\n preserveAspectRatio = 'none', filtered = true;\n if (this.group && this.group.type === 'path-group') {\n x = this.left;\n y = this.top;\n }\n if (this.alignX !== 'none' && this.alignY !== 'none') {\n preserveAspectRatio = 'x' + this.alignX + 'Y' + this.alignY + ' ' + this.meetOrSlice;\n }\n markup.push(\n '\\n',\n ' element with actual transformation, then offsetting object to the top/left\n // so that object's center aligns with container's left/top\n '\" width=\"', this.width,\n '\" height=\"', this.height,\n '\" preserveAspectRatio=\"', preserveAspectRatio, '\"',\n '>\\n'\n );\n\n if (this.stroke || this.strokeDashArray) {\n var origFill = this.fill;\n this.fill = null;\n markup.push(\n '\\n'\n );\n this.fill = origFill;\n }\n\n markup.push('\\n');\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns source of an image\n * @param {Boolean} filtered indicates if the src is needed for svg\n * @return {String} Source of an image\n */\n getSrc: function(filtered) {\n var element = filtered ? this._element : this._originalElement;\n if (element) {\n return fabric.isLikelyNode ? element._src : element.src;\n }\n else {\n return this.src || '';\n }\n },\n\n /**\n * Sets source of an image\n * @param {String} src Source string (URL)\n * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied)\n * @param {Object} [options] Options object\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setSrc: function(src, callback, options) {\n fabric.util.loadImage(src, function(img) {\n return this.setElement(img, callback, options);\n }, this, options && options.crossOrigin);\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of an instance\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Applies filters assigned to this image (from \"filters\" array)\n * @method applyFilters\n * @param {Function} callback Callback is invoked when all filters have been applied and new image is generated\n * @param {Array} filters to be applied\n * @param {fabric.Image} imgElement image to filter ( default to this._element )\n * @param {Boolean} forResizing\n * @return {CanvasElement} canvasEl to be drawn immediately\n * @chainable\n */\n applyFilters: function(callback, filters, imgElement, forResizing) {\n\n filters = filters || this.filters;\n imgElement = imgElement || this._originalElement;\n\n if (!imgElement) {\n return;\n }\n\n var replacement = fabric.util.createImage(),\n retinaScaling = this.canvas ? this.canvas.getRetinaScaling() : fabric.devicePixelRatio,\n minimumScale = this.minimumScaleTrigger / retinaScaling,\n _this = this, scaleX, scaleY;\n\n if (filters.length === 0) {\n this._element = imgElement;\n callback && callback(this);\n return imgElement;\n }\n\n var canvasEl = fabric.util.createCanvasElement();\n canvasEl.width = imgElement.width;\n canvasEl.height = imgElement.height;\n canvasEl.getContext('2d').drawImage(imgElement, 0, 0, imgElement.width, imgElement.height);\n\n filters.forEach(function(filter) {\n if (!filter) {\n return;\n }\n if (forResizing) {\n scaleX = _this.scaleX < minimumScale ? _this.scaleX : 1;\n scaleY = _this.scaleY < minimumScale ? _this.scaleY : 1;\n if (scaleX * retinaScaling < 1) {\n scaleX *= retinaScaling;\n }\n if (scaleY * retinaScaling < 1) {\n scaleY *= retinaScaling;\n }\n }\n else {\n scaleX = filter.scaleX;\n scaleY = filter.scaleY;\n }\n filter.applyTo(canvasEl, scaleX, scaleY);\n if (!forResizing && filter.type === 'Resize') {\n _this.width *= filter.scaleX;\n _this.height *= filter.scaleY;\n }\n });\n\n /** @ignore */\n replacement.width = canvasEl.width;\n replacement.height = canvasEl.height;\n if (fabric.isLikelyNode) {\n replacement.src = canvasEl.toBuffer(undefined, fabric.Image.pngCompression);\n // onload doesn't fire in some node versions, so we invoke callback manually\n _this._element = replacement;\n !forResizing && (_this._filteredEl = replacement);\n callback && callback(_this);\n }\n else {\n replacement.onload = function() {\n _this._element = replacement;\n !forResizing && (_this._filteredEl = replacement);\n callback && callback(_this);\n replacement.onload = canvasEl = null;\n };\n replacement.src = canvasEl.toDataURL('image/png');\n }\n return canvasEl;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n var x, y, imageMargins = this._findMargins(), elementToDraw;\n\n x = (noTransform ? this.left : -this.width / 2);\n y = (noTransform ? this.top : -this.height / 2);\n\n if (this.meetOrSlice === 'slice') {\n ctx.beginPath();\n ctx.rect(x, y, this.width, this.height);\n ctx.clip();\n }\n\n if (this.isMoving === false && this.resizeFilters.length && this._needsResize()) {\n this._lastScaleX = this.scaleX;\n this._lastScaleY = this.scaleY;\n elementToDraw = this.applyFilters(null, this.resizeFilters, this._filteredEl || this._originalElement, true);\n }\n else {\n elementToDraw = this._element;\n }\n elementToDraw && ctx.drawImage(elementToDraw,\n x + imageMargins.marginX,\n y + imageMargins.marginY,\n imageMargins.width,\n imageMargins.height\n );\n\n this._stroke(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private, needed to check if image needs resize\n */\n _needsResize: function() {\n return (this.scaleX !== this._lastScaleX || this.scaleY !== this._lastScaleY);\n },\n\n /**\n * @private\n */\n _findMargins: function() {\n var width = this.width, height = this.height, scales,\n scale, marginX = 0, marginY = 0;\n\n if (this.alignX !== 'none' || this.alignY !== 'none') {\n scales = [this.width / this._element.width, this.height / this._element.height];\n scale = this.meetOrSlice === 'meet'\n ? Math.min.apply(null, scales) : Math.max.apply(null, scales);\n width = this._element.width * scale;\n height = this._element.height * scale;\n if (this.alignX === 'Mid') {\n marginX = (this.width - width) / 2;\n }\n if (this.alignX === 'Max') {\n marginX = this.width - width;\n }\n if (this.alignY === 'Mid') {\n marginY = (this.height - height) / 2;\n }\n if (this.alignY === 'Max') {\n marginY = this.height - height;\n }\n }\n return {\n width: width,\n height: height,\n marginX: marginX,\n marginY: marginY\n };\n },\n\n /**\n * @private\n */\n _resetWidthHeight: function() {\n var element = this.getElement();\n\n this.set('width', element.width);\n this.set('height', element.height);\n },\n\n /**\n * The Image class's initialization method. This method is automatically\n * called by the constructor.\n * @private\n * @param {HTMLImageElement|String} element The element representing the image\n * @param {Object} [options] Options object\n */\n _initElement: function(element, options, callback) {\n this.setElement(fabric.util.getById(element), callback, options);\n fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS);\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initConfig: function(options) {\n options || (options = { });\n this.setOptions(options);\n this._setWidthHeight(options);\n if (this._element && this.crossOrigin) {\n this._element.crossOrigin = this.crossOrigin;\n }\n },\n\n /**\n * @private\n * @param {Array} filters to be initialized\n * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created\n */\n _initFilters: function(filters, callback) {\n if (filters && filters.length) {\n fabric.util.enlivenObjects(filters, function(enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, 'fabric.Image.filters');\n }\n else {\n callback && callback();\n }\n },\n\n /**\n * @private\n * @param {Object} [options] Object with width/height properties\n */\n _setWidthHeight: function(options) {\n this.width = 'width' in options\n ? options.width\n : (this.getElement()\n ? this.getElement().width || 0\n : 0);\n\n this.height = 'height' in options\n ? options.height\n : (this.getElement()\n ? this.getElement().height || 0\n : 0);\n },\n });\n\n /**\n * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n fabric.Image.CSS_CANVAS = 'canvas-img';\n\n /**\n * Alias for getSrc\n * @static\n */\n fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;\n\n /**\n * Creates an instance of fabric.Image from its object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} callback Callback to invoke when an image instance is created\n */\n fabric.Image.fromObject = function(object, callback) {\n fabric.util.loadImage(object.src, function(img, error) {\n if (error) {\n callback && callback(null, error);\n return;\n }\n fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) {\n object.filters = filters || [];\n fabric.Image.prototype._initFilters.call(object, object.resizeFilters, function(resizeFilters) {\n object.resizeFilters = resizeFilters || [];\n return new fabric.Image(img, object, callback);\n });\n });\n }, null, object.crossOrigin);\n };\n\n /**\n * Creates an instance of fabric.Image from an URL string\n * @static\n * @param {String} url URL to create an image from\n * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument)\n * @param {Object} [imgOptions] Options object\n */\n fabric.Image.fromURL = function(url, callback, imgOptions) {\n fabric.util.loadImage(url, function(img) {\n callback && callback(new fabric.Image(img, imgOptions));\n }, null, imgOptions && imgOptions.crossOrigin);\n };\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement})\n * @static\n * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n */\n fabric.Image.ATTRIBUTE_NAMES =\n fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin'.split(' '));\n\n /**\n * Returns {@link fabric.Image} instance from an SVG element\n * @static\n * @param {SVGElement} element Element to parse\n * @param {Function} callback Callback to execute when fabric.Image object is created\n * @param {Object} [options] Options object\n * @return {fabric.Image} Instance of fabric.Image\n */\n fabric.Image.fromElement = function(element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES),\n preserveAR;\n\n if (parsedAttributes.preserveAspectRatio) {\n preserveAR = fabric.util.parsePreserveAspectRatioAttribute(parsedAttributes.preserveAspectRatio);\n extend(parsedAttributes, preserveAR);\n }\n\n fabric.Image.fromURL(parsedAttributes['xlink:href'], callback,\n extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @type Boolean\n * @default\n */\n fabric.Image.async = true;\n\n /**\n * Indicates compression level used when generating PNG under Node (in applyFilters). Any of 0-9\n * @static\n * @type Number\n * @default\n */\n fabric.Image.pngCompression = 1;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * @private\n * @return {Number} angle value\n */\n _getAngleValueForStraighten: function() {\n var angle = this.getAngle() % 360;\n if (angle > 0) {\n return Math.round((angle - 1) / 90) * 90;\n }\n return Math.round(angle / 90) * 90;\n },\n\n /**\n * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n straighten: function() {\n this.setAngle(this._getAngleValueForStraighten());\n return this;\n },\n\n /**\n * Same as {@link fabric.Object.prototype.straighten} but with animation\n * @param {Object} callbacks Object with callback functions\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Object} thisArg\n * @chainable\n */\n fxStraighten: function(callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: this.get('angle'),\n endValue: this._getAngleValueForStraighten(),\n duration: this.FX_DURATION,\n onChange: function(value) {\n _this.setAngle(value);\n onChange();\n },\n onComplete: function() {\n _this.setCoords();\n onComplete();\n },\n onStart: function() {\n _this.set('active', false);\n }\n });\n\n return this;\n }\n});\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Straightens object, then rerenders canvas\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n straightenObject: function (object) {\n object.straighten();\n this.renderAll();\n return this;\n },\n\n /**\n * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxStraightenObject: function (object) {\n object.fxStraighten({\n onChange: this.renderAll.bind(this)\n });\n return this;\n }\n});\n\n\n/**\n * @namespace fabric.Image.filters\n * @memberOf fabric.Image\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters}\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n */\nfabric.Image.filters = fabric.Image.filters || { };\n\n/**\n * Root filter class from which all filter classes inherit from\n * @class fabric.Image.filters.BaseFilter\n * @memberOf fabric.Image.filters\n */\nfabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'BaseFilter',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Sets filter's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function(options) {\n for (var prop in options) {\n this[prop] = options[prop];\n }\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return { type: this.type };\n },\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON: function() {\n // delegate, not alias\n return this.toObject();\n }\n});\n\nfabric.Image.filters.BaseFilter.fromObject = function(object, callback) {\n var filter = new fabric.Image.filters[object.type](object);\n callback && callback(filter);\n return filter;\n};\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Brightness filter class\n * @class fabric.Image.filters.Brightness\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Brightness({\n * brightness: 200\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Brightness',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Brightness.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.brightness=0] Value to brighten the image up (-255..255)\n */\n initialize: function(options) {\n options = options || { };\n this.brightness = options.brightness || 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n brightness = this.brightness;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n data[i] += brightness;\n data[i + 1] += brightness;\n data[i + 2] += brightness;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n brightness: this.brightness\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness\n */\n fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Adapted from html5rocks article\n * @class fabric.Image.filters.Convolute\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example Sharpen filter\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 0, -1, 0,\n * -1, 5, -1,\n * 0, -1, 0 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Blur filter\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Emboss filter\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Emboss filter with opaqueness\n * var filter = new fabric.Image.filters.Convolute({\n * opaque: true,\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Convolute',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Convolute.prototype\n * @param {Object} [options] Options object\n * @param {Boolean} [options.opaque=false] Opaque value (true/false)\n * @param {Array} [options.matrix] Filter matrix\n */\n initialize: function(options) {\n options = options || { };\n\n this.opaque = options.opaque;\n this.matrix = options.matrix || [\n 0, 0, 0,\n 0, 1, 0,\n 0, 0, 0\n ];\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n\n var weights = this.matrix,\n context = canvasEl.getContext('2d'),\n pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n\n side = Math.round(Math.sqrt(weights.length)),\n halfSide = Math.floor(side / 2),\n src = pixels.data,\n sw = pixels.width,\n sh = pixels.height,\n output = context.createImageData(sw, sh),\n dst = output.data,\n // go through the destination image pixels\n alphaFac = this.opaque ? 1 : 0,\n r, g, b, a, dstOff,\n scx, scy, srcOff, wt;\n\n for (var y = 0; y < sh; y++) {\n for (var x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4;\n // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n r = 0; g = 0; b = 0; a = 0;\n\n for (var cy = 0; cy < side; cy++) {\n for (var cx = 0; cx < side; cx++) {\n scy = y + cy - halfSide;\n scx = x + cx - halfSide;\n\n // eslint-disable-next-line max-depth\n if (scy < 0 || scy > sh || scx < 0 || scx > sw) {\n continue;\n }\n\n srcOff = (scy * sw + scx) * 4;\n wt = weights[cy * side + cx];\n\n r += src[srcOff] * wt;\n g += src[srcOff + 1] * wt;\n b += src[srcOff + 2] * wt;\n a += src[srcOff + 3] * wt;\n }\n }\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n dst[dstOff + 3] = a + alphaFac * (255 - a);\n }\n }\n\n context.putImageData(output, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n opaque: this.opaque,\n matrix: this.matrix\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute\n */\n fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * GradientTransparency filter class\n * @class fabric.Image.filters.GradientTransparency\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.GradientTransparency#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.GradientTransparency({\n * threshold: 200\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n // eslint-disable-next-line max-len\n filters.GradientTransparency = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.GradientTransparency.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'GradientTransparency',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.GradientTransparency.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.threshold=100] Threshold value\n */\n initialize: function(options) {\n options = options || { };\n this.threshold = options.threshold || 100;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n threshold = this.threshold,\n total = data.length;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n data[i + 3] = threshold + 255 * (total - i) / total;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n threshold: this.threshold\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.GradientTransparency} Instance of fabric.Image.filters.GradientTransparency\n */\n fabric.Image.filters.GradientTransparency.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Grayscale image filter class\n * @class fabric.Image.filters.Grayscale\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Grayscale();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Grayscale',\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Grayscale.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n len = imageData.width * imageData.height * 4,\n index = 0,\n average;\n\n while (index < len) {\n average = (data[index] + data[index + 1] + data[index + 2]) / 3;\n data[index] = average;\n data[index + 1] = average;\n data[index + 2] = average;\n index += 4;\n }\n\n context.putImageData(imageData, 0, 0);\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale\n */\n fabric.Image.filters.Grayscale.fromObject = function(object, callback) {\n object = object || { };\n object.type = 'Grayscale';\n return fabric.Image.filters.BaseFilter.fromObject(object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Invert filter class\n * @class fabric.Image.filters.Invert\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Invert();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Invert',\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Invert.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i;\n\n for (i = 0; i < iLen; i += 4) {\n data[i] = 255 - data[i];\n data[i + 1] = 255 - data[i + 1];\n data[i + 2] = 255 - data[i + 2];\n }\n\n context.putImageData(imageData, 0, 0);\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert\n */\n fabric.Image.filters.Invert.fromObject = function(object, callback) {\n object = object || { };\n object.type = 'Invert';\n return fabric.Image.filters.BaseFilter.fromObject(object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Mask filter class\n * See http://resources.aleph-1.com/mask/\n * @class fabric.Image.filters.Mask\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Mask#initialize} for constructor definition\n */\n filters.Mask = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Mask.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Mask',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Mask.prototype\n * @param {Object} [options] Options object\n * @param {fabric.Image} [options.mask] Mask image object\n * @param {Number} [options.channel=0] Rgb channel (0, 1, 2 or 3)\n */\n initialize: function(options) {\n options = options || { };\n\n this.mask = options.mask;\n this.channel = [0, 1, 2, 3].indexOf(options.channel) > -1 ? options.channel : 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n if (!this.mask) {\n return;\n }\n\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n maskEl = this.mask.getElement(),\n maskCanvasEl = fabric.util.createCanvasElement(),\n channel = this.channel,\n i,\n iLen = imageData.width * imageData.height * 4;\n\n maskCanvasEl.width = canvasEl.width;\n maskCanvasEl.height = canvasEl.height;\n\n maskCanvasEl.getContext('2d').drawImage(maskEl, 0, 0, canvasEl.width, canvasEl.height);\n\n var maskImageData = maskCanvasEl.getContext('2d').getImageData(0, 0, canvasEl.width, canvasEl.height),\n maskData = maskImageData.data;\n\n for (i = 0; i < iLen; i += 4) {\n data[i + 3] = maskData[i + channel];\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n mask: this.mask.toObject(),\n channel: this.channel\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when a mask filter instance is created\n */\n fabric.Image.filters.Mask.fromObject = function(object, callback) {\n fabric.util.loadImage(object.mask.src, function(img) {\n object.mask = new fabric.Image(img, object.mask);\n return fabric.Image.filters.BaseFilter.fromObject(object, callback);\n });\n };\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @type Boolean\n * @default\n */\n fabric.Image.filters.Mask.async = true;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Noise filter class\n * @class fabric.Image.filters.Noise\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Noise({\n * noise: 700\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Noise',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Noise.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.noise=0] Noise value\n */\n initialize: function(options) {\n options = options || { };\n this.noise = options.noise || 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n noise = this.noise, rand;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n\n rand = (0.5 - Math.random()) * noise;\n\n data[i] += rand;\n data[i + 1] += rand;\n data[i + 2] += rand;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n noise: this.noise\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise\n */\n fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Pixelate filter class\n * @class fabric.Image.filters.Pixelate\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Pixelate({\n * blocksize: 8\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Pixelate',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Pixelate.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.blocksize=4] Blocksize for pixelate\n */\n initialize: function(options) {\n options = options || { };\n this.blocksize = options.blocksize || 4;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = imageData.height,\n jLen = imageData.width,\n index, i, j, r, g, b, a;\n\n for (i = 0; i < iLen; i += this.blocksize) {\n for (j = 0; j < jLen; j += this.blocksize) {\n\n index = (i * 4) * jLen + (j * 4);\n\n r = data[index];\n g = data[index + 1];\n b = data[index + 2];\n a = data[index + 3];\n\n /*\n blocksize: 4\n\n [1,x,x,x,1]\n [x,x,x,x,1]\n [x,x,x,x,1]\n [x,x,x,x,1]\n [1,1,1,1,1]\n */\n\n for (var _i = i, _ilen = i + this.blocksize; _i < _ilen; _i++) {\n for (var _j = j, _jlen = j + this.blocksize; _j < _jlen; _j++) {\n index = (_i * 4) * jLen + (_j * 4);\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = a;\n }\n }\n }\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n blocksize: this.blocksize\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate\n */\n fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Remove white filter class\n * @class fabric.Image.filters.RemoveWhite\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.RemoveWhite#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.RemoveWhite({\n * threshold: 40,\n * distance: 140\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.RemoveWhite = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveWhite.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'RemoveWhite',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.RemoveWhite.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.threshold=30] Threshold value\n * @param {Number} [options.distance=20] Distance value\n */\n initialize: function(options) {\n options = options || { };\n this.threshold = options.threshold || 30;\n this.distance = options.distance || 20;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n threshold = this.threshold,\n distance = this.distance,\n limit = 255 - threshold,\n abs = Math.abs,\n r, g, b;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n if (r > limit &&\n g > limit &&\n b > limit &&\n abs(r - g) < distance &&\n abs(r - b) < distance &&\n abs(g - b) < distance\n ) {\n data[i + 3] = 0;\n }\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n threshold: this.threshold,\n distance: this.distance\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.RemoveWhite} Instance of fabric.Image.filters.RemoveWhite\n */\n fabric.Image.filters.RemoveWhite.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Sepia filter class\n * @class fabric.Image.filters.Sepia\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Sepia();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Sepia = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Sepia.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Sepia',\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Sepia.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i, avg;\n\n for (i = 0; i < iLen; i += 4) {\n avg = 0.3 * data[i] + 0.59 * data[i + 1] + 0.11 * data[i + 2];\n data[i] = avg + 100;\n data[i + 1] = avg + 50;\n data[i + 2] = avg + 255;\n }\n\n context.putImageData(imageData, 0, 0);\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Sepia} Instance of fabric.Image.filters.Sepia\n */\n fabric.Image.filters.Sepia.fromObject = function(object, callback) {\n object = object || { };\n object.type = 'Sepia';\n return new fabric.Image.filters.BaseFilter.fromObject(object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Sepia2 filter class\n * @class fabric.Image.filters.Sepia2\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Sepia2();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Sepia2 = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Sepia2.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Sepia2',\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Sepia.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i, r, g, b;\n\n for (i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n data[i] = (r * 0.393 + g * 0.769 + b * 0.189 ) / 1.351;\n data[i + 1] = (r * 0.349 + g * 0.686 + b * 0.168 ) / 1.203;\n data[i + 2] = (r * 0.272 + g * 0.534 + b * 0.131 ) / 2.140;\n }\n\n context.putImageData(imageData, 0, 0);\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Sepia2} Instance of fabric.Image.filters.Sepia2\n */\n fabric.Image.filters.Sepia2.fromObject = function(object, callback) {\n object = object || { };\n object.type = 'Sepia2';\n return new fabric.Image.filters.BaseFilter.fromObject(object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Tint filter class\n * Adapted from https://github.com/mezzoblue/PaintbrushJS\n * @class fabric.Image.filters.Tint\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Tint#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example Tint filter with hex color and opacity\n * var filter = new fabric.Image.filters.Tint({\n * color: '#3513B0',\n * opacity: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Tint filter with rgba color\n * var filter = new fabric.Image.filters.Tint({\n * color: 'rgba(53, 21, 176, 0.5)'\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Tint = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Tint.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Tint',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Tint.prototype\n * @param {Object} [options] Options object\n * @param {String} [options.color=#000000] Color to tint the image with\n * @param {Number} [options.opacity] Opacity value that controls the tint effect's transparency (0..1)\n */\n initialize: function(options) {\n options = options || { };\n\n this.color = options.color || '#000000';\n this.opacity = typeof options.opacity !== 'undefined'\n ? options.opacity\n : new fabric.Color(this.color).getAlpha();\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i,\n tintR, tintG, tintB,\n r, g, b, alpha1,\n source;\n\n source = new fabric.Color(this.color).getSource();\n\n tintR = source[0] * this.opacity;\n tintG = source[1] * this.opacity;\n tintB = source[2] * this.opacity;\n\n alpha1 = 1 - this.opacity;\n\n for (i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n // alpha compositing\n data[i] = tintR + r * alpha1;\n data[i + 1] = tintG + g * alpha1;\n data[i + 2] = tintB + b * alpha1;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n color: this.color,\n opacity: this.opacity\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Tint} Instance of fabric.Image.filters.Tint\n */\n fabric.Image.filters.Tint.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Multiply filter class\n * Adapted from http://www.laurenscorijn.com/articles/colormath-basics\n * @class fabric.Image.filters.Multiply\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example Multiply filter with hex color\n * var filter = new fabric.Image.filters.Multiply({\n * color: '#F0F'\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Multiply filter with rgb color\n * var filter = new fabric.Image.filters.Multiply({\n * color: 'rgb(53, 21, 176)'\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Multiply = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Multiply.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Multiply',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Multiply.prototype\n * @param {Object} [options] Options object\n * @param {String} [options.color=#000000] Color to multiply the image pixels with\n */\n initialize: function(options) {\n options = options || { };\n\n this.color = options.color || '#000000';\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i,\n source;\n\n source = new fabric.Color(this.color).getSource();\n\n for (i = 0; i < iLen; i += 4) {\n data[i] *= source[0] / 255;\n data[i + 1] *= source[1] / 255;\n data[i + 2] *= source[2] / 255;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n color: this.color\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Multiply} Instance of fabric.Image.filters.Multiply\n */\n fabric.Image.filters.Multiply.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n 'use strict';\n\n var fabric = global.fabric,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Color Blend filter class\n * @class fabric.Image.filter.Blend\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example\n * var filter = new fabric.Image.filters.Blend({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * var filter = new fabric.Image.filters.Blend({\n * image: fabricImageObject,\n * mode: 'multiply',\n * alpha: 0.5\n * });\n\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n\n filters.Blend = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ {\n type: 'Blend',\n\n initialize: function(options) {\n options = options || {};\n this.color = options.color || '#000';\n this.image = options.image || false;\n this.mode = options.mode || 'multiply';\n this.alpha = options.alpha || 1;\n },\n\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n tr, tg, tb,\n r, g, b,\n _r, _g, _b,\n source,\n isImage = false;\n\n if (this.image) {\n // Blend images\n isImage = true;\n\n var _el = fabric.util.createCanvasElement();\n _el.width = this.image.width;\n _el.height = this.image.height;\n\n var tmpCanvas = new fabric.StaticCanvas(_el);\n tmpCanvas.add(this.image);\n var context2 = tmpCanvas.getContext('2d');\n source = context2.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height).data;\n }\n else {\n // Blend color\n source = new fabric.Color(this.color).getSource();\n\n tr = source[0] * this.alpha;\n tg = source[1] * this.alpha;\n tb = source[2] * this.alpha;\n }\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n if (isImage) {\n tr = source[i] * this.alpha;\n tg = source[i + 1] * this.alpha;\n tb = source[i + 2] * this.alpha;\n }\n\n switch (this.mode) {\n case 'multiply':\n data[i] = r * tr / 255;\n data[i + 1] = g * tg / 255;\n data[i + 2] = b * tb / 255;\n break;\n case 'screen':\n data[i] = 1 - (1 - r) * (1 - tr);\n data[i + 1] = 1 - (1 - g) * (1 - tg);\n data[i + 2] = 1 - (1 - b) * (1 - tb);\n break;\n case 'add':\n data[i] = Math.min(255, r + tr);\n data[i + 1] = Math.min(255, g + tg);\n data[i + 2] = Math.min(255, b + tb);\n break;\n case 'diff':\n case 'difference':\n data[i] = Math.abs(r - tr);\n data[i + 1] = Math.abs(g - tg);\n data[i + 2] = Math.abs(b - tb);\n break;\n case 'subtract':\n _r = r - tr;\n _g = g - tg;\n _b = b - tb;\n\n data[i] = (_r < 0) ? 0 : _r;\n data[i + 1] = (_g < 0) ? 0 : _g;\n data[i + 2] = (_b < 0) ? 0 : _b;\n break;\n case 'darken':\n data[i] = Math.min(r, tr);\n data[i + 1] = Math.min(g, tg);\n data[i + 2] = Math.min(b, tb);\n break;\n case 'lighten':\n data[i] = Math.max(r, tr);\n data[i + 1] = Math.max(g, tg);\n data[i + 2] = Math.max(b, tb);\n break;\n }\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n color: this.color,\n image: this.image,\n mode: this.mode,\n alpha: this.alpha\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Blend} Instance of fabric.Image.filters.Blend\n */\n fabric.Image.filters.Blend.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor,\n sqrt = Math.sqrt, abs = Math.abs, max = Math.max, round = Math.round, sin = Math.sin,\n ceil = Math.ceil,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Resize image filter class\n * @class fabric.Image.filters.Resize\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Resize();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Resize',\n\n /**\n * Resize type\n * @param {String} resizeType\n * @default\n */\n resizeType: 'hermite',\n\n /**\n * Scale factor for resizing, x axis\n * @param {Number} scaleX\n * @default\n */\n scaleX: 0,\n\n /**\n * Scale factor for resizing, y axis\n * @param {Number} scaleY\n * @default\n */\n scaleY: 0,\n\n /**\n * LanczosLobes parameter for lanczos filter\n * @param {Number} lanczosLobes\n * @default\n */\n lanczosLobes: 3,\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Resize.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} scaleX\n * @param {Number} scaleY\n */\n applyTo: function(canvasEl, scaleX, scaleY) {\n if (scaleX === 1 && scaleY === 1) {\n return;\n }\n\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n\n var oW = canvasEl.width, oH = canvasEl.height,\n dW = round(oW * scaleX), dH = round(oH * scaleY),\n imageData;\n\n if (this.resizeType === 'sliceHack') {\n imageData = this.sliceByTwo(canvasEl, oW, oH, dW, dH);\n }\n if (this.resizeType === 'hermite') {\n imageData = this.hermiteFastResize(canvasEl, oW, oH, dW, dH);\n }\n if (this.resizeType === 'bilinear') {\n imageData = this.bilinearFiltering(canvasEl, oW, oH, dW, dH);\n }\n if (this.resizeType === 'lanczos') {\n imageData = this.lanczosResize(canvasEl, oW, oH, dW, dH);\n }\n canvasEl.width = dW;\n canvasEl.height = dH;\n canvasEl.getContext('2d').putImageData(imageData, 0, 0);\n },\n\n /**\n * Filter sliceByTwo\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n sliceByTwo: function(canvasEl, oW, oH, dW, dH) {\n var context = canvasEl.getContext('2d'), imageData,\n multW = 0.5, multH = 0.5, signW = 1, signH = 1,\n doneW = false, doneH = false, stepW = oW, stepH = oH,\n tmpCanvas = fabric.util.createCanvasElement(),\n tmpCtx = tmpCanvas.getContext('2d');\n dW = floor(dW);\n dH = floor(dH);\n tmpCanvas.width = max(dW, oW);\n tmpCanvas.height = max(dH, oH);\n\n if (dW > oW) {\n multW = 2;\n signW = -1;\n }\n if (dH > oH) {\n multH = 2;\n signH = -1;\n }\n imageData = context.getImageData(0, 0, oW, oH);\n canvasEl.width = max(dW, oW);\n canvasEl.height = max(dH, oH);\n context.putImageData(imageData, 0, 0);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n if (dW * signW < floor(stepW * multW * signW)) {\n stepW = floor(stepW * multW);\n }\n else {\n stepW = dW;\n doneW = true;\n }\n if (dH * signH < floor(stepH * multH * signH)) {\n stepH = floor(stepH * multH);\n }\n else {\n stepH = dH;\n doneH = true;\n }\n imageData = context.getImageData(0, 0, oW, oH);\n tmpCtx.putImageData(imageData, 0, 0);\n context.clearRect(0, 0, stepW, stepH);\n context.drawImage(tmpCanvas, 0, 0, oW, oH, 0, 0, stepW, stepH);\n }\n return context.getImageData(0, 0, dW, dH);\n },\n\n /**\n * Filter lanczosResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n lanczosResize: function(canvasEl, oW, oH, dW, dH) {\n\n function lanczosCreate(lobes) {\n return function(x) {\n if (x > lobes) {\n return 0;\n }\n x *= Math.PI;\n if (abs(x) < 1e-16) {\n return 1;\n }\n var xx = x / lobes;\n return sin(x) * sin(xx) / x / xx;\n };\n }\n\n function process(u) {\n var v, i, weight, idx, a, red, green,\n blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = floor(center.x);\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = floor(center.y);\n a = 0; red = 0; green = 0; blue = 0; alpha = 0;\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n fX = floor(1000 * abs(i - center.x));\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = { };\n }\n for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n fY = floor(1000 * abs(j - center.y));\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000);\n }\n weight = cacheLanc[fX][fY];\n if (weight > 0) {\n idx = (j * oW + i) * 4;\n a += weight;\n red += weight * srcData[idx];\n green += weight * srcData[idx + 1];\n blue += weight * srcData[idx + 2];\n alpha += weight * srcData[idx + 3];\n }\n }\n }\n idx = (v * dW + u) * 4;\n destData[idx] = red / a;\n destData[idx + 1] = green / a;\n destData[idx + 2] = blue / a;\n destData[idx + 3] = alpha / a;\n }\n\n if (++u < dW) {\n return process(u);\n }\n else {\n return destImg;\n }\n }\n\n var context = canvasEl.getContext('2d'),\n srcImg = context.getImageData(0, 0, oW, oH),\n destImg = context.getImageData(0, 0, dW, dH),\n srcData = srcImg.data, destData = destImg.data,\n lanczos = lanczosCreate(this.lanczosLobes),\n ratioX = this.rcpScaleX, ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY,\n range2X = ceil(ratioX * this.lanczosLobes / 2),\n range2Y = ceil(ratioY * this.lanczosLobes / 2),\n cacheLanc = { }, center = { }, icenter = { };\n\n return process(0);\n },\n\n /**\n * bilinearFiltering\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n bilinearFiltering: function(canvasEl, oW, oH, dW, dH) {\n var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl,\n color, offset = 0, origPix, ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY, context = canvasEl.getContext('2d'),\n w4 = 4 * (oW - 1), img = context.getImageData(0, 0, oW, oH),\n pixels = img.data, destImage = context.getImageData(0, 0, dW, dH),\n destPixels = destImage.data;\n for (i = 0; i < dH; i++) {\n for (j = 0; j < dW; j++) {\n x = floor(ratioX * j);\n y = floor(ratioY * i);\n xDiff = ratioX * j - x;\n yDiff = ratioY * i - y;\n origPix = 4 * (y * oW + x);\n\n for (chnl = 0; chnl < 4; chnl++) {\n a = pixels[origPix + chnl];\n b = pixels[origPix + 4 + chnl];\n c = pixels[origPix + w4 + chnl];\n d = pixels[origPix + w4 + 4 + chnl];\n color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) +\n c * yDiff * (1 - xDiff) + d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\n }\n }\n return destImage;\n },\n\n /**\n * hermiteFastResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n hermiteFastResize: function(canvasEl, oW, oH, dW, dH) {\n var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY,\n ratioWHalf = ceil(ratioW / 2),\n ratioHHalf = ceil(ratioH / 2),\n context = canvasEl.getContext('2d'),\n img = context.getImageData(0, 0, oW, oH), data = img.data,\n img2 = context.getImageData(0, 0, dW, dH), data2 = img2.data;\n for (var j = 0; j < dH; j++) {\n for (var i = 0; i < dW; i++) {\n var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0,\n gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH;\n for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n var dy = abs(centerY - (yy + 0.5)) / ratioHHalf,\n centerX = (i + 0.5) * ratioW, w0 = dy * dy;\n for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n var dx = abs(centerX - (xx + 0.5)) / ratioWHalf,\n w = sqrt(w0 + dx * dx);\n /* eslint-disable max-depth */\n if (w > 1 && w < -1) {\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n if (weight > 0) {\n dx = 4 * (xx + yy * oW);\n //alpha\n gxA += weight * data[dx + 3];\n weightsAlpha += weight;\n //colors\n if (data[dx + 3] < 255) {\n weight = weight * data[dx + 3] / 250;\n }\n gxR += weight * data[dx];\n gxG += weight * data[dx + 1];\n gxB += weight * data[dx + 2];\n weights += weight;\n }\n /* eslint-enable max-depth */\n }\n }\n data2[x2] = gxR / weights;\n data2[x2 + 1] = gxG / weights;\n data2[x2 + 2] = gxB / weights;\n data2[x2 + 3] = gxA / weightsAlpha;\n }\n }\n return img2;\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n type: this.type,\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n resizeType: this.resizeType,\n lanczosLobes: this.lanczosLobes\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize\n */\n fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Color Matrix filter class\n * @class fabric.Image.filters.ColorMatrix\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php}\n * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl}\n * @example Kodachrome filter\n * var filter = new fabric.Image.filters.ColorMatrix({\n * matrix: [\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0\n ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'ColorMatrix',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.ColorMatrix.prototype\n * @param {Object} [options] Options object\n * @param {Array} [options.matrix] Color Matrix to modify the image data with\n */\n initialize: function( options ) {\n options || ( options = {} );\n this.matrix = options.matrix || [\n 1, 0, 0, 0, 0,\n 0, 1, 0, 0, 0,\n 0, 0, 1, 0, 0,\n 0, 0, 0, 1, 0\n ];\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function( canvasEl ) {\n var context = canvasEl.getContext( '2d' ),\n imageData = context.getImageData( 0, 0, canvasEl.width, canvasEl.height ),\n data = imageData.data,\n iLen = data.length,\n i,\n r,\n g,\n b,\n a,\n m = this.matrix;\n\n for ( i = 0; i < iLen; i += 4 ) {\n r = data[ i ];\n g = data[ i + 1 ];\n b = data[ i + 2 ];\n a = data[ i + 3 ];\n\n data[ i ] = r * m[ 0 ] + g * m[ 1 ] + b * m[ 2 ] + a * m[ 3 ] + m[ 4 ];\n data[ i + 1 ] = r * m[ 5 ] + g * m[ 6 ] + b * m[ 7 ] + a * m[ 8 ] + m[ 9 ];\n data[ i + 2 ] = r * m[ 10 ] + g * m[ 11 ] + b * m[ 12 ] + a * m[ 13 ] + m[ 14 ];\n data[ i + 3 ] = r * m[ 15 ] + g * m[ 16 ] + b * m[ 17 ] + a * m[ 18 ] + m[ 19 ];\n }\n\n context.putImageData( imageData, 0, 0 );\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n type: this.type,\n matrix: this.matrix\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] function to invoke after filter creation\n * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix\n */\n fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Contrast filter class\n * @class fabric.Image.filters.Contrast\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Contrast({\n * contrast: 40\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Contrast',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Contrast.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.contrast=0] Value to contrast the image up (-255...255)\n */\n initialize: function(options) {\n options = options || { };\n this.contrast = options.contrast || 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n contrastF = 259 * (this.contrast + 255) / (255 * (259 - this.contrast));\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n data[i] = contrastF * (data[i] - 128) + 128;\n data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n contrast: this.contrast\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast\n */\n fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Saturate filter class\n * @class fabric.Image.filters.Saturate\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Saturate#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Saturate({\n * saturate: 100\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Saturate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturate.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Saturate',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Saturate.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.saturate=0] Value to saturate the image (-100...100)\n */\n initialize: function(options) {\n options = options || { };\n this.saturate = options.saturate || 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n max, adjust = -this.saturate * 0.01;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n max = Math.max(data[i], data[i + 1], data[i + 2]);\n data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n saturate: this.saturate\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Saturate} Instance of fabric.Image.filters.Saturate\n */\n fabric.Image.filters.Saturate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n toFixed = fabric.util.toFixed,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n MIN_TEXT_WIDTH = 2;\n\n if (fabric.Text) {\n fabric.warn('fabric.Text is already defined');\n return;\n }\n\n /**\n * Text class\n * @class fabric.Text\n * @extends fabric.Object\n * @return {fabric.Text} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n * @see {@link fabric.Text#initialize} for constructor definition\n */\n fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ {\n\n /**\n * Properties which when set cause object to change dimensions\n * @type Object\n * @private\n */\n _dimensionAffectingProps: [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign'\n ],\n\n /**\n * @private\n */\n _reNewline: /\\r?\\n/,\n\n /**\n * Use this regular expression to filter for whitespace that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reSpacesAndTabs: /[ \\t\\r]+/g,\n\n /**\n * Retrieves object's fontSize\n * @method getFontSize\n * @memberOf fabric.Text.prototype\n * @return {String} Font size (in pixels)\n */\n\n /**\n * Sets object's fontSize\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setFontSize\n * @memberOf fabric.Text.prototype\n * @param {Number} fontSize Font size (in pixels)\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's fontWeight\n * @method getFontWeight\n * @memberOf fabric.Text.prototype\n * @return {(String|Number)} Font weight\n */\n\n /**\n * Sets object's fontWeight\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setFontWeight\n * @memberOf fabric.Text.prototype\n * @param {(Number|String)} fontWeight Font weight\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's fontFamily\n * @method getFontFamily\n * @memberOf fabric.Text.prototype\n * @return {String} Font family\n */\n\n /**\n * Sets object's fontFamily\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setFontFamily\n * @memberOf fabric.Text.prototype\n * @param {String} fontFamily Font family\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's text\n * @method getText\n * @memberOf fabric.Text.prototype\n * @return {String} text\n */\n\n /**\n * Sets object's text\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setText\n * @memberOf fabric.Text.prototype\n * @param {String} text Text\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's textDecoration\n * @method getTextDecoration\n * @memberOf fabric.Text.prototype\n * @return {String} Text decoration\n */\n\n /**\n * Sets object's textDecoration\n * @method setTextDecoration\n * @memberOf fabric.Text.prototype\n * @param {String} textDecoration Text decoration\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's fontStyle\n * @method getFontStyle\n * @memberOf fabric.Text.prototype\n * @return {String} Font style\n */\n\n /**\n * Sets object's fontStyle\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setFontStyle\n * @memberOf fabric.Text.prototype\n * @param {String} fontStyle Font style\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's lineHeight\n * @method getLineHeight\n * @memberOf fabric.Text.prototype\n * @return {Number} Line height\n */\n\n /**\n * Sets object's lineHeight\n * @method setLineHeight\n * @memberOf fabric.Text.prototype\n * @param {Number} lineHeight Line height\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's textAlign\n * @method getTextAlign\n * @memberOf fabric.Text.prototype\n * @return {String} Text alignment\n */\n\n /**\n * Sets object's textAlign\n * @method setTextAlign\n * @memberOf fabric.Text.prototype\n * @param {String} textAlign Text alignment\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's textBackgroundColor\n * @method getTextBackgroundColor\n * @memberOf fabric.Text.prototype\n * @return {String} Text background color\n */\n\n /**\n * Sets object's textBackgroundColor\n * @method setTextBackgroundColor\n * @memberOf fabric.Text.prototype\n * @param {String} textBackgroundColor Text background color\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'text',\n\n /**\n * Font size (in pixels)\n * @type Number\n * @default\n */\n fontSize: 40,\n\n /**\n * Font weight (e.g. bold, normal, 400, 600, 800)\n * @type {(Number|String)}\n * @default\n */\n fontWeight: 'normal',\n\n /**\n * Font family\n * @type String\n * @default\n */\n fontFamily: 'Times New Roman',\n\n /**\n * Text decoration Possible values: \"\", \"underline\", \"overline\" or \"line-through\".\n * @type String\n * @default\n */\n textDecoration: '',\n\n /**\n * Text alignment. Possible values: \"left\", \"center\", \"right\" or \"justify\".\n * @type String\n * @default\n */\n textAlign: 'left',\n\n /**\n * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n * @type String\n * @default\n */\n fontStyle: '',\n\n /**\n * Line height\n * @type Number\n * @default\n */\n lineHeight: 1.16,\n\n /**\n * Background color of text lines\n * @type String\n * @default\n */\n textBackgroundColor: '',\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat(\n 'fontFamily',\n 'fontWeight',\n 'fontSize',\n 'text',\n 'textDecoration',\n 'textAlign',\n 'fontStyle',\n 'lineHeight',\n 'textBackgroundColor',\n 'charSpacing'),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * @type Array\n */\n cacheProperties: fabric.Object.prototype.cacheProperties.concat(\n 'fontFamily',\n 'fontWeight',\n 'fontSize',\n 'text',\n 'textDecoration',\n 'textAlign',\n 'fontStyle',\n 'lineHeight',\n 'textBackgroundColor',\n 'charSpacing',\n 'styles'),\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color.\n * Backwards incompatibility note: This property was named \"strokeStyle\" until v1.1.6\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property was named \"textShadow\" (String) until v1.2.11\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * @private\n */\n _fontSizeFraction: 0.25,\n\n /**\n * Text Line proportion to font Size (in pixels)\n * @type Number\n * @default\n */\n _fontSizeMult: 1.13,\n\n /**\n * additional space between characters\n * expressed in thousands of em unit\n * @type Number\n * @default\n */\n charSpacing: 0,\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Text} thisArg\n */\n initialize: function(text, options) {\n options = options || { };\n this.text = text;\n this.__skipDimension = true;\n this.callSuper('initialize', options);\n this.__skipDimension = false;\n this._initDimensions();\n this.setCoords();\n this.setupState({ propertySet: '_dimensionAffectingProps' });\n },\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @param {CanvasRenderingContext2D} [ctx] Context to render on\n * @private\n */\n _initDimensions: function(ctx) {\n if (this.__skipDimension) {\n return;\n }\n if (!ctx) {\n ctx = fabric.util.createCanvasElement().getContext('2d');\n this._setTextStyles(ctx);\n }\n this._textLines = this._splitTextIntoLines();\n this._clearCache();\n this.width = this._getTextWidth(ctx) || this.cursorWidth || MIN_TEXT_WIDTH;\n this.height = this._getTextHeight(ctx);\n this.setCoords();\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of text object\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function() {\n var dims = this.callSuper('_getCacheCanvasDimensions');\n var fontSize = this.fontSize;\n dims.width += fontSize * dims.zoomX;\n dims.height += fontSize * dims.zoomY;\n return dims;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n this._setTextStyles(ctx);\n if (this.group && this.group.type === 'path-group') {\n ctx.translate(this.left, this.top);\n }\n this._renderTextLinesBackground(ctx);\n this._renderText(ctx);\n this._renderTextDecoration(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText: function(ctx) {\n this._renderTextFill(ctx);\n this._renderTextStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setTextStyles: function(ctx) {\n ctx.textBaseline = 'alphabetic';\n ctx.font = this._getFontDeclaration();\n },\n\n /**\n * @private\n * @return {Number} Height of fabric.Text object\n */\n _getTextHeight: function() {\n return this._getHeightOfSingleLine() + (this._textLines.length - 1) * this._getHeightOfLine();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {Number} Maximum width of fabric.Text object\n */\n _getTextWidth: function(ctx) {\n var maxWidth = this._getLineWidth(ctx, 0);\n\n for (var i = 1, len = this._textLines.length; i < len; i++) {\n var currentLineWidth = this._getLineWidth(ctx, i);\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\n }\n return maxWidth;\n },\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} chars Chars to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n */\n _renderChars: function(method, ctx, chars, left, top) {\n // remove Text word from method var\n var shortM = method.slice(0, -4), _char, width;\n if (this[shortM].toLive) {\n var offsetX = -this.width / 2 + this[shortM].offsetX || 0,\n offsetY = -this.height / 2 + this[shortM].offsetY || 0;\n ctx.save();\n ctx.translate(offsetX, offsetY);\n left -= offsetX;\n top -= offsetY;\n }\n if (this.charSpacing !== 0) {\n var additionalSpace = this._getWidthOfCharSpacing();\n chars = chars.split('');\n for (var i = 0, len = chars.length; i < len; i++) {\n _char = chars[i];\n width = ctx.measureText(_char).width + additionalSpace;\n ctx[method](_char, left, top);\n left += width > 0 ? width : 0;\n }\n }\n else {\n ctx[method](chars, left, top);\n }\n this[shortM].toLive && ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Text to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n * @param {Number} lineIndex Index of a line in a text\n */\n _renderTextLine: function(method, ctx, line, left, top, lineIndex) {\n // lift the line by quarter of fontSize\n top -= this.fontSize * this._fontSizeFraction;\n\n // short-circuit\n var lineWidth = this._getLineWidth(ctx, lineIndex);\n if (this.textAlign !== 'justify' || this.width < lineWidth) {\n this._renderChars(method, ctx, line, left, top, lineIndex);\n return;\n }\n\n // stretch the line\n var words = line.split(/\\s+/),\n charOffset = 0,\n wordsWidth = this._getWidthOfWords(ctx, words.join(' '), lineIndex, 0),\n widthDiff = this.width - wordsWidth,\n numSpaces = words.length - 1,\n spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0,\n leftOffset = 0, word;\n\n for (var i = 0, len = words.length; i < len; i++) {\n while (line[charOffset] === ' ' && charOffset < line.length) {\n charOffset++;\n }\n word = words[i];\n this._renderChars(method, ctx, word, left + leftOffset, top, lineIndex, charOffset);\n leftOffset += this._getWidthOfWords(ctx, word, lineIndex, charOffset) + spaceWidth;\n charOffset += word.length;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} word\n */\n _getWidthOfWords: function (ctx, word) {\n var width = ctx.measureText(word).width, charCount, additionalSpace;\n if (this.charSpacing !== 0) {\n charCount = word.split('').length;\n additionalSpace = charCount * this._getWidthOfCharSpacing();\n width += additionalSpace;\n }\n return width > 0 ? width : 0;\n },\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset: function() {\n return -this.width / 2;\n },\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset: function() {\n return -this.height / 2;\n },\n\n /**\n * Returns true because text has no style\n */\n isEmptyStyles: function() {\n return true;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n */\n _renderTextCommon: function(ctx, method) {\n\n var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset();\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n var heightOfLine = this._getHeightOfLine(ctx, i),\n maxHeight = heightOfLine / this.lineHeight,\n lineWidth = this._getLineWidth(ctx, i),\n leftOffset = this._getLineLeftOffset(lineWidth);\n this._renderTextLine(\n method,\n ctx,\n this._textLines[i],\n left + leftOffset,\n top + lineHeights + maxHeight,\n i\n );\n lineHeights += heightOfLine;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill: function(ctx) {\n if (!this.fill && this.isEmptyStyles()) {\n return;\n }\n\n this._renderTextCommon(ctx, 'fillText');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextStroke: function(ctx) {\n if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray);\n ctx.beginPath();\n this._renderTextCommon(ctx, 'strokeText');\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * @private\n * @return {Number} height of line\n */\n _getHeightOfLine: function() {\n return this._getHeightOfSingleLine() * this.lineHeight;\n },\n\n /**\n * @private\n * @return {Number} height of line without lineHeight\n */\n _getHeightOfSingleLine: function() {\n return this.fontSize * this._fontSizeMult;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground: function(ctx) {\n if (!this.textBackgroundColor) {\n return;\n }\n var lineTopOffset = 0, heightOfLine,\n lineWidth, lineLeftOffset, originalFill = ctx.fillStyle;\n\n ctx.fillStyle = this.textBackgroundColor;\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this._getHeightOfLine(ctx, i);\n lineWidth = this._getLineWidth(ctx, i);\n if (lineWidth > 0) {\n lineLeftOffset = this._getLineLeftOffset(lineWidth);\n ctx.fillRect(\n this._getLeftOffset() + lineLeftOffset,\n this._getTopOffset() + lineTopOffset,\n lineWidth,\n heightOfLine / this.lineHeight\n );\n }\n lineTopOffset += heightOfLine;\n }\n ctx.fillStyle = originalFill;\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {Number} lineWidth Width of text line\n * @return {Number} Line left offset\n */\n _getLineLeftOffset: function(lineWidth) {\n if (this.textAlign === 'center') {\n return (this.width - lineWidth) / 2;\n }\n if (this.textAlign === 'right') {\n return this.width - lineWidth;\n }\n return 0;\n },\n\n /**\n * @private\n */\n _clearCache: function() {\n this.__lineWidths = [];\n this.__lineHeights = [];\n },\n\n /**\n * @private\n */\n _shouldClearDimensionCache: function() {\n var shouldClear = this._forceClearCache;\n shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps'));\n if (shouldClear) {\n this.saveState({ propertySet: '_dimensionAffectingProps' });\n this.dirty = true;\n }\n return shouldClear;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n _getLineWidth: function(ctx, lineIndex) {\n if (this.__lineWidths[lineIndex]) {\n return this.__lineWidths[lineIndex] === -1 ? this.width : this.__lineWidths[lineIndex];\n }\n\n var width, wordCount, line = this._textLines[lineIndex];\n\n if (line === '') {\n width = 0;\n }\n else {\n width = this._measureLine(ctx, lineIndex);\n }\n this.__lineWidths[lineIndex] = width;\n\n if (width && this.textAlign === 'justify') {\n wordCount = line.split(/\\s+/);\n if (wordCount.length > 1) {\n this.__lineWidths[lineIndex] = -1;\n }\n }\n return width;\n },\n\n _getWidthOfCharSpacing: function() {\n if (this.charSpacing !== 0) {\n return this.fontSize * this.charSpacing / 1000;\n }\n return 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n _measureLine: function(ctx, lineIndex) {\n var line = this._textLines[lineIndex],\n width = ctx.measureText(line).width,\n additionalSpace = 0, charCount, finalWidth;\n if (this.charSpacing !== 0) {\n charCount = line.split('').length;\n additionalSpace = (charCount - 1) * this._getWidthOfCharSpacing();\n }\n finalWidth = width + additionalSpace;\n return finalWidth > 0 ? finalWidth : 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration: function(ctx) {\n if (!this.textDecoration) {\n return;\n }\n var halfOfVerticalBox = this.height / 2,\n _this = this, offsets = [];\n\n /** @ignore */\n function renderLinesAtOffset(offsets) {\n var i, lineHeight = 0, len, j, oLen, lineWidth,\n lineLeftOffset, heightOfLine;\n\n for (i = 0, len = _this._textLines.length; i < len; i++) {\n\n lineWidth = _this._getLineWidth(ctx, i);\n lineLeftOffset = _this._getLineLeftOffset(lineWidth);\n heightOfLine = _this._getHeightOfLine(ctx, i);\n\n for (j = 0, oLen = offsets.length; j < oLen; j++) {\n ctx.fillRect(\n _this._getLeftOffset() + lineLeftOffset,\n lineHeight + (_this._fontSizeMult - 1 + offsets[j] ) * _this.fontSize - halfOfVerticalBox,\n lineWidth,\n _this.fontSize / 15);\n }\n lineHeight += heightOfLine;\n }\n }\n\n if (this.textDecoration.indexOf('underline') > -1) {\n offsets.push(0.85); // 1 - 3/16\n }\n if (this.textDecoration.indexOf('line-through') > -1) {\n offsets.push(0.43);\n }\n if (this.textDecoration.indexOf('overline') > -1) {\n offsets.push(-0.12);\n }\n if (offsets.length > 0) {\n renderLinesAtOffset(offsets);\n }\n },\n\n /**\n * return font declaration string for canvas context\n * @returns {String} font declaration formatted for canvas context.\n */\n _getFontDeclaration: function() {\n return [\n // node-canvas needs \"weight style\", while browsers need \"style weight\"\n (fabric.isLikelyNode ? this.fontWeight : this.fontStyle),\n (fabric.isLikelyNode ? this.fontStyle : this.fontWeight),\n this.fontSize + 'px',\n (fabric.isLikelyNode ? ('\"' + this.fontFamily + '\"') : this.fontFamily)\n ].join(' ');\n },\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n render: function(ctx, noTransform) {\n // do not render if object is not visible\n if (!this.visible) {\n return;\n }\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n if (this._shouldClearDimensionCache()) {\n this._setTextStyles(ctx);\n this._initDimensions(ctx);\n }\n this.callSuper('render', ctx, noTransform);\n },\n\n /**\n * Returns the text as an array of lines.\n * @returns {Array} Lines in the text\n */\n _splitTextIntoLines: function() {\n return this.text.split(this._reNewline);\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var additionalProperties = [\n 'text',\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n 'lineHeight',\n 'textDecoration',\n 'textAlign',\n 'textBackgroundColor',\n 'charSpacing'\n ].concat(propertiesToInclude);\n return this.callSuper('toObject', additionalProperties);\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n if (!this.ctx) {\n this.ctx = fabric.util.createCanvasElement().getContext('2d');\n }\n var markup = this._createBaseSVGMarkup(),\n offsets = this._getSVGLeftTopOffsets(this.ctx),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n this._wrapSVGTextAndBg(markup, textAndBg);\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n\n /**\n * @private\n */\n _getSVGLeftTopOffsets: function(ctx) {\n var lineTop = this._getHeightOfLine(ctx, 0),\n textLeft = -this.width / 2,\n textTop = 0;\n\n return {\n textLeft: textLeft + (this.group && this.group.type === 'path-group' ? this.left : 0),\n textTop: textTop + (this.group && this.group.type === 'path-group' ? -this.top : 0),\n lineTop: lineTop\n };\n },\n\n /**\n * @private\n */\n _wrapSVGTextAndBg: function(markup, textAndBg) {\n var noShadow = true, filter = this.getSvgFilter(),\n style = filter === '' ? '' : ' style=\"' + filter + '\"';\n\n markup.push(\n '\\t\\n',\n textAndBg.textBgRects.join(''),\n '\\t\\t\\n',\n textAndBg.textSpans.join(''),\n '\\t\\t\\n',\n '\\t\\n'\n );\n },\n\n getSvgStyles: function(skipShadow) {\n var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow);\n return svgStyle + ' white-space: pre;';\n },\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n _getSVGTextAndBg: function(textTopOffset, textLeftOffset) {\n var textSpans = [],\n textBgRects = [],\n height = 0;\n // bounding-box background\n this._setSVGBg(textBgRects);\n\n // text and text-background\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n if (this.textBackgroundColor) {\n this._setSVGTextLineBg(textBgRects, i, textLeftOffset, textTopOffset, height);\n }\n this._setSVGTextLineText(i, textSpans, height, textLeftOffset, textTopOffset, textBgRects);\n height += this._getHeightOfLine(this.ctx, i);\n }\n\n return {\n textSpans: textSpans,\n textBgRects: textBgRects\n };\n },\n\n _setSVGTextLineText: function(i, textSpans, height, textLeftOffset, textTopOffset) {\n var yPos = this.fontSize * (this._fontSizeMult - this._fontSizeFraction)\n - textTopOffset + height - this.height / 2;\n if (this.textAlign === 'justify') {\n // i call from here to do not intefere with IText\n this._setSVGTextLineJustifed(i, textSpans, yPos, textLeftOffset);\n return;\n }\n textSpans.push(\n '\\t\\t\\t elements since setting opacity\n // on containing one doesn't work in Illustrator\n this._getFillAttributes(this.fill), '>',\n fabric.util.string.escapeXml(this._textLines[i]),\n '\\n'\n );\n },\n\n _setSVGTextLineJustifed: function(i, textSpans, yPos, textLeftOffset) {\n var ctx = fabric.util.createCanvasElement().getContext('2d');\n\n this._setTextStyles(ctx);\n\n var line = this._textLines[i],\n words = line.split(/\\s+/),\n wordsWidth = this._getWidthOfWords(ctx, words.join('')),\n widthDiff = this.width - wordsWidth,\n numSpaces = words.length - 1,\n spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0,\n word, attributes = this._getFillAttributes(this.fill),\n len;\n\n textLeftOffset += this._getLineLeftOffset(this._getLineWidth(ctx, i));\n\n for (i = 0, len = words.length; i < len; i++) {\n word = words[i];\n textSpans.push(\n '\\t\\t\\t elements since setting opacity\n // on containing one doesn't work in Illustrator\n attributes, '>',\n fabric.util.string.escapeXml(word),\n '\\n'\n );\n textLeftOffset += this._getWidthOfWords(ctx, word) + spaceWidth;\n }\n },\n\n _setSVGTextLineBg: function(textBgRects, i, textLeftOffset, textTopOffset, height) {\n textBgRects.push(\n '\\t\\t\\n');\n },\n\n _setSVGBg: function(textBgRects) {\n if (this.backgroundColor) {\n textBgRects.push(\n '\\t\\t\\n');\n }\n },\n\n /**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n *\n * @private\n * @param {*} value\n * @return {String}\n */\n _getFillAttributes: function(value) {\n var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : '';\n if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {\n return 'fill=\"' + value + '\"';\n }\n return 'opacity=\"' + fillColor.getAlpha() + '\" fill=\"' + fillColor.setAlpha(1).toRgb() + '\"';\n },\n /* _TO_SVG_END_ */\n\n /**\n * Sets specified property to a specified value\n * @param {String} key\n * @param {*} value\n * @return {fabric.Text} thisArg\n * @chainable\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n\n if (this._dimensionAffectingProps.indexOf(key) > -1) {\n this._initDimensions();\n this.setCoords();\n }\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity: function() {\n return 1;\n }\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement})\n * @static\n * @memberOf fabric.Text\n * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n */\n fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(\n 'x y dx dy font-family font-style font-weight font-size text-decoration text-anchor'.split(' '));\n\n /**\n * Default SVG font size\n * @static\n * @memberOf fabric.Text\n */\n fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;\n\n /**\n * Returns fabric.Text instance from an SVG element (not yet implemented)\n * @static\n * @memberOf fabric.Text\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Text} Instance of fabric.Text\n */\n fabric.Text.fromElement = function(element, options) {\n if (!element) {\n return null;\n }\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES);\n options = fabric.util.object.extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes);\n\n options.top = options.top || 0;\n options.left = options.left || 0;\n if ('dx' in parsedAttributes) {\n options.left += parsedAttributes.dx;\n }\n if ('dy' in parsedAttributes) {\n options.top += parsedAttributes.dy;\n }\n if (!('fontSize' in options)) {\n options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n\n if (!options.originX) {\n options.originX = 'left';\n }\n\n var textContent = '';\n\n // The XML is not properly parsed in IE9 so a workaround to get\n // textContent is through firstChild.data. Another workaround would be\n // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does)\n if (!('textContent' in element)) {\n if ('firstChild' in element && element.firstChild !== null) {\n if ('data' in element.firstChild && element.firstChild.data !== null) {\n textContent = element.firstChild.data;\n }\n }\n }\n else {\n textContent = element.textContent;\n }\n\n textContent = textContent.replace(/^\\s+|\\s+$|\\n+/g, '').replace(/\\s+/g, ' ');\n\n var text = new fabric.Text(textContent, options),\n textHeightScaleFactor = text.getHeight() / text.height,\n lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height,\n scaledDiff = lineHeightDiff * textHeightScaleFactor,\n textHeight = text.getHeight() + scaledDiff,\n offX = 0;\n /*\n Adjust positioning:\n x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n top/left properties in Fabric correspond to center point of text bounding box\n */\n if (text.originX === 'left') {\n offX = text.getWidth() / 2;\n }\n if (text.originX === 'right') {\n offX = -text.getWidth() / 2;\n }\n text.set({\n left: text.getLeft() + offX,\n top: text.getTop() - textHeight / 2 + text.fontSize * (0.18 + text._fontSizeFraction) / text.lineHeight /* 0.3 is the old lineHeight */\n });\n\n return text;\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Text instance from an object representation\n * @static\n * @memberOf fabric.Text\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Text} Instance of fabric.Text\n */\n fabric.Text.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Text', object, callback, forceAsync, 'text');\n };\n\n fabric.util.createAccessors(fabric.Text);\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var clone = fabric.util.object.clone;\n\n /**\n * IText class (introduced in v1.4) Events are also fired with \"text:\"\n * prefix when observing canvas.\n * @class fabric.IText\n * @extends fabric.Text\n * @mixes fabric.Observable\n *\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n *\n * @return {fabric.IText} thisArg\n * @see {@link fabric.IText#initialize} for constructor definition\n *\n *

Supported key combinations:

\n *
\n   *   Move cursor:                    left, right, up, down\n   *   Select character:               shift + left, shift + right\n   *   Select text vertically:         shift + up, shift + down\n   *   Move cursor by word:            alt + left, alt + right\n   *   Select words:                   shift + alt + left, shift + alt + right\n   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end\n   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end\n   *   Jump to start/end of text:      cmd + up, cmd + down\n   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n   *   Delete character:               backspace\n   *   Delete word:                    alt + backspace\n   *   Delete line:                    cmd + backspace\n   *   Forward delete:                 delete\n   *   Copy text:                      ctrl/cmd + c\n   *   Paste text:                     ctrl/cmd + v\n   *   Cut text:                       ctrl/cmd + x\n   *   Select entire text:             ctrl/cmd + a\n   *   Quit editing                    tab or esc\n   * 
\n *\n *

Supported mouse/touch combination

\n *
\n   *   Position cursor:                click/touch\n   *   Create selection:               click/touch & drag\n   *   Create selection:               click & shift + click\n   *   Select word:                    double click\n   *   Select line:                    triple click\n   * 
\n */\n fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'i-text',\n\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n selectionStart: 0,\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n selectionEnd: 0,\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(17,119,255,0.3)',\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n isEditing: false,\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n editable: true,\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n editingBorderColor: 'rgba(102,153,255,0.25)',\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n cursorWidth: 2,\n\n /**\n * Color of default cursor (when not overwritten by character style)\n * @type String\n * @default\n */\n cursorColor: '#333',\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n cursorDelay: 1000,\n\n /**\n * Duration of cursor fadein (in ms)\n * @type Number\n * @default\n */\n cursorDuration: 600,\n\n /**\n * Object containing character styles\n * (where top-level properties corresponds to line number and 2nd-level properties -- to char number in a line)\n * @type Object\n * @default\n */\n styles: null,\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n caching: true,\n\n /**\n * @private\n */\n _reSpace: /\\s|\\n/,\n\n /**\n * @private\n */\n _currentCursorOpacity: 0,\n\n /**\n * @private\n */\n _selectionDirection: null,\n\n /**\n * @private\n */\n _abortCursorAnimation: false,\n\n /**\n * @private\n */\n __widthOfSpace: [],\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.IText} thisArg\n */\n initialize: function(text, options) {\n this.styles = options ? (options.styles || { }) : { };\n this.callSuper('initialize', text, options);\n this.initBehavior();\n },\n\n /**\n * @private\n */\n _clearCache: function() {\n this.callSuper('_clearCache');\n this.__widthOfSpace = [];\n },\n\n /**\n * Returns true if object has no styling\n */\n isEmptyStyles: function() {\n if (!this.styles) {\n return true;\n }\n var obj = this.styles;\n\n for (var p1 in obj) {\n for (var p2 in obj[p1]) {\n // eslint-disable-next-line no-unused-vars\n for (var p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n return true;\n },\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart: function(index) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n },\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd: function(index) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n },\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n _updateAndFire: function(property, index) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n },\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged: function() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n },\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at\n * @return {Object} styles Style object at a specified (or current) index\n */\n getSelectionStyles: function(startIndex, endIndex) {\n\n if (arguments.length === 2) {\n var styles = [];\n for (var i = startIndex; i < endIndex; i++) {\n styles.push(this.getSelectionStyles(i));\n }\n return styles;\n }\n\n var loc = this.get2DCursorLocation(startIndex),\n style = this._getStyleDeclaration(loc.lineIndex, loc.charIndex);\n\n return style || {};\n },\n\n /**\n * Sets style of a current selection\n * @param {Object} [styles] Styles object\n * @return {fabric.IText} thisArg\n * @chainable\n */\n setSelectionStyles: function(styles) {\n if (this.selectionStart === this.selectionEnd) {\n this._extendStyles(this.selectionStart, styles);\n }\n else {\n for (var i = this.selectionStart; i < this.selectionEnd; i++) {\n this._extendStyles(i, styles);\n }\n }\n /* not included in _extendStyles to avoid clearing cache more than once */\n this._forceClearCache = true;\n return this;\n },\n\n /**\n * @private\n */\n _extendStyles: function(index, styles) {\n var loc = this.get2DCursorLocation(index);\n\n if (!this._getLineStyle(loc.lineIndex)) {\n this._setLineStyle(loc.lineIndex, {});\n }\n\n if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) {\n this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {});\n }\n\n fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles);\n },\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @param {CanvasRenderingContext2D} [ctx] Context to render on\n * @private\n */\n _initDimensions: function(ctx) {\n if (!ctx) {\n this.clearContextTop();\n }\n this.callSuper('_initDimensions', ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n render: function(ctx, noTransform) {\n this.clearContextTop();\n this.callSuper('render', ctx, noTransform);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = { };\n this.renderCursorOrSelection();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n this.callSuper('_render', ctx);\n this.ctx = ctx;\n },\n\n /**\n * Prepare and clean the contextTop\n */\n clearContextTop: function() {\n if (!this.active || !this.isEditing) {\n return;\n }\n if (this.canvas && this.canvas.contextTop) {\n var ctx = this.canvas.contextTop;\n ctx.save();\n ctx.transform.apply(ctx, this.canvas.viewportTransform);\n this.transform(ctx);\n this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix);\n this._clearTextArea(ctx);\n ctx.restore();\n }\n },\n\n /**\n * Renders cursor or selection (depending on what exists)\n */\n renderCursorOrSelection: function() {\n if (!this.active || !this.isEditing) {\n return;\n }\n var chars = this.text.split(''),\n boundaries, ctx;\n if (this.canvas && this.canvas.contextTop) {\n ctx = this.canvas.contextTop;\n ctx.save();\n ctx.transform.apply(ctx, this.canvas.viewportTransform);\n this.transform(ctx);\n this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix);\n this._clearTextArea(ctx);\n }\n else {\n ctx = this.ctx;\n ctx.save();\n }\n if (this.selectionStart === this.selectionEnd) {\n boundaries = this._getCursorBoundaries(chars, 'cursor');\n this.renderCursor(boundaries, ctx);\n }\n else {\n boundaries = this._getCursorBoundaries(chars, 'selection');\n this.renderSelection(chars, boundaries, ctx);\n }\n ctx.restore();\n },\n\n _clearTextArea: function(ctx) {\n // we add 4 pixel, to be sure to do not leave any pixel out\n var width = this.width + 4, height = this.height + 4;\n ctx.clearRect(-width / 2, -height / 2, width, height);\n },\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n */\n get2DCursorLocation: function(selectionStart) {\n if (typeof selectionStart === 'undefined') {\n selectionStart = this.selectionStart;\n }\n var len = this._textLines.length;\n for (var i = 0; i < len; i++) {\n if (selectionStart <= this._textLines[i].length) {\n return {\n lineIndex: i,\n charIndex: selectionStart\n };\n }\n selectionStart -= this._textLines[i].length + 1;\n }\n return {\n lineIndex: i - 1,\n charIndex: this._textLines[i - 1].length < selectionStart ? this._textLines[i - 1].length : selectionStart\n };\n },\n\n /**\n * Returns complete style of char at the current cursor\n * @param {Number} lineIndex Line index\n * @param {Number} charIndex Char index\n * @return {Object} Character style\n */\n getCurrentCharStyle: function(lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1);\n\n return {\n fontSize: style && style.fontSize || this.fontSize,\n fill: style && style.fill || this.fill,\n textBackgroundColor: style && style.textBackgroundColor || this.textBackgroundColor,\n textDecoration: style && style.textDecoration || this.textDecoration,\n fontFamily: style && style.fontFamily || this.fontFamily,\n fontWeight: style && style.fontWeight || this.fontWeight,\n fontStyle: style && style.fontStyle || this.fontStyle,\n stroke: style && style.stroke || this.stroke,\n strokeWidth: style && style.strokeWidth || this.strokeWidth\n };\n },\n\n /**\n * Returns fontSize of char at the current cursor\n * @param {Number} lineIndex Line index\n * @param {Number} charIndex Char index\n * @return {Number} Character font size\n */\n getCurrentCharFontSize: function(lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1);\n return style && style.fontSize ? style.fontSize : this.fontSize;\n },\n\n /**\n * Returns color (fill) of char at the current cursor\n * @param {Number} lineIndex Line index\n * @param {Number} charIndex Char index\n * @return {String} Character color (fill)\n */\n getCurrentCharColor: function(lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1);\n return style && style.fill ? style.fill : this.cursorColor;\n },\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * @private\n * @param {Array} chars Array of characters\n * @param {String} typeOfBoundaries\n */\n _getCursorBoundaries: function(chars, typeOfBoundaries) {\n\n // left/top are left/top of entire text box\n // leftOffset/topOffset are offset from that left/top point of a text box\n\n var left = Math.round(this._getLeftOffset()),\n top = this._getTopOffset(),\n\n offsets = this._getCursorBoundariesOffsets(\n chars, typeOfBoundaries);\n\n return {\n left: left,\n top: top,\n leftOffset: offsets.left + offsets.lineLeft,\n topOffset: offsets.top\n };\n },\n\n /**\n * @private\n */\n _getCursorBoundariesOffsets: function(chars, typeOfBoundaries) {\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache;\n }\n var lineLeftOffset = 0,\n lineIndex = 0,\n charIndex = 0,\n topOffset = 0,\n leftOffset = 0,\n boundaries;\n\n for (var i = 0; i < this.selectionStart; i++) {\n if (chars[i] === '\\n') {\n leftOffset = 0;\n topOffset += this._getHeightOfLine(this.ctx, lineIndex);\n\n lineIndex++;\n charIndex = 0;\n }\n else {\n leftOffset += this._getWidthOfChar(this.ctx, chars[i], lineIndex, charIndex);\n charIndex++;\n }\n\n lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex));\n }\n if (typeOfBoundaries === 'cursor') {\n topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, lineIndex) / this.lineHeight\n - this.getCurrentCharFontSize(lineIndex, charIndex) * (1 - this._fontSizeFraction);\n }\n if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n boundaries = {\n top: topOffset,\n left: leftOffset > 0 ? leftOffset : 0,\n lineLeft: lineLeftOffset\n };\n this.cursorOffsetCache = boundaries;\n return this.cursorOffsetCache;\n },\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor: function(boundaries, ctx) {\n\n var cursorLocation = this.get2DCursorLocation(),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight = this.getCurrentCharFontSize(lineIndex, charIndex),\n leftOffset = boundaries.leftOffset,\n multiplier = this.scaleX * this.canvas.getZoom(),\n cursorWidth = this.cursorWidth / multiplier;\n\n ctx.fillStyle = this.getCurrentCharColor(lineIndex, charIndex);\n ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;\n\n ctx.fillRect(\n boundaries.left + leftOffset - cursorWidth / 2,\n boundaries.top + boundaries.topOffset,\n cursorWidth,\n charHeight);\n },\n\n /**\n * Renders text selection\n * @param {Array} chars Array of characters\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection: function(chars, boundaries, ctx) {\n\n ctx.fillStyle = this.selectionColor;\n\n var start = this.get2DCursorLocation(this.selectionStart),\n end = this.get2DCursorLocation(this.selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex;\n for (var i = startLine; i <= endLine; i++) {\n var lineOffset = this._getLineLeftOffset(this._getLineWidth(ctx, i)) || 0,\n lineHeight = this._getHeightOfLine(this.ctx, i),\n realLineHeight = 0, boxWidth = 0, line = this._textLines[i];\n\n if (i === startLine) {\n for (var j = 0, len = line.length; j < len; j++) {\n if (j >= start.charIndex && (i !== endLine || j < end.charIndex)) {\n boxWidth += this._getWidthOfChar(ctx, line[j], i, j);\n }\n if (j < start.charIndex) {\n lineOffset += this._getWidthOfChar(ctx, line[j], i, j);\n }\n }\n if (j === line.length) {\n boxWidth -= this._getWidthOfCharSpacing();\n }\n }\n else if (i > startLine && i < endLine) {\n boxWidth += this._getLineWidth(ctx, i) || 5;\n }\n else if (i === endLine) {\n for (var j2 = 0, j2len = end.charIndex; j2 < j2len; j2++) {\n boxWidth += this._getWidthOfChar(ctx, line[j2], i, j2);\n }\n if (end.charIndex === line.length) {\n boxWidth -= this._getWidthOfCharSpacing();\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n ctx.fillRect(\n boundaries.left + lineOffset,\n boundaries.top + boundaries.topOffset,\n boxWidth > 0 ? boxWidth : 0,\n lineHeight);\n\n boundaries.topOffset += realLineHeight;\n }\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Content of the line\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n * @param {Number} charOffset\n */\n _renderChars: function(method, ctx, line, left, top, lineIndex, charOffset) {\n\n if (this.isEmptyStyles()) {\n return this._renderCharsFast(method, ctx, line, left, top);\n }\n\n charOffset = charOffset || 0;\n\n // set proper line offset\n var lineHeight = this._getHeightOfLine(ctx, lineIndex),\n prevStyle,\n thisStyle,\n charsToRender = '';\n\n ctx.save();\n top -= lineHeight / this.lineHeight * this._fontSizeFraction;\n for (var i = charOffset, len = line.length + charOffset; i <= len; i++) {\n prevStyle = prevStyle || this.getCurrentCharStyle(lineIndex, i);\n thisStyle = this.getCurrentCharStyle(lineIndex, i + 1);\n\n if (this._hasStyleChanged(prevStyle, thisStyle) || i === len) {\n this._renderChar(method, ctx, lineIndex, i - 1, charsToRender, left, top, lineHeight);\n charsToRender = '';\n prevStyle = thisStyle;\n }\n charsToRender += line[i - charOffset];\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Content of the line\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n */\n _renderCharsFast: function(method, ctx, line, left, top) {\n\n if (method === 'fillText' && this.fill) {\n this.callSuper('_renderChars', method, ctx, line, left, top);\n }\n if (method === 'strokeText' && ((this.stroke && this.strokeWidth > 0) || this.skipFillStrokeCheck)) {\n this.callSuper('_renderChars', method, ctx, line, left, top);\n }\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} i\n * @param {String} _char\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n * @param {Number} lineHeight Height of the line\n */\n _renderChar: function(method, ctx, lineIndex, i, _char, left, top, lineHeight) {\n var charWidth, charHeight, shouldFill, shouldStroke,\n decl = this._getStyleDeclaration(lineIndex, i),\n offset, textDecoration, chars, additionalSpace, _charWidth;\n\n if (decl) {\n charHeight = this._getHeightOfChar(ctx, _char, lineIndex, i);\n shouldStroke = decl.stroke;\n shouldFill = decl.fill;\n textDecoration = decl.textDecoration;\n }\n else {\n charHeight = this.fontSize;\n }\n\n shouldStroke = (shouldStroke || this.stroke) && method === 'strokeText';\n shouldFill = (shouldFill || this.fill) && method === 'fillText';\n\n decl && ctx.save();\n\n charWidth = this._applyCharStylesGetWidth(ctx, _char, lineIndex, i, decl || null);\n textDecoration = textDecoration || this.textDecoration;\n\n if (decl && decl.textBackgroundColor) {\n this._removeShadow(ctx);\n }\n if (this.charSpacing !== 0) {\n additionalSpace = this._getWidthOfCharSpacing();\n chars = _char.split('');\n charWidth = 0;\n for (var j = 0, len = chars.length, jChar; j < len; j++) {\n jChar = chars[j];\n shouldFill && ctx.fillText(jChar, left + charWidth, top);\n shouldStroke && ctx.strokeText(jChar, left + charWidth, top);\n _charWidth = ctx.measureText(jChar).width + additionalSpace;\n charWidth += _charWidth > 0 ? _charWidth : 0;\n }\n }\n else {\n shouldFill && ctx.fillText(_char, left, top);\n shouldStroke && ctx.strokeText(_char, left, top);\n }\n\n if (textDecoration || textDecoration !== '') {\n offset = this._fontSizeFraction * lineHeight / this.lineHeight;\n this._renderCharDecoration(ctx, textDecoration, left, top, offset, charWidth, charHeight);\n }\n\n decl && ctx.restore();\n ctx.translate(charWidth, 0);\n },\n\n /**\n * @private\n * @param {Object} prevStyle\n * @param {Object} thisStyle\n */\n _hasStyleChanged: function(prevStyle, thisStyle) {\n return (prevStyle.fill !== thisStyle.fill ||\n prevStyle.fontSize !== thisStyle.fontSize ||\n prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor ||\n prevStyle.textDecoration !== thisStyle.textDecoration ||\n prevStyle.fontFamily !== thisStyle.fontFamily ||\n prevStyle.fontWeight !== thisStyle.fontWeight ||\n prevStyle.fontStyle !== thisStyle.fontStyle ||\n prevStyle.stroke !== thisStyle.stroke ||\n prevStyle.strokeWidth !== thisStyle.strokeWidth\n );\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderCharDecoration: function(ctx, textDecoration, left, top, offset, charWidth, charHeight) {\n\n if (!textDecoration) {\n return;\n }\n\n var decorationWeight = charHeight / 15,\n positions = {\n underline: top + charHeight / 10,\n 'line-through': top - charHeight * (this._fontSizeFraction + this._fontSizeMult - 1) + decorationWeight,\n overline: top - (this._fontSizeMult - this._fontSizeFraction) * charHeight\n },\n decorations = ['underline', 'line-through', 'overline'], i, decoration;\n\n for (i = 0; i < decorations.length; i++) {\n decoration = decorations[i];\n if (textDecoration.indexOf(decoration) > -1) {\n ctx.fillRect(left, positions[decoration], charWidth , decorationWeight);\n }\n }\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n */\n _renderTextLine: function(method, ctx, line, left, top, lineIndex) {\n // to \"cancel\" this.fontSize subtraction in fabric.Text#_renderTextLine\n // the adding 0.03 is just to align text with itext by overlap test\n if (!this.isEmptyStyles()) {\n top += this.fontSize * (this._fontSizeFraction + 0.03);\n }\n this.callSuper('_renderTextLine', method, ctx, line, left, top, lineIndex);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration: function(ctx) {\n if (this.isEmptyStyles()) {\n return this.callSuper('_renderTextDecoration', ctx);\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground: function(ctx) {\n this.callSuper('_renderTextLinesBackground', ctx);\n\n var lineTopOffset = 0, heightOfLine,\n lineWidth, lineLeftOffset,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(),\n colorCache = '',\n line, _char, style, leftCache,\n topCache, widthCache, heightCache;\n ctx.save();\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this._getHeightOfLine(ctx, i);\n line = this._textLines[i];\n\n if (line === '' || !this.styles || !this._getLineStyle(i)) {\n lineTopOffset += heightOfLine;\n continue;\n }\n\n lineWidth = this._getLineWidth(ctx, i);\n lineLeftOffset = this._getLineLeftOffset(lineWidth);\n leftCache = topCache = widthCache = heightCache = 0;\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n style = this._getStyleDeclaration(i, j) || {};\n\n if (colorCache !== style.textBackgroundColor) {\n if (heightCache && widthCache) {\n ctx.fillStyle = colorCache;\n ctx.fillRect(leftCache, topCache, widthCache, heightCache);\n }\n leftCache = topCache = widthCache = heightCache = 0;\n colorCache = style.textBackgroundColor || '';\n }\n\n if (!style.textBackgroundColor) {\n colorCache = '';\n continue;\n }\n _char = line[j];\n\n if (colorCache === style.textBackgroundColor) {\n colorCache = style.textBackgroundColor;\n if (!leftCache) {\n leftCache = leftOffset + lineLeftOffset + this._getWidthOfCharsAt(ctx, i, j);\n }\n topCache = topOffset + lineTopOffset;\n widthCache += this._getWidthOfChar(ctx, _char, i, j);\n heightCache = heightOfLine / this.lineHeight;\n }\n }\n // if a textBackgroundColor ends on the last character of a line\n if (heightCache && widthCache) {\n ctx.fillStyle = colorCache;\n ctx.fillRect(leftCache, topCache, widthCache, heightCache);\n leftCache = topCache = widthCache = heightCache = 0;\n }\n lineTopOffset += heightOfLine;\n }\n ctx.restore();\n },\n\n /**\n * @private\n */\n _getCacheProp: function(_char, styleDeclaration) {\n return _char +\n styleDeclaration.fontSize +\n styleDeclaration.fontWeight +\n styleDeclaration.fontStyle;\n },\n\n /**\n * @private\n * @param {String} fontFamily name\n * @return {Object} reference to cache\n */\n _getFontCache: function(fontFamily) {\n if (!fabric.charWidthsCache[fontFamily]) {\n fabric.charWidthsCache[fontFamily] = { };\n }\n return fabric.charWidthsCache[fontFamily];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} _char\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} [decl]\n */\n _applyCharStylesGetWidth: function(ctx, _char, lineIndex, charIndex, decl) {\n var charDecl = decl || this._getStyleDeclaration(lineIndex, charIndex),\n styleDeclaration = clone(charDecl),\n width, cacheProp, charWidthsCache;\n\n this._applyFontStyles(styleDeclaration);\n charWidthsCache = this._getFontCache(styleDeclaration.fontFamily);\n cacheProp = this._getCacheProp(_char, styleDeclaration);\n\n // short-circuit if no styles for this char\n // global style from object is always applyed and handled by save and restore\n if (!charDecl && charWidthsCache[cacheProp] && this.caching) {\n return charWidthsCache[cacheProp];\n }\n\n if (typeof styleDeclaration.shadow === 'string') {\n styleDeclaration.shadow = new fabric.Shadow(styleDeclaration.shadow);\n }\n\n var fill = styleDeclaration.fill || this.fill;\n ctx.fillStyle = fill.toLive\n ? fill.toLive(ctx, this)\n : fill;\n\n if (styleDeclaration.stroke) {\n ctx.strokeStyle = (styleDeclaration.stroke && styleDeclaration.stroke.toLive)\n ? styleDeclaration.stroke.toLive(ctx, this)\n : styleDeclaration.stroke;\n }\n\n ctx.lineWidth = styleDeclaration.strokeWidth || this.strokeWidth;\n ctx.font = this._getFontDeclaration.call(styleDeclaration);\n\n //if we want this._setShadow.call to work with styleDeclarion\n //we have to add those references\n if (styleDeclaration.shadow) {\n styleDeclaration.scaleX = this.scaleX;\n styleDeclaration.scaleY = this.scaleY;\n styleDeclaration.canvas = this.canvas;\n styleDeclaration.getObjectScaling = this.getObjectScaling;\n this._setShadow.call(styleDeclaration, ctx);\n }\n\n if (!this.caching || !charWidthsCache[cacheProp]) {\n width = ctx.measureText(_char).width;\n this.caching && (charWidthsCache[cacheProp] = width);\n return width;\n }\n\n return charWidthsCache[cacheProp];\n },\n\n /**\n * @private\n * @param {Object} styleDeclaration\n */\n _applyFontStyles: function(styleDeclaration) {\n if (!styleDeclaration.fontFamily) {\n styleDeclaration.fontFamily = this.fontFamily;\n }\n if (!styleDeclaration.fontSize) {\n styleDeclaration.fontSize = this.fontSize;\n }\n if (!styleDeclaration.fontWeight) {\n styleDeclaration.fontWeight = this.fontWeight;\n }\n if (!styleDeclaration.fontStyle) {\n styleDeclaration.fontStyle = this.fontStyle;\n }\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Boolean} [returnCloneOrEmpty=false]\n * @private\n */\n _getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) {\n if (returnCloneOrEmpty) {\n return (this.styles[lineIndex] && this.styles[lineIndex][charIndex])\n ? clone(this.styles[lineIndex][charIndex])\n : { };\n }\n\n return this.styles[lineIndex] && this.styles[lineIndex][charIndex] ? this.styles[lineIndex][charIndex] : null;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function(lineIndex, charIndex, style) {\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n *\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function(lineIndex, charIndex) {\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _getLineStyle: function(lineIndex) {\n return this.styles[lineIndex];\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n _setLineStyle: function(lineIndex, style) {\n this.styles[lineIndex] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _deleteLineStyle: function(lineIndex) {\n delete this.styles[lineIndex];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _getWidthOfChar: function(ctx, _char, lineIndex, charIndex) {\n if (!this._isMeasuring && this.textAlign === 'justify' && this._reSpacesAndTabs.test(_char)) {\n return this._getWidthOfSpace(ctx, lineIndex);\n }\n ctx.save();\n var width = this._applyCharStylesGetWidth(ctx, _char, lineIndex, charIndex);\n if (this.charSpacing !== 0) {\n width += this._getWidthOfCharSpacing();\n }\n ctx.restore();\n return width > 0 ? width : 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n */\n _getHeightOfChar: function(ctx, lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex);\n return style && style.fontSize ? style.fontSize : this.fontSize;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n */\n _getWidthOfCharsAt: function(ctx, lineIndex, charIndex) {\n var width = 0, i, _char;\n for (i = 0; i < charIndex; i++) {\n _char = this._textLines[lineIndex][i];\n width += this._getWidthOfChar(ctx, _char, lineIndex, i);\n }\n return width;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n _measureLine: function(ctx, lineIndex) {\n this._isMeasuring = true;\n var width = this._getWidthOfCharsAt(ctx, lineIndex, this._textLines[lineIndex].length);\n if (this.charSpacing !== 0) {\n width -= this._getWidthOfCharSpacing();\n }\n this._isMeasuring = false;\n return width > 0 ? width : 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n */\n _getWidthOfSpace: function (ctx, lineIndex) {\n if (this.__widthOfSpace[lineIndex]) {\n return this.__widthOfSpace[lineIndex];\n }\n var line = this._textLines[lineIndex],\n wordsWidth = this._getWidthOfWords(ctx, line, lineIndex, 0),\n widthDiff = this.width - wordsWidth,\n numSpaces = line.length - line.replace(this._reSpacesAndTabs, '').length,\n width = Math.max(widthDiff / numSpaces, ctx.measureText(' ').width);\n this.__widthOfSpace[lineIndex] = width;\n return width;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line\n * @param {Number} lineIndex\n * @param {Number} charOffset\n */\n _getWidthOfWords: function (ctx, line, lineIndex, charOffset) {\n var width = 0;\n\n for (var charIndex = 0; charIndex < line.length; charIndex++) {\n var _char = line[charIndex];\n\n if (!_char.match(/\\s/)) {\n width += this._getWidthOfChar(ctx, _char, lineIndex, charIndex + charOffset);\n }\n }\n\n return width;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _getHeightOfLine: function(ctx, lineIndex) {\n if (this.__lineHeights[lineIndex]) {\n return this.__lineHeights[lineIndex];\n }\n\n var line = this._textLines[lineIndex],\n maxHeight = this._getHeightOfChar(ctx, lineIndex, 0);\n\n for (var i = 1, len = line.length; i < len; i++) {\n var currentCharHeight = this._getHeightOfChar(ctx, lineIndex, i);\n if (currentCharHeight > maxHeight) {\n maxHeight = currentCharHeight;\n }\n }\n this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;\n return this.__lineHeights[lineIndex];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _getTextHeight: function(ctx) {\n var lineHeight, height = 0;\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n lineHeight = this._getHeightOfLine(ctx, i);\n height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight);\n }\n return height;\n },\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return fabric.util.object.extend(this.callSuper('toObject', propertiesToInclude), {\n styles: clone(this.styles, true)\n });\n }\n });\n\n /**\n * Returns fabric.IText instance from an object representation\n * @static\n * @memberOf fabric.IText\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.IText} instance of fabric.IText\n */\n fabric.IText.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('IText', object, callback, forceAsync, 'text');\n };\n})();\n\n\n(function() {\n\n var clone = fabric.util.object.clone;\n\n fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior: function() {\n this.initAddedHandler();\n this.initRemovedHandler();\n this.initCursorSelectionHandlers();\n this.initDoubleClickSimulation();\n this.mouseMoveHandler = this.mouseMoveHandler.bind(this);\n },\n\n onDeselect: function() {\n this.isEditing && this.exitEditing();\n this.selected = false;\n this.callSuper('onDeselect');\n },\n\n /**\n * Initializes \"added\" event handler\n */\n initAddedHandler: function() {\n var _this = this;\n this.on('added', function() {\n var canvas = _this.canvas;\n if (canvas) {\n if (!canvas._hasITextHandlers) {\n canvas._hasITextHandlers = true;\n _this._initCanvasHandlers(canvas);\n }\n canvas._iTextInstances = canvas._iTextInstances || [];\n canvas._iTextInstances.push(_this);\n }\n });\n },\n\n initRemovedHandler: function() {\n var _this = this;\n this.on('removed', function() {\n var canvas = _this.canvas;\n if (canvas) {\n canvas._iTextInstances = canvas._iTextInstances || [];\n fabric.util.removeFromArray(canvas._iTextInstances, _this);\n if (canvas._iTextInstances.length === 0) {\n canvas._hasITextHandlers = false;\n _this._removeCanvasHandlers(canvas);\n }\n }\n });\n },\n\n /**\n * register canvas event to manage exiting on other instances\n * @private\n */\n _initCanvasHandlers: function(canvas) {\n canvas._mouseUpITextHandler = (function() {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function(obj) {\n obj.__isMousedown = false;\n });\n }\n }).bind(this);\n canvas.on('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * remove canvas event to manage exiting on other instances\n * @private\n */\n _removeCanvasHandlers: function(canvas) {\n canvas.off('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * @private\n */\n _tick: function() {\n this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');\n },\n\n /**\n * @private\n */\n _animateCursor: function(obj, targetOpacity, duration, completeMethod) {\n\n var tickState;\n\n tickState = {\n isAborted: false,\n abort: function() {\n this.isAborted = true;\n },\n };\n\n obj.animate('_currentCursorOpacity', targetOpacity, {\n duration: duration,\n onComplete: function() {\n if (!tickState.isAborted) {\n obj[completeMethod]();\n }\n },\n onChange: function() {\n // we do not want to animate a selection, only cursor\n if (obj.canvas && obj.selectionStart === obj.selectionEnd) {\n obj.renderCursorOrSelection();\n }\n },\n abort: function() {\n return tickState.isAborted;\n }\n });\n return tickState;\n },\n\n /**\n * @private\n */\n _onTickComplete: function() {\n\n var _this = this;\n\n if (this._cursorTimeout1) {\n clearTimeout(this._cursorTimeout1);\n }\n this._cursorTimeout1 = setTimeout(function() {\n _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick');\n }, 100);\n },\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor: function(restart) {\n var _this = this,\n delay = restart ? 0 : this.cursorDelay;\n\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this._cursorTimeout2 = setTimeout(function() {\n _this._tick();\n }, delay);\n },\n\n /**\n * Aborts cursor animation and clears all timeouts\n */\n abortCursorAnimation: function() {\n var shouldClear = this._currentTickState || this._currentTickCompleteState;\n this._currentTickState && this._currentTickState.abort();\n this._currentTickCompleteState && this._currentTickCompleteState.abort();\n\n clearTimeout(this._cursorTimeout1);\n clearTimeout(this._cursorTimeout2);\n\n this._currentCursorOpacity = 0;\n // to clear just itext area we need to transform the context\n // it may not be worth it\n if (shouldClear) {\n this.canvas && this.canvas.clearContext(this.canvas.contextTop || this.ctx);\n }\n\n },\n\n /**\n * Selects entire text\n */\n selectAll: function() {\n this.selectionStart = 0;\n this.selectionEnd = this.text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n },\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText: function() {\n return this.text.slice(this.selectionStart, this.selectionEnd);\n },\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Surrent selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft: function(startFrom) {\n var offset = 0, index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this.text.charAt(index))) {\n while (this._reSpace.test(this.text.charAt(index))) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this.text.charAt(index)) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight: function(startFrom) {\n var offset = 0, index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this.text.charAt(index))) {\n while (this._reSpace.test(this.text.charAt(index))) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this.text.charAt(index)) && index < this.text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft: function(startFrom) {\n var offset = 0, index = startFrom - 1;\n\n while (!/\\n/.test(this.text.charAt(index)) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight: function(startFrom) {\n var offset = 0, index = startFrom;\n\n while (!/\\n/.test(this.text.charAt(index)) && index < this.text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Returns number of newlines in selected text\n * @return {Number} Number of newlines in selected text\n */\n getNumNewLinesInSelectedText: function() {\n var selectedText = this.getSelectedText(),\n numNewLines = 0;\n\n for (var i = 0, len = selectedText.length; i < len; i++) {\n if (selectedText[i] === '\\n') {\n numNewLines++;\n }\n }\n return numNewLines;\n },\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary: function(selectionStart, direction) {\n var index = this._reSpace.test(this.text.charAt(selectionStart)) ? selectionStart - 1 : selectionStart,\n _char = this.text.charAt(index),\n reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\n while (!reNonWord.test(_char) && index > 0 && index < this.text.length) {\n index += direction;\n _char = this.text.charAt(index);\n }\n if (reNonWord.test(_char) && _char !== '\\n') {\n index += direction === 1 ? 0 : 1;\n }\n return index;\n },\n\n /**\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord: function(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */\n newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n },\n\n /**\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectLine: function(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n },\n\n /**\n * Enters editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n enterEditing: function(e) {\n if (this.isEditing || !this.editable) {\n return;\n }\n\n if (this.canvas) {\n this.exitEditingOnOthers(this.canvas);\n }\n\n this.isEditing = true;\n this.selected = true;\n this.initHiddenTextarea(e);\n this.hiddenTextarea.focus();\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered');\n this._fireSelectionChanged();\n if (!this.canvas) {\n return this;\n }\n this.canvas.fire('text:editing:entered', { target: this });\n this.initMouseMoveHandler();\n this.canvas.renderAll();\n return this;\n },\n\n exitEditingOnOthers: function(canvas) {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function(obj) {\n obj.selected = false;\n if (obj.isEditing) {\n obj.exitEditing();\n }\n });\n }\n },\n\n /**\n * Initializes \"mousemove\" event handler\n */\n initMouseMoveHandler: function() {\n this.canvas.on('mouse:move', this.mouseMoveHandler);\n },\n\n /**\n * @private\n */\n mouseMoveHandler: function(options) {\n if (!this.__isMousedown || !this.isEditing) {\n return;\n }\n\n var newSelectionStart = this.getSelectionStartFromPointer(options.e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd)\n &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n }\n else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {\n this.restartCursorIfNeeded();\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n },\n\n /**\n * @private\n */\n _setEditingProps: function() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n },\n\n /**\n * @private\n */\n _updateTextarea: function() {\n if (!this.hiddenTextarea || this.inCompositionMode) {\n return;\n }\n this.cursorOffsetCache = { };\n this.hiddenTextarea.value = this.text;\n this.hiddenTextarea.selectionStart = this.selectionStart;\n this.hiddenTextarea.selectionEnd = this.selectionEnd;\n if (this.selectionStart === this.selectionEnd) {\n var style = this._calcTextareaPosition();\n this.hiddenTextarea.style.left = style.left;\n this.hiddenTextarea.style.top = style.top;\n this.hiddenTextarea.style.fontSize = style.fontSize;\n }\n },\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition: function() {\n if (!this.canvas) {\n return { x: 1, y: 1 };\n }\n var chars = this.text.split(''),\n boundaries = this._getCursorBoundaries(chars, 'cursor'),\n cursorLocation = this.get2DCursorLocation(),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight = this.getCurrentCharFontSize(lineIndex, charIndex),\n leftOffset = boundaries.leftOffset,\n m = this.calcTransformMatrix(),\n p = {\n x: boundaries.left + leftOffset,\n y: boundaries.top + boundaries.topOffset + charHeight\n },\n upperCanvas = this.canvas.upperCanvasEl,\n maxWidth = upperCanvas.width - charHeight,\n maxHeight = upperCanvas.height - charHeight;\n\n p = fabric.util.transformPoint(p, m);\n p = fabric.util.transformPoint(p, this.canvas.viewportTransform);\n\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight };\n },\n\n /**\n * @private\n */\n _saveEditingProps: function() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor\n };\n },\n\n /**\n * @private\n */\n _restoreEditingProps: function() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.overCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor = this._savedProps.defaultCursor;\n this.canvas.moveCursor = this._savedProps.moveCursor;\n }\n },\n\n /**\n * Exits from editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n exitEditing: function() {\n var isTextChanged = (this._textBeforeEdit !== this.text);\n this.selected = false;\n this.isEditing = false;\n this.selectable = true;\n\n this.selectionEnd = this.selectionStart;\n\n if (this.hiddenTextarea) {\n this.hiddenTextarea.blur && this.hiddenTextarea.blur();\n this.canvas && this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);\n this.hiddenTextarea = null;\n }\n\n this.abortCursorAnimation();\n this._restoreEditingProps();\n this._currentCursorOpacity = 0;\n\n this.fire('editing:exited');\n isTextChanged && this.fire('modified');\n if (this.canvas) {\n this.canvas.off('mouse:move', this.mouseMoveHandler);\n this.canvas.fire('text:editing:exited', { target: this });\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n },\n\n /**\n * @private\n */\n _removeExtraneousStyles: function() {\n for (var prop in this.styles) {\n if (!this._textLines[prop]) {\n delete this.styles[prop];\n }\n }\n },\n\n /**\n * @private\n */\n _removeCharsFromTo: function(start, end) {\n while (end !== start) {\n this._removeSingleCharAndStyle(start + 1);\n end--;\n }\n this.selectionStart = start;\n this.selectionEnd = start;\n },\n\n _removeSingleCharAndStyle: function(index) {\n var isBeginningOfLine = this.text[index - 1] === '\\n',\n indexStyle = isBeginningOfLine ? index : index - 1;\n this.removeStyleObject(isBeginningOfLine, indexStyle);\n this.text = this.text.slice(0, index - 1) +\n this.text.slice(index);\n\n this._textLines = this._splitTextIntoLines();\n },\n\n /**\n * Inserts characters where cursor is (replacing selection if one exists)\n * @param {String} _chars Characters to insert\n * @param {Boolean} useCopiedStyle use fabric.copiedTextStyle\n */\n insertChars: function(_chars, useCopiedStyle) {\n var style;\n\n if (this.selectionEnd - this.selectionStart > 1) {\n this._removeCharsFromTo(this.selectionStart, this.selectionEnd);\n }\n //short circuit for block paste\n if (!useCopiedStyle && this.isEmptyStyles()) {\n this.insertChar(_chars, false);\n return;\n }\n for (var i = 0, len = _chars.length; i < len; i++) {\n if (useCopiedStyle) {\n style = fabric.util.object.clone(fabric.copiedTextStyle[i], true);\n }\n this.insertChar(_chars[i], i < len - 1, style);\n }\n },\n\n /**\n * Inserts a character where cursor is\n * @param {String} _char Characters to insert\n * @param {Boolean} skipUpdate trigger rendering and updates at the end of text insert\n * @param {Object} styleObject Style to be inserted for the new char\n */\n insertChar: function(_char, skipUpdate, styleObject) {\n var isEndOfLine = this.text[this.selectionStart] === '\\n';\n this.text = this.text.slice(0, this.selectionStart) +\n _char + this.text.slice(this.selectionEnd);\n this._textLines = this._splitTextIntoLines();\n this.insertStyleObjects(_char, isEndOfLine, styleObject);\n this.selectionStart += _char.length;\n this.selectionEnd = this.selectionStart;\n if (skipUpdate) {\n return;\n }\n this._updateTextarea();\n this.setCoords();\n this._fireSelectionChanged();\n this.fire('changed');\n this.restartCursorIfNeeded();\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this });\n this.canvas.renderAll();\n }\n },\n\n restartCursorIfNeeded: function() {\n if (!this._currentTickState || this._currentTickState.isAborted\n || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted\n ) {\n this.initDelayedCursor();\n }\n },\n\n /**\n * Inserts new style object\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Boolean} isEndOfLine True if it's end of line\n */\n insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) {\n\n this.shiftLineStyles(lineIndex, +1);\n\n var currentCharStyle = {},\n newLineStyles = {};\n\n if (this.styles[lineIndex] && this.styles[lineIndex][charIndex - 1]) {\n currentCharStyle = this.styles[lineIndex][charIndex - 1];\n }\n\n // if there's nothing after cursor,\n // we clone current char style onto the next (otherwise empty) line\n if (isEndOfLine && currentCharStyle) {\n newLineStyles[0] = clone(currentCharStyle);\n this.styles[lineIndex + 1] = newLineStyles;\n }\n // otherwise we clone styles of all chars\n // after cursor onto the next line, from the beginning\n else {\n var somethingAdded = false;\n for (var index in this.styles[lineIndex]) {\n var numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n somethingAdded = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n delete this.styles[lineIndex][index];\n }\n }\n somethingAdded && (this.styles[lineIndex + 1] = newLineStyles);\n }\n this._forceClearCache = true;\n },\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Object} [style] Style object to insert, if given\n */\n insertCharStyleObject: function(lineIndex, charIndex, style) {\n\n var currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = clone(currentLineStyles);\n\n if (charIndex === 0 && !style) {\n charIndex = 1;\n }\n\n // shift all char styles by 1 forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (var index in currentLineStylesCloned) {\n var numericIndex = parseInt(index, 10);\n\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + 1] = currentLineStylesCloned[numericIndex];\n\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - 1]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n var newStyle = style || clone(currentLineStyles[charIndex - 1]);\n newStyle && (this.styles[lineIndex][charIndex] = newStyle);\n this._forceClearCache = true;\n },\n\n /**\n * Inserts style object(s)\n * @param {String} _chars Characters at the location where style is inserted\n * @param {Boolean} isEndOfLine True if it's end of line\n * @param {Object} [styleObject] Style to insert\n */\n insertStyleObjects: function(_chars, isEndOfLine, styleObject) {\n // removed shortcircuit over isEmptyStyles\n\n var cursorLocation = this.get2DCursorLocation(),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex;\n\n if (!this._getLineStyle(lineIndex)) {\n this._setLineStyle(lineIndex, {});\n }\n\n if (_chars === '\\n') {\n this.insertNewlineStyleObject(lineIndex, charIndex, isEndOfLine);\n }\n else {\n this.insertCharStyleObject(lineIndex, charIndex, styleObject);\n }\n },\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can be -1 or +1\n */\n shiftLineStyles: function(lineIndex, offset) {\n // shift all line styles by 1 upward or downward\n var clonedStyles = clone(this.styles);\n for (var line in clonedStyles) {\n var numericLine = parseInt(line, 10);\n if (numericLine <= lineIndex) {\n delete clonedStyles[numericLine];\n }\n }\n for (var line in this.styles) {\n var numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n //TODO: evaluate if delete old style lines with offset -1\n },\n\n /**\n * Removes style object\n * @param {Boolean} isBeginningOfLine True if cursor is at the beginning of line\n * @param {Number} [index] Optional index. When not given, current selectionStart is used.\n */\n removeStyleObject: function(isBeginningOfLine, index) {\n\n var cursorLocation = this.get2DCursorLocation(index),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex;\n\n this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex);\n },\n\n _getTextOnPreviousLine: function(lIndex) {\n return this._textLines[lIndex - 1];\n },\n\n _removeStyleObject: function(isBeginningOfLine, cursorLocation, lineIndex, charIndex) {\n\n if (isBeginningOfLine) {\n var textOnPreviousLine = this._getTextOnPreviousLine(cursorLocation.lineIndex),\n newCharIndexOnPrevLine = textOnPreviousLine ? textOnPreviousLine.length : 0;\n\n if (!this.styles[lineIndex - 1]) {\n this.styles[lineIndex - 1] = {};\n }\n for (charIndex in this.styles[lineIndex]) {\n this.styles[lineIndex - 1][parseInt(charIndex, 10) + newCharIndexOnPrevLine]\n = this.styles[lineIndex][charIndex];\n }\n this.shiftLineStyles(cursorLocation.lineIndex, -1);\n }\n else {\n var currentLineStyles = this.styles[lineIndex];\n\n if (currentLineStyles) {\n delete currentLineStyles[charIndex];\n }\n var currentLineStylesCloned = clone(currentLineStyles);\n // shift all styles by 1 backwards\n for (var i in currentLineStylesCloned) {\n var numericIndex = parseInt(i, 10);\n if (numericIndex >= charIndex && numericIndex !== 0) {\n currentLineStyles[numericIndex - 1] = currentLineStylesCloned[numericIndex];\n delete currentLineStyles[numericIndex];\n }\n }\n }\n },\n\n /**\n * Inserts new line\n */\n insertNewline: function() {\n this.insertChars('\\n');\n },\n\n /**\n * Set the selectionStart and selectionEnd according to the ne postion of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift: function(start, end, newSelection) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = 'left';\n }\n else if (this._selectionDirection === 'right') {\n this._selectionDirection = 'left';\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n }\n else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === 'right') {\n this.selectionEnd = newSelection;\n }\n else {\n this.selectionStart = newSelection;\n }\n }\n else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = 'right';\n }\n else if (this._selectionDirection === 'left') {\n this._selectionDirection = 'right';\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n },\n\n setSelectionInBoundaries: function() {\n var length = this.text.length;\n if (this.selectionStart > length) {\n this.selectionStart = length;\n }\n else if (this.selectionStart < 0) {\n this.selectionStart = 0;\n }\n if (this.selectionEnd > length) {\n this.selectionEnd = length;\n }\n else if (this.selectionEnd < 0) {\n this.selectionEnd = 0;\n }\n }\n });\n})();\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n /**\n * Initializes \"dbclick\" event handler\n */\n initDoubleClickSimulation: function() {\n\n // for double click\n this.__lastClickTime = +new Date();\n\n // for triple click\n this.__lastLastClickTime = +new Date();\n\n this.__lastPointer = { };\n\n this.on('mousedown', this.onMouseDown.bind(this));\n },\n\n onMouseDown: function(options) {\n\n this.__newClickTime = +new Date();\n var newPointer = this.canvas.getPointer(options.e);\n\n if (this.isTripleClick(newPointer, options.e)) {\n this.fire('tripleclick', options);\n this._stopEvent(options.e);\n }\n else if (this.isDoubleClick(newPointer)) {\n this.fire('dblclick', options);\n this._stopEvent(options.e);\n }\n\n this.__lastLastClickTime = this.__lastClickTime;\n this.__lastClickTime = this.__newClickTime;\n this.__lastPointer = newPointer;\n this.__lastIsEditing = this.isEditing;\n this.__lastSelected = this.selected;\n },\n\n isDoubleClick: function(newPointer) {\n return this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y && this.__lastIsEditing;\n },\n\n isTripleClick: function(newPointer) {\n return this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastClickTime - this.__lastLastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y;\n },\n\n /**\n * @private\n */\n _stopEvent: function(e) {\n e.preventDefault && e.preventDefault();\n e.stopPropagation && e.stopPropagation();\n },\n\n /**\n * Initializes event handlers related to cursor or selection\n */\n initCursorSelectionHandlers: function() {\n this.initMousedownHandler();\n this.initMouseupHandler();\n this.initClicks();\n },\n\n /**\n * Initializes double and triple click event handlers\n */\n initClicks: function() {\n this.on('dblclick', function(options) {\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n });\n this.on('tripleclick', function(options) {\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n });\n },\n\n /**\n * Initializes \"mousedown\" event handler\n */\n initMousedownHandler: function() {\n this.on('mousedown', function(options) {\n if (!this.editable || (options.e.button && options.e.button !== 1)) {\n return;\n }\n var pointer = this.canvas.getPointer(options.e);\n this.__mousedownX = pointer.x;\n this.__mousedownY = pointer.y;\n this.__isMousedown = true;\n\n if (this.selected) {\n this.setCursorByClick(options.e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\n this.renderCursorOrSelection();\n }\n });\n },\n\n /**\n * @private\n */\n _isObjectMoved: function(e) {\n var pointer = this.canvas.getPointer(e);\n\n return this.__mousedownX !== pointer.x ||\n this.__mousedownY !== pointer.y;\n },\n\n /**\n * Initializes \"mouseup\" event handler\n */\n initMouseupHandler: function() {\n this.on('mouseup', function(options) {\n this.__isMousedown = false;\n if (!this.editable || this._isObjectMoved(options.e) || (options.e.button && options.e.button !== 1)) {\n return;\n }\n\n if (this.__lastSelected && !this.__corner) {\n this.enterEditing(options.e);\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n }\n else {\n this.renderCursorOrSelection();\n }\n }\n this.selected = true;\n });\n },\n\n /**\n * Changes cursor location in a text depending on passed pointer (x/y) object\n * @param {Event} e Event object\n */\n setCursorByClick: function(e) {\n var newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart, end = this.selectionEnd;\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n }\n else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n if (this.isEditing) {\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Returns index of a character corresponding to where an object was clicked\n * @param {Event} e Event object\n * @return {Number} Index of a character\n */\n getSelectionStartFromPointer: function(e) {\n var mouseOffset = this.getLocalPointer(e),\n prevWidth = 0,\n width = 0,\n height = 0,\n charIndex = 0,\n newSelectionStart,\n line;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n line = this._textLines[i];\n height += this._getHeightOfLine(this.ctx, i) * this.scaleY;\n\n var widthOfLine = this._getLineWidth(this.ctx, i),\n lineLeftOffset = this._getLineLeftOffset(widthOfLine);\n\n width = lineLeftOffset * this.scaleX;\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n\n prevWidth = width;\n\n width += this._getWidthOfChar(this.ctx, line[j], i, this.flipX ? jlen - j : j) *\n this.scaleX;\n\n if (height <= mouseOffset.y || width <= mouseOffset.x) {\n charIndex++;\n continue;\n }\n\n return this._getNewSelectionStartFromOffset(\n mouseOffset, prevWidth, width, charIndex + i, jlen);\n }\n\n if (mouseOffset.y < height) {\n //this happens just on end of lines.\n return this._getNewSelectionStartFromOffset(\n mouseOffset, prevWidth, width, charIndex + i - 1, jlen);\n }\n }\n\n // clicked somewhere after all chars, so set at the end\n if (typeof newSelectionStart === 'undefined') {\n return this.text.length;\n }\n },\n\n /**\n * @private\n */\n _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) {\n\n var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth,\n distanceBtwNextCharAndCursor = width - mouseOffset.x,\n offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ? 0 : 1,\n newSelectionStart = index + offset;\n\n // if object is horizontally flipped, mirror cursor location from the end\n if (this.flipX) {\n newSelectionStart = jlen - newSelectionStart;\n }\n\n if (newSelectionStart > this.text.length) {\n newSelectionStart = this.text.length;\n }\n\n return newSelectionStart;\n }\n});\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea: function() {\n this.hiddenTextarea = fabric.document.createElement('textarea');\n this.hiddenTextarea.setAttribute('autocapitalize', 'off');\n this.hiddenTextarea.setAttribute('autocorrect', 'off');\n this.hiddenTextarea.setAttribute('autocomplete', 'off');\n this.hiddenTextarea.setAttribute('spellcheck', 'false');\n this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', '');\n this.hiddenTextarea.setAttribute('wrap', 'off');\n var style = this._calcTextareaPosition();\n this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top +\n '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' +\n ' line-height: 1px; paddingーtop: ' + style.fontSize + ';';\n fabric.document.body.appendChild(this.hiddenTextarea);\n\n fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'cut', this.cut.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this));\n\n if (!this._clickHandlerInitialized && this.canvas) {\n fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this));\n this._clickHandlerInitialized = true;\n }\n },\n\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behaviour for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the fabric.Itext or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = fabric.util.object.clone(this.keysMap);\n * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0]\n */\n keysMap: {\n 8: 'removeChars',\n 9: 'exitEditing',\n 27: 'exitEditing',\n 13: 'insertNewline',\n 33: 'moveCursorUp',\n 34: 'moveCursorDown',\n 35: 'moveCursorRight',\n 36: 'moveCursorLeft',\n 37: 'moveCursorLeft',\n 38: 'moveCursorUp',\n 39: 'moveCursorRight',\n 40: 'moveCursorDown',\n 46: 'forwardDelete'\n },\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n ctrlKeysMapUp: {\n 67: 'copy',\n 88: 'cut'\n },\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n ctrlKeysMapDown: {\n 65: 'selectAll'\n },\n\n onClick: function() {\n // No need to trigger click event here, focus is enough to have the keyboard appear on Android\n this.hiddenTextarea && this.hiddenTextarea.focus();\n },\n\n /**\n * Handles keyup event\n * @param {Event} e Event object\n */\n onKeyDown: function(e) {\n if (!this.isEditing) {\n return;\n }\n if (e.keyCode in this.keysMap) {\n this[this.keysMap[e.keyCode]](e);\n }\n else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n }\n else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.clearContextTop();\n this.renderCursorOrSelection();\n }\n else {\n this.canvas && this.canvas.renderAll();\n }\n },\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {Event} e Event object\n */\n onKeyUp: function(e) {\n if (!this.isEditing || this._copyDone) {\n this._copyDone = false;\n return;\n }\n if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n }\n else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.renderAll();\n },\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput: function(e) {\n if (!this.isEditing || this.inCompositionMode) {\n return;\n }\n var offset = this.selectionStart || 0,\n offsetEnd = this.selectionEnd || 0,\n textLength = this.text.length,\n newTextLength = this.hiddenTextarea.value.length,\n diff, charsToInsert, start;\n if (newTextLength > textLength) {\n //we added some character\n start = this._selectionDirection === 'left' ? offsetEnd : offset;\n diff = newTextLength - textLength;\n charsToInsert = this.hiddenTextarea.value.slice(start, start + diff);\n }\n else {\n //we selected a portion of text and then input something else.\n //Internet explorer does not trigger this else\n diff = newTextLength - textLength + offsetEnd - offset;\n charsToInsert = this.hiddenTextarea.value.slice(offset, offset + diff);\n }\n this.insertChars(charsToInsert);\n e.stopPropagation();\n },\n\n /**\n * Composition start\n */\n onCompositionStart: function() {\n this.inCompositionMode = true;\n this.prevCompositionLength = 0;\n this.compositionStart = this.selectionStart;\n },\n\n /**\n * Composition end\n */\n onCompositionEnd: function() {\n this.inCompositionMode = false;\n },\n\n /**\n * Composition update\n */\n onCompositionUpdate: function(e) {\n var data = e.data;\n this.selectionStart = this.compositionStart;\n this.selectionEnd = this.selectionEnd === this.selectionStart ?\n this.compositionStart + this.prevCompositionLength : this.selectionEnd;\n this.insertChars(data, false);\n this.prevCompositionLength = data.length;\n },\n\n /**\n * Forward delete\n */\n forwardDelete: function(e) {\n if (this.selectionStart === this.selectionEnd) {\n if (this.selectionStart === this.text.length) {\n return;\n }\n this.moveCursorRight(e);\n }\n this.removeChars(e);\n },\n\n /**\n * Copies selected text\n * @param {Event} e Event object\n */\n copy: function(e) {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n var selectedText = this.getSelectedText(),\n clipboardData = this._getClipboardData(e);\n\n // Check for backward compatibility with old browsers\n if (clipboardData) {\n clipboardData.setData('text', selectedText);\n }\n\n fabric.copiedText = selectedText;\n fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd);\n e.stopImmediatePropagation();\n e.preventDefault();\n this._copyDone = true;\n },\n\n /**\n * Pastes text\n * @param {Event} e Event object\n */\n paste: function(e) {\n var copiedText = null,\n clipboardData = this._getClipboardData(e),\n useCopiedStyle = true;\n\n // Check for backward compatibility with old browsers\n if (clipboardData) {\n copiedText = clipboardData.getData('text').replace(/\\r/g, '');\n if (!fabric.copiedTextStyle || fabric.copiedText !== copiedText) {\n useCopiedStyle = false;\n }\n }\n else {\n copiedText = fabric.copiedText;\n }\n\n if (copiedText) {\n this.insertChars(copiedText, useCopiedStyle);\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n },\n\n /**\n * Cuts text\n * @param {Event} e Event object\n */\n cut: function(e) {\n if (this.selectionStart === this.selectionEnd) {\n return;\n }\n\n this.copy(e);\n this.removeChars(e);\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @return {Object} Clipboard data object\n */\n _getClipboardData: function(e) {\n return (e && e.clipboardData) || fabric.window.clipboardData;\n },\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor: function(lineIndex, charIndex) {\n var textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n widthOfLine = this._getLineWidth(this.ctx, lineIndex),\n widthBeforeCursor = this._getLineLeftOffset(widthOfLine), _char;\n\n for (var i = 0, len = textBeforeCursor.length; i < len; i++) {\n _char = textBeforeCursor[i];\n widthBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i);\n }\n return widthBeforeCursor;\n },\n\n /**\n * Gets start offset of a selection\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset: function(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n // if on last line, down cursor goes to end of line\n if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {\n // move to the end of a text\n return this.text.length - selectionProp;\n }\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n\n return textAfterCursor.length + indexOnOtherLine + 2;\n },\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset: function(e, isRight) {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n }\n else {\n return this.selectionStart;\n }\n },\n\n /**\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset: function(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex);\n // return a negative offset\n return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length;\n },\n\n /**\n * find for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine: function(lineIndex, width) {\n\n var widthOfLine = this._getLineWidth(this.ctx, lineIndex),\n textOnLine = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(widthOfLine),\n widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0,\n foundMatch;\n\n for (var j = 0, jlen = textOnLine.length; j < jlen; j++) {\n\n var _char = textOnLine[j],\n widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j);\n\n widthOfCharsOnLine += widthOfChar;\n\n if (widthOfCharsOnLine > width) {\n\n foundMatch = true;\n\n var leftEdge = widthOfCharsOnLine - widthOfChar,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1);\n\n break;\n }\n }\n\n // reached end\n if (!foundMatch) {\n indexOnLine = textOnLine.length - 1;\n }\n\n return indexOnLine;\n },\n\n\n /**\n * Moves cursor down\n * @param {Event} e Event object\n */\n moveCursorDown: function(e) {\n if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) {\n return;\n }\n this._moveCursorUpOrDown('Down', e);\n },\n\n /**\n * Moves cursor up\n * @param {Event} e Event object\n */\n moveCursorUp: function(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorUpOrDown('Up', e);\n },\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {Event} e Event object\n */\n _moveCursorUpOrDown: function(direction, e) {\n // getUpCursorOffset\n // getDownCursorOffset\n var action = 'get' + direction + 'CursorOffset',\n offset = this[action](e, this._selectionDirection === 'right');\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n }\n else {\n this.moveCursorWithoutShift(offset);\n }\n if (offset !== 0) {\n this.setSelectionInBoundaries();\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift: function(offset) {\n var newSelection = this._selectionDirection === 'left'\n ? this.selectionStart + offset\n : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection);\n return offset !== 0;\n },\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift: function(offset) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n }\n else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n return offset !== 0;\n },\n\n /**\n * Moves cursor left\n * @param {Event} e Event object\n */\n moveCursorLeft: function(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorLeftOrRight('Left', e);\n },\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n */\n _move: function(e, prop, direction) {\n var newValue;\n if (e.altKey) {\n newValue = this['findWordBoundary' + direction](this[prop]);\n }\n else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36 ) {\n newValue = this['findLineBoundary' + direction](this[prop]);\n }\n else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n if (typeof newValue !== undefined && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n },\n\n /**\n * @private\n */\n _moveLeft: function(e, prop) {\n return this._move(e, prop, 'Left');\n },\n\n /**\n * @private\n */\n _moveRight: function(e, prop) {\n return this._move(e, prop, 'Right');\n },\n\n /**\n * Moves cursor left without keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithoutShift: function(e) {\n var change = true;\n this._selectionDirection = 'left';\n\n // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) {\n change = this._moveLeft(e, 'selectionStart');\n\n }\n this.selectionEnd = this.selectionStart;\n return change;\n },\n\n /**\n * Moves cursor left while keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithShift: function(e) {\n if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) {\n return this._moveLeft(e, 'selectionEnd');\n }\n else if (this.selectionStart !== 0){\n this._selectionDirection = 'left';\n return this._moveLeft(e, 'selectionStart');\n }\n },\n\n /**\n * Moves cursor right\n * @param {Event} e Event object\n */\n moveCursorRight: function(e) {\n if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) {\n return;\n }\n this._moveCursorLeftOrRight('Right', e);\n },\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {Event} e Event object\n */\n _moveCursorLeftOrRight: function(direction, e) {\n var actionName = 'moveCursor' + direction + 'With';\n this._currentCursorOpacity = 1;\n\n if (e.shiftKey) {\n actionName += 'Shift';\n }\n else {\n actionName += 'outShift';\n }\n if (this[actionName](e)) {\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor right while keeping selection\n * @param {Event} e\n */\n moveCursorRightWithShift: function(e) {\n if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) {\n return this._moveRight(e, 'selectionStart');\n }\n else if (this.selectionEnd !== this.text.length) {\n this._selectionDirection = 'right';\n return this._moveRight(e, 'selectionEnd');\n }\n },\n\n /**\n * Moves cursor right without keeping selection\n * @param {Event} e Event object\n */\n moveCursorRightWithoutShift: function(e) {\n var changed = true;\n this._selectionDirection = 'right';\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n }\n else {\n this.selectionStart = this.selectionEnd;\n }\n return changed;\n },\n\n /**\n * Removes characters selected by selection\n * @param {Event} e Event object\n */\n removeChars: function(e) {\n if (this.selectionStart === this.selectionEnd) {\n this._removeCharsNearCursor(e);\n }\n else {\n this._removeCharsFromTo(this.selectionStart, this.selectionEnd);\n }\n\n this.set('dirty', true);\n this.setSelectionEnd(this.selectionStart);\n\n this._removeExtraneousStyles();\n\n this.canvas && this.canvas.renderAll();\n\n this.setCoords();\n this.fire('changed');\n this.canvas && this.canvas.fire('text:changed', { target: this });\n },\n\n /**\n * @private\n * @param {Event} e Event object\n */\n _removeCharsNearCursor: function(e) {\n if (this.selectionStart === 0) {\n return;\n }\n if (e.metaKey) {\n // remove all till the start of current line\n var leftLineBoundary = this.findLineBoundaryLeft(this.selectionStart);\n\n this._removeCharsFromTo(leftLineBoundary, this.selectionStart);\n this.setSelectionStart(leftLineBoundary);\n }\n else if (e.altKey) {\n // remove all till the start of current word\n var leftWordBoundary = this.findWordBoundaryLeft(this.selectionStart);\n\n this._removeCharsFromTo(leftWordBoundary, this.selectionStart);\n this.setSelectionStart(leftWordBoundary);\n }\n else {\n this._removeSingleCharAndStyle(this.selectionStart);\n this.setSelectionStart(this.selectionStart - 1);\n }\n }\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n var toFixed = fabric.util.toFixed,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * @private\n */\n _setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) {\n if (!this._getLineStyle(lineIndex)) {\n fabric.Text.prototype._setSVGTextLineText.call(this,\n lineIndex, textSpans, height, textLeftOffset, textTopOffset);\n }\n else {\n this._setSVGTextLineChars(\n lineIndex, textSpans, height, textLeftOffset, textBgRects);\n }\n },\n\n /**\n * @private\n */\n _setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) {\n\n var chars = this._textLines[lineIndex],\n charOffset = 0,\n lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) - this.width / 2,\n lineOffset = this._getSVGLineTopOffset(lineIndex),\n heightOfLine = this._getHeightOfLine(this.ctx, lineIndex);\n\n for (var i = 0, len = chars.length; i < len; i++) {\n var styleDecl = this._getStyleDeclaration(lineIndex, i) || { };\n\n textSpans.push(\n this._createTextCharSpan(\n chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset));\n\n var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i);\n\n if (styleDecl.textBackgroundColor) {\n textBgRects.push(\n this._createTextCharBg(\n styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset));\n }\n\n charOffset += charWidth;\n }\n },\n\n /**\n * @private\n */\n _getSVGLineTopOffset: function(lineIndex) {\n var lineTopOffset = 0, lastHeight = 0;\n for (var j = 0; j < lineIndex; j++) {\n lineTopOffset += this._getHeightOfLine(this.ctx, j);\n }\n lastHeight = this._getHeightOfLine(this.ctx, j);\n return {\n lineTop: lineTopOffset,\n offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)\n };\n },\n\n /**\n * @private\n */\n _createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) {\n return [\n '\\t\\t\\n'\n ].join('');\n },\n\n /**\n * @private\n */\n _createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) {\n\n var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({\n visible: true,\n fill: this.fill,\n stroke: this.stroke,\n type: 'text',\n getSvgFilter: fabric.Object.prototype.getSvgFilter\n }, styleDecl));\n\n return [\n '\\t\\t\\t',\n fabric.util.string.escapeXml(_char),\n '\\n'\n ].join('');\n },\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n /**\n * Textbox class, based on IText, allows the user to resize the text rectangle\n * and wraps lines automatically. Textboxes have their Y scaling locked, the\n * user can only change width. Height is adjusted automatically based on the\n * wrapping of lines.\n * @class fabric.Textbox\n * @extends fabric.IText\n * @mixes fabric.Observable\n * @return {fabric.Textbox} thisArg\n * @see {@link fabric.Textbox#initialize} for constructor definition\n */\n fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'textbox',\n\n /**\n * Minimum width of textbox, in pixels.\n * @type Number\n * @default\n */\n minWidth: 20,\n\n /**\n * Minimum calculated width of a textbox, in pixels.\n * fixed to 2 so that an empty textbox cannot go to 0\n * and is still selectable without text.\n * @type Number\n * @default\n */\n dynamicMinWidth: 2,\n\n /**\n * Cached array of text wrapping.\n * @type Array\n */\n __cachedLines: null,\n\n /**\n * Override standard Object class values\n */\n lockScalingY: true,\n\n /**\n * Override standard Object class values\n */\n lockScalingFlip: true,\n\n /**\n * Override standard Object class values\n * Textbox needs this on false\n */\n noScaleCache: false,\n\n /**\n * Properties which when set cause object to change dimensions\n * @type Object\n * @private\n */\n _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'),\n\n /**\n * Constructor. Some scaling related property values are forced. Visibility\n * of controls is also fixed; only the rotation and width controls are\n * made available.\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Textbox} thisArg\n */\n initialize: function(text, options) {\n\n this.callSuper('initialize', text, options);\n this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());\n this.ctx = this.objectCaching ? this._cacheContext : fabric.util.createCanvasElement().getContext('2d');\n },\n\n /**\n * Unlike superclass's version of this function, Textbox does not update\n * its width.\n * @param {CanvasRenderingContext2D} ctx Context to use for measurements\n * @private\n * @override\n */\n _initDimensions: function(ctx) {\n if (this.__skipDimension) {\n return;\n }\n\n if (!ctx) {\n ctx = fabric.util.createCanvasElement().getContext('2d');\n this._setTextStyles(ctx);\n this.clearContextTop();\n }\n\n // clear dynamicMinWidth as it will be different after we re-wrap line\n this.dynamicMinWidth = 0;\n\n // wrap lines\n this._textLines = this._splitTextIntoLines(ctx);\n // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\n\n // clear cache and re-calculate height\n this._clearCache();\n this.height = this._getTextHeight(ctx);\n this.setCoords();\n },\n\n /**\n * Generate an object that translates the style object so that it is\n * broken up by visual lines (new lines and automatic wrapping).\n * The original text styles object is broken up by actual lines (new lines only),\n * which is only sufficient for Text / IText\n * @private\n */\n _generateStyleMap: function() {\n var realLineCount = 0,\n realLineCharCount = 0,\n charCount = 0,\n map = {};\n\n for (var i = 0; i < this._textLines.length; i++) {\n if (this.text[charCount] === '\\n' && i > 0) {\n realLineCharCount = 0;\n charCount++;\n realLineCount++;\n }\n else if (this.text[charCount] === ' ' && i > 0) {\n // this case deals with space's that are removed from end of lines when wrapping\n realLineCharCount++;\n charCount++;\n }\n\n map[i] = { line: realLineCount, offset: realLineCharCount };\n\n charCount += this._textLines[i].length;\n realLineCharCount += this._textLines[i].length;\n }\n\n return map;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Boolean} [returnCloneOrEmpty=false]\n * @private\n */\n _getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) {\n if (this._styleMap) {\n var map = this._styleMap[lineIndex];\n if (!map) {\n return returnCloneOrEmpty ? { } : null;\n }\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\n return this.callSuper('_getStyleDeclaration', lineIndex, charIndex, returnCloneOrEmpty);\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function(lineIndex, charIndex, style) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function(lineIndex, charIndex) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _getLineStyle: function(lineIndex) {\n var map = this._styleMap[lineIndex];\n return this.styles[map.line];\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n _setLineStyle: function(lineIndex, style) {\n var map = this._styleMap[lineIndex];\n this.styles[map.line] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _deleteLineStyle: function(lineIndex) {\n var map = this._styleMap[lineIndex];\n delete this.styles[map.line];\n },\n\n /**\n * Wraps text using the 'width' property of Textbox. First this function\n * splits text on newlines, so we preserve newlines entered by the user.\n * Then it wraps each line using the width of the Textbox by calling\n * _wrapLine().\n * @param {CanvasRenderingContext2D} ctx Context to use for measurements\n * @param {String} text The string of text that is split into lines\n * @returns {Array} Array of lines\n */\n _wrapText: function(ctx, text) {\n var lines = text.split(this._reNewline), wrapped = [], i;\n\n for (i = 0; i < lines.length; i++) {\n wrapped = wrapped.concat(this._wrapLine(ctx, lines[i], i));\n }\n\n return wrapped;\n },\n\n /**\n * Helper function to measure a string of text, given its lineIndex and charIndex offset\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {String} text\n * @param {number} lineIndex\n * @param {number} charOffset\n * @returns {number}\n * @private\n */\n _measureText: function(ctx, text, lineIndex, charOffset) {\n var width = 0;\n charOffset = charOffset || 0;\n for (var i = 0, len = text.length; i < len; i++) {\n width += this._getWidthOfChar(ctx, text[i], lineIndex, i + charOffset);\n }\n return width;\n },\n\n /**\n * Wraps a line of text using the width of the Textbox and a context.\n * @param {CanvasRenderingContext2D} ctx Context to use for measurements\n * @param {String} text The string of text to split into lines\n * @param {Number} lineIndex\n * @returns {Array} Array of line(s) into which the given text is wrapped\n * to.\n */\n _wrapLine: function(ctx, text, lineIndex) {\n var lineWidth = 0,\n lines = [],\n line = '',\n words = text.split(' '),\n word = '',\n offset = 0,\n infix = ' ',\n wordWidth = 0,\n infixWidth = 0,\n largestWordWidth = 0,\n lineJustStarted = true,\n additionalSpace = this._getWidthOfCharSpacing();\n\n for (var i = 0; i < words.length; i++) {\n word = words[i];\n wordWidth = this._measureText(ctx, word, lineIndex, offset);\n\n offset += word.length;\n\n lineWidth += infixWidth + wordWidth - additionalSpace;\n\n if (lineWidth >= this.width && !lineJustStarted) {\n lines.push(line);\n line = '';\n lineWidth = wordWidth;\n lineJustStarted = true;\n }\n else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted) {\n line += infix;\n }\n line += word;\n\n infixWidth = this._measureText(ctx, infix, lineIndex, offset);\n offset++;\n lineJustStarted = false;\n // keep track of largest word\n if (wordWidth > largestWordWidth) {\n largestWordWidth = wordWidth;\n }\n }\n\n i && lines.push(line);\n\n if (largestWordWidth > this.dynamicMinWidth) {\n this.dynamicMinWidth = largestWordWidth - additionalSpace;\n }\n\n return lines;\n },\n /**\n * Gets lines of text to render in the Textbox. This function calculates\n * text wrapping on the fly everytime it is called.\n * @returns {Array} Array of lines in the Textbox.\n * @override\n */\n _splitTextIntoLines: function(ctx) {\n ctx = ctx || this.ctx;\n var originalAlign = this.textAlign;\n this._styleMap = null;\n ctx.save();\n this._setTextStyles(ctx);\n this.textAlign = 'left';\n var lines = this._wrapText(ctx, this.text);\n this.textAlign = originalAlign;\n ctx.restore();\n this._textLines = lines;\n this._styleMap = this._generateStyleMap();\n return lines;\n },\n\n /**\n * When part of a group, we don't want the Textbox's scale to increase if\n * the group's increases. That's why we reduce the scale of the Textbox by\n * the amount that the group's increases. This is to maintain the effective\n * scale of the Textbox at 1, so that font-size values make sense. Otherwise\n * the same font-size value would result in different actual size depending\n * on the value of the scale.\n * @param {String} key\n * @param {*} value\n */\n setOnGroup: function(key, value) {\n if (key === 'scaleX') {\n this.set('scaleX', Math.abs(1 / value));\n this.set('width', (this.get('width') * value) /\n (typeof this.__oldScaleX === 'undefined' ? 1 : this.__oldScaleX));\n this.__oldScaleX = value;\n }\n },\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start).\n * Overrides the superclass function to take into account text wrapping.\n *\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n */\n get2DCursorLocation: function(selectionStart) {\n if (typeof selectionStart === 'undefined') {\n selectionStart = this.selectionStart;\n }\n\n var numLines = this._textLines.length,\n removed = 0;\n\n for (var i = 0; i < numLines; i++) {\n var line = this._textLines[i],\n lineLen = line.length;\n\n if (selectionStart <= removed + lineLen) {\n return {\n lineIndex: i,\n charIndex: selectionStart - removed\n };\n }\n\n removed += lineLen;\n\n if (this.text[removed] === '\\n' || this.text[removed] === ' ') {\n removed++;\n }\n }\n\n return {\n lineIndex: numLines - 1,\n charIndex: this._textLines[numLines - 1].length\n };\n },\n\n /**\n * Overrides superclass function and uses text wrapping data to get cursor\n * boundary offsets instead of the array of chars.\n * @param {Array} chars Unused\n * @param {String} typeOfBoundaries Can be 'cursor' or 'selection'\n * @returns {Object} Object with 'top', 'left', and 'lineLeft' properties set.\n */\n _getCursorBoundariesOffsets: function(chars, typeOfBoundaries) {\n var topOffset = 0,\n leftOffset = 0,\n cursorLocation = this.get2DCursorLocation(),\n lineChars = this._textLines[cursorLocation.lineIndex].split(''),\n lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, cursorLocation.lineIndex));\n\n for (var i = 0; i < cursorLocation.charIndex; i++) {\n leftOffset += this._getWidthOfChar(this.ctx, lineChars[i], cursorLocation.lineIndex, i);\n }\n\n for (i = 0; i < cursorLocation.lineIndex; i++) {\n topOffset += this._getHeightOfLine(this.ctx, i);\n }\n\n if (typeOfBoundaries === 'cursor') {\n topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, cursorLocation.lineIndex)\n / this.lineHeight - this.getCurrentCharFontSize(cursorLocation.lineIndex, cursorLocation.charIndex)\n * (1 - this._fontSizeFraction);\n }\n\n return {\n top: topOffset,\n left: leftOffset,\n lineLeft: lineLeftOffset\n };\n },\n\n getMinWidth: function() {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n },\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['minWidth'].concat(propertiesToInclude));\n }\n });\n\n /**\n * Returns fabric.Textbox instance from an object representation\n * @static\n * @memberOf fabric.Textbox\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Textbox} instance of fabric.Textbox\n */\n fabric.Textbox.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Textbox', object, callback, forceAsync, 'text');\n };\n\n /**\n * Returns the default controls visibility required for Textboxes.\n * @returns {Object}\n */\n fabric.Textbox.getTextboxControlVisibility = function() {\n return {\n tl: false,\n tr: false,\n br: false,\n bl: false,\n ml: true,\n mt: false,\n mr: true,\n mb: false,\n mtr: true\n };\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n /**\n * Override _setObjectScale and add Textbox specific resizing behavior. Resizing\n * a Textbox doesn't scale text, it only changes width and makes text wrap automatically.\n */\n var setObjectScaleOverridden = fabric.Canvas.prototype._setObjectScale;\n\n fabric.Canvas.prototype._setObjectScale = function(localMouse, transform,\n lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {\n\n var t = transform.target;\n if (t instanceof fabric.Textbox) {\n var w = t.width * ((localMouse.x / transform.scaleX) / (t.width + t.strokeWidth));\n if (w >= t.getMinWidth()) {\n t.set('width', w);\n return true;\n }\n }\n else {\n return setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform,\n lockScalingX, lockScalingY, by, lockScalingFlip, _dim);\n }\n };\n\n /**\n * Sets controls of this group to the Textbox's special configuration if\n * one is present in the group. Deletes _controlsVisibility otherwise, so that\n * it gets initialized to default value at runtime.\n */\n fabric.Group.prototype._refreshControlsVisibility = function() {\n if (typeof fabric.Textbox === 'undefined') {\n return;\n }\n for (var i = this._objects.length; i--;) {\n if (this._objects[i] instanceof fabric.Textbox) {\n this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());\n return;\n }\n }\n };\n\n fabric.util.object.extend(fabric.Textbox.prototype, /** @lends fabric.IText.prototype */ {\n /**\n * @private\n */\n _removeExtraneousStyles: function() {\n for (var prop in this._styleMap) {\n if (!this._textLines[prop]) {\n delete this.styles[this._styleMap[prop].line];\n }\n }\n },\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Object} [style] Style object to insert, if given\n */\n insertCharStyleObject: function(lineIndex, charIndex, style) {\n // adjust lineIndex and charIndex\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n fabric.IText.prototype.insertCharStyleObject.apply(this, [lineIndex, charIndex, style]);\n },\n\n /**\n * Inserts new style object\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Boolean} isEndOfLine True if it's end of line\n */\n insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) {\n // adjust lineIndex and charIndex\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n fabric.IText.prototype.insertNewlineStyleObject.apply(this, [lineIndex, charIndex, isEndOfLine]);\n },\n\n /**\n * Shifts line styles up or down. This function is slightly different than the one in\n * itext_behaviour as it takes into account the styleMap.\n *\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can be -1 or +1\n */\n shiftLineStyles: function(lineIndex, offset) {\n // shift all line styles by 1 upward\n var map = this._styleMap[lineIndex];\n // adjust line index\n lineIndex = map.line;\n fabric.IText.prototype.shiftLineStyles.call(this, lineIndex, offset);\n },\n\n /**\n * Figure out programatically the text on previous actual line (actual = separated by \\n);\n *\n * @param {Number} lIndex\n * @returns {String}\n * @private\n */\n _getTextOnPreviousLine: function(lIndex) {\n var textOnPreviousLine = this._textLines[lIndex - 1];\n\n while (this._styleMap[lIndex - 2] && this._styleMap[lIndex - 2].line === this._styleMap[lIndex - 1].line) {\n textOnPreviousLine = this._textLines[lIndex - 2] + textOnPreviousLine;\n\n lIndex--;\n }\n\n return textOnPreviousLine;\n },\n\n /**\n * Removes style object\n * @param {Boolean} isBeginningOfLine True if cursor is at the beginning of line\n * @param {Number} [index] Optional index. When not given, current selectionStart is used.\n */\n removeStyleObject: function(isBeginningOfLine, index) {\n\n var cursorLocation = this.get2DCursorLocation(index),\n map = this._styleMap[cursorLocation.lineIndex],\n lineIndex = map.line,\n charIndex = map.offset + cursorLocation.charIndex;\n this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex);\n }\n });\n})();\n\n\n(function() {\n var override = fabric.IText.prototype._getNewSelectionStartFromOffset;\n /**\n * Overrides the IText implementation and adjusts character index as there is not always a linebreak\n *\n * @param {Number} mouseOffset\n * @param {Number} prevWidth\n * @param {Number} width\n * @param {Number} index\n * @param {Number} jlen\n * @returns {Number}\n */\n fabric.IText.prototype._getNewSelectionStartFromOffset = function(mouseOffset, prevWidth, width, index, jlen) {\n index = override.call(this, mouseOffset, prevWidth, width, index, jlen);\n\n // the index passed into the function is padded by the amount of lines from _textLines (to account for \\n)\n // we need to remove this padding, and pad it by actual lines, and / or spaces that are meant to be there\n var tmp = 0,\n removed = 0;\n\n // account for removed characters\n for (var i = 0; i < this._textLines.length; i++) {\n tmp += this._textLines[i].length;\n\n if (tmp + removed >= index) {\n break;\n }\n\n if (this.text[tmp + removed] === '\\n' || this.text[tmp + removed] === ' ') {\n removed++;\n }\n }\n\n return index - i + removed;\n };\n})();\n\n\n(function() {\n\n if (typeof document !== 'undefined' && typeof window !== 'undefined') {\n return;\n }\n\n var DOMParser = require('xmldom').DOMParser,\n URL = require('url'),\n HTTP = require('http'),\n HTTPS = require('https'),\n\n Canvas = require('canvas'),\n Image = require('canvas').Image;\n\n /** @private */\n function request(url, encoding, callback) {\n var oURL = URL.parse(url);\n\n // detect if http or https is used\n if ( !oURL.port ) {\n oURL.port = ( oURL.protocol.indexOf('https:') === 0 ) ? 443 : 80;\n }\n\n // assign request handler based on protocol\n var reqHandler = (oURL.protocol.indexOf('https:') === 0 ) ? HTTPS : HTTP,\n req = reqHandler.request({\n hostname: oURL.hostname,\n port: oURL.port,\n path: oURL.path,\n method: 'GET'\n }, function(response) {\n var body = '';\n if (encoding) {\n response.setEncoding(encoding);\n }\n response.on('end', function () {\n callback(body);\n });\n response.on('data', function (chunk) {\n if (response.statusCode === 200) {\n body += chunk;\n }\n });\n });\n\n req.on('error', function(err) {\n if (err.errno === process.ECONNREFUSED) {\n fabric.log('ECONNREFUSED: connection refused to ' + oURL.hostname + ':' + oURL.port);\n }\n else {\n fabric.log(err.message);\n }\n callback(null);\n });\n\n req.end();\n }\n\n /** @private */\n function requestFs(path, callback) {\n var fs = require('fs');\n fs.readFile(path, function (err, data) {\n if (err) {\n fabric.log(err);\n throw err;\n }\n else {\n callback(data);\n }\n });\n }\n\n fabric.util.loadImage = function(url, callback, context) {\n function createImageAndCallBack(data) {\n if (data) {\n img.src = new Buffer(data, 'binary');\n // preserving original url, which seems to be lost in node-canvas\n img._src = url;\n callback && callback.call(context, img);\n }\n else {\n img = null;\n callback && callback.call(context, null, true);\n }\n }\n var img = new Image();\n if (url && (url instanceof Buffer || url.indexOf('data') === 0)) {\n img.src = img._src = url;\n callback && callback.call(context, img);\n }\n else if (url && url.indexOf('http') !== 0) {\n requestFs(url, createImageAndCallBack);\n }\n else if (url) {\n request(url, 'binary', createImageAndCallBack);\n }\n else {\n callback && callback.call(context, url);\n }\n };\n\n fabric.loadSVGFromURL = function(url, callback, reviver) {\n url = url.replace(/^\\n\\s*/, '').replace(/\\?.*$/, '').trim();\n if (url.indexOf('http') !== 0) {\n requestFs(url, function(body) {\n fabric.loadSVGFromString(body.toString(), callback, reviver);\n });\n }\n else {\n request(url, '', function(body) {\n fabric.loadSVGFromString(body, callback, reviver);\n });\n }\n };\n\n fabric.loadSVGFromString = function(string, callback, reviver) {\n var doc = new DOMParser().parseFromString(string);\n fabric.parseSVGDocument(doc.documentElement, function(results, options) {\n callback && callback(results, options);\n }, reviver);\n };\n\n fabric.util.getScript = function(url, callback) {\n request(url, '', function(body) {\n // eslint-disable-next-line no-eval\n eval(body);\n callback && callback();\n });\n };\n\n // fabric.util.createCanvasElement = function(_, width, height) {\n // return new Canvas(width, height);\n // }\n\n /**\n * Only available when running fabric on node.js\n * @param {Number} width Canvas width\n * @param {Number} height Canvas height\n * @param {Object} [options] Options to pass to FabricCanvas.\n * @param {Object} [nodeCanvasOptions] Options to pass to NodeCanvas.\n * @return {Object} wrapped canvas instance\n */\n fabric.createCanvasForNode = function(width, height, options, nodeCanvasOptions) {\n nodeCanvasOptions = nodeCanvasOptions || options;\n\n var canvasEl = fabric.document.createElement('canvas'),\n nodeCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions),\n nodeCacheCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions);\n\n // jsdom doesn't create style on canvas element, so here be temp. workaround\n canvasEl.style = { };\n\n canvasEl.width = nodeCanvas.width;\n canvasEl.height = nodeCanvas.height;\n options = options || { };\n options.nodeCanvas = nodeCanvas;\n options.nodeCacheCanvas = nodeCacheCanvas;\n var FabricCanvas = fabric.Canvas || fabric.StaticCanvas,\n fabricCanvas = new FabricCanvas(canvasEl, options);\n fabricCanvas.nodeCanvas = nodeCanvas;\n fabricCanvas.nodeCacheCanvas = nodeCacheCanvas;\n fabricCanvas.contextContainer = nodeCanvas.getContext('2d');\n fabricCanvas.contextCache = nodeCacheCanvas.getContext('2d');\n fabricCanvas.Font = Canvas.Font;\n return fabricCanvas;\n };\n\n var originaInitStatic = fabric.StaticCanvas.prototype._initStatic;\n fabric.StaticCanvas.prototype._initStatic = function(el, options) {\n el = el || fabric.document.createElement('canvas');\n this.nodeCanvas = new Canvas(el.width, el.height);\n this.nodeCacheCanvas = new Canvas(el.width, el.height);\n originaInitStatic.call(this, el, options);\n this.contextContainer = this.nodeCanvas.getContext('2d');\n this.contextCache = this.nodeCacheCanvas.getContext('2d');\n this.Font = Canvas.Font;\n };\n\n /** @ignore */\n fabric.StaticCanvas.prototype.createPNGStream = function() {\n return this.nodeCanvas.createPNGStream();\n };\n\n fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {\n return this.nodeCanvas.createJPEGStream(opts);\n };\n\n fabric.StaticCanvas.prototype._initRetinaScaling = function() {\n if (!this._isRetinaScaling()) {\n return;\n }\n\n this.lowerCanvasEl.setAttribute('width', this.width * fabric.devicePixelRatio);\n this.lowerCanvasEl.setAttribute('height', this.height * fabric.devicePixelRatio);\n this.nodeCanvas.width = this.width * fabric.devicePixelRatio;\n this.nodeCanvas.height = this.height * fabric.devicePixelRatio;\n this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio);\n return this;\n };\n if (fabric.Canvas) {\n fabric.Canvas.prototype._initRetinaScaling = fabric.StaticCanvas.prototype._initRetinaScaling;\n }\n\n var origSetBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension;\n fabric.StaticCanvas.prototype._setBackstoreDimension = function(prop, value) {\n origSetBackstoreDimension.call(this, prop, value);\n this.nodeCanvas[prop] = value;\n return this;\n };\n if (fabric.Canvas) {\n fabric.Canvas.prototype._setBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension;\n }\n\n})();\n\n"]} \ No newline at end of file +{"version":3,"sources":["fabric.js"],"names":["fabric","version","exports","document","window","require","jsdom","decodeURIComponent","createWindow","parentWindow","isTouchSupported","isLikelyNode","Buffer","SHARED_ATTRIBUTES","DPI","reNum","fontPaths","iMatrix","canvasModule","perfLimitSizeTotal","maxCacheSideLimit","minCacheSideLimit","charWidthsCache","devicePixelRatio","webkitDevicePixelRatio","mozDevicePixelRatio","_removeEventListener","eventName","handler","this","__eventListeners","eventListener","indexOf","util","array","fill","observe","arguments","length","prop","on","push","stopObserving","call","fire","options","listenersForEvent","i","len","filter","value","Observable","off","trigger","Collection","_objects","add","apply","_onObjectAdded","renderOnAddRemove","renderAll","insertAt","object","index","nonSplicing","objects","getObjects","splice","remove","somethingRemoved","_onObjectRemoved","forEachObject","callback","context","type","o","item","isEmpty","size","contains","complexity","reduce","memo","current","CommonMethods","_setOptions","set","_initGradient","filler","property","colorStops","Gradient","_initPattern","source","Pattern","_initClipping","clipTo","functionBody","getFunctionBody","Function","_setObject","obj","_set","key","get","toggle","global","sqrt","Math","atan2","pow","abs","PiBy180","PI","removeFromArray","idx","getRandomInt","min","max","floor","random","degreesToRadians","degrees","radiansToDegrees","radians","rotatePoint","point","origin","subtractEquals","v","rotateVector","Point","x","y","addEquals","vector","sin","cos","transformPoint","p","t","ignoreOffset","makeBoundingBoxFromPoints","points","xPoints","minX","maxX","width","yPoints","minY","maxY","left","top","height","invertTransform","a","r","toFixed","number","fractionDigits","parseFloat","Number","parseUnit","fontSize","unit","exec","Text","DEFAULT_SVG_FONT_SIZE","falseFunction","getKlass","namespace","string","camelize","charAt","toUpperCase","slice","resolveNamespace","parts","split","loadImage","url","crossOrigin","img","createImage","onload","onerror","log","src","enlivenObjects","reviver","onLoaded","numLoadedObjects","numTotalObjects","enlivenedObjects","forEach","fromObject","error","enlivenPatterns","patterns","numLoadedPatterns","numPatterns","enlivenedPatterns","pattern","groupSVGElements","elements","path","PathGroup","sourcePath","populateWithProperties","destination","properties","Object","prototype","toString","drawDashedLine","ctx","x2","y2","da","dx","dy","rot","dc","di","draw","save","translate","moveTo","rotate","restore","createCanvasElement","canvasEl","createElement","getContext","G_vmlCanvasManager","initElement","createAccessors","klass","propName","capitalizedPropName","setterName","getterName","proto","stateProperties","clipContext","receiver","beginPath","clip","multiplyTransformMatrices","b","is2x2","qrDecompose","angle","denom","scaleX","scaleY","skewX","skewY","translateX","translateY","customTransformMatrix","skewMatrixX","tan","scaleMatrix","resetObjectTransform","target","flipX","flipY","setAngle","fn","String","match","isTransparent","tolerance","_isTransparent","imageData","getImageData","l","data","parsePreserveAspectRatioAttribute","attribute","align","meetOrSlice","aspectRatioAttrs","pop","alignX","alignY","clearFabricFontCache","fontFamily","limitDimsByArea","ar","maximumArea","roughWidth","perfLimitSizeY","capValue","arcToSegmentsCache","segmentToBezierCache","boundsOfCurveCache","_join","Array","join","arcToSegments","toX","toY","rx","ry","large","sweep","rotateX","argsString","th","sinTh","cosTh","fromX","fromY","px","py","rx2","ry2","py2","px2","pl","root","s","cx","cy","cx1","cy1","mTheta","calcVectorAngle","dtheta","segments","ceil","result","mDelta","mT","th3","segmentToBezier","th2","argsString2","costh2","sinth2","costh3","sinth3","cp1X","cp1Y","cp2X","cp2Y","ux","uy","vx","vy","ta","tb","getBoundsOfCurve","x0","y0","x1","y1","x3","y3","c","t1","t2","b2ac","sqrtb2ac","tvalues","bounds","mt","j","jlen","drawArc","fx","fy","coords","segs","segsNorm","bezierCurveTo","getBoundsOfArc","tx","ty","bound","find","byProperty","condition","searchElement","TypeError","n","POSITIVE_INFINITY","NEGATIVE_INFINITY","k","map","every","some","val","rv","invoke","method","args","value1","value2","extend","deep","Element","hasOwnProperty","clone","trim","replace","character","capitalize","firstLetterOnly","toLowerCase","escapeXml","Dummy","bind","thisArg","_this","concat","emptyFunction","addMethods","parent","superclass","constructor","returnValue","IS_DONTENUM_BUGGY","valueOf","Subclass","callSuper","methodName","parentMethod","superClassMethod","console","createClass","initialize","shift","subclasses","unknown","areHostMethods","methodNames","test","getElement","setElement","uid","getUniqueId","element","__uniqueID","createListener","wrappedHandler","e","event","createWrappedHandler","addListener","removeListener","shouldUseAddListenerRemoveListener","documentElement","shouldUseAttachEventDetachEvent","listeners","handlers","addEventListener","removeEventListener","listener","attachEvent","detachEvent","existingHandler","handlersForEvent","createDispatcher","pointerX","clientX","pointerY","clientY","_getPointer","pageProp","clientProp","touchProp","getPointer","srcElement","scroll","getScrollLeftTop","parseEl","supportsOpacity","style","opacity","supportsFilters","reOpacity","setOpacity","es","currentStyle","hasLayout","zoom","setStyle","styles","elementStyle","cssText","styleFloat","_slice","sliceCanConvertNodelists","getElementStyle","selectProp","toArray","arrayLike","childNodes","err","makeElement","tagName","attributes","el","className","htmlFor","setAttribute","docElement","body","scrollLeft","scrollTop","parentNode","host","nodeType","arr","defaultView","getComputedStyle","attr","undefined","makeElementUnselectable","onselectstart","unselectable","makeElementSelectable","getScript","headEl","getElementsByTagName","scriptEl","loading","onreadystatechange","readyState","appendChild","getById","id","getElementById","addClass","wrapElement","wrapper","replaceChild","getElementOffset","docElem","scrollLeftTop","doc","ownerDocument","box","offset","offsetAttributes","borderLeftWidth","borderTopWidth","paddingLeft","paddingTop","parseInt","getBoundingClientRect","clientLeft","clientTop","makeXHR","factories","ActiveXObject","XMLHttpRequest","emptyFn","request","onComplete","xhr","parameters","param","addParamToUrl","open","setRequestHeader","send","warn","noop","_requestAnimFrame","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","setTimeout","requestAnimFrame","animate","timestamp","time","start","Date","duration","finish","onChange","abort","easing","d","startValue","endValue","byValue","onStart","tick","ticktime","currentTime","timePerc","valuePerc","animateColor","fromColor","toColor","startColor","Color","getSource","endColor","begin","end","pos","color","calculateColor","colorEasing","normalize","asin","elastic","opts","easeInBounce","easeOutBounce","ease","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInSine","easeOutSine","easeInOutSine","easeInExpo","easeOutExpo","easeInOutExpo","easeInCirc","easeOutCirc","easeInOutCirc","easeInElastic","easeOutElastic","easeInOutElastic","easeInBack","easeOutBack","easeInOutBack","easeInOutBounce","commaWsp","transform","reTransformList","reTransform","reAllowedSVGTagNames","reViewBoxTagNames","reNotAllowedAncestors","reAllowedParents","attributesMap","display","visibility","fill-opacity","fill-rule","font-family","font-size","font-style","font-weight","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-decoration","text-anchor","colorAttributes","stroke","_getMultipleNodes","nodeNames","nodeName","nodeList","nodeArray","skewMatrix","matrix","elementMatchesRule","selectors","firstMatching","parentMatching","selectorMatches","selector","doesSomeParentMatch","matcher","classNames","getAttribute","RegExp","elementById","node","nodelist","cssRules","gradientDefs","parseTransformAttribute","attributeValue","matrices","m","operation","translateMatrix","rotateMatrix","multiplierX","multiplierY","combinedMatrix","reViewBoxAttrValue","applyViewboxTransform","viewBoxWidth","viewBoxHeight","viewBoxAttr","widthAttr","heightAttr","preserveAspectRatio","missingViewBox","missingDimAttr","toBeParsed","parsedDim","firstChild","parseSVGDocument","parsingOptions","attrs","xlink","substr","el2","cloneNode","currentTrans","oldLength","el3","nodeValue","removeAttribute","parseUseDirectives","svgUid","__uid","descendants","selectNodes","hasAncestorWithNodeName","getGradientDefs","getCSSRules","parseElements","instances","reFontDeclaration","parseFontDeclaration","oStyle","fontStyle","fontWeight","lineHeight","isNaN","elList","idsToXlinkMap","parseAttributes","parentAttributes","ownAttributes","rule","getGlobalStylesForElement","parseStyleAttribute","normalizedAttr","normalizedValue","parsed","isArray","normalizedStyle","transformMatrix","visible","font","mergedAttrs","setAlpha","getAlpha","toRgba","_setStrokeFillOpacity","ElementsParser","parse","chunk","pair","parseStyleString","parseStyleObject","parsePointsAttribute","parsedPoints","allRules","styleContents","textContent","text","ruleObj","propertyValuePairs","_rule","loadSVGFromURL","xml","responseXML","responseText","async","loadXML","results","_options","loadSVGFromString","DOMParser","parser","parseFromString","numElements","createObjects","_obj","createObject","fromElement","_createObject","checkIfDone","createCallback","resolveGradient","instanceFillValue","gradientId","that","scalarAdd","scalar","scalarAddEquals","subtract","scalarSubtract","scalarSubtractEquals","multiply","multiplyEquals","divide","divideEquals","eq","lt","lte","gt","gte","lerp","distanceFrom","midPointFrom","setXY","setX","setY","setFromPoint","swap","Intersection","status","appendPoint","appendPoints","intersectLineLine","a1","a2","b1","b2","uaT","ubT","uB","ua","ub","intersectLinePolygon","inter","intersectPolygonPolygon","points1","points2","intersectPolygonRectangle","r1","r2","topRight","bottomLeft","inter1","inter2","inter3","inter4","_tryParsingColor","setSource","hue2rgb","q","colorNameMap","sourceFromHex","sourceFromRgb","sourceFromHsl","_rgbToHsl","g","h","round","_source","toRgb","toHsl","hsl","toHsla","toHex","toHexa","alpha","toGrayscale","average","currentAlpha","toBlackWhite","threshold","overlayWith","otherColor","otherSource","reRGBa","reHSLa","reHex","aqua","black","blue","fuchsia","gray","grey","green","lime","maroon","navy","olive","orange","purple","red","silver","teal","white","yellow","fromRgb","fromSource","fromRgba","fromHsl","fromHsla","fromHex","isShortNotation","isRGBa","substring","oColor","getColorStop","colorAlpha","keyValuePairs","_convertPercentUnitsToValues","gradientUnits","propValue","addFactor","multFactor","ellipseMatrix","scaleFactor","offsetX","offsetY","gradientTransform","addColorStop","position","toObject","propertiesToInclude","toSVG","markup","commonAttributes","needsSwap","sort","group","reverse","minRadius","percentageShift","colorStop","toLive","gradient","createLinearGradient","createRadialGradient","instance","colorStopEls","getLinearCoords","getRadialCoords","forObject","repeat","setOptions","NUM_FRACTION_DIGITS","toDataURL","patternSource","patternWidth","patternHeight","patternOffsetX","patternOffsetY","patternImgSrc","complete","naturalWidth","naturalHeight","createPattern","Shadow","blur","affectStroke","includeDefaultValues","_parseShadow","shadow","shadowStr","offsetsAndBlur","reOffsetsAndBlur","fBoxX","fBoxY","StaticCanvas","CANVAS_INIT_ERROR","Error","_initStatic","backgroundColor","backgroundImage","overlayColor","overlayImage","stateful","controlsAboveOverlay","allowTouchScrolling","imageSmoothingEnabled","viewportTransform","backgroundVpt","overlayVpt","onBeforeScaleRotate","enableRetinaScaling","vptCoords","skipOffscreen","cb","_createLowerCanvas","_initOptions","_setImageSmoothing","interactive","_initRetinaScaling","setOverlayImage","setBackgroundImage","setBackgroundColor","setOverlayColor","calcOffset","_isRetinaScaling","getRetinaScaling","lowerCanvasEl","contextContainer","scale","_offset","image","__setBgOverlayImage","__setBgOverlayColor","webkitImageSmoothingEnabled","mozImageSmoothingEnabled","msImageSmoothingEnabled","oImageSmoothingEnabled","Image","_createCanvasElement","_applyCanvasStyle","getWidth","getHeight","setWidth","setDimensions","setHeight","dimensions","cssValue","cssOnly","_setBackstoreDimension","backstoreOnly","_setCssDimension","upperCanvasEl","cacheCanvasEl","wrapperEl","getZoom","setViewportTransform","vpt","activeGroup","_activeGroup","setCoords","calcViewportBoundaries","zoomToPoint","before","after","setZoom","absolutePan","relativePan","setupState","canvas","clearContext","clearRect","clear","_hasITextHandlers","_mouseUpITextHandler","_iTextInstances","canvasToDrawOn","renderCanvas","iVpt","tl","br","tr","bl","_renderBackground","_renderObjects","drawControls","_renderOverlay","render","_renderBackgroundOrOverlay","fillStyle","fillRect","getCenter","centerObjectH","_centerObject","getCenterPoint","centerObjectV","centerObject","center","viewportCenterObject","vpCenter","getVpCenter","viewportCenterObjectH","viewportCenterObjectV","setPositionByOrigin","toDatalessJSON","toDatalessObject","_toObjectMethod","_toObjects","__serializeBgOverlay","excludeFromExport","_toObject","originalValue","bgImage","overlay","background","svgViewportTransformation","_setSVGPreamble","_setSVGHeader","_setSVGBgOverlayColor","_setSVGBgOverlayImage","_setSVGObjects","suppressPreamble","encoding","viewBox","createSVGFontFacesMarkup","createSVGRefElementsMarkup","row","rowIndex","charIndex","fontList","_setSVGObject","sendToBack","objs","unshift","bringToFront","sendBackwards","intersecting","newIdx","objsMoved","_findNewLowerIndex","intersectsWithObject","isContainedWithinObject","bringForward","_findNewUpperIndex","dispose","DataURLExporter","EMPTY_JSON","supports","setLineDash","toJSON","BaseBrush","strokeLineCap","strokeLineJoin","strokeDashArray","setShadow","_setBrushStyles","contextTop","strokeStyle","lineWidth","lineCap","lineJoin","_setShadow","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY","_resetShadow","PencilBrush","_points","onMouseDown","pointer","_prepareForDrawing","_captureDrawingPath","_render","onMouseMove","onMouseUp","_finalizeAndAddPath","_reset","_addPoint","pointerPoint","p1","p2","midPoint","quadraticCurveTo","lineTo","convertPointsToSVGPath","multSignX","multSignY","manyPoints","createPath","pathData","Path","strokeWidth","originX","originY","translateToGivenOrigin","closePath","CircleBrush","drawDot","addPoint","arc","radius","originalRenderOnAddRemove","circles","circle","Circle","Group","circleRadius","circleColor","SprayBrush","density","dotWidth","dotWidthVariance","randomOpacity","optimizeOverlapping","sprayChunks","addSprayChunk","rects","ilen","sprayChunk","rect","Rect","_getOptimizedRects","uniqueRects","uniqueRectsArray","sprayChunkPoints","globalAlpha","PatternBrush","getPatternSrc","patternCanvas","patternCtx","getPatternSrcFunction","getPattern","topLeft","_getLeftTopCoords","supportLineDash","Canvas","_initInteractive","_createCacheCanvas","uniScaleTransform","uniScaleKey","centeredScaling","centeredRotation","centeredKey","altActionKey","selection","selectionKey","altSelectionKey","selectionColor","selectionDashArray","selectionBorderColor","selectionLineWidth","hoverCursor","moveCursor","defaultCursor","freeDrawingCursor","rotationCursor","containerClass","perPixelTargetFind","targetFindTolerance","skipTargetFind","isDrawingMode","preserveObjectStacking","snapAngle","snapThreshold","stopContextMenu","fireRightClick","fireMiddleClick","_currentTransform","_groupSelector","_initWrapperElement","_createUpperCanvas","_initEventListeners","freeDrawingBrush","_chooseObjectsToRender","getActiveGroup","activeObject","getActiveObject","objsToRender","activeGroupObjects","contextTopDirty","renderTop","_drawSelection","_resetCurrentTransform","original","_shouldCenterTransform","action","_setOriginToCenter","mouseXSign","mouseYSign","containsPoint","xy","_normalizePointer","_findTargetCorner","calcTransformMatrix","invertedM","vptPointer","restorePointerVpt","isTargetTransparent","hasBorders","transparentCorners","contextCache","originalColor","selectionBackgroundColor","active","_renderControls","_shouldClearSelection","evented","selectable","centerTransform","altKey","_getOriginFromCorner","corner","_getActionFromCorner","_setupCurrentTransform","ex","ey","lastX","lastY","theta","shiftKey","_translateObject","newLeft","newTop","moveX","moveY","_changeSkewTransformOrigin","mouseMove","by","origins","0","skew","originA","originB","flipSign","skewSign","_skewObject","skewed","lockSkewingX","lockSkewingY","actualMouseByOrigin","constraintPosition","actualMouseByCenter","toLocalPoint","lastMouseByCenter","dim","_getTransformedDimensions","translateToOriginPoint","_setObjectSkew","localMouse","_dim","newValue","newDim","dimNoSkew","otherBy","_otherBy","_by","newDimMouse","atan","_scaleObject","lockScalingX","lockScalingY","lockScalingFlip","scaled","_setLocalMouse","_setObjectScale","changeX","changeY","forbidScalingX","forbidScalingY","_scaleObjectEqually","newScaleX","newScaleY","_flipObject","dist","lastDist","signX","signY","padding","_rotateObject","lastAngle","curAngle","hasRoated","rightAngleLocked","leftAngleLocked","setCursor","cursor","_resetObjectTransform","groupSelector","aleft","atop","_setLineDash","strokeRect","findTarget","skipGroup","activeTarget","activeTargetSubs","targets","_searchPossibleTargets","_fireOverOutEvents","overOpt","outOpt","hoveredTarget","_hoveredTarget","previousTarget","nextTarget","_checkTarget","isEditing","normalizedPointer","subTarget","subTargetCheck","ignoreZoom","cssScale","boundsWidth","boundsHeight","bottom","right","lowerCanvasClass","_copyCanvasStyle","class","touch-action","fromEl","toEl","getSelectionContext","getSelectionElement","_setActiveObject","_activeObject","onDeselect","setActiveObject","currentActiveObject","_discardActiveObject","discardActiveObject","_setActiveGroup","setActiveGroup","_discardActiveGroup","destroy","discardActiveGroup","deactivateAll","allObjects","deactivateAllWithDispatch","removeListeners","removeChild","_drawObjectsControls","originalProperties","_realizeGroupTransformOnObject","_unwindGroupTransformOnObject","originalValues","realizeTransform","_setCursorFromEvent","cursorOffset","mr","mb","ml","checkClick","which","button","cursorMap","_bindEvents","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","passive","eventjs","_onGesture","_onDrag","_onOrientationChange","_onShake","_onLongPress","eventsBinded","_onMouseUp","self","__onTransformGesture","__onDrag","__onMouseWheel","hiddenTextarea","focus","__onOrientationChange","__onShake","__onLongPress","stopPropagation","preventDefault","__onMouseDown","__onMouseUp","__onMouseMove","_shouldRender","isMoving","_previousPointer","_handleEvent","_isCurrentlyDrawing","_onMouseUpInDrawingMode","searchTarget","isClick","_finalizeCurrentTransform","actionPerformed","shouldRender","_maybeGroupObjects","__corner","eventType","targetObj","subTargets","_scaling","_restoreOriginXY","hasStateChanged","_previousOriginX","_previousOriginY","originPoint","_onMouseDownInDrawingMode","_onMouseMoveInDrawingMode","shouldGroup","_shouldGroup","_handleGrouping","_beforeTransform","saveState","_setCenterToOrigin","touches","_transformObject","reset","_beforeScaleTransform","_performTransformAction","_fire","_onScale","currentAction","_setCornerCursor","_getRotatedCornerCursor","hasRotatingPoint","getAngle","_updateActiveGroup","_createActiveGroup","saveCoords","removeWithUpdate","addWithUpdate","_createGroup","groupObjects","exitEditing","_groupSelectedObjects","_collectObjects","currentObject","selectionX1Y1","selectionX2Y2","intersectsWithRect","isContainedWithinRect","setObjectsCoords","supportQuality","format","quality","multiplier","cropping","__toDataURLWithMultiplier","origWidth","origHeight","scaledWidth","scaledHeight","newZoom","vp","newVp","originalInteractive","__toDataURL","toDataURLWithMultiplier","loadFromDatalessJSON","json","loadFromJSON","serialized","JSON","_enlivenObjects","_setBgOverlay","loaded","cbIfLoaded","__setBgOverlay","enlivedObject","_toDataURL","_toDataURLWithMultiplier","stringify","cloneWithoutData","backgroundImageOpacity","backgroundImageStretch","supportsLineDash","objectCaching","cornerSize","borderColor","borderDashArray","cornerColor","cornerStrokeColor","cornerStyle","cornerDashArray","fillRule","globalCompositeOperation","strokeMiterLimit","borderOpacityWhenMoving","borderScaleFactor","minScaleLimit","hasControls","rotatingPointOffset","lockMovementX","lockMovementY","lockRotation","lockUniScaling","statefullCache","noScaleCache","dirty","cacheProperties","_cacheProperties","_cacheCanvas","_cacheContext","_updateCacheCanvas","_limitCacheSize","dims","limitedDims","zoomX","capped","zoomY","_getCacheCanvasDimensions","objectScale","getObjectScaling","retina","_getNonTransformedDimensions","drawingWidth","drawingHeight","minCacheSize","dimensionsChanged","cacheWidth","cacheHeight","zoomChanged","shouldRedraw","additionalWidth","additionalHeight","shouldResizeCanvas","canvasWidth","canvasHeight","sizeGrowing","setTransform","cacheTranslationX","cacheTranslationY","fromLeft","_transformDone","_removeDefaultValues","scaling","shouldConstrainValue","isChanged","_constrainScale","setOnGroup","setSourcePath","getViewportTransform","isNotVisible","noTransform","isOnScreen","_setupCompositeOperation","drawSelectionBackground","_setOpacity","shouldCache","isCacheDirty","propertySet","drawObject","drawCacheOnCanvas","_removeCacheCanvas","needsItsOwnCache","isCaching","willDrawShadow","_setStrokeStyles","_setFillStyles","drawImage","skipCanvas","_removeShadow","miterLimit","dashArray","alternative","drawBordersInGroup","drawBorders","multX","multY","_applyPatternGradientTransform","patternTransform","_renderFill","_renderStroke","_renderDashedStroke","cloneAsImage","dataUrl","boundingRect","getBoundingRect","origParams","getLeft","getTop","originalCanvas","isType","setGradient","setPatternFill","setColor","shouldCenterOrigin","_resetOrigin","centerH","viewportCenterH","centerV","viewportCenterV","viewportCenter","getLocalPointer","pClicked","objectLeftTop","_fromObject","forceAsync","extraParam","originXOffset","originYOffset","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","leftTop","getPointByOrigin","adjustPosition","to","offsetFrom","offsetTo","hypotFull","xFull","yFull","_originalOriginX","_originalOriginY","multiplyMatrices","oCoords","aCoords","getCoords","absolute","calculate","calcCoords","pointTL","pointBR","other","lines","_getImageLines","_findCrossPoints","centerPoint","topline","rightline","bottomline","leftline","iLine","xcount","lineKey","getBoundingRectWidth","getBoundingRectHeight","scaleToWidth","boundingRectFactor","scaleToHeight","_calculateCurrentDimensions","currentWidth","currentHeight","_angle","_hypotenuse","mtr","skipAbsolute","_setCornerCoords","_calcRotateMatrix","dimensionMatrix","_calcDimensionsTransformMatrix","flipping","bbox","dimX","dimY","getSvgColorString","str","getSvgStyles","skipShadow","getSvgFilter","getSvgId","getSvgTransform","getSkewX","getSkewY","translatePart","anglePart","scalePart","skewXPart","skewYPart","addTranslateX","flipXPart","addTranslateY","getSvgTransformMatrix","_createBaseSVGMarkup","originalSet","saveProps","props","tmpObj","dashedPropertySet","keys","_isEqual","origValue","currentValue","firstPass","_controlsVisibility","isControlVisible","newTheta","cornerHypotenuse","cosHalfOffset","sinHalfOffset","wh","rotateHeight","scaleOffset","_drawControl","control","controlName","_getControlsVisibility","setControlVisible","setControlsVisibility","FX_DURATION","fxCenterObjectH","callbacks","empty","fxCenterObjectV","fxRemove","skipCallbacks","propsToAnimate","_animate","propPair","from","valueProgress","timeProgress","coordProps","makeEdgeToOriginGetter","propertyNames","originValues","axis1","axis2","dimension","nearest","farthest","Line","_setWidthHeight","_getLeftToOriginX","_getTopToOriginY","cp","calcLinePoints","origStrokeStyle","xMult","yMult","ATTRIBUTE_NAMES","parsedAttributes","line","pi","startAngle","endAngle","setRadius","startX","startY","endX","endY","largeFlag","getRadiusX","getRadiusY","isValidRadius","Triangle","widthBy2","heightBy2","piBy2","Ellipse","getRx","getRy","ellipse","_initRxRy","w","isRounded","Polyline","_calcDimensions","pathOffset","diffX","diffY","commonRender","Polygon","_toString","commandLengths","repeatedCommands","M","fromArray","_parsePath","_setPositionDimensions","calcDim","_parseDimensions","_renderPathCommands","tempX","tempY","previous","subpathStartX","subpathStartY","controlX","controlY","chunks","addTransform","currentPath","coordsStr","coordsParsed","re","command","commandLength","repeatedCommand","klen","aX","aY","pathUrl","paths","parseDimensionsFromPaths","xC","yC","parentCache","caching","isSameColor","pathsToObject","originalDefaults","firstPathFill","pathFill","total","originalPaths","pathGroup","_lockProperties","isAlreadyGrouped","_updateObjectsCoords","_updateObjectsACoords","_calcBounds","skipCoordsChange","_updateObjectCoords","__origHasControls","objectLeft","objectTop","_restoreObjectsState","_setObjectActive","delegatedProperties","textDecoration","textAlign","objsToObject","_renderObject","originalHasRotatingPoint","_restoreObjectState","_originalLeft","_originalTop","hasMoved","onlyWidthHeight","iLen","jLen","_getBounds","minXY","maxXY","_lastScaleX","_lastScaleY","minimumScaleTrigger","filters","resizeFilters","_initElement","_element","_callback","_originalElement","_initConfig","applyFilters","_filteredEl","setCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","getSvgSrc","origFill","filtered","_src","setSrc","imgElement","forResizing","replacement","retinaScaling","minimumScale","applyTo","toBuffer","pngCompression","elementToDraw","imageMargins","_findMargins","_needsResize","marginX","marginY","scales","_resetWidthHeight","CSS_CANVAS","_initFilters","fromURL","imgOptions","preserveAR","_getAngleValueForStraighten","straighten","fxStraighten","straightenObject","fxStraightenObject","BaseFilter","Brightness","brightness","putImageData","Convolute","opaque","dstOff","scx","scy","srcOff","wt","weights","pixels","side","halfSide","sw","sh","output","createImageData","dst","alphaFac","GradientTransparency","Grayscale","Invert","Mask","mask","channel","maskEl","maskCanvasEl","maskData","Noise","noise","rand","Pixelate","blocksize","_i","_ilen","_j","_jlen","RemoveWhite","distance","limit","Sepia","avg","Sepia2","Tint","tintR","tintG","tintB","alpha1","Multiply","Blend","mode","tg","_r","_g","_b","isImage","_el","tmpCanvas","Resize","resizeType","lanczosLobes","rcpScaleX","rcpScaleY","oW","oH","dW","dH","sliceByTwo","hermiteFastResize","bilinearFiltering","lanczosResize","multW","multH","signW","signH","doneW","doneH","stepW","stepH","tmpCtx","lobes","srcImg","destImg","srcData","destData","lanczos","xx","ratioX","ratioY","rcpRatioX","rcpRatioY","range2X","range2Y","cacheLanc","icenter","process","u","weight","fX","fY","xDiff","yDiff","chnl","origPix","w4","destImage","destPixels","ratioW","ratioH","ratioWHalf","ratioHHalf","img2","data2","weightsAlpha","gxR","gxG","gxB","gxA","centerY","yy","centerX","w0","ColorMatrix","Contrast","contrast","contrastF","Saturate","saturate","adjust","_dimensionAffectingProps","_reNewline","_reSpacesAndTabs","textBackgroundColor","_fontSizeFraction","_fontSizeMult","charSpacing","__skipDimension","_initDimensions","_setTextStyles","_textLines","_splitTextIntoLines","_clearCache","_getTextWidth","cursorWidth","_getTextHeight","_renderTextLinesBackground","_renderText","_renderTextDecoration","_renderTextFill","_renderTextStroke","textBaseline","_getFontDeclaration","_getHeightOfSingleLine","_getHeightOfLine","maxWidth","_getLineWidth","currentLineWidth","_renderChars","chars","_char","shortM","additionalSpace","_getWidthOfCharSpacing","measureText","_renderTextLine","lineIndex","word","words","charOffset","wordsWidth","_getWidthOfWords","widthDiff","numSpaces","spaceWidth","leftOffset","_getLeftOffset","_getTopOffset","isEmptyStyles","_renderTextCommon","lineHeights","heightOfLine","maxHeight","_getLineLeftOffset","lineLeftOffset","lineTopOffset","originalFill","__lineWidths","__lineHeights","_shouldClearDimensionCache","shouldClear","_forceClearCache","_measureLine","finalWidth","halfOfVerticalBox","offsets","oLen","renderLinesAtOffset","additionalProperties","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","lineTop","textBgRects","textSpans","textTopOffset","textLeftOffset","_setSVGBg","_setSVGTextLineBg","_setSVGTextLineText","yPos","_getFillAttributes","_setSVGTextLineJustifed","fillColor","textHeightScaleFactor","scaledDiff","textHeight","offX","IText","selectionStart","selectionEnd","editable","editingBorderColor","cursorColor","cursorDelay","cursorDuration","_reSpace","_currentCursorOpacity","_selectionDirection","_abortCursorAnimation","__widthOfSpace","initBehavior","p3","setSelectionStart","_updateAndFire","setSelectionEnd","_fireSelectionChanged","_updateTextarea","getSelectionStyles","startIndex","endIndex","loc","get2DCursorLocation","_getStyleDeclaration","setSelectionStyles","_extendStyles","_getLineStyle","_setLineStyle","_setStyleDeclaration","clearContextTop","cursorOffsetCache","renderCursorOrSelection","_clearTextArea","boundaries","_getCursorBoundaries","renderCursor","renderSelection","getCurrentCharStyle","getCurrentCharFontSize","getCurrentCharColor","typeOfBoundaries","_getCursorBoundariesOffsets","lineLeft","topOffset","_getWidthOfChar","cursorLocation","charHeight","__isMousedown","startLine","endLine","realLineHeight","lineOffset","boxWidth","j2","j2len","_renderCharsFast","prevStyle","thisStyle","charsToRender","_hasStyleChanged","_renderChar","skipFillStrokeCheck","charWidth","shouldFill","shouldStroke","_charWidth","decl","_getHeightOfChar","_applyCharStylesGetWidth","jChar","fillText","strokeText","_renderCharDecoration","decoration","decorationWeight","positions","underline","line-through","overline","decorations","leftCache","topCache","widthCache","heightCache","colorCache","_getWidthOfCharsAt","_getCacheProp","styleDeclaration","_getFontCache","cacheProp","charDecl","_applyFontStyles","returnCloneOrEmpty","_deleteStyleDeclaration","_deleteLineStyle","_isMeasuring","_getWidthOfSpace","currentCharHeight","initAddedHandler","initRemovedHandler","initCursorSelectionHandlers","initDoubleClickSimulation","mouseMoveHandler","selected","_initCanvasHandlers","_removeCanvasHandlers","_tick","_currentTickState","_animateCursor","targetOpacity","completeMethod","tickState","isAborted","_onTickComplete","_cursorTimeout1","clearTimeout","_currentTickCompleteState","initDelayedCursor","restart","delay","abortCursorAnimation","_cursorTimeout2","selectAll","getSelectedText","findWordBoundaryLeft","startFrom","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","getNumNewLinesInSelectedText","selectedText","numNewLines","searchWordBoundary","direction","reNonWord","selectWord","newSelectionStart","newSelectionEnd","selectLine","enterEditing","exitEditingOnOthers","initHiddenTextarea","_saveEditingProps","_setEditingProps","_textBeforeEdit","initMouseMoveHandler","getSelectionStartFromPointer","currentStart","currentEnd","__selectionStartOnMouseDown","restartCursorIfNeeded","inCompositionMode","_calcTextareaPosition","upperCanvas","_savedProps","_restoreEditingProps","overCursor","isTextChanged","_removeExtraneousStyles","_removeCharsFromTo","_removeSingleCharAndStyle","isBeginningOfLine","indexStyle","removeStyleObject","insertChars","_chars","useCopiedStyle","copiedTextStyle","insertChar","skipUpdate","styleObject","isEndOfLine","insertStyleObjects","insertNewlineStyleObject","shiftLineStyles","currentCharStyle","newLineStyles","somethingAdded","numIndex","insertCharStyleObject","currentLineStyles","currentLineStylesCloned","numericIndex","newStyle","clonedStyles","numericLine","_removeStyleObject","_getTextOnPreviousLine","lIndex","textOnPreviousLine","newCharIndexOnPrevLine","insertNewline","setSelectionStartEndWithShift","newSelection","setSelectionInBoundaries","__lastClickTime","__lastLastClickTime","__lastPointer","__newClickTime","newPointer","isTripleClick","_stopEvent","isDoubleClick","__lastIsEditing","__lastSelected","initMousedownHandler","initMouseupHandler","initClicks","__mousedownX","__mousedownY","setCursorByClick","_isObjectMoved","mouseOffset","prevWidth","widthOfLine","_getNewSelectionStartFromOffset","onKeyDown","onKeyUp","onInput","copy","cut","paste","onCompositionStart","onCompositionUpdate","onCompositionEnd","_clickHandlerInitialized","onClick","keysMap","8","9","27","13","33","34","35","36","37","38","39","40","46","ctrlKeysMapUp","67","88","ctrlKeysMapDown","65","keyCode","ctrlKey","metaKey","stopImmediatePropagation","_copyDone","diff","charsToInsert","offsetEnd","textLength","newTextLength","prevCompositionLength","compositionStart","forwardDelete","moveCursorRight","removeChars","clipboardData","_getClipboardData","setData","copiedText","getData","_getWidthBeforeCursor","textBeforeCursor","widthBeforeCursor","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","indexOnOtherLine","_getIndexOnLine","getUpCursorOffset","foundMatch","textOnLine","widthOfCharsOnLine","indexOnLine","widthOfChar","leftEdge","rightEdge","offsetFromLeftEdge","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","moveCursorWithShift","moveCursorWithoutShift","moveCursorLeft","_moveCursorLeftOrRight","_move","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","actionName","moveCursorRightWithShift","moveCursorRightWithoutShift","changed","_removeCharsNearCursor","leftLineBoundary","leftWordBoundary","_setSVGTextLineChars","_getSVGLineTopOffset","styleDecl","_createTextCharSpan","_createTextCharBg","lastHeight","fillStyles","Textbox","minWidth","dynamicMinWidth","__cachedLines","getTextboxControlVisibility","_generateStyleMap","realLineCount","realLineCharCount","charCount","_styleMap","_wrapText","wrapped","_wrapLine","_measureText","wordWidth","infixWidth","largestWordWidth","lineJustStarted","originalAlign","__oldScaleX","numLines","removed","lineLen","lineChars","getMinWidth","setObjectScaleOverridden","_refreshControlsVisibility","override","tmp","URL","HTTP","HTTPS","createImageAndCallBack","requestFs","eval","createCanvasForNode","nodeCanvasOptions","nodeCanvas","nodeCacheCanvas","fabricCanvas","Font","originaInitStatic","createPNGStream","createJPEGStream","origSetBackstoreDimension","oURL","port","protocol","req","hostname","response","setEncoding","statusCode","errno","ECONNREFUSED","message","readFile"],"mappings":"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","file":"fabric.js","sourcesContent":["/* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */\n /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */\n\nvar fabric = fabric || { version: \"1.7.22\" };\nif (typeof exports !== 'undefined') {\n exports.fabric = fabric;\n}\n\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n fabric.document = document;\n fabric.window = window;\n // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system)\n window.fabric = fabric;\n}\nelse {\n // assume we're running under node.js when document/window are not present\n fabric.document = require(\"jsdom\")\n .jsdom(\n decodeURIComponent(\"%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E\")\n );\n\n if (fabric.document.createWindow) {\n fabric.window = fabric.document.createWindow();\n } else {\n fabric.window = fabric.document.parentWindow;\n }\n}\n\n/**\n * True when in environment that supports touch events\n * @type boolean\n */\n\nfabric.isTouchSupported = 'ontouchstart' in fabric.window;\n\n/**\n * True when in environment that's probably Node.js\n * @type boolean\n */\nfabric.isLikelyNode = typeof Buffer !== 'undefined' &&\n typeof window === 'undefined';\n\n/* _FROM_SVG_START_ */\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\nfabric.SHARED_ATTRIBUTES = [\n \"display\",\n \"transform\",\n \"fill\", \"fill-opacity\", \"fill-rule\",\n \"opacity\",\n \"stroke\", \"stroke-dasharray\", \"stroke-linecap\",\n \"stroke-linejoin\", \"stroke-miterlimit\",\n \"stroke-opacity\", \"stroke-width\",\n \"id\"\n];\n/* _FROM_SVG_END_ */\n\n/**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\nfabric.DPI = 96;\nfabric.reNum = '(?:[-+]?(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:e[-+]?\\\\d+)?)';\nfabric.fontPaths = { };\nfabric.iMatrix = [1, 0, 0, 1, 0, 0];\nfabric.canvasModule = 'canvas';\n\n/**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.perfLimitSizeTotal = 2097152;\n\n/**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.maxCacheSideLimit = 4096;\n\n/**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.minCacheSideLimit = 256;\n\n/**\n * Cache Object for widths of chars in text rendering.\n */\nfabric.charWidthsCache = { };\n\n/**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\nfabric.devicePixelRatio = fabric.window.devicePixelRatio ||\n fabric.window.webkitDevicePixelRatio ||\n fabric.window.mozDevicePixelRatio ||\n 1;\n\n\n(function() {\n\n /**\n * @private\n * @param {String} eventName\n * @param {Function} handler\n */\n function _removeEventListener(eventName, handler) {\n if (!this.__eventListeners[eventName]) {\n return;\n }\n var eventListener = this.__eventListeners[eventName];\n if (handler) {\n eventListener[eventListener.indexOf(handler)] = false;\n }\n else {\n fabric.util.array.fill(eventListener, false);\n }\n }\n\n /**\n * Observes specified event\n * @deprecated `observe` deprecated since 0.8.34 (use `on` instead)\n * @memberOf fabric.Observable\n * @alias on\n * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Self} thisArg\n * @chainable\n */\n function observe(eventName, handler) {\n if (!this.__eventListeners) {\n this.__eventListeners = { };\n }\n // one object with key/value pairs was passed\n if (arguments.length === 1) {\n for (var prop in eventName) {\n this.on(prop, eventName[prop]);\n }\n }\n else {\n if (!this.__eventListeners[eventName]) {\n this.__eventListeners[eventName] = [];\n }\n this.__eventListeners[eventName].push(handler);\n }\n return this;\n }\n\n /**\n * Stops event observing for a particular event handler. Calling this method\n * without arguments removes all handlers for all events\n * @deprecated `stopObserving` deprecated since 0.8.34 (use `off` instead)\n * @memberOf fabric.Observable\n * @alias off\n * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function to be deleted from EventListeners\n * @return {Self} thisArg\n * @chainable\n */\n function stopObserving(eventName, handler) {\n if (!this.__eventListeners) {\n return;\n }\n\n // remove all key/value pairs (event name -> event handler)\n if (arguments.length === 0) {\n for (eventName in this.__eventListeners) {\n _removeEventListener.call(this, eventName);\n }\n }\n // one object with key/value pairs was passed\n else if (arguments.length === 1 && typeof arguments[0] === 'object') {\n for (var prop in eventName) {\n _removeEventListener.call(this, prop, eventName[prop]);\n }\n }\n else {\n _removeEventListener.call(this, eventName, handler);\n }\n return this;\n }\n\n /**\n * Fires event with an optional options object\n * @deprecated `fire` deprecated since 1.0.7 (use `trigger` instead)\n * @memberOf fabric.Observable\n * @alias trigger\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n * @return {Self} thisArg\n * @chainable\n */\n function fire(eventName, options) {\n if (!this.__eventListeners) {\n return;\n }\n\n var listenersForEvent = this.__eventListeners[eventName];\n if (!listenersForEvent) {\n return;\n }\n\n for (var i = 0, len = listenersForEvent.length; i < len; i++) {\n listenersForEvent[i] && listenersForEvent[i].call(this, options || { });\n }\n this.__eventListeners[eventName] = listenersForEvent.filter(function(value) {\n return value !== false;\n });\n return this;\n }\n\n /**\n * @namespace fabric.Observable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n * @see {@link http://fabricjs.com/events|Events demo}\n */\n fabric.Observable = {\n observe: observe,\n stopObserving: stopObserving,\n fire: fire,\n\n on: observe,\n off: stopObserving,\n trigger: fire\n };\n})();\n\n\n/**\n * @namespace fabric.Collection\n */\nfabric.Collection = {\n\n _objects: [],\n\n /**\n * Adds objects to collection, Canvas or Group, then renders canvas\n * (if `renderOnAddRemove` is not `false`).\n * in case of Group no changes to bounding box are made.\n * Objects should be instances of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the add method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n add: function () {\n this._objects.push.apply(this._objects, arguments);\n if (this._onObjectAdded) {\n for (var i = 0, length = arguments.length; i < length; i++) {\n this._onObjectAdded(arguments[i]);\n }\n }\n this.renderOnAddRemove && this.renderAll();\n return this;\n },\n\n /**\n * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`)\n * An object should be an instance of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the insertAt method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {Object} object Object to insert\n * @param {Number} index Index to insert object at\n * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs\n * @return {Self} thisArg\n * @chainable\n */\n insertAt: function (object, index, nonSplicing) {\n var objects = this.getObjects();\n if (nonSplicing) {\n objects[index] = object;\n }\n else {\n objects.splice(index, 0, object);\n }\n this._onObjectAdded && this._onObjectAdded(object);\n this.renderOnAddRemove && this.renderAll();\n return this;\n },\n\n /**\n * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n remove: function() {\n var objects = this.getObjects(),\n index, somethingRemoved = false;\n\n for (var i = 0, length = arguments.length; i < length; i++) {\n index = objects.indexOf(arguments[i]);\n\n // only call onObjectRemoved if an object was actually removed\n if (index !== -1) {\n somethingRemoved = true;\n objects.splice(index, 1);\n this._onObjectRemoved && this._onObjectRemoved(arguments[i]);\n }\n }\n\n this.renderOnAddRemove && somethingRemoved && this.renderAll();\n return this;\n },\n\n /**\n * Executes given function for each object in this group\n * @param {Function} callback\n * Callback invoked with current object as first argument,\n * index - as second and an array of all objects - as third.\n * Callback is invoked in a context of Global Object (e.g. `window`)\n * when no `context` argument is given\n *\n * @param {Object} context Context (aka thisObject)\n * @return {Self} thisArg\n * @chainable\n */\n forEachObject: function(callback, context) {\n var objects = this.getObjects();\n for (var i = 0, len = objects.length; i < len; i++) {\n callback.call(context, objects[i], i, objects);\n }\n return this;\n },\n\n /**\n * Returns an array of children objects of this instance\n * Type parameter introduced in 1.3.10\n * @param {String} [type] When specified, only objects of this type are returned\n * @return {Array}\n */\n getObjects: function(type) {\n if (typeof type === 'undefined') {\n return this._objects;\n }\n return this._objects.filter(function(o) {\n return o.type === type;\n });\n },\n\n /**\n * Returns object at specified index\n * @param {Number} index\n * @return {Self} thisArg\n */\n item: function (index) {\n return this.getObjects()[index];\n },\n\n /**\n * Returns true if collection contains no objects\n * @return {Boolean} true if collection is empty\n */\n isEmpty: function () {\n return this.getObjects().length === 0;\n },\n\n /**\n * Returns a size of a collection (i.e: length of an array containing its objects)\n * @return {Number} Collection size\n */\n size: function() {\n return this.getObjects().length;\n },\n\n /**\n * Returns true if collection contains an object\n * @param {Object} object Object to check against\n * @return {Boolean} `true` if collection contains an object\n */\n contains: function(object) {\n return this.getObjects().indexOf(object) > -1;\n },\n\n /**\n * Returns number representation of a collection complexity\n * @return {Number} complexity\n */\n complexity: function () {\n return this.getObjects().reduce(function (memo, current) {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n};\n\n\n/**\n * @namespace fabric.CommonMethods\n */\nfabric.CommonMethods = {\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n _setOptions: function(options) {\n for (var prop in options) {\n this.set(prop, options[prop]);\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Gradient to\n */\n _initGradient: function(filler, property) {\n if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) {\n this.set(property, new fabric.Gradient(filler));\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Pattern to\n * @param {Function} [callback] callback to invoke after pattern load\n */\n _initPattern: function(filler, property, callback) {\n if (filler && filler.source && !(filler instanceof fabric.Pattern)) {\n this.set(property, new fabric.Pattern(filler, callback));\n }\n else {\n callback && callback();\n }\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initClipping: function(options) {\n if (!options.clipTo || typeof options.clipTo !== 'string') {\n return;\n }\n\n var functionBody = fabric.util.getFunctionBody(options.clipTo);\n if (typeof functionBody !== 'undefined') {\n this.clipTo = new Function('ctx', functionBody);\n }\n },\n\n /**\n * @private\n */\n _setObject: function(obj) {\n for (var prop in obj) {\n this._set(prop, obj[prop]);\n }\n },\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n set: function(key, value) {\n if (typeof key === 'object') {\n this._setObject(key);\n }\n else {\n if (typeof value === 'function' && key !== 'clipTo') {\n this._set(key, value(this.get(key)));\n }\n else {\n this._set(key, value);\n }\n }\n return this;\n },\n\n _set: function(key, value) {\n this[key] = value;\n },\n\n /**\n * Toggles specified property from `true` to `false` or from `false` to `true`\n * @param {String} property Property to toggle\n * @return {fabric.Object} thisArg\n * @chainable\n */\n toggle: function(property) {\n var value = this.get(property);\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\n return this;\n },\n\n /**\n * Basic getter\n * @param {String} property Property name\n * @return {*} value of a property\n */\n get: function(property) {\n return this[property];\n }\n};\n\n\n(function(global) {\n\n var sqrt = Math.sqrt,\n atan2 = Math.atan2,\n pow = Math.pow,\n abs = Math.abs,\n PiBy180 = Math.PI / 180;\n\n /**\n * @namespace fabric.util\n */\n fabric.util = {\n\n /**\n * Removes value from an array.\n * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n * @static\n * @memberOf fabric.util\n * @param {Array} array\n * @param {*} value\n * @return {Array} original array\n */\n removeFromArray: function(array, value) {\n var idx = array.indexOf(value);\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n return array;\n },\n\n /**\n * Returns random number between 2 specified ones.\n * @static\n * @memberOf fabric.util\n * @param {Number} min lower limit\n * @param {Number} max upper limit\n * @return {Number} random value (between min and max)\n */\n getRandomInt: function(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n },\n\n /**\n * Transforms degrees to radians.\n * @static\n * @memberOf fabric.util\n * @param {Number} degrees value in degrees\n * @return {Number} value in radians\n */\n degreesToRadians: function(degrees) {\n return degrees * PiBy180;\n },\n\n /**\n * Transforms radians to degrees.\n * @static\n * @memberOf fabric.util\n * @param {Number} radians value in radians\n * @return {Number} value in degrees\n */\n radiansToDegrees: function(radians) {\n return radians / PiBy180;\n },\n\n /**\n * Rotates `point` around `origin` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} point The point to rotate\n * @param {fabric.Point} origin The origin of the rotation\n * @param {Number} radians The radians of the angle for the rotation\n * @return {fabric.Point} The new rotated point\n */\n rotatePoint: function(point, origin, radians) {\n point.subtractEquals(origin);\n var v = fabric.util.rotateVector(point, radians);\n return new fabric.Point(v.x, v.y).addEquals(origin);\n },\n\n /**\n * Rotates `vector` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {Object} vector The vector to rotate (x and y)\n * @param {Number} radians The radians of the angle for the rotation\n * @return {Object} The new rotated point\n */\n rotateVector: function(vector, radians) {\n var sin = Math.sin(radians),\n cos = Math.cos(radians),\n rx = vector.x * cos - vector.y * sin,\n ry = vector.x * sin + vector.y * cos;\n return {\n x: rx,\n y: ry\n };\n },\n\n /**\n * Apply transform t to point p\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} p The point to transform\n * @param {Array} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {fabric.Point} The transformed point\n */\n transformPoint: function(p, t, ignoreOffset) {\n if (ignoreOffset) {\n return new fabric.Point(\n t[0] * p.x + t[2] * p.y,\n t[1] * p.x + t[3] * p.y\n );\n }\n return new fabric.Point(\n t[0] * p.x + t[2] * p.y + t[4],\n t[1] * p.x + t[3] * p.y + t[5]\n );\n },\n\n /**\n * Returns coordinates of points's bounding rectangle (left, top, width, height)\n * @param {Array} points 4 points array\n * @return {Object} Object with left, top, width, height properties\n */\n makeBoundingBoxFromPoints: function(points) {\n var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x],\n minX = fabric.util.array.min(xPoints),\n maxX = fabric.util.array.max(xPoints),\n width = Math.abs(minX - maxX),\n yPoints = [points[0].y, points[1].y, points[2].y, points[3].y],\n minY = fabric.util.array.min(yPoints),\n maxY = fabric.util.array.max(yPoints),\n height = Math.abs(minY - maxY);\n\n return {\n left: minX,\n top: minY,\n width: width,\n height: height\n };\n },\n\n /**\n * Invert transformation t\n * @static\n * @memberOf fabric.util\n * @param {Array} t The transform\n * @return {Array} The inverted transform\n */\n invertTransform: function(t) {\n var a = 1 / (t[0] * t[3] - t[1] * t[2]),\n r = [a * t[3], -a * t[1], -a * t[2], a * t[0]],\n o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r, true);\n r[4] = -o.x;\n r[5] = -o.y;\n return r;\n },\n\n /**\n * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n * @static\n * @memberOf fabric.util\n * @param {Number|String} number number to operate on\n * @param {Number} fractionDigits number of fraction digits to \"leave\"\n * @return {Number}\n */\n toFixed: function(number, fractionDigits) {\n return parseFloat(Number(number).toFixed(fractionDigits));\n },\n\n /**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {Number|String} value number to operate on\n * @param {Number} fontSize\n * @return {Number|String}\n */\n parseUnit: function(value, fontSize) {\n var unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n if (!fontSize) {\n fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n switch (unit[0]) {\n case 'mm':\n return number * fabric.DPI / 25.4;\n\n case 'cm':\n return number * fabric.DPI / 2.54;\n\n case 'in':\n return number * fabric.DPI;\n\n case 'pt':\n return number * fabric.DPI / 72; // or * 4 / 3\n\n case 'pc':\n return number * fabric.DPI / 72 * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n },\n\n /**\n * Function which always returns `false`.\n * @static\n * @memberOf fabric.util\n * @return {Boolean}\n */\n falseFunction: function() {\n return false;\n },\n\n /**\n * Returns klass \"Class\" object of given namespace\n * @memberOf fabric.util\n * @param {String} type Type of object (eg. 'circle')\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @return {Object} klass \"Class\"\n */\n getKlass: function(type, namespace) {\n // capitalize first letter only\n type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1));\n return fabric.util.resolveNamespace(namespace)[type];\n },\n\n /**\n * Returns object of given namespace\n * @memberOf fabric.util\n * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric'\n * @return {Object} Object for given namespace (default fabric)\n */\n resolveNamespace: function(namespace) {\n if (!namespace) {\n return fabric;\n }\n\n var parts = namespace.split('.'),\n len = parts.length, i,\n obj = global || fabric.window;\n\n for (i = 0; i < len; ++i) {\n obj = obj[parts[i]];\n }\n\n return obj;\n },\n\n /**\n * Loads image element from given url and passes it to a callback\n * @memberOf fabric.util\n * @param {String} url URL representing an image\n * @param {Function} callback Callback; invoked with loaded image\n * @param {*} [context] Context to invoke callback in\n * @param {Object} [crossOrigin] crossOrigin value to set image element to\n */\n loadImage: function(url, callback, context, crossOrigin) {\n if (!url) {\n callback && callback.call(context, url);\n return;\n }\n\n var img = fabric.util.createImage();\n\n /** @ignore */\n img.onload = function () {\n callback && callback.call(context, img);\n img = img.onload = img.onerror = null;\n };\n\n /** @ignore */\n img.onerror = function() {\n fabric.log('Error loading ' + img.src);\n callback && callback.call(context, null, true);\n img = img.onload = img.onerror = null;\n };\n\n // data-urls appear to be buggy with crossOrigin\n // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767\n // see https://code.google.com/p/chromium/issues/detail?id=315152\n // https://bugzilla.mozilla.org/show_bug.cgi?id=935069\n if (url.indexOf('data') !== 0 && crossOrigin) {\n img.crossOrigin = crossOrigin;\n }\n\n img.src = url;\n },\n\n /**\n * Creates corresponding fabric instances from their object representations\n * @static\n * @memberOf fabric.util\n * @param {Array} objects Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @param {Function} reviver Method for further parsing of object elements,\n * called after each fabric object created.\n */\n enlivenObjects: function(objects, callback, namespace, reviver) {\n objects = objects || [];\n\n function onLoaded() {\n if (++numLoadedObjects === numTotalObjects) {\n callback && callback(enlivenedObjects);\n }\n }\n\n var enlivenedObjects = [],\n numLoadedObjects = 0,\n numTotalObjects = objects.length,\n forceAsync = true;\n\n if (!numTotalObjects) {\n callback && callback(enlivenedObjects);\n return;\n }\n\n objects.forEach(function (o, index) {\n // if sparse array\n if (!o || !o.type) {\n onLoaded();\n return;\n }\n var klass = fabric.util.getKlass(o.type, namespace);\n klass.fromObject(o, function (obj, error) {\n error || (enlivenedObjects[index] = obj);\n reviver && reviver(o, obj, error);\n onLoaded();\n }, forceAsync);\n });\n },\n\n /**\n * Create and wait for loading of patterns\n * @static\n * @memberOf fabric.util\n * @param {Array} objects Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @param {Function} reviver Method for further parsing of object elements,\n * called after each fabric object created.\n */\n enlivenPatterns: function(patterns, callback) {\n patterns = patterns || [];\n\n function onLoaded() {\n if (++numLoadedPatterns === numPatterns) {\n callback && callback(enlivenedPatterns);\n }\n }\n\n var enlivenedPatterns = [],\n numLoadedPatterns = 0,\n numPatterns = patterns.length;\n\n if (!numPatterns) {\n callback && callback(enlivenedPatterns);\n return;\n }\n\n patterns.forEach(function (p, index) {\n if (p && p.source) {\n new fabric.Pattern(p, function(pattern) {\n enlivenedPatterns[index] = pattern;\n onLoaded();\n });\n }\n else {\n enlivenedPatterns[index] = p;\n onLoaded();\n }\n });\n },\n\n /**\n * Groups SVG elements (usually those retrieved from SVG document)\n * @static\n * @memberOf fabric.util\n * @param {Array} elements SVG elements to group\n * @param {Object} [options] Options object\n * @param {String} path Value to set sourcePath to\n * @return {fabric.Object|fabric.PathGroup}\n */\n groupSVGElements: function(elements, options, path) {\n var object;\n\n object = new fabric.PathGroup(elements, options);\n\n if (typeof path !== 'undefined') {\n object.sourcePath = path;\n }\n return object;\n },\n\n /**\n * Populates an object with properties of another object\n * @static\n * @memberOf fabric.util\n * @param {Object} source Source object\n * @param {Object} destination Destination object\n * @return {Array} properties Propertie names to include\n */\n populateWithProperties: function(source, destination, properties) {\n if (properties && Object.prototype.toString.call(properties) === '[object Array]') {\n for (var i = 0, len = properties.length; i < len; i++) {\n if (properties[i] in source) {\n destination[properties[i]] = source[properties[i]];\n }\n }\n }\n },\n\n /**\n * Draws a dashed line between two points\n *\n * This method is used to draw dashed line around selection area.\n * See dotted stroke in canvas\n *\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x start x coordinate\n * @param {Number} y start y coordinate\n * @param {Number} x2 end x coordinate\n * @param {Number} y2 end y coordinate\n * @param {Array} da dash array pattern\n */\n drawDashedLine: function(ctx, x, y, x2, y2, da) {\n var dx = x2 - x,\n dy = y2 - y,\n len = sqrt(dx * dx + dy * dy),\n rot = atan2(dy, dx),\n dc = da.length,\n di = 0,\n draw = true;\n\n ctx.save();\n ctx.translate(x, y);\n ctx.moveTo(0, 0);\n ctx.rotate(rot);\n\n x = 0;\n while (len > x) {\n x += da[di++ % dc];\n if (x > len) {\n x = len;\n }\n ctx[draw ? 'lineTo' : 'moveTo'](x, 0);\n draw = !draw;\n }\n\n ctx.restore();\n },\n\n /**\n * Creates canvas element and initializes it via excanvas if necessary\n * @static\n * @memberOf fabric.util\n * @param {CanvasElement} [canvasEl] optional canvas element to initialize;\n * when not given, element is created implicitly\n * @return {CanvasElement} initialized canvas element\n */\n createCanvasElement: function(canvasEl) {\n canvasEl || (canvasEl = fabric.document.createElement('canvas'));\n /* eslint-disable camelcase */\n if (!canvasEl.getContext && typeof G_vmlCanvasManager !== 'undefined') {\n G_vmlCanvasManager.initElement(canvasEl);\n }\n /* eslint-enable camelcase */\n return canvasEl;\n },\n\n /**\n * Creates image element (works on client and node)\n * @static\n * @memberOf fabric.util\n * @return {HTMLImageElement} HTML image element\n */\n createImage: function() {\n return fabric.isLikelyNode\n ? new (require('canvas').Image)()\n : fabric.document.createElement('img');\n },\n\n /**\n * Creates accessors (getXXX, setXXX) for a \"class\", based on \"stateProperties\" array\n * @static\n * @memberOf fabric.util\n * @param {Object} klass \"Class\" to create accessors for\n */\n createAccessors: function(klass) {\n var proto = klass.prototype, i, propName,\n capitalizedPropName, setterName, getterName;\n\n for (i = proto.stateProperties.length; i--; ) {\n\n propName = proto.stateProperties[i];\n capitalizedPropName = propName.charAt(0).toUpperCase() + propName.slice(1);\n setterName = 'set' + capitalizedPropName;\n getterName = 'get' + capitalizedPropName;\n\n // using `new Function` for better introspection\n if (!proto[getterName]) {\n proto[getterName] = (function(property) {\n return new Function('return this.get(\"' + property + '\")');\n })(propName);\n }\n if (!proto[setterName]) {\n proto[setterName] = (function(property) {\n return new Function('value', 'return this.set(\"' + property + '\", value)');\n })(propName);\n }\n }\n },\n\n /**\n * @static\n * @memberOf fabric.util\n * @param {fabric.Object} receiver Object implementing `clipTo` method\n * @param {CanvasRenderingContext2D} ctx Context to clip\n */\n clipContext: function(receiver, ctx) {\n ctx.save();\n ctx.beginPath();\n receiver.clipTo(ctx);\n ctx.clip();\n },\n\n /**\n * Multiply matrix A by matrix B to nest transformations\n * @static\n * @memberOf fabric.util\n * @param {Array} a First transformMatrix\n * @param {Array} b Second transformMatrix\n * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n * @return {Array} The product of the two transform matrices\n */\n multiplyTransformMatrices: function(a, b, is2x2) {\n // Matrix multiply a * b\n return [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]\n ];\n },\n\n /**\n * Decomposes standard 2x2 matrix into transform componentes\n * @static\n * @memberOf fabric.util\n * @param {Array} a transformMatrix\n * @return {Object} Components of transform\n */\n qrDecompose: function(a) {\n var angle = atan2(a[1], a[0]),\n denom = pow(a[0], 2) + pow(a[1], 2),\n scaleX = sqrt(denom),\n scaleY = (a[0] * a[3] - a[2] * a [1]) / scaleX,\n skewX = atan2(a[0] * a[2] + a[1] * a [3], denom);\n return {\n angle: angle / PiBy180,\n scaleX: scaleX,\n scaleY: scaleY,\n skewX: skewX / PiBy180,\n skewY: 0,\n translateX: a[4],\n translateY: a[5]\n };\n },\n\n customTransformMatrix: function(scaleX, scaleY, skewX) {\n var skewMatrixX = [1, 0, abs(Math.tan(skewX * PiBy180)), 1],\n scaleMatrix = [abs(scaleX), 0, 0, abs(scaleY)];\n return fabric.util.multiplyTransformMatrices(scaleMatrix, skewMatrixX, true);\n },\n\n resetObjectTransform: function (target) {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.flipX = false;\n target.flipY = false;\n target.setAngle(0);\n },\n\n /**\n * Returns string representation of function body\n * @param {Function} fn Function to get body of\n * @return {String} Function body\n */\n getFunctionBody: function(fn) {\n return (String(fn).match(/function[^{]*\\{([\\s\\S]*)\\}/) || {})[1];\n },\n\n /**\n * Returns true if context has transparent pixel\n * at specified location (taking tolerance into account)\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x x coordinate\n * @param {Number} y y coordinate\n * @param {Number} tolerance Tolerance\n */\n isTransparent: function(ctx, x, y, tolerance) {\n\n // If tolerance is > 0 adjust start coords to take into account.\n // If moves off Canvas fix to 0\n if (tolerance > 0) {\n if (x > tolerance) {\n x -= tolerance;\n }\n else {\n x = 0;\n }\n if (y > tolerance) {\n y -= tolerance;\n }\n else {\n y = 0;\n }\n }\n\n var _isTransparent = true, i, temp,\n imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1),\n l = imageData.data.length;\n\n // Split image data - for tolerance > 1, pixelDataSize = 4;\n for (i = 3; i < l; i += 4) {\n temp = imageData.data[i];\n _isTransparent = temp <= 0;\n if (_isTransparent === false) {\n break; // Stop if colour found\n }\n }\n\n imageData = null;\n\n return _isTransparent;\n },\n\n /**\n * Parse preserveAspectRatio attribute from element\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\n parsePreserveAspectRatioAttribute: function(attribute) {\n var meetOrSlice = 'meet', alignX = 'Mid', alignY = 'Mid',\n aspectRatioAttrs = attribute.split(' '), align;\n\n if (aspectRatioAttrs && aspectRatioAttrs.length) {\n meetOrSlice = aspectRatioAttrs.pop();\n if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') {\n align = meetOrSlice;\n meetOrSlice = 'meet';\n }\n else if (aspectRatioAttrs.length) {\n align = aspectRatioAttrs.pop();\n }\n }\n //divide align in alignX and alignY\n alignX = align !== 'none' ? align.slice(1, 4) : 'none';\n alignY = align !== 'none' ? align.slice(5, 8) : 'none';\n return {\n meetOrSlice: meetOrSlice,\n alignX: alignX,\n alignY: alignY\n };\n },\n\n /**\n * Clear char widths cache for a font family.\n * @memberOf fabric.util\n * @param {String} [fontFamily] font family to clear\n */\n clearFabricFontCache: function(fontFamily) {\n if (!fontFamily) {\n fabric.charWidthsCache = { };\n }\n else if (fabric.charWidthsCache[fontFamily]) {\n delete fabric.charWidthsCache[fontFamily];\n }\n },\n\n /**\n * Clear char widths cache for a font family.\n * @memberOf fabric.util\n * @param {Number} ar aspect ratio\n * @param {Number} maximumArea Maximum area you want to achieve\n * @param {Number} maximumSide biggest side allowed\n * @return {Object.x} Limited dimensions by X\n * @return {Object.y} Limited dimensions by Y\n */\n limitDimsByArea: function(ar, maximumArea) {\n var roughWidth = Math.sqrt(maximumArea * ar),\n perfLimitSizeY = Math.floor(maximumArea / roughWidth);\n return { x: Math.floor(roughWidth), y: perfLimitSizeY };\n },\n\n capValue: function(min, value, max) {\n return Math.max(min, Math.min(value, max));\n }\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var arcToSegmentsCache = { },\n segmentToBezierCache = { },\n boundsOfCurveCache = { },\n _join = Array.prototype.join;\n\n /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n */\n function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {\n var argsString = _join.call(arguments);\n if (arcToSegmentsCache[argsString]) {\n return arcToSegmentsCache[argsString];\n }\n\n var PI = Math.PI, th = rotateX * PI / 180,\n sinTh = Math.sin(th),\n cosTh = Math.cos(th),\n fromX = 0, fromY = 0;\n\n rx = Math.abs(rx);\n ry = Math.abs(ry);\n\n var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5,\n py = -cosTh * toY * 0.5 + sinTh * toX * 0.5,\n rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2,\n root = 0;\n\n if (pl < 0) {\n var s = Math.sqrt(1 - pl / (rx2 * ry2));\n rx *= s;\n ry *= s;\n }\n else {\n root = (large === sweep ? -1.0 : 1.0) *\n Math.sqrt( pl / (rx2 * py2 + ry2 * px2));\n }\n\n var cx = root * rx * py / ry,\n cy = -root * ry * px / rx,\n cx1 = cosTh * cx - sinTh * cy + toX * 0.5,\n cy1 = sinTh * cx + cosTh * cy + toY * 0.5,\n mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),\n dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry);\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n }\n else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n var segments = Math.ceil(Math.abs(dtheta / PI * 2)),\n result = [], mDelta = dtheta / segments,\n mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),\n th3 = mTheta + mDelta;\n\n for (var i = 0; i < segments; i++) {\n result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);\n fromX = result[i][4];\n fromY = result[i][5];\n mTheta = th3;\n th3 += mDelta;\n }\n arcToSegmentsCache[argsString] = result;\n return result;\n }\n\n function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {\n var argsString2 = _join.call(arguments);\n if (segmentToBezierCache[argsString2]) {\n return segmentToBezierCache[argsString2];\n }\n\n var costh2 = Math.cos(th2),\n sinth2 = Math.sin(th2),\n costh3 = Math.cos(th3),\n sinth3 = Math.sin(th3),\n toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1,\n toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1,\n cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2),\n cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2),\n cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),\n cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);\n\n segmentToBezierCache[argsString2] = [\n cp1X, cp1Y,\n cp2X, cp2Y,\n toX, toY\n ];\n return segmentToBezierCache[argsString2];\n }\n\n /*\n * Private\n */\n function calcVectorAngle(ux, uy, vx, vy) {\n var ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n }\n else {\n return 2 * Math.PI - (ta - tb);\n }\n }\n\n /**\n * Draws arc\n * @param {CanvasRenderingContext2D} ctx\n * @param {Number} fx\n * @param {Number} fy\n * @param {Array} coords\n */\n fabric.util.drawArc = function(ctx, fx, fy, coords) {\n var rx = coords[0],\n ry = coords[1],\n rot = coords[2],\n large = coords[3],\n sweep = coords[4],\n tx = coords[5],\n ty = coords[6],\n segs = [[], [], [], []],\n segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segsNorm.length; i < len; i++) {\n segs[i][0] = segsNorm[i][0] + fx;\n segs[i][1] = segsNorm[i][1] + fy;\n segs[i][2] = segsNorm[i][2] + fx;\n segs[i][3] = segsNorm[i][3] + fy;\n segs[i][4] = segsNorm[i][4] + fx;\n segs[i][5] = segsNorm[i][5] + fy;\n ctx.bezierCurveTo.apply(ctx, segs[i]);\n }\n };\n\n /**\n * Calculate bounding box of a elliptic-arc\n * @param {Number} fx start point of arc\n * @param {Number} fy\n * @param {Number} rx horizontal radius\n * @param {Number} ry vertical radius\n * @param {Number} rot angle of horizontal axe\n * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points\n * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction\n * @param {Number} tx end point of arc\n * @param {Number} ty\n */\n fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) {\n\n var fromX = 0, fromY = 0, bound, bounds = [],\n segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segs.length; i < len; i++) {\n bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]);\n bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy });\n bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy });\n fromX = segs[i][4];\n fromY = segs[i][5];\n }\n return bounds;\n };\n\n /**\n * Calculate bounding box of a beziercurve\n * @param {Number} x0 starting point\n * @param {Number} y0\n * @param {Number} x1 first control point\n * @param {Number} y1\n * @param {Number} x2 secondo control point\n * @param {Number} y2\n * @param {Number} x3 end of beizer\n * @param {Number} y3\n */\n // taken from http://jsbin.com/ivomiq/56/edit no credits available for that.\n function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {\n var argsString = _join.call(arguments);\n if (boundsOfCurveCache[argsString]) {\n return boundsOfCurveCache[argsString];\n }\n\n var sqrt = Math.sqrt,\n min = Math.min, max = Math.max,\n abs = Math.abs, tvalues = [],\n bounds = [[], []],\n a, b, c, t, t1, t2, b2ac, sqrtb2ac;\n\n b = 6 * x0 - 12 * x1 + 6 * x2;\n a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n c = 3 * x1 - 3 * x0;\n\n for (var i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * y0 - 12 * y1 + 6 * y2;\n a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n c = 3 * y1 - 3 * y0;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n sqrtb2ac = sqrt(b2ac);\n t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n var x, y, j = tvalues.length, jlen = j, mt;\n while (j--) {\n t = tvalues[j];\n mt = 1 - t;\n x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);\n bounds[0][j] = x;\n\n y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = x0;\n bounds[1][jlen] = y0;\n bounds[0][jlen + 1] = x3;\n bounds[1][jlen + 1] = y3;\n var result = [\n {\n x: min.apply(null, bounds[0]),\n y: min.apply(null, bounds[1])\n },\n {\n x: max.apply(null, bounds[0]),\n y: max.apply(null, bounds[1])\n }\n ];\n boundsOfCurveCache[argsString] = result;\n return result;\n }\n\n fabric.util.getBoundsOfCurve = getBoundsOfCurve;\n\n})();\n\n\n(function() {\n\n var slice = Array.prototype.slice;\n\n /* _ES5_COMPAT_START_ */\n\n if (!Array.prototype.indexOf) {\n /**\n * Finds index of an element in an array\n * @param {*} searchElement\n * @return {Number}\n */\n Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {\n if (this === void 0 || this === null) {\n throw new TypeError();\n }\n var t = Object(this), len = t.length >>> 0;\n if (len === 0) {\n return -1;\n }\n var n = 0;\n if (arguments.length > 0) {\n n = Number(arguments[1]);\n if (n !== n) { // shortcut for verifying if it's NaN\n n = 0;\n }\n else if (n !== 0 && n !== Number.POSITIVE_INFINITY && n !== Number.NEGATIVE_INFINITY) {\n n = (n > 0 || -1) * Math.floor(Math.abs(n));\n }\n }\n if (n >= len) {\n return -1;\n }\n var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);\n for (; k < len; k++) {\n if (k in t && t[k] === searchElement) {\n return k;\n }\n }\n return -1;\n };\n }\n\n if (!Array.prototype.forEach) {\n /**\n * Iterates an array, invoking callback for each element\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Array}\n */\n Array.prototype.forEach = function(fn, context) {\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this) {\n fn.call(context, this[i], i, this);\n }\n }\n };\n }\n\n if (!Array.prototype.map) {\n /**\n * Returns a result of iterating over an array, invoking callback for each element\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Array}\n */\n Array.prototype.map = function(fn, context) {\n var result = [];\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this) {\n result[i] = fn.call(context, this[i], i, this);\n }\n }\n return result;\n };\n }\n\n if (!Array.prototype.every) {\n /**\n * Returns true if a callback returns truthy value for all elements in an array\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Boolean}\n */\n Array.prototype.every = function(fn, context) {\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this && !fn.call(context, this[i], i, this)) {\n return false;\n }\n }\n return true;\n };\n }\n\n if (!Array.prototype.some) {\n /**\n * Returns true if a callback returns truthy value for at least one element in an array\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Boolean}\n */\n Array.prototype.some = function(fn, context) {\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this && fn.call(context, this[i], i, this)) {\n return true;\n }\n }\n return false;\n };\n }\n\n if (!Array.prototype.filter) {\n /**\n * Returns the result of iterating over elements in an array\n * @param {Function} fn Callback to invoke for each element\n * @param {Object} [context] Context to invoke callback in\n * @return {Array}\n */\n Array.prototype.filter = function(fn, context) {\n var result = [], val;\n for (var i = 0, len = this.length >>> 0; i < len; i++) {\n if (i in this) {\n val = this[i]; // in case fn mutates this\n if (fn.call(context, val, i, this)) {\n result.push(val);\n }\n }\n }\n return result;\n };\n }\n\n if (!Array.prototype.reduce) {\n /**\n * Returns \"folded\" (reduced) result of iterating over elements in an array\n * @param {Function} fn Callback to invoke for each element\n * @return {*}\n */\n Array.prototype.reduce = function(fn /*, initial*/) {\n var len = this.length >>> 0,\n i = 0,\n rv;\n\n if (arguments.length > 1) {\n rv = arguments[1];\n }\n else {\n do {\n if (i in this) {\n rv = this[i++];\n break;\n }\n // if array contains no values, no initial value to return\n if (++i >= len) {\n throw new TypeError();\n }\n }\n while (true);\n }\n for (; i < len; i++) {\n if (i in this) {\n rv = fn.call(null, rv, this[i], i, this);\n }\n }\n return rv;\n };\n }\n\n /* _ES5_COMPAT_END_ */\n\n /**\n * Invokes method on all items in a given array\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} method Name of a method to invoke\n * @return {Array}\n */\n function invoke(array, method) {\n var args = slice.call(arguments, 2), result = [];\n for (var i = 0, len = array.length; i < len; i++) {\n result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);\n }\n return result;\n }\n\n /**\n * Finds maximum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n function max(array, byProperty) {\n return find(array, byProperty, function(value1, value2) {\n return value1 >= value2;\n });\n }\n\n /**\n * Finds minimum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n function min(array, byProperty) {\n return find(array, byProperty, function(value1, value2) {\n return value1 < value2;\n });\n }\n\n /**\n * @private\n */\n function fill(array, value) {\n var k = array.length;\n while (k--) {\n array[k] = value;\n }\n return array;\n }\n\n /**\n * @private\n */\n function find(array, byProperty, condition) {\n if (!array || array.length === 0) {\n return;\n }\n\n var i = array.length - 1,\n result = byProperty ? array[i][byProperty] : array[i];\n if (byProperty) {\n while (i--) {\n if (condition(array[i][byProperty], result)) {\n result = array[i][byProperty];\n }\n }\n }\n else {\n while (i--) {\n if (condition(array[i], result)) {\n result = array[i];\n }\n }\n }\n return result;\n }\n\n /**\n * @namespace fabric.util.array\n */\n fabric.util.array = {\n fill: fill,\n invoke: invoke,\n min: min,\n max: max\n };\n\n})();\n\n\n(function() {\n /**\n * Copies all enumerable properties of one js object to another\n * Does not clone or extend fabric.Object subclasses.\n * @memberOf fabric.util.object\n * @param {Object} destination Where to copy to\n * @param {Object} source Where to copy from\n * @return {Object}\n */\n\n function extend(destination, source, deep) {\n // JScript DontEnum bug is not taken care of\n // the deep clone is for internal use, is not meant to avoid\n // javascript traps or cloning html element or self referenced objects.\n if (deep) {\n if (!fabric.isLikelyNode && source instanceof Element) {\n // avoid cloning deep images, canvases,\n destination = source;\n }\n else if (source instanceof Array) {\n destination = [];\n for (var i = 0, len = source.length; i < len; i++) {\n destination[i] = extend({ }, source[i], deep);\n }\n }\n else if (source && typeof source === 'object') {\n for (var property in source) {\n if (source.hasOwnProperty(property)) {\n destination[property] = extend({ }, source[property], deep);\n }\n }\n }\n else {\n // this sounds odd for an extend but is ok for recursive use\n destination = source;\n }\n }\n else {\n for (var property in source) {\n destination[property] = source[property];\n }\n }\n return destination;\n }\n\n /**\n * Creates an empty object and copies all enumerable properties of another object to it\n * @memberOf fabric.util.object\n * @param {Object} object Object to clone\n * @return {Object}\n */\n function clone(object, deep) {\n return extend({ }, object, deep);\n }\n\n /** @namespace fabric.util.object */\n fabric.util.object = {\n extend: extend,\n clone: clone\n };\n\n})();\n\n\n(function() {\n\n /* _ES5_COMPAT_START_ */\n if (!String.prototype.trim) {\n /**\n * Trims a string (removing whitespace from the beginning and the end)\n * @function external:String#trim\n * @see String#trim on MDN\n */\n String.prototype.trim = function () {\n // this trim is not fully ES3 or ES5 compliant, but it should cover most cases for now\n return this.replace(/^[\\s\\xA0]+/, '').replace(/[\\s\\xA0]+$/, '');\n };\n }\n /* _ES5_COMPAT_END_ */\n\n /**\n * Camelizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to camelize\n * @return {String} Camelized version of a string\n */\n function camelize(string) {\n return string.replace(/-+(.)?/g, function(match, character) {\n return character ? character.toUpperCase() : '';\n });\n }\n\n /**\n * Capitalizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to capitalize\n * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n * and other letters stay untouched, if false first letter is capitalized\n * and other letters are converted to lowercase.\n * @return {String} Capitalized version of a string\n */\n function capitalize(string, firstLetterOnly) {\n return string.charAt(0).toUpperCase() +\n (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());\n }\n\n /**\n * Escapes XML in a string\n * @memberOf fabric.util.string\n * @param {String} string String to escape\n * @return {String} Escaped version of a string\n */\n function escapeXml(string) {\n return string.replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(//g, '>');\n }\n\n /**\n * String utilities\n * @namespace fabric.util.string\n */\n fabric.util.string = {\n camelize: camelize,\n capitalize: capitalize,\n escapeXml: escapeXml\n };\n})();\n\n\n/* _ES5_COMPAT_START_ */\n(function() {\n\n var slice = Array.prototype.slice,\n apply = Function.prototype.apply,\n Dummy = function() { };\n\n if (!Function.prototype.bind) {\n /**\n * Cross-browser approximation of ES5 Function.prototype.bind (not fully spec conforming)\n * @see Function#bind on MDN\n * @param {Object} thisArg Object to bind function to\n * @param {Any[]} Values to pass to a bound function\n * @return {Function}\n */\n Function.prototype.bind = function(thisArg) {\n var _this = this, args = slice.call(arguments, 1), bound;\n if (args.length) {\n bound = function() {\n return apply.call(_this, this instanceof Dummy ? this : thisArg, args.concat(slice.call(arguments)));\n };\n }\n else {\n /** @ignore */\n bound = function() {\n return apply.call(_this, this instanceof Dummy ? this : thisArg, arguments);\n };\n }\n Dummy.prototype = this.prototype;\n bound.prototype = new Dummy();\n\n return bound;\n };\n }\n\n})();\n/* _ES5_COMPAT_END_ */\n\n\n(function() {\n\n var slice = Array.prototype.slice, emptyFunction = function() { },\n\n IS_DONTENUM_BUGGY = (function() {\n for (var p in { toString: 1 }) {\n if (p === 'toString') {\n return false;\n }\n }\n return true;\n })(),\n\n /** @ignore */\n addMethods = function(klass, source, parent) {\n for (var property in source) {\n\n if (property in klass.prototype &&\n typeof klass.prototype[property] === 'function' &&\n (source[property] + '').indexOf('callSuper') > -1) {\n\n klass.prototype[property] = (function(property) {\n return function() {\n\n var superclass = this.constructor.superclass;\n this.constructor.superclass = parent;\n var returnValue = source[property].apply(this, arguments);\n this.constructor.superclass = superclass;\n\n if (property !== 'initialize') {\n return returnValue;\n }\n };\n })(property);\n }\n else {\n klass.prototype[property] = source[property];\n }\n\n if (IS_DONTENUM_BUGGY) {\n if (source.toString !== Object.prototype.toString) {\n klass.prototype.toString = source.toString;\n }\n if (source.valueOf !== Object.prototype.valueOf) {\n klass.prototype.valueOf = source.valueOf;\n }\n }\n }\n };\n\n function Subclass() { }\n\n function callSuper(methodName) {\n var parentMethod = null,\n _this = this;\n\n // climb prototype chain to find method not equal to callee's method\n while (_this.constructor.superclass) {\n var superClassMethod = _this.constructor.superclass.prototype[methodName];\n if (_this[methodName] !== superClassMethod) {\n parentMethod = superClassMethod;\n break;\n }\n // eslint-disable-next-line\n _this = _this.constructor.superclass.prototype;\n }\n\n if (!parentMethod) {\n return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this);\n }\n\n return (arguments.length > 1)\n ? parentMethod.apply(this, slice.call(arguments, 1))\n : parentMethod.call(this);\n }\n\n /**\n * Helper for creation of \"classes\".\n * @memberOf fabric.util\n * @param {Function} [parent] optional \"Class\" to inherit from\n * @param {Object} [properties] Properties shared by all instances of this class\n * (be careful modifying objects defined here as this would affect all instances)\n */\n function createClass() {\n var parent = null,\n properties = slice.call(arguments, 0);\n\n if (typeof properties[0] === 'function') {\n parent = properties.shift();\n }\n function klass() {\n this.initialize.apply(this, arguments);\n }\n\n klass.superclass = parent;\n klass.subclasses = [];\n\n if (parent) {\n Subclass.prototype = parent.prototype;\n klass.prototype = new Subclass();\n parent.subclasses.push(klass);\n }\n for (var i = 0, length = properties.length; i < length; i++) {\n addMethods(klass, properties[i], parent);\n }\n if (!klass.prototype.initialize) {\n klass.prototype.initialize = emptyFunction;\n }\n klass.prototype.constructor = klass;\n klass.prototype.callSuper = callSuper;\n return klass;\n }\n\n fabric.util.createClass = createClass;\n})();\n\n\n(function () {\n\n var unknown = 'unknown';\n\n /* EVENT HANDLING */\n\n function areHostMethods(object) {\n var methodNames = Array.prototype.slice.call(arguments, 1),\n t, i, len = methodNames.length;\n for (i = 0; i < len; i++) {\n t = typeof object[methodNames[i]];\n if (!(/^(?:function|object|unknown)$/).test(t)) {\n return false;\n }\n }\n return true;\n }\n\n /** @ignore */\n var getElement,\n setElement,\n getUniqueId = (function () {\n var uid = 0;\n return function (element) {\n return element.__uniqueID || (element.__uniqueID = 'uniqueID__' + uid++);\n };\n })();\n\n (function () {\n var elements = { };\n /** @ignore */\n getElement = function (uid) {\n return elements[uid];\n };\n /** @ignore */\n setElement = function (uid, element) {\n elements[uid] = element;\n };\n })();\n\n function createListener(uid, handler) {\n return {\n handler: handler,\n wrappedHandler: createWrappedHandler(uid, handler)\n };\n }\n\n function createWrappedHandler(uid, handler) {\n return function (e) {\n handler.call(getElement(uid), e || fabric.window.event);\n };\n }\n\n function createDispatcher(uid, eventName) {\n return function (e) {\n if (handlers[uid] && handlers[uid][eventName]) {\n var handlersForEvent = handlers[uid][eventName];\n for (var i = 0, len = handlersForEvent.length; i < len; i++) {\n handlersForEvent[i].call(this, e || fabric.window.event);\n }\n }\n };\n }\n\n var shouldUseAddListenerRemoveListener = (\n areHostMethods(fabric.document.documentElement, 'addEventListener', 'removeEventListener') &&\n areHostMethods(fabric.window, 'addEventListener', 'removeEventListener')),\n\n shouldUseAttachEventDetachEvent = (\n areHostMethods(fabric.document.documentElement, 'attachEvent', 'detachEvent') &&\n areHostMethods(fabric.window, 'attachEvent', 'detachEvent')),\n\n // IE branch\n listeners = { },\n\n // DOM L0 branch\n handlers = { },\n\n addListener, removeListener;\n\n if (shouldUseAddListenerRemoveListener) {\n /** @ignore */\n addListener = function (element, eventName, handler, options) {\n // since ie10 or ie9 can use addEventListener but they do not support options, i need to check\n element && element.addEventListener(eventName, handler, shouldUseAttachEventDetachEvent ? false : options);\n };\n /** @ignore */\n removeListener = function (element, eventName, handler, options) {\n element && element.removeEventListener(eventName, handler, shouldUseAttachEventDetachEvent ? false : options);\n };\n }\n\n else if (shouldUseAttachEventDetachEvent) {\n /** @ignore */\n addListener = function (element, eventName, handler) {\n if (!element) {\n return;\n }\n var uid = getUniqueId(element);\n setElement(uid, element);\n if (!listeners[uid]) {\n listeners[uid] = { };\n }\n if (!listeners[uid][eventName]) {\n listeners[uid][eventName] = [];\n\n }\n var listener = createListener(uid, handler);\n listeners[uid][eventName].push(listener);\n element.attachEvent('on' + eventName, listener.wrappedHandler);\n };\n /** @ignore */\n removeListener = function (element, eventName, handler) {\n if (!element) {\n return;\n }\n var uid = getUniqueId(element), listener;\n if (listeners[uid] && listeners[uid][eventName]) {\n for (var i = 0, len = listeners[uid][eventName].length; i < len; i++) {\n listener = listeners[uid][eventName][i];\n if (listener && listener.handler === handler) {\n element.detachEvent('on' + eventName, listener.wrappedHandler);\n listeners[uid][eventName][i] = null;\n }\n }\n }\n };\n }\n else {\n /** @ignore */\n addListener = function (element, eventName, handler) {\n if (!element) {\n return;\n }\n var uid = getUniqueId(element);\n if (!handlers[uid]) {\n handlers[uid] = { };\n }\n if (!handlers[uid][eventName]) {\n handlers[uid][eventName] = [];\n var existingHandler = element['on' + eventName];\n if (existingHandler) {\n handlers[uid][eventName].push(existingHandler);\n }\n element['on' + eventName] = createDispatcher(uid, eventName);\n }\n handlers[uid][eventName].push(handler);\n };\n /** @ignore */\n removeListener = function (element, eventName, handler) {\n if (!element) {\n return;\n }\n var uid = getUniqueId(element);\n if (handlers[uid] && handlers[uid][eventName]) {\n var handlersForEvent = handlers[uid][eventName];\n for (var i = 0, len = handlersForEvent.length; i < len; i++) {\n if (handlersForEvent[i] === handler) {\n handlersForEvent.splice(i, 1);\n }\n }\n }\n };\n }\n\n /**\n * Adds an event listener to an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n fabric.util.addListener = addListener;\n\n /**\n * Removes an event listener from an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n fabric.util.removeListener = removeListener;\n\n /**\n * Cross-browser wrapper for getting event's coordinates\n * @memberOf fabric.util\n * @param {Event} event Event object\n */\n function getPointer(event) {\n event || (event = fabric.window.event);\n\n var element = event.target ||\n (typeof event.srcElement !== unknown ? event.srcElement : null),\n\n scroll = fabric.util.getScrollLeftTop(element);\n\n return {\n x: pointerX(event) + scroll.left,\n y: pointerY(event) + scroll.top\n };\n }\n\n var pointerX = function(event) {\n // looks like in IE (<9) clientX at certain point (apparently when mouseup fires on VML element)\n // is represented as COM object, with all the consequences, like \"unknown\" type and error on [[Get]]\n // need to investigate later\n return (typeof event.clientX !== unknown ? event.clientX : 0);\n },\n\n pointerY = function(event) {\n return (typeof event.clientY !== unknown ? event.clientY : 0);\n };\n\n function _getPointer(event, pageProp, clientProp) {\n var touchProp = event.type === 'touchend' ? 'changedTouches' : 'touches';\n\n return (event[touchProp] && event[touchProp][0]\n ? (event[touchProp][0][pageProp] - (event[touchProp][0][pageProp] - event[touchProp][0][clientProp]))\n || event[clientProp]\n : event[clientProp]);\n }\n\n if (fabric.isTouchSupported) {\n pointerX = function(event) {\n return _getPointer(event, 'pageX', 'clientX');\n };\n pointerY = function(event) {\n return _getPointer(event, 'pageY', 'clientY');\n };\n }\n\n fabric.util.getPointer = getPointer;\n\n fabric.util.object.extend(fabric.util, fabric.Observable);\n\n})();\n\n\n(function () {\n\n /**\n * Cross-browser wrapper for setting element's style\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {Object} styles\n * @return {HTMLElement} Element that was passed as a first argument\n */\n function setStyle(element, styles) {\n var elementStyle = element.style;\n if (!elementStyle) {\n return element;\n }\n if (typeof styles === 'string') {\n element.style.cssText += ';' + styles;\n return styles.indexOf('opacity') > -1\n ? setOpacity(element, styles.match(/opacity:\\s*(\\d?\\.?\\d*)/)[1])\n : element;\n }\n for (var property in styles) {\n if (property === 'opacity') {\n setOpacity(element, styles[property]);\n }\n else {\n var normalizedProperty = (property === 'float' || property === 'cssFloat')\n ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')\n : property;\n elementStyle[normalizedProperty] = styles[property];\n }\n }\n return element;\n }\n\n var parseEl = fabric.document.createElement('div'),\n supportsOpacity = typeof parseEl.style.opacity === 'string',\n supportsFilters = typeof parseEl.style.filter === 'string',\n reOpacity = /alpha\\s*\\(\\s*opacity\\s*=\\s*([^\\)]+)\\)/,\n\n /** @ignore */\n setOpacity = function (element) { return element; };\n\n if (supportsOpacity) {\n /** @ignore */\n setOpacity = function(element, value) {\n element.style.opacity = value;\n return element;\n };\n }\n else if (supportsFilters) {\n /** @ignore */\n setOpacity = function(element, value) {\n var es = element.style;\n if (element.currentStyle && !element.currentStyle.hasLayout) {\n es.zoom = 1;\n }\n if (reOpacity.test(es.filter)) {\n value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')');\n es.filter = es.filter.replace(reOpacity, value);\n }\n else {\n es.filter += ' alpha(opacity=' + (value * 100) + ')';\n }\n return element;\n };\n }\n\n fabric.util.setStyle = setStyle;\n\n})();\n\n\n(function() {\n\n var _slice = Array.prototype.slice;\n\n /**\n * Takes id and returns an element with that id (if one exists in a document)\n * @memberOf fabric.util\n * @param {String|HTMLElement} id\n * @return {HTMLElement|null}\n */\n function getById(id) {\n return typeof id === 'string' ? fabric.document.getElementById(id) : id;\n }\n\n var sliceCanConvertNodelists,\n /**\n * Converts an array-like object (e.g. arguments or NodeList) to an array\n * @memberOf fabric.util\n * @param {Object} arrayLike\n * @return {Array}\n */\n toArray = function(arrayLike) {\n return _slice.call(arrayLike, 0);\n };\n\n try {\n sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;\n }\n catch (err) { }\n\n if (!sliceCanConvertNodelists) {\n toArray = function(arrayLike) {\n var arr = new Array(arrayLike.length), i = arrayLike.length;\n while (i--) {\n arr[i] = arrayLike[i];\n }\n return arr;\n };\n }\n\n /**\n * Creates specified element with specified attributes\n * @memberOf fabric.util\n * @param {String} tagName Type of an element to create\n * @param {Object} [attributes] Attributes to set on an element\n * @return {HTMLElement} Newly created element\n */\n function makeElement(tagName, attributes) {\n var el = fabric.document.createElement(tagName);\n for (var prop in attributes) {\n if (prop === 'class') {\n el.className = attributes[prop];\n }\n else if (prop === 'for') {\n el.htmlFor = attributes[prop];\n }\n else {\n el.setAttribute(prop, attributes[prop]);\n }\n }\n return el;\n }\n\n /**\n * Adds class to an element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to add class to\n * @param {String} className Class to add to an element\n */\n function addClass(element, className) {\n if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {\n element.className += (element.className ? ' ' : '') + className;\n }\n }\n\n /**\n * Wraps element with another element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to wrap\n * @param {HTMLElement|String} wrapper Element to wrap with\n * @param {Object} [attributes] Attributes to set on a wrapper\n * @return {HTMLElement} wrapper\n */\n function wrapElement(element, wrapper, attributes) {\n if (typeof wrapper === 'string') {\n wrapper = makeElement(wrapper, attributes);\n }\n if (element.parentNode) {\n element.parentNode.replaceChild(wrapper, element);\n }\n wrapper.appendChild(element);\n return wrapper;\n }\n\n /**\n * Returns element scroll offsets\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to operate on\n * @return {Object} Object with left/top values\n */\n function getScrollLeftTop(element) {\n\n var left = 0,\n top = 0,\n docElement = fabric.document.documentElement,\n body = fabric.document.body || {\n scrollLeft: 0, scrollTop: 0\n };\n\n // While loop checks (and then sets element to) .parentNode OR .host\n // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n // but the .parentNode of a root ShadowDOM node will always be null, instead\n // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n while (element && (element.parentNode || element.host)) {\n\n // Set element to element parent, or 'host' in case of ShadowDOM\n element = element.parentNode || element.host;\n\n if (element === fabric.document) {\n left = body.scrollLeft || docElement.scrollLeft || 0;\n top = body.scrollTop || docElement.scrollTop || 0;\n }\n else {\n left += element.scrollLeft || 0;\n top += element.scrollTop || 0;\n }\n\n if (element.nodeType === 1 &&\n fabric.util.getElementStyle(element, 'position') === 'fixed') {\n break;\n }\n }\n\n return { left: left, top: top };\n }\n\n /**\n * Returns offset for a given element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get offset for\n * @return {Object} Object with \"left\" and \"top\" properties\n */\n function getElementOffset(element) {\n var docElem,\n doc = element && element.ownerDocument,\n box = { left: 0, top: 0 },\n offset = { left: 0, top: 0 },\n scrollLeftTop,\n offsetAttributes = {\n borderLeftWidth: 'left',\n borderTopWidth: 'top',\n paddingLeft: 'left',\n paddingTop: 'top'\n };\n\n if (!doc) {\n return offset;\n }\n\n for (var attr in offsetAttributes) {\n offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0;\n }\n\n docElem = doc.documentElement;\n if ( typeof element.getBoundingClientRect !== 'undefined' ) {\n box = element.getBoundingClientRect();\n }\n\n scrollLeftTop = getScrollLeftTop(element);\n\n return {\n left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top\n };\n }\n\n /**\n * Returns style attribute value of a given element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get style attribute for\n * @param {String} attr Style attribute to get for element\n * @return {String} Style attribute value of the given element.\n */\n var getElementStyle;\n if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {\n getElementStyle = function(element, attr) {\n var style = fabric.document.defaultView.getComputedStyle(element, null);\n return style ? style[attr] : undefined;\n };\n }\n else {\n getElementStyle = function(element, attr) {\n var value = element.style[attr];\n if (!value && element.currentStyle) {\n value = element.currentStyle[attr];\n }\n return value;\n };\n }\n\n (function () {\n var style = fabric.document.documentElement.style,\n selectProp = 'userSelect' in style\n ? 'userSelect'\n : 'MozUserSelect' in style\n ? 'MozUserSelect'\n : 'WebkitUserSelect' in style\n ? 'WebkitUserSelect'\n : 'KhtmlUserSelect' in style\n ? 'KhtmlUserSelect'\n : '';\n\n /**\n * Makes element unselectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make unselectable\n * @return {HTMLElement} Element that was passed in\n */\n function makeElementUnselectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = fabric.util.falseFunction;\n }\n if (selectProp) {\n element.style[selectProp] = 'none';\n }\n else if (typeof element.unselectable === 'string') {\n element.unselectable = 'on';\n }\n return element;\n }\n\n /**\n * Makes element selectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make selectable\n * @return {HTMLElement} Element that was passed in\n */\n function makeElementSelectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = null;\n }\n if (selectProp) {\n element.style[selectProp] = '';\n }\n else if (typeof element.unselectable === 'string') {\n element.unselectable = '';\n }\n return element;\n }\n\n fabric.util.makeElementUnselectable = makeElementUnselectable;\n fabric.util.makeElementSelectable = makeElementSelectable;\n })();\n\n (function() {\n\n /**\n * Inserts a script element with a given url into a document; invokes callback, when that script is finished loading\n * @memberOf fabric.util\n * @param {String} url URL of a script to load\n * @param {Function} callback Callback to execute when script is finished loading\n */\n function getScript(url, callback) {\n var headEl = fabric.document.getElementsByTagName('head')[0],\n scriptEl = fabric.document.createElement('script'),\n loading = true;\n\n /** @ignore */\n scriptEl.onload = /** @ignore */ scriptEl.onreadystatechange = function(e) {\n if (loading) {\n if (typeof this.readyState === 'string' &&\n this.readyState !== 'loaded' &&\n this.readyState !== 'complete') {\n return;\n }\n loading = false;\n callback(e || fabric.window.event);\n scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null;\n }\n };\n scriptEl.src = url;\n headEl.appendChild(scriptEl);\n // causes issue in Opera\n // headEl.removeChild(scriptEl);\n }\n\n fabric.util.getScript = getScript;\n })();\n\n fabric.util.getById = getById;\n fabric.util.toArray = toArray;\n fabric.util.makeElement = makeElement;\n fabric.util.addClass = addClass;\n fabric.util.wrapElement = wrapElement;\n fabric.util.getScrollLeftTop = getScrollLeftTop;\n fabric.util.getElementOffset = getElementOffset;\n fabric.util.getElementStyle = getElementStyle;\n\n})();\n\n\n(function() {\n\n function addParamToUrl(url, param) {\n return url + (/\\?/.test(url) ? '&' : '?') + param;\n }\n\n var makeXHR = (function() {\n var factories = [\n function() { return new ActiveXObject('Microsoft.XMLHTTP'); },\n function() { return new ActiveXObject('Msxml2.XMLHTTP'); },\n function() { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); },\n function() { return new XMLHttpRequest(); }\n ];\n for (var i = factories.length; i--; ) {\n try {\n var req = factories[i]();\n if (req) {\n return factories[i];\n }\n }\n catch (err) { }\n }\n })();\n\n function emptyFn() { }\n\n /**\n * Cross-browser abstraction for sending XMLHttpRequest\n * @memberOf fabric.util\n * @param {String} url URL to send XMLHttpRequest to\n * @param {Object} [options] Options object\n * @param {String} [options.method=\"GET\"]\n * @param {String} [options.parameters] parameters to append to url in GET or in body\n * @param {String} [options.body] body to send with POST or PUT request\n * @param {Function} options.onComplete Callback to invoke when request is completed\n * @return {XMLHttpRequest} request\n */\n function request(url, options) {\n\n options || (options = { });\n\n var method = options.method ? options.method.toUpperCase() : 'GET',\n onComplete = options.onComplete || function() { },\n xhr = makeXHR(),\n body = options.body || options.parameters;\n\n /** @ignore */\n xhr.onreadystatechange = function() {\n if (xhr.readyState === 4) {\n onComplete(xhr);\n xhr.onreadystatechange = emptyFn;\n }\n };\n\n if (method === 'GET') {\n body = null;\n if (typeof options.parameters === 'string') {\n url = addParamToUrl(url, options.parameters);\n }\n }\n\n xhr.open(method, url, true);\n\n if (method === 'POST' || method === 'PUT') {\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n }\n\n xhr.send(body);\n return xhr;\n }\n\n fabric.util.request = request;\n})();\n\n\n/**\n * Wrapper around `console.log` (when available)\n * @param {*} [values] Values to log\n */\nfabric.log = function() { };\n\n/**\n * Wrapper around `console.warn` (when available)\n * @param {*} [values] Values to log as a warning\n */\nfabric.warn = function() { };\n\n/* eslint-disable */\nif (typeof console !== 'undefined') {\n\n ['log', 'warn'].forEach(function(methodName) {\n\n if (typeof console[methodName] !== 'undefined' &&\n typeof console[methodName].apply === 'function') {\n\n fabric[methodName] = function() {\n return console[methodName].apply(console, arguments);\n };\n }\n });\n}\n/* eslint-enable */\n\n\n(function() {\n\n function noop() {\n return false;\n }\n\n /**\n * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Number} [options.startValue=0] Starting value\n * @param {Number} [options.endValue=100] Ending value\n * @param {Number} [options.byValue=100] Value to modify the property by\n * @param {Function} [options.easing] Easing function\n * @param {Number} [options.duration=500] Duration of change (in ms)\n */\n function animate(options) {\n\n requestAnimFrame(function(timestamp) {\n options || (options = { });\n\n var start = timestamp || +new Date(),\n duration = options.duration || 500,\n finish = start + duration, time,\n onChange = options.onChange || noop,\n abort = options.abort || noop,\n onComplete = options.onComplete || noop,\n easing = options.easing || function(t, b, c, d) {return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;},\n startValue = 'startValue' in options ? options.startValue : 0,\n endValue = 'endValue' in options ? options.endValue : 100,\n byValue = options.byValue || endValue - startValue;\n\n options.onStart && options.onStart();\n\n (function tick(ticktime) {\n if (abort()) {\n onComplete(endValue, 1, 1);\n return;\n }\n time = ticktime || +new Date();\n var currentTime = time > finish ? duration : (time - start),\n timePerc = currentTime / duration,\n current = easing(currentTime, startValue, byValue, duration),\n valuePerc = Math.abs((current - startValue) / byValue);\n onChange(current, valuePerc, timePerc);\n if (time > finish) {\n options.onComplete && options.onComplete();\n return;\n }\n requestAnimFrame(tick);\n })(start);\n });\n\n }\n\n var _requestAnimFrame = fabric.window.requestAnimationFrame ||\n fabric.window.webkitRequestAnimationFrame ||\n fabric.window.mozRequestAnimationFrame ||\n fabric.window.oRequestAnimationFrame ||\n fabric.window.msRequestAnimationFrame ||\n function(callback) {\n fabric.window.setTimeout(callback, 1000 / 60);\n };\n\n /**\n * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method\n * @memberOf fabric.util\n * @param {Function} callback Callback to invoke\n * @param {DOMElement} element optional Element to associate with animation\n */\n function requestAnimFrame() {\n return _requestAnimFrame.apply(fabric.window, arguments);\n }\n\n fabric.util.animate = animate;\n fabric.util.requestAnimFrame = requestAnimFrame;\n\n})();\n\n\n(function() {\n // Calculate an in-between color. Returns a \"rgba()\" string.\n // Credit: Edwin Martin \n // http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js\n function calculateColor(begin, end, pos) {\n var color = 'rgba('\n + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ','\n + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ','\n + parseInt((begin[2] + pos * (end[2] - begin[2])), 10);\n\n color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1);\n color += ')';\n return color;\n }\n\n /**\n * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {String} fromColor The starting color in hex or rgb(a) format.\n * @param {String} toColor The starting color in hex or rgb(a) format.\n * @param {Number} [duration] Duration of change (in ms).\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used.\n */\n function animateColor(fromColor, toColor, duration, options) {\n var startColor = new fabric.Color(fromColor).getSource(),\n endColor = new fabric.Color(toColor).getSource();\n\n options = options || {};\n\n fabric.util.animate(fabric.util.object.extend(options, {\n duration: duration || 500,\n startValue: startColor,\n endValue: endColor,\n byValue: endColor,\n easing: function (currentTime, startValue, byValue, duration) {\n var posValue = options.colorEasing\n ? options.colorEasing(currentTime, duration)\n : 1 - Math.cos(currentTime / duration * (Math.PI / 2));\n return calculateColor(startValue, byValue, posValue);\n }\n }));\n }\n\n fabric.util.animateColor = animateColor;\n\n})();\n\n\n(function() {\n\n function normalize(a, c, p, s) {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n }\n else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = p / (2 * Math.PI) * Math.asin(1);\n }\n else {\n s = p / (2 * Math.PI) * Math.asin(c / a);\n }\n }\n return { a: a, c: c, p: p, s: s };\n }\n\n function elastic(opts, t, d) {\n return opts.a *\n Math.pow(2, 10 * (t -= 1)) *\n Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p );\n }\n\n /**\n * Cubic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutCubic(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t + 1) + b;\n }\n\n /**\n * Cubic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutCubic(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t + b;\n }\n return c / 2 * ((t -= 2) * t * t + 2) + b;\n }\n\n /**\n * Quartic easing in\n * @memberOf fabric.util.ease\n */\n function easeInQuart(t, b, c, d) {\n return c * (t /= d) * t * t * t + b;\n }\n\n /**\n * Quartic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutQuart(t, b, c, d) {\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n }\n\n /**\n * Quartic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutQuart(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t * t + b;\n }\n return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\n }\n\n /**\n * Quintic easing in\n * @memberOf fabric.util.ease\n */\n function easeInQuint(t, b, c, d) {\n return c * (t /= d) * t * t * t * t + b;\n }\n\n /**\n * Quintic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutQuint(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\n }\n\n /**\n * Quintic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutQuint(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t * t * t + b;\n }\n return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\n }\n\n /**\n * Sinusoidal easing in\n * @memberOf fabric.util.ease\n */\n function easeInSine(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n }\n\n /**\n * Sinusoidal easing out\n * @memberOf fabric.util.ease\n */\n function easeOutSine(t, b, c, d) {\n return c * Math.sin(t / d * (Math.PI / 2)) + b;\n }\n\n /**\n * Sinusoidal easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutSine(t, b, c, d) {\n return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n }\n\n /**\n * Exponential easing in\n * @memberOf fabric.util.ease\n */\n function easeInExpo(t, b, c, d) {\n return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;\n }\n\n /**\n * Exponential easing out\n * @memberOf fabric.util.ease\n */\n function easeOutExpo(t, b, c, d) {\n return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;\n }\n\n /**\n * Exponential easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutExpo(t, b, c, d) {\n if (t === 0) {\n return b;\n }\n if (t === d) {\n return b + c;\n }\n t /= d / 2;\n if (t < 1) {\n return c / 2 * Math.pow(2, 10 * (t - 1)) + b;\n }\n return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;\n }\n\n /**\n * Circular easing in\n * @memberOf fabric.util.ease\n */\n function easeInCirc(t, b, c, d) {\n return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n }\n\n /**\n * Circular easing out\n * @memberOf fabric.util.ease\n */\n function easeOutCirc(t, b, c, d) {\n return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n }\n\n /**\n * Circular easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutCirc(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;\n }\n return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n }\n\n /**\n * Elastic easing in\n * @memberOf fabric.util.ease\n */\n function easeInElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n var opts = normalize(a, c, p, s);\n return -elastic(opts, t, d) + b;\n }\n\n /**\n * Elastic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n var opts = normalize(a, c, p, s);\n return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b;\n }\n\n /**\n * Elastic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d / 2;\n if (t === 2) {\n return b + c;\n }\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n var opts = normalize(a, c, p, s);\n if (t < 1) {\n return -0.5 * elastic(opts, t, d) + b;\n }\n return opts.a * Math.pow(2, -10 * (t -= 1)) *\n Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b;\n }\n\n /**\n * Backwards easing in\n * @memberOf fabric.util.ease\n */\n function easeInBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\n }\n\n /**\n * Backwards easing out\n * @memberOf fabric.util.ease\n */\n function easeOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n }\n\n /**\n * Backwards easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n t /= d / 2;\n if (t < 1) {\n return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;\n }\n return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\n }\n\n /**\n * Bouncing easing in\n * @memberOf fabric.util.ease\n */\n function easeInBounce(t, b, c, d) {\n return c - easeOutBounce (d - t, 0, c, d) + b;\n }\n\n /**\n * Bouncing easing out\n * @memberOf fabric.util.ease\n */\n function easeOutBounce(t, b, c, d) {\n if ((t /= d) < (1 / 2.75)) {\n return c * (7.5625 * t * t) + b;\n }\n else if (t < (2 / 2.75)) {\n return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;\n }\n else if (t < (2.5 / 2.75)) {\n return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;\n }\n else {\n return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;\n }\n }\n\n /**\n * Bouncing easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutBounce(t, b, c, d) {\n if (t < d / 2) {\n return easeInBounce (t * 2, 0, c, d) * 0.5 + b;\n }\n return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n }\n\n /**\n * Easing functions\n * See Easing Equations by Robert Penner\n * @namespace fabric.util.ease\n */\n fabric.util.ease = {\n\n /**\n * Quadratic easing in\n * @memberOf fabric.util.ease\n */\n easeInQuad: function(t, b, c, d) {\n return c * (t /= d) * t + b;\n },\n\n /**\n * Quadratic easing out\n * @memberOf fabric.util.ease\n */\n easeOutQuad: function(t, b, c, d) {\n return -c * (t /= d) * (t - 2) + b;\n },\n\n /**\n * Quadratic easing in and out\n * @memberOf fabric.util.ease\n */\n easeInOutQuad: function(t, b, c, d) {\n t /= (d / 2);\n if (t < 1) {\n return c / 2 * t * t + b;\n }\n return -c / 2 * ((--t) * (t - 2) - 1) + b;\n },\n\n /**\n * Cubic easing in\n * @memberOf fabric.util.ease\n */\n easeInCubic: function(t, b, c, d) {\n return c * (t /= d) * t * t + b;\n },\n\n easeOutCubic: easeOutCubic,\n easeInOutCubic: easeInOutCubic,\n easeInQuart: easeInQuart,\n easeOutQuart: easeOutQuart,\n easeInOutQuart: easeInOutQuart,\n easeInQuint: easeInQuint,\n easeOutQuint: easeOutQuint,\n easeInOutQuint: easeInOutQuint,\n easeInSine: easeInSine,\n easeOutSine: easeOutSine,\n easeInOutSine: easeInOutSine,\n easeInExpo: easeInExpo,\n easeOutExpo: easeOutExpo,\n easeInOutExpo: easeInOutExpo,\n easeInCirc: easeInCirc,\n easeOutCirc: easeOutCirc,\n easeInOutCirc: easeInOutCirc,\n easeInElastic: easeInElastic,\n easeOutElastic: easeOutElastic,\n easeInOutElastic: easeInOutElastic,\n easeInBack: easeInBack,\n easeOutBack: easeOutBack,\n easeInOutBack: easeInOutBack,\n easeInBounce: easeInBounce,\n easeOutBounce: easeOutBounce,\n easeInOutBounce: easeInOutBounce\n };\n\n})();\n\n\n(function(global) {\n\n 'use strict';\n\n /**\n * @name fabric\n * @namespace\n */\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n parseUnit = fabric.util.parseUnit,\n multiplyTransformMatrices = fabric.util.multiplyTransformMatrices,\n\n reAllowedSVGTagNames = /^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,\n reViewBoxTagNames = /^(symbol|image|marker|pattern|view|svg)$/i,\n reNotAllowedAncestors = /^(?:pattern|defs|symbol|metadata|clipPath|mask)$/i,\n reAllowedParents = /^(symbol|g|a|svg)$/i,\n\n attributesMap = {\n cx: 'left',\n x: 'left',\n r: 'radius',\n cy: 'top',\n y: 'top',\n display: 'visible',\n visibility: 'visible',\n transform: 'transformMatrix',\n 'fill-opacity': 'fillOpacity',\n 'fill-rule': 'fillRule',\n 'font-family': 'fontFamily',\n 'font-size': 'fontSize',\n 'font-style': 'fontStyle',\n 'font-weight': 'fontWeight',\n 'stroke-dasharray': 'strokeDashArray',\n 'stroke-linecap': 'strokeLineCap',\n 'stroke-linejoin': 'strokeLineJoin',\n 'stroke-miterlimit': 'strokeMiterLimit',\n 'stroke-opacity': 'strokeOpacity',\n 'stroke-width': 'strokeWidth',\n 'text-decoration': 'textDecoration',\n 'text-anchor': 'originX',\n opacity: 'opacity'\n },\n\n colorAttributes = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity'\n };\n\n fabric.cssRules = { };\n fabric.gradientDefs = { };\n\n function normalizeAttr(attr) {\n // transform attribute names\n if (attr in attributesMap) {\n return attributesMap[attr];\n }\n return attr;\n }\n\n function normalizeValue(attr, value, parentAttributes, fontSize) {\n var isArray = Object.prototype.toString.call(value) === '[object Array]',\n parsed;\n\n if ((attr === 'fill' || attr === 'stroke') && value === 'none') {\n value = '';\n }\n else if (attr === 'strokeDashArray') {\n if (value === 'none') {\n value = null;\n }\n else {\n value = value.replace(/,/g, ' ').split(/\\s+/).map(function(n) {\n return parseFloat(n);\n });\n }\n }\n else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n value = multiplyTransformMatrices(\n parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));\n }\n else {\n value = fabric.parseTransformAttribute(value);\n }\n }\n else if (attr === 'visible') {\n value = (value === 'none' || value === 'hidden') ? false : true;\n // display=none on parent element always takes precedence over child element\n if (parentAttributes && parentAttributes.visible === false) {\n value = false;\n }\n }\n else if (attr === 'opacity') {\n value = parseFloat(value);\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n value *= parentAttributes.opacity;\n }\n }\n else if (attr === 'originX' /* text-anchor */) {\n value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';\n }\n else {\n parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);\n }\n\n return (!isArray && isNaN(parsed) ? value : parsed);\n }\n\n /**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n function _setStrokeFillOpacity(attributes) {\n for (var attr in colorAttributes) {\n\n if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') {\n continue;\n }\n\n if (typeof attributes[attr] === 'undefined') {\n if (!fabric.Object.prototype[attr]) {\n continue;\n }\n attributes[attr] = fabric.Object.prototype[attr];\n }\n\n if (attributes[attr].indexOf('url(') === 0) {\n continue;\n }\n\n var color = new fabric.Color(attributes[attr]);\n attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba();\n }\n return attributes;\n }\n\n /**\n * @private\n */\n function _getMultipleNodes(doc, nodeNames) {\n var nodeName, nodeArray = [], nodeList;\n for (var i = 0; i < nodeNames.length; i++) {\n nodeName = nodeNames[i];\n nodeList = doc.getElementsByTagName(nodeName);\n nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList));\n }\n return nodeArray;\n }\n\n /**\n * Parses \"transform\" attribute, returning an array of values\n * @static\n * @function\n * @memberOf fabric\n * @param {String} attributeValue String containing attribute value\n * @return {Array} Array of 6 elements representing transformation matrix\n */\n fabric.parseTransformAttribute = (function() {\n function rotateMatrix(matrix, args) {\n var cos = Math.cos(args[0]), sin = Math.sin(args[0]),\n x = 0, y = 0;\n if (args.length === 3) {\n x = args[1];\n y = args[2];\n }\n\n matrix[0] = cos;\n matrix[1] = sin;\n matrix[2] = -sin;\n matrix[3] = cos;\n matrix[4] = x - (cos * x - sin * y);\n matrix[5] = y - (sin * x + cos * y);\n }\n\n function scaleMatrix(matrix, args) {\n var multiplierX = args[0],\n multiplierY = (args.length === 2) ? args[1] : args[0];\n\n matrix[0] = multiplierX;\n matrix[3] = multiplierY;\n }\n\n function skewMatrix(matrix, args, pos) {\n matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0]));\n }\n\n function translateMatrix(matrix, args) {\n matrix[4] = args[0];\n if (args.length === 2) {\n matrix[5] = args[1];\n }\n }\n\n // identity matrix\n var iMatrix = [\n 1, // a\n 0, // b\n 0, // c\n 1, // d\n 0, // e\n 0 // f\n ],\n\n // == begin transform regexp\n number = fabric.reNum,\n\n commaWsp = '(?:\\\\s+,?\\\\s*|,\\\\s*)',\n\n skewX = '(?:(skewX)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n skewY = '(?:(skewY)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n rotate = '(?:(rotate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + ')' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n scale = '(?:(scale)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n translate = '(?:(translate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n matrix = '(?:(matrix)\\\\s*\\\\(\\\\s*' +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' +\n '\\\\s*\\\\))',\n\n transform = '(?:' +\n matrix + '|' +\n translate + '|' +\n scale + '|' +\n rotate + '|' +\n skewX + '|' +\n skewY +\n ')',\n\n transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',\n\n transformList = '^\\\\s*(?:' + transforms + '?)\\\\s*$',\n\n // http://www.w3.org/TR/SVG/coords.html#TransformAttribute\n reTransformList = new RegExp(transformList),\n // == end transform regexp\n\n reTransform = new RegExp(transform, 'g');\n\n return function(attributeValue) {\n\n // start with identity matrix\n var matrix = iMatrix.concat(),\n matrices = [];\n\n // return if no argument was given or\n // an argument does not match transform attribute regexp\n if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) {\n return matrix;\n }\n\n attributeValue.replace(reTransform, function(match) {\n\n var m = new RegExp(transform).exec(match).filter(function (match) {\n // match !== '' && match != null\n return (!!match);\n }),\n operation = m[1],\n args = m.slice(2).map(parseFloat);\n\n switch (operation) {\n case 'translate':\n translateMatrix(matrix, args);\n break;\n case 'rotate':\n args[0] = fabric.util.degreesToRadians(args[0]);\n rotateMatrix(matrix, args);\n break;\n case 'scale':\n scaleMatrix(matrix, args);\n break;\n case 'skewX':\n skewMatrix(matrix, args, 2);\n break;\n case 'skewY':\n skewMatrix(matrix, args, 1);\n break;\n case 'matrix':\n matrix = args;\n break;\n }\n\n // snapshot current matrix into matrices array\n matrices.push(matrix.concat());\n // reset\n matrix = iMatrix.concat();\n });\n\n var combinedMatrix = matrices[0];\n while (matrices.length > 1) {\n matrices.shift();\n combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);\n }\n return combinedMatrix;\n };\n })();\n\n /**\n * @private\n */\n function parseStyleString(style, oStyle) {\n var attr, value;\n style.replace(/;\\s*$/, '').split(';').forEach(function (chunk) {\n var pair = chunk.split(':');\n\n attr = pair[0].trim().toLowerCase();\n value = pair[1].trim();\n\n oStyle[attr] = value;\n });\n }\n\n /**\n * @private\n */\n function parseStyleObject(style, oStyle) {\n var attr, value;\n for (var prop in style) {\n if (typeof style[prop] === 'undefined') {\n continue;\n }\n\n attr = prop.toLowerCase();\n value = style[prop];\n\n oStyle[attr] = value;\n }\n }\n\n /**\n * @private\n */\n function getGlobalStylesForElement(element, svgUid) {\n var styles = { };\n for (var rule in fabric.cssRules[svgUid]) {\n if (elementMatchesRule(element, rule.split(' '))) {\n for (var property in fabric.cssRules[svgUid][rule]) {\n styles[property] = fabric.cssRules[svgUid][rule][property];\n }\n }\n }\n return styles;\n }\n\n /**\n * @private\n */\n function elementMatchesRule(element, selectors) {\n var firstMatching, parentMatching = true;\n //start from rightmost selector.\n firstMatching = selectorMatches(element, selectors.pop());\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n return firstMatching && parentMatching && (selectors.length === 0);\n }\n\n function doesSomeParentMatch(element, selectors) {\n var selector, parentMatching = true;\n while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {\n if (parentMatching) {\n selector = selectors.pop();\n }\n element = element.parentNode;\n parentMatching = selectorMatches(element, selector);\n }\n return selectors.length === 0;\n }\n\n /**\n * @private\n */\n function selectorMatches(element, selector) {\n var nodeName = element.nodeName,\n classNames = element.getAttribute('class'),\n id = element.getAttribute('id'), matcher;\n // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n if (id && selector.length) {\n matcher = new RegExp('#' + id + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n if (classNames && selector.length) {\n classNames = classNames.split(' ');\n for (var i = classNames.length; i--;) {\n matcher = new RegExp('\\\\.' + classNames[i] + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n }\n return selector.length === 0;\n }\n\n /**\n * @private\n * to support IE8 missing getElementById on SVGdocument\n */\n function elementById(doc, id) {\n var el;\n doc.getElementById && (el = doc.getElementById(id));\n if (el) {\n return el;\n }\n var node, i, nodelist = doc.getElementsByTagName('*');\n for (i = 0; i < nodelist.length; i++) {\n node = nodelist[i];\n if (id === node.getAttribute('id')) {\n return node;\n }\n }\n }\n\n /**\n * @private\n */\n function parseUseDirectives(doc) {\n var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']), i = 0;\n\n while (nodelist.length && i < nodelist.length) {\n var el = nodelist[i],\n xlink = el.getAttribute('xlink:href').substr(1),\n x = el.getAttribute('x') || 0,\n y = el.getAttribute('y') || 0,\n el2 = elementById(doc, xlink).cloneNode(true),\n currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')',\n parentNode, oldLength = nodelist.length, attr, j, attrs, l;\n\n applyViewboxTransform(el2);\n if (/^svg$/i.test(el2.nodeName)) {\n var el3 = el2.ownerDocument.createElement('g');\n for (j = 0, attrs = el2.attributes, l = attrs.length; j < l; j++) {\n attr = attrs.item(j);\n el3.setAttribute(attr.nodeName, attr.nodeValue);\n }\n // el2.firstChild != null\n while (el2.firstChild) {\n el3.appendChild(el2.firstChild);\n }\n el2 = el3;\n }\n\n for (j = 0, attrs = el.attributes, l = attrs.length; j < l; j++) {\n attr = attrs.item(j);\n if (attr.nodeName === 'x' || attr.nodeName === 'y' || attr.nodeName === 'xlink:href') {\n continue;\n }\n\n if (attr.nodeName === 'transform') {\n currentTrans = attr.nodeValue + ' ' + currentTrans;\n }\n else {\n el2.setAttribute(attr.nodeName, attr.nodeValue);\n }\n }\n\n el2.setAttribute('transform', currentTrans);\n el2.setAttribute('instantiated_by_use', '1');\n el2.removeAttribute('id');\n parentNode = el.parentNode;\n parentNode.replaceChild(el2, el);\n // some browsers do not shorten nodelist after replaceChild (IE8)\n if (nodelist.length === oldLength) {\n i++;\n }\n }\n }\n\n // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n // matches, e.g.: +14.56e-12, etc.\n var reViewBoxAttrValue = new RegExp(\n '^' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*' +\n '$'\n );\n\n /**\n * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\n function applyViewboxTransform(element) {\n\n var viewBoxAttr = element.getAttribute('viewBox'),\n scaleX = 1,\n scaleY = 1,\n minX = 0,\n minY = 0,\n viewBoxWidth, viewBoxHeight, matrix, el,\n widthAttr = element.getAttribute('width'),\n heightAttr = element.getAttribute('height'),\n x = element.getAttribute('x') || 0,\n y = element.getAttribute('y') || 0,\n preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '',\n missingViewBox = (!viewBoxAttr || !reViewBoxTagNames.test(element.nodeName)\n || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))),\n missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'),\n toBeParsed = missingViewBox && missingDimAttr,\n parsedDim = { }, translateMatrix = '';\n\n parsedDim.width = 0;\n parsedDim.height = 0;\n parsedDim.toBeParsed = toBeParsed;\n\n if (toBeParsed) {\n return parsedDim;\n }\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n return parsedDim;\n }\n\n minX = -parseFloat(viewBoxAttr[1]);\n minY = -parseFloat(viewBoxAttr[2]);\n viewBoxWidth = parseFloat(viewBoxAttr[3]);\n viewBoxHeight = parseFloat(viewBoxAttr[4]);\n\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n }\n else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n }\n\n // default is to preserve aspect ratio\n preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);\n if (preserveAspectRatio.alignX !== 'none') {\n //translate all container for the effect of Mid, Min, Max\n scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX);\n }\n\n if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) {\n return parsedDim;\n }\n\n if (x || y) {\n translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n }\n\n matrix = translateMatrix + ' matrix(' + scaleX +\n ' 0' +\n ' 0 ' +\n scaleY + ' ' +\n (minX * scaleX) + ' ' +\n (minY * scaleY) + ') ';\n\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElement('g');\n // element.firstChild != null\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n element.appendChild(el);\n }\n else {\n el = element;\n matrix = el.getAttribute('transform') + matrix;\n }\n\n el.setAttribute('transform', matrix);\n return parsedDim;\n }\n\n function hasAncestorWithNodeName(element, nodeName) {\n while (element && (element = element.parentNode)) {\n if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', ''))\n && !element.getAttribute('instantiated_by_use')) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @param {Function} callback Callback to call when parsing is finished;\n * It's being passed an array of elements (parsed from a document).\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [parsingOptions] options for parsing document\n * @param {String} [parsingOptions.crossOrigin] crossOrigin settings\n */\n fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {\n if (!doc) {\n return;\n }\n\n parseUseDirectives(doc);\n\n var svgUid = fabric.Object.__uid++,\n options = applyViewboxTransform(doc),\n descendants = fabric.util.toArray(doc.getElementsByTagName('*'));\n options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;\n options.svgUid = svgUid;\n\n if (descendants.length === 0 && fabric.isLikelyNode) {\n // we're likely in node, where \"o3-xml\" library fails to gEBTN(\"*\")\n // https://github.com/ajaxorg/node-o3-xml/issues/21\n descendants = doc.selectNodes('//*[name(.)!=\"svg\"]');\n var arr = [];\n for (var i = 0, len = descendants.length; i < len; i++) {\n arr[i] = descendants[i];\n }\n descendants = arr;\n }\n\n var elements = descendants.filter(function(el) {\n applyViewboxTransform(el);\n return reAllowedSVGTagNames.test(el.nodeName.replace('svg:', '')) &&\n !hasAncestorWithNodeName(el, reNotAllowedAncestors); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n });\n\n if (!elements || (elements && !elements.length)) {\n callback && callback([], {});\n return;\n }\n\n fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc);\n fabric.cssRules[svgUid] = fabric.getCSSRules(doc);\n // Precedence of rules: style > class > attribute\n fabric.parseElements(elements, function(instances) {\n if (callback) {\n callback(instances, options);\n }\n }, clone(options), reviver, parsingOptions);\n };\n\n var reFontDeclaration = new RegExp(\n '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n fabric.reNum +\n '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' + fabric.reNum + '))?\\\\s+(.*)');\n\n extend(fabric, {\n /**\n * Parses a short font declaration, building adding its properties to a style object\n * @static\n * @function\n * @memberOf fabric\n * @param {String} value font declaration\n * @param {Object} oStyle definition\n */\n parseFontDeclaration: function(value, oStyle) {\n var match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\n var fontStyle = match[1],\n // font variant is not used\n // fontVariant = match[2],\n fontWeight = match[3],\n fontSize = match[4],\n lineHeight = match[5],\n fontFamily = match[6];\n\n if (fontStyle) {\n oStyle.fontStyle = fontStyle;\n }\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);\n }\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\n if (lineHeight) {\n oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n }\n },\n\n /**\n * Parses an SVG document, returning all of the gradient declarations found in it\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n */\n getGradientDefs: function(doc) {\n var tagArray = [\n 'linearGradient',\n 'radialGradient',\n 'svg:linearGradient',\n 'svg:radialGradient'],\n elList = _getMultipleNodes(doc, tagArray),\n el, j = 0, id, xlink,\n gradientDefs = { }, idsToXlinkMap = { };\n\n j = elList.length;\n\n while (j--) {\n el = elList[j];\n xlink = el.getAttribute('xlink:href');\n id = el.getAttribute('id');\n if (xlink) {\n idsToXlinkMap[id] = xlink.substr(1);\n }\n gradientDefs[id] = el;\n }\n\n for (id in idsToXlinkMap) {\n var el2 = gradientDefs[idsToXlinkMap[id]].cloneNode(true);\n el = gradientDefs[id];\n while (el2.firstChild) {\n el.appendChild(el2.firstChild);\n }\n }\n return gradientDefs;\n },\n\n /**\n * Returns an object of attributes' name/value, given element and an array of attribute names;\n * Parses parent \"g\" nodes recursively upwards.\n * @static\n * @memberOf fabric\n * @param {DOMElement} element Element to parse\n * @param {Array} attributes Array of attributes to parse\n * @return {Object} object containing parsed attributes' names/values\n */\n parseAttributes: function(element, attributes, svgUid) {\n\n if (!element) {\n return;\n }\n\n var value,\n parentAttributes = { },\n fontSize;\n\n if (typeof svgUid === 'undefined') {\n svgUid = element.getAttribute('svgUid');\n }\n // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n if (element.parentNode && reAllowedParents.test(element.parentNode.nodeName)) {\n parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);\n }\n fontSize = (parentAttributes && parentAttributes.fontSize ) ||\n element.getAttribute('font-size') || fabric.Text.DEFAULT_SVG_FONT_SIZE;\n\n var ownAttributes = attributes.reduce(function(memo, attr) {\n value = element.getAttribute(attr);\n if (value) { // eslint-disable-line\n memo[attr] = value;\n }\n return memo;\n }, { });\n // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n ownAttributes = extend(ownAttributes,\n extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element)));\n\n var normalizedAttr, normalizedValue, normalizedStyle = {};\n for (var attr in ownAttributes) {\n normalizedAttr = normalizeAttr(attr);\n normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n if (normalizedStyle && normalizedStyle.font) {\n fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);\n }\n var mergedAttrs = extend(parentAttributes, normalizedStyle);\n return reAllowedParents.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);\n },\n\n /**\n * Transforms an array of svg elements to corresponding fabric.* instances\n * @static\n * @memberOf fabric\n * @param {Array} elements Array of elements to parse\n * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements)\n * @param {Object} [options] Options object\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n */\n parseElements: function(elements, callback, options, reviver, parsingOptions) {\n new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();\n },\n\n /**\n * Parses \"style\" attribute, retuning an object with values\n * @static\n * @memberOf fabric\n * @param {SVGElement} element Element to parse\n * @return {Object} Objects with values parsed from style attribute of an element\n */\n parseStyleAttribute: function(element) {\n var oStyle = { },\n style = element.getAttribute('style');\n\n if (!style) {\n return oStyle;\n }\n\n if (typeof style === 'string') {\n parseStyleString(style, oStyle);\n }\n else {\n parseStyleObject(style, oStyle);\n }\n\n return oStyle;\n },\n\n /**\n * Parses \"points\" attribute, returning an array of values\n * @static\n * @memberOf fabric\n * @param {String} points points attribute string\n * @return {Array} array of points\n */\n parsePointsAttribute: function(points) {\n\n // points attribute is required and must not be empty\n if (!points) {\n return null;\n }\n\n // replace commas with whitespace and remove bookending whitespace\n points = points.replace(/,/g, ' ').trim();\n\n points = points.split(/\\s+/);\n var parsedPoints = [], i, len;\n\n i = 0;\n len = points.length;\n for (; i < len; i += 2) {\n parsedPoints.push({\n x: parseFloat(points[i]),\n y: parseFloat(points[i + 1])\n });\n }\n\n // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\n\n return parsedPoints;\n },\n\n /**\n * Returns CSS rules for a given SVG document\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} CSS rules of this document\n */\n getCSSRules: function(doc) {\n var styles = doc.getElementsByTagName('style'),\n allRules = { }, rules;\n\n // very crude parsing of style contents\n for (var i = 0, len = styles.length; i < len; i++) {\n // IE9 doesn't support textContent, but provides text instead.\n var styleContents = styles[i].textContent || styles[i].text;\n\n // remove comments\n styleContents = styleContents.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n if (styleContents.trim() === '') {\n continue;\n }\n rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n rules = rules.map(function(rule) { return rule.trim(); });\n rules.forEach(function(rule) {\n\n var match = rule.match(/([\\s\\S]*?)\\s*\\{([^}]*)\\}/),\n ruleObj = { }, declaration = match[2].trim(),\n propertyValuePairs = declaration.replace(/;$/, '').split(/\\s*;\\s*/);\n\n for (var i = 0, len = propertyValuePairs.length; i < len; i++) {\n var pair = propertyValuePairs[i].split(/\\s*:\\s*/),\n property = pair[0],\n value = pair[1];\n ruleObj[property] = value;\n }\n rule = match[1];\n rule.split(',').forEach(function(_rule) {\n _rule = _rule.replace(/^svg/i, '').trim();\n if (_rule === '') {\n return;\n }\n if (allRules[_rule]) {\n fabric.util.object.extend(allRules[_rule], ruleObj);\n }\n else {\n allRules[_rule] = fabric.util.object.clone(ruleObj);\n }\n });\n });\n }\n return allRules;\n },\n\n /**\n * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n * @memberOf fabric\n * @param {String} url\n * @param {Function} callback\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n */\n loadSVGFromURL: function(url, callback, reviver, options) {\n\n url = url.replace(/^\\n\\s*/, '').trim();\n new fabric.util.request(url, {\n method: 'get',\n onComplete: onComplete\n });\n\n function onComplete(r) {\n\n var xml = r.responseXML;\n if (xml && !xml.documentElement && fabric.window.ActiveXObject && r.responseText) {\n xml = new ActiveXObject('Microsoft.XMLDOM');\n xml.async = 'false';\n //IE chokes on DOCTYPE\n xml.loadXML(r.responseText.replace(//i, ''));\n }\n if (!xml || !xml.documentElement) {\n callback && callback(null);\n }\n\n fabric.parseSVGDocument(xml.documentElement, function (results, _options) {\n callback && callback(results, _options);\n }, reviver, options);\n }\n },\n\n /**\n * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n * @memberOf fabric\n * @param {String} string\n * @param {Function} callback\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n */\n loadSVGFromString: function(string, callback, reviver, options) {\n string = string.trim();\n var doc;\n if (typeof DOMParser !== 'undefined') {\n var parser = new DOMParser();\n if (parser && parser.parseFromString) {\n doc = parser.parseFromString(string, 'text/xml');\n }\n }\n else if (fabric.window.ActiveXObject) {\n doc = new ActiveXObject('Microsoft.XMLDOM');\n doc.async = 'false';\n // IE chokes on DOCTYPE\n doc.loadXML(string.replace(//i, ''));\n }\n\n fabric.parseSVGDocument(doc.documentElement, function (results, _options) {\n callback(results, _options);\n }, reviver, options);\n }\n });\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {\n this.elements = elements;\n this.callback = callback;\n this.options = options;\n this.reviver = reviver;\n this.svgUid = (options && options.svgUid) || 0;\n this.parsingOptions = parsingOptions;\n};\n\nfabric.ElementsParser.prototype.parse = function() {\n this.instances = new Array(this.elements.length);\n this.numElements = this.elements.length;\n\n this.createObjects();\n};\n\nfabric.ElementsParser.prototype.createObjects = function() {\n for (var i = 0, len = this.elements.length; i < len; i++) {\n this.elements[i].setAttribute('svgUid', this.svgUid);\n (function(_obj, i) {\n setTimeout(function() {\n _obj.createObject(_obj.elements[i], i);\n }, 0);\n })(this, i);\n }\n};\n\nfabric.ElementsParser.prototype.createObject = function(el, index) {\n var klass = fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))];\n if (klass && klass.fromElement) {\n try {\n this._createObject(klass, el, index);\n }\n catch (err) {\n fabric.log(err);\n }\n }\n else {\n this.checkIfDone();\n }\n};\n\nfabric.ElementsParser.prototype._createObject = function(klass, el, index) {\n if (klass.async) {\n klass.fromElement(el, this.createCallback(index, el), this.options);\n }\n else {\n var obj = klass.fromElement(el, this.options);\n this.resolveGradient(obj, 'fill');\n this.resolveGradient(obj, 'stroke');\n this.reviver && this.reviver(el, obj);\n this.instances[index] = obj;\n this.checkIfDone();\n }\n};\n\nfabric.ElementsParser.prototype.createCallback = function(index, el) {\n var _this = this;\n return function(obj) {\n _this.resolveGradient(obj, 'fill');\n _this.resolveGradient(obj, 'stroke');\n _this.reviver && _this.reviver(el, obj);\n _this.instances[index] = obj;\n _this.checkIfDone();\n };\n};\n\nfabric.ElementsParser.prototype.resolveGradient = function(obj, property) {\n\n var instanceFillValue = obj.get(property);\n if (!(/^url\\(/).test(instanceFillValue)) {\n return;\n }\n var gradientId = instanceFillValue.slice(5, instanceFillValue.length - 1);\n if (fabric.gradientDefs[this.svgUid][gradientId]) {\n obj.set(property,\n fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][gradientId], obj));\n }\n};\n\nfabric.ElementsParser.prototype.checkIfDone = function() {\n if (--this.numElements === 0) {\n this.instances = this.instances.filter(function(el) {\n // eslint-disable-next-line no-eq-null, eqeqeq\n return el != null;\n });\n this.callback(this.instances);\n }\n};\n\n\n(function(global) {\n\n 'use strict';\n\n /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Point) {\n fabric.warn('fabric.Point is already defined');\n return;\n }\n\n fabric.Point = Point;\n\n /**\n * Point class\n * @class fabric.Point\n * @memberOf fabric\n * @constructor\n * @param {Number} x\n * @param {Number} y\n * @return {fabric.Point} thisArg\n */\n function Point(x, y) {\n this.x = x;\n this.y = y;\n }\n\n Point.prototype = /** @lends fabric.Point.prototype */ {\n\n type: 'point',\n\n constructor: Point,\n\n /**\n * Adds another point to this one and returns another one\n * @param {fabric.Point} that\n * @return {fabric.Point} new Point instance with added values\n */\n add: function (that) {\n return new Point(this.x + that.x, this.y + that.y);\n },\n\n /**\n * Adds another point to this one\n * @param {fabric.Point} that\n * @return {fabric.Point} thisArg\n * @chainable\n */\n addEquals: function (that) {\n this.x += that.x;\n this.y += that.y;\n return this;\n },\n\n /**\n * Adds value to this point and returns a new one\n * @param {Number} scalar\n * @return {fabric.Point} new Point with added value\n */\n scalarAdd: function (scalar) {\n return new Point(this.x + scalar, this.y + scalar);\n },\n\n /**\n * Adds value to this point\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n scalarAddEquals: function (scalar) {\n this.x += scalar;\n this.y += scalar;\n return this;\n },\n\n /**\n * Subtracts another point from this point and returns a new one\n * @param {fabric.Point} that\n * @return {fabric.Point} new Point object with subtracted values\n */\n subtract: function (that) {\n return new Point(this.x - that.x, this.y - that.y);\n },\n\n /**\n * Subtracts another point from this point\n * @param {fabric.Point} that\n * @return {fabric.Point} thisArg\n * @chainable\n */\n subtractEquals: function (that) {\n this.x -= that.x;\n this.y -= that.y;\n return this;\n },\n\n /**\n * Subtracts value from this point and returns a new one\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n scalarSubtract: function (scalar) {\n return new Point(this.x - scalar, this.y - scalar);\n },\n\n /**\n * Subtracts value from this point\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n scalarSubtractEquals: function (scalar) {\n this.x -= scalar;\n this.y -= scalar;\n return this;\n },\n\n /**\n * Miltiplies this point by a value and returns a new one\n * TODO: rename in scalarMultiply in 2.0\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n multiply: function (scalar) {\n return new Point(this.x * scalar, this.y * scalar);\n },\n\n /**\n * Miltiplies this point by a value\n * TODO: rename in scalarMultiplyEquals in 2.0\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n multiplyEquals: function (scalar) {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n },\n\n /**\n * Divides this point by a value and returns a new one\n * TODO: rename in scalarDivide in 2.0\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n divide: function (scalar) {\n return new Point(this.x / scalar, this.y / scalar);\n },\n\n /**\n * Divides this point by a value\n * TODO: rename in scalarDivideEquals in 2.0\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n divideEquals: function (scalar) {\n this.x /= scalar;\n this.y /= scalar;\n return this;\n },\n\n /**\n * Returns true if this point is equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n eq: function (that) {\n return (this.x === that.x && this.y === that.y);\n },\n\n /**\n * Returns true if this point is less than another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n lt: function (that) {\n return (this.x < that.x && this.y < that.y);\n },\n\n /**\n * Returns true if this point is less than or equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n lte: function (that) {\n return (this.x <= that.x && this.y <= that.y);\n },\n\n /**\n\n * Returns true if this point is greater another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n gt: function (that) {\n return (this.x > that.x && this.y > that.y);\n },\n\n /**\n * Returns true if this point is greater than or equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n gte: function (that) {\n return (this.x >= that.x && this.y >= that.y);\n },\n\n /**\n * Returns new point which is the result of linear interpolation with this one and another one\n * @param {fabric.Point} that\n * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n * @return {fabric.Point}\n */\n lerp: function (that, t) {\n if (typeof t === 'undefined') {\n t = 0.5;\n }\n t = Math.max(Math.min(1, t), 0);\n return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);\n },\n\n /**\n * Returns distance from this point and another one\n * @param {fabric.Point} that\n * @return {Number}\n */\n distanceFrom: function (that) {\n var dx = this.x - that.x,\n dy = this.y - that.y;\n return Math.sqrt(dx * dx + dy * dy);\n },\n\n /**\n * Returns the point between this point and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n midPointFrom: function (that) {\n return this.lerp(that);\n },\n\n /**\n * Returns a new point which is the min of this and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n min: function (that) {\n return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n },\n\n /**\n * Returns a new point which is the max of this and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n max: function (that) {\n return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n },\n\n /**\n * Returns string representation of this point\n * @return {String}\n */\n toString: function () {\n return this.x + ',' + this.y;\n },\n\n /**\n * Sets x/y of this point\n * @param {Number} x\n * @param {Number} y\n * @chainable\n */\n setXY: function (x, y) {\n this.x = x;\n this.y = y;\n return this;\n },\n\n /**\n * Sets x of this point\n * @param {Number} x\n * @chainable\n */\n setX: function (x) {\n this.x = x;\n return this;\n },\n\n /**\n * Sets y of this point\n * @param {Number} y\n * @chainable\n */\n setY: function (y) {\n this.y = y;\n return this;\n },\n\n /**\n * Sets x/y of this point from another point\n * @param {fabric.Point} that\n * @chainable\n */\n setFromPoint: function (that) {\n this.x = that.x;\n this.y = that.y;\n return this;\n },\n\n /**\n * Swaps x/y of this point and another point\n * @param {fabric.Point} that\n */\n swap: function (that) {\n var x = this.x,\n y = this.y;\n this.x = that.x;\n this.y = that.y;\n that.x = x;\n that.y = y;\n },\n\n /**\n * return a cloned instance of the point\n * @return {fabric.Point}\n */\n clone: function () {\n return new Point(this.x, this.y);\n }\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Intersection) {\n fabric.warn('fabric.Intersection is already defined');\n return;\n }\n\n /**\n * Intersection class\n * @class fabric.Intersection\n * @memberOf fabric\n * @constructor\n */\n function Intersection(status) {\n this.status = status;\n this.points = [];\n }\n\n fabric.Intersection = Intersection;\n\n fabric.Intersection.prototype = /** @lends fabric.Intersection.prototype */ {\n\n constructor: Intersection,\n\n /**\n * Appends a point to intersection\n * @param {fabric.Point} point\n * @return {fabric.Intersection} thisArg\n * @chainable\n */\n appendPoint: function (point) {\n this.points.push(point);\n return this;\n },\n\n /**\n * Appends points to intersection\n * @param {Array} points\n * @return {fabric.Intersection} thisArg\n * @chainable\n */\n appendPoints: function (points) {\n this.points = this.points.concat(points);\n return this;\n }\n };\n\n /**\n * Checks if one line intersects another\n * TODO: rename in intersectSegmentSegment\n * @static\n * @param {fabric.Point} a1\n * @param {fabric.Point} a2\n * @param {fabric.Point} b1\n * @param {fabric.Point} b2\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) {\n var result,\n uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),\n ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),\n uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);\n if (uB !== 0) {\n var ua = uaT / uB,\n ub = ubT / uB;\n if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n result = new Intersection('Intersection');\n result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)));\n }\n else {\n result = new Intersection();\n }\n }\n else {\n if (uaT === 0 || ubT === 0) {\n result = new Intersection('Coincident');\n }\n else {\n result = new Intersection('Parallel');\n }\n }\n return result;\n };\n\n /**\n * Checks if line intersects polygon\n * TODO: rename in intersectSegmentPolygon\n * fix detection of coincident\n * @static\n * @param {fabric.Point} a1\n * @param {fabric.Point} a2\n * @param {Array} points\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectLinePolygon = function(a1, a2, points) {\n var result = new Intersection(),\n length = points.length,\n b1, b2, inter;\n\n for (var i = 0; i < length; i++) {\n b1 = points[i];\n b2 = points[(i + 1) % length];\n inter = Intersection.intersectLineLine(a1, a2, b1, b2);\n\n result.appendPoints(inter.points);\n }\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n return result;\n };\n\n /**\n * Checks if polygon intersects another polygon\n * @static\n * @param {Array} points1\n * @param {Array} points2\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectPolygonPolygon = function (points1, points2) {\n var result = new Intersection(),\n length = points1.length;\n\n for (var i = 0; i < length; i++) {\n var a1 = points1[i],\n a2 = points1[(i + 1) % length],\n inter = Intersection.intersectLinePolygon(a1, a2, points2);\n\n result.appendPoints(inter.points);\n }\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n return result;\n };\n\n /**\n * Checks if polygon intersects rectangle\n * @static\n * @param {Array} points\n * @param {fabric.Point} r1\n * @param {fabric.Point} r2\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) {\n var min = r1.min(r2),\n max = r1.max(r2),\n topRight = new fabric.Point(max.x, min.y),\n bottomLeft = new fabric.Point(min.x, max.y),\n inter1 = Intersection.intersectLinePolygon(min, topRight, points),\n inter2 = Intersection.intersectLinePolygon(topRight, max, points),\n inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points),\n inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points),\n result = new Intersection();\n\n result.appendPoints(inter1.points);\n result.appendPoints(inter2.points);\n result.appendPoints(inter3.points);\n result.appendPoints(inter4.points);\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n return result;\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Color) {\n fabric.warn('fabric.Color is already defined.');\n return;\n }\n\n /**\n * Color class\n * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;\n * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.\n *\n * @class fabric.Color\n * @param {String} color optional in hex or rgb(a) or hsl format or from known color list\n * @return {fabric.Color} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors}\n */\n function Color(color) {\n if (!color) {\n this.setSource([0, 0, 0, 1]);\n }\n else {\n this._tryParsingColor(color);\n }\n }\n\n fabric.Color = Color;\n\n fabric.Color.prototype = /** @lends fabric.Color.prototype */ {\n\n /**\n * @private\n * @param {String|Array} color Color value to parse\n */\n _tryParsingColor: function(color) {\n var source;\n\n if (color in Color.colorNameMap) {\n color = Color.colorNameMap[color];\n }\n\n if (color === 'transparent') {\n source = [255, 255, 255, 0];\n }\n\n if (!source) {\n source = Color.sourceFromHex(color);\n }\n if (!source) {\n source = Color.sourceFromRgb(color);\n }\n if (!source) {\n source = Color.sourceFromHsl(color);\n }\n if (!source) {\n //if color is not recognize let's make black as canvas does\n source = [0, 0, 0, 1];\n }\n if (source) {\n this.setSource(source);\n }\n },\n\n /**\n * Adapted from https://github.com/mjijackson\n * @private\n * @param {Number} r Red color value\n * @param {Number} g Green color value\n * @param {Number} b Blue color value\n * @return {Array} Hsl color\n */\n _rgbToHsl: function(r, g, b) {\n r /= 255; g /= 255; b /= 255;\n\n var h, s, l,\n max = fabric.util.array.max([r, g, b]),\n min = fabric.util.array.min([r, g, b]);\n\n l = (max + min) / 2;\n\n if (max === min) {\n h = s = 0; // achromatic\n }\n else {\n var d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n\n return [\n Math.round(h * 360),\n Math.round(s * 100),\n Math.round(l * 100)\n ];\n },\n\n /**\n * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @return {Array}\n */\n getSource: function() {\n return this._source;\n },\n\n /**\n * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @param {Array} source\n */\n setSource: function(source) {\n this._source = source;\n },\n\n /**\n * Returns color representation in RGB format\n * @return {String} ex: rgb(0-255,0-255,0-255)\n */\n toRgb: function() {\n var source = this.getSource();\n return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')';\n },\n\n /**\n * Returns color representation in RGBA format\n * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n */\n toRgba: function() {\n var source = this.getSource();\n return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')';\n },\n\n /**\n * Returns color representation in HSL format\n * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n */\n toHsl: function() {\n var source = this.getSource(),\n hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)';\n },\n\n /**\n * Returns color representation in HSLA format\n * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n */\n toHsla: function() {\n var source = this.getSource(),\n hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')';\n },\n\n /**\n * Returns color representation in HEX format\n * @return {String} ex: FF5555\n */\n toHex: function() {\n var source = this.getSource(), r, g, b;\n\n r = source[0].toString(16);\n r = (r.length === 1) ? ('0' + r) : r;\n\n g = source[1].toString(16);\n g = (g.length === 1) ? ('0' + g) : g;\n\n b = source[2].toString(16);\n b = (b.length === 1) ? ('0' + b) : b;\n\n return r.toUpperCase() + g.toUpperCase() + b.toUpperCase();\n },\n\n /**\n * Returns color representation in HEXA format\n * @return {String} ex: FF5555CC\n */\n toHexa: function() {\n var source = this.getSource(), a;\n\n a = source[3] * 255;\n a = a.toString(16);\n a = (a.length === 1) ? ('0' + a) : a;\n\n return this.toHex() + a.toUpperCase();\n },\n\n /**\n * Gets value of alpha channel for this color\n * @return {Number} 0-1\n */\n getAlpha: function() {\n return this.getSource()[3];\n },\n\n /**\n * Sets value of alpha channel for this color\n * @param {Number} alpha Alpha value 0-1\n * @return {fabric.Color} thisArg\n */\n setAlpha: function(alpha) {\n var source = this.getSource();\n source[3] = alpha;\n this.setSource(source);\n return this;\n },\n\n /**\n * Transforms color to its grayscale representation\n * @return {fabric.Color} thisArg\n */\n toGrayscale: function() {\n var source = this.getSource(),\n average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10),\n currentAlpha = source[3];\n this.setSource([average, average, average, currentAlpha]);\n return this;\n },\n\n /**\n * Transforms color to its black and white representation\n * @param {Number} threshold\n * @return {fabric.Color} thisArg\n */\n toBlackWhite: function(threshold) {\n var source = this.getSource(),\n average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0),\n currentAlpha = source[3];\n\n threshold = threshold || 127;\n\n average = (Number(average) < Number(threshold)) ? 0 : 255;\n this.setSource([average, average, average, currentAlpha]);\n return this;\n },\n\n /**\n * Overlays color with another color\n * @param {String|fabric.Color} otherColor\n * @return {fabric.Color} thisArg\n */\n overlayWith: function(otherColor) {\n if (!(otherColor instanceof Color)) {\n otherColor = new Color(otherColor);\n }\n\n var result = [],\n alpha = this.getAlpha(),\n otherAlpha = 0.5,\n source = this.getSource(),\n otherSource = otherColor.getSource();\n\n for (var i = 0; i < 3; i++) {\n result.push(Math.round((source[i] * (1 - otherAlpha)) + (otherSource[i] * otherAlpha)));\n }\n\n result[3] = alpha;\n this.setSource(result);\n return this;\n }\n };\n\n /**\n * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))\n * @static\n * @field\n * @memberOf fabric.Color\n */\n // eslint-disable-next-line max-len\n 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*)?\\)$/;\n\n /**\n * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 ))\n * @static\n * @field\n * @memberOf fabric.Color\n */\n fabric.Color.reHSLa = /^hsla?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}\\%)\\s*,\\s*(\\d{1,3}\\%)\\s*(?:\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)$/;\n\n /**\n * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n * @static\n * @field\n * @memberOf fabric.Color\n */\n fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i;\n\n /**\n * Map of the 17 basic color names with HEX code\n * @static\n * @field\n * @memberOf fabric.Color\n * @see: http://www.w3.org/TR/CSS2/syndata.html#color-units\n */\n fabric.Color.colorNameMap = {\n aqua: '#00FFFF',\n black: '#000000',\n blue: '#0000FF',\n fuchsia: '#FF00FF',\n gray: '#808080',\n grey: '#808080',\n green: '#008000',\n lime: '#00FF00',\n maroon: '#800000',\n navy: '#000080',\n olive: '#808000',\n orange: '#FFA500',\n purple: '#800080',\n red: '#FF0000',\n silver: '#C0C0C0',\n teal: '#008080',\n white: '#FFFFFF',\n yellow: '#FFFF00'\n };\n\n /**\n * @private\n * @param {Number} p\n * @param {Number} q\n * @param {Number} t\n * @return {Number}\n */\n function hue2rgb(p, q, t) {\n if (t < 0) {\n t += 1;\n }\n if (t > 1) {\n t -= 1;\n }\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n if (t < 1 / 2) {\n return q;\n }\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n return p;\n }\n\n /**\n * Returns new color object, when given a color in RGB format\n * @memberOf fabric.Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n * @return {fabric.Color}\n */\n fabric.Color.fromRgb = function(color) {\n return Color.fromSource(Color.sourceFromRgb(color));\n };\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n * @memberOf fabric.Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n * @return {Array} source\n */\n fabric.Color.sourceFromRgb = function(color) {\n var match = color.match(Color.reRGBa);\n if (match) {\n var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1),\n g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1),\n b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1);\n\n return [\n parseInt(r, 10),\n parseInt(g, 10),\n parseInt(b, 10),\n match[4] ? parseFloat(match[4]) : 1\n ];\n }\n };\n\n /**\n * Returns new color object, when given a color in RGBA format\n * @static\n * @function\n * @memberOf fabric.Color\n * @param {String} color\n * @return {fabric.Color}\n */\n fabric.Color.fromRgba = Color.fromRgb;\n\n /**\n * Returns new color object, when given a color in HSL format\n * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n * @memberOf fabric.Color\n * @return {fabric.Color}\n */\n fabric.Color.fromHsl = function(color) {\n return Color.fromSource(Color.sourceFromHsl(color));\n };\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n * Adapted from https://github.com/mjijackson\n * @memberOf fabric.Color\n * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n * @return {Array} source\n * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n */\n fabric.Color.sourceFromHsl = function(color) {\n var match = color.match(Color.reHSLa);\n if (!match) {\n return;\n }\n\n var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360,\n s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1),\n l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1),\n r, g, b;\n\n if (s === 0) {\n r = g = b = l;\n }\n else {\n var q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n p = l * 2 - q;\n\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n match[4] ? parseFloat(match[4]) : 1\n ];\n };\n\n /**\n * Returns new color object, when given a color in HSLA format\n * @static\n * @function\n * @memberOf fabric.Color\n * @param {String} color\n * @return {fabric.Color}\n */\n fabric.Color.fromHsla = Color.fromHsl;\n\n /**\n * Returns new color object, when given a color in HEX format\n * @static\n * @memberOf fabric.Color\n * @param {String} color Color value ex: FF5555\n * @return {fabric.Color}\n */\n fabric.Color.fromHex = function(color) {\n return Color.fromSource(Color.sourceFromHex(color));\n };\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n * @static\n * @memberOf fabric.Color\n * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n * @return {Array} source\n */\n fabric.Color.sourceFromHex = function(color) {\n if (color.match(Color.reHex)) {\n var value = color.slice(color.indexOf('#') + 1),\n isShortNotation = (value.length === 3 || value.length === 4),\n isRGBa = (value.length === 8 || value.length === 4),\n r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2),\n g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4),\n b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6),\n a = isRGBa ? (isShortNotation ? (value.charAt(3) + value.charAt(3)) : value.substring(6, 8)) : 'FF';\n\n return [\n parseInt(r, 16),\n parseInt(g, 16),\n parseInt(b, 16),\n parseFloat((parseInt(a, 16) / 255).toFixed(2))\n ];\n }\n };\n\n /**\n * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5])\n * @static\n * @memberOf fabric.Color\n * @param {Array} source\n * @return {fabric.Color}\n */\n fabric.Color.fromSource = function(source) {\n var oColor = new Color();\n oColor.setSource(source);\n return oColor;\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n /* _FROM_SVG_START_ */\n function getColorStop(el) {\n var style = el.getAttribute('style'),\n offset = el.getAttribute('offset') || 0,\n color, colorAlpha, opacity;\n\n // convert percents to absolute values\n offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);\n offset = offset < 0 ? 0 : offset > 1 ? 1 : offset;\n if (style) {\n var keyValuePairs = style.split(/\\s*;\\s*/);\n\n if (keyValuePairs[keyValuePairs.length - 1] === '') {\n keyValuePairs.pop();\n }\n\n for (var i = keyValuePairs.length; i--; ) {\n\n var split = keyValuePairs[i].split(/\\s*:\\s*/),\n key = split[0].trim(),\n value = split[1].trim();\n\n if (key === 'stop-color') {\n color = value;\n }\n else if (key === 'stop-opacity') {\n opacity = value;\n }\n }\n }\n\n if (!color) {\n color = el.getAttribute('stop-color') || 'rgb(0,0,0)';\n }\n if (!opacity) {\n opacity = el.getAttribute('stop-opacity');\n }\n\n color = new fabric.Color(color);\n colorAlpha = color.getAlpha();\n opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);\n opacity *= colorAlpha;\n\n return {\n offset: offset,\n color: color.toRgb(),\n opacity: opacity\n };\n }\n\n function getLinearCoords(el) {\n return {\n x1: el.getAttribute('x1') || 0,\n y1: el.getAttribute('y1') || 0,\n x2: el.getAttribute('x2') || '100%',\n y2: el.getAttribute('y2') || 0\n };\n }\n\n function getRadialCoords(el) {\n return {\n x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',\n y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',\n r1: 0,\n x2: el.getAttribute('cx') || '50%',\n y2: el.getAttribute('cy') || '50%',\n r2: el.getAttribute('r') || '50%'\n };\n }\n /* _FROM_SVG_END_ */\n\n var clone = fabric.util.object.clone;\n\n /**\n * Gradient class\n * @class fabric.Gradient\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n * @see {@link fabric.Gradient#initialize} for constructor definition\n */\n fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {\n\n /**\n * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n offsetX: 0,\n\n /**\n * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n offsetY: 0,\n\n /**\n * Constructor\n * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops\n * @return {fabric.Gradient} thisArg\n */\n initialize: function(options) {\n options || (options = { });\n\n var coords = { };\n\n this.id = fabric.Object.__uid++;\n this.type = options.type || 'linear';\n\n coords = {\n x1: options.coords.x1 || 0,\n y1: options.coords.y1 || 0,\n x2: options.coords.x2 || 0,\n y2: options.coords.y2 || 0\n };\n\n if (this.type === 'radial') {\n coords.r1 = options.coords.r1 || 0;\n coords.r2 = options.coords.r2 || 0;\n }\n this.coords = coords;\n this.colorStops = options.colorStops.slice();\n if (options.gradientTransform) {\n this.gradientTransform = options.gradientTransform;\n }\n this.offsetX = options.offsetX || this.offsetX;\n this.offsetY = options.offsetY || this.offsetY;\n },\n\n /**\n * Adds another colorStop\n * @param {Object} colorStop Object with offset and color\n * @return {fabric.Gradient} thisArg\n */\n addColorStop: function(colorStops) {\n for (var position in colorStops) {\n var color = new fabric.Color(colorStops[position]);\n this.colorStops.push({\n offset: parseFloat(position),\n color: color.toRgb(),\n opacity: color.getAlpha()\n });\n }\n return this;\n },\n\n /**\n * Returns object representation of a gradient\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object}\n */\n toObject: function(propertiesToInclude) {\n var object = {\n type: this.type,\n coords: this.coords,\n colorStops: this.colorStops,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform\n };\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n return object;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an gradient\n * @param {Object} object Object to create a gradient for\n * @return {String} SVG representation of an gradient (linear/radial)\n */\n toSVG: function(object) {\n var coords = clone(this.coords, true),\n markup, commonAttributes, colorStops = clone(this.colorStops, true),\n needsSwap = coords.r1 > coords.r2;\n // colorStops must be sorted ascending\n colorStops.sort(function(a, b) {\n return a.offset - b.offset;\n });\n\n if (!(object.group && object.group.type === 'path-group')) {\n for (var prop in coords) {\n if (prop === 'x1' || prop === 'x2') {\n coords[prop] += this.offsetX - object.width / 2;\n }\n else if (prop === 'y1' || prop === 'y2') {\n coords[prop] += this.offsetY - object.height / 2;\n }\n }\n }\n\n commonAttributes = 'id=\"SVGID_' + this.id +\n '\" gradientUnits=\"userSpaceOnUse\"';\n if (this.gradientTransform) {\n commonAttributes += ' gradientTransform=\"matrix(' + this.gradientTransform.join(' ') + ')\" ';\n }\n if (this.type === 'linear') {\n markup = [\n '\\n'\n ];\n }\n else if (this.type === 'radial') {\n // svg radial gradient has just 1 radius. the biggest.\n markup = [\n '\\n'\n ];\n }\n\n if (this.type === 'radial') {\n if (needsSwap) {\n // svg goes from internal to external radius. if radius are inverted, swap color stops.\n colorStops = colorStops.concat();\n colorStops.reverse();\n for (var i = 0; i < colorStops.length; i++) {\n colorStops[i].offset = 1 - colorStops[i].offset;\n }\n }\n var minRadius = Math.min(coords.r1, coords.r2);\n if (minRadius > 0) {\n // i have to shift all colorStops and add new one in 0.\n var maxRadius = Math.max(coords.r1, coords.r2),\n percentageShift = minRadius / maxRadius;\n for (var i = 0; i < colorStops.length; i++) {\n colorStops[i].offset += percentageShift * (1 - colorStops[i].offset);\n }\n }\n }\n\n for (var i = 0; i < colorStops.length; i++) {\n var colorStop = colorStops[i];\n markup.push(\n '\\n'\n );\n }\n\n markup.push((this.type === 'linear' ? '\\n' : '\\n'));\n\n return markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns an instance of CanvasGradient\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} object\n * @return {CanvasGradient}\n */\n toLive: function(ctx, object) {\n var gradient, prop, coords = fabric.util.object.clone(this.coords);\n\n if (!this.type) {\n return;\n }\n\n if (object.group && object.group.type === 'path-group') {\n for (prop in coords) {\n if (prop === 'x1' || prop === 'x2') {\n coords[prop] += -this.offsetX + object.width / 2;\n }\n else if (prop === 'y1' || prop === 'y2') {\n coords[prop] += -this.offsetY + object.height / 2;\n }\n }\n }\n\n if (this.type === 'linear') {\n gradient = ctx.createLinearGradient(\n coords.x1, coords.y1, coords.x2, coords.y2);\n }\n else if (this.type === 'radial') {\n gradient = ctx.createRadialGradient(\n coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);\n }\n\n for (var i = 0, len = this.colorStops.length; i < len; i++) {\n var color = this.colorStops[i].color,\n opacity = this.colorStops[i].opacity,\n offset = this.colorStops[i].offset;\n\n if (typeof opacity !== 'undefined') {\n color = new fabric.Color(color).setAlpha(opacity).toRgba();\n }\n gradient.addColorStop(offset, color);\n }\n\n return gradient;\n }\n });\n\n fabric.util.object.extend(fabric.Gradient, {\n\n /* _FROM_SVG_START_ */\n /**\n * Returns {@link fabric.Gradient} instance from an SVG element\n * @static\n * @memberOf fabric.Gradient\n * @param {SVGGradientElement} el SVG gradient element\n * @param {fabric.Object} instance\n * @return {fabric.Gradient} Gradient instance\n * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n */\n fromElement: function(el, instance) {\n\n /**\n * @example:\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n */\n\n var colorStopEls = el.getElementsByTagName('stop'),\n type,\n gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',\n gradientTransform = el.getAttribute('gradientTransform'),\n colorStops = [],\n coords, ellipseMatrix;\n\n if (el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT') {\n type = 'linear';\n }\n else {\n type = 'radial';\n }\n\n if (type === 'linear') {\n coords = getLinearCoords(el);\n }\n else if (type === 'radial') {\n coords = getRadialCoords(el);\n }\n\n for (var i = colorStopEls.length; i--; ) {\n colorStops.push(getColorStop(colorStopEls[i]));\n }\n\n ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits);\n\n var gradient = new fabric.Gradient({\n type: type,\n coords: coords,\n colorStops: colorStops,\n offsetX: -instance.left,\n offsetY: -instance.top\n });\n\n if (gradientTransform || ellipseMatrix !== '') {\n gradient.gradientTransform = fabric.parseTransformAttribute((gradientTransform || '') + ellipseMatrix);\n }\n return gradient;\n },\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Gradient} instance from its object representation\n * @static\n * @memberOf fabric.Gradient\n * @param {Object} obj\n * @param {Object} [options] Options object\n */\n forObject: function(obj, options) {\n options || (options = { });\n _convertPercentUnitsToValues(obj, options.coords, 'userSpaceOnUse');\n return new fabric.Gradient(options);\n }\n });\n\n /**\n * @private\n */\n function _convertPercentUnitsToValues(object, options, gradientUnits) {\n var propValue, addFactor = 0, multFactor = 1, ellipseMatrix = '';\n for (var prop in options) {\n if (options[prop] === 'Infinity') {\n options[prop] = 1;\n }\n else if (options[prop] === '-Infinity') {\n options[prop] = 0;\n }\n propValue = parseFloat(options[prop], 10);\n if (typeof options[prop] === 'string' && /^\\d+%$/.test(options[prop])) {\n multFactor = 0.01;\n }\n else {\n multFactor = 1;\n }\n if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n multFactor *= gradientUnits === 'objectBoundingBox' ? object.width : 1;\n addFactor = gradientUnits === 'objectBoundingBox' ? object.left || 0 : 0;\n }\n else if (prop === 'y1' || prop === 'y2') {\n multFactor *= gradientUnits === 'objectBoundingBox' ? object.height : 1;\n addFactor = gradientUnits === 'objectBoundingBox' ? object.top || 0 : 0;\n }\n options[prop] = propValue * multFactor + addFactor;\n }\n if (object.type === 'ellipse' &&\n options.r2 !== null &&\n gradientUnits === 'objectBoundingBox' &&\n object.rx !== object.ry) {\n\n var scaleFactor = object.ry / object.rx;\n ellipseMatrix = ' scale(1, ' + scaleFactor + ')';\n if (options.y1) {\n options.y1 /= scaleFactor;\n }\n if (options.y2) {\n options.y2 /= scaleFactor;\n }\n }\n return ellipseMatrix;\n }\n})();\n\n\n(function() {\n\n 'use strict';\n\n var toFixed = fabric.util.toFixed;\n\n /**\n * Pattern class\n * @class fabric.Pattern\n * @see {@link http://fabricjs.com/patterns|Pattern demo}\n * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo}\n * @see {@link fabric.Pattern#initialize} for constructor definition\n */\n\n\n fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ {\n\n /**\n * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n * @type String\n * @default\n */\n repeat: 'repeat',\n\n /**\n * Pattern horizontal offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetX: 0,\n\n /**\n * Pattern vertical offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetY: 0,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @param {Function} [callback] function to invoke after callback init.\n * @return {fabric.Pattern} thisArg\n */\n initialize: function(options, callback) {\n options || (options = { });\n\n this.id = fabric.Object.__uid++;\n this.setOptions(options);\n if (!options.source || (options.source && typeof options.source !== 'string')) {\n callback && callback(this);\n return;\n }\n // function string\n if (typeof fabric.util.getFunctionBody(options.source) !== 'undefined') {\n this.source = new Function(fabric.util.getFunctionBody(options.source));\n callback && callback(this);\n }\n else {\n // img src string\n var _this = this;\n this.source = fabric.util.createImage();\n fabric.util.loadImage(options.source, function(img) {\n _this.source = img;\n callback && callback(_this);\n });\n }\n },\n\n /**\n * Returns object representation of a pattern\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of a pattern instance\n */\n toObject: function(propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n source, object;\n\n // callback\n if (typeof this.source === 'function') {\n source = String(this.source);\n }\n // element\n else if (typeof this.source.src === 'string') {\n source = this.source.src;\n }\n // element\n else if (typeof this.source === 'object' && this.source.toDataURL) {\n source = this.source.toDataURL();\n }\n\n object = {\n type: 'pattern',\n source: source,\n repeat: this.repeat,\n offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS),\n offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS),\n };\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n return object;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a pattern\n * @param {fabric.Object} object\n * @return {String} SVG representation of a pattern\n */\n toSVG: function(object) {\n var patternSource = typeof this.source === 'function' ? this.source() : this.source,\n patternWidth = patternSource.width / object.width,\n patternHeight = patternSource.height / object.height,\n patternOffsetX = this.offsetX / object.width,\n patternOffsetY = this.offsetY / object.height,\n patternImgSrc = '';\n if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') {\n patternHeight = 1;\n }\n if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') {\n patternWidth = 1;\n }\n if (patternSource.src) {\n patternImgSrc = patternSource.src;\n }\n else if (patternSource.toDataURL) {\n patternImgSrc = patternSource.toDataURL();\n }\n\n return '\\n' +\n '\\n' +\n '\\n';\n },\n /* _TO_SVG_END_ */\n\n setOptions: function(options) {\n for (var prop in options) {\n this[prop] = options[prop];\n }\n },\n\n /**\n * Returns an instance of CanvasPattern\n * @param {CanvasRenderingContext2D} ctx Context to create pattern\n * @return {CanvasPattern}\n */\n toLive: function(ctx) {\n var source = typeof this.source === 'function' ? this.source() : this.source;\n\n // if the image failed to load, return, and allow rest to continue loading\n if (!source) {\n return '';\n }\n\n // if an image\n if (typeof source.src !== 'undefined') {\n if (!source.complete) {\n return '';\n }\n if (source.naturalWidth === 0 || source.naturalHeight === 0) {\n return '';\n }\n }\n return ctx.createPattern(source, this.repeat);\n }\n });\n})();\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n toFixed = fabric.util.toFixed;\n\n if (fabric.Shadow) {\n fabric.warn('fabric.Shadow is already defined.');\n return;\n }\n\n /**\n * Shadow class\n * @class fabric.Shadow\n * @see {@link http://fabricjs.com/shadows|Shadow demo}\n * @see {@link fabric.Shadow#initialize} for constructor definition\n */\n fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ {\n\n /**\n * Shadow color\n * @type String\n * @default\n */\n color: 'rgb(0,0,0)',\n\n /**\n * Shadow blur\n * @type Number\n */\n blur: 0,\n\n /**\n * Shadow horizontal offset\n * @type Number\n * @default\n */\n offsetX: 0,\n\n /**\n * Shadow vertical offset\n * @type Number\n * @default\n */\n offsetY: 0,\n\n /**\n * Whether the shadow should affect stroke operations\n * @type Boolean\n * @default\n */\n affectStroke: false,\n\n /**\n * Indicates whether toObject should include default values\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * Constructor\n * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetX properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px, \"2px 2px 10px rgba(0,0,0,0.2)\")\n * @return {fabric.Shadow} thisArg\n */\n initialize: function(options) {\n\n if (typeof options === 'string') {\n options = this._parseShadow(options);\n }\n\n for (var prop in options) {\n this[prop] = options[prop];\n }\n\n this.id = fabric.Object.__uid++;\n },\n\n /**\n * @private\n * @param {String} shadow Shadow value to parse\n * @return {Object} Shadow object with color, offsetX, offsetY and blur\n */\n _parseShadow: function(shadow) {\n var shadowStr = shadow.trim(),\n offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [],\n color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)';\n\n return {\n color: color.trim(),\n offsetX: parseInt(offsetsAndBlur[1], 10) || 0,\n offsetY: parseInt(offsetsAndBlur[2], 10) || 0,\n blur: parseInt(offsetsAndBlur[3], 10) || 0\n };\n },\n\n /**\n * Returns a string representation of an instance\n * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n * @return {String} Returns CSS3 text-shadow declaration\n */\n toString: function() {\n return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a shadow\n * @param {fabric.Object} object\n * @return {String} SVG representation of a shadow\n */\n toSVG: function(object) {\n var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n offset = fabric.util.rotateVector(\n { x: this.offsetX, y: this.offsetY },\n fabric.util.degreesToRadians(-object.angle)),\n BLUR_BOX = 20;\n\n if (object.width && object.height) {\n //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n // we add some extra space to filter box to contain the blur ( 20 )\n fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n }\n if (object.flipX) {\n offset.x *= -1;\n }\n if (object.flipY) {\n offset.y *= -1;\n }\n return (\n '\\n' +\n '\\t\\n' +\n '\\t\\n' +\n '\\t\\n' +\n '\\t\\n' +\n '\\t\\n' +\n '\\t\\t\\n' +\n '\\t\\t\\n' +\n '\\t\\n' +\n '\\n');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns object representation of a shadow\n * @return {Object} Object representation of a shadow instance\n */\n toObject: function() {\n if (this.includeDefaultValues) {\n return {\n color: this.color,\n blur: this.blur,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n affectStroke: this.affectStroke\n };\n }\n var obj = { }, proto = fabric.Shadow.prototype;\n\n ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke'].forEach(function(prop) {\n if (this[prop] !== proto[prop]) {\n obj[prop] = this[prop];\n }\n }, this);\n\n return obj;\n }\n });\n\n /**\n * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n * @static\n * @field\n * @memberOf fabric.Shadow\n */\n // eslint-disable-next-line max-len\n fabric.Shadow.reOffsetsAndBlur = /(?:\\s|^)(-?\\d+(?:px)?(?:\\s?|$))?(-?\\d+(?:px)?(?:\\s?|$))?(\\d+(?:px)?)?(?:\\s?|$)(?:$|\\s)/;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function () {\n\n 'use strict';\n\n if (fabric.StaticCanvas) {\n fabric.warn('fabric.StaticCanvas is already defined.');\n return;\n }\n\n // aliases for faster resolution\n var extend = fabric.util.object.extend,\n getElementOffset = fabric.util.getElementOffset,\n removeFromArray = fabric.util.removeFromArray,\n toFixed = fabric.util.toFixed,\n transformPoint = fabric.util.transformPoint,\n invertTransform = fabric.util.invertTransform,\n\n CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element');\n\n /**\n * Static canvas class\n * @class fabric.StaticCanvas\n * @mixes fabric.Collection\n * @mixes fabric.Observable\n * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n * @see {@link fabric.StaticCanvas#initialize} for constructor definition\n * @fires before:render\n * @fires after:render\n * @fires canvas:cleared\n * @fires object:added\n * @fires object:removed\n */\n fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(el, options) {\n options || (options = { });\n\n this._initStatic(el, options);\n },\n\n /**\n * Background color of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}.\n * @type {(String|fabric.Pattern)}\n * @default\n */\n backgroundColor: '',\n\n /**\n * Background image of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setBackgroundImage}.\n * Backwards incompatibility note: The \"backgroundImageOpacity\"\n * and \"backgroundImageStretch\" properties are deprecated since 1.3.9.\n * Use {@link fabric.Image#opacity}, {@link fabric.Image#width} and {@link fabric.Image#height}.\n * @type fabric.Image\n * @default\n */\n backgroundImage: null,\n\n /**\n * Overlay color of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setOverlayColor}\n * @since 1.3.9\n * @type {(String|fabric.Pattern)}\n * @default\n */\n overlayColor: '',\n\n /**\n * Overlay image of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setOverlayImage}.\n * Backwards incompatibility note: The \"overlayImageLeft\"\n * and \"overlayImageTop\" properties are deprecated since 1.3.9.\n * Use {@link fabric.Image#left} and {@link fabric.Image#top}.\n * @type fabric.Image\n * @default\n */\n overlayImage: null,\n\n /**\n * Indicates whether toObject/toDatalessObject should include default values\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * Indicates whether objects' state should be saved\n * @type Boolean\n * @default\n */\n stateful: false,\n\n /**\n * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove} should also re-render canvas.\n * Disabling this option could give a great performance boost when adding/removing a lot of objects to/from canvas at once\n * (followed by a manual rendering after addition/deletion)\n * @type Boolean\n * @default\n */\n renderOnAddRemove: true,\n\n /**\n * Function that determines clipping of entire canvas area\n * Being passed context as first argument. See clipping canvas area in {@link https://github.com/kangax/fabric.js/wiki/FAQ}\n * @type Function\n * @default\n */\n clipTo: null,\n\n /**\n * Indicates whether object controls (borders/controls) are rendered above overlay image\n * @type Boolean\n * @default\n */\n controlsAboveOverlay: false,\n\n /**\n * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n * @type Boolean\n * @default\n */\n allowTouchScrolling: false,\n\n /**\n * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n * @type Boolean\n * @default\n */\n imageSmoothingEnabled: true,\n\n /**\n * The transformation (in the format of Canvas transform) which focuses the viewport\n * @type Array\n * @default\n */\n viewportTransform: fabric.iMatrix.concat(),\n\n /**\n * if set to false background image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n backgroundVpt: true,\n\n /**\n * if set to false overlya image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n overlayVpt: true,\n\n /**\n * Callback; invoked right before object is about to be scaled/rotated\n */\n onBeforeScaleRotate: function () {\n /* NOOP */\n },\n\n /**\n * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n */\n enableRetinaScaling: true,\n\n /**\n * Describe canvas element extension over design\n * properties are tl,tr,bl,br.\n * if canvas is not zoomed/panned those points are the four corner of canvas\n * if canvas is viewportTransformed you those points indicate the extension\n * of canvas element in plain untrasformed coordinates\n * The coordinates get updated with @method calcViewportBoundaries.\n * @memberOf fabric.StaticCanvas.prototype\n */\n vptCoords: { },\n\n /**\n * Based on vptCoords and object.aCoords, skip rendering of objects that\n * are not included in current viewport.\n * May greatly help in applications with crowded canvas and use of zoom/pan\n * If One of the corner of the bounding box of the object is on the canvas\n * the objects get rendered.\n * @memberOf fabric.StaticCanvas.prototype\n */\n skipOffscreen: false,\n\n /**\n * @private\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n */\n _initStatic: function(el, options) {\n var cb = fabric.StaticCanvas.prototype.renderAll.bind(this);\n this._objects = [];\n this._createLowerCanvas(el);\n this._initOptions(options);\n this._setImageSmoothing();\n // only initialize retina scaling once\n if (!this.interactive) {\n this._initRetinaScaling();\n }\n\n if (options.overlayImage) {\n this.setOverlayImage(options.overlayImage, cb);\n }\n if (options.backgroundImage) {\n this.setBackgroundImage(options.backgroundImage, cb);\n }\n if (options.backgroundColor) {\n this.setBackgroundColor(options.backgroundColor, cb);\n }\n if (options.overlayColor) {\n this.setOverlayColor(options.overlayColor, cb);\n }\n this.calcOffset();\n },\n\n /**\n * @private\n */\n _isRetinaScaling: function() {\n return (fabric.devicePixelRatio !== 1 && this.enableRetinaScaling);\n },\n\n /**\n * @private\n * @return {Number} retinaScaling if applied, otherwise 1;\n */\n getRetinaScaling: function() {\n return this._isRetinaScaling() ? fabric.devicePixelRatio : 1;\n },\n\n /**\n * @private\n */\n _initRetinaScaling: function() {\n if (!this._isRetinaScaling()) {\n return;\n }\n this.lowerCanvasEl.setAttribute('width', this.width * fabric.devicePixelRatio);\n this.lowerCanvasEl.setAttribute('height', this.height * fabric.devicePixelRatio);\n\n this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio);\n },\n\n /**\n * Calculates canvas element offset relative to the document\n * This method is also attached as \"resize\" event handler of window\n * @return {fabric.Canvas} instance\n * @chainable\n */\n calcOffset: function () {\n this._offset = getElementOffset(this.lowerCanvasEl);\n return this;\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas\n * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to\n * @param {Function} callback callback to invoke when image is loaded and set as an overlay\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}.\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo}\n * @example Normal overlayImage with left/top = 0\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * // Needed to position overlayImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example overlayImage with different properties\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top'\n * });\n * @example Stretched overlayImage #1 - width/height correspond to canvas width/height\n * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img) {\n * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n * canvas.setOverlayImage(img, canvas.renderAll.bind(canvas));\n * });\n * @example Stretched overlayImage #2 - width/height correspond to canvas width/height\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * width: canvas.width,\n * height: canvas.height,\n * // Needed to position overlayImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example overlayImage loaded from cross-origin\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top',\n * crossOrigin: 'anonymous'\n * });\n */\n setOverlayImage: function (image, callback, options) {\n return this.__setBgOverlayImage('overlayImage', image, callback, options);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas\n * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to\n * @param {Function} callback Callback to invoke when image is loaded and set as background\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}.\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/YH9yD/|jsFiddle demo}\n * @example Normal backgroundImage with left/top = 0\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * // Needed to position backgroundImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example backgroundImage with different properties\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top'\n * });\n * @example Stretched backgroundImage #1 - width/height correspond to canvas width/height\n * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img) {\n * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n * canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));\n * });\n * @example Stretched backgroundImage #2 - width/height correspond to canvas width/height\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * width: canvas.width,\n * height: canvas.height,\n * // Needed to position backgroundImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example backgroundImage loaded from cross-origin\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top',\n * crossOrigin: 'anonymous'\n * });\n */\n setBackgroundImage: function (image, callback, options) {\n return this.__setBgOverlayImage('backgroundImage', image, callback, options);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#overlayColor|background color} for this canvas\n * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set background color to\n * @param {Function} callback Callback to invoke when background color is set\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo}\n * @example Normal overlayColor - color value\n * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n * @example fabric.Pattern used as overlayColor\n * canvas.setOverlayColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png'\n * }, canvas.renderAll.bind(canvas));\n * @example fabric.Pattern used as overlayColor with repeat and offset\n * canvas.setOverlayColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png',\n * repeat: 'repeat',\n * offsetX: 200,\n * offsetY: 100\n * }, canvas.renderAll.bind(canvas));\n */\n setOverlayColor: function(overlayColor, callback) {\n return this.__setBgOverlayColor('overlayColor', overlayColor, callback);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas\n * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to\n * @param {Function} callback Callback to invoke when background color is set\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo}\n * @example Normal backgroundColor - color value\n * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n * @example fabric.Pattern used as backgroundColor\n * canvas.setBackgroundColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png'\n * }, canvas.renderAll.bind(canvas));\n * @example fabric.Pattern used as backgroundColor with repeat and offset\n * canvas.setBackgroundColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png',\n * repeat: 'repeat',\n * offsetX: 200,\n * offsetY: 100\n * }, canvas.renderAll.bind(canvas));\n */\n setBackgroundColor: function(backgroundColor, callback) {\n return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback);\n },\n\n /**\n * @private\n * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-imagesmoothingenabled|WhatWG Canvas Standard}\n */\n _setImageSmoothing: function() {\n var ctx = this.getContext();\n\n ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled\n || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;\n ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;\n },\n\n /**\n * @private\n * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage}\n * or {@link fabric.StaticCanvas#overlayImage|overlayImage})\n * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to\n * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}.\n */\n __setBgOverlayImage: function(property, image, callback, options) {\n if (typeof image === 'string') {\n fabric.util.loadImage(image, function(img) {\n img && (this[property] = new fabric.Image(img, options));\n callback && callback(img);\n }, this, options && options.crossOrigin);\n }\n else {\n options && image.setOptions(options);\n this[property] = image;\n callback && callback(image);\n }\n\n return this;\n },\n\n /**\n * @private\n * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor}\n * or {@link fabric.StaticCanvas#overlayColor|overlayColor})\n * @param {(Object|String|null)} color Object with pattern information, color value or null\n * @param {Function} [callback] Callback is invoked when color is set\n */\n __setBgOverlayColor: function(property, color, callback) {\n this[property] = color;\n this._initGradient(color, property);\n this._initPattern(color, property, callback);\n return this;\n },\n\n /**\n * @private\n */\n _createCanvasElement: function(canvasEl) {\n var element = fabric.util.createCanvasElement(canvasEl);\n if (!element.style) {\n element.style = { };\n }\n if (!element) {\n throw CANVAS_INIT_ERROR;\n }\n if (typeof element.getContext === 'undefined') {\n throw CANVAS_INIT_ERROR;\n }\n return element;\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initOptions: function (options) {\n this._setOptions(options);\n\n this.width = this.width || parseInt(this.lowerCanvasEl.width, 10) || 0;\n this.height = this.height || parseInt(this.lowerCanvasEl.height, 10) || 0;\n\n if (!this.lowerCanvasEl.style) {\n return;\n }\n\n this.lowerCanvasEl.width = this.width;\n this.lowerCanvasEl.height = this.height;\n\n this.lowerCanvasEl.style.width = this.width + 'px';\n this.lowerCanvasEl.style.height = this.height + 'px';\n\n this.viewportTransform = this.viewportTransform.slice();\n },\n\n /**\n * Creates a bottom canvas\n * @private\n * @param {HTMLElement} [canvasEl]\n */\n _createLowerCanvas: function (canvasEl) {\n this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(canvasEl);\n\n fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas');\n\n if (this.interactive) {\n this._applyCanvasStyle(this.lowerCanvasEl);\n }\n\n this.contextContainer = this.lowerCanvasEl.getContext('2d');\n },\n\n /**\n * Returns canvas width (in px)\n * @return {Number}\n */\n getWidth: function () {\n return this.width;\n },\n\n /**\n * Returns canvas height (in px)\n * @return {Number}\n */\n getHeight: function () {\n return this.height;\n },\n\n /**\n * Sets width of this canvas instance\n * @param {Number|String} value Value to set width to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setWidth: function (value, options) {\n return this.setDimensions({ width: value }, options);\n },\n\n /**\n * Sets height of this canvas instance\n * @param {Number|String} value Value to set height to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setHeight: function (value, options) {\n return this.setDimensions({ height: value }, options);\n },\n\n /**\n * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n * @param {Object} dimensions Object with width/height properties\n * @param {Number|String} [dimensions.width] Width of canvas element\n * @param {Number|String} [dimensions.height] Height of canvas element\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setDimensions: function (dimensions, options) {\n var cssValue;\n\n options = options || {};\n\n for (var prop in dimensions) {\n cssValue = dimensions[prop];\n\n if (!options.cssOnly) {\n this._setBackstoreDimension(prop, dimensions[prop]);\n cssValue += 'px';\n }\n\n if (!options.backstoreOnly) {\n this._setCssDimension(prop, cssValue);\n }\n }\n this._initRetinaScaling();\n this._setImageSmoothing();\n this.calcOffset();\n\n if (!options.cssOnly) {\n this.renderAll();\n }\n\n return this;\n },\n\n /**\n * Helper for setting width/height\n * @private\n * @param {String} prop property (width|height)\n * @param {Number} value value to set property to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n _setBackstoreDimension: function (prop, value) {\n this.lowerCanvasEl[prop] = value;\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl[prop] = value;\n }\n\n if (this.cacheCanvasEl) {\n this.cacheCanvasEl[prop] = value;\n }\n\n this[prop] = value;\n\n return this;\n },\n\n /**\n * Helper for setting css width/height\n * @private\n * @param {String} prop property (width|height)\n * @param {String} value value to set property to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n _setCssDimension: function (prop, value) {\n this.lowerCanvasEl.style[prop] = value;\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl.style[prop] = value;\n }\n\n if (this.wrapperEl) {\n this.wrapperEl.style[prop] = value;\n }\n\n return this;\n },\n\n /**\n * Returns canvas zoom level\n * @return {Number}\n */\n getZoom: function () {\n return this.viewportTransform[0];\n },\n\n /**\n * Sets viewport transform of this canvas instance\n * @param {Array} vpt the transform in the form of context.transform\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setViewportTransform: function (vpt) {\n var activeGroup = this._activeGroup, object, ignoreVpt = false, skipAbsolute = true;\n this.viewportTransform = vpt;\n for (var i = 0, len = this._objects.length; i < len; i++) {\n object = this._objects[i];\n object.group || object.setCoords(ignoreVpt, skipAbsolute);\n }\n if (activeGroup) {\n activeGroup.setCoords(ignoreVpt, skipAbsolute);\n }\n this.calcViewportBoundaries();\n this.renderAll();\n return this;\n },\n\n /**\n * Sets zoom level of this canvas instance, zoom centered around point\n * @param {fabric.Point} point to zoom with respect to\n * @param {Number} value to set zoom to, less than 1 zooms out\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n zoomToPoint: function (point, value) {\n // TODO: just change the scale, preserve other transformations\n var before = point, vpt = this.viewportTransform.slice(0);\n point = transformPoint(point, invertTransform(this.viewportTransform));\n vpt[0] = value;\n vpt[3] = value;\n var after = transformPoint(point, vpt);\n vpt[4] += before.x - after.x;\n vpt[5] += before.y - after.y;\n return this.setViewportTransform(vpt);\n },\n\n /**\n * Sets zoom level of this canvas instance\n * @param {Number} value to set zoom to, less than 1 zooms out\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setZoom: function (value) {\n this.zoomToPoint(new fabric.Point(0, 0), value);\n return this;\n },\n\n /**\n * Pan viewport so as to place point at top left corner of canvas\n * @param {fabric.Point} point to move to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n absolutePan: function (point) {\n var vpt = this.viewportTransform.slice(0);\n vpt[4] = -point.x;\n vpt[5] = -point.y;\n return this.setViewportTransform(vpt);\n },\n\n /**\n * Pans viewpoint relatively\n * @param {fabric.Point} point (position vector) to move by\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n relativePan: function (point) {\n return this.absolutePan(new fabric.Point(\n -point.x - this.viewportTransform[4],\n -point.y - this.viewportTransform[5]\n ));\n },\n\n /**\n * Returns <canvas> element corresponding to this instance\n * @return {HTMLCanvasElement}\n */\n getElement: function () {\n return this.lowerCanvasEl;\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was added\n */\n _onObjectAdded: function(obj) {\n this.stateful && obj.setupState();\n obj._set('canvas', this);\n obj.setCoords();\n this.fire('object:added', { target: obj });\n obj.fire('added');\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function(obj) {\n this.fire('object:removed', { target: obj });\n obj.fire('removed');\n delete obj.canvas;\n },\n\n /**\n * Clears specified context of canvas element\n * @param {CanvasRenderingContext2D} ctx Context to clear\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clearContext: function(ctx) {\n ctx.clearRect(0, 0, this.width, this.height);\n return this;\n },\n\n /**\n * Returns context of canvas where objects are drawn\n * @return {CanvasRenderingContext2D}\n */\n getContext: function () {\n return this.contextContainer;\n },\n\n /**\n * Clears all contexts (background, main, top) of an instance\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clear: function () {\n this._objects.length = 0;\n this.backgroundImage = null;\n this.overlayImage = null;\n this.backgroundColor = '';\n this.overlayColor = '';\n if (this._hasITextHandlers) {\n this.off('mouse:up', this._mouseUpITextHandler);\n this._iTextInstances = null;\n this._hasITextHandlers = false;\n }\n this.clearContext(this.contextContainer);\n this.fire('canvas:cleared');\n this.renderAll();\n return this;\n },\n\n /**\n * Renders the canvas\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAll: function () {\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._objects);\n return this;\n },\n\n /**\n * Calculate the position of the 4 corner of canvas with current viewportTransform.\n * helps to determinate when an object is in the current rendering viewport using\n * object absolute coordinates ( aCoords )\n * @return {Object} points.tl\n * @chainable\n */\n calcViewportBoundaries: function() {\n var points = { }, width = this.getWidth(), height = this.getHeight(),\n iVpt = invertTransform(this.viewportTransform);\n points.tl = transformPoint({ x: 0, y: 0 }, iVpt);\n points.br = transformPoint({ x: width, y: height }, iVpt);\n points.tr = new fabric.Point(points.br.x, points.tl.y);\n points.bl = new fabric.Point(points.tl.x, points.br.y);\n this.vptCoords = points;\n return points;\n },\n\n /**\n * Renders background, objects, overlay and controls.\n * @param {CanvasRenderingContext2D} ctx\n * @param {Array} objects to render\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderCanvas: function(ctx, objects) {\n this.calcViewportBoundaries();\n this.clearContext(ctx);\n this.fire('before:render');\n if (this.clipTo) {\n fabric.util.clipContext(this, ctx);\n }\n this._renderBackground(ctx);\n\n ctx.save();\n //apply viewport transform once for all rendering process\n ctx.transform.apply(ctx, this.viewportTransform);\n this._renderObjects(ctx, objects);\n ctx.restore();\n if (!this.controlsAboveOverlay && this.interactive) {\n this.drawControls(ctx);\n }\n if (this.clipTo) {\n ctx.restore();\n }\n this._renderOverlay(ctx);\n if (this.controlsAboveOverlay && this.interactive) {\n this.drawControls(ctx);\n }\n this.fire('after:render');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} objects to render\n */\n _renderObjects: function(ctx, objects) {\n for (var i = 0, length = objects.length; i < length; ++i) {\n objects[i] && objects[i].render(ctx);\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {string} property 'background' or 'overlay'\n */\n _renderBackgroundOrOverlay: function(ctx, property) {\n var object = this[property + 'Color'];\n if (object) {\n ctx.fillStyle = object.toLive\n ? object.toLive(ctx, this)\n : object;\n\n ctx.fillRect(\n object.offsetX || 0,\n object.offsetY || 0,\n this.width,\n this.height);\n }\n object = this[property + 'Image'];\n if (object) {\n if (this[property + 'Vpt']) {\n ctx.save();\n ctx.transform.apply(ctx, this.viewportTransform);\n }\n object.render(ctx);\n this[property + 'Vpt'] && ctx.restore();\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground: function(ctx) {\n this._renderBackgroundOrOverlay(ctx, 'background');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderOverlay: function(ctx) {\n this._renderBackgroundOrOverlay(ctx, 'overlay');\n },\n\n /**\n * Returns coordinates of a center of canvas.\n * Returned value is an object with top and left properties\n * @return {Object} object with \"top\" and \"left\" number values\n */\n getCenter: function () {\n return {\n top: this.getHeight() / 2,\n left: this.getWidth() / 2\n };\n },\n\n /**\n * Centers object horizontally in the canvas\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center horizontally\n * @return {fabric.Canvas} thisArg\n */\n centerObjectH: function (object) {\n return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y));\n },\n\n /**\n * Centers object vertically in the canvas\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n centerObjectV: function (object) {\n return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top));\n },\n\n /**\n * Centers object vertically and horizontally in the canvas\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n centerObject: function(object) {\n var center = this.getCenter();\n\n return this._centerObject(object, new fabric.Point(center.left, center.top));\n },\n\n /**\n * Centers object vertically and horizontally in the viewport\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObject: function(object) {\n var vpCenter = this.getVpCenter();\n\n return this._centerObject(object, vpCenter);\n },\n\n /**\n * Centers object horizontally in the viewport, object.top is unchanged\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObjectH: function(object) {\n var vpCenter = this.getVpCenter();\n this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y));\n return this;\n },\n\n /**\n * Centers object Vertically in the viewport, object.top is unchanged\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObjectV: function(object) {\n var vpCenter = this.getVpCenter();\n\n return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y));\n },\n\n /**\n * Calculate the point in canvas that correspond to the center of actual viewport.\n * @return {fabric.Point} vpCenter, viewport center\n * @chainable\n */\n getVpCenter: function() {\n var center = this.getCenter(),\n iVpt = invertTransform(this.viewportTransform);\n return transformPoint({ x: center.left, y: center.top }, iVpt);\n },\n\n /**\n * @private\n * @param {fabric.Object} object Object to center\n * @param {fabric.Point} center Center point\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n _centerObject: function(object, center) {\n object.setPositionByOrigin(center, 'center', 'center');\n this.renderAll();\n return this;\n },\n\n /**\n * Returs dataless JSON representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} json string\n */\n toDatalessJSON: function (propertiesToInclude) {\n return this.toDatalessObject(propertiesToInclude);\n },\n\n /**\n * Returns object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return this._toObjectMethod('toObject', propertiesToInclude);\n },\n\n /**\n * Returns dataless object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function (propertiesToInclude) {\n return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n },\n\n /**\n * @private\n */\n _toObjectMethod: function (methodName, propertiesToInclude) {\n\n var data = {\n objects: this._toObjects(methodName, propertiesToInclude)\n };\n\n extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));\n\n fabric.util.populateWithProperties(this, data, propertiesToInclude);\n\n return data;\n },\n\n /**\n * @private\n */\n _toObjects: function(methodName, propertiesToInclude) {\n return this.getObjects().filter(function(object) {\n return !object.excludeFromExport;\n }).map(function(instance) {\n return this._toObject(instance, methodName, propertiesToInclude);\n }, this);\n },\n\n /**\n * @private\n */\n _toObject: function(instance, methodName, propertiesToInclude) {\n var originalValue;\n\n if (!this.includeDefaultValues) {\n originalValue = instance.includeDefaultValues;\n instance.includeDefaultValues = false;\n }\n\n var object = instance[methodName](propertiesToInclude);\n if (!this.includeDefaultValues) {\n instance.includeDefaultValues = originalValue;\n }\n return object;\n },\n\n /**\n * @private\n */\n __serializeBgOverlay: function(methodName, propertiesToInclude) {\n var data = { }, bgImage = this.backgroundImage, overlay = this.overlayImage;\n\n if (this.backgroundColor) {\n data.background = this.backgroundColor.toObject\n ? this.backgroundColor.toObject(propertiesToInclude)\n : this.backgroundColor;\n }\n\n if (this.overlayColor) {\n data.overlay = this.overlayColor.toObject\n ? this.overlayColor.toObject(propertiesToInclude)\n : this.overlayColor;\n }\n if (bgImage && !bgImage.excludeFromExport) {\n data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude);\n }\n if (overlay && !overlay.excludeFromExport) {\n data.overlayImage = this._toObject(overlay, methodName, propertiesToInclude);\n }\n\n return data;\n },\n\n /* _TO_SVG_START_ */\n /**\n * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n * a zoomed canvas will then produce zoomed SVG output.\n * @type Boolean\n * @default\n */\n svgViewportTransformation: true,\n\n /**\n * Returns SVG representation of canvas\n * @function\n * @param {Object} [options] Options object for SVG output\n * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n * @param {Object} [options.viewBox] SVG viewbox object\n * @param {Number} [options.viewBox.x] x-cooridnate of viewbox\n * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n * @param {Number} [options.viewBox.width] Width of viewbox\n * @param {Number} [options.viewBox.height] Height of viewbox\n * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n * @param {String} [options.width] desired width of svg with or without units\n * @param {String} [options.height] desired height of svg with or without units\n * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n * @return {String} SVG string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n * @example Normal SVG output\n * var svg = canvas.toSVG();\n * @example SVG output without preamble (without <?xml ../>)\n * var svg = canvas.toSVG({suppressPreamble: true});\n * @example SVG output with viewBox attribute\n * var svg = canvas.toSVG({\n * viewBox: {\n * x: 100,\n * y: 100,\n * width: 200,\n * height: 300\n * }\n * });\n * @example SVG output with different encoding (default: UTF-8)\n * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n * @example Modify SVG output with reviver function\n * var svg = canvas.toSVG(null, function(svg) {\n * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n * });\n */\n toSVG: function(options, reviver) {\n options || (options = { });\n\n var markup = [];\n\n this._setSVGPreamble(markup, options);\n this._setSVGHeader(markup, options);\n\n this._setSVGBgOverlayColor(markup, 'backgroundColor');\n this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n\n this._setSVGObjects(markup, reviver);\n\n this._setSVGBgOverlayColor(markup, 'overlayColor');\n this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n markup.push('');\n\n return markup.join('');\n },\n\n /**\n * @private\n */\n _setSVGPreamble: function(markup, options) {\n if (options.suppressPreamble) {\n return;\n }\n markup.push(\n '\\n',\n '\\n'\n );\n },\n\n /**\n * @private\n */\n _setSVGHeader: function(markup, options) {\n var width = options.width || this.width,\n height = options.height || this.height,\n vpt, viewBox = 'viewBox=\"0 0 ' + this.width + ' ' + this.height + '\" ',\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n if (options.viewBox) {\n viewBox = 'viewBox=\"' +\n options.viewBox.x + ' ' +\n options.viewBox.y + ' ' +\n options.viewBox.width + ' ' +\n options.viewBox.height + '\" ';\n }\n else {\n if (this.svgViewportTransformation) {\n vpt = this.viewportTransform;\n viewBox = 'viewBox=\"' +\n toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' +\n toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '\" ';\n }\n }\n\n markup.push(\n '\\n',\n 'Created with Fabric.js ', fabric.version, '\\n',\n '\\n',\n this.createSVGFontFacesMarkup(),\n this.createSVGRefElementsMarkup(),\n '\\n'\n );\n },\n\n /**\n * Creates markup containing SVG referenced elements like patterns, gradients etc.\n * @return {String}\n */\n createSVGRefElementsMarkup: function() {\n var _this = this,\n markup = ['backgroundColor', 'overlayColor'].map(function(prop) {\n var fill = _this[prop];\n if (fill && fill.toLive) {\n return fill.toSVG(_this, false);\n }\n });\n return markup.join('');\n },\n\n /**\n * Creates markup containing SVG font faces,\n * font URLs for font faces must be collected by developers\n * and are not extracted from the DOM by fabricjs\n * @param {Array} objects Array of fabric objects\n * @return {String}\n */\n createSVGFontFacesMarkup: function() {\n var markup = '', fontList = { }, obj, fontFamily,\n style, row, rowIndex, _char, charIndex,\n fontPaths = fabric.fontPaths, objects = this.getObjects();\n\n for (var i = 0, len = objects.length; i < len; i++) {\n obj = objects[i];\n fontFamily = obj.fontFamily;\n if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) {\n continue;\n }\n fontList[fontFamily] = true;\n if (!obj.styles) {\n continue;\n }\n style = obj.styles;\n for (rowIndex in style) {\n row = style[rowIndex];\n for (charIndex in row) {\n _char = row[charIndex];\n fontFamily = _char.fontFamily;\n if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n fontList[fontFamily] = true;\n }\n }\n }\n }\n\n for (var j in fontList) {\n markup += [\n '\\t\\t@font-face {\\n',\n '\\t\\t\\tfont-family: \\'', j, '\\';\\n',\n '\\t\\t\\tsrc: url(\\'', fontPaths[j], '\\');\\n',\n '\\t\\t}\\n'\n ].join('');\n }\n\n if (markup) {\n markup = [\n '\\t\\n'\n ].join('');\n }\n\n return markup;\n },\n\n /**\n * @private\n */\n _setSVGObjects: function(markup, reviver) {\n var instance;\n for (var i = 0, objects = this.getObjects(), len = objects.length; i < len; i++) {\n instance = objects[i];\n if (instance.excludeFromExport) {\n continue;\n }\n this._setSVGObject(markup, instance, reviver);\n }\n },\n\n /**\n * push single object svg representation in the markup\n * @private\n */\n _setSVGObject: function(markup, instance, reviver) {\n markup.push(instance.toSVG(reviver));\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayImage: function(markup, property, reviver) {\n if (this[property] && this[property].toSVG) {\n markup.push(this[property].toSVG(reviver));\n }\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayColor: function(markup, property) {\n var filler = this[property];\n if (!filler) {\n return;\n }\n if (filler.toLive) {\n var repeat = filler.repeat;\n markup.push(\n '\\n'\n );\n }\n else {\n markup.push(\n '\\n'\n );\n }\n },\n /* _TO_SVG_END_ */\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the bottom of the stack of drawn objects\n * @param {fabric.Object} object Object to send to back\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendToBack: function (object) {\n if (!object) {\n return this;\n }\n var activeGroup = this._activeGroup,\n i, obj, objs;\n if (object === activeGroup) {\n objs = activeGroup._objects;\n for (i = objs.length; i--;) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n this._objects.unshift(obj);\n }\n }\n else {\n removeFromArray(this._objects, object);\n this._objects.unshift(object);\n }\n return this.renderAll && this.renderAll();\n },\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the top of the stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringToFront: function (object) {\n if (!object) {\n return this;\n }\n var activeGroup = this._activeGroup,\n i, obj, objs;\n if (object === activeGroup) {\n objs = activeGroup._objects;\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n this._objects.push(obj);\n }\n }\n else {\n removeFromArray(this._objects, object);\n this._objects.push(object);\n }\n return this.renderAll && this.renderAll();\n },\n\n /**\n * Moves an object or a selection down in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendBackwards: function (object, intersecting) {\n if (!object) {\n return this;\n }\n\n var activeGroup = this._activeGroup,\n i, obj, idx, newIdx, objs, objsMoved = 0;\n\n if (object === activeGroup) {\n objs = activeGroup._objects;\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n if (idx > 0 + objsMoved) {\n newIdx = idx - 1;\n removeFromArray(this._objects, obj);\n this._objects.splice(newIdx, 0, obj);\n }\n objsMoved++;\n }\n }\n else {\n idx = this._objects.indexOf(object);\n if (idx !== 0) {\n // if object is not on the bottom of stack\n newIdx = this._findNewLowerIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n }\n }\n this.renderAll && this.renderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewLowerIndex: function(object, idx, intersecting) {\n var newIdx;\n\n if (intersecting) {\n newIdx = idx;\n\n // traverse down the stack looking for the nearest intersecting object\n for (var i = idx - 1; i >= 0; --i) {\n\n var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n object.isContainedWithinObject(this._objects[i]) ||\n this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n }\n else {\n newIdx = idx - 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object or a selection up in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringForward: function (object, intersecting) {\n if (!object) {\n return this;\n }\n\n var activeGroup = this._activeGroup,\n i, obj, idx, newIdx, objs, objsMoved = 0;\n\n if (object === activeGroup) {\n objs = activeGroup._objects;\n for (i = objs.length; i--;) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n if (idx < this._objects.length - 1 - objsMoved) {\n newIdx = idx + 1;\n removeFromArray(this._objects, obj);\n this._objects.splice(newIdx, 0, obj);\n }\n objsMoved++;\n }\n }\n else {\n idx = this._objects.indexOf(object);\n if (idx !== this._objects.length - 1) {\n // if object is not on top of stack (last item in an array)\n newIdx = this._findNewUpperIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n }\n }\n this.renderAll && this.renderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewUpperIndex: function(object, idx, intersecting) {\n var newIdx;\n\n if (intersecting) {\n newIdx = idx;\n\n // traverse up the stack looking for the nearest intersecting object\n for (var i = idx + 1; i < this._objects.length; ++i) {\n\n var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n object.isContainedWithinObject(this._objects[i]) ||\n this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n }\n else {\n newIdx = idx + 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {Number} index Position to move to\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n moveTo: function (object, index) {\n removeFromArray(this._objects, object);\n this._objects.splice(index, 0, object);\n return this.renderAll && this.renderAll();\n },\n\n /**\n * Clears a canvas element and removes all event listeners\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n this.clear();\n return this;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function () {\n return '#';\n }\n });\n\n extend(fabric.StaticCanvas.prototype, fabric.Observable);\n extend(fabric.StaticCanvas.prototype, fabric.Collection);\n extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);\n\n extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ {\n\n /**\n * @static\n * @type String\n * @default\n */\n EMPTY_JSON: '{\"objects\": [], \"background\": \"white\"}',\n\n /**\n * Provides a way to check support of some of the canvas methods\n * (either those of HTMLCanvasElement itself, or rendering context)\n *\n * @param {String} methodName Method to check support for;\n * Could be one of \"getImageData\", \"toDataURL\", \"toDataURLWithQuality\" or \"setLineDash\"\n * @return {Boolean | null} `true` if method is supported (or at least exists),\n * `null` if canvas element or context can not be initialized\n */\n supports: function (methodName) {\n var el = fabric.util.createCanvasElement();\n\n if (!el || !el.getContext) {\n return null;\n }\n\n var ctx = el.getContext('2d');\n if (!ctx) {\n return null;\n }\n\n switch (methodName) {\n\n case 'getImageData':\n return typeof ctx.getImageData !== 'undefined';\n\n case 'setLineDash':\n return typeof ctx.setLineDash !== 'undefined';\n\n case 'toDataURL':\n return typeof el.toDataURL !== 'undefined';\n\n case 'toDataURLWithQuality':\n try {\n el.toDataURL('image/jpeg', 0);\n return true;\n }\n catch (e) { }\n return false;\n\n default:\n return null;\n }\n }\n });\n\n /**\n * Returns JSON representation of canvas\n * @function\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} JSON string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n * @example JSON without additional properties\n * var json = canvas.toJSON();\n * @example JSON with additional properties included\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY', 'lockUniScaling']);\n * @example JSON without default values\n * canvas.includeDefaultValues = false;\n * var json = canvas.toJSON();\n */\n fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;\n\n})();\n\n\n/**\n * BaseBrush class\n * @class fabric.BaseBrush\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nfabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ {\n\n /**\n * Color of a brush\n * @type String\n * @default\n */\n color: 'rgb(0, 0, 0)',\n\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width: 1,\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'round',\n\n /**\n * Corner style of a brush (one of \"bevil\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'round',\n\n /**\n * Stroke Dash Array.\n * @type Array\n * @default\n */\n strokeDashArray: null,\n\n /**\n * Sets shadow of an object\n * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setShadow: function(options) {\n this.shadow = new fabric.Shadow(options);\n return this;\n },\n\n /**\n * Sets brush styles\n * @private\n */\n _setBrushStyles: function() {\n var ctx = this.canvas.contextTop;\n\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = this.strokeLineCap;\n ctx.lineJoin = this.strokeLineJoin;\n if (this.strokeDashArray && fabric.StaticCanvas.supports('setLineDash')) {\n ctx.setLineDash(this.strokeDashArray);\n }\n },\n\n /**\n * Sets brush shadow styles\n * @private\n */\n _setShadow: function() {\n if (!this.shadow) {\n return;\n }\n\n var ctx = this.canvas.contextTop,\n zoom = this.canvas.getZoom();\n\n ctx.shadowColor = this.shadow.color;\n ctx.shadowBlur = this.shadow.blur * zoom;\n ctx.shadowOffsetX = this.shadow.offsetX * zoom;\n ctx.shadowOffsetY = this.shadow.offsetY * zoom;\n },\n\n /**\n * Removes brush shadow styles\n * @private\n */\n _resetShadow: function() {\n var ctx = this.canvas.contextTop;\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n});\n\n\n(function() {\n\n /**\n * PencilBrush class\n * @class fabric.PencilBrush\n * @extends fabric.BaseBrush\n */\n fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ {\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.PencilBrush} Instance of a pencil brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this._points = [];\n },\n\n /**\n * Inovoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function(pointer) {\n this._prepareForDrawing(pointer);\n // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n this._captureDrawingPath(pointer);\n this._render();\n },\n\n /**\n * Inovoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n this._captureDrawingPath(pointer);\n // redraw curve\n // clear top canvas\n this.canvas.clearContext(this.canvas.contextTop);\n this._render();\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n this._finalizeAndAddPath();\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing: function(pointer) {\n\n var p = new fabric.Point(pointer.x, pointer.y);\n\n this._reset();\n this._addPoint(p);\n\n this.canvas.contextTop.moveTo(p.x, p.y);\n },\n\n /**\n * @private\n * @param {fabric.Point} point Point to be added to points array\n */\n _addPoint: function(point) {\n if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) {\n return;\n }\n this._points.push(point);\n },\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset: function() {\n this._points.length = 0;\n\n this._setBrushStyles();\n this._setShadow();\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _captureDrawingPath: function(pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y);\n this._addPoint(pointerPoint);\n },\n\n /**\n * Draw a smooth path on the topCanvas using quadraticCurveTo\n * @private\n */\n _render: function() {\n var ctx = this.canvas.contextTop, i, len,\n v = this.canvas.viewportTransform,\n p1 = this._points[0],\n p2 = this._points[1];\n\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n ctx.beginPath();\n\n //if we only have 2 points in the path and they are the same\n //it means that the user only clicked the canvas without moving the mouse\n //then we should be drawing a dot. A path isn't drawn between two identical dots\n //that's why we set them apart a bit\n if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n var width = this.width / 1000;\n p1 = new fabric.Point(p1.x, p1.y);\n p2 = new fabric.Point(p2.x, p2.y);\n p1.x -= width;\n p2.x += width;\n }\n ctx.moveTo(p1.x, p1.y);\n\n for (i = 1, len = this._points.length; i < len; i++) {\n // we pick the point between pi + 1 & pi + 2 as the\n // end point and p1 as our control point.\n var midPoint = p1.midPointFrom(p2);\n ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n\n p1 = this._points[i];\n p2 = this._points[i + 1];\n }\n // Draw last line as a straight line while\n // we wait for the next point to be able to calculate\n // the bezier control point\n ctx.lineTo(p1.x, p1.y);\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * Converts points to SVG path\n * @param {Array} points Array of points\n * @return {String} SVG path\n */\n convertPointsToSVGPath: function(points) {\n var path = [], i, width = this.width / 1000,\n p1 = new fabric.Point(points[0].x, points[0].y),\n p2 = new fabric.Point(points[1].x, points[1].y),\n len = points.length, multSignX = 1, multSignY = 1, manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' ');\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n var midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');\n }\n p1 = points[i];\n if ((i + 1) < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push('L ', p1.x + multSignX * width, ' ', p1.y + multSignY * width);\n return path;\n },\n\n /**\n * Creates fabric.Path object to add on canvas\n * @param {String} pathData Path data\n * @return {fabric.Path} Path to add on canvas\n */\n createPath: function(pathData) {\n var path = new fabric.Path(pathData, {\n fill: null,\n stroke: this.color,\n strokeWidth: this.width,\n strokeLineCap: this.strokeLineCap,\n strokeLineJoin: this.strokeLineJoin,\n strokeDashArray: this.strokeDashArray,\n originX: 'center',\n originY: 'center'\n });\n var position = new fabric.Point(path.left, path.top);\n path.originX = fabric.Object.prototype.originX;\n path.originY = fabric.Object.prototype.originY;\n position = path.translateToGivenOrigin(\n position, 'center', 'center', path.originX, path.originY);\n path.top = position.y;\n path.left = position.x;\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.setShadow(this.shadow);\n }\n\n return path;\n },\n\n /**\n * On mouseup after drawing the path on contextTop canvas\n * we use the points captured to create an new fabric path object\n * and add it to the fabric canvas.\n */\n _finalizeAndAddPath: function() {\n var ctx = this.canvas.contextTop;\n ctx.closePath();\n\n var pathData = this.convertPointsToSVGPath(this._points).join('');\n if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') {\n // do not create 0 width/height paths, as they are\n // rendered inconsistently across browsers\n // Firefox 4, for example, renders a dot,\n // whereas Chrome 10 renders nothing\n this.canvas.renderAll();\n return;\n }\n\n var path = this.createPath(pathData);\n\n this.canvas.add(path);\n path.setCoords();\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderAll();\n\n // fire event 'path' created\n this.canvas.fire('path:created', { path: path });\n }\n });\n})();\n\n\n/**\n * CircleBrush class\n * @class fabric.CircleBrush\n */\nfabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ {\n\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.CircleBrush} Instance of a circle brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this.points = [];\n },\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Object} pointer\n */\n drawDot: function(pointer) {\n var point = this.addPoint(pointer),\n ctx = this.canvas.contextTop,\n v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n\n ctx.fillStyle = point.fill;\n ctx.beginPath();\n ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n ctx.closePath();\n ctx.fill();\n\n ctx.restore();\n },\n\n /**\n * Invoked on mouse down\n */\n onMouseDown: function(pointer) {\n this.points.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n this.drawDot(pointer);\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n this.drawDot(pointer);\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n var circles = [];\n\n for (var i = 0, len = this.points.length; i < len; i++) {\n var point = this.points[i],\n circle = new fabric.Circle({\n radius: point.radius,\n left: point.x,\n top: point.y,\n originX: 'center',\n originY: 'center',\n fill: point.fill\n });\n\n this.shadow && circle.setShadow(this.shadow);\n\n circles.push(circle);\n }\n var group = new fabric.Group(circles, { originX: 'center', originY: 'center' });\n group.canvas = this.canvas;\n\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.renderAll();\n },\n\n /**\n * @param {Object} pointer\n * @return {fabric.Point} Just added pointer point\n */\n addPoint: function(pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y),\n\n circleRadius = fabric.util.getRandomInt(\n Math.max(0, this.width - 20), this.width + 20) / 2,\n\n circleColor = new fabric.Color(this.color)\n .setAlpha(fabric.util.getRandomInt(0, 100) / 100)\n .toRgba();\n\n pointerPoint.radius = circleRadius;\n pointerPoint.fill = circleColor;\n\n this.points.push(pointerPoint);\n\n return pointerPoint;\n }\n});\n\n\n/**\n * SprayBrush class\n * @class fabric.SprayBrush\n */\nfabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ {\n\n /**\n * Width of a spray\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Density of a spray (number of dots per chunk)\n * @type Number\n * @default\n */\n density: 20,\n\n /**\n * Width of spray dots\n * @type Number\n * @default\n */\n dotWidth: 1,\n\n /**\n * Width variance of spray dots\n * @type Number\n * @default\n */\n dotWidthVariance: 1,\n\n /**\n * Whether opacity of a dot should be random\n * @type Boolean\n * @default\n */\n randomOpacity: false,\n\n /**\n * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n * @type Boolean\n * @default\n */\n optimizeOverlapping: true,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.SprayBrush} Instance of a spray brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this.sprayChunks = [];\n },\n\n /**\n * Invoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function(pointer) {\n this.sprayChunks.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n\n this.addSprayChunk(pointer);\n this.render();\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n this.addSprayChunk(pointer);\n this.render();\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n var rects = [];\n\n for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n var sprayChunk = this.sprayChunks[i];\n\n for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {\n\n var rect = new fabric.Rect({\n width: sprayChunk[j].width,\n height: sprayChunk[j].width,\n left: sprayChunk[j].x + 1,\n top: sprayChunk[j].y + 1,\n originX: 'center',\n originY: 'center',\n fill: this.color\n });\n\n this.shadow && rect.setShadow(this.shadow);\n rects.push(rect);\n }\n }\n\n if (this.optimizeOverlapping) {\n rects = this._getOptimizedRects(rects);\n }\n\n var group = new fabric.Group(rects, { originX: 'center', originY: 'center' });\n group.canvas = this.canvas;\n\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.renderAll();\n },\n\n /**\n * @private\n * @param {Array} rects\n */\n _getOptimizedRects: function(rects) {\n\n // avoid creating duplicate rects at the same coordinates\n var uniqueRects = { }, key;\n\n for (var i = 0, len = rects.length; i < len; i++) {\n key = rects[i].left + '' + rects[i].top;\n if (!uniqueRects[key]) {\n uniqueRects[key] = rects[i];\n }\n }\n var uniqueRectsArray = [];\n for (key in uniqueRects) {\n uniqueRectsArray.push(uniqueRects[key]);\n }\n\n return uniqueRectsArray;\n },\n\n /**\n * Renders brush\n */\n render: function() {\n var ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n var v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n\n for (var i = 0, len = this.sprayChunkPoints.length; i < len; i++) {\n var point = this.sprayChunkPoints[i];\n if (typeof point.opacity !== 'undefined') {\n ctx.globalAlpha = point.opacity;\n }\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n ctx.restore();\n },\n\n /**\n * @param {Object} pointer\n */\n addSprayChunk: function(pointer) {\n this.sprayChunkPoints = [];\n\n var x, y, width, radius = this.width / 2;\n\n for (var i = 0; i < this.density; i++) {\n\n x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);\n y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);\n\n if (this.dotWidthVariance) {\n width = fabric.util.getRandomInt(\n // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance),\n this.dotWidth + this.dotWidthVariance);\n }\n else {\n width = this.dotWidth;\n }\n\n var point = new fabric.Point(x, y);\n point.width = width;\n\n if (this.randomOpacity) {\n point.opacity = fabric.util.getRandomInt(0, 100) / 100;\n }\n\n this.sprayChunkPoints.push(point);\n }\n\n this.sprayChunks.push(this.sprayChunkPoints);\n }\n});\n\n\n/**\n * PatternBrush class\n * @class fabric.PatternBrush\n * @extends fabric.BaseBrush\n */\nfabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ {\n\n getPatternSrc: function() {\n\n var dotWidth = 20,\n dotDistance = 5,\n patternCanvas = fabric.document.createElement('canvas'),\n patternCtx = patternCanvas.getContext('2d');\n\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n\n patternCtx.fillStyle = this.color;\n patternCtx.beginPath();\n patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);\n patternCtx.closePath();\n patternCtx.fill();\n\n return patternCanvas;\n },\n\n getPatternSrcFunction: function() {\n return String(this.getPatternSrc).replace('this.color', '\"' + this.color + '\"');\n },\n\n /**\n * Creates \"pattern\" instance property\n */\n getPattern: function() {\n return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat');\n },\n\n /**\n * Sets brush styles\n */\n _setBrushStyles: function() {\n this.callSuper('_setBrushStyles');\n this.canvas.contextTop.strokeStyle = this.getPattern();\n },\n\n /**\n * Creates path\n */\n createPath: function(pathData) {\n var path = this.callSuper('createPath', pathData),\n topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n path.stroke = new fabric.Pattern({\n source: this.source || this.getPatternSrcFunction(),\n offsetX: -topLeft.x,\n offsetY: -topLeft.y\n });\n return path;\n }\n});\n\n\n(function() {\n\n var getPointer = fabric.util.getPointer,\n degreesToRadians = fabric.util.degreesToRadians,\n radiansToDegrees = fabric.util.radiansToDegrees,\n atan2 = Math.atan2,\n abs = Math.abs,\n supportLineDash = fabric.StaticCanvas.supports('setLineDash'),\n\n STROKE_OFFSET = 0.5;\n\n /**\n * Canvas class\n * @class fabric.Canvas\n * @extends fabric.StaticCanvas\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n * @see {@link fabric.Canvas#initialize} for constructor definition\n *\n * @fires object:added\n * @fires object:modified\n * @fires object:rotating\n * @fires object:scaling\n * @fires object:moving\n * @fires object:selected\n *\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:created\n *\n * @fires path:created\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:over\n * @fires mouse:out\n *\n */\n fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(el, options) {\n options || (options = { });\n\n this._initStatic(el, options);\n this._initInteractive();\n this._createCacheCanvas();\n },\n\n /**\n * When true, objects can be transformed by one side (unproportionally)\n * @type Boolean\n * @default\n */\n uniScaleTransform: false,\n\n /**\n * Indicates which key enable unproportional scaling\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n uniScaleKey: 'shiftKey',\n\n /**\n * When true, objects use center point as the origin of scale transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, objects use center point as the origin of rotate transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: false,\n\n /**\n * Indicates which key enable centered Transfrom\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n centeredKey: 'altKey',\n\n /**\n * Indicates which key enable alternate action on corner\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n altActionKey: 'shiftKey',\n\n /**\n * Indicates that canvas is interactive. This property should not be changed.\n * @type Boolean\n * @default\n */\n interactive: true,\n\n /**\n * Indicates whether group selection should be enabled\n * @type Boolean\n * @default\n */\n selection: true,\n\n /**\n * Indicates which key enable multiple click selection\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n selectionKey: 'shiftKey',\n\n /**\n * Indicates which key enable alternative selection\n * in case of target overlapping with active object\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.5\n * @type null|String\n * @default\n */\n altSelectionKey: null,\n\n /**\n * Color of selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(100, 100, 255, 0.3)', // blue\n\n /**\n * Default dash array pattern\n * If not empty the selection border is dashed\n * @type Array\n */\n selectionDashArray: [],\n\n /**\n * Color of the border of selection (usually slightly darker than color of selection itself)\n * @type String\n * @default\n */\n selectionBorderColor: 'rgba(255, 255, 255, 0.3)',\n\n /**\n * Width of a line used in object/group selection\n * @type Number\n * @default\n */\n selectionLineWidth: 1,\n\n /**\n * Default cursor value used when hovering over an object on canvas\n * @type String\n * @default\n */\n hoverCursor: 'move',\n\n /**\n * Default cursor value used when moving an object on canvas\n * @type String\n * @default\n */\n moveCursor: 'move',\n\n /**\n * Default cursor value used for the entire canvas\n * @type String\n * @default\n */\n defaultCursor: 'default',\n\n /**\n * Cursor value used during free drawing\n * @type String\n * @default\n */\n freeDrawingCursor: 'crosshair',\n\n /**\n * Cursor value used for rotation point\n * @type String\n * @default\n */\n rotationCursor: 'crosshair',\n\n /**\n * Default element class that's given to wrapper (div) element of canvas\n * @type String\n * @default\n */\n containerClass: 'canvas-container',\n\n /**\n * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * Number of pixels around target pixel to tolerate (consider active) during object detection\n * @type Number\n * @default\n */\n targetFindTolerance: 0,\n\n /**\n * When true, target detection is skipped when hovering over canvas. This can be used to improve performance.\n * @type Boolean\n * @default\n */\n skipTargetFind: false,\n\n /**\n * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n * After mousedown, mousemove creates a shape,\n * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n * @type Boolean\n * @default\n */\n isDrawingMode: false,\n\n /**\n * Indicates whether objects should remain in current stack position when selected.\n * When false objects are brought to top and rendered as part of the selection group\n * @type Boolean\n * @default\n */\n preserveObjectStacking: false,\n\n /**\n * Indicates the angle that an object will lock to while rotating.\n * @type Number\n * @since 1.6.7\n * @default\n */\n snapAngle: 0,\n\n /**\n * Indicates the distance from the snapAngle the rotation will lock to the snapAngle.\n * When `null`, the snapThreshold will default to the snapAngle.\n * @type null|Number\n * @since 1.6.7\n * @default\n */\n snapThreshold: null,\n\n /**\n * Indicates if the right click on canvas can output the context menu or not\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n stopContextMenu: false,\n\n /**\n * Indicates if the canvas can fire right click events\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n fireRightClick: false,\n\n /**\n * Indicates if the canvas can fire middle click events\n * @type Boolean\n * @since 1.7.8\n * @default\n */\n fireMiddleClick: false,\n\n /**\n * @private\n */\n _initInteractive: function() {\n this._currentTransform = null;\n this._groupSelector = null;\n this._initWrapperElement();\n this._createUpperCanvas();\n this._initEventListeners();\n\n this._initRetinaScaling();\n\n this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);\n\n this.calcOffset();\n },\n\n /**\n * Divides objects in two groups, one to render immediately\n * and one to render as activeGroup.\n * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n */\n _chooseObjectsToRender: function() {\n var activeGroup = this.getActiveGroup(),\n activeObject = this.getActiveObject(),\n object, objsToRender = [], activeGroupObjects = [];\n\n if ((activeGroup || activeObject) && !this.preserveObjectStacking) {\n for (var i = 0, length = this._objects.length; i < length; i++) {\n object = this._objects[i];\n if ((!activeGroup || !activeGroup.contains(object)) && object !== activeObject) {\n objsToRender.push(object);\n }\n else {\n activeGroupObjects.push(object);\n }\n }\n if (activeGroup) {\n activeGroup._set('_objects', activeGroupObjects);\n objsToRender.push(activeGroup);\n }\n activeObject && objsToRender.push(activeObject);\n }\n else {\n objsToRender = this._objects;\n }\n return objsToRender;\n },\n\n /**\n * Renders both the top canvas and the secondary container canvas.\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAll: function () {\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());\n return this;\n },\n\n /**\n * Method to render only the top canvas.\n * Also used to render the group selection box.\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n renderTop: function () {\n var ctx = this.contextTop;\n this.clearContext(ctx);\n\n // we render the top context - last object\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n }\n\n this.fire('after:render');\n this.contextTopDirty = true;\n return this;\n },\n\n /**\n * Resets the current transform to its original values and chooses the type of resizing based on the event\n * @private\n */\n _resetCurrentTransform: function() {\n var t = this._currentTransform;\n\n t.target.set({\n scaleX: t.original.scaleX,\n scaleY: t.original.scaleY,\n skewX: t.original.skewX,\n skewY: t.original.skewY,\n left: t.original.left,\n top: t.original.top\n });\n\n if (this._shouldCenterTransform(t.target)) {\n if (t.action === 'rotate') {\n this._setOriginToCenter(t.target);\n }\n else {\n if (t.originX !== 'center') {\n if (t.originX === 'right') {\n t.mouseXSign = -1;\n }\n else {\n t.mouseXSign = 1;\n }\n }\n if (t.originY !== 'center') {\n if (t.originY === 'bottom') {\n t.mouseYSign = -1;\n }\n else {\n t.mouseYSign = 1;\n }\n }\n\n t.originX = 'center';\n t.originY = 'center';\n }\n }\n else {\n t.originX = t.original.originX;\n t.originY = t.original.originY;\n }\n },\n\n /**\n * Checks if point is contained within an area of given object\n * @param {Event} e Event object\n * @param {fabric.Object} target Object to test against\n * @param {Object} [point] x,y object of point coordinates we want to check.\n * @return {Boolean} true if point is contained within an area of given object\n */\n containsPoint: function (e, target, point) {\n var ignoreZoom = true,\n pointer = point || this.getPointer(e, ignoreZoom),\n xy;\n\n if (target.group && target.group === this.getActiveGroup()) {\n xy = this._normalizePointer(target.group, pointer);\n }\n else {\n xy = { x: pointer.x, y: pointer.y };\n }\n // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html\n // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html\n return (target.containsPoint(xy) || target._findTargetCorner(pointer));\n },\n\n /**\n * @private\n */\n _normalizePointer: function (object, pointer) {\n var m = object.calcTransformMatrix(),\n invertedM = fabric.util.invertTransform(m),\n vptPointer = this.restorePointerVpt(pointer);\n return fabric.util.transformPoint(vptPointer, invertedM);\n },\n\n /**\n * Returns true if object is transparent at a certain location\n * @param {fabric.Object} target Object to check\n * @param {Number} x Left coordinate\n * @param {Number} y Top coordinate\n * @return {Boolean}\n */\n isTargetTransparent: function (target, x, y) {\n var hasBorders = target.hasBorders,\n transparentCorners = target.transparentCorners,\n ctx = this.contextCache,\n originalColor = target.selectionBackgroundColor;\n\n target.hasBorders = target.transparentCorners = false;\n target.selectionBackgroundColor = '';\n\n ctx.save();\n ctx.transform.apply(ctx, this.viewportTransform);\n target.render(ctx);\n ctx.restore();\n\n target.active && target._renderControls(ctx);\n\n target.hasBorders = hasBorders;\n target.transparentCorners = transparentCorners;\n target.selectionBackgroundColor = originalColor;\n\n var isTransparent = fabric.util.isTransparent(\n ctx, x, y, this.targetFindTolerance);\n\n this.clearContext(ctx);\n\n return isTransparent;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _shouldClearSelection: function (e, target) {\n var activeGroup = this.getActiveGroup(),\n activeObject = this.getActiveObject();\n\n return (\n !target\n ||\n (target &&\n activeGroup &&\n !activeGroup.contains(target) &&\n activeGroup !== target &&\n !e[this.selectionKey])\n ||\n (target && !target.evented)\n ||\n (target &&\n !target.selectable &&\n activeObject &&\n activeObject !== target)\n );\n },\n\n /**\n * @private\n * @param {fabric.Object} target\n */\n _shouldCenterTransform: function (target) {\n if (!target) {\n return;\n }\n\n var t = this._currentTransform,\n centerTransform;\n\n if (t.action === 'scale' || t.action === 'scaleX' || t.action === 'scaleY') {\n centerTransform = this.centeredScaling || target.centeredScaling;\n }\n else if (t.action === 'rotate') {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !t.altKey : t.altKey;\n },\n\n /**\n * @private\n */\n _getOriginFromCorner: function(target, corner) {\n var origin = {\n x: target.originX,\n y: target.originY\n };\n\n if (corner === 'ml' || corner === 'tl' || corner === 'bl') {\n origin.x = 'right';\n }\n else if (corner === 'mr' || corner === 'tr' || corner === 'br') {\n origin.x = 'left';\n }\n\n if (corner === 'tl' || corner === 'mt' || corner === 'tr') {\n origin.y = 'bottom';\n }\n else if (corner === 'bl' || corner === 'mb' || corner === 'br') {\n origin.y = 'top';\n }\n\n return origin;\n },\n\n /**\n * @private\n */\n _getActionFromCorner: function(target, corner, e) {\n if (!corner) {\n return 'drag';\n }\n\n switch (corner) {\n case 'mtr':\n return 'rotate';\n case 'ml':\n case 'mr':\n return e[this.altActionKey] ? 'skewY' : 'scaleX';\n case 'mt':\n case 'mb':\n return e[this.altActionKey] ? 'skewX' : 'scaleY';\n default:\n return 'scale';\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _setupCurrentTransform: function (e, target) {\n if (!target) {\n return;\n }\n\n var pointer = this.getPointer(e),\n corner = target._findTargetCorner(this.getPointer(e, true)),\n action = this._getActionFromCorner(target, corner, e),\n origin = this._getOriginFromCorner(target, corner);\n\n this._currentTransform = {\n target: target,\n action: action,\n corner: corner,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n offsetX: pointer.x - target.left,\n offsetY: pointer.y - target.top,\n originX: origin.x,\n originY: origin.y,\n ex: pointer.x,\n ey: pointer.y,\n lastX: pointer.x,\n lastY: pointer.y,\n left: target.left,\n top: target.top,\n theta: degreesToRadians(target.angle),\n width: target.width * target.scaleX,\n mouseXSign: 1,\n mouseYSign: 1,\n shiftKey: e.shiftKey,\n altKey: e[this.centeredKey]\n };\n\n this._currentTransform.original = {\n left: target.left,\n top: target.top,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n originX: origin.x,\n originY: origin.y\n };\n\n this._resetCurrentTransform();\n },\n\n /**\n * Translates object by \"setting\" its left/top\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @return {Boolean} true if the translation occurred\n */\n _translateObject: function (x, y) {\n var transform = this._currentTransform,\n target = transform.target,\n newLeft = x - transform.offsetX,\n newTop = y - transform.offsetY,\n moveX = !target.get('lockMovementX') && target.left !== newLeft,\n moveY = !target.get('lockMovementY') && target.top !== newTop;\n\n moveX && target.set('left', newLeft);\n moveY && target.set('top', newTop);\n return moveX || moveY;\n },\n\n /**\n * Check if we are increasing a positive skew or lower it,\n * checking mouse direction and pressed corner.\n * @private\n */\n _changeSkewTransformOrigin: function(mouseMove, t, by) {\n var property = 'originX', origins = { 0: 'center' },\n skew = t.target.skewX, originA = 'left', originB = 'right',\n corner = t.corner === 'mt' || t.corner === 'ml' ? 1 : -1,\n flipSign = 1;\n\n mouseMove = mouseMove > 0 ? 1 : -1;\n if (by === 'y') {\n skew = t.target.skewY;\n originA = 'top';\n originB = 'bottom';\n property = 'originY';\n }\n origins[-1] = originA;\n origins[1] = originB;\n\n t.target.flipX && (flipSign *= -1);\n t.target.flipY && (flipSign *= -1);\n\n if (skew === 0) {\n t.skewSign = -corner * mouseMove * flipSign;\n t[property] = origins[-mouseMove];\n }\n else {\n skew = skew > 0 ? 1 : -1;\n t.skewSign = skew;\n t[property] = origins[skew * corner * flipSign];\n }\n },\n\n /**\n * Skew object by mouse events\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @param {String} by Either 'x' or 'y'\n * @return {Boolean} true if the skewing occurred\n */\n _skewObject: function (x, y, by) {\n var t = this._currentTransform,\n target = t.target, skewed = false,\n lockSkewingX = target.get('lockSkewingX'),\n lockSkewingY = target.get('lockSkewingY');\n\n if ((lockSkewingX && by === 'x') || (lockSkewingY && by === 'y')) {\n return false;\n }\n\n // Get the constraint point\n var center = target.getCenterPoint(),\n actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), 'center', 'center')[by],\n lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), 'center', 'center')[by],\n actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions();\n\n this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by);\n actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by];\n constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY);\n // Actually skew the object\n skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim);\n t.lastX = x;\n t.lastY = y;\n // Make sure the constraints apply\n target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n return skewed;\n },\n\n /**\n * Set object skew\n * @private\n * @return {Boolean} true if the skewing occurred\n */\n _setObjectSkew: function(localMouse, transform, by, _dim) {\n var target = transform.target, newValue, skewed = false,\n skewSign = transform.skewSign, newDim, dimNoSkew,\n otherBy, _otherBy, _by, newDimMouse, skewX, skewY;\n\n if (by === 'x') {\n otherBy = 'y';\n _otherBy = 'Y';\n _by = 'X';\n skewX = 0;\n skewY = target.skewY;\n }\n else {\n otherBy = 'x';\n _otherBy = 'X';\n _by = 'Y';\n skewX = target.skewX;\n skewY = 0;\n }\n\n dimNoSkew = target._getTransformedDimensions(skewX, skewY);\n newDimMouse = 2 * Math.abs(localMouse) - dimNoSkew[by];\n if (newDimMouse <= 2) {\n newValue = 0;\n }\n else {\n newValue = skewSign * Math.atan((newDimMouse / target['scale' + _by]) /\n (dimNoSkew[otherBy] / target['scale' + _otherBy]));\n newValue = fabric.util.radiansToDegrees(newValue);\n }\n skewed = target['skew' + _by] !== newValue;\n target.set('skew' + _by, newValue);\n if (target['skew' + _otherBy] !== 0) {\n newDim = target._getTransformedDimensions();\n newValue = (_dim[otherBy] / newDim[otherBy]) * target['scale' + _otherBy];\n target.set('scale' + _otherBy, newValue);\n }\n return skewed;\n },\n\n /**\n * Scales object by invoking its scaleX/scaleY methods\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @param {String} by Either 'x' or 'y' - specifies dimension constraint by which to scale an object.\n * When not provided, an object is scaled by both dimensions equally\n * @return {Boolean} true if the scaling occurred\n */\n _scaleObject: function (x, y, by) {\n var t = this._currentTransform,\n target = t.target,\n lockScalingX = target.get('lockScalingX'),\n lockScalingY = target.get('lockScalingY'),\n lockScalingFlip = target.get('lockScalingFlip');\n\n if (lockScalingX && lockScalingY) {\n return false;\n }\n\n // Get the constraint point\n var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY),\n localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY),\n dim = target._getTransformedDimensions(), scaled = false;\n\n this._setLocalMouse(localMouse, t);\n\n // Actually scale the object\n scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim);\n\n // Make sure the constraints apply\n target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n return scaled;\n },\n\n /**\n * @private\n * @return {Boolean} true if the scaling occurred\n */\n _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {\n var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false,\n changeX, changeY, scaleX, scaleY;\n\n scaleX = localMouse.x * target.scaleX / _dim.x;\n scaleY = localMouse.y * target.scaleY / _dim.y;\n changeX = target.scaleX !== scaleX;\n changeY = target.scaleY !== scaleY;\n\n if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) {\n forbidScalingX = true;\n }\n\n if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) {\n forbidScalingY = true;\n }\n\n if (by === 'equally' && !lockScalingX && !lockScalingY) {\n forbidScalingX || forbidScalingY || (scaled = this._scaleObjectEqually(localMouse, target, transform, _dim));\n }\n else if (!by) {\n forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));\n forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));\n }\n else if (by === 'x' && !target.get('lockUniScaling')) {\n forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));\n }\n else if (by === 'y' && !target.get('lockUniScaling')) {\n forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));\n }\n transform.newScaleX = scaleX;\n transform.newScaleY = scaleY;\n forbidScalingX || forbidScalingY || this._flipObject(transform, by);\n return scaled;\n },\n\n /**\n * @private\n * @return {Boolean} true if the scaling occurred\n */\n _scaleObjectEqually: function(localMouse, target, transform, _dim) {\n\n var dist = localMouse.y + localMouse.x,\n lastDist = _dim.y * transform.original.scaleY / target.scaleY +\n _dim.x * transform.original.scaleX / target.scaleX,\n scaled, signX = localMouse.x / Math.abs(localMouse.x),\n signY = localMouse.y / Math.abs(localMouse.y);\n\n // We use transform.scaleX/Y instead of target.scaleX/Y\n // because the object may have a min scale and we'll loose the proportions\n transform.newScaleX = signX * Math.abs(transform.original.scaleX * dist / lastDist);\n transform.newScaleY = signY * Math.abs(transform.original.scaleY * dist / lastDist);\n scaled = transform.newScaleX !== target.scaleX || transform.newScaleY !== target.scaleY;\n target.set('scaleX', transform.newScaleX);\n target.set('scaleY', transform.newScaleY);\n return scaled;\n },\n\n /**\n * @private\n */\n _flipObject: function(transform, by) {\n if (transform.newScaleX < 0 && by !== 'y') {\n if (transform.originX === 'left') {\n transform.originX = 'right';\n }\n else if (transform.originX === 'right') {\n transform.originX = 'left';\n }\n }\n\n if (transform.newScaleY < 0 && by !== 'x') {\n if (transform.originY === 'top') {\n transform.originY = 'bottom';\n }\n else if (transform.originY === 'bottom') {\n transform.originY = 'top';\n }\n }\n },\n\n /**\n * @private\n */\n _setLocalMouse: function(localMouse, t) {\n var target = t.target, zoom = this.getZoom(),\n padding = target.padding / zoom;\n\n if (t.originX === 'right') {\n localMouse.x *= -1;\n }\n else if (t.originX === 'center') {\n localMouse.x *= t.mouseXSign * 2;\n if (localMouse.x < 0) {\n t.mouseXSign = -t.mouseXSign;\n }\n }\n\n if (t.originY === 'bottom') {\n localMouse.y *= -1;\n }\n else if (t.originY === 'center') {\n localMouse.y *= t.mouseYSign * 2;\n if (localMouse.y < 0) {\n t.mouseYSign = -t.mouseYSign;\n }\n }\n\n // adjust the mouse coordinates when dealing with padding\n if (abs(localMouse.x) > padding) {\n if (localMouse.x < 0) {\n localMouse.x += padding;\n }\n else {\n localMouse.x -= padding;\n }\n }\n else { // mouse is within the padding, set to 0\n localMouse.x = 0;\n }\n\n if (abs(localMouse.y) > padding) {\n if (localMouse.y < 0) {\n localMouse.y += padding;\n }\n else {\n localMouse.y -= padding;\n }\n }\n else {\n localMouse.y = 0;\n }\n },\n\n /**\n * Rotates object by invoking its rotate method\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @return {Boolean} true if the rotation occurred\n */\n _rotateObject: function (x, y) {\n\n var t = this._currentTransform;\n\n if (t.target.get('lockRotation')) {\n return false;\n }\n\n var lastAngle = atan2(t.ey - t.top, t.ex - t.left),\n curAngle = atan2(y - t.top, x - t.left),\n angle = radiansToDegrees(curAngle - lastAngle + t.theta),\n hasRoated = true;\n\n if (t.target.snapAngle > 0) {\n var snapAngle = t.target.snapAngle,\n snapThreshold = t.target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n }\n else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n }\n\n // normalize angle to positive value\n if (angle < 0) {\n angle = 360 + angle;\n }\n angle %= 360;\n\n if (t.target.angle === angle) {\n hasRoated = false;\n }\n else {\n t.target.angle = angle;\n }\n\n return hasRoated;\n },\n\n /**\n * Set the cursor type of the canvas element\n * @param {String} value Cursor type of the canvas element.\n * @see http://www.w3.org/TR/css3-ui/#cursor\n */\n setCursor: function (value) {\n this.upperCanvasEl.style.cursor = value;\n },\n\n /**\n * @param {fabric.Object} target to reset transform\n * @private\n */\n _resetObjectTransform: function (target) {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.setAngle(0);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx to draw the selection on\n */\n _drawSelection: function (ctx) {\n var groupSelector = this._groupSelector,\n left = groupSelector.left,\n top = groupSelector.top,\n aleft = abs(left),\n atop = abs(top);\n\n if (this.selectionColor) {\n ctx.fillStyle = this.selectionColor;\n\n ctx.fillRect(\n groupSelector.ex - ((left > 0) ? 0 : -left),\n groupSelector.ey - ((top > 0) ? 0 : -top),\n aleft,\n atop\n );\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor;\n\n // selection border\n if (this.selectionDashArray.length > 1 && !supportLineDash) {\n\n var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop);\n\n ctx.beginPath();\n\n fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray);\n\n ctx.closePath();\n ctx.stroke();\n }\n else {\n fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);\n ctx.strokeRect(\n groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop),\n aleft,\n atop\n );\n }\n },\n\n /**\n * Method that determines what object we are clicking on\n * the skipGroup parameter is for internal use, is needed for shift+click action\n * @param {Event} e mouse event\n * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through\n */\n findTarget: function (e, skipGroup) {\n if (this.skipTargetFind) {\n return;\n }\n\n var ignoreZoom = true,\n pointer = this.getPointer(e, ignoreZoom),\n activeGroup = this.getActiveGroup(),\n activeObject = this.getActiveObject(),\n activeTarget, activeTargetSubs;\n // first check current group (if one exists)\n // active group does not check sub targets like normal groups.\n // if active group just exits.\n this.targets = [];\n if (activeGroup && !skipGroup && activeGroup === this._searchPossibleTargets([activeGroup], pointer)) {\n this._fireOverOutEvents(activeGroup, e);\n return activeGroup;\n }\n // if we hit the corner of an activeObject, let's return that.\n if (activeObject && activeObject._findTargetCorner(pointer)) {\n this._fireOverOutEvents(activeObject, e);\n return activeObject;\n }\n if (activeObject && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n if (!this.preserveObjectStacking) {\n this._fireOverOutEvents(activeObject, e);\n return activeObject;\n }\n else {\n activeTarget = activeObject;\n activeTargetSubs = this.targets;\n this.targets = [];\n }\n }\n\n var target = this._searchPossibleTargets(this._objects, pointer);\n if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {\n target = activeTarget;\n this.targets = activeTargetSubs;\n }\n this._fireOverOutEvents(target, e);\n return target;\n },\n\n /**\n * @private\n */\n _fireOverOutEvents: function(target, e) {\n var overOpt, outOpt, hoveredTarget = this._hoveredTarget;\n if (hoveredTarget !== target) {\n overOpt = { e: e, target: target, previousTarget: this._hoveredTarget };\n outOpt = { e: e, target: this._hoveredTarget, nextTarget: target };\n this._hoveredTarget = target;\n }\n if (target) {\n if (hoveredTarget !== target) {\n if (hoveredTarget) {\n this.fire('mouse:out', outOpt);\n hoveredTarget.fire('mouseout', outOpt);\n }\n this.fire('mouse:over', overOpt);\n target.fire('mouseover', overOpt);\n }\n }\n else if (hoveredTarget) {\n this.fire('mouse:out', outOpt);\n hoveredTarget.fire('mouseout', outOpt);\n }\n },\n\n /**\n * @private\n */\n _checkTarget: function(pointer, obj) {\n if (obj &&\n obj.visible &&\n obj.evented &&\n this.containsPoint(null, obj, pointer)){\n if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {\n var isTransparent = this.isTargetTransparent(obj, pointer.x, pointer.y);\n if (!isTransparent) {\n return true;\n }\n }\n else {\n return true;\n }\n }\n },\n\n /**\n * @private\n */\n _searchPossibleTargets: function(objects, pointer) {\n\n // Cache all targets where their bounding box contains point.\n var target, i = objects.length, normalizedPointer, subTarget;\n // Do not check for currently grouped objects, since we check the parent group itself.\n // untill we call this function specifically to search inside the activeGroup\n while (i--) {\n if (this._checkTarget(pointer, objects[i])) {\n target = objects[i];\n if (target.type === 'group' && target.subTargetCheck) {\n normalizedPointer = this._normalizePointer(target, pointer);\n subTarget = this._searchPossibleTargets(target._objects, normalizedPointer);\n subTarget && this.targets.push(subTarget);\n }\n break;\n }\n }\n return target;\n },\n\n /**\n * Returns pointer coordinates without the effect of the viewport\n * @param {Object} pointer with \"x\" and \"y\" number values\n * @return {Object} object with \"x\" and \"y\" number values\n */\n restorePointerVpt: function(pointer) {\n return fabric.util.transformPoint(\n pointer,\n fabric.util.invertTransform(this.viewportTransform)\n );\n },\n\n /**\n * Returns pointer coordinates relative to canvas.\n * Can return coordinates with or without viewportTransform.\n * ignoreZoom false gives back coordinates that represent\n * the point clicked on canvas element.\n * ignoreZoom true gives back coordinates after being processed\n * by the viewportTransform ( sort of coordinates of what is displayed\n * on the canvas where you are clicking.\n * To interact with your shapes top and left you want to use ignoreZoom true\n * most of the time, while ignoreZoom false will give you coordinates\n * compatible with the object.oCoords system.\n * of the time.\n * @param {Event} e\n * @param {Boolean} ignoreZoom\n * @return {Object} object with \"x\" and \"y\" number values\n */\n getPointer: function (e, ignoreZoom, upperCanvasEl) {\n if (!upperCanvasEl) {\n upperCanvasEl = this.upperCanvasEl;\n }\n var pointer = getPointer(e),\n bounds = upperCanvasEl.getBoundingClientRect(),\n boundsWidth = bounds.width || 0,\n boundsHeight = bounds.height || 0,\n cssScale;\n\n if (!boundsWidth || !boundsHeight ) {\n if ('top' in bounds && 'bottom' in bounds) {\n boundsHeight = Math.abs( bounds.top - bounds.bottom );\n }\n if ('right' in bounds && 'left' in bounds) {\n boundsWidth = Math.abs( bounds.right - bounds.left );\n }\n }\n\n this.calcOffset();\n\n pointer.x = pointer.x - this._offset.left;\n pointer.y = pointer.y - this._offset.top;\n if (!ignoreZoom) {\n pointer = this.restorePointerVpt(pointer);\n }\n\n if (boundsWidth === 0 || boundsHeight === 0) {\n // If bounds are not available (i.e. not visible), do not apply scale.\n cssScale = { width: 1, height: 1 };\n }\n else {\n cssScale = {\n width: upperCanvasEl.width / boundsWidth,\n height: upperCanvasEl.height / boundsHeight\n };\n }\n\n return {\n x: pointer.x * cssScale.width,\n y: pointer.y * cssScale.height\n };\n },\n\n /**\n * @private\n * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized\n */\n _createUpperCanvas: function () {\n var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\\s*lower-canvas\\s*/, '');\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl.className = '';\n }\n else {\n this.upperCanvasEl = this._createCanvasElement();\n }\n fabric.util.addClass(this.upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);\n\n this.wrapperEl.appendChild(this.upperCanvasEl);\n\n this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl);\n this._applyCanvasStyle(this.upperCanvasEl);\n this.contextTop = this.upperCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _createCacheCanvas: function () {\n this.cacheCanvasEl = this._createCanvasElement();\n this.cacheCanvasEl.setAttribute('width', this.width);\n this.cacheCanvasEl.setAttribute('height', this.height);\n this.contextCache = this.cacheCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _initWrapperElement: function () {\n this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', {\n 'class': this.containerClass\n });\n fabric.util.setStyle(this.wrapperEl, {\n width: this.getWidth() + 'px',\n height: this.getHeight() + 'px',\n position: 'relative'\n });\n fabric.util.makeElementUnselectable(this.wrapperEl);\n },\n\n /**\n * @private\n * @param {HTMLElement} element canvas element to apply styles on\n */\n _applyCanvasStyle: function (element) {\n var width = this.getWidth() || element.width,\n height = this.getHeight() || element.height;\n\n fabric.util.setStyle(element, {\n position: 'absolute',\n width: width + 'px',\n height: height + 'px',\n left: 0,\n top: 0,\n 'touch-action': 'none'\n });\n element.width = width;\n element.height = height;\n fabric.util.makeElementUnselectable(element);\n },\n\n /**\n * Copys the the entire inline style from one element (fromEl) to another (toEl)\n * @private\n * @param {Element} fromEl Element style is copied from\n * @param {Element} toEl Element copied style is applied to\n */\n _copyCanvasStyle: function (fromEl, toEl) {\n toEl.style.cssText = fromEl.style.cssText;\n },\n\n /**\n * Returns context of canvas where object selection is drawn\n * @return {CanvasRenderingContext2D}\n */\n getSelectionContext: function() {\n return this.contextTop;\n },\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement: function () {\n return this.upperCanvasEl;\n },\n\n /**\n * @private\n * @param {Object} object\n */\n _setActiveObject: function(object) {\n var obj = this._activeObject;\n if (obj) {\n obj.set('active', false);\n if (object !== obj && obj.onDeselect && typeof obj.onDeselect === 'function') {\n obj.onDeselect();\n }\n }\n this._activeObject = object;\n object.set('active', true);\n },\n\n /**\n * Sets given object as the only active object on canvas\n * @param {fabric.Object} object Object to set as an active one\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setActiveObject: function (object, e) {\n var currentActiveObject = this.getActiveObject();\n if (currentActiveObject && currentActiveObject !== object) {\n currentActiveObject.fire('deselected', { e: e });\n }\n this._setActiveObject(object);\n this.fire('object:selected', { target: object, e: e });\n object.fire('selected', { e: e });\n this.renderAll();\n return this;\n },\n\n /**\n * Returns currently active object\n * @return {fabric.Object} active object\n */\n getActiveObject: function () {\n return this._activeObject;\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function(obj) {\n // removing active object should fire \"selection:cleared\" events\n if (this.getActiveObject() === obj) {\n this.fire('before:selection:cleared', { target: obj });\n this._discardActiveObject();\n this.fire('selection:cleared', { target: obj });\n obj.fire('deselected');\n }\n if (this._hoveredTarget === obj) {\n this._hoveredTarget = null;\n }\n this.callSuper('_onObjectRemoved', obj);\n },\n\n /**\n * @private\n */\n _discardActiveObject: function() {\n var obj = this._activeObject;\n if (obj) {\n obj.set('active', false);\n if (obj.onDeselect && typeof obj.onDeselect === 'function') {\n obj.onDeselect();\n }\n }\n this._activeObject = null;\n },\n\n /**\n * Discards currently active object and fire events. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parmater and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {event} e\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n discardActiveObject: function (e) {\n var activeObject = this._activeObject;\n if (activeObject) {\n this.fire('before:selection:cleared', { target: activeObject, e: e });\n this._discardActiveObject();\n this.fire('selection:cleared', { e: e });\n activeObject.fire('deselected', { e: e });\n }\n return this;\n },\n\n /**\n * @private\n * @param {fabric.Group} group\n */\n _setActiveGroup: function(group) {\n this._activeGroup = group;\n if (group) {\n group.set('active', true);\n }\n },\n\n /**\n * Sets active group to a specified one. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parmater and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {fabric.Group} group Group to set as a current one\n * @param {Event} e Event object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setActiveGroup: function (group, e) {\n this._setActiveGroup(group);\n if (group) {\n this.fire('object:selected', { target: group, e: e });\n group.fire('selected', { e: e });\n }\n return this;\n },\n\n /**\n * Returns currently active group\n * @return {fabric.Group} Current group\n */\n getActiveGroup: function () {\n return this._activeGroup;\n },\n\n /**\n * @private\n */\n _discardActiveGroup: function() {\n var g = this.getActiveGroup();\n if (g) {\n g.destroy();\n }\n this.setActiveGroup(null);\n },\n\n /**\n * Discards currently active group and fire events If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parmater and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n discardActiveGroup: function (e) {\n var g = this.getActiveGroup();\n if (g) {\n this.fire('before:selection:cleared', { e: e, target: g });\n this._discardActiveGroup();\n this.fire('selection:cleared', { e: e });\n }\n return this;\n },\n\n /**\n * Deactivates all objects on canvas, removing any active group or object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n deactivateAll: function () {\n var allObjects = this.getObjects(),\n i = 0,\n len = allObjects.length,\n obj;\n for ( ; i < len; i++) {\n obj = allObjects[i];\n obj && obj.set('active', false);\n }\n this._discardActiveGroup();\n this._discardActiveObject();\n return this;\n },\n\n /**\n * Deactivates all objects and dispatches appropriate events If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parmater and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n deactivateAllWithDispatch: function (e) {\n var allObjects = this.getObjects(),\n i = 0,\n len = allObjects.length,\n obj;\n for ( ; i < len; i++) {\n obj = allObjects[i];\n obj && obj.set('active', false);\n }\n this.discardActiveGroup(e);\n this.discardActiveObject(e);\n return this;\n },\n\n /**\n * Clears a canvas element and removes all event listeners\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n fabric.StaticCanvas.prototype.dispose.call(this);\n var wrapper = this.wrapperEl;\n this.removeListeners();\n wrapper.removeChild(this.upperCanvasEl);\n wrapper.removeChild(this.lowerCanvasEl);\n delete this.upperCanvasEl;\n if (wrapper.parentNode) {\n wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);\n }\n delete this.wrapperEl;\n return this;\n },\n\n /**\n * Clears all contexts (background, main, top) of an instance\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clear: function () {\n this.discardActiveGroup();\n this.discardActiveObject();\n this.clearContext(this.contextTop);\n return this.callSuper('clear');\n },\n\n /**\n * Draws objects' controls (borders/controls)\n * @param {CanvasRenderingContext2D} ctx Context to render controls on\n */\n drawControls: function(ctx) {\n var activeGroup = this.getActiveGroup();\n\n if (activeGroup) {\n activeGroup._renderControls(ctx);\n }\n else {\n this._drawObjectsControls(ctx);\n }\n },\n\n /**\n * @private\n */\n _drawObjectsControls: function(ctx) {\n for (var i = 0, len = this._objects.length; i < len; ++i) {\n if (!this._objects[i] || !this._objects[i].active) {\n continue;\n }\n this._objects[i]._renderControls(ctx);\n }\n },\n\n /**\n * @private\n */\n _toObject: function(instance, methodName, propertiesToInclude) {\n //If the object is part of the current selection group, it should\n //be transformed appropriately\n //i.e. it should be serialised as it would appear if the selection group\n //were to be destroyed.\n var originalProperties = this._realizeGroupTransformOnObject(instance),\n object = this.callSuper('_toObject', instance, methodName, propertiesToInclude);\n //Undo the damage we did by changing all of its properties\n this._unwindGroupTransformOnObject(instance, originalProperties);\n return object;\n },\n\n /**\n * Realises an object's group transformation on it\n * @private\n * @param {fabric.Object} [instance] the object to transform (gets mutated)\n * @returns the original values of instance which were changed\n */\n _realizeGroupTransformOnObject: function(instance) {\n if (instance.group && instance.group === this.getActiveGroup()) {\n //Copy all the positionally relevant properties across now\n var originalValues = {},\n layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top'];\n layoutProps.forEach(function(prop) {\n originalValues[prop] = instance[prop];\n });\n this.getActiveGroup().realizeTransform(instance);\n return originalValues;\n }\n else {\n return null;\n }\n },\n\n /**\n * Restores the changed properties of instance\n * @private\n * @param {fabric.Object} [instance] the object to un-transform (gets mutated)\n * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject\n */\n _unwindGroupTransformOnObject: function(instance, originalValues) {\n if (originalValues) {\n instance.set(originalValues);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function(markup, instance, reviver) {\n var originalProperties;\n //If the object is in a selection group, simulate what would happen to that\n //object when the group is deselected\n originalProperties = this._realizeGroupTransformOnObject(instance);\n this.callSuper('_setSVGObject', markup, instance, reviver);\n this._unwindGroupTransformOnObject(instance, originalProperties);\n },\n });\n\n // copying static properties manually to work around Opera's bug,\n // where \"prototype\" property is enumerable and overrides existing prototype\n for (var prop in fabric.StaticCanvas) {\n if (prop !== 'prototype') {\n fabric.Canvas[prop] = fabric.StaticCanvas[prop];\n }\n }\n\n if (fabric.isTouchSupported) {\n /** @ignore */\n fabric.Canvas.prototype._setCursorFromEvent = function() { };\n }\n\n /**\n * @ignore\n * @class fabric.Element\n * @alias fabric.Canvas\n * @deprecated Use {@link fabric.Canvas} instead.\n * @constructor\n */\n fabric.Element = fabric.Canvas;\n})();\n\n\n(function() {\n\n var cursorOffset = {\n mt: 0, // n\n tr: 1, // ne\n mr: 2, // e\n br: 3, // se\n mb: 4, // s\n bl: 5, // sw\n ml: 6, // w\n tl: 7 // nw\n },\n addListener = fabric.util.addListener,\n removeListener = fabric.util.removeListener,\n RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1;\n\n function checkClick(e, value) {\n return 'which' in e ? e.which === value : e.button === value - 1;\n }\n\n fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * Map of cursor style values for each of the object controls\n * @private\n */\n cursorMap: [\n 'n-resize',\n 'ne-resize',\n 'e-resize',\n 'se-resize',\n 's-resize',\n 'sw-resize',\n 'w-resize',\n 'nw-resize'\n ],\n\n /**\n * Adds mouse listeners to canvas\n * @private\n */\n _initEventListeners: function () {\n // in case we initialized the class twice. This should not happen normally\n // but in some kind of applications where the canvas element may be changed\n // this is a workaround to having double listeners.\n this.removeListeners();\n this._bindEvents();\n\n addListener(fabric.window, 'resize', this._onResize);\n\n // mouse events\n addListener(this.upperCanvasEl, 'mousedown', this._onMouseDown);\n addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove);\n addListener(this.upperCanvasEl, 'mouseout', this._onMouseOut);\n addListener(this.upperCanvasEl, 'mouseenter', this._onMouseEnter);\n addListener(this.upperCanvasEl, 'wheel', this._onMouseWheel);\n addListener(this.upperCanvasEl, 'contextmenu', this._onContextMenu);\n\n // touch events\n addListener(this.upperCanvasEl, 'touchstart', this._onMouseDown, { passive: false });\n addListener(this.upperCanvasEl, 'touchmove', this._onMouseMove, { passive: false });\n\n if (typeof eventjs !== 'undefined' && 'add' in eventjs) {\n eventjs.add(this.upperCanvasEl, 'gesture', this._onGesture);\n eventjs.add(this.upperCanvasEl, 'drag', this._onDrag);\n eventjs.add(this.upperCanvasEl, 'orientation', this._onOrientationChange);\n eventjs.add(this.upperCanvasEl, 'shake', this._onShake);\n eventjs.add(this.upperCanvasEl, 'longpress', this._onLongPress);\n }\n },\n\n /**\n * @private\n */\n _bindEvents: function() {\n if (this.eventsBinded) {\n // for any reason we pass here twice we do not want to bind events twice.\n return;\n }\n this._onMouseDown = this._onMouseDown.bind(this);\n this._onMouseMove = this._onMouseMove.bind(this);\n this._onMouseUp = this._onMouseUp.bind(this);\n this._onResize = this._onResize.bind(this);\n this._onGesture = this._onGesture.bind(this);\n this._onDrag = this._onDrag.bind(this);\n this._onShake = this._onShake.bind(this);\n this._onLongPress = this._onLongPress.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n this._onMouseWheel = this._onMouseWheel.bind(this);\n this._onMouseOut = this._onMouseOut.bind(this);\n this._onMouseEnter = this._onMouseEnter.bind(this);\n this._onContextMenu = this._onContextMenu.bind(this);\n this.eventsBinded = true;\n },\n\n /**\n * Removes all event listeners\n */\n removeListeners: function() {\n removeListener(fabric.window, 'resize', this._onResize);\n\n removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown);\n removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove);\n removeListener(this.upperCanvasEl, 'mouseout', this._onMouseOut);\n removeListener(this.upperCanvasEl, 'mouseenter', this._onMouseEnter);\n removeListener(this.upperCanvasEl, 'wheel', this._onMouseWheel);\n removeListener(this.upperCanvasEl, 'contextmenu', this._onContextMenu);\n\n removeListener(this.upperCanvasEl, 'touchstart', this._onMouseDown);\n removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove);\n\n if (typeof eventjs !== 'undefined' && 'remove' in eventjs) {\n eventjs.remove(this.upperCanvasEl, 'gesture', this._onGesture);\n eventjs.remove(this.upperCanvasEl, 'drag', this._onDrag);\n eventjs.remove(this.upperCanvasEl, 'orientation', this._onOrientationChange);\n eventjs.remove(this.upperCanvasEl, 'shake', this._onShake);\n eventjs.remove(this.upperCanvasEl, 'longpress', this._onLongPress);\n }\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js gesture\n * @param {Event} [self] Inner Event object\n */\n _onGesture: function(e, self) {\n this.__onTransformGesture && this.__onTransformGesture(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js drag\n * @param {Event} [self] Inner Event object\n */\n _onDrag: function(e, self) {\n this.__onDrag && this.__onDrag(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on wheel event\n */\n _onMouseWheel: function(e) {\n this.__onMouseWheel(e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseOut: function(e) {\n var target = this._hoveredTarget;\n this.fire('mouse:out', { target: target, e: e });\n this._hoveredTarget = null;\n target && target.fire('mouseout', { e: e });\n if (this._iTextInstances) {\n this._iTextInstances.forEach(function(obj) {\n if (obj.isEditing) {\n obj.hiddenTextarea.focus();\n }\n });\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseenter\n */\n _onMouseEnter: function(e) {\n if (!this.findTarget(e)) {\n this.fire('mouse:over', { target: null, e: e });\n this._hoveredTarget = null;\n }\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js orientation change\n * @param {Event} [self] Inner Event object\n */\n _onOrientationChange: function(e, self) {\n this.__onOrientationChange && this.__onOrientationChange(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onShake: function(e, self) {\n this.__onShake && this.__onShake(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onLongPress: function(e, self) {\n this.__onLongPress && this.__onLongPress(e, self);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onContextMenu: function (e) {\n if (this.stopContextMenu) {\n e.stopPropagation();\n e.preventDefault();\n }\n return false;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDown: function (e) {\n this.__onMouseDown(e);\n\n addListener(fabric.document, 'touchend', this._onMouseUp, { passive: false });\n addListener(fabric.document, 'touchmove', this._onMouseMove, { passive: false });\n\n removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove);\n removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove);\n\n if (e.type === 'touchstart') {\n // Unbind mousedown to prevent double triggers from touch devices\n removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown);\n }\n else {\n addListener(fabric.document, 'mouseup', this._onMouseUp);\n addListener(fabric.document, 'mousemove', this._onMouseMove);\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUp: function (e) {\n this.__onMouseUp(e);\n\n removeListener(fabric.document, 'mouseup', this._onMouseUp);\n removeListener(fabric.document, 'touchend', this._onMouseUp);\n\n removeListener(fabric.document, 'mousemove', this._onMouseMove);\n removeListener(fabric.document, 'touchmove', this._onMouseMove);\n\n addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove);\n addListener(this.upperCanvasEl, 'touchmove', this._onMouseMove, { passive: false });\n\n if (e.type === 'touchend') {\n // Wait 400ms before rebinding mousedown to prevent double triggers\n // from touch devices\n var _this = this;\n setTimeout(function() {\n addListener(_this.upperCanvasEl, 'mousedown', _this._onMouseDown);\n }, 400);\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMove: function (e) {\n !this.allowTouchScrolling && e.preventDefault && e.preventDefault();\n this.__onMouseMove(e);\n },\n\n /**\n * @private\n */\n _onResize: function () {\n this.calcOffset();\n },\n\n /**\n * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n * @private\n * @param {Object} target\n * @param {Object} pointer\n */\n _shouldRender: function(target, pointer) {\n var activeObject = this.getActiveGroup() || this.getActiveObject();\n\n if (activeObject && activeObject.isEditing && target === activeObject) {\n // if we mouse up/down over a editing textbox a cursor change,\n // there is no need to re render\n return false;\n }\n return !!(\n (target && (\n target.isMoving ||\n target !== activeObject))\n ||\n (!target && !!activeObject)\n ||\n (!target && !activeObject && !this._groupSelector)\n ||\n (pointer &&\n this._previousPointer &&\n this.selection && (\n pointer.x !== this._previousPointer.x ||\n pointer.y !== this._previousPointer.y))\n );\n },\n\n /**\n * Method that defines the actions when mouse is released on canvas.\n * The method resets the currentTransform parameters, store the image corner\n * position in the image object and render the canvas on top.\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseUp: function (e) {\n\n var target;\n // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'up', target, RIGHT_CLICK);\n }\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'up', target, MIDDLE_CLICK);\n }\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n return;\n }\n\n var searchTarget = true, transform = this._currentTransform,\n groupSelector = this._groupSelector,\n isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0));\n\n if (transform) {\n this._finalizeCurrentTransform(e);\n searchTarget = !transform.actionPerformed;\n }\n\n target = searchTarget ? this.findTarget(e, true) : transform.target;\n\n var shouldRender = this._shouldRender(target, this.getPointer(e));\n\n if (target || !isClick) {\n this._maybeGroupObjects(e);\n }\n else {\n // those are done by default on mouse up\n // by _maybeGroupObjects, we are skipping it in case of no target find\n this._groupSelector = null;\n this._currentTransform = null;\n }\n\n if (target) {\n target.isMoving = false;\n }\n this._setCursorFromEvent(e, target);\n this._handleEvent(e, 'up', target ? target : null, LEFT_CLICK, isClick);\n target && (target.__corner = 0);\n shouldRender && this.renderAll();\n },\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {Event} e event from mouse\n * @param {String} eventType event to fire (up, down or move)\n * @param {fabric.Object} targetObj receiving event\n * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right\n * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move.\n */\n _handleEvent: function(e, eventType, targetObj, button, isClick) {\n var target = typeof targetObj === 'undefined' ? this.findTarget(e) : targetObj,\n targets = this.targets || [],\n options = {\n e: e,\n target: target,\n subTargets: targets,\n button: button || LEFT_CLICK,\n isClick: isClick || false\n };\n this.fire('mouse:' + eventType, options);\n target && target.fire('mouse' + eventType, options);\n for (var i = 0; i < targets.length; i++) {\n targets[i].fire('mouse' + eventType, options);\n }\n },\n\n /**\n * @private\n * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n */\n _finalizeCurrentTransform: function(e) {\n\n var transform = this._currentTransform,\n target = transform.target;\n\n if (target._scaling) {\n target._scaling = false;\n }\n\n target.setCoords();\n this._restoreOriginXY(target);\n\n if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {\n this.fire('object:modified', { target: target, e: e });\n target.fire('modified', { e: e });\n }\n },\n\n /**\n * @private\n * @param {Object} target Object to restore\n */\n _restoreOriginXY: function(target) {\n if (this._previousOriginX && this._previousOriginY) {\n\n var originPoint = target.translateToOriginPoint(\n target.getCenterPoint(),\n this._previousOriginX,\n this._previousOriginY);\n\n target.originX = this._previousOriginX;\n target.originY = this._previousOriginY;\n\n target.left = originPoint.x;\n target.top = originPoint.y;\n\n this._previousOriginX = null;\n this._previousOriginY = null;\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDownInDrawingMode: function(e) {\n this._isCurrentlyDrawing = true;\n this.discardActiveObject(e).renderAll();\n if (this.clipTo) {\n fabric.util.clipContext(this, this.contextTop);\n }\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseDown(pointer);\n this._handleEvent(e, 'down');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode: function(e) {\n if (this._isCurrentlyDrawing) {\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseMove(pointer);\n }\n this.setCursor(this.freeDrawingCursor);\n this._handleEvent(e, 'move');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode: function(e) {\n this._isCurrentlyDrawing = false;\n if (this.clipTo) {\n this.contextTop.restore();\n }\n this.freeDrawingBrush.onMouseUp();\n this._handleEvent(e, 'up');\n },\n\n /**\n * Method that defines the actions when mouse is clicked on canvas.\n * The method inits the currentTransform parameters and renders all the\n * canvas so the current image can be placed on the top canvas and the rest\n * in on the container one.\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n __onMouseDown: function (e) {\n\n var target = this.findTarget(e);\n\n // if right click just fire events\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'down', target ? target : null, RIGHT_CLICK);\n }\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'down', target ? target : null, MIDDLE_CLICK);\n }\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n return;\n }\n\n // ignore if some object is being transformed at this moment\n if (this._currentTransform) {\n return;\n }\n\n // save pointer for check in __onMouseUp event\n var pointer = this.getPointer(e, true);\n this._previousPointer = pointer;\n\n var shouldRender = this._shouldRender(target, pointer),\n shouldGroup = this._shouldGroup(e, target);\n\n if (this._shouldClearSelection(e, target)) {\n this.deactivateAllWithDispatch(e);\n }\n else if (shouldGroup) {\n this._handleGrouping(e, target);\n target = this.getActiveGroup();\n }\n\n if (this.selection && (!target || (!target.selectable && !target.isEditing))) {\n this._groupSelector = {\n ex: pointer.x,\n ey: pointer.y,\n top: 0,\n left: 0\n };\n }\n\n if (target) {\n if (target.selectable && (target.__corner || !shouldGroup)) {\n this._beforeTransform(e, target);\n this._setupCurrentTransform(e, target);\n }\n var activeObject = this.getActiveObject();\n if (target !== this.getActiveGroup() && target !== activeObject) {\n this.deactivateAll();\n if (target.selectable) {\n activeObject && activeObject.fire('deselected', { e: e });\n this.setActiveObject(target, e);\n }\n }\n }\n this._handleEvent(e, 'down', target ? target : null);\n // we must renderAll so that we update the visuals\n shouldRender && this.renderAll();\n },\n\n /**\n * @private\n */\n _beforeTransform: function(e, target) {\n this.stateful && target.saveState();\n\n // determine if it's a drag or rotate case\n if (target._findTargetCorner(this.getPointer(e))) {\n this.onBeforeScaleRotate(target);\n }\n\n },\n\n /**\n * @private\n * @param {Object} target Object for that origin is set to center\n */\n _setOriginToCenter: function(target) {\n this._previousOriginX = this._currentTransform.target.originX;\n this._previousOriginY = this._currentTransform.target.originY;\n\n var center = target.getCenterPoint();\n\n target.originX = 'center';\n target.originY = 'center';\n\n target.left = center.x;\n target.top = center.y;\n\n this._currentTransform.left = target.left;\n this._currentTransform.top = target.top;\n },\n\n /**\n * @private\n * @param {Object} target Object for that center is set to origin\n */\n _setCenterToOrigin: function(target) {\n var originPoint = target.translateToOriginPoint(\n target.getCenterPoint(),\n this._previousOriginX,\n this._previousOriginY);\n\n target.originX = this._previousOriginX;\n target.originY = this._previousOriginY;\n\n target.left = originPoint.x;\n target.top = originPoint.y;\n\n this._previousOriginX = null;\n this._previousOriginY = null;\n },\n\n /**\n * Method that defines the actions when mouse is hovering the canvas.\n * The currentTransform parameter will definde whether the user is rotating/scaling/translating\n * an image or neither of them (only hovering). A group selection is also possible and would cancel\n * all any other type of action.\n * In case of an image transformation only the top canvas will be rendered.\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n __onMouseMove: function (e) {\n\n var target, pointer;\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n return;\n }\n if (typeof e.touches !== 'undefined' && e.touches.length > 1) {\n return;\n }\n\n var groupSelector = this._groupSelector;\n\n // We initially clicked in an empty area, so we draw a box for multiple selection\n if (groupSelector) {\n pointer = this.getPointer(e, true);\n\n groupSelector.left = pointer.x - groupSelector.ex;\n groupSelector.top = pointer.y - groupSelector.ey;\n\n this.renderTop();\n }\n else if (!this._currentTransform) {\n target = this.findTarget(e);\n this._setCursorFromEvent(e, target);\n }\n else {\n this._transformObject(e);\n }\n this._handleEvent(e, 'move', target ? target : null);\n },\n\n /**\n * Method that defines actions when an Event Mouse Wheel\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseWheel: function(e) {\n this._handleEvent(e, 'wheel');\n },\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject: function(e) {\n var pointer = this.getPointer(e),\n transform = this._currentTransform;\n\n transform.reset = false;\n transform.target.isMoving = true;\n transform.shiftKey = e.shiftKey;\n transform.altKey = e[this.centeredKey];\n\n this._beforeScaleTransform(e, transform);\n this._performTransformAction(e, transform, pointer);\n\n transform.actionPerformed && this.renderAll();\n },\n\n /**\n * @private\n */\n _performTransformAction: function(e, transform, pointer) {\n var x = pointer.x,\n y = pointer.y,\n target = transform.target,\n action = transform.action,\n actionPerformed = false;\n\n if (action === 'rotate') {\n (actionPerformed = this._rotateObject(x, y)) && this._fire('rotating', target, e);\n }\n else if (action === 'scale') {\n (actionPerformed = this._onScale(e, transform, x, y)) && this._fire('scaling', target, e);\n }\n else if (action === 'scaleX') {\n (actionPerformed = this._scaleObject(x, y, 'x')) && this._fire('scaling', target, e);\n }\n else if (action === 'scaleY') {\n (actionPerformed = this._scaleObject(x, y, 'y')) && this._fire('scaling', target, e);\n }\n else if (action === 'skewX') {\n (actionPerformed = this._skewObject(x, y, 'x')) && this._fire('skewing', target, e);\n }\n else if (action === 'skewY') {\n (actionPerformed = this._skewObject(x, y, 'y')) && this._fire('skewing', target, e);\n }\n else {\n actionPerformed = this._translateObject(x, y);\n if (actionPerformed) {\n this._fire('moving', target, e);\n this.setCursor(target.moveCursor || this.moveCursor);\n }\n }\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n },\n\n /**\n * @private\n */\n _fire: function(eventName, target, e) {\n this.fire('object:' + eventName, { target: target, e: e });\n target.fire(eventName, { e: e });\n },\n\n /**\n * @private\n */\n _beforeScaleTransform: function(e, transform) {\n if (transform.action === 'scale' || transform.action === 'scaleX' || transform.action === 'scaleY') {\n var centerTransform = this._shouldCenterTransform(transform.target);\n\n // Switch from a normal resize to center-based\n if ((centerTransform && (transform.originX !== 'center' || transform.originY !== 'center')) ||\n // Switch from center-based resize to normal one\n (!centerTransform && transform.originX === 'center' && transform.originY === 'center')\n ) {\n this._resetCurrentTransform();\n transform.reset = true;\n }\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {Object} transform current tranform\n * @param {Number} x mouse position x from origin\n * @param {Number} y mouse poistion y from origin\n * @return {Boolean} true if the scaling occurred\n */\n _onScale: function(e, transform, x, y) {\n if ((e[this.uniScaleKey] || this.uniScaleTransform) && !transform.target.get('lockUniScaling')) {\n transform.currentAction = 'scale';\n return this._scaleObject(x, y);\n }\n else {\n // Switch from a normal resize to proportional\n if (!transform.reset && transform.currentAction === 'scale') {\n this._resetCurrentTransform();\n }\n\n transform.currentAction = 'scaleEqually';\n return this._scaleObject(x, y, 'equally');\n }\n },\n\n /**\n * Sets the cursor depending on where the canvas is being hovered.\n * Note: very buggy in Opera\n * @param {Event} e Event object\n * @param {Object} target Object that the mouse is hovering, if so.\n */\n _setCursorFromEvent: function (e, target) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return false;\n }\n\n var hoverCursor = target.hoverCursor || this.hoverCursor,\n activeGroup = this.getActiveGroup(),\n // only show proper corner when group selection is not active\n corner = target._findTargetCorner\n && (!activeGroup || !activeGroup.contains(target))\n && target._findTargetCorner(this.getPointer(e, true));\n\n if (!corner) {\n this.setCursor(hoverCursor);\n }\n else {\n this._setCornerCursor(corner, target, e);\n }\n //actually unclear why it should return something\n //is never evaluated\n return true;\n },\n\n /**\n * @private\n */\n _setCornerCursor: function(corner, target, e) {\n if (corner in cursorOffset) {\n this.setCursor(this._getRotatedCornerCursor(corner, target, e));\n }\n else if (corner === 'mtr' && target.hasRotatingPoint) {\n this.setCursor(this.rotationCursor);\n }\n else {\n this.setCursor(this.defaultCursor);\n return false;\n }\n },\n\n /**\n * @private\n */\n _getRotatedCornerCursor: function(corner, target, e) {\n var n = Math.round((target.getAngle() % 360) / 45);\n\n if (n < 0) {\n n += 8; // full circle ahead\n }\n n += cursorOffset[corner];\n if (e[this.altActionKey] && cursorOffset[corner] % 2 === 0) {\n //if we are holding shift and we are on a mx corner...\n n += 2;\n }\n // normalize n to be from 0 to 7\n n %= 8;\n\n return this.cursorMap[n];\n }\n });\n})();\n\n\n(function() {\n\n var min = Math.min,\n max = Math.max;\n\n fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n * @return {Boolean}\n */\n _shouldGroup: function(e, target) {\n var activeObject = this.getActiveObject();\n return e[this.selectionKey] && target && target.selectable &&\n (this.getActiveGroup() || (activeObject && activeObject !== target))\n && this.selection;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _handleGrouping: function (e, target) {\n var activeGroup = this.getActiveGroup();\n\n if (target === activeGroup) {\n // if it's a group, find target again, using activeGroup objects\n target = this.findTarget(e, true);\n // if even object is not found, bail out\n if (!target) {\n return;\n }\n }\n if (activeGroup) {\n this._updateActiveGroup(target, e);\n }\n else {\n this._createActiveGroup(target, e);\n }\n\n if (this._activeGroup) {\n this._activeGroup.saveCoords();\n }\n },\n\n /**\n * @private\n */\n _updateActiveGroup: function(target, e) {\n var activeGroup = this.getActiveGroup();\n\n if (activeGroup.contains(target)) {\n\n activeGroup.removeWithUpdate(target);\n target.set('active', false);\n\n if (activeGroup.size() === 1) {\n // remove group alltogether if after removal it only contains 1 object\n this.discardActiveGroup(e);\n // activate last remaining object\n this.setActiveObject(activeGroup.item(0), e);\n return;\n }\n }\n else {\n activeGroup.addWithUpdate(target);\n }\n this.fire('selection:created', { target: activeGroup, e: e });\n activeGroup.set('active', true);\n },\n\n /**\n * @private\n */\n _createActiveGroup: function(target, e) {\n\n if (this._activeObject && target !== this._activeObject) {\n\n var group = this._createGroup(target);\n group.addWithUpdate();\n\n this.setActiveGroup(group, e);\n this._activeObject = null;\n\n this.fire('selection:created', { target: group, e: e });\n }\n\n target.set('active', true);\n },\n\n /**\n * @private\n * @param {Object} target\n */\n _createGroup: function(target) {\n\n var objects = this.getObjects(),\n isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),\n groupObjects = isActiveLower\n ? [this._activeObject, target]\n : [target, this._activeObject];\n this._activeObject.isEditing && this._activeObject.exitEditing();\n return new fabric.Group(groupObjects, {\n canvas: this\n });\n },\n\n /**\n * @private\n * @param {Event} e mouse event\n */\n _groupSelectedObjects: function (e) {\n\n var group = this._collectObjects();\n\n // do not create group for 1 element only\n if (group.length === 1) {\n this.setActiveObject(group[0], e);\n }\n else if (group.length > 1) {\n group = new fabric.Group(group.reverse(), {\n canvas: this\n });\n group.addWithUpdate();\n this.setActiveGroup(group, e);\n group.saveCoords();\n this.fire('selection:created', { target: group, e: e });\n this.renderAll();\n }\n },\n\n /**\n * @private\n */\n _collectObjects: function() {\n var group = [],\n currentObject,\n x1 = this._groupSelector.ex,\n y1 = this._groupSelector.ey,\n x2 = x1 + this._groupSelector.left,\n y2 = y1 + this._groupSelector.top,\n selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),\n selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),\n isClick = x1 === x2 && y1 === y2;\n\n for (var i = this._objects.length; i--; ) {\n currentObject = this._objects[i];\n\n if (!currentObject || !currentObject.selectable || !currentObject.visible) {\n continue;\n }\n\n if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) ||\n currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) ||\n currentObject.containsPoint(selectionX1Y1) ||\n currentObject.containsPoint(selectionX2Y2)\n ) {\n currentObject.set('active', true);\n group.push(currentObject);\n\n // only add one object if it's a click\n if (isClick) {\n break;\n }\n }\n }\n\n return group;\n },\n\n /**\n * @private\n */\n _maybeGroupObjects: function(e) {\n if (this.selection && this._groupSelector) {\n this._groupSelectedObjects(e);\n }\n\n var activeGroup = this.getActiveGroup();\n if (activeGroup) {\n activeGroup.setObjectsCoords().setCoords();\n activeGroup.isMoving = false;\n this.setCursor(this.defaultCursor);\n }\n\n // clear selection and current transformation\n this._groupSelector = null;\n this._currentTransform = null;\n }\n });\n\n})();\n\n\n(function () {\n\n var supportQuality = fabric.StaticCanvas.supports('toDataURLWithQuality');\n\n fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n * @param {Object} [options] Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo}\n * @example Generate jpeg dataURL with lower quality\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example Generate cropped png dataURL (clipping of canvas)\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example Generate double scaled png dataURL\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n */\n toDataURL: function (options) {\n options || (options = { });\n\n var format = options.format || 'png',\n quality = options.quality || 1,\n multiplier = options.multiplier || 1,\n cropping = {\n left: options.left || 0,\n top: options.top || 0,\n width: options.width || 0,\n height: options.height || 0,\n };\n return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier);\n },\n\n /**\n * @private\n */\n __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) {\n\n var origWidth = this.getWidth(),\n origHeight = this.getHeight(),\n scaledWidth = (cropping.width || this.getWidth()) * multiplier,\n scaledHeight = (cropping.height || this.getHeight()) * multiplier,\n zoom = this.getZoom(),\n newZoom = zoom * multiplier,\n vp = this.viewportTransform,\n translateX = (vp[4] - cropping.left) * multiplier,\n translateY = (vp[5] - cropping.top) * multiplier,\n newVp = [newZoom, 0, 0, newZoom, translateX, translateY],\n originalInteractive = this.interactive;\n\n this.viewportTransform = newVp;\n // setting interactive to false avoid exporting controls\n this.interactive && (this.interactive = false);\n if (origWidth !== scaledWidth || origHeight !== scaledHeight) {\n // this.setDimensions is going to renderAll also;\n this.setDimensions({ width: scaledWidth, height: scaledHeight }, { backstoreOnly: true });\n }\n else {\n this.renderAll();\n }\n var data = this.__toDataURL(format, quality, cropping);\n originalInteractive && (this.interactive = originalInteractive);\n this.viewportTransform = vp;\n //setDimensions with no option object is taking care of:\n //this.width, this.height, this.renderAll()\n this.setDimensions({ width: origWidth, height: origHeight }, { backstoreOnly: true });\n return data;\n },\n\n /**\n * @private\n */\n __toDataURL: function(format, quality) {\n\n var canvasEl = this.contextContainer.canvas;\n // to avoid common confusion https://github.com/kangax/fabric.js/issues/806\n if (format === 'jpg') {\n format = 'jpeg';\n }\n\n var data = supportQuality\n ? canvasEl.toDataURL('image/' + format, quality)\n : canvasEl.toDataURL('image/' + format);\n\n return data;\n },\n\n /**\n * Exports canvas element to a dataurl image (allowing to change image size via multiplier).\n * @deprecated since 1.0.13\n * @param {String} format (png|jpeg)\n * @param {Number} multiplier\n * @param {Number} quality (0..1)\n * @return {String}\n */\n toDataURLWithMultiplier: function (format, multiplier, quality) {\n return this.toDataURL({\n format: format,\n multiplier: multiplier,\n quality: quality\n });\n },\n });\n\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Populates canvas with data from the specified dataless JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toDatalessJSON}\n * @deprecated since 1.2.2\n * @param {String|Object} json JSON string or object\n * @param {Function} callback Callback, invoked when json is parsed\n * and corresponding objects (e.g: {@link fabric.Image})\n * are initialized\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @return {fabric.Canvas} instance\n * @chainable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n */\n loadFromDatalessJSON: function (json, callback, reviver) {\n return this.loadFromJSON(json, callback, reviver);\n },\n\n /**\n * Populates canvas with data from the specified JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n * @param {String|Object} json JSON string or object\n * @param {Function} callback Callback, invoked when json is parsed\n * and corresponding objects (e.g: {@link fabric.Image})\n * are initialized\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @return {fabric.Canvas} instance\n * @chainable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n * @example loadFromJSON\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));\n * @example loadFromJSON with reviver\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) {\n * // `o` = json object\n * // `object` = fabric.Object instance\n * // ... do some stuff ...\n * });\n */\n loadFromJSON: function (json, callback, reviver) {\n if (!json) {\n return;\n }\n\n // serialize if it wasn't already\n var serialized = (typeof json === 'string')\n ? JSON.parse(json)\n : fabric.util.object.clone(json);\n\n var _this = this,\n renderOnAddRemove = this.renderOnAddRemove;\n this.renderOnAddRemove = false;\n\n this._enlivenObjects(serialized.objects, function (enlivenedObjects) {\n _this.clear();\n _this._setBgOverlay(serialized, function () {\n enlivenedObjects.forEach(function(obj, index) {\n // we splice the array just in case some custom classes restored from JSON\n // will add more object to canvas at canvas init.\n _this.insertAt(obj, index);\n });\n _this.renderOnAddRemove = renderOnAddRemove;\n // remove parts i cannot set as options\n delete serialized.objects;\n delete serialized.backgroundImage;\n delete serialized.overlayImage;\n delete serialized.background;\n delete serialized.overlay;\n // this._initOptions does too many things to just\n // call it. Normally loading an Object from JSON\n // create the Object instance. Here the Canvas is\n // already an instance and we are just loading things over it\n _this._setOptions(serialized);\n _this.renderAll();\n callback && callback();\n });\n }, reviver);\n return this;\n },\n\n /**\n * @private\n * @param {Object} serialized Object with background and overlay information\n * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n */\n _setBgOverlay: function(serialized, callback) {\n var loaded = {\n backgroundColor: false,\n overlayColor: false,\n backgroundImage: false,\n overlayImage: false\n };\n\n if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) {\n callback && callback();\n return;\n }\n\n var cbIfLoaded = function () {\n if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) {\n callback && callback();\n }\n };\n\n this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded);\n this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded);\n this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded);\n this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded);\n },\n\n /**\n * @private\n * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor)\n * @param {(Object|String)} value Value to set\n * @param {Object} loaded Set loaded property to true if property is set\n * @param {Object} callback Callback function to invoke after property is set\n */\n __setBgOverlay: function(property, value, loaded, callback) {\n var _this = this;\n\n if (!value) {\n loaded[property] = true;\n callback && callback();\n return;\n }\n\n if (property === 'backgroundImage' || property === 'overlayImage') {\n fabric.util.enlivenObjects([value], function(enlivedObject){\n _this[property] = enlivedObject[0];\n loaded[property] = true;\n callback && callback();\n });\n }\n else {\n this['set' + fabric.util.string.capitalize(property, true)](value, function() {\n loaded[property] = true;\n callback && callback();\n });\n }\n },\n\n /**\n * @private\n * @param {Array} objects\n * @param {Function} callback\n * @param {Function} [reviver]\n */\n _enlivenObjects: function (objects, callback, reviver) {\n if (!objects || objects.length === 0) {\n callback && callback([]);\n return;\n }\n\n fabric.util.enlivenObjects(objects, function(enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, null, reviver);\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Function} callback\n */\n _toDataURL: function (format, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURL(format));\n });\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Number} multiplier\n * @param {Function} callback\n */\n _toDataURLWithMultiplier: function (format, multiplier, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURLWithMultiplier(format, multiplier));\n });\n },\n\n /**\n * Clones canvas instance\n * @param {Object} [callback] Receives cloned instance as a first argument\n * @param {Array} [properties] Array of properties to include in the cloned canvas and children\n */\n clone: function (callback, properties) {\n var data = JSON.stringify(this.toJSON(properties));\n this.cloneWithoutData(function(clone) {\n clone.loadFromJSON(data, function() {\n callback && callback(clone);\n });\n });\n },\n\n /**\n * Clones canvas instance without cloning existing data.\n * This essentially copies canvas dimensions, clipping properties, etc.\n * but leaves data empty (so that you can populate it with your own)\n * @param {Object} [callback] Receives cloned instance as a first argument\n */\n cloneWithoutData: function(callback) {\n var el = fabric.document.createElement('canvas');\n\n el.width = this.getWidth();\n el.height = this.getHeight();\n\n var clone = new fabric.Canvas(el);\n clone.clipTo = this.clipTo;\n if (this.backgroundImage) {\n clone.setBackgroundImage(this.backgroundImage.src, function() {\n clone.renderAll();\n callback && callback(clone);\n });\n clone.backgroundImageOpacity = this.backgroundImageOpacity;\n clone.backgroundImageStretch = this.backgroundImageStretch;\n }\n else {\n callback && callback(clone);\n }\n }\n});\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n capitalize = fabric.util.string.capitalize,\n degreesToRadians = fabric.util.degreesToRadians,\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash'),\n objectCaching = !fabric.isLikelyNode,\n ALIASING_LIMIT = 2;\n\n if (fabric.Object) {\n return;\n }\n\n /**\n * Root object class from which all 2d shape classes inherit from\n * @class fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n * @see {@link fabric.Object#initialize} for constructor definition\n *\n * @fires added\n * @fires removed\n *\n * @fires selected\n * @fires deselected\n * @fires modified\n * @fires rotating\n * @fires scaling\n * @fires moving\n * @fires skewing\n *\n * @fires mousedown\n * @fires mouseup\n * @fires mouseover\n * @fires mouseout\n * @fires mousewheel\n */\n fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ {\n\n /**\n * Retrieves object's {@link fabric.Object#clipTo|clipping function}\n * @method getClipTo\n * @memberOf fabric.Object.prototype\n * @return {Function}\n */\n\n /**\n * Sets object's {@link fabric.Object#clipTo|clipping function}\n * @method setClipTo\n * @memberOf fabric.Object.prototype\n * @param {Function} clipTo Clipping function\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#transformMatrix|transformMatrix}\n * @method getTransformMatrix\n * @memberOf fabric.Object.prototype\n * @return {Array} transformMatrix\n */\n\n /**\n * Sets object's {@link fabric.Object#transformMatrix|transformMatrix}\n * @method setTransformMatrix\n * @memberOf fabric.Object.prototype\n * @param {Array} transformMatrix\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#visible|visible} state\n * @method getVisible\n * @memberOf fabric.Object.prototype\n * @return {Boolean} True if visible\n */\n\n /**\n * Sets object's {@link fabric.Object#visible|visible} state\n * @method setVisible\n * @memberOf fabric.Object.prototype\n * @param {Boolean} value visible value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#shadow|shadow}\n * @method getShadow\n * @memberOf fabric.Object.prototype\n * @return {Object} Shadow instance\n */\n\n /**\n * Retrieves object's {@link fabric.Object#stroke|stroke}\n * @method getStroke\n * @memberOf fabric.Object.prototype\n * @return {String} stroke value\n */\n\n /**\n * Sets object's {@link fabric.Object#stroke|stroke}\n * @method setStroke\n * @memberOf fabric.Object.prototype\n * @param {String} value stroke value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#strokeWidth|strokeWidth}\n * @method getStrokeWidth\n * @memberOf fabric.Object.prototype\n * @return {Number} strokeWidth value\n */\n\n /**\n * Sets object's {@link fabric.Object#strokeWidth|strokeWidth}\n * @method setStrokeWidth\n * @memberOf fabric.Object.prototype\n * @param {Number} value strokeWidth value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#originX|originX}\n * @method getOriginX\n * @memberOf fabric.Object.prototype\n * @return {String} originX value\n */\n\n /**\n * Sets object's {@link fabric.Object#originX|originX}\n * @method setOriginX\n * @memberOf fabric.Object.prototype\n * @param {String} value originX value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#originY|originY}\n * @method getOriginY\n * @memberOf fabric.Object.prototype\n * @return {String} originY value\n */\n\n /**\n * Sets object's {@link fabric.Object#originY|originY}\n * @method setOriginY\n * @memberOf fabric.Object.prototype\n * @param {String} value originY value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#fill|fill}\n * @method getFill\n * @memberOf fabric.Object.prototype\n * @return {String} Fill value\n */\n\n /**\n * Sets object's {@link fabric.Object#fill|fill}\n * @method setFill\n * @memberOf fabric.Object.prototype\n * @param {String} value Fill value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#opacity|opacity}\n * @method getOpacity\n * @memberOf fabric.Object.prototype\n * @return {Number} Opacity value (0-1)\n */\n\n /**\n * Sets object's {@link fabric.Object#opacity|opacity}\n * @method setOpacity\n * @memberOf fabric.Object.prototype\n * @param {Number} value Opacity value (0-1)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#angle|angle} (in degrees)\n * @method getAngle\n * @memberOf fabric.Object.prototype\n * @return {Number}\n */\n\n /**\n * Retrieves object's {@link fabric.Object#top|top position}\n * @method getTop\n * @memberOf fabric.Object.prototype\n * @return {Number} Top value (in pixels)\n */\n\n /**\n * Sets object's {@link fabric.Object#top|top position}\n * @method setTop\n * @memberOf fabric.Object.prototype\n * @param {Number} value Top value (in pixels)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#left|left position}\n * @method getLeft\n * @memberOf fabric.Object.prototype\n * @return {Number} Left value (in pixels)\n */\n\n /**\n * Sets object's {@link fabric.Object#left|left position}\n * @method setLeft\n * @memberOf fabric.Object.prototype\n * @param {Number} value Left value (in pixels)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#scaleX|scaleX} value\n * @method getScaleX\n * @memberOf fabric.Object.prototype\n * @return {Number} scaleX value\n */\n\n /**\n * Sets object's {@link fabric.Object#scaleX|scaleX} value\n * @method setScaleX\n * @memberOf fabric.Object.prototype\n * @param {Number} value scaleX value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#scaleY|scaleY} value\n * @method getScaleY\n * @memberOf fabric.Object.prototype\n * @return {Number} scaleY value\n */\n\n /**\n * Sets object's {@link fabric.Object#scaleY|scaleY} value\n * @method setScaleY\n * @memberOf fabric.Object.prototype\n * @param {Number} value scaleY value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#flipX|flipX} value\n * @method getFlipX\n * @memberOf fabric.Object.prototype\n * @return {Boolean} flipX value\n */\n\n /**\n * Sets object's {@link fabric.Object#flipX|flipX} value\n * @method setFlipX\n * @memberOf fabric.Object.prototype\n * @param {Boolean} value flipX value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Retrieves object's {@link fabric.Object#flipY|flipY} value\n * @method getFlipY\n * @memberOf fabric.Object.prototype\n * @return {Boolean} flipY value\n */\n\n /**\n * Sets object's {@link fabric.Object#flipY|flipY} value\n * @method setFlipY\n * @memberOf fabric.Object.prototype\n * @param {Boolean} value flipY value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n\n /**\n * Type of an object (rect, circle, path, etc.).\n * Note that this property is meant to be read-only and not meant to be modified.\n * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly.\n * @type String\n * @default\n */\n type: 'object',\n\n /**\n * Horizontal origin of transformation of an object (one of \"left\", \"right\", \"center\")\n * See http://jsfiddle.net/1ow02gea/40/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originX: 'left',\n\n /**\n * Vertical origin of transformation of an object (one of \"top\", \"bottom\", \"center\")\n * See http://jsfiddle.net/1ow02gea/40/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originY: 'top',\n\n /**\n * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom}\n * @type Number\n * @default\n */\n top: 0,\n\n /**\n * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right}\n * @type Number\n * @default\n */\n left: 0,\n\n /**\n * Object width\n * @type Number\n * @default\n */\n width: 0,\n\n /**\n * Object height\n * @type Number\n * @default\n */\n height: 0,\n\n /**\n * Object scale factor (horizontal)\n * @type Number\n * @default\n */\n scaleX: 1,\n\n /**\n * Object scale factor (vertical)\n * @type Number\n * @default\n */\n scaleY: 1,\n\n /**\n * When true, an object is rendered as flipped horizontally\n * @type Boolean\n * @default\n */\n flipX: false,\n\n /**\n * When true, an object is rendered as flipped vertically\n * @type Boolean\n * @default\n */\n flipY: false,\n\n /**\n * Opacity of an object\n * @type Number\n * @default\n */\n opacity: 1,\n\n /**\n * Angle of rotation of an object (in degrees)\n * @type Number\n * @default\n */\n angle: 0,\n\n /**\n * Angle of skew on x axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewX: 0,\n\n /**\n * Angle of skew on y axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewY: 0,\n\n /**\n * Size of object's controlling corners (in pixels)\n * @type Number\n * @default\n */\n cornerSize: 13,\n\n /**\n * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill)\n * @type Boolean\n * @default\n */\n transparentCorners: true,\n\n /**\n * Default cursor value used when hovering over this object on canvas\n * @type String\n * @default\n */\n hoverCursor: null,\n\n /**\n * Default cursor value used when moving this object on canvas\n * @type String\n * @default\n */\n moveCursor: null,\n\n /**\n * Padding between object and its controlling borders (in pixels)\n * @type Number\n * @default\n */\n padding: 0,\n\n /**\n * Color of controlling borders of an object (when it's active)\n * @type String\n * @default\n */\n borderColor: 'rgba(102,153,255,0.75)',\n\n /**\n * Array specifying dash pattern of an object's borders (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n borderDashArray: null,\n\n /**\n * Color of controlling corners of an object (when it's active)\n * @type String\n * @default\n */\n cornerColor: 'rgba(102,153,255,0.5)',\n\n /**\n * Color of controlling corners of an object (when it's active and transparentCorners false)\n * @since 1.6.2\n * @type String\n * @default\n */\n cornerStrokeColor: null,\n\n /**\n * Specify style of control, 'rect' or 'circle'\n * @since 1.6.2\n * @type String\n */\n cornerStyle: 'rect',\n\n /**\n * Array specifying dash pattern of an object's control (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n cornerDashArray: null,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being scaled via the controls.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being rotated via the controls.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: true,\n\n /**\n * Color of object's fill\n * @type String\n * @default\n */\n fill: 'rgb(0,0,0)',\n\n /**\n * Fill rule used to fill an object\n * accepted values are nonzero, evenodd\n * Backwards incompatibility note: This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead)\n * @type String\n * @default\n */\n fillRule: 'nonzero',\n\n /**\n * Composite rule used for canvas globalCompositeOperation\n * @type String\n * @default\n */\n globalCompositeOperation: 'source-over',\n\n /**\n * Background color of an object.\n * @type String\n * @default\n */\n backgroundColor: '',\n\n /**\n * Selection Background color of an object. colored layer behind the object when it is active.\n * does not mix good with globalCompositeOperation methods.\n * @type String\n * @default\n */\n selectionBackgroundColor: '',\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Width of a stroke used to render this object\n * @type Number\n * @default\n */\n strokeWidth: 1,\n\n /**\n * Array specifying dash pattern of an object's stroke (stroke must be defined)\n * @type Array\n */\n strokeDashArray: null,\n\n /**\n * Line endings style of an object's stroke (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'butt',\n\n /**\n * Corner style of an object's stroke (one of \"bevil\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'miter',\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of an object's stroke\n * @type Number\n * @default\n */\n strokeMiterLimit: 10,\n\n /**\n * Shadow object representing shadow of this shape\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Opacity of object's controlling borders when object is active and moving\n * @type Number\n * @default\n */\n borderOpacityWhenMoving: 0.4,\n\n /**\n * Scale factor of object's controlling borders\n * @type Number\n * @default\n */\n borderScaleFactor: 1,\n\n /**\n * Transform matrix (similar to SVG's transform matrix)\n * @type Array\n */\n transformMatrix: null,\n\n /**\n * Minimum allowed scale value of an object\n * @type Number\n * @default\n */\n minScaleLimit: 0.01,\n\n /**\n * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection).\n * But events still fire on it.\n * @type Boolean\n * @default\n */\n selectable: true,\n\n /**\n * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4\n * @type Boolean\n * @default\n */\n evented: true,\n\n /**\n * When set to `false`, an object is not rendered on canvas\n * @type Boolean\n * @default\n */\n visible: true,\n\n /**\n * When set to `false`, object's controls are not displayed and can not be used to manipulate object\n * @type Boolean\n * @default\n */\n hasControls: true,\n\n /**\n * When set to `false`, object's controlling borders are not rendered\n * @type Boolean\n * @default\n */\n hasBorders: true,\n\n /**\n * When set to `false`, object's controlling rotating point will not be visible or selectable\n * @type Boolean\n * @default\n */\n hasRotatingPoint: true,\n\n /**\n * Offset for object's controlling rotating point (when enabled via `hasRotatingPoint`)\n * @type Number\n * @default\n */\n rotatingPointOffset: 40,\n\n /**\n * When set to `true`, objects are \"found\" on canvas on per-pixel basis rather than according to bounding box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * When `false`, default object's values are not included in its serialization\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * Function that determines clipping of an object (context is passed as a first argument)\n * Note that context origin is at the object's center point (not left/top corner)\n * @type Function\n */\n clipTo: null,\n\n /**\n * When `true`, object horizontal movement is locked\n * @type Boolean\n * @default\n */\n lockMovementX: false,\n\n /**\n * When `true`, object vertical movement is locked\n * @type Boolean\n * @default\n */\n lockMovementY: false,\n\n /**\n * When `true`, object rotation is locked\n * @type Boolean\n * @default\n */\n lockRotation: false,\n\n /**\n * When `true`, object horizontal scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingX: false,\n\n /**\n * When `true`, object vertical scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingY: false,\n\n /**\n * When `true`, object non-uniform scaling is locked\n * @type Boolean\n * @default\n */\n lockUniScaling: false,\n\n /**\n * When `true`, object horizontal skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingX: false,\n\n /**\n * When `true`, object vertical skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingY: false,\n\n /**\n * When `true`, object cannot be flipped by scaling into negative values\n * @type Boolean\n * @default\n */\n lockScalingFlip: false,\n\n /**\n * When `true`, object is not exported in SVG or OBJECT/JSON\n * since 1.6.3\n * @type Boolean\n * @default\n */\n excludeFromExport: false,\n\n /**\n * When `true`, object is cached on an additional canvas.\n * default to true\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n objectCaching: objectCaching,\n\n /**\n * When `true`, object properties are checked for cache invalidation. In some particular\n * situation you may want this to be disabled ( spray brush, very big pathgroups, groups)\n * or if your application does not allow you to modify properties for groups child you want\n * to disable it for groups.\n * default to false\n * since 1.7.0\n * @type Boolean\n * @default false\n */\n statefullCache: false,\n\n /**\n * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled\n * too much and will be redrawn with correct details at the end of scaling.\n * this setting is performance and application dependant.\n * default to true\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n noScaleCache: true,\n\n /**\n * When set to `true`, object's cache will be rerendered next render call.\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n dirty: true,\n\n /**\n * List of properties to consider when checking if state\n * of an object is changed (fabric.Object#hasStateChanged)\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: (\n 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' +\n 'stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit ' +\n 'angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor ' +\n 'skewX skewY fillRule'\n ).split(' '),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * @type Array\n */\n cacheProperties: (\n 'fill stroke strokeWidth strokeDashArray width height' +\n ' strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor'\n ).split(' '),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n options = options || { };\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Create a the canvas used to keep the cached copy of the object\n * @private\n */\n _createCacheCanvas: function() {\n this._cacheProperties = {};\n this._cacheCanvas = fabric.document.createElement('canvas');\n this._cacheContext = this._cacheCanvas.getContext('2d');\n this._updateCacheCanvas();\n },\n\n /**\n * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal\n * and each side do not cross fabric.cacheSideLimit\n * those numbers are configurable so that you can get as much detail as you want\n * making bargain with performances.\n * @param {Object} dims\n * @param {Object} dims.width width of canvas\n * @param {Object} dims.height height of canvas\n * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _limitCacheSize: function(dims) {\n var perfLimitSizeTotal = fabric.perfLimitSizeTotal,\n width = dims.width, height = dims.height,\n max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit;\n if (width <= max && height <= max && width * height <= perfLimitSizeTotal) {\n if (width < min) {\n dims.width = min;\n }\n if (height < min) {\n dims.height = min;\n }\n return dims;\n }\n var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal),\n capValue = fabric.util.capValue,\n x = capValue(min, limitedDims.x, max),\n y = capValue(min, limitedDims.y, max);\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\n return dims;\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function() {\n var zoom = this.canvas && this.canvas.getZoom() || 1,\n objectScale = this.getObjectScaling(),\n retina = this.canvas && this.canvas._isRetinaScaling() ? fabric.devicePixelRatio : 1,\n dim = this._getNonTransformedDimensions(),\n zoomX = objectScale.scaleX * zoom * retina,\n zoomY = objectScale.scaleY * zoom * retina,\n width = dim.x * zoomX,\n height = dim.y * zoomY;\n return {\n width: width + ALIASING_LIMIT,\n height: height + ALIASING_LIMIT,\n zoomX: zoomX,\n zoomY: zoomY,\n x: dim.x,\n y: dim.y\n };\n },\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas: function() {\n if (this.noScaleCache && this.canvas && this.canvas._currentTransform) {\n var target = this.canvas._currentTransform.target,\n action = this.canvas._currentTransform.action;\n if (this === target && action.slice && action.slice(0, 5) === 'scale') {\n return false;\n }\n }\n var canvas = this._cacheCanvas,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = fabric.minCacheSideLimit,\n width = dims.width, height = dims.height, drawingWidth, drawingHeight,\n zoomX = dims.zoomX, zoomY = dims.zoomY,\n dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,\n zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,\n shouldRedraw = dimensionsChanged || zoomChanged,\n additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false;\n if (dimensionsChanged) {\n var canvasWidth = this._cacheCanvas.width,\n canvasHeight = this._cacheCanvas.height,\n sizeGrowing = width > canvasWidth || height > canvasHeight,\n sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n canvasWidth > minCacheSize && canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n }\n else {\n this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);\n this._cacheContext.clearRect(0, 0, canvas.width, canvas.height);\n }\n drawingWidth = dims.x * zoomX / 2;\n drawingHeight = dims.y * zoomY / 2;\n this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n this.cacheWidth = width;\n this.cacheHeight = height;\n this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY);\n this._cacheContext.scale(zoomX, zoomY);\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n return false;\n },\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function(options) {\n this._setOptions(options);\n this._initGradient(options.fill, 'fill');\n this._initGradient(options.stroke, 'stroke');\n this._initClipping(options);\n this._initPattern(options.fill, 'fill');\n this._initPattern(options.stroke, 'stroke');\n },\n\n /**\n * Transforms context when rendering an object\n * @param {CanvasRenderingContext2D} ctx Context\n * @param {Boolean} fromLeft When true, context is transformed to object's top/left corner. This is used when rendering text on Node\n */\n transform: function(ctx, fromLeft) {\n if (this.group && !this.group._transformDone && this.group === this.canvas._activeGroup) {\n this.group.transform(ctx);\n }\n var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint();\n ctx.translate(center.x, center.y);\n this.angle && ctx.rotate(degreesToRadians(this.angle));\n ctx.scale(\n this.scaleX * (this.flipX ? -1 : 1),\n this.scaleY * (this.flipY ? -1 : 1)\n );\n this.skewX && ctx.transform(1, 0, Math.tan(degreesToRadians(this.skewX)), 1, 0, 0);\n this.skewY && ctx.transform(1, Math.tan(degreesToRadians(this.skewY)), 0, 1, 0, 0);\n },\n\n /**\n * Returns an object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n\n object = {\n type: this.type,\n originX: this.originX,\n originY: this.originY,\n left: toFixed(this.left, NUM_FRACTION_DIGITS),\n top: toFixed(this.top, NUM_FRACTION_DIGITS),\n width: toFixed(this.width, NUM_FRACTION_DIGITS),\n height: toFixed(this.height, NUM_FRACTION_DIGITS),\n fill: (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill,\n stroke: (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke,\n strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),\n strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,\n strokeLineCap: this.strokeLineCap,\n strokeLineJoin: this.strokeLineJoin,\n strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),\n scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS),\n scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS),\n angle: toFixed(this.getAngle(), NUM_FRACTION_DIGITS),\n flipX: this.flipX,\n flipY: this.flipY,\n opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS),\n shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow,\n visible: this.visible,\n clipTo: this.clipTo && String(this.clipTo),\n backgroundColor: this.backgroundColor,\n fillRule: this.fillRule,\n globalCompositeOperation: this.globalCompositeOperation,\n transformMatrix: this.transformMatrix ? this.transformMatrix.concat() : null,\n skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS),\n skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS)\n };\n\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n if (!this.includeDefaultValues) {\n object = this._removeDefaultValues(object);\n }\n\n return object;\n },\n\n /**\n * Returns (dataless) object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n // will be overwritten by subclasses\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * @private\n * @param {Object} object\n */\n _removeDefaultValues: function(object) {\n var prototype = fabric.util.getKlass(object.type).prototype,\n stateProperties = prototype.stateProperties;\n stateProperties.forEach(function(prop) {\n if (object[prop] === prototype[prop]) {\n delete object[prop];\n }\n var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' &&\n Object.prototype.toString.call(prototype[prop]) === '[object Array]';\n\n // basically a check for [] === []\n if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {\n delete object[prop];\n }\n });\n\n return object;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Return the object scale factor counting also the group scaling\n * @return {Object} object with scaleX and scaleY properties\n */\n getObjectScaling: function() {\n var scaleX = this.scaleX, scaleY = this.scaleY;\n if (this.group) {\n var scaling = this.group.getObjectScaling();\n scaleX *= scaling.scaleX;\n scaleY *= scaling.scaleY;\n }\n return { scaleX: scaleX, scaleY: scaleY };\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Object} thisArg\n */\n _set: function(key, value) {\n var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'),\n isChanged = this[key] !== value;\n\n if (shouldConstrainValue) {\n value = this._constrainScale(value);\n }\n if (key === 'scaleX' && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n }\n else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n }\n else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) {\n value = new fabric.Shadow(value);\n }\n else if (key === 'dirty' && this.group) {\n this.group.set('dirty', value);\n }\n\n this[key] = value;\n\n if (isChanged && this.cacheProperties.indexOf(key) > -1) {\n if (this.group) {\n this.group.set('dirty', true);\n }\n this.dirty = true;\n }\n\n if (isChanged && this.group && this.stateProperties.indexOf(key) > -1) {\n this.group.set('dirty', true);\n }\n\n if (key === 'width' || key === 'height') {\n this.minScaleLimit = Math.min(0.1, 1 / Math.max(this.width, this.height));\n }\n\n return this;\n },\n\n /**\n * This callback function is called by the parent group of an object every\n * time a non-delegated property changes on the group. It is passed the key\n * and value as parameters. Not adding in this function's signature to avoid\n * Travis build error about unused variables.\n */\n setOnGroup: function() {\n // implemented by sub-classes, as needed.\n },\n\n /**\n * Sets sourcePath of an object\n * @param {String} value Value to set sourcePath to\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setSourcePath: function(value) {\n this.sourcePath = value;\n return this;\n },\n\n /**\n * Retrieves viewportTransform from Object's canvas if possible\n * @method getViewportTransform\n * @memberOf fabric.Object.prototype\n * @return {Boolean}\n */\n getViewportTransform: function() {\n if (this.canvas && this.canvas.viewportTransform) {\n return this.canvas.viewportTransform;\n }\n return fabric.iMatrix.concat();\n },\n\n /*\n * @private\n * return if the object would be visible in rendering\n * @memberOf fabric.Object.prototype\n * @return {Boolean}\n */\n isNotVisible: function() {\n return this.opacity === 0 || (this.width === 0 && this.height === 0) || !this.visible;\n },\n\n /**\n * Renders an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n render: function(ctx, noTransform) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n ctx.save();\n //setup fill rule for current object\n this._setupCompositeOperation(ctx);\n this.drawSelectionBackground(ctx);\n if (!noTransform) {\n this.transform(ctx);\n }\n this._setOpacity(ctx);\n this._setShadow(ctx);\n if (this.transformMatrix) {\n ctx.transform.apply(ctx, this.transformMatrix);\n }\n this.clipTo && fabric.util.clipContext(this, ctx);\n if (this.shouldCache(noTransform)) {\n if (!this._cacheCanvas) {\n this._createCacheCanvas();\n }\n if (this.isCacheDirty(noTransform)) {\n this.statefullCache && this.saveState({ propertySet: 'cacheProperties' });\n this.drawObject(this._cacheContext, noTransform);\n this.dirty = false;\n }\n this.drawCacheOnCanvas(ctx);\n }\n else {\n this._removeCacheCanvas();\n this.dirty = false;\n this.drawObject(ctx, noTransform);\n if (noTransform && this.objectCaching && this.statefullCache) {\n this.saveState({ propertySet: 'cacheProperties' });\n }\n }\n this.clipTo && ctx.restore();\n ctx.restore();\n },\n\n /**\n * Remove cacheCanvas and its dimensions from the objects\n */\n _removeCacheCanvas: function() {\n this._cacheCanvas = null;\n this.cacheWidth = 0;\n this.cacheHeight = 0;\n },\n\n /**\n * When set to `true`, force the object to have its own cache, even if it is inside a group\n * it may be needed when your object behave in a particular way on the cache and always needs\n * its own isolated canvas to render correctly.\n * This function is created to be subclassed by custom classes.\n * since 1.7.12\n * @type function\n * @return false\n */\n needsItsOwnCache: function() {\n return false;\n },\n\n /**\n * Decide if the object should cache or not.\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @param {Boolean} noTransform if rendereing in pathGroup, caching is not supported at object level\n * @return {Boolean}\n */\n shouldCache: function(noTransform) {\n return !noTransform && this.objectCaching &&\n (!this.group || this.needsItsOwnCache() || !this.group.isCaching());\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * used by Group.shouldCache to know if child has a shadow recursively\n * @return {Boolean}\n */\n willDrawShadow: function() {\n return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0);\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n drawObject: function(ctx, noTransform) {\n this._renderBackground(ctx);\n this._setStrokeStyles(ctx);\n this._setFillStyles(ctx);\n this._render(ctx, noTransform);\n },\n\n /**\n * Paint the cached copy of the object on the target context.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas: function(ctx) {\n ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY);\n },\n\n /**\n * Check if cache is dirty\n * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n * on parent canvas.\n */\n isCacheDirty: function(skipCanvas) {\n if (this.isNotVisible()) {\n return false;\n }\n if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n }\n else {\n if (this.dirty || (this.statefullCache && this.hasStateChanged('cacheProperties'))) {\n if (this._cacheCanvas && !skipCanvas) {\n var width = this.cacheWidth / this.zoomX;\n var height = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-width / 2, -height / 2, width, height);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Draws a background for the object big as its untrasformed dimensions\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground: function(ctx) {\n if (!this.backgroundColor) {\n return;\n }\n var dim = this._getNonTransformedDimensions();\n ctx.fillStyle = this.backgroundColor;\n\n ctx.fillRect(\n -dim.x / 2,\n -dim.y / 2,\n dim.x,\n dim.y\n );\n // if there is background color no other shadows\n // should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity: function(ctx) {\n ctx.globalAlpha *= this.opacity;\n },\n\n _setStrokeStyles: function(ctx) {\n if (this.stroke) {\n ctx.lineWidth = this.strokeWidth;\n ctx.lineCap = this.strokeLineCap;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.miterLimit = this.strokeMiterLimit;\n ctx.strokeStyle = this.stroke.toLive\n ? this.stroke.toLive(ctx, this)\n : this.stroke;\n }\n },\n\n _setFillStyles: function(ctx) {\n if (this.fill) {\n ctx.fillStyle = this.fill.toLive\n ? this.fill.toLive(ctx, this)\n : this.fill;\n }\n },\n\n /**\n * @private\n * Sets line dash\n * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n * @param {Array} dashArray array representing dashes\n * @param {Function} alternative function to call if browaser does not support lineDash\n */\n _setLineDash: function(ctx, dashArray, alternative) {\n if (!dashArray) {\n return;\n }\n // Spec requires the concatenation of two copies the dash list when the number of elements is odd\n if (1 & dashArray.length) {\n dashArray.push.apply(dashArray, dashArray);\n }\n if (supportsLineDash) {\n ctx.setLineDash(dashArray);\n }\n else {\n alternative && alternative(ctx);\n }\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderControls: function(ctx) {\n if (!this.active || (this.group && this.group !== this.canvas.getActiveGroup())) {\n return;\n }\n\n var vpt = this.getViewportTransform(),\n matrix = this.calcTransformMatrix(),\n options;\n matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);\n options = fabric.util.qrDecompose(matrix);\n\n ctx.save();\n ctx.translate(options.translateX, options.translateY);\n ctx.lineWidth = 1 * this.borderScaleFactor;\n if (!this.group) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n if (this.group && this.group === this.canvas.getActiveGroup()) {\n ctx.rotate(degreesToRadians(options.angle));\n this.drawBordersInGroup(ctx, options);\n }\n else {\n ctx.rotate(degreesToRadians(this.angle));\n this.drawBorders(ctx);\n }\n this.drawControls(ctx);\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setShadow: function(ctx) {\n if (!this.shadow) {\n return;\n }\n\n var multX = (this.canvas && this.canvas.viewportTransform[0]) || 1,\n multY = (this.canvas && this.canvas.viewportTransform[3]) || 1,\n scaling = this.getObjectScaling();\n if (this.canvas && this.canvas._isRetinaScaling()) {\n multX *= fabric.devicePixelRatio;\n multY *= fabric.devicePixelRatio;\n }\n ctx.shadowColor = this.shadow.color;\n ctx.shadowBlur = this.shadow.blur * (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;\n ctx.shadowOffsetX = this.shadow.offsetX * multX * scaling.scaleX;\n ctx.shadowOffsetY = this.shadow.offsetY * multY * scaling.scaleY;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _removeShadow: function(ctx) {\n if (!this.shadow) {\n return;\n }\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} filler fabric.Pattern or fabric.Gradient\n */\n _applyPatternGradientTransform: function(ctx, filler) {\n if (!filler.toLive) {\n return;\n }\n var transform = filler.gradientTransform || filler.patternTransform;\n if (transform) {\n ctx.transform.apply(ctx, transform);\n }\n var offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n ctx.translate(offsetX, offsetY);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill: function(ctx) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n this._applyPatternGradientTransform(ctx, this.fill);\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n }\n else {\n ctx.fill();\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke: function(ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);\n this._applyPatternGradientTransform(ctx, this.stroke);\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * Clones an instance, some objects are async, so using callback method will work for every object.\n * Using the direct return does not work for images and groups.\n * @param {Function} callback Callback is invoked with a clone as a first argument\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {fabric.Object} clone of an instance\n */\n clone: function(callback, propertiesToInclude) {\n if (this.constructor.fromObject) {\n return this.constructor.fromObject(this.toObject(propertiesToInclude), callback);\n }\n return new fabric.Object(this.toObject(propertiesToInclude));\n },\n\n /**\n * Creates an instance of fabric.Image out of an object\n * @param {Function} callback callback, invoked with an instance as a first argument\n * @param {Object} [options] for clone as image, passed to toDataURL\n * @param {Boolean} [options.enableRetinaScaling] enable retina scaling for the cloned image\n * @return {fabric.Object} thisArg\n */\n cloneAsImage: function(callback, options) {\n var dataUrl = this.toDataURL(options);\n fabric.util.loadImage(dataUrl, function(img) {\n if (callback) {\n callback(new fabric.Image(img));\n }\n });\n return this;\n },\n\n /**\n * Converts an object into a data-url-like string\n * @param {Object} options Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetina] Enable retina scaling for clone image. Introduce in 1.6.4\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n */\n toDataURL: function(options) {\n options || (options = { });\n\n var el = fabric.util.createCanvasElement(),\n boundingRect = this.getBoundingRect();\n\n el.width = boundingRect.width;\n el.height = boundingRect.height;\n fabric.util.wrapElement(el, 'div');\n var canvas = new fabric.StaticCanvas(el, { enableRetinaScaling: options.enableRetinaScaling });\n // to avoid common confusion https://github.com/kangax/fabric.js/issues/806\n if (options.format === 'jpg') {\n options.format = 'jpeg';\n }\n\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n\n var origParams = {\n active: this.get('active'),\n left: this.getLeft(),\n top: this.getTop()\n };\n\n this.set('active', false);\n this.setPositionByOrigin(new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2), 'center', 'center');\n\n var originalCanvas = this.canvas;\n canvas.add(this);\n var data = canvas.toDataURL(options);\n\n this.set(origParams).setCoords();\n this.canvas = originalCanvas;\n\n canvas.dispose();\n canvas = null;\n\n return data;\n },\n\n /**\n * Returns true if specified type is identical to the type of an instance\n * @param {String} type Type to check against\n * @return {Boolean}\n */\n isType: function(type) {\n return this.type === type;\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance (is 1 unless subclassed)\n */\n complexity: function() {\n return 1;\n },\n\n /**\n * Returns a JSON representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} JSON\n */\n toJSON: function(propertiesToInclude) {\n // delegate, not alias\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * Sets gradient (fill or stroke) of an object\n * Backwards incompatibility note: This method was named \"setGradientFill\" until v1.1.0\n * @param {String} property Property name 'stroke' or 'fill'\n * @param {Object} [options] Options object\n * @param {String} [options.type] Type of gradient 'radial' or 'linear'\n * @param {Number} [options.x1=0] x-coordinate of start point\n * @param {Number} [options.y1=0] y-coordinate of start point\n * @param {Number} [options.x2=0] x-coordinate of end point\n * @param {Number} [options.y2=0] y-coordinate of end point\n * @param {Number} [options.r1=0] Radius of start point (only for radial gradients)\n * @param {Number} [options.r2=0] Radius of end point (only for radial gradients)\n * @param {Object} [options.colorStops] Color stops object eg. {0: 'ff0000', 1: '000000'}\n * @param {Object} [options.gradientTransform] transforMatrix for gradient\n * @return {fabric.Object} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/58y8b/|jsFiddle demo}\n * @example Set linear gradient\n * object.setGradient('fill', {\n * type: 'linear',\n * x1: -object.width / 2,\n * y1: 0,\n * x2: object.width / 2,\n * y2: 0,\n * colorStops: {\n * 0: 'red',\n * 0.5: '#005555',\n * 1: 'rgba(0,0,255,0.5)'\n * }\n * });\n * canvas.renderAll();\n * @example Set radial gradient\n * object.setGradient('fill', {\n * type: 'radial',\n * x1: 0,\n * y1: 0,\n * x2: 0,\n * y2: 0,\n * r1: object.width / 2,\n * r2: 10,\n * colorStops: {\n * 0: 'red',\n * 0.5: '#005555',\n * 1: 'rgba(0,0,255,0.5)'\n * }\n * });\n * canvas.renderAll();\n */\n setGradient: function(property, options) {\n options || (options = { });\n\n var gradient = { colorStops: [] };\n\n gradient.type = options.type || (options.r1 || options.r2 ? 'radial' : 'linear');\n gradient.coords = {\n x1: options.x1,\n y1: options.y1,\n x2: options.x2,\n y2: options.y2\n };\n\n if (options.r1 || options.r2) {\n gradient.coords.r1 = options.r1;\n gradient.coords.r2 = options.r2;\n }\n\n gradient.gradientTransform = options.gradientTransform;\n fabric.Gradient.prototype.addColorStop.call(gradient, options.colorStops);\n\n return this.set(property, fabric.Gradient.forObject(this, gradient));\n },\n\n /**\n * Sets pattern fill of an object\n * @param {Object} options Options object\n * @param {(String|HTMLImageElement)} options.source Pattern source\n * @param {String} [options.repeat=repeat] Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n * @param {Number} [options.offsetX=0] Pattern horizontal offset from object's left/top corner\n * @param {Number} [options.offsetY=0] Pattern vertical offset from object's left/top corner\n * @return {fabric.Object} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/QT3pa/|jsFiddle demo}\n * @example Set pattern\n * fabric.util.loadImage('http://fabricjs.com/assets/escheresque_ste.png', function(img) {\n * object.setPatternFill({\n * source: img,\n * repeat: 'repeat'\n * });\n * canvas.renderAll();\n * });\n */\n setPatternFill: function(options) {\n return this.set('fill', new fabric.Pattern(options));\n },\n\n /**\n * Sets {@link fabric.Object#shadow|shadow} of an object\n * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n * @param {String} [options.color=rgb(0,0,0)] Shadow color\n * @param {Number} [options.blur=0] Shadow blur\n * @param {Number} [options.offsetX=0] Shadow horizontal offset\n * @param {Number} [options.offsetY=0] Shadow vertical offset\n * @return {fabric.Object} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/7gvJG/|jsFiddle demo}\n * @example Set shadow with string notation\n * object.setShadow('2px 2px 10px rgba(0,0,0,0.2)');\n * canvas.renderAll();\n * @example Set shadow with object notation\n * object.setShadow({\n * color: 'red',\n * blur: 10,\n * offsetX: 20,\n * offsetY: 20\n * });\n * canvas.renderAll();\n */\n setShadow: function(options) {\n return this.set('shadow', options ? new fabric.Shadow(options) : null);\n },\n\n /**\n * Sets \"color\" of an instance (alias of `set('fill', …)`)\n * @param {String} color Color value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setColor: function(color) {\n this.set('fill', color);\n return this;\n },\n\n /**\n * Sets \"angle\" of an instance\n * @param {Number} angle Angle value (in degrees)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setAngle: function(angle) {\n var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation;\n\n if (shouldCenterOrigin) {\n this._setOriginToCenter();\n }\n\n this.set('angle', angle);\n\n if (shouldCenterOrigin) {\n this._resetOrigin();\n }\n\n return this;\n },\n\n /**\n * Centers object horizontally on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerH: function () {\n this.canvas && this.canvas.centerObjectH(this);\n return this;\n },\n\n /**\n * Centers object horizontally on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterH: function () {\n this.canvas && this.canvas.viewportCenterObjectH(this);\n return this;\n },\n\n /**\n * Centers object vertically on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerV: function () {\n this.canvas && this.canvas.centerObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterV: function () {\n this.canvas && this.canvas.viewportCenterObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically and horizontally on canvas to which is was added last\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n center: function () {\n this.canvas && this.canvas.centerObject(this);\n return this;\n },\n\n /**\n * Centers object on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenter: function () {\n this.canvas && this.canvas.viewportCenterObject(this);\n return this;\n },\n\n /**\n * Removes object from canvas to which it was added last\n * @return {fabric.Object} thisArg\n * @chainable\n */\n remove: function() {\n if (this.canvas) {\n if (this.group && this.group === this.canvas._activeGroup) {\n this.group.remove(this);\n }\n this.canvas.remove(this);\n }\n return this;\n },\n\n /**\n * Returns coordinates of a pointer relative to an object\n * @param {Event} e Event to operate upon\n * @param {Object} [pointer] Pointer to operate upon (instead of event)\n * @return {Object} Coordinates of a pointer (x, y)\n */\n getLocalPointer: function(e, pointer) {\n pointer = pointer || this.canvas.getPointer(e);\n var pClicked = new fabric.Point(pointer.x, pointer.y),\n objectLeftTop = this._getLeftTopCoords();\n if (this.angle) {\n pClicked = fabric.util.rotatePoint(\n pClicked, objectLeftTop, degreesToRadians(-this.angle));\n }\n return {\n x: pClicked.x - objectLeftTop.x,\n y: pClicked.y - objectLeftTop.y\n };\n },\n\n /**\n * Sets canvas globalCompositeOperation for specific object\n * custom composition operation for the particular object can be specifed using globalCompositeOperation property\n * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n */\n _setupCompositeOperation: function (ctx) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n });\n\n fabric.util.createAccessors(fabric.Object);\n\n /**\n * Alias for {@link fabric.Object.prototype.setAngle}\n * @alias rotate -> setAngle\n * @memberOf fabric.Object\n */\n fabric.Object.prototype.rotate = fabric.Object.prototype.setAngle;\n\n extend(fabric.Object.prototype, fabric.Observable);\n\n /**\n * Defines the number of fraction digits to use when serializing object values.\n * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n * @static\n * @memberOf fabric.Object\n * @constant\n * @type Number\n */\n fabric.Object.NUM_FRACTION_DIGITS = 2;\n\n fabric.Object._fromObject = function(className, object, callback, forceAsync, extraParam) {\n var klass = fabric[className];\n object = clone(object, true);\n if (forceAsync) {\n fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) {\n if (typeof patterns[0] !== 'undefined') {\n object.fill = patterns[0];\n }\n if (typeof patterns[1] !== 'undefined') {\n object.stroke = patterns[1];\n }\n var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);\n callback && callback(instance);\n });\n }\n else {\n var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);\n callback && callback(instance);\n return instance;\n }\n };\n\n /**\n * Unique id used internally when creating SVG elements\n * @static\n * @memberOf fabric.Object\n * @type Number\n */\n fabric.Object.__uid = 0;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var degreesToRadians = fabric.util.degreesToRadians,\n originXOffset = {\n left: -0.5,\n center: 0,\n right: 0.5\n },\n originYOffset = {\n top: -0.5,\n center: 0,\n bottom: 0.5\n };\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) {\n var x = point.x,\n y = point.y,\n offsetX, offsetY, dim;\n\n if (typeof fromOriginX === 'string') {\n fromOriginX = originXOffset[fromOriginX];\n }\n else {\n fromOriginX -= 0.5;\n }\n\n if (typeof toOriginX === 'string') {\n toOriginX = originXOffset[toOriginX];\n }\n else {\n toOriginX -= 0.5;\n }\n\n offsetX = toOriginX - fromOriginX;\n\n if (typeof fromOriginY === 'string') {\n fromOriginY = originYOffset[fromOriginY];\n }\n else {\n fromOriginY -= 0.5;\n }\n\n if (typeof toOriginY === 'string') {\n toOriginY = originYOffset[toOriginY];\n }\n else {\n toOriginY -= 0.5;\n }\n\n offsetY = toOriginY - fromOriginY;\n\n if (offsetX || offsetY) {\n dim = this._getTransformedDimensions();\n x = point.x + offsetX * dim.x;\n y = point.y + offsetY * dim.y;\n }\n\n return new fabric.Point(x, y);\n },\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToCenterPoint: function(point, originX, originY) {\n var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center');\n if (this.angle) {\n return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));\n }\n return p;\n },\n\n /**\n * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n * @param {fabric.Point} center The point which corresponds to center of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToOriginPoint: function(center, originX, originY) {\n var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n if (this.angle) {\n return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));\n }\n return p;\n },\n\n /**\n * Returns the real center coordinates of the object\n * @return {fabric.Point}\n */\n getCenterPoint: function() {\n var leftTop = new fabric.Point(this.left, this.top);\n return this.translateToCenterPoint(leftTop, this.originX, this.originY);\n },\n\n /**\n * Returns the coordinates of the object based on center coordinates\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @return {fabric.Point}\n */\n // getOriginPoint: function(center) {\n // return this.translateToOriginPoint(center, this.originX, this.originY);\n // },\n\n /**\n * Returns the coordinates of the object as if it has a different origin\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n getPointByOrigin: function(originX, originY) {\n var center = this.getCenterPoint();\n return this.translateToOriginPoint(center, originX, originY);\n },\n\n /**\n * Returns the point in local coordinates\n * @param {fabric.Point} point The point relative to the global coordinate system\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n toLocalPoint: function(point, originX, originY) {\n var center = this.getCenterPoint(),\n p, p2;\n\n if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) {\n p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n }\n else {\n p = new fabric.Point(this.left, this.top);\n }\n\n p2 = new fabric.Point(point.x, point.y);\n if (this.angle) {\n p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));\n }\n return p2.subtractEquals(p);\n },\n\n /**\n * Returns the point in global coordinates\n * @param {fabric.Point} The point relative to the local coordinate system\n * @return {fabric.Point}\n */\n // toGlobalPoint: function(point) {\n // return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top));\n // },\n\n /**\n * Sets the position of the object taking into consideration the object's origin\n * @param {fabric.Point} pos The new position of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {void}\n */\n setPositionByOrigin: function(pos, originX, originY) {\n var center = this.translateToCenterPoint(pos, originX, originY),\n position = this.translateToOriginPoint(center, this.originX, this.originY);\n\n this.set('left', position.x);\n this.set('top', position.y);\n },\n\n /**\n * @param {String} to One of 'left', 'center', 'right'\n */\n adjustPosition: function(to) {\n var angle = degreesToRadians(this.angle),\n hypotFull = this.getWidth(),\n xFull = Math.cos(angle) * hypotFull,\n yFull = Math.sin(angle) * hypotFull,\n offsetFrom, offsetTo;\n\n //TODO: this function does not consider mixed situation like top, center.\n if (typeof this.originX === 'string') {\n offsetFrom = originXOffset[this.originX];\n }\n else {\n offsetFrom = this.originX - 0.5;\n }\n if (typeof to === 'string') {\n offsetTo = originXOffset[to];\n }\n else {\n offsetTo = to - 0.5;\n }\n this.left += xFull * (offsetTo - offsetFrom);\n this.top += yFull * (offsetTo - offsetFrom);\n this.setCoords();\n this.originX = to;\n },\n\n /**\n * Sets the origin/position of the object to it's center point\n * @private\n * @return {void}\n */\n _setOriginToCenter: function() {\n this._originalOriginX = this.originX;\n this._originalOriginY = this.originY;\n\n var center = this.getCenterPoint();\n\n this.originX = 'center';\n this.originY = 'center';\n\n this.left = center.x;\n this.top = center.y;\n },\n\n /**\n * Resets the origin/position of the object to it's original origin\n * @private\n * @return {void}\n */\n _resetOrigin: function() {\n var originPoint = this.translateToOriginPoint(\n this.getCenterPoint(),\n this._originalOriginX,\n this._originalOriginY);\n\n this.originX = this._originalOriginX;\n this.originY = this._originalOriginY;\n\n this.left = originPoint.x;\n this.top = originPoint.y;\n\n this._originalOriginX = null;\n this._originalOriginY = null;\n },\n\n /**\n * @private\n */\n _getLeftTopCoords: function() {\n return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');\n },\n\n /**\n * Callback; invoked right before object is about to go from active to inactive\n */\n onDeselect: function() {\n /* NOOP */\n }\n });\n\n})();\n\n\n(function() {\n\n function getCoords(coords) {\n return [\n new fabric.Point(coords.tl.x, coords.tl.y),\n new fabric.Point(coords.tr.x, coords.tr.y),\n new fabric.Point(coords.br.x, coords.br.y),\n new fabric.Point(coords.bl.x, coords.bl.y)\n ];\n }\n\n var degreesToRadians = fabric.util.degreesToRadians,\n multiplyMatrices = fabric.util.multiplyTransformMatrices;\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Describe object's corner position in canvas element coordinates.\n * properties are tl,mt,tr,ml,mr,bl,mb,br,mtr for the main controls.\n * each property is an object with x, y and corner.\n * The `corner` property contains in a similar manner the 4 points of the\n * interactive area of the corner.\n * The coordinates depends from this properties: width, height, scaleX, scaleY\n * skewX, skewY, angle, strokeWidth, viewportTransform, top, left, padding.\n * The coordinates get updated with @method setCoords.\n * You can calculate them without updating with @method calcCoords;\n * @memberOf fabric.Object.prototype\n */\n oCoords: null,\n\n /**\n * Describe object's corner position in canvas object absolute coordinates\n * properties are tl,tr,bl,br and describe the four main corner.\n * each property is an object with x, y, instance of Fabric.Point.\n * The coordinates depends from this properties: width, height, scaleX, scaleY\n * skewX, skewY, angle, strokeWidth, top, left.\n * Those coordinates are usefull to understand where an object is. They get updated\n * with oCoords but they do not need to be updated when zoom or panning change.\n * The coordinates get updated with @method setCoords.\n * You can calculate them without updating with @method calcCoords(true);\n * @memberOf fabric.Object.prototype\n */\n aCoords: null,\n\n /**\n * return correct set of coordinates for intersection\n */\n getCoords: function(absolute, calculate) {\n if (!this.oCoords) {\n this.setCoords();\n }\n var coords = absolute ? this.aCoords : this.oCoords;\n return getCoords(calculate ? this.calcCoords(absolute) : coords);\n },\n\n /**\n * Checks if object intersects with an area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with an area formed by 2 points\n */\n intersectsWithRect: function(pointTL, pointBR, absolute, calculate) {\n var coords = this.getCoords(absolute, calculate),\n intersection = fabric.Intersection.intersectPolygonRectangle(\n coords,\n pointTL,\n pointBR\n );\n return intersection.status === 'Intersection';\n },\n\n /**\n * Checks if object intersects with another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with another object\n */\n intersectsWithObject: function(other, absolute, calculate) {\n var intersection = fabric.Intersection.intersectPolygonPolygon(\n this.getCoords(absolute, calculate),\n other.getCoords(absolute, calculate)\n );\n\n return intersection.status === 'Intersection'\n || other.isContainedWithinObject(this, absolute, calculate)\n || this.isContainedWithinObject(other, absolute, calculate);\n },\n\n /**\n * Checks if object is fully contained within area of another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area of another object\n */\n isContainedWithinObject: function(other, absolute, calculate) {\n var points = this.getCoords(absolute, calculate),\n i = 0, lines = other._getImageLines(\n calculate ? other.calcCoords(absolute) : absolute ? other.aCoords : other.oCoords\n );\n for (; i < 4; i++) {\n if (!other.containsPoint(points[i], lines)) {\n return false;\n }\n }\n return true;\n },\n\n /**\n * Checks if object is fully contained within area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area formed by 2 points\n */\n isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) {\n var boundingRect = this.getBoundingRect(absolute, calculate);\n\n return (\n boundingRect.left >= pointTL.x &&\n boundingRect.left + boundingRect.width <= pointBR.x &&\n boundingRect.top >= pointTL.y &&\n boundingRect.top + boundingRect.height <= pointBR.y\n );\n },\n\n /**\n * Checks if point is inside the object\n * @param {fabric.Point} point Point to check against\n * @param {Object} [lines] object returned from @method _getImageLines\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if point is inside the object\n */\n containsPoint: function(point, lines, absolute, calculate) {\n var lines = lines || this._getImageLines(\n calculate ? this.calcCoords(absolute) : absolute ? this.aCoords : this.oCoords\n ),\n xPoints = this._findCrossPoints(point, lines);\n\n // if xPoints is odd then point is inside the object\n return (xPoints !== 0 && xPoints % 2 === 1);\n },\n\n /**\n * Checks if object is contained within the canvas with current viewportTransform\n * the check is done stopping at first point that appear on screen\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within canvas\n */\n isOnScreen: function(calculate) {\n if (!this.canvas) {\n return false;\n }\n var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n var points = this.getCoords(true, calculate), point;\n for (var i = 0; i < 4; i++) {\n point = points[i];\n if (point.x <= pointBR.x && point.x >= pointTL.x && point.y <= pointBR.y && point.y >= pointTL.y) {\n return true;\n }\n }\n // no points on screen, check intersection with absolute coordinates\n if (this.intersectsWithRect(pointTL, pointBR, true)) {\n return true;\n }\n // worst case scenario the object is so big that contanins the screen\n var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 };\n if (this.containsPoint(centerPoint, null, true)) {\n return true;\n }\n return false;\n },\n\n /**\n * Method that returns an object with the object edges in it, given the coordinates of the corners\n * @private\n * @param {Object} oCoords Coordinates of the object corners\n */\n _getImageLines: function(oCoords) {\n return {\n topline: {\n o: oCoords.tl,\n d: oCoords.tr\n },\n rightline: {\n o: oCoords.tr,\n d: oCoords.br\n },\n bottomline: {\n o: oCoords.br,\n d: oCoords.bl\n },\n leftline: {\n o: oCoords.bl,\n d: oCoords.tl\n }\n };\n },\n\n /**\n * Helper method to determine how many cross points are between the 4 object edges\n * and the horizontal line determined by a point on canvas\n * @private\n * @param {fabric.Point} point Point to check\n * @param {Object} lines Coordinates of the object being evaluated\n */\n // remove yi, not used but left code here just in case.\n _findCrossPoints: function(point, lines) {\n var b1, b2, a1, a2, xi, // yi,\n xcount = 0,\n iLine;\n\n for (var lineKey in lines) {\n iLine = lines[lineKey];\n // optimisation 1: line below point. no cross\n if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) {\n continue;\n }\n // optimisation 2: line above point. no cross\n if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) {\n continue;\n }\n // optimisation 3: vertical line case\n if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) {\n xi = iLine.o.x;\n // yi = point.y;\n }\n // calculate the intersection point\n else {\n b1 = 0;\n b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);\n a1 = point.y - b1 * point.x;\n a2 = iLine.o.y - b2 * iLine.o.x;\n\n xi = -(a1 - a2) / (b1 - b2);\n // yi = a1 + b1 * xi;\n }\n // dont count xi < point.x cases\n if (xi >= point.x) {\n xcount += 1;\n }\n // optimisation 4: specific for square images\n if (xcount === 2) {\n break;\n }\n }\n return xcount;\n },\n\n /**\n * Returns width of an object's bounding rectangle\n * @deprecated since 1.0.4\n * @return {Number} width value\n */\n getBoundingRectWidth: function() {\n return this.getBoundingRect().width;\n },\n\n /**\n * Returns height of an object's bounding rectangle\n * @deprecated since 1.0.4\n * @return {Number} height value\n */\n getBoundingRectHeight: function() {\n return this.getBoundingRect().height;\n },\n\n /**\n * Returns coordinates of object's bounding rectangle (left, top, width, height)\n * the box is intented as aligned to axis of canvas.\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Object} Object with left, top, width, height properties\n */\n getBoundingRect: function(absolute, calculate) {\n var coords = this.getCoords(absolute, calculate);\n return fabric.util.makeBoundingBoxFromPoints(coords);\n },\n\n /**\n * Returns width of an object bounding box counting transformations\n * @return {Number} width value\n */\n getWidth: function() {\n return this._getTransformedDimensions().x;\n },\n\n /**\n * Returns height of an object bounding box counting transformations\n * to be renamed in 2.0\n * @return {Number} height value\n */\n getHeight: function() {\n return this._getTransformedDimensions().y;\n },\n\n /**\n * Makes sure the scale is valid and modifies it if necessary\n * @private\n * @param {Number} value\n * @return {Number}\n */\n _constrainScale: function(value) {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n }\n else {\n return this.minScaleLimit;\n }\n }\n return value;\n },\n\n /**\n * Scales an object (equally by x and y)\n * @param {Number} value Scale factor\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scale: function(value) {\n value = this._constrainScale(value);\n\n if (value < 0) {\n this.flipX = !this.flipX;\n this.flipY = !this.flipY;\n value *= -1;\n }\n\n this.scaleX = value;\n this.scaleY = value;\n return this.setCoords();\n },\n\n /**\n * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New width value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToWidth: function(value) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect().width / this.getWidth();\n return this.scale(value / this.width / boundingRectFactor);\n },\n\n /**\n * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New height value\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToHeight: function(value) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect().height / this.getHeight();\n return this.scale(value / this.height / boundingRectFactor);\n },\n\n /**\n * Calculate and returns the .coords of an object.\n * @return {Object} Object with tl, tr, br, bl ....\n * @chainable\n */\n calcCoords: function(absolute) {\n var theta = degreesToRadians(this.angle),\n vpt = this.getViewportTransform(),\n dim = absolute ? this._getTransformedDimensions() : this._calculateCurrentDimensions(),\n currentWidth = dim.x, currentHeight = dim.y,\n sinTh = Math.sin(theta),\n cosTh = Math.cos(theta),\n _angle = currentWidth > 0 ? Math.atan(currentHeight / currentWidth) : 0,\n _hypotenuse = (currentWidth / Math.cos(_angle)) / 2,\n offsetX = Math.cos(_angle + theta) * _hypotenuse,\n offsetY = Math.sin(_angle + theta) * _hypotenuse,\n center = this.getCenterPoint(),\n // offset added for rotate and scale actions\n coords = absolute ? center : fabric.util.transformPoint(center, vpt),\n tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY),\n tr = new fabric.Point(tl.x + (currentWidth * cosTh), tl.y + (currentWidth * sinTh)),\n bl = new fabric.Point(tl.x - (currentHeight * sinTh), tl.y + (currentHeight * cosTh)),\n br = new fabric.Point(coords.x + offsetX, coords.y + offsetY);\n if (!absolute) {\n var ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2),\n mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2),\n mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2),\n mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2),\n mtr = new fabric.Point(mt.x + sinTh * this.rotatingPointOffset, mt.y - cosTh * this.rotatingPointOffset);\n }\n\n // debugging\n\n /* setTimeout(function() {\n canvas.contextTop.fillStyle = 'green';\n canvas.contextTop.fillRect(mb.x, mb.y, 3, 3);\n canvas.contextTop.fillRect(bl.x, bl.y, 3, 3);\n canvas.contextTop.fillRect(br.x, br.y, 3, 3);\n canvas.contextTop.fillRect(tl.x, tl.y, 3, 3);\n canvas.contextTop.fillRect(tr.x, tr.y, 3, 3);\n canvas.contextTop.fillRect(ml.x, ml.y, 3, 3);\n canvas.contextTop.fillRect(mr.x, mr.y, 3, 3);\n canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);\n canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3);\n }, 50); */\n\n var coords = {\n // corners\n tl: tl, tr: tr, br: br, bl: bl,\n };\n if (!absolute) {\n // middle\n coords.ml = ml;\n coords.mt = mt;\n coords.mr = mr;\n coords.mb = mb;\n // rotating point\n coords.mtr = mtr;\n }\n return coords;\n },\n\n /**\n * Sets corner position coordinates based on current angle, width and height\n * See https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords\n * @param {Boolean} [ignoreZoom] set oCoords with or without the viewport transform.\n * @param {Boolean} [skipAbsolute] skip calculation of aCoords, usefull in setViewportTransform\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setCoords: function(ignoreZoom, skipAbsolute) {\n this.oCoords = this.calcCoords(ignoreZoom);\n if (!skipAbsolute) {\n this.aCoords = this.calcCoords(true);\n }\n\n // set coordinates of the draggable boxes in the corners used to scale/rotate the image\n ignoreZoom || (this._setCornerCoords && this._setCornerCoords());\n\n return this;\n },\n\n /**\n * calculate rotation matrix of an object\n * @return {Array} rotation matrix for the object\n */\n _calcRotateMatrix: function() {\n if (this.angle) {\n var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta);\n // trying to keep rounding error small, ugly but it works.\n if (cos === 6.123233995736766e-17 || cos === -1.8369701987210297e-16) {\n cos = 0;\n }\n return [cos, sin, -sin, cos, 0, 0];\n }\n return fabric.iMatrix.concat();\n },\n\n /**\n * calculate trasform Matrix that represent current transformation from\n * object properties.\n * @param {Boolean} [skipGroup] return transformMatrix for object and not go upward with parents\n * @return {Array} matrix Transform Matrix for the object\n */\n calcTransformMatrix: function(skipGroup) {\n var center = this.getCenterPoint(),\n translateMatrix = [1, 0, 0, 1, center.x, center.y],\n rotateMatrix,\n dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true),\n matrix;\n if (this.group && !skipGroup) {\n matrix = multiplyMatrices(this.group.calcTransformMatrix(), translateMatrix);\n }\n else {\n matrix = translateMatrix;\n }\n if (this.angle) {\n rotateMatrix = this._calcRotateMatrix();\n matrix = multiplyMatrices(matrix, rotateMatrix);\n }\n matrix = multiplyMatrices(matrix, dimensionMatrix);\n return matrix;\n },\n\n _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) {\n var skewMatrix,\n scaleX = this.scaleX * (flipping && this.flipX ? -1 : 1),\n scaleY = this.scaleY * (flipping && this.flipY ? -1 : 1),\n scaleMatrix = [scaleX, 0, 0, scaleY, 0, 0];\n if (skewX) {\n skewMatrix = [1, 0, Math.tan(degreesToRadians(skewX)), 1];\n scaleMatrix = multiplyMatrices(scaleMatrix, skewMatrix, true);\n }\n if (skewY) {\n skewMatrix = [1, Math.tan(degreesToRadians(skewY)), 0, 1];\n scaleMatrix = multiplyMatrices(scaleMatrix, skewMatrix, true);\n }\n return scaleMatrix;\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getNonTransformedDimensions: function() {\n var strokeWidth = this.strokeWidth,\n w = this.width + strokeWidth,\n h = this.height + strokeWidth;\n return { x: w, y: h };\n },\n\n /*\n * Calculate object bounding boxdimensions from its properties scale, skew.\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getTransformedDimensions: function(skewX, skewY) {\n if (typeof skewX === 'undefined') {\n skewX = this.skewX;\n }\n if (typeof skewY === 'undefined') {\n skewY = this.skewY;\n }\n var dimensions = this._getNonTransformedDimensions(),\n dimX = dimensions.x / 2, dimY = dimensions.y / 2,\n points = [\n {\n x: -dimX,\n y: -dimY\n },\n {\n x: dimX,\n y: -dimY\n },\n {\n x: -dimX,\n y: dimY\n },\n {\n x: dimX,\n y: dimY\n }],\n i, transformMatrix = this._calcDimensionsTransformMatrix(skewX, skewY, false),\n bbox;\n for (i = 0; i < points.length; i++) {\n points[i] = fabric.util.transformPoint(points[i], transformMatrix);\n }\n bbox = fabric.util.makeBoundingBoxFromPoints(points);\n return { x: bbox.width, y: bbox.height };\n },\n\n /*\n * Calculate object dimensions for controls. include padding and canvas zoom\n * private\n */\n _calculateCurrentDimensions: function() {\n var vpt = this.getViewportTransform(),\n dim = this._getTransformedDimensions(),\n p = fabric.util.transformPoint(dim, vpt, true);\n\n return p.scalarAdd(2 * this.padding);\n },\n });\n})();\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Moves an object to the bottom of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendToBack: function() {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);\n }\n else {\n this.canvas.sendToBack(this);\n }\n return this;\n },\n\n /**\n * Moves an object to the top of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringToFront: function() {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);\n }\n else {\n this.canvas.bringToFront(this);\n }\n return this;\n },\n\n /**\n * Moves an object down in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendBackwards: function(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);\n }\n else {\n this.canvas.sendBackwards(this, intersecting);\n }\n return this;\n },\n\n /**\n * Moves an object up in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringForward: function(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);\n }\n else {\n this.canvas.bringForward(this, intersecting);\n }\n return this;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {Number} index New position of object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n moveTo: function(index) {\n if (this.group) {\n fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);\n }\n else {\n this.canvas.moveTo(this, index);\n }\n return this;\n }\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n\n function getSvgColorString(prop, value) {\n if (!value) {\n return prop + ': none; ';\n }\n else if (value.toLive) {\n return prop + ': url(#SVGID_' + value.id + '); ';\n }\n else {\n var color = new fabric.Color(value),\n str = prop + ': ' + color.toRgb() + '; ',\n opacity = color.getAlpha();\n if (opacity !== 1) {\n //change the color in rgb + opacity\n str += prop + '-opacity: ' + opacity.toString() + '; ';\n }\n return str;\n }\n }\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles: function(skipShadow) {\n\n var fillRule = this.fillRule,\n strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',\n strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n visibility = this.visible ? '' : ' visibility: hidden;',\n filter = skipShadow ? '' : this.getSvgFilter(),\n fill = getSvgColorString('fill', this.fill),\n stroke = getSvgColorString('stroke', this.stroke);\n\n return [\n stroke,\n 'stroke-width: ', strokeWidth, '; ',\n 'stroke-dasharray: ', strokeDashArray, '; ',\n 'stroke-linecap: ', strokeLineCap, '; ',\n 'stroke-linejoin: ', strokeLineJoin, '; ',\n 'stroke-miterlimit: ', strokeMiterLimit, '; ',\n fill,\n 'fill-rule: ', fillRule, '; ',\n 'opacity: ', opacity, ';',\n filter,\n visibility\n ].join('');\n },\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter: function() {\n return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';\n },\n\n /**\n * Returns id attribute for svg output\n * @return {String}\n */\n getSvgId: function() {\n return this.id ? 'id=\"' + this.id + '\" ' : '';\n },\n\n /**\n * Returns transform-string for svg-export\n * @return {String}\n */\n getSvgTransform: function() {\n if (this.group && this.group.type === 'path-group') {\n return '';\n }\n var toFixed = fabric.util.toFixed,\n angle = this.getAngle(),\n skewX = (this.getSkewX() % 360),\n skewY = (this.getSkewY() % 360),\n center = this.getCenterPoint(),\n\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n\n translatePart = this.type === 'path-group' ? '' : 'translate(' +\n toFixed(center.x, NUM_FRACTION_DIGITS) +\n ' ' +\n toFixed(center.y, NUM_FRACTION_DIGITS) +\n ')',\n\n anglePart = angle !== 0\n ? (' rotate(' + toFixed(angle, NUM_FRACTION_DIGITS) + ')')\n : '',\n\n scalePart = (this.scaleX === 1 && this.scaleY === 1)\n ? '' :\n (' scale(' +\n toFixed(this.scaleX, NUM_FRACTION_DIGITS) +\n ' ' +\n toFixed(this.scaleY, NUM_FRACTION_DIGITS) +\n ')'),\n\n skewXPart = skewX !== 0 ? ' skewX(' + toFixed(skewX, NUM_FRACTION_DIGITS) + ')' : '',\n\n skewYPart = skewY !== 0 ? ' skewY(' + toFixed(skewY, NUM_FRACTION_DIGITS) + ')' : '',\n\n addTranslateX = this.type === 'path-group' ? this.width : 0,\n\n flipXPart = this.flipX ? ' matrix(-1 0 0 1 ' + addTranslateX + ' 0) ' : '',\n\n addTranslateY = this.type === 'path-group' ? this.height : 0,\n\n flipYPart = this.flipY ? ' matrix(1 0 0 -1 0 ' + addTranslateY + ')' : '';\n\n return [\n translatePart, anglePart, scalePart, flipXPart, flipYPart, skewXPart, skewYPart\n ].join('');\n },\n\n /**\n * Returns transform-string for svg-export from the transform matrix of single elements\n * @return {String}\n */\n getSvgTransformMatrix: function() {\n return this.transformMatrix ? ' matrix(' + this.transformMatrix.join(' ') + ') ' : '';\n },\n\n /**\n * @private\n */\n _createBaseSVGMarkup: function() {\n var markup = [];\n\n if (this.fill && this.fill.toLive) {\n markup.push(this.fill.toSVG(this, false));\n }\n if (this.stroke && this.stroke.toLive) {\n markup.push(this.stroke.toSVG(this, false));\n }\n if (this.shadow) {\n markup.push(this.shadow.toSVG(this));\n }\n return markup;\n }\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function() {\n\n var extend = fabric.util.object.extend,\n originalSet = 'stateProperties';\n\n /*\n Depends on `stateProperties`\n */\n function saveProps(origin, destination, props) {\n var tmpObj = { }, deep = true;\n props.forEach(function(prop) {\n tmpObj[prop] = origin[prop];\n });\n extend(origin[destination], tmpObj, deep);\n }\n\n function _isEqual(origValue, currentValue, firstPass) {\n if (origValue === currentValue) {\n // if the objects are identical, return\n return true;\n }\n else if (Array.isArray(origValue)) {\n if (origValue.length !== currentValue.length) {\n return false;\n }\n for (var i = 0, len = origValue.length; i < len; i++) {\n if (!_isEqual(origValue[i], currentValue[i])) {\n return false;\n }\n }\n return true;\n }\n else if (origValue && typeof origValue === 'object') {\n var keys = Object.keys(origValue), key;\n if (!firstPass && keys.length !== Object.keys(currentValue).length) {\n return false;\n }\n for (var i = 0, len = keys.length; i < len; i++) {\n key = keys[i];\n if (!_isEqual(origValue[key], currentValue[key])) {\n return false;\n }\n }\n return true;\n }\n }\n\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Returns true if object state (one of its state properties) was changed\n * @param {String} [propertySet] optional name for the set of property we want to save\n * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called\n */\n hasStateChanged: function(propertySet) {\n propertySet = propertySet || originalSet;\n var dashedPropertySet = '_' + propertySet;\n if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) {\n return true;\n }\n return !_isEqual(this[dashedPropertySet], this, true);\n },\n\n /**\n * Saves state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n saveState: function(options) {\n var propertySet = options && options.propertySet || originalSet,\n destination = '_' + propertySet;\n if (!this[destination]) {\n return this.setupState(options);\n }\n saveProps(this, destination, this[propertySet]);\n if (options && options.stateProperties) {\n saveProps(this, destination, options.stateProperties);\n }\n return this;\n },\n\n /**\n * Setups state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n setupState: function(options) {\n options = options || { };\n var propertySet = options.propertySet || originalSet;\n options.propertySet = propertySet;\n this['_' + propertySet] = { };\n this.saveState(options);\n return this;\n }\n });\n})();\n\n\n(function() {\n\n var degreesToRadians = fabric.util.degreesToRadians,\n /* eslint-disable camelcase */\n isVML = function() { return typeof G_vmlCanvasManager !== 'undefined'; };\n /* eslint-enable camelcase */\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * The object interactivity controls.\n * @private\n */\n _controlsVisibility: null,\n\n /**\n * Determines which corner has been clicked\n * @private\n * @param {Object} pointer The pointer indicating the mouse position\n * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found\n */\n _findTargetCorner: function(pointer) {\n if (!this.hasControls || !this.active) {\n return false;\n }\n\n var ex = pointer.x,\n ey = pointer.y,\n xPoints,\n lines;\n this.__corner = 0;\n for (var i in this.oCoords) {\n\n if (!this.isControlVisible(i)) {\n continue;\n }\n\n if (i === 'mtr' && !this.hasRotatingPoint) {\n continue;\n }\n\n if (this.get('lockUniScaling') &&\n (i === 'mt' || i === 'mr' || i === 'mb' || i === 'ml')) {\n continue;\n }\n\n lines = this._getImageLines(this.oCoords[i].corner);\n\n // debugging\n\n // canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n\n // canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n\n // canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n\n // canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n\n xPoints = this._findCrossPoints({ x: ex, y: ey }, lines);\n if (xPoints !== 0 && xPoints % 2 === 1) {\n this.__corner = i;\n return i;\n }\n }\n return false;\n },\n\n /**\n * Sets the coordinates of the draggable boxes in the corners of\n * the image used to scale/rotate it.\n * @private\n */\n _setCornerCoords: function() {\n var coords = this.oCoords,\n newTheta = degreesToRadians(45 - this.angle),\n /* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */\n /* 0.707106 stands for sqrt(2)/2 */\n cornerHypotenuse = this.cornerSize * 0.707106,\n cosHalfOffset = cornerHypotenuse * Math.cos(newTheta),\n sinHalfOffset = cornerHypotenuse * Math.sin(newTheta),\n x, y;\n\n for (var point in coords) {\n x = coords[point].x;\n y = coords[point].y;\n coords[point].corner = {\n tl: {\n x: x - sinHalfOffset,\n y: y - cosHalfOffset\n },\n tr: {\n x: x + cosHalfOffset,\n y: y - sinHalfOffset\n },\n bl: {\n x: x - cosHalfOffset,\n y: y + sinHalfOffset\n },\n br: {\n x: x + sinHalfOffset,\n y: y + cosHalfOffset\n }\n };\n }\n },\n\n /**\n * Draws a colored layer behind the object, inside its selection borders.\n * Requires public options: padding, selectionBackgroundColor\n * this function is called when the context is transformed\n * has checks to be skipped when the object is on a staticCanvas\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawSelectionBackground: function(ctx) {\n if (!this.selectionBackgroundColor || this.group || !this.active ||\n (this.canvas && !this.canvas.interactive)) {\n return this;\n }\n ctx.save();\n var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(),\n vpt = this.canvas.viewportTransform;\n ctx.translate(center.x, center.y);\n ctx.scale(1 / vpt[0], 1 / vpt[3]);\n ctx.rotate(degreesToRadians(this.angle));\n ctx.fillStyle = this.selectionBackgroundColor;\n ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBorders: function(ctx) {\n if (!this.hasBorders) {\n return this;\n }\n\n var wh = this._calculateCurrentDimensions(),\n strokeWidth = 1 / this.borderScaleFactor,\n width = wh.x + strokeWidth,\n height = wh.y + strokeWidth;\n\n ctx.save();\n ctx.strokeStyle = this.borderColor;\n this._setLineDash(ctx, this.borderDashArray, null);\n\n ctx.strokeRect(\n -width / 2,\n -height / 2,\n width,\n height\n );\n\n if (this.hasRotatingPoint && this.isControlVisible('mtr') && !this.get('lockRotation') && this.hasControls) {\n\n var rotateHeight = -height / 2;\n\n ctx.beginPath();\n ctx.moveTo(0, rotateHeight);\n ctx.lineTo(0, rotateHeight - this.rotatingPointOffset);\n ctx.closePath();\n ctx.stroke();\n }\n\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box when it is inside a group.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {object} options object representing current object parameters\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBordersInGroup: function(ctx, options) {\n if (!this.hasBorders) {\n return this;\n }\n\n var p = this._getNonTransformedDimensions(),\n matrix = fabric.util.customTransformMatrix(options.scaleX, options.scaleY, options.skewX),\n wh = fabric.util.transformPoint(p, matrix),\n strokeWidth = 1 / this.borderScaleFactor,\n width = wh.x + strokeWidth,\n height = wh.y + strokeWidth;\n\n ctx.save();\n this._setLineDash(ctx, this.borderDashArray, null);\n ctx.strokeStyle = this.borderColor;\n\n ctx.strokeRect(\n -width / 2,\n -height / 2,\n width,\n height\n );\n\n ctx.restore();\n return this;\n },\n\n /**\n * Draws corners of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: cornerSize, padding\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawControls: function(ctx) {\n if (!this.hasControls) {\n return this;\n }\n\n var wh = this._calculateCurrentDimensions(),\n width = wh.x,\n height = wh.y,\n scaleOffset = this.cornerSize,\n left = -(width + scaleOffset) / 2,\n top = -(height + scaleOffset) / 2,\n methodName = this.transparentCorners ? 'stroke' : 'fill';\n\n ctx.save();\n ctx.strokeStyle = ctx.fillStyle = this.cornerColor;\n if (!this.transparentCorners) {\n ctx.strokeStyle = this.cornerStrokeColor;\n }\n this._setLineDash(ctx, this.cornerDashArray, null);\n\n // top-left\n this._drawControl('tl', ctx, methodName,\n left,\n top);\n\n // top-right\n this._drawControl('tr', ctx, methodName,\n left + width,\n top);\n\n // bottom-left\n this._drawControl('bl', ctx, methodName,\n left,\n top + height);\n\n // bottom-right\n this._drawControl('br', ctx, methodName,\n left + width,\n top + height);\n\n if (!this.get('lockUniScaling')) {\n\n // middle-top\n this._drawControl('mt', ctx, methodName,\n left + width / 2,\n top);\n\n // middle-bottom\n this._drawControl('mb', ctx, methodName,\n left + width / 2,\n top + height);\n\n // middle-right\n this._drawControl('mr', ctx, methodName,\n left + width,\n top + height / 2);\n\n // middle-left\n this._drawControl('ml', ctx, methodName,\n left,\n top + height / 2);\n }\n\n // middle-top-rotate\n if (this.hasRotatingPoint) {\n this._drawControl('mtr', ctx, methodName,\n left + width / 2,\n top - this.rotatingPointOffset);\n }\n\n ctx.restore();\n\n return this;\n },\n\n /**\n * @private\n */\n _drawControl: function(control, ctx, methodName, left, top) {\n if (!this.isControlVisible(control)) {\n return;\n }\n var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor;\n switch (this.cornerStyle) {\n case 'circle':\n ctx.beginPath();\n ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false);\n ctx[methodName]();\n if (stroke) {\n ctx.stroke();\n }\n break;\n default:\n isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size);\n ctx[methodName + 'Rect'](left, top, size, size);\n if (stroke) {\n ctx.strokeRect(left, top, size, size);\n }\n }\n },\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @returns {Boolean} true if the specified control is visible, false otherwise\n */\n isControlVisible: function(controlName) {\n return this._getControlsVisibility()[controlName];\n },\n\n /**\n * Sets the visibility of the specified control.\n * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @param {Boolean} visible true to set the specified control visible, false otherwise\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlVisible: function(controlName, visible) {\n this._getControlsVisibility()[controlName] = visible;\n return this;\n },\n\n /**\n * Sets the visibility state of object controls.\n * @param {Object} [options] Options object\n * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it\n * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it\n * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it\n * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it\n * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it\n * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it\n * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it\n * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlsVisibility: function(options) {\n options || (options = { });\n\n for (var p in options) {\n this.setControlVisible(p, options[p]);\n }\n return this;\n },\n\n /**\n * Returns the instance of the control visibility set for this object.\n * @private\n * @returns {Object}\n */\n _getControlsVisibility: function() {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {\n tl: true,\n tr: true,\n br: true,\n bl: true,\n ml: true,\n mt: true,\n mr: true,\n mb: true,\n mtr: true\n };\n }\n return this._controlsVisibility;\n }\n });\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Animation duration (in ms) for fx* methods\n * @type Number\n * @default\n */\n FX_DURATION: 500,\n\n /**\n * Centers object horizontally with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectH: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.get('left'),\n endValue: this.getCenter().left,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('left', value);\n _this.renderAll();\n onChange();\n },\n onComplete: function() {\n object.setCoords();\n onComplete();\n }\n });\n\n return this;\n },\n\n /**\n * Centers object vertically with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectV: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.get('top'),\n endValue: this.getCenter().top,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('top', value);\n _this.renderAll();\n onChange();\n },\n onComplete: function() {\n object.setCoords();\n onComplete();\n }\n });\n\n return this;\n },\n\n /**\n * Same as `fabric.Canvas#remove` but animated\n * @param {fabric.Object} object Object to remove\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxRemove: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.get('opacity'),\n endValue: 0,\n duration: this.FX_DURATION,\n onStart: function() {\n object.set('active', false);\n },\n onChange: function(value) {\n object.set('opacity', value);\n _this.renderAll();\n onChange();\n },\n onComplete: function () {\n _this.remove(object);\n onComplete();\n }\n });\n\n return this;\n }\n});\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n /**\n * Animates object's properties\n * @param {String|Object} property Property to animate (if string) or properties to animate (if object)\n * @param {Number|Object} value Value to animate property to (if string was given first) or options object\n * @return {fabric.Object} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n * @chainable\n *\n * As object — multiple properties\n *\n * object.animate({ left: ..., top: ... });\n * object.animate({ left: ..., top: ... }, { duration: ... });\n *\n * As string — one property\n *\n * object.animate('left', ...);\n * object.animate('left', { duration: ... });\n *\n */\n animate: function() {\n if (arguments[0] && typeof arguments[0] === 'object') {\n var propsToAnimate = [], prop, skipCallbacks;\n for (prop in arguments[0]) {\n propsToAnimate.push(prop);\n }\n for (var i = 0, len = propsToAnimate.length; i < len; i++) {\n prop = propsToAnimate[i];\n skipCallbacks = i !== len - 1;\n this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);\n }\n }\n else {\n this._animate.apply(this, arguments);\n }\n return this;\n },\n\n /**\n * @private\n * @param {String} property Property to animate\n * @param {String} to Value to animate to\n * @param {Object} [options] Options object\n * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked\n */\n _animate: function(property, to, options, skipCallbacks) {\n var _this = this, propPair;\n\n to = to.toString();\n\n if (!options) {\n options = { };\n }\n else {\n options = fabric.util.object.clone(options);\n }\n\n if (~property.indexOf('.')) {\n propPair = property.split('.');\n }\n\n var currentValue = propPair\n ? this.get(propPair[0])[propPair[1]]\n : this.get(property);\n\n if (!('from' in options)) {\n options.from = currentValue;\n }\n\n if (~to.indexOf('=')) {\n to = currentValue + parseFloat(to.replace('=', ''));\n }\n else {\n to = parseFloat(to);\n }\n\n fabric.util.animate({\n startValue: options.from,\n endValue: to,\n byValue: options.by,\n easing: options.easing,\n duration: options.duration,\n abort: options.abort && function() {\n return options.abort.call(_this);\n },\n onChange: function(value, valueProgress, timeProgress) {\n if (propPair) {\n _this[propPair[0]][propPair[1]] = value;\n }\n else {\n _this.set(property, value);\n }\n if (skipCallbacks) {\n return;\n }\n options.onChange && options.onChange(value, valueProgress, timeProgress);\n },\n onComplete: function(value, valueProgress, timeProgress) {\n if (skipCallbacks) {\n return;\n }\n\n _this.setCoords();\n options.onComplete && options.onComplete(value, valueProgress, timeProgress);\n }\n });\n }\n});\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 },\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash');\n\n if (fabric.Line) {\n fabric.warn('fabric.Line is already defined');\n return;\n }\n\n /**\n * Line class\n * @class fabric.Line\n * @extends fabric.Object\n * @see {@link fabric.Line#initialize} for constructor definition\n */\n fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'line',\n\n /**\n * x value or first line edge\n * @type Number\n * @default\n */\n x1: 0,\n\n /**\n * y value or first line edge\n * @type Number\n * @default\n */\n y1: 0,\n\n /**\n * x value or second line edge\n * @type Number\n * @default\n */\n x2: 0,\n\n /**\n * y value or second line edge\n * @type Number\n * @default\n */\n y2: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'),\n\n /**\n * Constructor\n * @param {Array} [points] Array of points\n * @param {Object} [options] Options object\n * @return {fabric.Line} thisArg\n */\n initialize: function(points, options) {\n if (!points) {\n points = [0, 0, 0, 0];\n }\n\n this.callSuper('initialize', options);\n\n this.set('x1', points[0]);\n this.set('y1', points[1]);\n this.set('x2', points[2]);\n this.set('y2', points[3]);\n\n this._setWidthHeight(options);\n },\n\n /**\n * @private\n * @param {Object} [options] Options\n */\n _setWidthHeight: function(options) {\n options || (options = { });\n\n this.width = Math.abs(this.x2 - this.x1);\n this.height = Math.abs(this.y2 - this.y1);\n\n this.left = 'left' in options\n ? options.left\n : this._getLeftToOriginX();\n\n this.top = 'top' in options\n ? options.top\n : this._getTopToOriginY();\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n if (typeof coordProps[key] !== 'undefined') {\n this._setWidthHeight();\n }\n return this;\n },\n\n /**\n * @private\n * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.\n */\n _getLeftToOriginX: makeEdgeToOriginGetter(\n { // property names\n origin: 'originX',\n axis1: 'x1',\n axis2: 'x2',\n dimension: 'width'\n },\n { // possible values of origin\n nearest: 'left',\n center: 'center',\n farthest: 'right'\n }\n ),\n\n /**\n * @private\n * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line.\n */\n _getTopToOriginY: makeEdgeToOriginGetter(\n { // property names\n origin: 'originY',\n axis1: 'y1',\n axis2: 'y2',\n dimension: 'height'\n },\n { // possible values of origin\n nearest: 'top',\n center: 'center',\n farthest: 'bottom'\n }\n ),\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n ctx.beginPath();\n\n if (noTransform) {\n // Line coords are distances from left-top of canvas to origin of line.\n // To render line in a path-group, we need to translate them to\n // distances from center of path-group to center of line.\n var cp = this.getCenterPoint(),\n offset = this.strokeWidth / 2;\n ctx.translate(\n cp.x - (this.strokeLineCap === 'butt' && this.height === 0 ? 0 : offset),\n cp.y - (this.strokeLineCap === 'butt' && this.width === 0 ? 0 : offset)\n );\n }\n\n if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {\n // move from center (of virtual box) to its left/top corner\n // we can't assume x1, y1 is top left and x2, y2 is bottom right\n var p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n }\n\n ctx.lineWidth = this.strokeWidth;\n\n // TODO: test this\n // make sure setting \"fill\" changes color of a line\n // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n var origStrokeStyle = ctx.strokeStyle;\n ctx.strokeStyle = this.stroke || ctx.fillStyle;\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var p = this.calcLinePoints();\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * Returns object representation of an instance\n * @methd toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints());\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n */\n _getNonTransformedDimensions: function() {\n var dim = this.callSuper('_getNonTransformedDimensions');\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n return dim;\n },\n\n /**\n * Recalculates line points given width and height\n * @private\n */\n calcLinePoints: function() {\n var xMult = this.x1 <= this.x2 ? -1 : 1,\n yMult = this.y1 <= this.y2 ? -1 : 1,\n x1 = (xMult * this.width * 0.5),\n y1 = (yMult * this.height * 0.5),\n x2 = (xMult * this.width * -0.5),\n y2 = (yMult * this.height * -0.5);\n\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2\n };\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(),\n p = { x1: this.x1, x2: this.x2, y1: this.y1, y2: this.y2 };\n\n if (!(this.group && this.group.type === 'path-group')) {\n p = this.calcLinePoints();\n }\n markup.push(\n '\\n'\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})\n * @static\n * @memberOf fabric.Line\n * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n */\n fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));\n\n /**\n * Returns fabric.Line instance from an SVG element\n * @static\n * @memberOf fabric.Line\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Line} instance of fabric.Line\n */\n fabric.Line.fromElement = function(element, options) {\n options = options || { };\n var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES),\n points = [\n parsedAttributes.x1 || 0,\n parsedAttributes.y1 || 0,\n parsedAttributes.x2 || 0,\n parsedAttributes.y2 || 0\n ];\n options.originX = 'left';\n options.originY = 'top';\n return new fabric.Line(points, extend(parsedAttributes, options));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Line instance from an object representation\n * @static\n * @memberOf fabric.Line\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Line} instance of fabric.Line\n */\n fabric.Line.fromObject = function(object, callback, forceAsync) {\n function _callback(instance) {\n delete instance.points;\n callback && callback(instance);\n };\n var options = clone(object, true);\n options.points = [object.x1, object.y1, object.x2, object.y2];\n var line = fabric.Object._fromObject('Line', options, _callback, forceAsync, 'points');\n if (line) {\n delete line.points;\n }\n return line;\n };\n\n /**\n * Produces a function that calculates distance from canvas edge to Line origin.\n */\n function makeEdgeToOriginGetter(propertyNames, originValues) {\n var origin = propertyNames.origin,\n axis1 = propertyNames.axis1,\n axis2 = propertyNames.axis2,\n dimension = propertyNames.dimension,\n nearest = originValues.nearest,\n center = originValues.center,\n farthest = originValues.farthest;\n\n return function() {\n switch (this.get(origin)) {\n case nearest:\n return Math.min(this.get(axis1), this.get(axis2));\n case center:\n return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension));\n case farthest:\n return Math.max(this.get(axis1), this.get(axis2));\n }\n };\n\n }\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n pi = Math.PI,\n extend = fabric.util.object.extend;\n\n if (fabric.Circle) {\n fabric.warn('fabric.Circle is already defined.');\n return;\n }\n\n /**\n * Circle class\n * @class fabric.Circle\n * @extends fabric.Object\n * @see {@link fabric.Circle#initialize} for constructor definition\n */\n fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'circle',\n\n /**\n * Radius of this circle\n * @type Number\n * @default\n */\n radius: 0,\n\n /**\n * Start angle of the circle, moving clockwise\n * @type Number\n * @default 0\n */\n startAngle: 0,\n\n /**\n * End angle of the circle\n * @type Number\n * @default 2Pi\n */\n endAngle: pi * 2,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {fabric.Circle} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this.set('radius', options && options.radius || 0);\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Circle} thisArg\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n\n if (key === 'radius') {\n this.setRadius(value);\n }\n\n return this;\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(), x = 0, y = 0,\n angle = (this.endAngle - this.startAngle) % ( 2 * pi);\n\n if (angle === 0) {\n if (this.group && this.group.type === 'path-group') {\n x = this.left + this.radius;\n y = this.top + this.radius;\n }\n markup.push(\n '\\n'\n );\n }\n else {\n var startX = Math.cos(this.startAngle) * this.radius,\n startY = Math.sin(this.startAngle) * this.radius,\n endX = Math.cos(this.endAngle) * this.radius,\n endY = Math.sin(this.endAngle) * this.radius,\n largeFlag = angle > pi ? '1' : '0';\n\n markup.push(\n '\\n'\n );\n }\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n _render: function(ctx, noTransform) {\n ctx.beginPath();\n ctx.arc(noTransform ? this.left + this.radius : 0,\n noTransform ? this.top + this.radius : 0,\n this.radius,\n this.startAngle,\n this.endAngle, false);\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusX: function() {\n return this.get('radius') * this.get('scaleX');\n },\n\n /**\n * Returns vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusY: function() {\n return this.get('radius') * this.get('scaleY');\n },\n\n /**\n * Sets radius of an object (and updates width accordingly)\n * @return {fabric.Circle} thisArg\n */\n setRadius: function(value) {\n this.radius = value;\n return this.set('width', value * 2).set('height', value * 2);\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement})\n * @static\n * @memberOf fabric.Circle\n * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n */\n fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '));\n\n /**\n * Returns {@link fabric.Circle} instance from an SVG element\n * @static\n * @memberOf fabric.Circle\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @throws {Error} If value of `r` attribute is missing or invalid\n * @return {fabric.Circle} Instance of fabric.Circle\n */\n fabric.Circle.fromElement = function(element, options) {\n options || (options = { });\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);\n\n if (!isValidRadius(parsedAttributes)) {\n throw new Error('value of `r` attribute is required and can not be negative');\n }\n\n parsedAttributes.left = parsedAttributes.left || 0;\n parsedAttributes.top = parsedAttributes.top || 0;\n\n var obj = new fabric.Circle(extend(parsedAttributes, options));\n\n obj.left -= obj.radius;\n obj.top -= obj.radius;\n return obj;\n };\n\n /**\n * @private\n */\n function isValidRadius(attributes) {\n return (('radius' in attributes) && (attributes.radius >= 0));\n }\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Circle} instance from an object representation\n * @static\n * @memberOf fabric.Circle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {Object} Instance of fabric.Circle\n */\n fabric.Circle.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Circle', object, callback, forceAsync);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Triangle) {\n fabric.warn('fabric.Triangle is already defined');\n return;\n }\n\n /**\n * Triangle class\n * @class fabric.Triangle\n * @extends fabric.Object\n * @return {fabric.Triangle} thisArg\n * @see {@link fabric.Triangle#initialize} for constructor definition\n */\n fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'triangle',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this.set('width', options && options.width || 100)\n .set('height', options && options.height || 100);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n ctx.moveTo(-widthBy2, heightBy2);\n ctx.lineTo(0, -heightBy2);\n ctx.lineTo(widthBy2, heightBy2);\n ctx.closePath();\n\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(),\n widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = [\n -widthBy2 + ' ' + heightBy2,\n '0 ' + -heightBy2,\n widthBy2 + ' ' + heightBy2\n ]\n .join(',');\n\n markup.push(\n ''\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n });\n\n /**\n * Returns {@link fabric.Triangle} instance from an object representation\n * @static\n * @memberOf fabric.Triangle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Triangle}\n */\n fabric.Triangle.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Triangle', object, callback, forceAsync);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n piBy2 = Math.PI * 2,\n extend = fabric.util.object.extend;\n\n if (fabric.Ellipse) {\n fabric.warn('fabric.Ellipse is already defined.');\n return;\n }\n\n /**\n * Ellipse class\n * @class fabric.Ellipse\n * @extends fabric.Object\n * @return {fabric.Ellipse} thisArg\n * @see {@link fabric.Ellipse#initialize} for constructor definition\n */\n fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'ellipse',\n\n /**\n * Horizontal radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical radius\n * @type Number\n * @default\n */\n ry: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {fabric.Ellipse} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this.set('rx', options && options.rx || 0);\n this.set('ry', options && options.ry || 0);\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Ellipse} thisArg\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n switch (key) {\n\n case 'rx':\n this.rx = value;\n this.set('width', value * 2);\n break;\n\n case 'ry':\n this.ry = value;\n this.set('height', value * 2);\n break;\n\n }\n return this;\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRx: function() {\n return this.get('rx') * this.get('scaleX');\n },\n\n /**\n * Returns Vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRy: function() {\n return this.get('ry') * this.get('scaleY');\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(), x = 0, y = 0;\n if (this.group && this.group.type === 'path-group') {\n x = this.left + this.rx;\n y = this.top + this.ry;\n }\n markup.push(\n '\\n'\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n _render: function(ctx, noTransform) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(\n noTransform ? this.left + this.rx : 0,\n noTransform ? (this.top + this.ry) * this.rx / this.ry : 0,\n this.rx,\n 0,\n piBy2,\n false);\n ctx.restore();\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement})\n * @static\n * @memberOf fabric.Ellipse\n * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n */\n fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '));\n\n /**\n * Returns {@link fabric.Ellipse} instance from an SVG element\n * @static\n * @memberOf fabric.Ellipse\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Ellipse}\n */\n fabric.Ellipse.fromElement = function(element, options) {\n options || (options = { });\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);\n\n parsedAttributes.left = parsedAttributes.left || 0;\n parsedAttributes.top = parsedAttributes.top || 0;\n\n var ellipse = new fabric.Ellipse(extend(parsedAttributes, options));\n\n ellipse.top -= ellipse.ry;\n ellipse.left -= ellipse.rx;\n return ellipse;\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Ellipse} instance from an object representation\n * @static\n * @memberOf fabric.Ellipse\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Ellipse}\n */\n fabric.Ellipse.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Ellipse', object, callback, forceAsync);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend;\n\n if (fabric.Rect) {\n fabric.warn('fabric.Rect is already defined');\n return;\n }\n\n /**\n * Rectangle class\n * @class fabric.Rect\n * @extends fabric.Object\n * @return {fabric.Rect} thisArg\n * @see {@link fabric.Rect#initialize} for constructor definition\n */\n fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ {\n\n /**\n * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'),\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'rect',\n\n /**\n * Horizontal border radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical border radius\n * @type Number\n * @default\n */\n ry: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this._initRxRy();\n },\n\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy: function() {\n if (this.rx && !this.ry) {\n this.ry = this.rx;\n }\n else if (this.ry && !this.rx) {\n this.rx = this.ry;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n\n // optimize 1x1 case (used in spray brush)\n if (this.width === 1 && this.height === 1) {\n ctx.fillRect(-0.5, -0.5, 1, 1);\n return;\n }\n\n var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0,\n ry = this.ry ? Math.min(this.ry, this.height / 2) : 0,\n w = this.width,\n h = this.height,\n x = noTransform ? this.left : -this.width / 2,\n y = noTransform ? this.top : -this.height / 2,\n isRounded = rx !== 0 || ry !== 0,\n /* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\n k = 1 - 0.5522847498;\n ctx.beginPath();\n\n ctx.moveTo(x + rx, y);\n\n ctx.lineTo(x + w - rx, y);\n isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);\n\n ctx.lineTo(x + w, y + h - ry);\n isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);\n\n ctx.lineTo(x + rx, y + h);\n isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);\n\n ctx.lineTo(x, y + ry);\n isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);\n\n ctx.closePath();\n\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(), x = this.left, y = this.top;\n if (!(this.group && this.group.type === 'path-group')) {\n x = -this.width / 2;\n y = -this.height / 2;\n }\n markup.push(\n '\\n');\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)\n * @static\n * @memberOf fabric.Rect\n * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n */\n fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '));\n\n /**\n * Returns {@link fabric.Rect} instance from an SVG element\n * @static\n * @memberOf fabric.Rect\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Rect} Instance of fabric.Rect\n */\n fabric.Rect.fromElement = function(element, options) {\n if (!element) {\n return null;\n }\n options = options || { };\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);\n\n parsedAttributes.left = parsedAttributes.left || 0;\n parsedAttributes.top = parsedAttributes.top || 0;\n var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n rect.visible = rect.visible && rect.width > 0 && rect.height > 0;\n return rect;\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Rect} instance from an object representation\n * @static\n * @memberOf fabric.Rect\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {Object} instance of fabric.Rect\n */\n fabric.Rect.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Rect', object, callback, forceAsync);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n toFixed = fabric.util.toFixed,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n if (fabric.Polyline) {\n fabric.warn('fabric.Polyline is already defined');\n return;\n }\n\n /**\n * Polyline class\n * @class fabric.Polyline\n * @extends fabric.Object\n * @see {@link fabric.Polyline#initialize} for constructor definition\n */\n fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polyline',\n\n /**\n * Points array\n * @type Array\n * @default\n */\n points: null,\n\n /**\n * Minimum X from points values, necessary to offset points\n * @type Number\n * @default\n */\n minX: 0,\n\n /**\n * Minimum Y from points values, necessary to offset points\n * @type Number\n * @default\n */\n minY: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'),\n\n /**\n * Constructor\n * @param {Array} points Array of points (where each point is an object with x and y)\n * @param {Object} [options] Options object\n * @return {fabric.Polyline} thisArg\n * @example\n * var poly = new fabric.Polyline([\n * { x: 10, y: 10 },\n * { x: 50, y: 30 },\n * { x: 40, y: 70 },\n * { x: 60, y: 50 },\n * { x: 100, y: 150 },\n * { x: 40, y: 100 }\n * ], {\n * stroke: 'red',\n * left: 100,\n * top: 100\n * });\n */\n initialize: function(points, options) {\n options = options || {};\n this.points = points || [];\n this.callSuper('initialize', options);\n this._calcDimensions();\n if (!('top' in options)) {\n this.top = this.minY;\n }\n if (!('left' in options)) {\n this.left = this.minX;\n }\n this.pathOffset = {\n x: this.minX + this.width / 2,\n y: this.minY + this.height / 2\n };\n },\n\n /**\n * @private\n */\n _calcDimensions: function() {\n\n var points = this.points,\n minX = min(points, 'x'),\n minY = min(points, 'y'),\n maxX = max(points, 'x'),\n maxY = max(points, 'y');\n\n this.width = (maxX - minX) || 0;\n this.height = (maxY - minY) || 0;\n this.minX = minX || 0;\n this.minY = minY || 0;\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n points: this.points.concat()\n });\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var points = [],\n diffX = 0,\n diffY = 0,\n markup = this._createBaseSVGMarkup();\n\n if (!(this.group && this.group.type === 'path-group')) {\n diffX = this.pathOffset.x;\n diffY = this.pathOffset.y;\n }\n\n for (var i = 0, len = this.points.length; i < len; i++) {\n points.push(\n toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',',\n toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '\n );\n }\n markup.push(\n '<', this.type, ' ', this.getSvgId(),\n 'points=\"', points.join(''),\n '\" style=\"', this.getSvgStyles(),\n '\" transform=\"', this.getSvgTransform(),\n ' ', this.getSvgTransformMatrix(),\n '\"/>\\n'\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n commonRender: function(ctx, noTransform) {\n var point, len = this.points.length,\n x = noTransform ? 0 : this.pathOffset.x,\n y = noTransform ? 0 : this.pathOffset.y;\n\n if (!len || isNaN(this.points[len - 1].y)) {\n // do not draw if no points or odd points\n // NaN comes from parseFloat of a empty string in parser\n return false;\n }\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n for (var i = 0; i < len; i++) {\n point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n return true;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n if (!this.commonRender(ctx, noTransform)) {\n return;\n }\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var p1, p2;\n\n ctx.beginPath();\n for (var i = 0, len = this.points.length; i < len; i++) {\n p1 = this.points[i];\n p2 = this.points[i + 1] || p1;\n fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray);\n }\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance\n */\n complexity: function() {\n return this.get('points').length;\n }\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement})\n * @static\n * @memberOf fabric.Polyline\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n */\n fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n /**\n * Returns fabric.Polyline instance from an SVG element\n * @static\n * @memberOf fabric.Polyline\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Polyline} Instance of fabric.Polyline\n */\n fabric.Polyline.fromElement = function(element, options) {\n if (!element) {\n return null;\n }\n options || (options = { });\n\n var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES);\n\n return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polyline instance from an object representation\n * @static\n * @memberOf fabric.Polyline\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Polyline} Instance of fabric.Polyline\n */\n fabric.Polyline.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Polyline', object, callback, forceAsync, 'points');\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend;\n\n if (fabric.Polygon) {\n fabric.warn('fabric.Polygon is already defined');\n return;\n }\n\n /**\n * Polygon class\n * @class fabric.Polygon\n * @extends fabric.Polyline\n * @see {@link fabric.Polygon#initialize} for constructor definition\n */\n fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polygon',\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n if (!this.commonRender(ctx, noTransform)) {\n return;\n }\n ctx.closePath();\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n this.callSuper('_renderDashedStroke', ctx);\n ctx.closePath();\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)\n * @static\n * @memberOf fabric.Polygon\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement\n */\n fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n /**\n * Returns {@link fabric.Polygon} instance from an SVG element\n * @static\n * @memberOf fabric.Polygon\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Polygon} Instance of fabric.Polygon\n */\n fabric.Polygon.fromElement = function(element, options) {\n if (!element) {\n return null;\n }\n\n options || (options = { });\n\n var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES);\n\n return new fabric.Polygon(points, extend(parsedAttributes, options));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polygon instance from an object representation\n * @static\n * @memberOf fabric.Polygon\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Polygon} Instance of fabric.Polygon\n */\n fabric.Polygon.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Polygon', object, callback, forceAsync, 'points');\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n extend = fabric.util.object.extend,\n _toString = Object.prototype.toString,\n drawArc = fabric.util.drawArc,\n commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7\n },\n repeatedCommands = {\n m: 'l',\n M: 'L'\n };\n\n if (fabric.Path) {\n fabric.warn('fabric.Path is already defined');\n return;\n }\n\n /**\n * Path class\n * @class fabric.Path\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}\n * @see {@link fabric.Path#initialize} for constructor definition\n */\n fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'path',\n\n /**\n * Array of path points\n * @type Array\n * @default\n */\n path: null,\n\n /**\n * Minimum X from points values, necessary to offset points\n * @type Number\n * @default\n */\n minX: 0,\n\n /**\n * Minimum Y from points values, necessary to offset points\n * @type Number\n * @default\n */\n minY: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'),\n\n stateProperties: fabric.Object.prototype.stateProperties.concat('path'),\n\n /**\n * Constructor\n * @param {Array|String} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {Object} [options] Options object\n * @return {fabric.Path} thisArg\n */\n initialize: function(path, options) {\n options = options || { };\n this.callSuper('initialize', options);\n\n if (!path) {\n path = [];\n }\n\n var fromArray = _toString.call(path) === '[object Array]';\n\n this.path = fromArray\n ? path\n // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values)\n : path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);\n\n if (!this.path) {\n return;\n }\n\n if (!fromArray) {\n this.path = this._parsePath();\n }\n\n this._setPositionDimensions(options);\n },\n\n /**\n * @private\n * @param {Object} options Options object\n */\n _setPositionDimensions: function(options) {\n var calcDim = this._parseDimensions();\n\n this.minX = calcDim.left;\n this.minY = calcDim.top;\n this.width = calcDim.width;\n this.height = calcDim.height;\n\n if (typeof options.left === 'undefined') {\n this.left = calcDim.left + (this.originX === 'center'\n ? this.width / 2\n : this.originX === 'right'\n ? this.width\n : 0);\n }\n\n if (typeof options.top === 'undefined') {\n this.top = calcDim.top + (this.originY === 'center'\n ? this.height / 2\n : this.originY === 'bottom'\n ? this.height\n : 0);\n }\n\n this.pathOffset = this.pathOffset || {\n x: this.minX + this.width / 2,\n y: this.minY + this.height / 2\n };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _renderPathCommands: function(ctx) {\n var current, // current instruction\n previous = null,\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0, // current y\n controlX = 0, // current control point x\n controlY = 0, // current control point y\n tempX,\n tempY,\n l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n\n if (this.group && this.group.type === 'path-group') {\n l = 0;\n t = 0;\n }\n\n ctx.beginPath();\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n\n current = this.path[i];\n\n switch (current[0]) { // first letter\n\n case 'l': // lineto, relative\n x += current[1];\n y += current[2];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'L': // lineto, absolute\n x = current[1];\n y = current[2];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'h': // horizontal lineto, relative\n x += current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'H': // horizontal lineto, absolute\n x = current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'v': // vertical lineto, relative\n y += current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'V': // verical lineto, absolute\n y = current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'm': // moveTo, relative\n x += current[1];\n y += current[2];\n subpathStartX = x;\n subpathStartY = y;\n ctx.moveTo(x + l, y + t);\n break;\n\n case 'M': // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n ctx.moveTo(x + l, y + t);\n break;\n\n case 'c': // bezierCurveTo, relative\n tempX = x + current[5];\n tempY = y + current[6];\n controlX = x + current[3];\n controlY = y + current[4];\n ctx.bezierCurveTo(\n x + current[1] + l, // x1\n y + current[2] + t, // y1\n controlX + l, // x2\n controlY + t, // y2\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'C': // bezierCurveTo, absolute\n x = current[5];\n y = current[6];\n controlX = current[3];\n controlY = current[4];\n ctx.bezierCurveTo(\n current[1] + l,\n current[2] + t,\n controlX + l,\n controlY + t,\n x + l,\n y + t\n );\n break;\n\n case 's': // shorthand cubic bezierCurveTo, relative\n\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n ctx.bezierCurveTo(\n controlX + l,\n controlY + t,\n x + current[1] + l,\n y + current[2] + t,\n tempX + l,\n tempY + t\n );\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = x + current[1];\n controlY = y + current[2];\n\n x = tempX;\n y = tempY;\n break;\n\n case 'S': // shorthand cubic bezierCurveTo, absolute\n tempX = current[3];\n tempY = current[4];\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n ctx.bezierCurveTo(\n controlX + l,\n controlY + t,\n current[1] + l,\n current[2] + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = current[1];\n controlY = current[2];\n\n break;\n\n case 'q': // quadraticCurveTo, relative\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n\n controlX = x + current[1];\n controlY = y + current[2];\n\n ctx.quadraticCurveTo(\n controlX + l,\n controlY + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n tempX = current[3];\n tempY = current[4];\n\n ctx.quadraticCurveTo(\n current[1] + l,\n current[2] + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n controlX = current[1];\n controlY = current[2];\n break;\n\n case 't': // shorthand quadraticCurveTo, relative\n\n // transform to absolute x,y\n tempX = x + current[1];\n tempY = y + current[2];\n\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n ctx.quadraticCurveTo(\n controlX + l,\n controlY + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n\n break;\n\n case 'T':\n tempX = current[1];\n tempY = current[2];\n\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n ctx.quadraticCurveTo(\n controlX + l,\n controlY + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'a':\n // TODO: optimize this\n drawArc(ctx, x + l, y + t, [\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6] + x + l,\n current[7] + y + t\n ]);\n x += current[6];\n y += current[7];\n break;\n\n case 'A':\n // TODO: optimize this\n drawArc(ctx, x + l, y + t, [\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6] + l,\n current[7] + t\n ]);\n x = current[6];\n y = current[7];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n ctx.closePath();\n break;\n }\n previous = current;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render: function(ctx) {\n this._renderPathCommands(ctx);\n this._renderFill(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var o = extend(this.callSuper('toObject', ['sourcePath', 'pathOffset'].concat(propertiesToInclude)), {\n path: this.path.map(function(item) { return item.slice(); }),\n top: this.top,\n left: this.left,\n });\n return o;\n },\n\n /**\n * Returns dataless object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var o = this.toObject(propertiesToInclude);\n if (this.sourcePath) {\n o.path = this.sourcePath;\n }\n delete o.sourcePath;\n return o;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var chunks = [],\n markup = this._createBaseSVGMarkup(), addTransform = '';\n\n for (var i = 0, len = this.path.length; i < len; i++) {\n chunks.push(this.path[i].join(' '));\n }\n var path = chunks.join(' ');\n if (!(this.group && this.group.type === 'path-group')) {\n addTransform = ' translate(' + (-this.pathOffset.x) + ', ' + (-this.pathOffset.y) + ') ';\n }\n markup.push(\n '\\n'\n );\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns number representation of an instance complexity\n * @return {Number} complexity of this instance\n */\n complexity: function() {\n return this.path.length;\n },\n\n /**\n * @private\n */\n _parsePath: function() {\n var result = [],\n coords = [],\n currentPath,\n parsed,\n re = /([-+]?((\\d+\\.\\d+)|((\\d+)|(\\.\\d+)))(?:e[-+]?\\d+)?)/ig,\n match,\n coordsStr;\n\n for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) {\n currentPath = this.path[i];\n\n coordsStr = currentPath.slice(1).trim();\n coords.length = 0;\n\n while ((match = re.exec(coordsStr))) {\n coords.push(match[0]);\n }\n\n coordsParsed = [currentPath.charAt(0)];\n\n for (var j = 0, jlen = coords.length; j < jlen; j++) {\n parsed = parseFloat(coords[j]);\n if (!isNaN(parsed)) {\n coordsParsed.push(parsed);\n }\n }\n\n var command = coordsParsed[0],\n commandLength = commandLengths[command.toLowerCase()],\n repeatedCommand = repeatedCommands[command] || command;\n\n if (coordsParsed.length - 1 > commandLength) {\n for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) {\n result.push([command].concat(coordsParsed.slice(k, k + commandLength)));\n command = repeatedCommand;\n }\n }\n else {\n result.push(coordsParsed);\n }\n }\n\n return result;\n },\n\n /**\n * @private\n */\n _parseDimensions: function() {\n\n var aX = [],\n aY = [],\n current, // current instruction\n previous = null,\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0, // current y\n controlX = 0, // current control point x\n controlY = 0, // current control point y\n tempX,\n tempY,\n bounds;\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n\n current = this.path[i];\n\n switch (current[0]) { // first letter\n\n case 'l': // lineto, relative\n x += current[1];\n y += current[2];\n bounds = [];\n break;\n\n case 'L': // lineto, absolute\n x = current[1];\n y = current[2];\n bounds = [];\n break;\n\n case 'h': // horizontal lineto, relative\n x += current[1];\n bounds = [];\n break;\n\n case 'H': // horizontal lineto, absolute\n x = current[1];\n bounds = [];\n break;\n\n case 'v': // vertical lineto, relative\n y += current[1];\n bounds = [];\n break;\n\n case 'V': // verical lineto, absolute\n y = current[1];\n bounds = [];\n break;\n\n case 'm': // moveTo, relative\n x += current[1];\n y += current[2];\n subpathStartX = x;\n subpathStartY = y;\n bounds = [];\n break;\n\n case 'M': // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n bounds = [];\n break;\n\n case 'c': // bezierCurveTo, relative\n tempX = x + current[5];\n tempY = y + current[6];\n controlX = x + current[3];\n controlY = y + current[4];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n x + current[1], // x1\n y + current[2], // y1\n controlX, // x2\n controlY, // y2\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'C': // bezierCurveTo, absolute\n controlX = current[3];\n controlY = current[4];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n current[1],\n current[2],\n controlX,\n controlY,\n current[5],\n current[6]\n );\n x = current[5];\n y = current[6];\n break;\n\n case 's': // shorthand cubic bezierCurveTo, relative\n\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n x + current[1],\n y + current[2],\n tempX,\n tempY\n );\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = x + current[1];\n controlY = y + current[2];\n x = tempX;\n y = tempY;\n break;\n\n case 'S': // shorthand cubic bezierCurveTo, absolute\n tempX = current[3];\n tempY = current[4];\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n current[1],\n current[2],\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = current[1];\n controlY = current[2];\n break;\n\n case 'q': // quadraticCurveTo, relative\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n controlX = x + current[1];\n controlY = y + current[2];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n controlX = current[1];\n controlY = current[2];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n current[3],\n current[4]\n );\n x = current[3];\n y = current[4];\n break;\n\n case 't': // shorthand quadraticCurveTo, relative\n // transform to absolute x,y\n tempX = x + current[1];\n tempY = y + current[2];\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n\n break;\n\n case 'T':\n tempX = current[1];\n tempY = current[2];\n\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'a':\n // TODO: optimize this\n bounds = fabric.util.getBoundsOfArc(x, y,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6] + x,\n current[7] + y\n );\n x += current[6];\n y += current[7];\n break;\n\n case 'A':\n // TODO: optimize this\n bounds = fabric.util.getBoundsOfArc(x, y,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n current[7]\n );\n x = current[6];\n y = current[7];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n previous = current;\n bounds.forEach(function (point) {\n aX.push(point.x);\n aY.push(point.y);\n });\n aX.push(x);\n aY.push(y);\n }\n\n var minX = min(aX) || 0,\n minY = min(aY) || 0,\n maxX = max(aX) || 0,\n maxY = max(aY) || 0,\n deltaX = maxX - minX,\n deltaY = maxY - minY,\n\n o = {\n left: minX,\n top: minY,\n width: deltaX,\n height: deltaY\n };\n\n return o;\n }\n });\n\n /**\n * Creates an instance of fabric.Path from an object\n * @static\n * @memberOf fabric.Path\n * @param {Object} object\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n */\n fabric.Path.fromObject = function(object, callback, forceAsync) {\n // remove this pattern rom 2.0, accept just object.\n var path;\n if (typeof object.path === 'string') {\n fabric.loadSVGFromURL(object.path, function (elements) {\n var pathUrl = object.path;\n path = elements[0];\n delete object.path;\n\n path.setOptions(object);\n path.setSourcePath(pathUrl);\n\n callback && callback(path);\n });\n }\n else {\n return fabric.Object._fromObject('Path', object, callback, forceAsync, 'path');\n }\n };\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`)\n * @static\n * @memberOf fabric.Path\n * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n */\n fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']);\n\n /**\n * Creates an instance of fabric.Path from an SVG element\n * @static\n * @memberOf fabric.Path\n * @param {SVGElement} element to parse\n * @param {Function} callback Callback to invoke when an fabric.Path instance is created\n * @param {Object} [options] Options object\n */\n fabric.Path.fromElement = function(element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);\n callback && callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @memberOf fabric.Path\n * @type Boolean\n * @default\n */\n fabric.Path.async = true;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend;\n\n if (fabric.PathGroup) {\n fabric.warn('fabric.PathGroup is already defined');\n return;\n }\n\n /**\n * Path group class\n * @class fabric.PathGroup\n * @extends fabric.Path\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}\n * @see {@link fabric.PathGroup#initialize} for constructor definition\n */\n fabric.PathGroup = fabric.util.createClass(fabric.Object, /** @lends fabric.PathGroup.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'path-group',\n\n /**\n * Fill value\n * @type String\n * @default\n */\n fill: '',\n\n /**\n * Pathgroups are container, do not render anything on theyr own, ence no cache properties\n * @type Boolean\n * @default\n */\n cacheProperties: [],\n\n /**\n * Constructor\n * @param {Array} paths\n * @param {Object} [options] Options object\n * @return {fabric.PathGroup} thisArg\n */\n initialize: function(paths, options) {\n\n options = options || { };\n this.paths = paths || [];\n\n for (var i = this.paths.length; i--;) {\n this.paths[i].group = this;\n }\n\n if (options.toBeParsed) {\n this.parseDimensionsFromPaths(options);\n delete options.toBeParsed;\n }\n this.setOptions(options);\n this.setCoords();\n },\n\n /**\n * Calculate width and height based on paths contained\n */\n parseDimensionsFromPaths: function(options) {\n var points, p, xC = [], yC = [], path, height, width,\n m;\n for (var j = this.paths.length; j--;) {\n path = this.paths[j];\n height = path.height + path.strokeWidth;\n width = path.width + path.strokeWidth;\n points = [\n { x: path.left, y: path.top },\n { x: path.left + width, y: path.top },\n { x: path.left, y: path.top + height },\n { x: path.left + width, y: path.top + height }\n ];\n m = this.paths[j].transformMatrix;\n for (var i = 0; i < points.length; i++) {\n p = points[i];\n if (m) {\n p = fabric.util.transformPoint(p, m, false);\n }\n xC.push(p.x);\n yC.push(p.y);\n }\n }\n options.width = Math.max.apply(null, xC);\n options.height = Math.max.apply(null, yC);\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n drawObject: function(ctx) {\n ctx.save();\n ctx.translate(-this.width / 2, -this.height / 2);\n for (var i = 0, l = this.paths.length; i < l; ++i) {\n this.paths[i].render(ctx, true);\n }\n ctx.restore();\n },\n\n /**\n * Decide if the object should cache or not.\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache: function() {\n var parentCache = this.objectCaching && (!this.group || this.needsItsOwnCache() || !this.group.isCaching());\n this.caching = parentCache;\n if (parentCache) {\n for (var i = 0, len = this.paths.length; i < len; i++) {\n if (this.paths[i].willDrawShadow()) {\n this.caching = false;\n return false;\n }\n }\n }\n return parentCache;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow: function() {\n if (this.shadow) {\n return true;\n }\n for (var i = 0, len = this.paths.length; i < len; i++) {\n if (this.paths[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isCaching: function() {\n return this.caching || this.group && this.group.isCaching();\n },\n\n /**\n * Check if cache is dirty\n */\n isCacheDirty: function() {\n if (this.callSuper('isCacheDirty')) {\n return true;\n }\n if (!this.statefullCache) {\n return false;\n }\n for (var i = 0, len = this.paths.length; i < len; i++) {\n if (this.paths[i].isCacheDirty(true)) {\n if (this._cacheCanvas) {\n var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Sets certain property to a certain value\n * @param {String} prop\n * @param {*} value\n * @return {fabric.PathGroup} thisArg\n */\n _set: function(prop, value) {\n\n if (prop === 'fill' && value && this.isSameColor()) {\n var i = this.paths.length;\n while (i--) {\n this.paths[i]._set(prop, value);\n }\n }\n\n return this.callSuper('_set', prop, value);\n },\n\n /**\n * Returns object representation of this path group\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var pathsToObject = this.paths.map(function(path) {\n var originalDefaults = path.includeDefaultValues;\n path.includeDefaultValues = path.group.includeDefaultValues;\n var obj = path.toObject(propertiesToInclude);\n path.includeDefaultValues = originalDefaults;\n return obj;\n });\n var o = extend(this.callSuper('toObject', ['sourcePath'].concat(propertiesToInclude)), {\n paths: pathsToObject\n });\n return o;\n },\n\n /**\n * Returns dataless object representation of this path group\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} dataless object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var o = this.toObject(propertiesToInclude);\n if (this.sourcePath) {\n o.paths = this.sourcePath;\n }\n return o;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var objects = this.getObjects(),\n p = this.getPointByOrigin('left', 'top'),\n translatePart = 'translate(' + p.x + ' ' + p.y + ')',\n markup = this._createBaseSVGMarkup();\n markup.push(\n '\\n'\n );\n\n for (var i = 0, len = objects.length; i < len; i++) {\n markup.push('\\t', objects[i].toSVG(reviver));\n }\n markup.push('\\n');\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns a string representation of this path group\n * @return {String} string representation of an object\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Returns true if all paths in this group are of same color\n * @return {Boolean} true if all paths are of the same color (`fill`)\n */\n isSameColor: function() {\n var firstPathFill = this.getObjects()[0].get('fill') || '';\n if (typeof firstPathFill !== 'string') {\n return false;\n }\n firstPathFill = firstPathFill.toLowerCase();\n return this.getObjects().every(function(path) {\n var pathFill = path.get('fill') || '';\n return typeof pathFill === 'string' && (pathFill).toLowerCase() === firstPathFill;\n });\n },\n\n /**\n * Returns number representation of object's complexity\n * @return {Number} complexity\n */\n complexity: function() {\n return this.paths.reduce(function(total, path) {\n return total + ((path && path.complexity) ? path.complexity() : 0);\n }, 0);\n },\n\n /**\n * Returns all paths in this path group\n * @return {Array} array of path objects included in this path group\n */\n getObjects: function() {\n return this.paths;\n }\n });\n\n /**\n * Creates fabric.PathGroup instance from an object representation\n * @static\n * @memberOf fabric.PathGroup\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.PathGroup instance is created\n */\n fabric.PathGroup.fromObject = function(object, callback) {\n var originalPaths = object.paths;\n delete object.paths;\n if (typeof originalPaths === 'string') {\n fabric.loadSVGFromURL(originalPaths, function (elements) {\n var pathUrl = originalPaths;\n var pathGroup = fabric.util.groupSVGElements(elements, object, pathUrl);\n object.paths = originalPaths;\n callback(pathGroup);\n });\n }\n else {\n fabric.util.enlivenObjects(originalPaths, function(enlivenedObjects) {\n var pathGroup = new fabric.PathGroup(enlivenedObjects, object);\n object.paths = originalPaths;\n callback(pathGroup);\n });\n }\n };\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @memberOf fabric.PathGroup\n * @type Boolean\n * @default\n */\n fabric.PathGroup.async = true;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n min = fabric.util.array.min,\n max = fabric.util.array.max;\n\n if (fabric.Group) {\n return;\n }\n\n // lock-related properties, for use in fabric.Group#get\n // to enable locking behavior on group\n // when one of its objects has lock-related properties set\n var _lockProperties = {\n lockMovementX: true,\n lockMovementY: true,\n lockRotation: true,\n lockScalingX: true,\n lockScalingY: true,\n lockUniScaling: true\n };\n\n /**\n * Group class\n * @class fabric.Group\n * @extends fabric.Object\n * @mixes fabric.Collection\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n * @see {@link fabric.Group#initialize} for constructor definition\n */\n fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'group',\n\n /**\n * Width of stroke\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * Indicates if click events should also check for subtargets\n * @type Boolean\n * @default\n */\n subTargetCheck: false,\n\n /**\n * Groups are container, do not render anything on theyr own, ence no cache properties\n * @type Boolean\n * @default\n */\n cacheProperties: [],\n\n /**\n * Constructor\n * @param {Object} objects Group objects\n * @param {Object} [options] Options object\n * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already.\n * @return {Object} thisArg\n */\n initialize: function(objects, options, isAlreadyGrouped) {\n options = options || { };\n\n this._objects = [];\n // if objects enclosed in a group have been grouped already,\n // we cannot change properties of objects.\n // Thus we need to set options to group without objects,\n // because delegatedProperties propagate to objects.\n isAlreadyGrouped && this.callSuper('initialize', options);\n\n this._objects = objects || [];\n for (var i = this._objects.length; i--; ) {\n this._objects[i].group = this;\n }\n\n if (options.originX) {\n this.originX = options.originX;\n }\n if (options.originY) {\n this.originY = options.originY;\n }\n\n if (isAlreadyGrouped) {\n // do not change coordinate of objects enclosed in a group,\n // because objects coordinate system have been group coodinate system already.\n this._updateObjectsCoords(true);\n this._updateObjectsACoords();\n }\n else {\n this._calcBounds();\n this._updateObjectsCoords();\n this.callSuper('initialize', options);\n }\n\n this.setCoords();\n this.saveCoords();\n },\n\n _updateObjectsACoords: function() {\n var ignoreZoom = true, skipAbsolute = true;\n for (var i = this._objects.length; i--; ){\n this._objects[i].setCoords(ignoreZoom, skipAbsolute);\n }\n },\n\n /**\n * @private\n * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n */\n _updateObjectsCoords: function(skipCoordsChange) {\n var center = this.getCenterPoint();\n for (var i = this._objects.length; i--; ){\n this._updateObjectCoords(this._objects[i], center, skipCoordsChange);\n }\n },\n\n /**\n * @private\n * @param {Object} object\n * @param {fabric.Point} center, current center of group.\n * @param {Boolean} [skipCoordsChange] if true, coordinates of object dose not change\n */\n _updateObjectCoords: function(object, center, skipCoordsChange) {\n // do not display corners of objects enclosed in a group\n object.__origHasControls = object.hasControls;\n object.hasControls = false;\n\n if (skipCoordsChange) {\n return;\n }\n\n var objectLeft = object.getLeft(),\n objectTop = object.getTop(),\n ignoreZoom = true, skipAbsolute = true;\n\n object.set({\n left: objectLeft - center.x,\n top: objectTop - center.y\n });\n object.setCoords(ignoreZoom, skipAbsolute);\n },\n\n /**\n * Returns string represenation of a group\n * @return {String}\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Adds an object to a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n addWithUpdate: function(object) {\n this._restoreObjectsState();\n fabric.util.resetObjectTransform(this);\n if (object) {\n this._objects.push(object);\n object.group = this;\n object._set('canvas', this.canvas);\n }\n // since _restoreObjectsState set objects inactive\n this.forEachObject(this._setObjectActive, this);\n this._calcBounds();\n this._updateObjectsCoords();\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * @private\n */\n _setObjectActive: function(object) {\n object.set('active', true);\n object.group = this;\n },\n\n /**\n * Removes an object from a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n removeWithUpdate: function(object) {\n this._restoreObjectsState();\n fabric.util.resetObjectTransform(this);\n // since _restoreObjectsState set objects inactive\n this.forEachObject(this._setObjectActive, this);\n\n this.remove(object);\n this._calcBounds();\n this._updateObjectsCoords();\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * @private\n */\n _onObjectAdded: function(object) {\n this.dirty = true;\n object.group = this;\n object._set('canvas', this.canvas);\n },\n\n /**\n * @private\n */\n _onObjectRemoved: function(object) {\n this.dirty = true;\n delete object.group;\n object.set('active', false);\n },\n\n /**\n * Properties that are delegated to group objects when reading/writing\n * @param {Object} delegatedProperties\n */\n delegatedProperties: {\n fill: true,\n stroke: true,\n strokeWidth: true,\n fontFamily: true,\n fontWeight: true,\n fontSize: true,\n fontStyle: true,\n lineHeight: true,\n textDecoration: true,\n textAlign: true,\n backgroundColor: true\n },\n\n /**\n * @private\n */\n _set: function(key, value) {\n var i = this._objects.length;\n\n if (this.delegatedProperties[key] || key === 'canvas') {\n while (i--) {\n this._objects[i].set(key, value);\n }\n }\n else {\n while (i--) {\n this._objects[i].setOnGroup(key, value);\n }\n }\n\n this.callSuper('_set', key, value);\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var objsToObject = this.getObjects().map(function(obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = obj.group.includeDefaultValues;\n var _obj = obj.toObject(propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n return extend(this.callSuper('toObject', propertiesToInclude), {\n objects: objsToObject\n });\n },\n\n /**\n * Returns object representation of an instance, in dataless mode.\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var objsToObject = this.getObjects().map(function(obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = obj.group.includeDefaultValues;\n var _obj = obj.toDatalessObject(propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n return extend(this.callSuper('toDatalessObject', propertiesToInclude), {\n objects: objsToObject\n });\n },\n\n /**\n * Renders instance on a given context\n * @param {CanvasRenderingContext2D} ctx context to render instance on\n */\n render: function(ctx) {\n this._transformDone = true;\n this.callSuper('render', ctx);\n this._transformDone = false;\n },\n\n /**\n * Decide if the object should cache or not.\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache: function() {\n var parentCache = this.objectCaching && (!this.group || this.needsItsOwnCache() || !this.group.isCaching());\n this.caching = parentCache;\n if (parentCache) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n this.caching = false;\n return false;\n }\n }\n }\n return parentCache;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow: function() {\n if (this.callSuper('willDrawShadow')) {\n return true;\n }\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isCaching: function() {\n return this.caching || this.group && this.group.isCaching();\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n drawObject: function(ctx) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._renderObject(this._objects[i], ctx);\n }\n },\n\n /**\n * Check if cache is dirty\n */\n isCacheDirty: function() {\n if (this.callSuper('isCacheDirty')) {\n return true;\n }\n if (!this.statefullCache) {\n return false;\n }\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].isCacheDirty(true)) {\n if (this._cacheCanvas) {\n // if this group has not a cache canvas there is nothing to clean\n var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} [noTransform] When true, context is not transformed\n */\n _renderControls: function(ctx, noTransform) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n this.callSuper('_renderControls', ctx, noTransform);\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i]._renderControls(ctx);\n }\n ctx.restore();\n },\n\n /**\n * @private\n */\n _renderObject: function(object, ctx) {\n // do not render if object is not visible\n if (!object.visible) {\n return;\n }\n\n var originalHasRotatingPoint = object.hasRotatingPoint;\n object.hasRotatingPoint = false;\n object.render(ctx);\n object.hasRotatingPoint = originalHasRotatingPoint;\n },\n\n /**\n * Retores original state of each of group objects (original state is that which was before group was created).\n * @private\n * @return {fabric.Group} thisArg\n * @chainable\n */\n _restoreObjectsState: function() {\n this._objects.forEach(this._restoreObjectState, this);\n return this;\n },\n\n /**\n * Realises the transform from this group onto the supplied object\n * i.e. it tells you what would happen if the supplied object was in\n * the group, and then the group was destroyed. It mutates the supplied\n * object.\n * @param {fabric.Object} object\n * @return {fabric.Object} transformedObject\n */\n realizeTransform: function(object) {\n var matrix = object.calcTransformMatrix(),\n options = fabric.util.qrDecompose(matrix),\n center = new fabric.Point(options.translateX, options.translateY);\n object.flipX = false;\n object.flipY = false;\n object.set('scaleX', options.scaleX);\n object.set('scaleY', options.scaleY);\n object.skewX = options.skewX;\n object.skewY = options.skewY;\n object.angle = options.angle;\n object.setPositionByOrigin(center, 'center', 'center');\n return object;\n },\n\n /**\n * Restores original state of a specified object in group\n * @private\n * @param {fabric.Object} object\n * @return {fabric.Group} thisArg\n */\n _restoreObjectState: function(object) {\n this.realizeTransform(object);\n object.setCoords();\n object.hasControls = object.__origHasControls;\n delete object.__origHasControls;\n object.set('active', false);\n delete object.group;\n\n return this;\n },\n\n /**\n * Destroys a group (restoring state of its objects)\n * @return {fabric.Group} thisArg\n * @chainable\n */\n destroy: function() {\n // when group is destroyed objects needs to get a repaint to be eventually\n // displayed on canvas.\n this._objects.forEach(function(object) {\n object.set('dirty', true);\n });\n return this._restoreObjectsState();\n },\n\n /**\n * Saves coordinates of this instance (to be used together with `hasMoved`)\n * @saveCoords\n * @return {fabric.Group} thisArg\n * @chainable\n */\n saveCoords: function() {\n this._originalLeft = this.get('left');\n this._originalTop = this.get('top');\n return this;\n },\n\n /**\n * Checks whether this group was moved (since `saveCoords` was called last)\n * @return {Boolean} true if an object was moved (since fabric.Group#saveCoords was called)\n */\n hasMoved: function() {\n return this._originalLeft !== this.get('left') ||\n this._originalTop !== this.get('top');\n },\n\n /**\n * Sets coordinates of all objects inside group\n * @return {fabric.Group} thisArg\n * @chainable\n */\n setObjectsCoords: function() {\n var ignoreZoom = true, skipAbsolute = true;\n this.forEachObject(function(object) {\n object.setCoords(ignoreZoom, skipAbsolute);\n });\n return this;\n },\n\n /**\n * @private\n */\n _calcBounds: function(onlyWidthHeight) {\n var aX = [],\n aY = [],\n o, prop,\n props = ['tr', 'br', 'bl', 'tl'],\n i = 0, iLen = this._objects.length,\n j, jLen = props.length,\n ignoreZoom = true;\n\n for ( ; i < iLen; ++i) {\n o = this._objects[i];\n o.setCoords(ignoreZoom);\n for (j = 0; j < jLen; j++) {\n prop = props[j];\n aX.push(o.oCoords[prop].x);\n aY.push(o.oCoords[prop].y);\n }\n }\n\n this.set(this._getBounds(aX, aY, onlyWidthHeight));\n },\n\n /**\n * @private\n */\n _getBounds: function(aX, aY, onlyWidthHeight) {\n var minXY = new fabric.Point(min(aX), min(aY)),\n maxXY = new fabric.Point(max(aX), max(aY)),\n obj = {\n width: (maxXY.x - minXY.x) || 0,\n height: (maxXY.y - minXY.y) || 0\n };\n\n if (!onlyWidthHeight) {\n obj.left = minXY.x || 0;\n obj.top = minXY.y || 0;\n if (this.originX === 'center') {\n obj.left += obj.width / 2;\n }\n if (this.originX === 'right') {\n obj.left += obj.width;\n }\n if (this.originY === 'center') {\n obj.top += obj.height / 2;\n }\n if (this.originY === 'bottom') {\n obj.top += obj.height;\n }\n }\n return obj;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup();\n markup.push(\n '\\n'\n );\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n markup.push('\\t', this._objects[i].toSVG(reviver));\n }\n\n markup.push('\\n');\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns requested property\n * @param {String} prop Property to get\n * @return {*}\n */\n get: function(prop) {\n if (prop in _lockProperties) {\n if (this[prop]) {\n return this[prop];\n }\n else {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i][prop]) {\n return true;\n }\n }\n return false;\n }\n }\n else {\n if (prop in this.delegatedProperties) {\n return this._objects[0] && this._objects[0].get(prop);\n }\n return this[prop];\n }\n }\n });\n\n /**\n * Returns {@link fabric.Group} instance from an object representation\n * @static\n * @memberOf fabric.Group\n * @param {Object} object Object to create a group from\n * @param {Function} [callback] Callback to invoke when an group instance is created\n */\n fabric.Group.fromObject = function(object, callback) {\n fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {\n var options = fabric.util.object.clone(object, true);\n delete options.objects;\n callback && callback(new fabric.Group(enlivenedObjects, options, true));\n });\n };\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @memberOf fabric.Group\n * @type Boolean\n * @default\n */\n fabric.Group.async = true;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var extend = fabric.util.object.extend;\n\n if (!global.fabric) {\n global.fabric = { };\n }\n\n if (global.fabric.Image) {\n fabric.warn('fabric.Image is already defined.');\n return;\n }\n\n /**\n * Image class\n * @class fabric.Image\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n * @see {@link fabric.Image#initialize} for constructor definition\n */\n fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'image',\n\n /**\n * crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n * @type String\n * @default\n */\n crossOrigin: '',\n\n /**\n * AlignX value, part of preserveAspectRatio (one of \"none\", \"mid\", \"min\", \"max\")\n * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute\n * This parameter defines how the picture is aligned to its viewport when image element width differs from image width.\n * @type String\n * @default\n */\n alignX: 'none',\n\n /**\n * AlignY value, part of preserveAspectRatio (one of \"none\", \"mid\", \"min\", \"max\")\n * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute\n * This parameter defines how the picture is aligned to its viewport when image element height differs from image height.\n * @type String\n * @default\n */\n alignY: 'none',\n\n /**\n * meetOrSlice value, part of preserveAspectRatio (one of \"meet\", \"slice\").\n * if meet the image is always fully visibile, if slice the viewport is always filled with image.\n * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute\n * @type String\n * @default\n */\n meetOrSlice: 'meet',\n\n /**\n * Width of a stroke.\n * For image quality a stroke multiple of 2 gives better results.\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * private\n * contains last value of scaleX to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleX: 1,\n\n /**\n * private\n * contains last value of scaleY to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleY: 1,\n\n /**\n * minimum scale factor under which any resizeFilter is triggered to resize the image\n * 0 will disable the automatic resize. 1 will trigger automatically always.\n * number bigger than 1 can be used in case we want to scale with some filter above\n * the natural image dimensions\n * @type Number\n */\n minimumScaleTrigger: 0.5,\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat(\n 'alignX',\n 'alignY',\n 'meetOrSlice'),\n\n /**\n * When `true`, object is cached on an additional canvas.\n * default to false for images\n * since 1.7.0\n * @type Boolean\n * @default\n */\n objectCaching: false,\n\n /**\n * Constructor\n * @param {HTMLImageElement | String} element Image element\n * @param {Object} [options] Options object\n * @param {function} [callback] callback function to call after eventual filters applied.\n * @return {fabric.Image} thisArg\n */\n initialize: function(element, options, callback) {\n options || (options = { });\n this.filters = [];\n this.resizeFilters = [];\n this.callSuper('initialize', options);\n this._initElement(element, options, callback);\n },\n\n /**\n * Returns image element which this instance if based on\n * @return {HTMLImageElement} Image element\n */\n getElement: function() {\n return this._element;\n },\n\n /**\n * Sets image element for this instance to a specified one.\n * If filters defined they are applied to new image.\n * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n * @param {HTMLImageElement} element\n * @param {Function} [callback] Callback is invoked when all filters have been applied and new image is generated\n * @param {Object} [options] Options object\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setElement: function(element, callback, options) {\n\n var _callback, _this;\n\n this._element = element;\n this._originalElement = element;\n this._initConfig(options);\n\n if (this.resizeFilters.length === 0) {\n _callback = callback;\n }\n else {\n _this = this;\n _callback = function() {\n _this.applyFilters(callback, _this.resizeFilters, _this._filteredEl || _this._originalElement, true);\n };\n }\n\n if (this.filters.length !== 0) {\n this.applyFilters(_callback);\n }\n else if (_callback) {\n _callback(this);\n }\n\n return this;\n },\n\n /**\n * Sets crossOrigin value (on an instance and corresponding image element)\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setCrossOrigin: function(value) {\n this.crossOrigin = value;\n this._element.crossOrigin = value;\n\n return this;\n },\n\n /**\n * Returns original size of an image\n * @return {Object} Object with \"width\" and \"height\" properties\n */\n getOriginalSize: function() {\n var element = this.getElement();\n return {\n width: element.width,\n height: element.height\n };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _stroke: function(ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n var w = this.width / 2, h = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-w, -h);\n ctx.lineTo(w, -h);\n ctx.lineTo(w, h);\n ctx.lineTo(-w, h);\n ctx.lineTo(-w, -h);\n ctx.closePath();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n\n ctx.save();\n this._setStrokeStyles(ctx);\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var filters = [], resizeFilters = [],\n scaleX = 1, scaleY = 1;\n\n this.filters.forEach(function(filterObj) {\n if (filterObj) {\n if (filterObj.type === 'Resize') {\n scaleX *= filterObj.scaleX;\n scaleY *= filterObj.scaleY;\n }\n filters.push(filterObj.toObject());\n }\n });\n\n this.resizeFilters.forEach(function(filterObj) {\n filterObj && resizeFilters.push(filterObj.toObject());\n });\n var object = extend(\n this.callSuper(\n 'toObject',\n ['crossOrigin', 'alignX', 'alignY', 'meetOrSlice'].concat(propertiesToInclude)\n ), {\n src: this.getSrc(),\n filters: filters,\n resizeFilters: resizeFilters,\n });\n\n object.width /= scaleX;\n object.height /= scaleY;\n\n return object;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2,\n preserveAspectRatio = 'none', filtered = true;\n if (this.group && this.group.type === 'path-group') {\n x = this.left;\n y = this.top;\n }\n if (this.alignX !== 'none' && this.alignY !== 'none') {\n preserveAspectRatio = 'x' + this.alignX + 'Y' + this.alignY + ' ' + this.meetOrSlice;\n }\n markup.push(\n '\\n',\n ' element with actual transformation, then offsetting object to the top/left\n // so that object's center aligns with container's left/top\n '\" width=\"', this.width,\n '\" height=\"', this.height,\n '\" preserveAspectRatio=\"', preserveAspectRatio, '\"',\n '>\\n'\n );\n\n if (this.stroke || this.strokeDashArray) {\n var origFill = this.fill;\n this.fill = null;\n markup.push(\n '\\n'\n );\n this.fill = origFill;\n }\n\n markup.push('\\n');\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns source of an image\n * @param {Boolean} filtered indicates if the src is needed for svg\n * @return {String} Source of an image\n */\n getSrc: function(filtered) {\n var element = filtered ? this._element : this._originalElement;\n if (element) {\n return fabric.isLikelyNode ? element._src : element.src;\n }\n else {\n return this.src || '';\n }\n },\n\n /**\n * Sets source of an image\n * @param {String} src Source string (URL)\n * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied)\n * @param {Object} [options] Options object\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setSrc: function(src, callback, options) {\n fabric.util.loadImage(src, function(img) {\n return this.setElement(img, callback, options);\n }, this, options && options.crossOrigin);\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of an instance\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Applies filters assigned to this image (from \"filters\" array)\n * @method applyFilters\n * @param {Function} callback Callback is invoked when all filters have been applied and new image is generated\n * @param {Array} filters to be applied\n * @param {fabric.Image} imgElement image to filter ( default to this._element )\n * @param {Boolean} forResizing\n * @return {CanvasElement} canvasEl to be drawn immediately\n * @chainable\n */\n applyFilters: function(callback, filters, imgElement, forResizing) {\n\n filters = filters || this.filters;\n imgElement = imgElement || this._originalElement;\n\n if (!imgElement) {\n return;\n }\n\n var replacement = fabric.util.createImage(),\n retinaScaling = this.canvas ? this.canvas.getRetinaScaling() : fabric.devicePixelRatio,\n minimumScale = this.minimumScaleTrigger / retinaScaling,\n _this = this, scaleX, scaleY;\n\n if (filters.length === 0) {\n this._element = imgElement;\n callback && callback(this);\n return imgElement;\n }\n\n var canvasEl = fabric.util.createCanvasElement();\n canvasEl.width = imgElement.width;\n canvasEl.height = imgElement.height;\n canvasEl.getContext('2d').drawImage(imgElement, 0, 0, imgElement.width, imgElement.height);\n\n filters.forEach(function(filter) {\n if (!filter) {\n return;\n }\n if (forResizing) {\n scaleX = _this.scaleX < minimumScale ? _this.scaleX : 1;\n scaleY = _this.scaleY < minimumScale ? _this.scaleY : 1;\n if (scaleX * retinaScaling < 1) {\n scaleX *= retinaScaling;\n }\n if (scaleY * retinaScaling < 1) {\n scaleY *= retinaScaling;\n }\n }\n else {\n scaleX = filter.scaleX;\n scaleY = filter.scaleY;\n }\n filter.applyTo(canvasEl, scaleX, scaleY);\n if (!forResizing && filter.type === 'Resize') {\n _this.width *= filter.scaleX;\n _this.height *= filter.scaleY;\n }\n });\n\n /** @ignore */\n replacement.width = canvasEl.width;\n replacement.height = canvasEl.height;\n if (fabric.isLikelyNode) {\n replacement.src = canvasEl.toBuffer(undefined, fabric.Image.pngCompression);\n // onload doesn't fire in some node versions, so we invoke callback manually\n _this._element = replacement;\n !forResizing && (_this._filteredEl = replacement);\n callback && callback(_this);\n }\n else {\n replacement.onload = function() {\n _this._element = replacement;\n !forResizing && (_this._filteredEl = replacement);\n callback && callback(_this);\n replacement.onload = canvasEl = null;\n };\n replacement.src = canvasEl.toDataURL('image/png');\n }\n return canvasEl;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n _render: function(ctx, noTransform) {\n var x, y, imageMargins = this._findMargins(), elementToDraw;\n\n x = (noTransform ? this.left : -this.width / 2);\n y = (noTransform ? this.top : -this.height / 2);\n\n if (this.meetOrSlice === 'slice') {\n ctx.beginPath();\n ctx.rect(x, y, this.width, this.height);\n ctx.clip();\n }\n\n if (this.isMoving === false && this.resizeFilters.length && this._needsResize()) {\n this._lastScaleX = this.scaleX;\n this._lastScaleY = this.scaleY;\n elementToDraw = this.applyFilters(null, this.resizeFilters, this._filteredEl || this._originalElement, true);\n }\n else {\n elementToDraw = this._element;\n }\n elementToDraw && ctx.drawImage(elementToDraw,\n x + imageMargins.marginX,\n y + imageMargins.marginY,\n imageMargins.width,\n imageMargins.height\n );\n\n this._stroke(ctx);\n this._renderStroke(ctx);\n },\n\n /**\n * @private, needed to check if image needs resize\n */\n _needsResize: function() {\n return (this.scaleX !== this._lastScaleX || this.scaleY !== this._lastScaleY);\n },\n\n /**\n * @private\n */\n _findMargins: function() {\n var width = this.width, height = this.height, scales,\n scale, marginX = 0, marginY = 0;\n\n if (this.alignX !== 'none' || this.alignY !== 'none') {\n scales = [this.width / this._element.width, this.height / this._element.height];\n scale = this.meetOrSlice === 'meet'\n ? Math.min.apply(null, scales) : Math.max.apply(null, scales);\n width = this._element.width * scale;\n height = this._element.height * scale;\n if (this.alignX === 'Mid') {\n marginX = (this.width - width) / 2;\n }\n if (this.alignX === 'Max') {\n marginX = this.width - width;\n }\n if (this.alignY === 'Mid') {\n marginY = (this.height - height) / 2;\n }\n if (this.alignY === 'Max') {\n marginY = this.height - height;\n }\n }\n return {\n width: width,\n height: height,\n marginX: marginX,\n marginY: marginY\n };\n },\n\n /**\n * @private\n */\n _resetWidthHeight: function() {\n var element = this.getElement();\n\n this.set('width', element.width);\n this.set('height', element.height);\n },\n\n /**\n * The Image class's initialization method. This method is automatically\n * called by the constructor.\n * @private\n * @param {HTMLImageElement|String} element The element representing the image\n * @param {Object} [options] Options object\n */\n _initElement: function(element, options, callback) {\n this.setElement(fabric.util.getById(element), callback, options);\n fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS);\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initConfig: function(options) {\n options || (options = { });\n this.setOptions(options);\n this._setWidthHeight(options);\n if (this._element && this.crossOrigin) {\n this._element.crossOrigin = this.crossOrigin;\n }\n },\n\n /**\n * @private\n * @param {Array} filters to be initialized\n * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created\n */\n _initFilters: function(filters, callback) {\n if (filters && filters.length) {\n fabric.util.enlivenObjects(filters, function(enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, 'fabric.Image.filters');\n }\n else {\n callback && callback();\n }\n },\n\n /**\n * @private\n * @param {Object} [options] Object with width/height properties\n */\n _setWidthHeight: function(options) {\n this.width = 'width' in options\n ? options.width\n : (this.getElement()\n ? this.getElement().width || 0\n : 0);\n\n this.height = 'height' in options\n ? options.height\n : (this.getElement()\n ? this.getElement().height || 0\n : 0);\n },\n });\n\n /**\n * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n fabric.Image.CSS_CANVAS = 'canvas-img';\n\n /**\n * Alias for getSrc\n * @static\n */\n fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;\n\n /**\n * Creates an instance of fabric.Image from its object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} callback Callback to invoke when an image instance is created\n */\n fabric.Image.fromObject = function(object, callback) {\n fabric.util.loadImage(object.src, function(img, error) {\n if (error) {\n callback && callback(null, error);\n return;\n }\n fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) {\n object.filters = filters || [];\n fabric.Image.prototype._initFilters.call(object, object.resizeFilters, function(resizeFilters) {\n object.resizeFilters = resizeFilters || [];\n return new fabric.Image(img, object, callback);\n });\n });\n }, null, object.crossOrigin);\n };\n\n /**\n * Creates an instance of fabric.Image from an URL string\n * @static\n * @param {String} url URL to create an image from\n * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument)\n * @param {Object} [imgOptions] Options object\n */\n fabric.Image.fromURL = function(url, callback, imgOptions) {\n fabric.util.loadImage(url, function(img) {\n callback && callback(new fabric.Image(img, imgOptions));\n }, null, imgOptions && imgOptions.crossOrigin);\n };\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement})\n * @static\n * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n */\n fabric.Image.ATTRIBUTE_NAMES =\n fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin'.split(' '));\n\n /**\n * Returns {@link fabric.Image} instance from an SVG element\n * @static\n * @param {SVGElement} element Element to parse\n * @param {Function} callback Callback to execute when fabric.Image object is created\n * @param {Object} [options] Options object\n * @return {fabric.Image} Instance of fabric.Image\n */\n fabric.Image.fromElement = function(element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES),\n preserveAR;\n\n if (parsedAttributes.preserveAspectRatio) {\n preserveAR = fabric.util.parsePreserveAspectRatioAttribute(parsedAttributes.preserveAspectRatio);\n extend(parsedAttributes, preserveAR);\n }\n\n fabric.Image.fromURL(parsedAttributes['xlink:href'], callback,\n extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @type Boolean\n * @default\n */\n fabric.Image.async = true;\n\n /**\n * Indicates compression level used when generating PNG under Node (in applyFilters). Any of 0-9\n * @static\n * @type Number\n * @default\n */\n fabric.Image.pngCompression = 1;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * @private\n * @return {Number} angle value\n */\n _getAngleValueForStraighten: function() {\n var angle = this.getAngle() % 360;\n if (angle > 0) {\n return Math.round((angle - 1) / 90) * 90;\n }\n return Math.round(angle / 90) * 90;\n },\n\n /**\n * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n straighten: function() {\n this.setAngle(this._getAngleValueForStraighten());\n return this;\n },\n\n /**\n * Same as {@link fabric.Object.prototype.straighten} but with animation\n * @param {Object} callbacks Object with callback functions\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Object} thisArg\n * @chainable\n */\n fxStraighten: function(callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: this.get('angle'),\n endValue: this._getAngleValueForStraighten(),\n duration: this.FX_DURATION,\n onChange: function(value) {\n _this.setAngle(value);\n onChange();\n },\n onComplete: function() {\n _this.setCoords();\n onComplete();\n },\n onStart: function() {\n _this.set('active', false);\n }\n });\n\n return this;\n }\n});\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Straightens object, then rerenders canvas\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n straightenObject: function (object) {\n object.straighten();\n this.renderAll();\n return this;\n },\n\n /**\n * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxStraightenObject: function (object) {\n object.fxStraighten({\n onChange: this.renderAll.bind(this)\n });\n return this;\n }\n});\n\n\n/**\n * @namespace fabric.Image.filters\n * @memberOf fabric.Image\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters}\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n */\nfabric.Image.filters = fabric.Image.filters || { };\n\n/**\n * Root filter class from which all filter classes inherit from\n * @class fabric.Image.filters.BaseFilter\n * @memberOf fabric.Image.filters\n */\nfabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'BaseFilter',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Sets filter's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function(options) {\n for (var prop in options) {\n this[prop] = options[prop];\n }\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return { type: this.type };\n },\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON: function() {\n // delegate, not alias\n return this.toObject();\n }\n});\n\nfabric.Image.filters.BaseFilter.fromObject = function(object, callback) {\n var filter = new fabric.Image.filters[object.type](object);\n callback && callback(filter);\n return filter;\n};\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Brightness filter class\n * @class fabric.Image.filters.Brightness\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Brightness({\n * brightness: 200\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Brightness',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Brightness.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.brightness=0] Value to brighten the image up (-255..255)\n */\n initialize: function(options) {\n options = options || { };\n this.brightness = options.brightness || 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n brightness = this.brightness;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n data[i] += brightness;\n data[i + 1] += brightness;\n data[i + 2] += brightness;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n brightness: this.brightness\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness\n */\n fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Adapted from html5rocks article\n * @class fabric.Image.filters.Convolute\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example Sharpen filter\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 0, -1, 0,\n * -1, 5, -1,\n * 0, -1, 0 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Blur filter\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Emboss filter\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Emboss filter with opaqueness\n * var filter = new fabric.Image.filters.Convolute({\n * opaque: true,\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Convolute',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Convolute.prototype\n * @param {Object} [options] Options object\n * @param {Boolean} [options.opaque=false] Opaque value (true/false)\n * @param {Array} [options.matrix] Filter matrix\n */\n initialize: function(options) {\n options = options || { };\n\n this.opaque = options.opaque;\n this.matrix = options.matrix || [\n 0, 0, 0,\n 0, 1, 0,\n 0, 0, 0\n ];\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n\n var weights = this.matrix,\n context = canvasEl.getContext('2d'),\n pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n\n side = Math.round(Math.sqrt(weights.length)),\n halfSide = Math.floor(side / 2),\n src = pixels.data,\n sw = pixels.width,\n sh = pixels.height,\n output = context.createImageData(sw, sh),\n dst = output.data,\n // go through the destination image pixels\n alphaFac = this.opaque ? 1 : 0,\n r, g, b, a, dstOff,\n scx, scy, srcOff, wt;\n\n for (var y = 0; y < sh; y++) {\n for (var x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4;\n // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n r = 0; g = 0; b = 0; a = 0;\n\n for (var cy = 0; cy < side; cy++) {\n for (var cx = 0; cx < side; cx++) {\n scy = y + cy - halfSide;\n scx = x + cx - halfSide;\n\n // eslint-disable-next-line max-depth\n if (scy < 0 || scy > sh || scx < 0 || scx > sw) {\n continue;\n }\n\n srcOff = (scy * sw + scx) * 4;\n wt = weights[cy * side + cx];\n\n r += src[srcOff] * wt;\n g += src[srcOff + 1] * wt;\n b += src[srcOff + 2] * wt;\n a += src[srcOff + 3] * wt;\n }\n }\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n dst[dstOff + 3] = a + alphaFac * (255 - a);\n }\n }\n\n context.putImageData(output, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n opaque: this.opaque,\n matrix: this.matrix\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute\n */\n fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * GradientTransparency filter class\n * @class fabric.Image.filters.GradientTransparency\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.GradientTransparency#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.GradientTransparency({\n * threshold: 200\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n // eslint-disable-next-line max-len\n filters.GradientTransparency = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.GradientTransparency.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'GradientTransparency',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.GradientTransparency.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.threshold=100] Threshold value\n */\n initialize: function(options) {\n options = options || { };\n this.threshold = options.threshold || 100;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n threshold = this.threshold,\n total = data.length;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n data[i + 3] = threshold + 255 * (total - i) / total;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n threshold: this.threshold\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.GradientTransparency} Instance of fabric.Image.filters.GradientTransparency\n */\n fabric.Image.filters.GradientTransparency.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Grayscale image filter class\n * @class fabric.Image.filters.Grayscale\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Grayscale();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Grayscale',\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Grayscale.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n len = imageData.width * imageData.height * 4,\n index = 0,\n average;\n\n while (index < len) {\n average = (data[index] + data[index + 1] + data[index + 2]) / 3;\n data[index] = average;\n data[index + 1] = average;\n data[index + 2] = average;\n index += 4;\n }\n\n context.putImageData(imageData, 0, 0);\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale\n */\n fabric.Image.filters.Grayscale.fromObject = function(object, callback) {\n object = object || { };\n object.type = 'Grayscale';\n return fabric.Image.filters.BaseFilter.fromObject(object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Invert filter class\n * @class fabric.Image.filters.Invert\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Invert();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Invert',\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Invert.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i;\n\n for (i = 0; i < iLen; i += 4) {\n data[i] = 255 - data[i];\n data[i + 1] = 255 - data[i + 1];\n data[i + 2] = 255 - data[i + 2];\n }\n\n context.putImageData(imageData, 0, 0);\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert\n */\n fabric.Image.filters.Invert.fromObject = function(object, callback) {\n object = object || { };\n object.type = 'Invert';\n return fabric.Image.filters.BaseFilter.fromObject(object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Mask filter class\n * See http://resources.aleph-1.com/mask/\n * @class fabric.Image.filters.Mask\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Mask#initialize} for constructor definition\n */\n filters.Mask = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Mask.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Mask',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Mask.prototype\n * @param {Object} [options] Options object\n * @param {fabric.Image} [options.mask] Mask image object\n * @param {Number} [options.channel=0] Rgb channel (0, 1, 2 or 3)\n */\n initialize: function(options) {\n options = options || { };\n\n this.mask = options.mask;\n this.channel = [0, 1, 2, 3].indexOf(options.channel) > -1 ? options.channel : 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n if (!this.mask) {\n return;\n }\n\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n maskEl = this.mask.getElement(),\n maskCanvasEl = fabric.util.createCanvasElement(),\n channel = this.channel,\n i,\n iLen = imageData.width * imageData.height * 4;\n\n maskCanvasEl.width = canvasEl.width;\n maskCanvasEl.height = canvasEl.height;\n\n maskCanvasEl.getContext('2d').drawImage(maskEl, 0, 0, canvasEl.width, canvasEl.height);\n\n var maskImageData = maskCanvasEl.getContext('2d').getImageData(0, 0, canvasEl.width, canvasEl.height),\n maskData = maskImageData.data;\n\n for (i = 0; i < iLen; i += 4) {\n data[i + 3] = maskData[i + channel];\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n mask: this.mask.toObject(),\n channel: this.channel\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when a mask filter instance is created\n */\n fabric.Image.filters.Mask.fromObject = function(object, callback) {\n fabric.util.loadImage(object.mask.src, function(img) {\n object.mask = new fabric.Image(img, object.mask);\n return fabric.Image.filters.BaseFilter.fromObject(object, callback);\n });\n };\n\n /**\n * Indicates that instances of this type are async\n * @static\n * @type Boolean\n * @default\n */\n fabric.Image.filters.Mask.async = true;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Noise filter class\n * @class fabric.Image.filters.Noise\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Noise({\n * noise: 700\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Noise',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Noise.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.noise=0] Noise value\n */\n initialize: function(options) {\n options = options || { };\n this.noise = options.noise || 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n noise = this.noise, rand;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n\n rand = (0.5 - Math.random()) * noise;\n\n data[i] += rand;\n data[i + 1] += rand;\n data[i + 2] += rand;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n noise: this.noise\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise\n */\n fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Pixelate filter class\n * @class fabric.Image.filters.Pixelate\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Pixelate({\n * blocksize: 8\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Pixelate',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Pixelate.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.blocksize=4] Blocksize for pixelate\n */\n initialize: function(options) {\n options = options || { };\n this.blocksize = options.blocksize || 4;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = imageData.height,\n jLen = imageData.width,\n index, i, j, r, g, b, a;\n\n for (i = 0; i < iLen; i += this.blocksize) {\n for (j = 0; j < jLen; j += this.blocksize) {\n\n index = (i * 4) * jLen + (j * 4);\n\n r = data[index];\n g = data[index + 1];\n b = data[index + 2];\n a = data[index + 3];\n\n /*\n blocksize: 4\n\n [1,x,x,x,1]\n [x,x,x,x,1]\n [x,x,x,x,1]\n [x,x,x,x,1]\n [1,1,1,1,1]\n */\n\n for (var _i = i, _ilen = i + this.blocksize; _i < _ilen; _i++) {\n for (var _j = j, _jlen = j + this.blocksize; _j < _jlen; _j++) {\n index = (_i * 4) * jLen + (_j * 4);\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = a;\n }\n }\n }\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n blocksize: this.blocksize\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate\n */\n fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Remove white filter class\n * @class fabric.Image.filters.RemoveWhite\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.RemoveWhite#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.RemoveWhite({\n * threshold: 40,\n * distance: 140\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.RemoveWhite = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveWhite.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'RemoveWhite',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.RemoveWhite.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.threshold=30] Threshold value\n * @param {Number} [options.distance=20] Distance value\n */\n initialize: function(options) {\n options = options || { };\n this.threshold = options.threshold || 30;\n this.distance = options.distance || 20;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n threshold = this.threshold,\n distance = this.distance,\n limit = 255 - threshold,\n abs = Math.abs,\n r, g, b;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n if (r > limit &&\n g > limit &&\n b > limit &&\n abs(r - g) < distance &&\n abs(r - b) < distance &&\n abs(g - b) < distance\n ) {\n data[i + 3] = 0;\n }\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n threshold: this.threshold,\n distance: this.distance\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.RemoveWhite} Instance of fabric.Image.filters.RemoveWhite\n */\n fabric.Image.filters.RemoveWhite.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Sepia filter class\n * @class fabric.Image.filters.Sepia\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Sepia();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Sepia = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Sepia.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Sepia',\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Sepia.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i, avg;\n\n for (i = 0; i < iLen; i += 4) {\n avg = 0.3 * data[i] + 0.59 * data[i + 1] + 0.11 * data[i + 2];\n data[i] = avg + 100;\n data[i + 1] = avg + 50;\n data[i + 2] = avg + 255;\n }\n\n context.putImageData(imageData, 0, 0);\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Sepia} Instance of fabric.Image.filters.Sepia\n */\n fabric.Image.filters.Sepia.fromObject = function(object, callback) {\n object = object || { };\n object.type = 'Sepia';\n return new fabric.Image.filters.BaseFilter.fromObject(object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Sepia2 filter class\n * @class fabric.Image.filters.Sepia2\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Sepia2();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Sepia2 = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Sepia2.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Sepia2',\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Sepia.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i, r, g, b;\n\n for (i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n data[i] = (r * 0.393 + g * 0.769 + b * 0.189 ) / 1.351;\n data[i + 1] = (r * 0.349 + g * 0.686 + b * 0.168 ) / 1.203;\n data[i + 2] = (r * 0.272 + g * 0.534 + b * 0.131 ) / 2.140;\n }\n\n context.putImageData(imageData, 0, 0);\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Sepia2} Instance of fabric.Image.filters.Sepia2\n */\n fabric.Image.filters.Sepia2.fromObject = function(object, callback) {\n object = object || { };\n object.type = 'Sepia2';\n return new fabric.Image.filters.BaseFilter.fromObject(object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Tint filter class\n * Adapted from https://github.com/mezzoblue/PaintbrushJS\n * @class fabric.Image.filters.Tint\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Tint#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example Tint filter with hex color and opacity\n * var filter = new fabric.Image.filters.Tint({\n * color: '#3513B0',\n * opacity: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Tint filter with rgba color\n * var filter = new fabric.Image.filters.Tint({\n * color: 'rgba(53, 21, 176, 0.5)'\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Tint = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Tint.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Tint',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Tint.prototype\n * @param {Object} [options] Options object\n * @param {String} [options.color=#000000] Color to tint the image with\n * @param {Number} [options.opacity] Opacity value that controls the tint effect's transparency (0..1)\n */\n initialize: function(options) {\n options = options || { };\n\n this.color = options.color || '#000000';\n this.opacity = typeof options.opacity !== 'undefined'\n ? options.opacity\n : new fabric.Color(this.color).getAlpha();\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i,\n tintR, tintG, tintB,\n r, g, b, alpha1,\n source;\n\n source = new fabric.Color(this.color).getSource();\n\n tintR = source[0] * this.opacity;\n tintG = source[1] * this.opacity;\n tintB = source[2] * this.opacity;\n\n alpha1 = 1 - this.opacity;\n\n for (i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n // alpha compositing\n data[i] = tintR + r * alpha1;\n data[i + 1] = tintG + g * alpha1;\n data[i + 2] = tintB + b * alpha1;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n color: this.color,\n opacity: this.opacity\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Tint} Instance of fabric.Image.filters.Tint\n */\n fabric.Image.filters.Tint.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Multiply filter class\n * Adapted from http://www.laurenscorijn.com/articles/colormath-basics\n * @class fabric.Image.filters.Multiply\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example Multiply filter with hex color\n * var filter = new fabric.Image.filters.Multiply({\n * color: '#F0F'\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n * @example Multiply filter with rgb color\n * var filter = new fabric.Image.filters.Multiply({\n * color: 'rgb(53, 21, 176)'\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Multiply = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Multiply.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Multiply',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Multiply.prototype\n * @param {Object} [options] Options object\n * @param {String} [options.color=#000000] Color to multiply the image pixels with\n */\n initialize: function(options) {\n options = options || { };\n\n this.color = options.color || '#000000';\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n iLen = data.length, i,\n source;\n\n source = new fabric.Color(this.color).getSource();\n\n for (i = 0; i < iLen; i += 4) {\n data[i] *= source[0] / 255;\n data[i + 1] *= source[1] / 255;\n data[i + 2] *= source[2] / 255;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n color: this.color\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Multiply} Instance of fabric.Image.filters.Multiply\n */\n fabric.Image.filters.Multiply.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n 'use strict';\n\n var fabric = global.fabric,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Color Blend filter class\n * @class fabric.Image.filter.Blend\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example\n * var filter = new fabric.Image.filters.Blend({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * var filter = new fabric.Image.filters.Blend({\n * image: fabricImageObject,\n * mode: 'multiply',\n * alpha: 0.5\n * });\n\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n\n filters.Blend = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ {\n type: 'Blend',\n\n initialize: function(options) {\n options = options || {};\n this.color = options.color || '#000';\n this.image = options.image || false;\n this.mode = options.mode || 'multiply';\n this.alpha = options.alpha || 1;\n },\n\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n tr, tg, tb,\n r, g, b,\n _r, _g, _b,\n source,\n isImage = false;\n\n if (this.image) {\n // Blend images\n isImage = true;\n\n var _el = fabric.util.createCanvasElement();\n _el.width = this.image.width;\n _el.height = this.image.height;\n\n var tmpCanvas = new fabric.StaticCanvas(_el);\n tmpCanvas.add(this.image);\n var context2 = tmpCanvas.getContext('2d');\n source = context2.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height).data;\n }\n else {\n // Blend color\n source = new fabric.Color(this.color).getSource();\n\n tr = source[0] * this.alpha;\n tg = source[1] * this.alpha;\n tb = source[2] * this.alpha;\n }\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n if (isImage) {\n tr = source[i] * this.alpha;\n tg = source[i + 1] * this.alpha;\n tb = source[i + 2] * this.alpha;\n }\n\n switch (this.mode) {\n case 'multiply':\n data[i] = r * tr / 255;\n data[i + 1] = g * tg / 255;\n data[i + 2] = b * tb / 255;\n break;\n case 'screen':\n data[i] = 1 - (1 - r) * (1 - tr);\n data[i + 1] = 1 - (1 - g) * (1 - tg);\n data[i + 2] = 1 - (1 - b) * (1 - tb);\n break;\n case 'add':\n data[i] = Math.min(255, r + tr);\n data[i + 1] = Math.min(255, g + tg);\n data[i + 2] = Math.min(255, b + tb);\n break;\n case 'diff':\n case 'difference':\n data[i] = Math.abs(r - tr);\n data[i + 1] = Math.abs(g - tg);\n data[i + 2] = Math.abs(b - tb);\n break;\n case 'subtract':\n _r = r - tr;\n _g = g - tg;\n _b = b - tb;\n\n data[i] = (_r < 0) ? 0 : _r;\n data[i + 1] = (_g < 0) ? 0 : _g;\n data[i + 2] = (_b < 0) ? 0 : _b;\n break;\n case 'darken':\n data[i] = Math.min(r, tr);\n data[i + 1] = Math.min(g, tg);\n data[i + 2] = Math.min(b, tb);\n break;\n case 'lighten':\n data[i] = Math.max(r, tr);\n data[i + 1] = Math.max(g, tg);\n data[i + 2] = Math.max(b, tb);\n break;\n }\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n color: this.color,\n image: this.image,\n mode: this.mode,\n alpha: this.alpha\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Blend} Instance of fabric.Image.filters.Blend\n */\n fabric.Image.filters.Blend.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor,\n sqrt = Math.sqrt, abs = Math.abs, max = Math.max, round = Math.round, sin = Math.sin,\n ceil = Math.ceil,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Resize image filter class\n * @class fabric.Image.filters.Resize\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Resize();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Resize',\n\n /**\n * Resize type\n * @param {String} resizeType\n * @default\n */\n resizeType: 'hermite',\n\n /**\n * Scale factor for resizing, x axis\n * @param {Number} scaleX\n * @default\n */\n scaleX: 0,\n\n /**\n * Scale factor for resizing, y axis\n * @param {Number} scaleY\n * @default\n */\n scaleY: 0,\n\n /**\n * LanczosLobes parameter for lanczos filter\n * @param {Number} lanczosLobes\n * @default\n */\n lanczosLobes: 3,\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Resize.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} scaleX\n * @param {Number} scaleY\n */\n applyTo: function(canvasEl, scaleX, scaleY) {\n if (scaleX === 1 && scaleY === 1) {\n return;\n }\n\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n\n var oW = canvasEl.width, oH = canvasEl.height,\n dW = round(oW * scaleX), dH = round(oH * scaleY),\n imageData;\n\n if (this.resizeType === 'sliceHack') {\n imageData = this.sliceByTwo(canvasEl, oW, oH, dW, dH);\n }\n if (this.resizeType === 'hermite') {\n imageData = this.hermiteFastResize(canvasEl, oW, oH, dW, dH);\n }\n if (this.resizeType === 'bilinear') {\n imageData = this.bilinearFiltering(canvasEl, oW, oH, dW, dH);\n }\n if (this.resizeType === 'lanczos') {\n imageData = this.lanczosResize(canvasEl, oW, oH, dW, dH);\n }\n canvasEl.width = dW;\n canvasEl.height = dH;\n canvasEl.getContext('2d').putImageData(imageData, 0, 0);\n },\n\n /**\n * Filter sliceByTwo\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n sliceByTwo: function(canvasEl, oW, oH, dW, dH) {\n var context = canvasEl.getContext('2d'), imageData,\n multW = 0.5, multH = 0.5, signW = 1, signH = 1,\n doneW = false, doneH = false, stepW = oW, stepH = oH,\n tmpCanvas = fabric.util.createCanvasElement(),\n tmpCtx = tmpCanvas.getContext('2d');\n dW = floor(dW);\n dH = floor(dH);\n tmpCanvas.width = max(dW, oW);\n tmpCanvas.height = max(dH, oH);\n\n if (dW > oW) {\n multW = 2;\n signW = -1;\n }\n if (dH > oH) {\n multH = 2;\n signH = -1;\n }\n imageData = context.getImageData(0, 0, oW, oH);\n canvasEl.width = max(dW, oW);\n canvasEl.height = max(dH, oH);\n context.putImageData(imageData, 0, 0);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n if (dW * signW < floor(stepW * multW * signW)) {\n stepW = floor(stepW * multW);\n }\n else {\n stepW = dW;\n doneW = true;\n }\n if (dH * signH < floor(stepH * multH * signH)) {\n stepH = floor(stepH * multH);\n }\n else {\n stepH = dH;\n doneH = true;\n }\n imageData = context.getImageData(0, 0, oW, oH);\n tmpCtx.putImageData(imageData, 0, 0);\n context.clearRect(0, 0, stepW, stepH);\n context.drawImage(tmpCanvas, 0, 0, oW, oH, 0, 0, stepW, stepH);\n }\n return context.getImageData(0, 0, dW, dH);\n },\n\n /**\n * Filter lanczosResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n lanczosResize: function(canvasEl, oW, oH, dW, dH) {\n\n function lanczosCreate(lobes) {\n return function(x) {\n if (x > lobes) {\n return 0;\n }\n x *= Math.PI;\n if (abs(x) < 1e-16) {\n return 1;\n }\n var xx = x / lobes;\n return sin(x) * sin(xx) / x / xx;\n };\n }\n\n function process(u) {\n var v, i, weight, idx, a, red, green,\n blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = floor(center.x);\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = floor(center.y);\n a = 0; red = 0; green = 0; blue = 0; alpha = 0;\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n fX = floor(1000 * abs(i - center.x));\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = { };\n }\n for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n fY = floor(1000 * abs(j - center.y));\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000);\n }\n weight = cacheLanc[fX][fY];\n if (weight > 0) {\n idx = (j * oW + i) * 4;\n a += weight;\n red += weight * srcData[idx];\n green += weight * srcData[idx + 1];\n blue += weight * srcData[idx + 2];\n alpha += weight * srcData[idx + 3];\n }\n }\n }\n idx = (v * dW + u) * 4;\n destData[idx] = red / a;\n destData[idx + 1] = green / a;\n destData[idx + 2] = blue / a;\n destData[idx + 3] = alpha / a;\n }\n\n if (++u < dW) {\n return process(u);\n }\n else {\n return destImg;\n }\n }\n\n var context = canvasEl.getContext('2d'),\n srcImg = context.getImageData(0, 0, oW, oH),\n destImg = context.getImageData(0, 0, dW, dH),\n srcData = srcImg.data, destData = destImg.data,\n lanczos = lanczosCreate(this.lanczosLobes),\n ratioX = this.rcpScaleX, ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY,\n range2X = ceil(ratioX * this.lanczosLobes / 2),\n range2Y = ceil(ratioY * this.lanczosLobes / 2),\n cacheLanc = { }, center = { }, icenter = { };\n\n return process(0);\n },\n\n /**\n * bilinearFiltering\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n bilinearFiltering: function(canvasEl, oW, oH, dW, dH) {\n var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl,\n color, offset = 0, origPix, ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY, context = canvasEl.getContext('2d'),\n w4 = 4 * (oW - 1), img = context.getImageData(0, 0, oW, oH),\n pixels = img.data, destImage = context.getImageData(0, 0, dW, dH),\n destPixels = destImage.data;\n for (i = 0; i < dH; i++) {\n for (j = 0; j < dW; j++) {\n x = floor(ratioX * j);\n y = floor(ratioY * i);\n xDiff = ratioX * j - x;\n yDiff = ratioY * i - y;\n origPix = 4 * (y * oW + x);\n\n for (chnl = 0; chnl < 4; chnl++) {\n a = pixels[origPix + chnl];\n b = pixels[origPix + 4 + chnl];\n c = pixels[origPix + w4 + chnl];\n d = pixels[origPix + w4 + 4 + chnl];\n color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) +\n c * yDiff * (1 - xDiff) + d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\n }\n }\n return destImage;\n },\n\n /**\n * hermiteFastResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n hermiteFastResize: function(canvasEl, oW, oH, dW, dH) {\n var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY,\n ratioWHalf = ceil(ratioW / 2),\n ratioHHalf = ceil(ratioH / 2),\n context = canvasEl.getContext('2d'),\n img = context.getImageData(0, 0, oW, oH), data = img.data,\n img2 = context.getImageData(0, 0, dW, dH), data2 = img2.data;\n for (var j = 0; j < dH; j++) {\n for (var i = 0; i < dW; i++) {\n var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0,\n gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH;\n for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n var dy = abs(centerY - (yy + 0.5)) / ratioHHalf,\n centerX = (i + 0.5) * ratioW, w0 = dy * dy;\n for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n var dx = abs(centerX - (xx + 0.5)) / ratioWHalf,\n w = sqrt(w0 + dx * dx);\n /* eslint-disable max-depth */\n if (w > 1 && w < -1) {\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n if (weight > 0) {\n dx = 4 * (xx + yy * oW);\n //alpha\n gxA += weight * data[dx + 3];\n weightsAlpha += weight;\n //colors\n if (data[dx + 3] < 255) {\n weight = weight * data[dx + 3] / 250;\n }\n gxR += weight * data[dx];\n gxG += weight * data[dx + 1];\n gxB += weight * data[dx + 2];\n weights += weight;\n }\n /* eslint-enable max-depth */\n }\n }\n data2[x2] = gxR / weights;\n data2[x2 + 1] = gxG / weights;\n data2[x2 + 2] = gxB / weights;\n data2[x2 + 3] = gxA / weightsAlpha;\n }\n }\n return img2;\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n type: this.type,\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n resizeType: this.resizeType,\n lanczosLobes: this.lanczosLobes\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize\n */\n fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Color Matrix filter class\n * @class fabric.Image.filters.ColorMatrix\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php}\n * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl}\n * @example Kodachrome filter\n * var filter = new fabric.Image.filters.ColorMatrix({\n * matrix: [\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0\n ]\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'ColorMatrix',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.ColorMatrix.prototype\n * @param {Object} [options] Options object\n * @param {Array} [options.matrix] Color Matrix to modify the image data with\n */\n initialize: function( options ) {\n options || ( options = {} );\n this.matrix = options.matrix || [\n 1, 0, 0, 0, 0,\n 0, 1, 0, 0, 0,\n 0, 0, 1, 0, 0,\n 0, 0, 0, 1, 0\n ];\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function( canvasEl ) {\n var context = canvasEl.getContext( '2d' ),\n imageData = context.getImageData( 0, 0, canvasEl.width, canvasEl.height ),\n data = imageData.data,\n iLen = data.length,\n i,\n r,\n g,\n b,\n a,\n m = this.matrix;\n\n for ( i = 0; i < iLen; i += 4 ) {\n r = data[ i ];\n g = data[ i + 1 ];\n b = data[ i + 2 ];\n a = data[ i + 3 ];\n\n data[ i ] = r * m[ 0 ] + g * m[ 1 ] + b * m[ 2 ] + a * m[ 3 ] + m[ 4 ];\n data[ i + 1 ] = r * m[ 5 ] + g * m[ 6 ] + b * m[ 7 ] + a * m[ 8 ] + m[ 9 ];\n data[ i + 2 ] = r * m[ 10 ] + g * m[ 11 ] + b * m[ 12 ] + a * m[ 13 ] + m[ 14 ];\n data[ i + 3 ] = r * m[ 15 ] + g * m[ 16 ] + b * m[ 17 ] + a * m[ 18 ] + m[ 19 ];\n }\n\n context.putImageData( imageData, 0, 0 );\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n type: this.type,\n matrix: this.matrix\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] function to invoke after filter creation\n * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix\n */\n fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Contrast filter class\n * @class fabric.Image.filters.Contrast\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Contrast({\n * contrast: 40\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Contrast',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Contrast.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.contrast=0] Value to contrast the image up (-255...255)\n */\n initialize: function(options) {\n options = options || { };\n this.contrast = options.contrast || 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n contrastF = 259 * (this.contrast + 255) / (255 * (259 - this.contrast));\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n data[i] = contrastF * (data[i] - 128) + 128;\n data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n contrast: this.contrast\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast\n */\n fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Saturate filter class\n * @class fabric.Image.filters.Saturate\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Saturate#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Saturate({\n * saturate: 100\n * });\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Saturate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturate.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Saturate',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Saturate.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.saturate=0] Value to saturate the image (-100...100)\n */\n initialize: function(options) {\n options = options || { };\n this.saturate = options.saturate || 0;\n },\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo: function(canvasEl) {\n var context = canvasEl.getContext('2d'),\n imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),\n data = imageData.data,\n max, adjust = -this.saturate * 0.01;\n\n for (var i = 0, len = data.length; i < len; i += 4) {\n max = Math.max(data[i], data[i + 1], data[i + 2]);\n data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n }\n\n context.putImageData(imageData, 0, 0);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n saturate: this.saturate\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Saturate} Instance of fabric.Image.filters.Saturate\n */\n fabric.Image.filters.Saturate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n toFixed = fabric.util.toFixed,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n MIN_TEXT_WIDTH = 2;\n\n if (fabric.Text) {\n fabric.warn('fabric.Text is already defined');\n return;\n }\n\n /**\n * Text class\n * @class fabric.Text\n * @extends fabric.Object\n * @return {fabric.Text} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n * @see {@link fabric.Text#initialize} for constructor definition\n */\n fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ {\n\n /**\n * Properties which when set cause object to change dimensions\n * @type Object\n * @private\n */\n _dimensionAffectingProps: [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign'\n ],\n\n /**\n * @private\n */\n _reNewline: /\\r?\\n/,\n\n /**\n * Use this regular expression to filter for whitespace that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reSpacesAndTabs: /[ \\t\\r]+/g,\n\n /**\n * Retrieves object's fontSize\n * @method getFontSize\n * @memberOf fabric.Text.prototype\n * @return {String} Font size (in pixels)\n */\n\n /**\n * Sets object's fontSize\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setFontSize\n * @memberOf fabric.Text.prototype\n * @param {Number} fontSize Font size (in pixels)\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's fontWeight\n * @method getFontWeight\n * @memberOf fabric.Text.prototype\n * @return {(String|Number)} Font weight\n */\n\n /**\n * Sets object's fontWeight\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setFontWeight\n * @memberOf fabric.Text.prototype\n * @param {(Number|String)} fontWeight Font weight\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's fontFamily\n * @method getFontFamily\n * @memberOf fabric.Text.prototype\n * @return {String} Font family\n */\n\n /**\n * Sets object's fontFamily\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setFontFamily\n * @memberOf fabric.Text.prototype\n * @param {String} fontFamily Font family\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's text\n * @method getText\n * @memberOf fabric.Text.prototype\n * @return {String} text\n */\n\n /**\n * Sets object's text\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setText\n * @memberOf fabric.Text.prototype\n * @param {String} text Text\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's textDecoration\n * @method getTextDecoration\n * @memberOf fabric.Text.prototype\n * @return {String} Text decoration\n */\n\n /**\n * Sets object's textDecoration\n * @method setTextDecoration\n * @memberOf fabric.Text.prototype\n * @param {String} textDecoration Text decoration\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's fontStyle\n * @method getFontStyle\n * @memberOf fabric.Text.prototype\n * @return {String} Font style\n */\n\n /**\n * Sets object's fontStyle\n * Does not update the object .width and .height,\n * call ._initDimensions() to update the values.\n * @method setFontStyle\n * @memberOf fabric.Text.prototype\n * @param {String} fontStyle Font style\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's lineHeight\n * @method getLineHeight\n * @memberOf fabric.Text.prototype\n * @return {Number} Line height\n */\n\n /**\n * Sets object's lineHeight\n * @method setLineHeight\n * @memberOf fabric.Text.prototype\n * @param {Number} lineHeight Line height\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's textAlign\n * @method getTextAlign\n * @memberOf fabric.Text.prototype\n * @return {String} Text alignment\n */\n\n /**\n * Sets object's textAlign\n * @method setTextAlign\n * @memberOf fabric.Text.prototype\n * @param {String} textAlign Text alignment\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Retrieves object's textBackgroundColor\n * @method getTextBackgroundColor\n * @memberOf fabric.Text.prototype\n * @return {String} Text background color\n */\n\n /**\n * Sets object's textBackgroundColor\n * @method setTextBackgroundColor\n * @memberOf fabric.Text.prototype\n * @param {String} textBackgroundColor Text background color\n * @return {fabric.Text}\n * @chainable\n */\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'text',\n\n /**\n * Font size (in pixels)\n * @type Number\n * @default\n */\n fontSize: 40,\n\n /**\n * Font weight (e.g. bold, normal, 400, 600, 800)\n * @type {(Number|String)}\n * @default\n */\n fontWeight: 'normal',\n\n /**\n * Font family\n * @type String\n * @default\n */\n fontFamily: 'Times New Roman',\n\n /**\n * Text decoration Possible values: \"\", \"underline\", \"overline\" or \"line-through\".\n * @type String\n * @default\n */\n textDecoration: '',\n\n /**\n * Text alignment. Possible values: \"left\", \"center\", \"right\" or \"justify\".\n * @type String\n * @default\n */\n textAlign: 'left',\n\n /**\n * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n * @type String\n * @default\n */\n fontStyle: '',\n\n /**\n * Line height\n * @type Number\n * @default\n */\n lineHeight: 1.16,\n\n /**\n * Background color of text lines\n * @type String\n * @default\n */\n textBackgroundColor: '',\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat(\n 'fontFamily',\n 'fontWeight',\n 'fontSize',\n 'text',\n 'textDecoration',\n 'textAlign',\n 'fontStyle',\n 'lineHeight',\n 'textBackgroundColor',\n 'charSpacing'),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * @type Array\n */\n cacheProperties: fabric.Object.prototype.cacheProperties.concat(\n 'fontFamily',\n 'fontWeight',\n 'fontSize',\n 'text',\n 'textDecoration',\n 'textAlign',\n 'fontStyle',\n 'lineHeight',\n 'textBackgroundColor',\n 'charSpacing',\n 'styles'),\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color.\n * Backwards incompatibility note: This property was named \"strokeStyle\" until v1.1.6\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property was named \"textShadow\" (String) until v1.2.11\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * @private\n */\n _fontSizeFraction: 0.25,\n\n /**\n * Text Line proportion to font Size (in pixels)\n * @type Number\n * @default\n */\n _fontSizeMult: 1.13,\n\n /**\n * additional space between characters\n * expressed in thousands of em unit\n * @type Number\n * @default\n */\n charSpacing: 0,\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Text} thisArg\n */\n initialize: function(text, options) {\n options = options || { };\n this.text = text;\n this.__skipDimension = true;\n this.callSuper('initialize', options);\n this.__skipDimension = false;\n this._initDimensions();\n this.setCoords();\n this.setupState({ propertySet: '_dimensionAffectingProps' });\n },\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @param {CanvasRenderingContext2D} [ctx] Context to render on\n * @private\n */\n _initDimensions: function(ctx) {\n if (this.__skipDimension) {\n return;\n }\n if (!ctx) {\n ctx = fabric.util.createCanvasElement().getContext('2d');\n this._setTextStyles(ctx);\n }\n this._textLines = this._splitTextIntoLines();\n this._clearCache();\n this.width = this._getTextWidth(ctx) || this.cursorWidth || MIN_TEXT_WIDTH;\n this.height = this._getTextHeight(ctx);\n this.setCoords();\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of text object\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function() {\n var dims = this.callSuper('_getCacheCanvasDimensions');\n var fontSize = this.fontSize;\n dims.width += fontSize * dims.zoomX;\n dims.height += fontSize * dims.zoomY;\n return dims;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n this._setTextStyles(ctx);\n if (this.group && this.group.type === 'path-group') {\n ctx.translate(this.left, this.top);\n }\n this._renderTextLinesBackground(ctx);\n this._renderText(ctx);\n this._renderTextDecoration(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText: function(ctx) {\n this._renderTextFill(ctx);\n this._renderTextStroke(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setTextStyles: function(ctx) {\n ctx.textBaseline = 'alphabetic';\n ctx.font = this._getFontDeclaration();\n },\n\n /**\n * @private\n * @return {Number} Height of fabric.Text object\n */\n _getTextHeight: function() {\n return this._getHeightOfSingleLine() + (this._textLines.length - 1) * this._getHeightOfLine();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {Number} Maximum width of fabric.Text object\n */\n _getTextWidth: function(ctx) {\n var maxWidth = this._getLineWidth(ctx, 0);\n\n for (var i = 1, len = this._textLines.length; i < len; i++) {\n var currentLineWidth = this._getLineWidth(ctx, i);\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\n }\n return maxWidth;\n },\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} chars Chars to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n */\n _renderChars: function(method, ctx, chars, left, top) {\n // remove Text word from method var\n var shortM = method.slice(0, -4), _char, width;\n if (this[shortM].toLive) {\n var offsetX = -this.width / 2 + this[shortM].offsetX || 0,\n offsetY = -this.height / 2 + this[shortM].offsetY || 0;\n ctx.save();\n ctx.translate(offsetX, offsetY);\n left -= offsetX;\n top -= offsetY;\n }\n if (this.charSpacing !== 0) {\n var additionalSpace = this._getWidthOfCharSpacing();\n chars = chars.split('');\n for (var i = 0, len = chars.length; i < len; i++) {\n _char = chars[i];\n width = ctx.measureText(_char).width + additionalSpace;\n ctx[method](_char, left, top);\n left += width > 0 ? width : 0;\n }\n }\n else {\n ctx[method](chars, left, top);\n }\n this[shortM].toLive && ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Text to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n * @param {Number} lineIndex Index of a line in a text\n */\n _renderTextLine: function(method, ctx, line, left, top, lineIndex) {\n // lift the line by quarter of fontSize\n top -= this.fontSize * this._fontSizeFraction;\n\n // short-circuit\n var lineWidth = this._getLineWidth(ctx, lineIndex);\n if (this.textAlign !== 'justify' || this.width < lineWidth) {\n this._renderChars(method, ctx, line, left, top, lineIndex);\n return;\n }\n\n // stretch the line\n var words = line.split(/\\s+/),\n charOffset = 0,\n wordsWidth = this._getWidthOfWords(ctx, words.join(' '), lineIndex, 0),\n widthDiff = this.width - wordsWidth,\n numSpaces = words.length - 1,\n spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0,\n leftOffset = 0, word;\n\n for (var i = 0, len = words.length; i < len; i++) {\n while (line[charOffset] === ' ' && charOffset < line.length) {\n charOffset++;\n }\n word = words[i];\n this._renderChars(method, ctx, word, left + leftOffset, top, lineIndex, charOffset);\n leftOffset += this._getWidthOfWords(ctx, word, lineIndex, charOffset) + spaceWidth;\n charOffset += word.length;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} word\n */\n _getWidthOfWords: function (ctx, word) {\n var width = ctx.measureText(word).width, charCount, additionalSpace;\n if (this.charSpacing !== 0) {\n charCount = word.split('').length;\n additionalSpace = charCount * this._getWidthOfCharSpacing();\n width += additionalSpace;\n }\n return width > 0 ? width : 0;\n },\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset: function() {\n return -this.width / 2;\n },\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset: function() {\n return -this.height / 2;\n },\n\n /**\n * Returns true because text has no style\n */\n isEmptyStyles: function() {\n return true;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n */\n _renderTextCommon: function(ctx, method) {\n\n var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset();\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n var heightOfLine = this._getHeightOfLine(ctx, i),\n maxHeight = heightOfLine / this.lineHeight,\n lineWidth = this._getLineWidth(ctx, i),\n leftOffset = this._getLineLeftOffset(lineWidth);\n this._renderTextLine(\n method,\n ctx,\n this._textLines[i],\n left + leftOffset,\n top + lineHeights + maxHeight,\n i\n );\n lineHeights += heightOfLine;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill: function(ctx) {\n if (!this.fill && this.isEmptyStyles()) {\n return;\n }\n\n this._renderTextCommon(ctx, 'fillText');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextStroke: function(ctx) {\n if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray);\n ctx.beginPath();\n this._renderTextCommon(ctx, 'strokeText');\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * @private\n * @return {Number} height of line\n */\n _getHeightOfLine: function() {\n return this._getHeightOfSingleLine() * this.lineHeight;\n },\n\n /**\n * @private\n * @return {Number} height of line without lineHeight\n */\n _getHeightOfSingleLine: function() {\n return this.fontSize * this._fontSizeMult;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground: function(ctx) {\n if (!this.textBackgroundColor) {\n return;\n }\n var lineTopOffset = 0, heightOfLine,\n lineWidth, lineLeftOffset, originalFill = ctx.fillStyle;\n\n ctx.fillStyle = this.textBackgroundColor;\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this._getHeightOfLine(ctx, i);\n lineWidth = this._getLineWidth(ctx, i);\n if (lineWidth > 0) {\n lineLeftOffset = this._getLineLeftOffset(lineWidth);\n ctx.fillRect(\n this._getLeftOffset() + lineLeftOffset,\n this._getTopOffset() + lineTopOffset,\n lineWidth,\n heightOfLine / this.lineHeight\n );\n }\n lineTopOffset += heightOfLine;\n }\n ctx.fillStyle = originalFill;\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {Number} lineWidth Width of text line\n * @return {Number} Line left offset\n */\n _getLineLeftOffset: function(lineWidth) {\n if (this.textAlign === 'center') {\n return (this.width - lineWidth) / 2;\n }\n if (this.textAlign === 'right') {\n return this.width - lineWidth;\n }\n return 0;\n },\n\n /**\n * @private\n */\n _clearCache: function() {\n this.__lineWidths = [];\n this.__lineHeights = [];\n },\n\n /**\n * @private\n */\n _shouldClearDimensionCache: function() {\n var shouldClear = this._forceClearCache;\n shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps'));\n if (shouldClear) {\n this.saveState({ propertySet: '_dimensionAffectingProps' });\n this.dirty = true;\n }\n return shouldClear;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n _getLineWidth: function(ctx, lineIndex) {\n if (this.__lineWidths[lineIndex]) {\n return this.__lineWidths[lineIndex] === -1 ? this.width : this.__lineWidths[lineIndex];\n }\n\n var width, wordCount, line = this._textLines[lineIndex];\n\n if (line === '') {\n width = 0;\n }\n else {\n width = this._measureLine(ctx, lineIndex);\n }\n this.__lineWidths[lineIndex] = width;\n\n if (width && this.textAlign === 'justify') {\n wordCount = line.split(/\\s+/);\n if (wordCount.length > 1) {\n this.__lineWidths[lineIndex] = -1;\n }\n }\n return width;\n },\n\n _getWidthOfCharSpacing: function() {\n if (this.charSpacing !== 0) {\n return this.fontSize * this.charSpacing / 1000;\n }\n return 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n _measureLine: function(ctx, lineIndex) {\n var line = this._textLines[lineIndex],\n width = ctx.measureText(line).width,\n additionalSpace = 0, charCount, finalWidth;\n if (this.charSpacing !== 0) {\n charCount = line.split('').length;\n additionalSpace = (charCount - 1) * this._getWidthOfCharSpacing();\n }\n finalWidth = width + additionalSpace;\n return finalWidth > 0 ? finalWidth : 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration: function(ctx) {\n if (!this.textDecoration) {\n return;\n }\n var halfOfVerticalBox = this.height / 2,\n _this = this, offsets = [];\n\n /** @ignore */\n function renderLinesAtOffset(offsets) {\n var i, lineHeight = 0, len, j, oLen, lineWidth,\n lineLeftOffset, heightOfLine;\n\n for (i = 0, len = _this._textLines.length; i < len; i++) {\n\n lineWidth = _this._getLineWidth(ctx, i);\n lineLeftOffset = _this._getLineLeftOffset(lineWidth);\n heightOfLine = _this._getHeightOfLine(ctx, i);\n\n for (j = 0, oLen = offsets.length; j < oLen; j++) {\n ctx.fillRect(\n _this._getLeftOffset() + lineLeftOffset,\n lineHeight + (_this._fontSizeMult - 1 + offsets[j] ) * _this.fontSize - halfOfVerticalBox,\n lineWidth,\n _this.fontSize / 15);\n }\n lineHeight += heightOfLine;\n }\n }\n\n if (this.textDecoration.indexOf('underline') > -1) {\n offsets.push(0.85); // 1 - 3/16\n }\n if (this.textDecoration.indexOf('line-through') > -1) {\n offsets.push(0.43);\n }\n if (this.textDecoration.indexOf('overline') > -1) {\n offsets.push(-0.12);\n }\n if (offsets.length > 0) {\n renderLinesAtOffset(offsets);\n }\n },\n\n /**\n * return font declaration string for canvas context\n * @returns {String} font declaration formatted for canvas context.\n */\n _getFontDeclaration: function() {\n return [\n // node-canvas needs \"weight style\", while browsers need \"style weight\"\n (fabric.isLikelyNode ? this.fontWeight : this.fontStyle),\n (fabric.isLikelyNode ? this.fontStyle : this.fontWeight),\n this.fontSize + 'px',\n (fabric.isLikelyNode ? ('\"' + this.fontFamily + '\"') : this.fontFamily)\n ].join(' ');\n },\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n render: function(ctx, noTransform) {\n // do not render if object is not visible\n if (!this.visible) {\n return;\n }\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n if (this._shouldClearDimensionCache()) {\n this._setTextStyles(ctx);\n this._initDimensions(ctx);\n }\n this.callSuper('render', ctx, noTransform);\n },\n\n /**\n * Returns the text as an array of lines.\n * @returns {Array} Lines in the text\n */\n _splitTextIntoLines: function() {\n return this.text.split(this._reNewline);\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var additionalProperties = [\n 'text',\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n 'lineHeight',\n 'textDecoration',\n 'textAlign',\n 'textBackgroundColor',\n 'charSpacing'\n ].concat(propertiesToInclude);\n return this.callSuper('toObject', additionalProperties);\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n if (!this.ctx) {\n this.ctx = fabric.util.createCanvasElement().getContext('2d');\n }\n var markup = this._createBaseSVGMarkup(),\n offsets = this._getSVGLeftTopOffsets(this.ctx),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n this._wrapSVGTextAndBg(markup, textAndBg);\n\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n\n /**\n * @private\n */\n _getSVGLeftTopOffsets: function(ctx) {\n var lineTop = this._getHeightOfLine(ctx, 0),\n textLeft = -this.width / 2,\n textTop = 0;\n\n return {\n textLeft: textLeft + (this.group && this.group.type === 'path-group' ? this.left : 0),\n textTop: textTop + (this.group && this.group.type === 'path-group' ? -this.top : 0),\n lineTop: lineTop\n };\n },\n\n /**\n * @private\n */\n _wrapSVGTextAndBg: function(markup, textAndBg) {\n var noShadow = true, filter = this.getSvgFilter(),\n style = filter === '' ? '' : ' style=\"' + filter + '\"';\n\n markup.push(\n '\\t\\n',\n textAndBg.textBgRects.join(''),\n '\\t\\t\\n',\n textAndBg.textSpans.join(''),\n '\\t\\t\\n',\n '\\t\\n'\n );\n },\n\n getSvgStyles: function(skipShadow) {\n var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow);\n return svgStyle + ' white-space: pre;';\n },\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n _getSVGTextAndBg: function(textTopOffset, textLeftOffset) {\n var textSpans = [],\n textBgRects = [],\n height = 0;\n // bounding-box background\n this._setSVGBg(textBgRects);\n\n // text and text-background\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n if (this.textBackgroundColor) {\n this._setSVGTextLineBg(textBgRects, i, textLeftOffset, textTopOffset, height);\n }\n this._setSVGTextLineText(i, textSpans, height, textLeftOffset, textTopOffset, textBgRects);\n height += this._getHeightOfLine(this.ctx, i);\n }\n\n return {\n textSpans: textSpans,\n textBgRects: textBgRects\n };\n },\n\n _setSVGTextLineText: function(i, textSpans, height, textLeftOffset, textTopOffset) {\n var yPos = this.fontSize * (this._fontSizeMult - this._fontSizeFraction)\n - textTopOffset + height - this.height / 2;\n if (this.textAlign === 'justify') {\n // i call from here to do not intefere with IText\n this._setSVGTextLineJustifed(i, textSpans, yPos, textLeftOffset);\n return;\n }\n textSpans.push(\n '\\t\\t\\t elements since setting opacity\n // on containing one doesn't work in Illustrator\n this._getFillAttributes(this.fill), '>',\n fabric.util.string.escapeXml(this._textLines[i]),\n '\\n'\n );\n },\n\n _setSVGTextLineJustifed: function(i, textSpans, yPos, textLeftOffset) {\n var ctx = fabric.util.createCanvasElement().getContext('2d');\n\n this._setTextStyles(ctx);\n\n var line = this._textLines[i],\n words = line.split(/\\s+/),\n wordsWidth = this._getWidthOfWords(ctx, words.join('')),\n widthDiff = this.width - wordsWidth,\n numSpaces = words.length - 1,\n spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0,\n word, attributes = this._getFillAttributes(this.fill),\n len;\n\n textLeftOffset += this._getLineLeftOffset(this._getLineWidth(ctx, i));\n\n for (i = 0, len = words.length; i < len; i++) {\n word = words[i];\n textSpans.push(\n '\\t\\t\\t elements since setting opacity\n // on containing one doesn't work in Illustrator\n attributes, '>',\n fabric.util.string.escapeXml(word),\n '\\n'\n );\n textLeftOffset += this._getWidthOfWords(ctx, word) + spaceWidth;\n }\n },\n\n _setSVGTextLineBg: function(textBgRects, i, textLeftOffset, textTopOffset, height) {\n textBgRects.push(\n '\\t\\t\\n');\n },\n\n _setSVGBg: function(textBgRects) {\n if (this.backgroundColor) {\n textBgRects.push(\n '\\t\\t\\n');\n }\n },\n\n /**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n *\n * @private\n * @param {*} value\n * @return {String}\n */\n _getFillAttributes: function(value) {\n var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : '';\n if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {\n return 'fill=\"' + value + '\"';\n }\n return 'opacity=\"' + fillColor.getAlpha() + '\" fill=\"' + fillColor.setAlpha(1).toRgb() + '\"';\n },\n /* _TO_SVG_END_ */\n\n /**\n * Sets specified property to a specified value\n * @param {String} key\n * @param {*} value\n * @return {fabric.Text} thisArg\n * @chainable\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n\n if (this._dimensionAffectingProps.indexOf(key) > -1) {\n this._initDimensions();\n this.setCoords();\n }\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity: function() {\n return 1;\n }\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement})\n * @static\n * @memberOf fabric.Text\n * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n */\n fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(\n 'x y dx dy font-family font-style font-weight font-size text-decoration text-anchor'.split(' '));\n\n /**\n * Default SVG font size\n * @static\n * @memberOf fabric.Text\n */\n fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;\n\n /**\n * Returns fabric.Text instance from an SVG element (not yet implemented)\n * @static\n * @memberOf fabric.Text\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @return {fabric.Text} Instance of fabric.Text\n */\n fabric.Text.fromElement = function(element, options) {\n if (!element) {\n return null;\n }\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES);\n options = fabric.util.object.extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes);\n\n options.top = options.top || 0;\n options.left = options.left || 0;\n if ('dx' in parsedAttributes) {\n options.left += parsedAttributes.dx;\n }\n if ('dy' in parsedAttributes) {\n options.top += parsedAttributes.dy;\n }\n if (!('fontSize' in options)) {\n options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n\n if (!options.originX) {\n options.originX = 'left';\n }\n\n var textContent = '';\n\n // The XML is not properly parsed in IE9 so a workaround to get\n // textContent is through firstChild.data. Another workaround would be\n // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does)\n if (!('textContent' in element)) {\n if ('firstChild' in element && element.firstChild !== null) {\n if ('data' in element.firstChild && element.firstChild.data !== null) {\n textContent = element.firstChild.data;\n }\n }\n }\n else {\n textContent = element.textContent;\n }\n\n textContent = textContent.replace(/^\\s+|\\s+$|\\n+/g, '').replace(/\\s+/g, ' ');\n\n var text = new fabric.Text(textContent, options),\n textHeightScaleFactor = text.getHeight() / text.height,\n lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height,\n scaledDiff = lineHeightDiff * textHeightScaleFactor,\n textHeight = text.getHeight() + scaledDiff,\n offX = 0;\n /*\n Adjust positioning:\n x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n top/left properties in Fabric correspond to center point of text bounding box\n */\n if (text.originX === 'left') {\n offX = text.getWidth() / 2;\n }\n if (text.originX === 'right') {\n offX = -text.getWidth() / 2;\n }\n text.set({\n left: text.getLeft() + offX,\n top: text.getTop() - textHeight / 2 + text.fontSize * (0.18 + text._fontSizeFraction) / text.lineHeight /* 0.3 is the old lineHeight */\n });\n\n return text;\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Text instance from an object representation\n * @static\n * @memberOf fabric.Text\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Text} Instance of fabric.Text\n */\n fabric.Text.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Text', object, callback, forceAsync, 'text');\n };\n\n fabric.util.createAccessors(fabric.Text);\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var clone = fabric.util.object.clone;\n\n /**\n * IText class (introduced in v1.4) Events are also fired with \"text:\"\n * prefix when observing canvas.\n * @class fabric.IText\n * @extends fabric.Text\n * @mixes fabric.Observable\n *\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n *\n * @return {fabric.IText} thisArg\n * @see {@link fabric.IText#initialize} for constructor definition\n *\n *

Supported key combinations:

\n *
\n   *   Move cursor:                    left, right, up, down\n   *   Select character:               shift + left, shift + right\n   *   Select text vertically:         shift + up, shift + down\n   *   Move cursor by word:            alt + left, alt + right\n   *   Select words:                   shift + alt + left, shift + alt + right\n   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end\n   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end\n   *   Jump to start/end of text:      cmd + up, cmd + down\n   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n   *   Delete character:               backspace\n   *   Delete word:                    alt + backspace\n   *   Delete line:                    cmd + backspace\n   *   Forward delete:                 delete\n   *   Copy text:                      ctrl/cmd + c\n   *   Paste text:                     ctrl/cmd + v\n   *   Cut text:                       ctrl/cmd + x\n   *   Select entire text:             ctrl/cmd + a\n   *   Quit editing                    tab or esc\n   * 
\n *\n *

Supported mouse/touch combination

\n *
\n   *   Position cursor:                click/touch\n   *   Create selection:               click/touch & drag\n   *   Create selection:               click & shift + click\n   *   Select word:                    double click\n   *   Select line:                    triple click\n   * 
\n */\n fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'i-text',\n\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n selectionStart: 0,\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n selectionEnd: 0,\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(17,119,255,0.3)',\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n isEditing: false,\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n editable: true,\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n editingBorderColor: 'rgba(102,153,255,0.25)',\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n cursorWidth: 2,\n\n /**\n * Color of default cursor (when not overwritten by character style)\n * @type String\n * @default\n */\n cursorColor: '#333',\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n cursorDelay: 1000,\n\n /**\n * Duration of cursor fadein (in ms)\n * @type Number\n * @default\n */\n cursorDuration: 600,\n\n /**\n * Object containing character styles\n * (where top-level properties corresponds to line number and 2nd-level properties -- to char number in a line)\n * @type Object\n * @default\n */\n styles: null,\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n caching: true,\n\n /**\n * @private\n */\n _reSpace: /\\s|\\n/,\n\n /**\n * @private\n */\n _currentCursorOpacity: 0,\n\n /**\n * @private\n */\n _selectionDirection: null,\n\n /**\n * @private\n */\n _abortCursorAnimation: false,\n\n /**\n * @private\n */\n __widthOfSpace: [],\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.IText} thisArg\n */\n initialize: function(text, options) {\n this.styles = options ? (options.styles || { }) : { };\n this.callSuper('initialize', text, options);\n this.initBehavior();\n },\n\n /**\n * @private\n */\n _clearCache: function() {\n this.callSuper('_clearCache');\n this.__widthOfSpace = [];\n },\n\n /**\n * Returns true if object has no styling\n */\n isEmptyStyles: function() {\n if (!this.styles) {\n return true;\n }\n var obj = this.styles;\n\n for (var p1 in obj) {\n for (var p2 in obj[p1]) {\n // eslint-disable-next-line no-unused-vars\n for (var p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n return true;\n },\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart: function(index) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n },\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd: function(index) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n },\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n _updateAndFire: function(property, index) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n },\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged: function() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n },\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at\n * @return {Object} styles Style object at a specified (or current) index\n */\n getSelectionStyles: function(startIndex, endIndex) {\n\n if (arguments.length === 2) {\n var styles = [];\n for (var i = startIndex; i < endIndex; i++) {\n styles.push(this.getSelectionStyles(i));\n }\n return styles;\n }\n\n var loc = this.get2DCursorLocation(startIndex),\n style = this._getStyleDeclaration(loc.lineIndex, loc.charIndex);\n\n return style || {};\n },\n\n /**\n * Sets style of a current selection\n * @param {Object} [styles] Styles object\n * @return {fabric.IText} thisArg\n * @chainable\n */\n setSelectionStyles: function(styles) {\n if (this.selectionStart === this.selectionEnd) {\n this._extendStyles(this.selectionStart, styles);\n }\n else {\n for (var i = this.selectionStart; i < this.selectionEnd; i++) {\n this._extendStyles(i, styles);\n }\n }\n /* not included in _extendStyles to avoid clearing cache more than once */\n this._forceClearCache = true;\n return this;\n },\n\n /**\n * @private\n */\n _extendStyles: function(index, styles) {\n var loc = this.get2DCursorLocation(index);\n\n if (!this._getLineStyle(loc.lineIndex)) {\n this._setLineStyle(loc.lineIndex, {});\n }\n\n if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) {\n this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {});\n }\n\n fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles);\n },\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @param {CanvasRenderingContext2D} [ctx] Context to render on\n * @private\n */\n _initDimensions: function(ctx) {\n if (!ctx) {\n this.clearContextTop();\n }\n this.callSuper('_initDimensions', ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Boolean} noTransform\n */\n render: function(ctx, noTransform) {\n this.clearContextTop();\n this.callSuper('render', ctx, noTransform);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = { };\n this.renderCursorOrSelection();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n this.callSuper('_render', ctx);\n this.ctx = ctx;\n },\n\n /**\n * Prepare and clean the contextTop\n */\n clearContextTop: function() {\n if (!this.active || !this.isEditing) {\n return;\n }\n if (this.canvas && this.canvas.contextTop) {\n var ctx = this.canvas.contextTop;\n ctx.save();\n ctx.transform.apply(ctx, this.canvas.viewportTransform);\n this.transform(ctx);\n this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix);\n this._clearTextArea(ctx);\n ctx.restore();\n }\n },\n\n /**\n * Renders cursor or selection (depending on what exists)\n */\n renderCursorOrSelection: function() {\n if (!this.active || !this.isEditing) {\n return;\n }\n var chars = this.text.split(''),\n boundaries, ctx;\n if (this.canvas && this.canvas.contextTop) {\n ctx = this.canvas.contextTop;\n ctx.save();\n ctx.transform.apply(ctx, this.canvas.viewportTransform);\n this.transform(ctx);\n this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix);\n this._clearTextArea(ctx);\n }\n else {\n ctx = this.ctx;\n ctx.save();\n }\n if (this.selectionStart === this.selectionEnd) {\n boundaries = this._getCursorBoundaries(chars, 'cursor');\n this.renderCursor(boundaries, ctx);\n }\n else {\n boundaries = this._getCursorBoundaries(chars, 'selection');\n this.renderSelection(chars, boundaries, ctx);\n }\n ctx.restore();\n },\n\n _clearTextArea: function(ctx) {\n // we add 4 pixel, to be sure to do not leave any pixel out\n var width = this.width + 4, height = this.height + 4;\n ctx.clearRect(-width / 2, -height / 2, width, height);\n },\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n */\n get2DCursorLocation: function(selectionStart) {\n if (typeof selectionStart === 'undefined') {\n selectionStart = this.selectionStart;\n }\n var len = this._textLines.length;\n for (var i = 0; i < len; i++) {\n if (selectionStart <= this._textLines[i].length) {\n return {\n lineIndex: i,\n charIndex: selectionStart\n };\n }\n selectionStart -= this._textLines[i].length + 1;\n }\n return {\n lineIndex: i - 1,\n charIndex: this._textLines[i - 1].length < selectionStart ? this._textLines[i - 1].length : selectionStart\n };\n },\n\n /**\n * Returns complete style of char at the current cursor\n * @param {Number} lineIndex Line index\n * @param {Number} charIndex Char index\n * @return {Object} Character style\n */\n getCurrentCharStyle: function(lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1);\n\n return {\n fontSize: style && style.fontSize || this.fontSize,\n fill: style && style.fill || this.fill,\n textBackgroundColor: style && style.textBackgroundColor || this.textBackgroundColor,\n textDecoration: style && style.textDecoration || this.textDecoration,\n fontFamily: style && style.fontFamily || this.fontFamily,\n fontWeight: style && style.fontWeight || this.fontWeight,\n fontStyle: style && style.fontStyle || this.fontStyle,\n stroke: style && style.stroke || this.stroke,\n strokeWidth: style && style.strokeWidth || this.strokeWidth\n };\n },\n\n /**\n * Returns fontSize of char at the current cursor\n * @param {Number} lineIndex Line index\n * @param {Number} charIndex Char index\n * @return {Number} Character font size\n */\n getCurrentCharFontSize: function(lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1);\n return style && style.fontSize ? style.fontSize : this.fontSize;\n },\n\n /**\n * Returns color (fill) of char at the current cursor\n * @param {Number} lineIndex Line index\n * @param {Number} charIndex Char index\n * @return {String} Character color (fill)\n */\n getCurrentCharColor: function(lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1);\n return style && style.fill ? style.fill : this.cursorColor;\n },\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * @private\n * @param {Array} chars Array of characters\n * @param {String} typeOfBoundaries\n */\n _getCursorBoundaries: function(chars, typeOfBoundaries) {\n\n // left/top are left/top of entire text box\n // leftOffset/topOffset are offset from that left/top point of a text box\n\n var left = Math.round(this._getLeftOffset()),\n top = this._getTopOffset(),\n\n offsets = this._getCursorBoundariesOffsets(\n chars, typeOfBoundaries);\n\n return {\n left: left,\n top: top,\n leftOffset: offsets.left + offsets.lineLeft,\n topOffset: offsets.top\n };\n },\n\n /**\n * @private\n */\n _getCursorBoundariesOffsets: function(chars, typeOfBoundaries) {\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache;\n }\n var lineLeftOffset = 0,\n lineIndex = 0,\n charIndex = 0,\n topOffset = 0,\n leftOffset = 0,\n boundaries;\n\n for (var i = 0; i < this.selectionStart; i++) {\n if (chars[i] === '\\n') {\n leftOffset = 0;\n topOffset += this._getHeightOfLine(this.ctx, lineIndex);\n\n lineIndex++;\n charIndex = 0;\n }\n else {\n leftOffset += this._getWidthOfChar(this.ctx, chars[i], lineIndex, charIndex);\n charIndex++;\n }\n\n lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex));\n }\n if (typeOfBoundaries === 'cursor') {\n topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, lineIndex) / this.lineHeight\n - this.getCurrentCharFontSize(lineIndex, charIndex) * (1 - this._fontSizeFraction);\n }\n if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n boundaries = {\n top: topOffset,\n left: leftOffset > 0 ? leftOffset : 0,\n lineLeft: lineLeftOffset\n };\n this.cursorOffsetCache = boundaries;\n return this.cursorOffsetCache;\n },\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor: function(boundaries, ctx) {\n\n var cursorLocation = this.get2DCursorLocation(),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight = this.getCurrentCharFontSize(lineIndex, charIndex),\n leftOffset = boundaries.leftOffset,\n multiplier = this.scaleX * this.canvas.getZoom(),\n cursorWidth = this.cursorWidth / multiplier;\n\n ctx.fillStyle = this.getCurrentCharColor(lineIndex, charIndex);\n ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;\n\n ctx.fillRect(\n boundaries.left + leftOffset - cursorWidth / 2,\n boundaries.top + boundaries.topOffset,\n cursorWidth,\n charHeight);\n },\n\n /**\n * Renders text selection\n * @param {Array} chars Array of characters\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection: function(chars, boundaries, ctx) {\n\n ctx.fillStyle = this.selectionColor;\n\n var start = this.get2DCursorLocation(this.selectionStart),\n end = this.get2DCursorLocation(this.selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex;\n for (var i = startLine; i <= endLine; i++) {\n var lineOffset = this._getLineLeftOffset(this._getLineWidth(ctx, i)) || 0,\n lineHeight = this._getHeightOfLine(this.ctx, i),\n realLineHeight = 0, boxWidth = 0, line = this._textLines[i];\n\n if (i === startLine) {\n for (var j = 0, len = line.length; j < len; j++) {\n if (j >= start.charIndex && (i !== endLine || j < end.charIndex)) {\n boxWidth += this._getWidthOfChar(ctx, line[j], i, j);\n }\n if (j < start.charIndex) {\n lineOffset += this._getWidthOfChar(ctx, line[j], i, j);\n }\n }\n if (j === line.length) {\n boxWidth -= this._getWidthOfCharSpacing();\n }\n }\n else if (i > startLine && i < endLine) {\n boxWidth += this._getLineWidth(ctx, i) || 5;\n }\n else if (i === endLine) {\n for (var j2 = 0, j2len = end.charIndex; j2 < j2len; j2++) {\n boxWidth += this._getWidthOfChar(ctx, line[j2], i, j2);\n }\n if (end.charIndex === line.length) {\n boxWidth -= this._getWidthOfCharSpacing();\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n ctx.fillRect(\n boundaries.left + lineOffset,\n boundaries.top + boundaries.topOffset,\n boxWidth > 0 ? boxWidth : 0,\n lineHeight);\n\n boundaries.topOffset += realLineHeight;\n }\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Content of the line\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n * @param {Number} charOffset\n */\n _renderChars: function(method, ctx, line, left, top, lineIndex, charOffset) {\n\n if (this.isEmptyStyles()) {\n return this._renderCharsFast(method, ctx, line, left, top);\n }\n\n charOffset = charOffset || 0;\n\n // set proper line offset\n var lineHeight = this._getHeightOfLine(ctx, lineIndex),\n prevStyle,\n thisStyle,\n charsToRender = '';\n\n ctx.save();\n top -= lineHeight / this.lineHeight * this._fontSizeFraction;\n for (var i = charOffset, len = line.length + charOffset; i <= len; i++) {\n prevStyle = prevStyle || this.getCurrentCharStyle(lineIndex, i);\n thisStyle = this.getCurrentCharStyle(lineIndex, i + 1);\n\n if (this._hasStyleChanged(prevStyle, thisStyle) || i === len) {\n this._renderChar(method, ctx, lineIndex, i - 1, charsToRender, left, top, lineHeight);\n charsToRender = '';\n prevStyle = thisStyle;\n }\n charsToRender += line[i - charOffset];\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Content of the line\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n */\n _renderCharsFast: function(method, ctx, line, left, top) {\n\n if (method === 'fillText' && this.fill) {\n this.callSuper('_renderChars', method, ctx, line, left, top);\n }\n if (method === 'strokeText' && ((this.stroke && this.strokeWidth > 0) || this.skipFillStrokeCheck)) {\n this.callSuper('_renderChars', method, ctx, line, left, top);\n }\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} i\n * @param {String} _char\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n * @param {Number} lineHeight Height of the line\n */\n _renderChar: function(method, ctx, lineIndex, i, _char, left, top, lineHeight) {\n var charWidth, charHeight, shouldFill, shouldStroke,\n decl = this._getStyleDeclaration(lineIndex, i),\n offset, textDecoration, chars, additionalSpace, _charWidth;\n\n if (decl) {\n charHeight = this._getHeightOfChar(ctx, _char, lineIndex, i);\n shouldStroke = decl.stroke;\n shouldFill = decl.fill;\n textDecoration = decl.textDecoration;\n }\n else {\n charHeight = this.fontSize;\n }\n\n shouldStroke = (shouldStroke || this.stroke) && method === 'strokeText';\n shouldFill = (shouldFill || this.fill) && method === 'fillText';\n\n decl && ctx.save();\n\n charWidth = this._applyCharStylesGetWidth(ctx, _char, lineIndex, i, decl || null);\n textDecoration = textDecoration || this.textDecoration;\n\n if (decl && decl.textBackgroundColor) {\n this._removeShadow(ctx);\n }\n if (this.charSpacing !== 0) {\n additionalSpace = this._getWidthOfCharSpacing();\n chars = _char.split('');\n charWidth = 0;\n for (var j = 0, len = chars.length, jChar; j < len; j++) {\n jChar = chars[j];\n shouldFill && ctx.fillText(jChar, left + charWidth, top);\n shouldStroke && ctx.strokeText(jChar, left + charWidth, top);\n _charWidth = ctx.measureText(jChar).width + additionalSpace;\n charWidth += _charWidth > 0 ? _charWidth : 0;\n }\n }\n else {\n shouldFill && ctx.fillText(_char, left, top);\n shouldStroke && ctx.strokeText(_char, left, top);\n }\n\n if (textDecoration || textDecoration !== '') {\n offset = this._fontSizeFraction * lineHeight / this.lineHeight;\n this._renderCharDecoration(ctx, textDecoration, left, top, offset, charWidth, charHeight);\n }\n\n decl && ctx.restore();\n ctx.translate(charWidth, 0);\n },\n\n /**\n * @private\n * @param {Object} prevStyle\n * @param {Object} thisStyle\n */\n _hasStyleChanged: function(prevStyle, thisStyle) {\n return (prevStyle.fill !== thisStyle.fill ||\n prevStyle.fontSize !== thisStyle.fontSize ||\n prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor ||\n prevStyle.textDecoration !== thisStyle.textDecoration ||\n prevStyle.fontFamily !== thisStyle.fontFamily ||\n prevStyle.fontWeight !== thisStyle.fontWeight ||\n prevStyle.fontStyle !== thisStyle.fontStyle ||\n prevStyle.stroke !== thisStyle.stroke ||\n prevStyle.strokeWidth !== thisStyle.strokeWidth\n );\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderCharDecoration: function(ctx, textDecoration, left, top, offset, charWidth, charHeight) {\n\n if (!textDecoration) {\n return;\n }\n\n var decorationWeight = charHeight / 15,\n positions = {\n underline: top + charHeight / 10,\n 'line-through': top - charHeight * (this._fontSizeFraction + this._fontSizeMult - 1) + decorationWeight,\n overline: top - (this._fontSizeMult - this._fontSizeFraction) * charHeight\n },\n decorations = ['underline', 'line-through', 'overline'], i, decoration;\n\n for (i = 0; i < decorations.length; i++) {\n decoration = decorations[i];\n if (textDecoration.indexOf(decoration) > -1) {\n ctx.fillRect(left, positions[decoration], charWidth , decorationWeight);\n }\n }\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n */\n _renderTextLine: function(method, ctx, line, left, top, lineIndex) {\n // to \"cancel\" this.fontSize subtraction in fabric.Text#_renderTextLine\n // the adding 0.03 is just to align text with itext by overlap test\n if (!this.isEmptyStyles()) {\n top += this.fontSize * (this._fontSizeFraction + 0.03);\n }\n this.callSuper('_renderTextLine', method, ctx, line, left, top, lineIndex);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration: function(ctx) {\n if (this.isEmptyStyles()) {\n return this.callSuper('_renderTextDecoration', ctx);\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground: function(ctx) {\n this.callSuper('_renderTextLinesBackground', ctx);\n\n var lineTopOffset = 0, heightOfLine,\n lineWidth, lineLeftOffset,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(),\n colorCache = '',\n line, _char, style, leftCache,\n topCache, widthCache, heightCache;\n ctx.save();\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this._getHeightOfLine(ctx, i);\n line = this._textLines[i];\n\n if (line === '' || !this.styles || !this._getLineStyle(i)) {\n lineTopOffset += heightOfLine;\n continue;\n }\n\n lineWidth = this._getLineWidth(ctx, i);\n lineLeftOffset = this._getLineLeftOffset(lineWidth);\n leftCache = topCache = widthCache = heightCache = 0;\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n style = this._getStyleDeclaration(i, j) || {};\n\n if (colorCache !== style.textBackgroundColor) {\n if (heightCache && widthCache) {\n ctx.fillStyle = colorCache;\n ctx.fillRect(leftCache, topCache, widthCache, heightCache);\n }\n leftCache = topCache = widthCache = heightCache = 0;\n colorCache = style.textBackgroundColor || '';\n }\n\n if (!style.textBackgroundColor) {\n colorCache = '';\n continue;\n }\n _char = line[j];\n\n if (colorCache === style.textBackgroundColor) {\n colorCache = style.textBackgroundColor;\n if (!leftCache) {\n leftCache = leftOffset + lineLeftOffset + this._getWidthOfCharsAt(ctx, i, j);\n }\n topCache = topOffset + lineTopOffset;\n widthCache += this._getWidthOfChar(ctx, _char, i, j);\n heightCache = heightOfLine / this.lineHeight;\n }\n }\n // if a textBackgroundColor ends on the last character of a line\n if (heightCache && widthCache) {\n ctx.fillStyle = colorCache;\n ctx.fillRect(leftCache, topCache, widthCache, heightCache);\n leftCache = topCache = widthCache = heightCache = 0;\n }\n lineTopOffset += heightOfLine;\n }\n ctx.restore();\n },\n\n /**\n * @private\n */\n _getCacheProp: function(_char, styleDeclaration) {\n return _char +\n styleDeclaration.fontSize +\n styleDeclaration.fontWeight +\n styleDeclaration.fontStyle;\n },\n\n /**\n * @private\n * @param {String} fontFamily name\n * @return {Object} reference to cache\n */\n _getFontCache: function(fontFamily) {\n if (!fabric.charWidthsCache[fontFamily]) {\n fabric.charWidthsCache[fontFamily] = { };\n }\n return fabric.charWidthsCache[fontFamily];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} _char\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} [decl]\n */\n _applyCharStylesGetWidth: function(ctx, _char, lineIndex, charIndex, decl) {\n var charDecl = decl || this._getStyleDeclaration(lineIndex, charIndex),\n styleDeclaration = clone(charDecl),\n width, cacheProp, charWidthsCache;\n\n this._applyFontStyles(styleDeclaration);\n charWidthsCache = this._getFontCache(styleDeclaration.fontFamily);\n cacheProp = this._getCacheProp(_char, styleDeclaration);\n\n // short-circuit if no styles for this char\n // global style from object is always applyed and handled by save and restore\n if (!charDecl && charWidthsCache[cacheProp] && this.caching) {\n return charWidthsCache[cacheProp];\n }\n\n if (typeof styleDeclaration.shadow === 'string') {\n styleDeclaration.shadow = new fabric.Shadow(styleDeclaration.shadow);\n }\n\n var fill = styleDeclaration.fill || this.fill;\n ctx.fillStyle = fill.toLive\n ? fill.toLive(ctx, this)\n : fill;\n\n if (styleDeclaration.stroke) {\n ctx.strokeStyle = (styleDeclaration.stroke && styleDeclaration.stroke.toLive)\n ? styleDeclaration.stroke.toLive(ctx, this)\n : styleDeclaration.stroke;\n }\n\n ctx.lineWidth = styleDeclaration.strokeWidth || this.strokeWidth;\n ctx.font = this._getFontDeclaration.call(styleDeclaration);\n\n //if we want this._setShadow.call to work with styleDeclarion\n //we have to add those references\n if (styleDeclaration.shadow) {\n styleDeclaration.scaleX = this.scaleX;\n styleDeclaration.scaleY = this.scaleY;\n styleDeclaration.canvas = this.canvas;\n styleDeclaration.getObjectScaling = this.getObjectScaling;\n this._setShadow.call(styleDeclaration, ctx);\n }\n\n if (!this.caching || !charWidthsCache[cacheProp]) {\n width = ctx.measureText(_char).width;\n this.caching && (charWidthsCache[cacheProp] = width);\n return width;\n }\n\n return charWidthsCache[cacheProp];\n },\n\n /**\n * @private\n * @param {Object} styleDeclaration\n */\n _applyFontStyles: function(styleDeclaration) {\n if (!styleDeclaration.fontFamily) {\n styleDeclaration.fontFamily = this.fontFamily;\n }\n if (!styleDeclaration.fontSize) {\n styleDeclaration.fontSize = this.fontSize;\n }\n if (!styleDeclaration.fontWeight) {\n styleDeclaration.fontWeight = this.fontWeight;\n }\n if (!styleDeclaration.fontStyle) {\n styleDeclaration.fontStyle = this.fontStyle;\n }\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Boolean} [returnCloneOrEmpty=false]\n * @private\n */\n _getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) {\n if (returnCloneOrEmpty) {\n return (this.styles[lineIndex] && this.styles[lineIndex][charIndex])\n ? clone(this.styles[lineIndex][charIndex])\n : { };\n }\n\n return this.styles[lineIndex] && this.styles[lineIndex][charIndex] ? this.styles[lineIndex][charIndex] : null;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function(lineIndex, charIndex, style) {\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n *\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function(lineIndex, charIndex) {\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _getLineStyle: function(lineIndex) {\n return this.styles[lineIndex];\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n _setLineStyle: function(lineIndex, style) {\n this.styles[lineIndex] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _deleteLineStyle: function(lineIndex) {\n delete this.styles[lineIndex];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _getWidthOfChar: function(ctx, _char, lineIndex, charIndex) {\n if (!this._isMeasuring && this.textAlign === 'justify' && this._reSpacesAndTabs.test(_char)) {\n return this._getWidthOfSpace(ctx, lineIndex);\n }\n ctx.save();\n var width = this._applyCharStylesGetWidth(ctx, _char, lineIndex, charIndex);\n if (this.charSpacing !== 0) {\n width += this._getWidthOfCharSpacing();\n }\n ctx.restore();\n return width > 0 ? width : 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n */\n _getHeightOfChar: function(ctx, lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex);\n return style && style.fontSize ? style.fontSize : this.fontSize;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n */\n _getWidthOfCharsAt: function(ctx, lineIndex, charIndex) {\n var width = 0, i, _char;\n for (i = 0; i < charIndex; i++) {\n _char = this._textLines[lineIndex][i];\n width += this._getWidthOfChar(ctx, _char, lineIndex, i);\n }\n return width;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n _measureLine: function(ctx, lineIndex) {\n this._isMeasuring = true;\n var width = this._getWidthOfCharsAt(ctx, lineIndex, this._textLines[lineIndex].length);\n if (this.charSpacing !== 0) {\n width -= this._getWidthOfCharSpacing();\n }\n this._isMeasuring = false;\n return width > 0 ? width : 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n */\n _getWidthOfSpace: function (ctx, lineIndex) {\n if (this.__widthOfSpace[lineIndex]) {\n return this.__widthOfSpace[lineIndex];\n }\n var line = this._textLines[lineIndex],\n wordsWidth = this._getWidthOfWords(ctx, line, lineIndex, 0),\n widthDiff = this.width - wordsWidth,\n numSpaces = line.length - line.replace(this._reSpacesAndTabs, '').length,\n width = Math.max(widthDiff / numSpaces, ctx.measureText(' ').width);\n this.__widthOfSpace[lineIndex] = width;\n return width;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line\n * @param {Number} lineIndex\n * @param {Number} charOffset\n */\n _getWidthOfWords: function (ctx, line, lineIndex, charOffset) {\n var width = 0;\n\n for (var charIndex = 0; charIndex < line.length; charIndex++) {\n var _char = line[charIndex];\n\n if (!_char.match(/\\s/)) {\n width += this._getWidthOfChar(ctx, _char, lineIndex, charIndex + charOffset);\n }\n }\n\n return width;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _getHeightOfLine: function(ctx, lineIndex) {\n if (this.__lineHeights[lineIndex]) {\n return this.__lineHeights[lineIndex];\n }\n\n var line = this._textLines[lineIndex],\n maxHeight = this._getHeightOfChar(ctx, lineIndex, 0);\n\n for (var i = 1, len = line.length; i < len; i++) {\n var currentCharHeight = this._getHeightOfChar(ctx, lineIndex, i);\n if (currentCharHeight > maxHeight) {\n maxHeight = currentCharHeight;\n }\n }\n this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;\n return this.__lineHeights[lineIndex];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _getTextHeight: function(ctx) {\n var lineHeight, height = 0;\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n lineHeight = this._getHeightOfLine(ctx, i);\n height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight);\n }\n return height;\n },\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return fabric.util.object.extend(this.callSuper('toObject', propertiesToInclude), {\n styles: clone(this.styles, true)\n });\n }\n });\n\n /**\n * Returns fabric.IText instance from an object representation\n * @static\n * @memberOf fabric.IText\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as argument\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.IText} instance of fabric.IText\n */\n fabric.IText.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('IText', object, callback, forceAsync, 'text');\n };\n})();\n\n\n(function() {\n\n var clone = fabric.util.object.clone;\n\n fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior: function() {\n this.initAddedHandler();\n this.initRemovedHandler();\n this.initCursorSelectionHandlers();\n this.initDoubleClickSimulation();\n this.mouseMoveHandler = this.mouseMoveHandler.bind(this);\n },\n\n onDeselect: function() {\n this.isEditing && this.exitEditing();\n this.selected = false;\n this.callSuper('onDeselect');\n },\n\n /**\n * Initializes \"added\" event handler\n */\n initAddedHandler: function() {\n var _this = this;\n this.on('added', function() {\n var canvas = _this.canvas;\n if (canvas) {\n if (!canvas._hasITextHandlers) {\n canvas._hasITextHandlers = true;\n _this._initCanvasHandlers(canvas);\n }\n canvas._iTextInstances = canvas._iTextInstances || [];\n canvas._iTextInstances.push(_this);\n }\n });\n },\n\n initRemovedHandler: function() {\n var _this = this;\n this.on('removed', function() {\n var canvas = _this.canvas;\n if (canvas) {\n canvas._iTextInstances = canvas._iTextInstances || [];\n fabric.util.removeFromArray(canvas._iTextInstances, _this);\n if (canvas._iTextInstances.length === 0) {\n canvas._hasITextHandlers = false;\n _this._removeCanvasHandlers(canvas);\n }\n }\n });\n },\n\n /**\n * register canvas event to manage exiting on other instances\n * @private\n */\n _initCanvasHandlers: function(canvas) {\n canvas._mouseUpITextHandler = (function() {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function(obj) {\n obj.__isMousedown = false;\n });\n }\n }).bind(this);\n canvas.on('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * remove canvas event to manage exiting on other instances\n * @private\n */\n _removeCanvasHandlers: function(canvas) {\n canvas.off('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * @private\n */\n _tick: function() {\n this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');\n },\n\n /**\n * @private\n */\n _animateCursor: function(obj, targetOpacity, duration, completeMethod) {\n\n var tickState;\n\n tickState = {\n isAborted: false,\n abort: function() {\n this.isAborted = true;\n },\n };\n\n obj.animate('_currentCursorOpacity', targetOpacity, {\n duration: duration,\n onComplete: function() {\n if (!tickState.isAborted) {\n obj[completeMethod]();\n }\n },\n onChange: function() {\n // we do not want to animate a selection, only cursor\n if (obj.canvas && obj.selectionStart === obj.selectionEnd) {\n obj.renderCursorOrSelection();\n }\n },\n abort: function() {\n return tickState.isAborted;\n }\n });\n return tickState;\n },\n\n /**\n * @private\n */\n _onTickComplete: function() {\n\n var _this = this;\n\n if (this._cursorTimeout1) {\n clearTimeout(this._cursorTimeout1);\n }\n this._cursorTimeout1 = setTimeout(function() {\n _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick');\n }, 100);\n },\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor: function(restart) {\n var _this = this,\n delay = restart ? 0 : this.cursorDelay;\n\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this._cursorTimeout2 = setTimeout(function() {\n _this._tick();\n }, delay);\n },\n\n /**\n * Aborts cursor animation and clears all timeouts\n */\n abortCursorAnimation: function() {\n var shouldClear = this._currentTickState || this._currentTickCompleteState;\n this._currentTickState && this._currentTickState.abort();\n this._currentTickCompleteState && this._currentTickCompleteState.abort();\n\n clearTimeout(this._cursorTimeout1);\n clearTimeout(this._cursorTimeout2);\n\n this._currentCursorOpacity = 0;\n // to clear just itext area we need to transform the context\n // it may not be worth it\n if (shouldClear) {\n this.canvas && this.canvas.clearContext(this.canvas.contextTop || this.ctx);\n }\n\n },\n\n /**\n * Selects entire text\n */\n selectAll: function() {\n this.selectionStart = 0;\n this.selectionEnd = this.text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n },\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText: function() {\n return this.text.slice(this.selectionStart, this.selectionEnd);\n },\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Surrent selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft: function(startFrom) {\n var offset = 0, index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this.text.charAt(index))) {\n while (this._reSpace.test(this.text.charAt(index))) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this.text.charAt(index)) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight: function(startFrom) {\n var offset = 0, index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this.text.charAt(index))) {\n while (this._reSpace.test(this.text.charAt(index))) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this.text.charAt(index)) && index < this.text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft: function(startFrom) {\n var offset = 0, index = startFrom - 1;\n\n while (!/\\n/.test(this.text.charAt(index)) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight: function(startFrom) {\n var offset = 0, index = startFrom;\n\n while (!/\\n/.test(this.text.charAt(index)) && index < this.text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Returns number of newlines in selected text\n * @return {Number} Number of newlines in selected text\n */\n getNumNewLinesInSelectedText: function() {\n var selectedText = this.getSelectedText(),\n numNewLines = 0;\n\n for (var i = 0, len = selectedText.length; i < len; i++) {\n if (selectedText[i] === '\\n') {\n numNewLines++;\n }\n }\n return numNewLines;\n },\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary: function(selectionStart, direction) {\n var index = this._reSpace.test(this.text.charAt(selectionStart)) ? selectionStart - 1 : selectionStart,\n _char = this.text.charAt(index),\n reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\n while (!reNonWord.test(_char) && index > 0 && index < this.text.length) {\n index += direction;\n _char = this.text.charAt(index);\n }\n if (reNonWord.test(_char) && _char !== '\\n') {\n index += direction === 1 ? 0 : 1;\n }\n return index;\n },\n\n /**\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord: function(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */\n newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n },\n\n /**\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectLine: function(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n },\n\n /**\n * Enters editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n enterEditing: function(e) {\n if (this.isEditing || !this.editable) {\n return;\n }\n\n if (this.canvas) {\n this.exitEditingOnOthers(this.canvas);\n }\n\n this.isEditing = true;\n this.selected = true;\n this.initHiddenTextarea(e);\n this.hiddenTextarea.focus();\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered');\n this._fireSelectionChanged();\n if (!this.canvas) {\n return this;\n }\n this.canvas.fire('text:editing:entered', { target: this });\n this.initMouseMoveHandler();\n this.canvas.renderAll();\n return this;\n },\n\n exitEditingOnOthers: function(canvas) {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function(obj) {\n obj.selected = false;\n if (obj.isEditing) {\n obj.exitEditing();\n }\n });\n }\n },\n\n /**\n * Initializes \"mousemove\" event handler\n */\n initMouseMoveHandler: function() {\n this.canvas.on('mouse:move', this.mouseMoveHandler);\n },\n\n /**\n * @private\n */\n mouseMoveHandler: function(options) {\n if (!this.__isMousedown || !this.isEditing) {\n return;\n }\n\n var newSelectionStart = this.getSelectionStartFromPointer(options.e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd)\n &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n }\n else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {\n this.restartCursorIfNeeded();\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n },\n\n /**\n * @private\n */\n _setEditingProps: function() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n },\n\n /**\n * @private\n */\n _updateTextarea: function() {\n if (!this.hiddenTextarea || this.inCompositionMode) {\n return;\n }\n this.cursorOffsetCache = { };\n this.hiddenTextarea.value = this.text;\n this.hiddenTextarea.selectionStart = this.selectionStart;\n this.hiddenTextarea.selectionEnd = this.selectionEnd;\n if (this.selectionStart === this.selectionEnd) {\n var style = this._calcTextareaPosition();\n this.hiddenTextarea.style.left = style.left;\n this.hiddenTextarea.style.top = style.top;\n this.hiddenTextarea.style.fontSize = style.fontSize;\n }\n },\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition: function() {\n if (!this.canvas) {\n return { x: 1, y: 1 };\n }\n var chars = this.text.split(''),\n boundaries = this._getCursorBoundaries(chars, 'cursor'),\n cursorLocation = this.get2DCursorLocation(),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight = this.getCurrentCharFontSize(lineIndex, charIndex),\n leftOffset = boundaries.leftOffset,\n m = this.calcTransformMatrix(),\n p = {\n x: boundaries.left + leftOffset,\n y: boundaries.top + boundaries.topOffset + charHeight\n },\n upperCanvas = this.canvas.upperCanvasEl,\n maxWidth = upperCanvas.width - charHeight,\n maxHeight = upperCanvas.height - charHeight;\n\n p = fabric.util.transformPoint(p, m);\n p = fabric.util.transformPoint(p, this.canvas.viewportTransform);\n\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight };\n },\n\n /**\n * @private\n */\n _saveEditingProps: function() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor\n };\n },\n\n /**\n * @private\n */\n _restoreEditingProps: function() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.overCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor = this._savedProps.defaultCursor;\n this.canvas.moveCursor = this._savedProps.moveCursor;\n }\n },\n\n /**\n * Exits from editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n exitEditing: function() {\n var isTextChanged = (this._textBeforeEdit !== this.text);\n this.selected = false;\n this.isEditing = false;\n this.selectable = true;\n\n this.selectionEnd = this.selectionStart;\n\n if (this.hiddenTextarea) {\n this.hiddenTextarea.blur && this.hiddenTextarea.blur();\n this.canvas && this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);\n this.hiddenTextarea = null;\n }\n\n this.abortCursorAnimation();\n this._restoreEditingProps();\n this._currentCursorOpacity = 0;\n\n this.fire('editing:exited');\n isTextChanged && this.fire('modified');\n if (this.canvas) {\n this.canvas.off('mouse:move', this.mouseMoveHandler);\n this.canvas.fire('text:editing:exited', { target: this });\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n },\n\n /**\n * @private\n */\n _removeExtraneousStyles: function() {\n for (var prop in this.styles) {\n if (!this._textLines[prop]) {\n delete this.styles[prop];\n }\n }\n },\n\n /**\n * @private\n */\n _removeCharsFromTo: function(start, end) {\n while (end !== start) {\n this._removeSingleCharAndStyle(start + 1);\n end--;\n }\n this.selectionStart = start;\n this.selectionEnd = start;\n },\n\n _removeSingleCharAndStyle: function(index) {\n var isBeginningOfLine = this.text[index - 1] === '\\n',\n indexStyle = isBeginningOfLine ? index : index - 1;\n this.removeStyleObject(isBeginningOfLine, indexStyle);\n this.text = this.text.slice(0, index - 1) +\n this.text.slice(index);\n\n this._textLines = this._splitTextIntoLines();\n },\n\n /**\n * Inserts characters where cursor is (replacing selection if one exists)\n * @param {String} _chars Characters to insert\n * @param {Boolean} useCopiedStyle use fabric.copiedTextStyle\n */\n insertChars: function(_chars, useCopiedStyle) {\n var style;\n\n if (this.selectionEnd - this.selectionStart > 1) {\n this._removeCharsFromTo(this.selectionStart, this.selectionEnd);\n }\n //short circuit for block paste\n if (!useCopiedStyle && this.isEmptyStyles()) {\n this.insertChar(_chars, false);\n return;\n }\n for (var i = 0, len = _chars.length; i < len; i++) {\n if (useCopiedStyle) {\n style = fabric.util.object.clone(fabric.copiedTextStyle[i], true);\n }\n this.insertChar(_chars[i], i < len - 1, style);\n }\n },\n\n /**\n * Inserts a character where cursor is\n * @param {String} _char Characters to insert\n * @param {Boolean} skipUpdate trigger rendering and updates at the end of text insert\n * @param {Object} styleObject Style to be inserted for the new char\n */\n insertChar: function(_char, skipUpdate, styleObject) {\n var isEndOfLine = this.text[this.selectionStart] === '\\n';\n this.text = this.text.slice(0, this.selectionStart) +\n _char + this.text.slice(this.selectionEnd);\n this._textLines = this._splitTextIntoLines();\n this.insertStyleObjects(_char, isEndOfLine, styleObject);\n this.selectionStart += _char.length;\n this.selectionEnd = this.selectionStart;\n if (skipUpdate) {\n return;\n }\n this._updateTextarea();\n this.setCoords();\n this._fireSelectionChanged();\n this.fire('changed');\n this.restartCursorIfNeeded();\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this });\n this.canvas.renderAll();\n }\n },\n\n restartCursorIfNeeded: function() {\n if (!this._currentTickState || this._currentTickState.isAborted\n || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted\n ) {\n this.initDelayedCursor();\n }\n },\n\n /**\n * Inserts new style object\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Boolean} isEndOfLine True if it's end of line\n */\n insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) {\n\n this.shiftLineStyles(lineIndex, +1);\n\n var currentCharStyle = {},\n newLineStyles = {};\n\n if (this.styles[lineIndex] && this.styles[lineIndex][charIndex - 1]) {\n currentCharStyle = this.styles[lineIndex][charIndex - 1];\n }\n\n // if there's nothing after cursor,\n // we clone current char style onto the next (otherwise empty) line\n if (isEndOfLine && currentCharStyle) {\n newLineStyles[0] = clone(currentCharStyle);\n this.styles[lineIndex + 1] = newLineStyles;\n }\n // otherwise we clone styles of all chars\n // after cursor onto the next line, from the beginning\n else {\n var somethingAdded = false;\n for (var index in this.styles[lineIndex]) {\n var numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n somethingAdded = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n delete this.styles[lineIndex][index];\n }\n }\n somethingAdded && (this.styles[lineIndex + 1] = newLineStyles);\n }\n this._forceClearCache = true;\n },\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Object} [style] Style object to insert, if given\n */\n insertCharStyleObject: function(lineIndex, charIndex, style) {\n\n var currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = clone(currentLineStyles);\n\n if (charIndex === 0 && !style) {\n charIndex = 1;\n }\n\n // shift all char styles by 1 forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (var index in currentLineStylesCloned) {\n var numericIndex = parseInt(index, 10);\n\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + 1] = currentLineStylesCloned[numericIndex];\n\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - 1]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n var newStyle = style || clone(currentLineStyles[charIndex - 1]);\n newStyle && (this.styles[lineIndex][charIndex] = newStyle);\n this._forceClearCache = true;\n },\n\n /**\n * Inserts style object(s)\n * @param {String} _chars Characters at the location where style is inserted\n * @param {Boolean} isEndOfLine True if it's end of line\n * @param {Object} [styleObject] Style to insert\n */\n insertStyleObjects: function(_chars, isEndOfLine, styleObject) {\n // removed shortcircuit over isEmptyStyles\n\n var cursorLocation = this.get2DCursorLocation(),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex;\n\n if (!this._getLineStyle(lineIndex)) {\n this._setLineStyle(lineIndex, {});\n }\n\n if (_chars === '\\n') {\n this.insertNewlineStyleObject(lineIndex, charIndex, isEndOfLine);\n }\n else {\n this.insertCharStyleObject(lineIndex, charIndex, styleObject);\n }\n },\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can be -1 or +1\n */\n shiftLineStyles: function(lineIndex, offset) {\n // shift all line styles by 1 upward or downward\n var clonedStyles = clone(this.styles);\n for (var line in clonedStyles) {\n var numericLine = parseInt(line, 10);\n if (numericLine <= lineIndex) {\n delete clonedStyles[numericLine];\n }\n }\n for (var line in this.styles) {\n var numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n //TODO: evaluate if delete old style lines with offset -1\n },\n\n /**\n * Removes style object\n * @param {Boolean} isBeginningOfLine True if cursor is at the beginning of line\n * @param {Number} [index] Optional index. When not given, current selectionStart is used.\n */\n removeStyleObject: function(isBeginningOfLine, index) {\n\n var cursorLocation = this.get2DCursorLocation(index),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex;\n\n this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex);\n },\n\n _getTextOnPreviousLine: function(lIndex) {\n return this._textLines[lIndex - 1];\n },\n\n _removeStyleObject: function(isBeginningOfLine, cursorLocation, lineIndex, charIndex) {\n\n if (isBeginningOfLine) {\n var textOnPreviousLine = this._getTextOnPreviousLine(cursorLocation.lineIndex),\n newCharIndexOnPrevLine = textOnPreviousLine ? textOnPreviousLine.length : 0;\n\n if (!this.styles[lineIndex - 1]) {\n this.styles[lineIndex - 1] = {};\n }\n for (charIndex in this.styles[lineIndex]) {\n this.styles[lineIndex - 1][parseInt(charIndex, 10) + newCharIndexOnPrevLine]\n = this.styles[lineIndex][charIndex];\n }\n this.shiftLineStyles(cursorLocation.lineIndex, -1);\n }\n else {\n var currentLineStyles = this.styles[lineIndex];\n\n if (currentLineStyles) {\n delete currentLineStyles[charIndex];\n }\n var currentLineStylesCloned = clone(currentLineStyles);\n // shift all styles by 1 backwards\n for (var i in currentLineStylesCloned) {\n var numericIndex = parseInt(i, 10);\n if (numericIndex >= charIndex && numericIndex !== 0) {\n currentLineStyles[numericIndex - 1] = currentLineStylesCloned[numericIndex];\n delete currentLineStyles[numericIndex];\n }\n }\n }\n },\n\n /**\n * Inserts new line\n */\n insertNewline: function() {\n this.insertChars('\\n');\n },\n\n /**\n * Set the selectionStart and selectionEnd according to the ne postion of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift: function(start, end, newSelection) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = 'left';\n }\n else if (this._selectionDirection === 'right') {\n this._selectionDirection = 'left';\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n }\n else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === 'right') {\n this.selectionEnd = newSelection;\n }\n else {\n this.selectionStart = newSelection;\n }\n }\n else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = 'right';\n }\n else if (this._selectionDirection === 'left') {\n this._selectionDirection = 'right';\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n },\n\n setSelectionInBoundaries: function() {\n var length = this.text.length;\n if (this.selectionStart > length) {\n this.selectionStart = length;\n }\n else if (this.selectionStart < 0) {\n this.selectionStart = 0;\n }\n if (this.selectionEnd > length) {\n this.selectionEnd = length;\n }\n else if (this.selectionEnd < 0) {\n this.selectionEnd = 0;\n }\n }\n });\n})();\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n /**\n * Initializes \"dbclick\" event handler\n */\n initDoubleClickSimulation: function() {\n\n // for double click\n this.__lastClickTime = +new Date();\n\n // for triple click\n this.__lastLastClickTime = +new Date();\n\n this.__lastPointer = { };\n\n this.on('mousedown', this.onMouseDown.bind(this));\n },\n\n onMouseDown: function(options) {\n\n this.__newClickTime = +new Date();\n var newPointer = this.canvas.getPointer(options.e);\n\n if (this.isTripleClick(newPointer, options.e)) {\n this.fire('tripleclick', options);\n this._stopEvent(options.e);\n }\n else if (this.isDoubleClick(newPointer)) {\n this.fire('dblclick', options);\n this._stopEvent(options.e);\n }\n\n this.__lastLastClickTime = this.__lastClickTime;\n this.__lastClickTime = this.__newClickTime;\n this.__lastPointer = newPointer;\n this.__lastIsEditing = this.isEditing;\n this.__lastSelected = this.selected;\n },\n\n isDoubleClick: function(newPointer) {\n return this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y && this.__lastIsEditing;\n },\n\n isTripleClick: function(newPointer) {\n return this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastClickTime - this.__lastLastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y;\n },\n\n /**\n * @private\n */\n _stopEvent: function(e) {\n e.preventDefault && e.preventDefault();\n e.stopPropagation && e.stopPropagation();\n },\n\n /**\n * Initializes event handlers related to cursor or selection\n */\n initCursorSelectionHandlers: function() {\n this.initMousedownHandler();\n this.initMouseupHandler();\n this.initClicks();\n },\n\n /**\n * Initializes double and triple click event handlers\n */\n initClicks: function() {\n this.on('dblclick', function(options) {\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n });\n this.on('tripleclick', function(options) {\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n });\n },\n\n /**\n * Initializes \"mousedown\" event handler\n */\n initMousedownHandler: function() {\n this.on('mousedown', function(options) {\n if (!this.editable || (options.e.button && options.e.button !== 1)) {\n return;\n }\n var pointer = this.canvas.getPointer(options.e);\n this.__mousedownX = pointer.x;\n this.__mousedownY = pointer.y;\n this.__isMousedown = true;\n\n if (this.selected) {\n this.setCursorByClick(options.e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\n this.renderCursorOrSelection();\n }\n });\n },\n\n /**\n * @private\n */\n _isObjectMoved: function(e) {\n var pointer = this.canvas.getPointer(e);\n\n return this.__mousedownX !== pointer.x ||\n this.__mousedownY !== pointer.y;\n },\n\n /**\n * Initializes \"mouseup\" event handler\n */\n initMouseupHandler: function() {\n this.on('mouseup', function(options) {\n this.__isMousedown = false;\n if (!this.editable || this._isObjectMoved(options.e) || (options.e.button && options.e.button !== 1)) {\n return;\n }\n\n if (this.__lastSelected && !this.__corner) {\n this.enterEditing(options.e);\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n }\n else {\n this.renderCursorOrSelection();\n }\n }\n this.selected = true;\n });\n },\n\n /**\n * Changes cursor location in a text depending on passed pointer (x/y) object\n * @param {Event} e Event object\n */\n setCursorByClick: function(e) {\n var newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart, end = this.selectionEnd;\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n }\n else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n if (this.isEditing) {\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Returns index of a character corresponding to where an object was clicked\n * @param {Event} e Event object\n * @return {Number} Index of a character\n */\n getSelectionStartFromPointer: function(e) {\n var mouseOffset = this.getLocalPointer(e),\n prevWidth = 0,\n width = 0,\n height = 0,\n charIndex = 0,\n newSelectionStart,\n line;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n line = this._textLines[i];\n height += this._getHeightOfLine(this.ctx, i) * this.scaleY;\n\n var widthOfLine = this._getLineWidth(this.ctx, i),\n lineLeftOffset = this._getLineLeftOffset(widthOfLine);\n\n width = lineLeftOffset * this.scaleX;\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n\n prevWidth = width;\n\n width += this._getWidthOfChar(this.ctx, line[j], i, this.flipX ? jlen - j : j) *\n this.scaleX;\n\n if (height <= mouseOffset.y || width <= mouseOffset.x) {\n charIndex++;\n continue;\n }\n\n return this._getNewSelectionStartFromOffset(\n mouseOffset, prevWidth, width, charIndex + i, jlen);\n }\n\n if (mouseOffset.y < height) {\n //this happens just on end of lines.\n return this._getNewSelectionStartFromOffset(\n mouseOffset, prevWidth, width, charIndex + i - 1, jlen);\n }\n }\n\n // clicked somewhere after all chars, so set at the end\n if (typeof newSelectionStart === 'undefined') {\n return this.text.length;\n }\n },\n\n /**\n * @private\n */\n _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) {\n\n var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth,\n distanceBtwNextCharAndCursor = width - mouseOffset.x,\n offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ? 0 : 1,\n newSelectionStart = index + offset;\n\n // if object is horizontally flipped, mirror cursor location from the end\n if (this.flipX) {\n newSelectionStart = jlen - newSelectionStart;\n }\n\n if (newSelectionStart > this.text.length) {\n newSelectionStart = this.text.length;\n }\n\n return newSelectionStart;\n }\n});\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea: function() {\n this.hiddenTextarea = fabric.document.createElement('textarea');\n this.hiddenTextarea.setAttribute('autocapitalize', 'off');\n this.hiddenTextarea.setAttribute('autocorrect', 'off');\n this.hiddenTextarea.setAttribute('autocomplete', 'off');\n this.hiddenTextarea.setAttribute('spellcheck', 'false');\n this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', '');\n this.hiddenTextarea.setAttribute('wrap', 'off');\n var style = this._calcTextareaPosition();\n this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top +\n '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' +\n ' line-height: 1px; paddingーtop: ' + style.fontSize + ';';\n fabric.document.body.appendChild(this.hiddenTextarea);\n\n fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'cut', this.cut.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this));\n\n if (!this._clickHandlerInitialized && this.canvas) {\n fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this));\n this._clickHandlerInitialized = true;\n }\n },\n\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behaviour for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the fabric.Itext or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = fabric.util.object.clone(this.keysMap);\n * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0]\n */\n keysMap: {\n 8: 'removeChars',\n 9: 'exitEditing',\n 27: 'exitEditing',\n 13: 'insertNewline',\n 33: 'moveCursorUp',\n 34: 'moveCursorDown',\n 35: 'moveCursorRight',\n 36: 'moveCursorLeft',\n 37: 'moveCursorLeft',\n 38: 'moveCursorUp',\n 39: 'moveCursorRight',\n 40: 'moveCursorDown',\n 46: 'forwardDelete'\n },\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n ctrlKeysMapUp: {\n 67: 'copy',\n 88: 'cut'\n },\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n ctrlKeysMapDown: {\n 65: 'selectAll'\n },\n\n onClick: function() {\n // No need to trigger click event here, focus is enough to have the keyboard appear on Android\n this.hiddenTextarea && this.hiddenTextarea.focus();\n },\n\n /**\n * Handles keyup event\n * @param {Event} e Event object\n */\n onKeyDown: function(e) {\n if (!this.isEditing) {\n return;\n }\n if (e.keyCode in this.keysMap) {\n this[this.keysMap[e.keyCode]](e);\n }\n else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n }\n else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.clearContextTop();\n this.renderCursorOrSelection();\n }\n else {\n this.canvas && this.canvas.renderAll();\n }\n },\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {Event} e Event object\n */\n onKeyUp: function(e) {\n if (!this.isEditing || this._copyDone) {\n this._copyDone = false;\n return;\n }\n if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n }\n else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.renderAll();\n },\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput: function(e) {\n if (!this.isEditing || this.inCompositionMode) {\n return;\n }\n var offset = this.selectionStart || 0,\n offsetEnd = this.selectionEnd || 0,\n textLength = this.text.length,\n newTextLength = this.hiddenTextarea.value.length,\n diff, charsToInsert, start;\n if (newTextLength > textLength) {\n //we added some character\n start = this._selectionDirection === 'left' ? offsetEnd : offset;\n diff = newTextLength - textLength;\n charsToInsert = this.hiddenTextarea.value.slice(start, start + diff);\n }\n else {\n //we selected a portion of text and then input something else.\n //Internet explorer does not trigger this else\n diff = newTextLength - textLength + offsetEnd - offset;\n charsToInsert = this.hiddenTextarea.value.slice(offset, offset + diff);\n }\n this.insertChars(charsToInsert);\n e.stopPropagation();\n },\n\n /**\n * Composition start\n */\n onCompositionStart: function() {\n this.inCompositionMode = true;\n this.prevCompositionLength = 0;\n this.compositionStart = this.selectionStart;\n },\n\n /**\n * Composition end\n */\n onCompositionEnd: function() {\n this.inCompositionMode = false;\n },\n\n /**\n * Composition update\n */\n onCompositionUpdate: function(e) {\n var data = e.data;\n this.selectionStart = this.compositionStart;\n this.selectionEnd = this.selectionEnd === this.selectionStart ?\n this.compositionStart + this.prevCompositionLength : this.selectionEnd;\n this.insertChars(data, false);\n this.prevCompositionLength = data.length;\n },\n\n /**\n * Forward delete\n */\n forwardDelete: function(e) {\n if (this.selectionStart === this.selectionEnd) {\n if (this.selectionStart === this.text.length) {\n return;\n }\n this.moveCursorRight(e);\n }\n this.removeChars(e);\n },\n\n /**\n * Copies selected text\n * @param {Event} e Event object\n */\n copy: function(e) {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n var selectedText = this.getSelectedText(),\n clipboardData = this._getClipboardData(e);\n\n // Check for backward compatibility with old browsers\n if (clipboardData) {\n clipboardData.setData('text', selectedText);\n }\n\n fabric.copiedText = selectedText;\n fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd);\n e.stopImmediatePropagation();\n e.preventDefault();\n this._copyDone = true;\n },\n\n /**\n * Pastes text\n * @param {Event} e Event object\n */\n paste: function(e) {\n var copiedText = null,\n clipboardData = this._getClipboardData(e),\n useCopiedStyle = true;\n\n // Check for backward compatibility with old browsers\n if (clipboardData) {\n copiedText = clipboardData.getData('text').replace(/\\r/g, '');\n if (!fabric.copiedTextStyle || fabric.copiedText !== copiedText) {\n useCopiedStyle = false;\n }\n }\n else {\n copiedText = fabric.copiedText;\n }\n\n if (copiedText) {\n this.insertChars(copiedText, useCopiedStyle);\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n },\n\n /**\n * Cuts text\n * @param {Event} e Event object\n */\n cut: function(e) {\n if (this.selectionStart === this.selectionEnd) {\n return;\n }\n\n this.copy(e);\n this.removeChars(e);\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @return {Object} Clipboard data object\n */\n _getClipboardData: function(e) {\n return (e && e.clipboardData) || fabric.window.clipboardData;\n },\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor: function(lineIndex, charIndex) {\n var textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n widthOfLine = this._getLineWidth(this.ctx, lineIndex),\n widthBeforeCursor = this._getLineLeftOffset(widthOfLine), _char;\n\n for (var i = 0, len = textBeforeCursor.length; i < len; i++) {\n _char = textBeforeCursor[i];\n widthBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i);\n }\n return widthBeforeCursor;\n },\n\n /**\n * Gets start offset of a selection\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset: function(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n // if on last line, down cursor goes to end of line\n if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {\n // move to the end of a text\n return this.text.length - selectionProp;\n }\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n\n return textAfterCursor.length + indexOnOtherLine + 2;\n },\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset: function(e, isRight) {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n }\n else {\n return this.selectionStart;\n }\n },\n\n /**\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset: function(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex);\n // return a negative offset\n return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length;\n },\n\n /**\n * find for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine: function(lineIndex, width) {\n\n var widthOfLine = this._getLineWidth(this.ctx, lineIndex),\n textOnLine = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(widthOfLine),\n widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0,\n foundMatch;\n\n for (var j = 0, jlen = textOnLine.length; j < jlen; j++) {\n\n var _char = textOnLine[j],\n widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j);\n\n widthOfCharsOnLine += widthOfChar;\n\n if (widthOfCharsOnLine > width) {\n\n foundMatch = true;\n\n var leftEdge = widthOfCharsOnLine - widthOfChar,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1);\n\n break;\n }\n }\n\n // reached end\n if (!foundMatch) {\n indexOnLine = textOnLine.length - 1;\n }\n\n return indexOnLine;\n },\n\n\n /**\n * Moves cursor down\n * @param {Event} e Event object\n */\n moveCursorDown: function(e) {\n if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) {\n return;\n }\n this._moveCursorUpOrDown('Down', e);\n },\n\n /**\n * Moves cursor up\n * @param {Event} e Event object\n */\n moveCursorUp: function(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorUpOrDown('Up', e);\n },\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {Event} e Event object\n */\n _moveCursorUpOrDown: function(direction, e) {\n // getUpCursorOffset\n // getDownCursorOffset\n var action = 'get' + direction + 'CursorOffset',\n offset = this[action](e, this._selectionDirection === 'right');\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n }\n else {\n this.moveCursorWithoutShift(offset);\n }\n if (offset !== 0) {\n this.setSelectionInBoundaries();\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift: function(offset) {\n var newSelection = this._selectionDirection === 'left'\n ? this.selectionStart + offset\n : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection);\n return offset !== 0;\n },\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift: function(offset) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n }\n else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n return offset !== 0;\n },\n\n /**\n * Moves cursor left\n * @param {Event} e Event object\n */\n moveCursorLeft: function(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorLeftOrRight('Left', e);\n },\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n */\n _move: function(e, prop, direction) {\n var newValue;\n if (e.altKey) {\n newValue = this['findWordBoundary' + direction](this[prop]);\n }\n else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36 ) {\n newValue = this['findLineBoundary' + direction](this[prop]);\n }\n else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n if (typeof newValue !== undefined && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n },\n\n /**\n * @private\n */\n _moveLeft: function(e, prop) {\n return this._move(e, prop, 'Left');\n },\n\n /**\n * @private\n */\n _moveRight: function(e, prop) {\n return this._move(e, prop, 'Right');\n },\n\n /**\n * Moves cursor left without keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithoutShift: function(e) {\n var change = true;\n this._selectionDirection = 'left';\n\n // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) {\n change = this._moveLeft(e, 'selectionStart');\n\n }\n this.selectionEnd = this.selectionStart;\n return change;\n },\n\n /**\n * Moves cursor left while keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithShift: function(e) {\n if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) {\n return this._moveLeft(e, 'selectionEnd');\n }\n else if (this.selectionStart !== 0){\n this._selectionDirection = 'left';\n return this._moveLeft(e, 'selectionStart');\n }\n },\n\n /**\n * Moves cursor right\n * @param {Event} e Event object\n */\n moveCursorRight: function(e) {\n if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) {\n return;\n }\n this._moveCursorLeftOrRight('Right', e);\n },\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {Event} e Event object\n */\n _moveCursorLeftOrRight: function(direction, e) {\n var actionName = 'moveCursor' + direction + 'With';\n this._currentCursorOpacity = 1;\n\n if (e.shiftKey) {\n actionName += 'Shift';\n }\n else {\n actionName += 'outShift';\n }\n if (this[actionName](e)) {\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor right while keeping selection\n * @param {Event} e\n */\n moveCursorRightWithShift: function(e) {\n if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) {\n return this._moveRight(e, 'selectionStart');\n }\n else if (this.selectionEnd !== this.text.length) {\n this._selectionDirection = 'right';\n return this._moveRight(e, 'selectionEnd');\n }\n },\n\n /**\n * Moves cursor right without keeping selection\n * @param {Event} e Event object\n */\n moveCursorRightWithoutShift: function(e) {\n var changed = true;\n this._selectionDirection = 'right';\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n }\n else {\n this.selectionStart = this.selectionEnd;\n }\n return changed;\n },\n\n /**\n * Removes characters selected by selection\n * @param {Event} e Event object\n */\n removeChars: function(e) {\n if (this.selectionStart === this.selectionEnd) {\n this._removeCharsNearCursor(e);\n }\n else {\n this._removeCharsFromTo(this.selectionStart, this.selectionEnd);\n }\n\n this.set('dirty', true);\n this.setSelectionEnd(this.selectionStart);\n\n this._removeExtraneousStyles();\n\n this.canvas && this.canvas.renderAll();\n\n this.setCoords();\n this.fire('changed');\n this.canvas && this.canvas.fire('text:changed', { target: this });\n },\n\n /**\n * @private\n * @param {Event} e Event object\n */\n _removeCharsNearCursor: function(e) {\n if (this.selectionStart === 0) {\n return;\n }\n if (e.metaKey) {\n // remove all till the start of current line\n var leftLineBoundary = this.findLineBoundaryLeft(this.selectionStart);\n\n this._removeCharsFromTo(leftLineBoundary, this.selectionStart);\n this.setSelectionStart(leftLineBoundary);\n }\n else if (e.altKey) {\n // remove all till the start of current word\n var leftWordBoundary = this.findWordBoundaryLeft(this.selectionStart);\n\n this._removeCharsFromTo(leftWordBoundary, this.selectionStart);\n this.setSelectionStart(leftWordBoundary);\n }\n else {\n this._removeSingleCharAndStyle(this.selectionStart);\n this.setSelectionStart(this.selectionStart - 1);\n }\n }\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n var toFixed = fabric.util.toFixed,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * @private\n */\n _setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) {\n if (!this._getLineStyle(lineIndex)) {\n fabric.Text.prototype._setSVGTextLineText.call(this,\n lineIndex, textSpans, height, textLeftOffset, textTopOffset);\n }\n else {\n this._setSVGTextLineChars(\n lineIndex, textSpans, height, textLeftOffset, textBgRects);\n }\n },\n\n /**\n * @private\n */\n _setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) {\n\n var chars = this._textLines[lineIndex],\n charOffset = 0,\n lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) - this.width / 2,\n lineOffset = this._getSVGLineTopOffset(lineIndex),\n heightOfLine = this._getHeightOfLine(this.ctx, lineIndex);\n\n for (var i = 0, len = chars.length; i < len; i++) {\n var styleDecl = this._getStyleDeclaration(lineIndex, i) || { };\n\n textSpans.push(\n this._createTextCharSpan(\n chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset));\n\n var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i);\n\n if (styleDecl.textBackgroundColor) {\n textBgRects.push(\n this._createTextCharBg(\n styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset));\n }\n\n charOffset += charWidth;\n }\n },\n\n /**\n * @private\n */\n _getSVGLineTopOffset: function(lineIndex) {\n var lineTopOffset = 0, lastHeight = 0;\n for (var j = 0; j < lineIndex; j++) {\n lineTopOffset += this._getHeightOfLine(this.ctx, j);\n }\n lastHeight = this._getHeightOfLine(this.ctx, j);\n return {\n lineTop: lineTopOffset,\n offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)\n };\n },\n\n /**\n * @private\n */\n _createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) {\n return [\n '\\t\\t\\n'\n ].join('');\n },\n\n /**\n * @private\n */\n _createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) {\n\n var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({\n visible: true,\n fill: this.fill,\n stroke: this.stroke,\n type: 'text',\n getSvgFilter: fabric.Object.prototype.getSvgFilter\n }, styleDecl));\n\n return [\n '\\t\\t\\t',\n fabric.util.string.escapeXml(_char),\n '\\n'\n ].join('');\n },\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n /**\n * Textbox class, based on IText, allows the user to resize the text rectangle\n * and wraps lines automatically. Textboxes have their Y scaling locked, the\n * user can only change width. Height is adjusted automatically based on the\n * wrapping of lines.\n * @class fabric.Textbox\n * @extends fabric.IText\n * @mixes fabric.Observable\n * @return {fabric.Textbox} thisArg\n * @see {@link fabric.Textbox#initialize} for constructor definition\n */\n fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'textbox',\n\n /**\n * Minimum width of textbox, in pixels.\n * @type Number\n * @default\n */\n minWidth: 20,\n\n /**\n * Minimum calculated width of a textbox, in pixels.\n * fixed to 2 so that an empty textbox cannot go to 0\n * and is still selectable without text.\n * @type Number\n * @default\n */\n dynamicMinWidth: 2,\n\n /**\n * Cached array of text wrapping.\n * @type Array\n */\n __cachedLines: null,\n\n /**\n * Override standard Object class values\n */\n lockScalingY: true,\n\n /**\n * Override standard Object class values\n */\n lockScalingFlip: true,\n\n /**\n * Override standard Object class values\n * Textbox needs this on false\n */\n noScaleCache: false,\n\n /**\n * Properties which when set cause object to change dimensions\n * @type Object\n * @private\n */\n _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'),\n\n /**\n * Constructor. Some scaling related property values are forced. Visibility\n * of controls is also fixed; only the rotation and width controls are\n * made available.\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Textbox} thisArg\n */\n initialize: function(text, options) {\n\n this.callSuper('initialize', text, options);\n this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());\n this.ctx = this.objectCaching ? this._cacheContext : fabric.util.createCanvasElement().getContext('2d');\n },\n\n /**\n * Unlike superclass's version of this function, Textbox does not update\n * its width.\n * @param {CanvasRenderingContext2D} ctx Context to use for measurements\n * @private\n * @override\n */\n _initDimensions: function(ctx) {\n if (this.__skipDimension) {\n return;\n }\n\n if (!ctx) {\n ctx = fabric.util.createCanvasElement().getContext('2d');\n this._setTextStyles(ctx);\n this.clearContextTop();\n }\n\n // clear dynamicMinWidth as it will be different after we re-wrap line\n this.dynamicMinWidth = 0;\n\n // wrap lines\n this._textLines = this._splitTextIntoLines(ctx);\n // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\n\n // clear cache and re-calculate height\n this._clearCache();\n this.height = this._getTextHeight(ctx);\n this.setCoords();\n },\n\n /**\n * Generate an object that translates the style object so that it is\n * broken up by visual lines (new lines and automatic wrapping).\n * The original text styles object is broken up by actual lines (new lines only),\n * which is only sufficient for Text / IText\n * @private\n */\n _generateStyleMap: function() {\n var realLineCount = 0,\n realLineCharCount = 0,\n charCount = 0,\n map = {};\n\n for (var i = 0; i < this._textLines.length; i++) {\n if (this.text[charCount] === '\\n' && i > 0) {\n realLineCharCount = 0;\n charCount++;\n realLineCount++;\n }\n else if (this.text[charCount] === ' ' && i > 0) {\n // this case deals with space's that are removed from end of lines when wrapping\n realLineCharCount++;\n charCount++;\n }\n\n map[i] = { line: realLineCount, offset: realLineCharCount };\n\n charCount += this._textLines[i].length;\n realLineCharCount += this._textLines[i].length;\n }\n\n return map;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Boolean} [returnCloneOrEmpty=false]\n * @private\n */\n _getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) {\n if (this._styleMap) {\n var map = this._styleMap[lineIndex];\n if (!map) {\n return returnCloneOrEmpty ? { } : null;\n }\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\n return this.callSuper('_getStyleDeclaration', lineIndex, charIndex, returnCloneOrEmpty);\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function(lineIndex, charIndex, style) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function(lineIndex, charIndex) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _getLineStyle: function(lineIndex) {\n var map = this._styleMap[lineIndex];\n return this.styles[map.line];\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n _setLineStyle: function(lineIndex, style) {\n var map = this._styleMap[lineIndex];\n this.styles[map.line] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _deleteLineStyle: function(lineIndex) {\n var map = this._styleMap[lineIndex];\n delete this.styles[map.line];\n },\n\n /**\n * Wraps text using the 'width' property of Textbox. First this function\n * splits text on newlines, so we preserve newlines entered by the user.\n * Then it wraps each line using the width of the Textbox by calling\n * _wrapLine().\n * @param {CanvasRenderingContext2D} ctx Context to use for measurements\n * @param {String} text The string of text that is split into lines\n * @returns {Array} Array of lines\n */\n _wrapText: function(ctx, text) {\n var lines = text.split(this._reNewline), wrapped = [], i;\n\n for (i = 0; i < lines.length; i++) {\n wrapped = wrapped.concat(this._wrapLine(ctx, lines[i], i));\n }\n\n return wrapped;\n },\n\n /**\n * Helper function to measure a string of text, given its lineIndex and charIndex offset\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {String} text\n * @param {number} lineIndex\n * @param {number} charOffset\n * @returns {number}\n * @private\n */\n _measureText: function(ctx, text, lineIndex, charOffset) {\n var width = 0;\n charOffset = charOffset || 0;\n for (var i = 0, len = text.length; i < len; i++) {\n width += this._getWidthOfChar(ctx, text[i], lineIndex, i + charOffset);\n }\n return width;\n },\n\n /**\n * Wraps a line of text using the width of the Textbox and a context.\n * @param {CanvasRenderingContext2D} ctx Context to use for measurements\n * @param {String} text The string of text to split into lines\n * @param {Number} lineIndex\n * @returns {Array} Array of line(s) into which the given text is wrapped\n * to.\n */\n _wrapLine: function(ctx, text, lineIndex) {\n var lineWidth = 0,\n lines = [],\n line = '',\n words = text.split(' '),\n word = '',\n offset = 0,\n infix = ' ',\n wordWidth = 0,\n infixWidth = 0,\n largestWordWidth = 0,\n lineJustStarted = true,\n additionalSpace = this._getWidthOfCharSpacing();\n\n for (var i = 0; i < words.length; i++) {\n word = words[i];\n wordWidth = this._measureText(ctx, word, lineIndex, offset);\n\n offset += word.length;\n\n lineWidth += infixWidth + wordWidth - additionalSpace;\n\n if (lineWidth >= this.width && !lineJustStarted) {\n lines.push(line);\n line = '';\n lineWidth = wordWidth;\n lineJustStarted = true;\n }\n else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted) {\n line += infix;\n }\n line += word;\n\n infixWidth = this._measureText(ctx, infix, lineIndex, offset);\n offset++;\n lineJustStarted = false;\n // keep track of largest word\n if (wordWidth > largestWordWidth) {\n largestWordWidth = wordWidth;\n }\n }\n\n i && lines.push(line);\n\n if (largestWordWidth > this.dynamicMinWidth) {\n this.dynamicMinWidth = largestWordWidth - additionalSpace;\n }\n\n return lines;\n },\n /**\n * Gets lines of text to render in the Textbox. This function calculates\n * text wrapping on the fly everytime it is called.\n * @returns {Array} Array of lines in the Textbox.\n * @override\n */\n _splitTextIntoLines: function(ctx) {\n ctx = ctx || this.ctx;\n var originalAlign = this.textAlign;\n this._styleMap = null;\n ctx.save();\n this._setTextStyles(ctx);\n this.textAlign = 'left';\n var lines = this._wrapText(ctx, this.text);\n this.textAlign = originalAlign;\n ctx.restore();\n this._textLines = lines;\n this._styleMap = this._generateStyleMap();\n return lines;\n },\n\n /**\n * When part of a group, we don't want the Textbox's scale to increase if\n * the group's increases. That's why we reduce the scale of the Textbox by\n * the amount that the group's increases. This is to maintain the effective\n * scale of the Textbox at 1, so that font-size values make sense. Otherwise\n * the same font-size value would result in different actual size depending\n * on the value of the scale.\n * @param {String} key\n * @param {*} value\n */\n setOnGroup: function(key, value) {\n if (key === 'scaleX') {\n this.set('scaleX', Math.abs(1 / value));\n this.set('width', (this.get('width') * value) /\n (typeof this.__oldScaleX === 'undefined' ? 1 : this.__oldScaleX));\n this.__oldScaleX = value;\n }\n },\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start).\n * Overrides the superclass function to take into account text wrapping.\n *\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n */\n get2DCursorLocation: function(selectionStart) {\n if (typeof selectionStart === 'undefined') {\n selectionStart = this.selectionStart;\n }\n\n var numLines = this._textLines.length,\n removed = 0;\n\n for (var i = 0; i < numLines; i++) {\n var line = this._textLines[i],\n lineLen = line.length;\n\n if (selectionStart <= removed + lineLen) {\n return {\n lineIndex: i,\n charIndex: selectionStart - removed\n };\n }\n\n removed += lineLen;\n\n if (this.text[removed] === '\\n' || this.text[removed] === ' ') {\n removed++;\n }\n }\n\n return {\n lineIndex: numLines - 1,\n charIndex: this._textLines[numLines - 1].length\n };\n },\n\n /**\n * Overrides superclass function and uses text wrapping data to get cursor\n * boundary offsets instead of the array of chars.\n * @param {Array} chars Unused\n * @param {String} typeOfBoundaries Can be 'cursor' or 'selection'\n * @returns {Object} Object with 'top', 'left', and 'lineLeft' properties set.\n */\n _getCursorBoundariesOffsets: function(chars, typeOfBoundaries) {\n var topOffset = 0,\n leftOffset = 0,\n cursorLocation = this.get2DCursorLocation(),\n lineChars = this._textLines[cursorLocation.lineIndex].split(''),\n lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, cursorLocation.lineIndex));\n\n for (var i = 0; i < cursorLocation.charIndex; i++) {\n leftOffset += this._getWidthOfChar(this.ctx, lineChars[i], cursorLocation.lineIndex, i);\n }\n\n for (i = 0; i < cursorLocation.lineIndex; i++) {\n topOffset += this._getHeightOfLine(this.ctx, i);\n }\n\n if (typeOfBoundaries === 'cursor') {\n topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, cursorLocation.lineIndex)\n / this.lineHeight - this.getCurrentCharFontSize(cursorLocation.lineIndex, cursorLocation.charIndex)\n * (1 - this._fontSizeFraction);\n }\n\n return {\n top: topOffset,\n left: leftOffset,\n lineLeft: lineLeftOffset\n };\n },\n\n getMinWidth: function() {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n },\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['minWidth'].concat(propertiesToInclude));\n }\n });\n\n /**\n * Returns fabric.Textbox instance from an object representation\n * @static\n * @memberOf fabric.Textbox\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created\n * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first\n * @return {fabric.Textbox} instance of fabric.Textbox\n */\n fabric.Textbox.fromObject = function(object, callback, forceAsync) {\n return fabric.Object._fromObject('Textbox', object, callback, forceAsync, 'text');\n };\n\n /**\n * Returns the default controls visibility required for Textboxes.\n * @returns {Object}\n */\n fabric.Textbox.getTextboxControlVisibility = function() {\n return {\n tl: false,\n tr: false,\n br: false,\n bl: false,\n ml: true,\n mt: false,\n mr: true,\n mb: false,\n mtr: true\n };\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n /**\n * Override _setObjectScale and add Textbox specific resizing behavior. Resizing\n * a Textbox doesn't scale text, it only changes width and makes text wrap automatically.\n */\n var setObjectScaleOverridden = fabric.Canvas.prototype._setObjectScale;\n\n fabric.Canvas.prototype._setObjectScale = function(localMouse, transform,\n lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {\n\n var t = transform.target;\n if (t instanceof fabric.Textbox) {\n var w = t.width * ((localMouse.x / transform.scaleX) / (t.width + t.strokeWidth));\n if (w >= t.getMinWidth()) {\n t.set('width', w);\n return true;\n }\n }\n else {\n return setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform,\n lockScalingX, lockScalingY, by, lockScalingFlip, _dim);\n }\n };\n\n /**\n * Sets controls of this group to the Textbox's special configuration if\n * one is present in the group. Deletes _controlsVisibility otherwise, so that\n * it gets initialized to default value at runtime.\n */\n fabric.Group.prototype._refreshControlsVisibility = function() {\n if (typeof fabric.Textbox === 'undefined') {\n return;\n }\n for (var i = this._objects.length; i--;) {\n if (this._objects[i] instanceof fabric.Textbox) {\n this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());\n return;\n }\n }\n };\n\n fabric.util.object.extend(fabric.Textbox.prototype, /** @lends fabric.IText.prototype */ {\n /**\n * @private\n */\n _removeExtraneousStyles: function() {\n for (var prop in this._styleMap) {\n if (!this._textLines[prop]) {\n delete this.styles[this._styleMap[prop].line];\n }\n }\n },\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Object} [style] Style object to insert, if given\n */\n insertCharStyleObject: function(lineIndex, charIndex, style) {\n // adjust lineIndex and charIndex\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n fabric.IText.prototype.insertCharStyleObject.apply(this, [lineIndex, charIndex, style]);\n },\n\n /**\n * Inserts new style object\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Boolean} isEndOfLine True if it's end of line\n */\n insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) {\n // adjust lineIndex and charIndex\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n fabric.IText.prototype.insertNewlineStyleObject.apply(this, [lineIndex, charIndex, isEndOfLine]);\n },\n\n /**\n * Shifts line styles up or down. This function is slightly different than the one in\n * itext_behaviour as it takes into account the styleMap.\n *\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can be -1 or +1\n */\n shiftLineStyles: function(lineIndex, offset) {\n // shift all line styles by 1 upward\n var map = this._styleMap[lineIndex];\n // adjust line index\n lineIndex = map.line;\n fabric.IText.prototype.shiftLineStyles.call(this, lineIndex, offset);\n },\n\n /**\n * Figure out programatically the text on previous actual line (actual = separated by \\n);\n *\n * @param {Number} lIndex\n * @returns {String}\n * @private\n */\n _getTextOnPreviousLine: function(lIndex) {\n var textOnPreviousLine = this._textLines[lIndex - 1];\n\n while (this._styleMap[lIndex - 2] && this._styleMap[lIndex - 2].line === this._styleMap[lIndex - 1].line) {\n textOnPreviousLine = this._textLines[lIndex - 2] + textOnPreviousLine;\n\n lIndex--;\n }\n\n return textOnPreviousLine;\n },\n\n /**\n * Removes style object\n * @param {Boolean} isBeginningOfLine True if cursor is at the beginning of line\n * @param {Number} [index] Optional index. When not given, current selectionStart is used.\n */\n removeStyleObject: function(isBeginningOfLine, index) {\n\n var cursorLocation = this.get2DCursorLocation(index),\n map = this._styleMap[cursorLocation.lineIndex],\n lineIndex = map.line,\n charIndex = map.offset + cursorLocation.charIndex;\n this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex);\n }\n });\n})();\n\n\n(function() {\n var override = fabric.IText.prototype._getNewSelectionStartFromOffset;\n /**\n * Overrides the IText implementation and adjusts character index as there is not always a linebreak\n *\n * @param {Number} mouseOffset\n * @param {Number} prevWidth\n * @param {Number} width\n * @param {Number} index\n * @param {Number} jlen\n * @returns {Number}\n */\n fabric.IText.prototype._getNewSelectionStartFromOffset = function(mouseOffset, prevWidth, width, index, jlen) {\n index = override.call(this, mouseOffset, prevWidth, width, index, jlen);\n\n // the index passed into the function is padded by the amount of lines from _textLines (to account for \\n)\n // we need to remove this padding, and pad it by actual lines, and / or spaces that are meant to be there\n var tmp = 0,\n removed = 0;\n\n // account for removed characters\n for (var i = 0; i < this._textLines.length; i++) {\n tmp += this._textLines[i].length;\n\n if (tmp + removed >= index) {\n break;\n }\n\n if (this.text[tmp + removed] === '\\n' || this.text[tmp + removed] === ' ') {\n removed++;\n }\n }\n\n return index - i + removed;\n };\n})();\n\n\n(function() {\n\n if (typeof document !== 'undefined' && typeof window !== 'undefined') {\n return;\n }\n\n var DOMParser = require('xmldom').DOMParser,\n URL = require('url'),\n HTTP = require('http'),\n HTTPS = require('https'),\n\n Canvas = require('canvas'),\n Image = require('canvas').Image;\n\n /** @private */\n function request(url, encoding, callback) {\n var oURL = URL.parse(url);\n\n // detect if http or https is used\n if ( !oURL.port ) {\n oURL.port = ( oURL.protocol.indexOf('https:') === 0 ) ? 443 : 80;\n }\n\n // assign request handler based on protocol\n var reqHandler = (oURL.protocol.indexOf('https:') === 0 ) ? HTTPS : HTTP,\n req = reqHandler.request({\n hostname: oURL.hostname,\n port: oURL.port,\n path: oURL.path,\n method: 'GET'\n }, function(response) {\n var body = '';\n if (encoding) {\n response.setEncoding(encoding);\n }\n response.on('end', function () {\n callback(body);\n });\n response.on('data', function (chunk) {\n if (response.statusCode === 200) {\n body += chunk;\n }\n });\n });\n\n req.on('error', function(err) {\n if (err.errno === process.ECONNREFUSED) {\n fabric.log('ECONNREFUSED: connection refused to ' + oURL.hostname + ':' + oURL.port);\n }\n else {\n fabric.log(err.message);\n }\n callback(null);\n });\n\n req.end();\n }\n\n /** @private */\n function requestFs(path, callback) {\n var fs = require('fs');\n fs.readFile(path, function (err, data) {\n if (err) {\n fabric.log(err);\n throw err;\n }\n else {\n callback(data);\n }\n });\n }\n\n fabric.util.loadImage = function(url, callback, context) {\n function createImageAndCallBack(data) {\n if (data) {\n img.src = new Buffer(data, 'binary');\n // preserving original url, which seems to be lost in node-canvas\n img._src = url;\n callback && callback.call(context, img);\n }\n else {\n img = null;\n callback && callback.call(context, null, true);\n }\n }\n var img = new Image();\n if (url && (url instanceof Buffer || url.indexOf('data') === 0)) {\n img.src = img._src = url;\n callback && callback.call(context, img);\n }\n else if (url && url.indexOf('http') !== 0) {\n requestFs(url, createImageAndCallBack);\n }\n else if (url) {\n request(url, 'binary', createImageAndCallBack);\n }\n else {\n callback && callback.call(context, url);\n }\n };\n\n fabric.loadSVGFromURL = function(url, callback, reviver) {\n url = url.replace(/^\\n\\s*/, '').replace(/\\?.*$/, '').trim();\n if (url.indexOf('http') !== 0) {\n requestFs(url, function(body) {\n fabric.loadSVGFromString(body.toString(), callback, reviver);\n });\n }\n else {\n request(url, '', function(body) {\n fabric.loadSVGFromString(body, callback, reviver);\n });\n }\n };\n\n fabric.loadSVGFromString = function(string, callback, reviver) {\n var doc = new DOMParser().parseFromString(string);\n fabric.parseSVGDocument(doc.documentElement, function(results, options) {\n callback && callback(results, options);\n }, reviver);\n };\n\n fabric.util.getScript = function(url, callback) {\n request(url, '', function(body) {\n // eslint-disable-next-line no-eval\n eval(body);\n callback && callback();\n });\n };\n\n // fabric.util.createCanvasElement = function(_, width, height) {\n // return new Canvas(width, height);\n // }\n\n /**\n * Only available when running fabric on node.js\n * @param {Number} width Canvas width\n * @param {Number} height Canvas height\n * @param {Object} [options] Options to pass to FabricCanvas.\n * @param {Object} [nodeCanvasOptions] Options to pass to NodeCanvas.\n * @return {Object} wrapped canvas instance\n */\n fabric.createCanvasForNode = function(width, height, options, nodeCanvasOptions) {\n nodeCanvasOptions = nodeCanvasOptions || options;\n\n var canvasEl = fabric.document.createElement('canvas'),\n nodeCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions),\n nodeCacheCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions);\n\n // jsdom doesn't create style on canvas element, so here be temp. workaround\n canvasEl.style = { };\n\n canvasEl.width = nodeCanvas.width;\n canvasEl.height = nodeCanvas.height;\n options = options || { };\n options.nodeCanvas = nodeCanvas;\n options.nodeCacheCanvas = nodeCacheCanvas;\n var FabricCanvas = fabric.Canvas || fabric.StaticCanvas,\n fabricCanvas = new FabricCanvas(canvasEl, options);\n fabricCanvas.nodeCanvas = nodeCanvas;\n fabricCanvas.nodeCacheCanvas = nodeCacheCanvas;\n fabricCanvas.contextContainer = nodeCanvas.getContext('2d');\n fabricCanvas.contextCache = nodeCacheCanvas.getContext('2d');\n fabricCanvas.Font = Canvas.Font;\n return fabricCanvas;\n };\n\n var originaInitStatic = fabric.StaticCanvas.prototype._initStatic;\n fabric.StaticCanvas.prototype._initStatic = function(el, options) {\n el = el || fabric.document.createElement('canvas');\n this.nodeCanvas = new Canvas(el.width, el.height);\n this.nodeCacheCanvas = new Canvas(el.width, el.height);\n originaInitStatic.call(this, el, options);\n this.contextContainer = this.nodeCanvas.getContext('2d');\n this.contextCache = this.nodeCacheCanvas.getContext('2d');\n this.Font = Canvas.Font;\n };\n\n /** @ignore */\n fabric.StaticCanvas.prototype.createPNGStream = function() {\n return this.nodeCanvas.createPNGStream();\n };\n\n fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {\n return this.nodeCanvas.createJPEGStream(opts);\n };\n\n fabric.StaticCanvas.prototype._initRetinaScaling = function() {\n if (!this._isRetinaScaling()) {\n return;\n }\n\n this.lowerCanvasEl.setAttribute('width', this.width * fabric.devicePixelRatio);\n this.lowerCanvasEl.setAttribute('height', this.height * fabric.devicePixelRatio);\n this.nodeCanvas.width = this.width * fabric.devicePixelRatio;\n this.nodeCanvas.height = this.height * fabric.devicePixelRatio;\n this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio);\n return this;\n };\n if (fabric.Canvas) {\n fabric.Canvas.prototype._initRetinaScaling = fabric.StaticCanvas.prototype._initRetinaScaling;\n }\n\n var origSetBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension;\n fabric.StaticCanvas.prototype._setBackstoreDimension = function(prop, value) {\n origSetBackstoreDimension.call(this, prop, value);\n this.nodeCanvas[prop] = value;\n return this;\n };\n if (fabric.Canvas) {\n fabric.Canvas.prototype._setBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension;\n }\n\n})();\n\n"]} \ No newline at end of file diff --git a/lib/fileupload/jquery.fileupload.js b/lib/fileupload/jquery.fileupload.js index bcb5912215d..b05c398d7ae 100644 --- a/lib/fileupload/jquery.fileupload.js +++ b/lib/fileupload/jquery.fileupload.js @@ -1,2 +1,2 @@ -!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery","jquery-ui/ui/widget"],e):"object"==typeof exports?e(require("jquery"),require("./vendor/jquery.ui.widget")):e(window.jQuery)}(function(m){"use strict";function e(i){var r="dragover"===i;return function(e){e.dataTransfer=e.originalEvent&&e.originalEvent.dataTransfer;var t=e.dataTransfer;t&&-1!==m.inArray("Files",t.types)&&!1!==this._trigger(i,m.Event(i,{delegatedEvent:e}))&&(e.preventDefault(),r&&(t.dropEffect="copy"))}}m.support.fileInput=!(new RegExp("(Android (1\\.[0156]|2\\.[01]))|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)|(w(eb)?OSBrowser)|(webOS)|(Kindle/(1\\.0|2\\.[05]|3\\.0))").test(window.navigator.userAgent)||m('').prop("disabled")),m.support.xhrFileUpload=!(!window.ProgressEvent||!window.FileReader),m.support.xhrFormDataFileUpload=!!window.FormData,m.support.blobSlice=window.Blob&&(Blob.prototype.slice||Blob.prototype.webkitSlice||Blob.prototype.mozSlice),m.widget("blueimp.fileupload",{options:{dropZone:m(document),pasteZone:void 0,fileInput:void 0,replaceFileInput:!0,paramName:void 0,singleFileUploads:!0,limitMultiFileUploads:void 0,limitMultiFileUploadSize:void 0,limitMultiFileUploadSizeOverhead:512,sequentialUploads:!1,limitConcurrentUploads:void 0,forceIframeTransport:!1,redirect:void 0,redirectParamName:void 0,postMessage:void 0,multipart:!0,maxChunkSize:void 0,uploadedBytes:void 0,recalculateProgress:!0,progressInterval:100,bitrateInterval:500,autoUpload:!0,messages:{uploadedBytes:"Uploaded bytes exceed file size"},i18n:function(i,e){return i=this.messages[i]||i.toString(),e&&m.each(e,function(e,t){i=i.replace("{"+e+"}",t)}),i},formData:function(e){return e.serializeArray()},add:function(e,t){if(e.isDefaultPrevented())return!1;(t.autoUpload||!1!==t.autoUpload&&m(this).fileupload("option","autoUpload"))&&t.process().done(function(){t.submit()})},processData:!1,contentType:!1,cache:!1,timeout:0},_specialOptions:["fileInput","dropZone","pasteZone","multipart","forceIframeTransport"],_blobSlice:m.support.blobSlice&&function(){return(this.slice||this.webkitSlice||this.mozSlice).apply(this,arguments)},_BitrateTimer:function(){this.timestamp=Date.now?Date.now():(new Date).getTime(),this.loaded=0,this.bitrate=0,this.getBitrate=function(e,t,i){var r=e-this.timestamp;return(!this.bitrate||!i||i").prop("href",e.url).prop("host");e.dataType="iframe "+(e.dataType||""),e.formData=this._getFormData(e),e.redirect&&t&&t!==location.host&&e.formData.push({name:e.redirectParamName||"redirect",value:e.redirect})},_initDataSettings:function(e){this._isXHRUpload(e)?(this._chunkedUpload(e,!0)||(e.data||this._initXHRData(e),this._initProgressListener(e)),e.postMessage&&(e.dataType="postmessage "+(e.dataType||""))):this._initIframeSettings(e)},_getParamName:function(e){var t=m(e.fileInput),r=e.paramName;return r?m.isArray(r)||(r=[r]):(r=[],t.each(function(){for(var e=m(this),t=e.prop("name")||"files[]",i=(e.prop("files")||[1]).length;i;)r.push(t),i-=1}),r.length||(r=[t.prop("name")||"files[]"])),r},_initFormSettings:function(e){e.form&&e.form.length||(e.form=m(e.fileInput.prop("form")),e.form.length||(e.form=m(this.options.fileInput.prop("form")))),e.paramName=this._getParamName(e),e.url||(e.url=e.form.prop("action")||location.href),e.type=(e.type||"string"===m.type(e.form.prop("method"))&&e.form.prop("method")||"").toUpperCase(),"POST"!==e.type&&"PUT"!==e.type&&"PATCH"!==e.type&&(e.type="POST"),e.formAcceptCharset||(e.formAcceptCharset=e.form.attr("accept-charset"))},_getAJAXSettings:function(e){var t=m.extend({},this.options,e);return this._initFormSettings(t),this._initDataSettings(t),t},_getDeferredState:function(e){return e.state?e.state():e.isResolved()?"resolved":e.isRejected()?"rejected":"pending"},_enhancePromise:function(e){return e.success=e.done,e.error=e.fail,e.complete=e.always,e},_getXHRPromise:function(e,t,i){var r=m.Deferred(),n=r.promise();return t=t||this.options.context||n,!0===e?r.resolveWith(t,i):!1===e&&r.rejectWith(t,i),n.abort=r.promise,this._enhancePromise(n)},_addConvenienceMethods:function(e,i){var r=this,n=function(e){return m.Deferred().resolveWith(r,e).promise()};i.process=function(e,t){return(e||t)&&(i._processQueue=this._processQueue=(this._processQueue||n([this])).then(function(){return i.errorThrown?m.Deferred().rejectWith(r,[i]).promise():n(arguments)}).then(e,t)),this._processQueue||n([this])},i.submit=function(){return"pending"!==this.state()&&(i.jqXHR=this.jqXHR=!1!==r._trigger("submit",m.Event("submit",{delegatedEvent:e}),this)&&r._onSend(e,this)),this.jqXHR||r._getXHRPromise()},i.abort=function(){return this.jqXHR?this.jqXHR.abort():(this.errorThrown="abort",r._trigger("fail",null,this),r._getXHRPromise(!1))},i.state=function(){return this.jqXHR?r._getDeferredState(this.jqXHR):this._processQueue?r._getDeferredState(this._processQueue):void 0},i.processing=function(){return!this.jqXHR&&this._processQueue&&"pending"===r._getDeferredState(this._processQueue)},i.progress=function(){return this._progress},i.response=function(){return this._response}},_getUploadedBytes:function(e){var t=e.getResponseHeader("Range"),i=t&&t.split("-"),r=i&&1s._sending)for(var r=s._slots.shift();r;){if("pending"===s._getDeferredState(r)){r.resolve();break}r=s._slots.shift()}0===s._active&&s._trigger("stop")})};return this._beforeSend(e,a),this.options.sequentialUploads||this.options.limitConcurrentUploads&&this.options.limitConcurrentUploads<=this._sending?((o=1h||d&&d<=t+1-_)&&(s.push(p.slice(_,t+1)),(e=g.slice(_,t+1)).length||(e=g),o.push(e),_=t+1,f=0);else o=g;else for(s=[],o=[],t=0;t").append(r)[0].reset(),i.after(r).detach(),t&&r.focus(),m.cleanData(i.unbind("remove")),this.options.fileInput=this.options.fileInput.map(function(e,t){return t===i[0]?r[0]:t}),i[0]===this.element[0]&&(this.element=r)},_handleFileTreeEntry:function(i,r){var e,n=this,o=m.Deferred(),s=[],a=function(e){e&&!e.entry&&(e.entry=i),o.resolve([e])},l=function(){e.readEntries(function(e){var t;e.length?(s=s.concat(e),l()):(t=s,n._handleFileTreeEntries(t,r+i.name+"/").done(function(e){o.resolve(e)}).fail(a))},a)};return r=r||"",i.isFile?i._file?(i._file.relativePath=r,o.resolve(i._file)):i.file(function(e){e.relativePath=r,o.resolve(e)},a):i.isDirectory?(e=i.createReader(),l()):o.resolve([]),o.promise()},_handleFileTreeEntries:function(e,t){var i=this;return m.when.apply(m,m.map(e,function(e){return i._handleFileTreeEntry(e,t)})).then(function(){return Array.prototype.concat.apply([],arguments)})},_getDroppedFiles:function(e){var t=(e=e||{}).items;return t&&t.length&&(t[0].webkitGetAsEntry||t[0].getAsEntry)?this._handleFileTreeEntries(m.map(t,function(e){var t;return e.webkitGetAsEntry?((t=e.webkitGetAsEntry())&&(t._file=e.getAsFile()),t):e.getAsEntry()})):m.Deferred().resolve(m.makeArray(e.files)).promise()},_getSingleFileInputFiles:function(e){var t,i,r=(e=m(e)).prop("webkitEntries")||e.prop("entries");if(r&&r.length)return this._handleFileTreeEntries(r);if((t=m.makeArray(e.prop("files"))).length)void 0===t[0].name&&t[0].fileName&&m.each(t,function(e,t){t.name=t.fileName,t.size=t.fileSize});else{if(!(i=e.prop("value")))return m.Deferred().resolve([]).promise();t=[{name:i.replace(/^.*\\/,"")}]}return m.Deferred().resolve(t).promise()},_getFileInputFiles:function(e){return e instanceof m&&1!==e.length?m.when.apply(m,m.map(e,this._getSingleFileInputFiles)).then(function(){return Array.prototype.concat.apply([],arguments)}):this._getSingleFileInputFiles(e)},_onChange:function(t){var i=this,r={fileInput:m(t.target),form:m(t.target.form)};this._getFileInputFiles(r.fileInput).always(function(e){r.files=e,i.options.replaceFileInput&&i._replaceFileInput(r),!1!==i._trigger("change",m.Event("change",{delegatedEvent:t}),r)&&i._onAdd(t,r)})},_onPaste:function(e){var t=e.originalEvent&&e.originalEvent.clipboardData&&e.originalEvent.clipboardData.items,r={files:[]};t&&t.length&&(m.each(t,function(e,t){var i=t.getAsFile&&t.getAsFile();i&&r.files.push(i)}),!1!==this._trigger("paste",m.Event("paste",{delegatedEvent:e}),r)&&this._onAdd(e,r))},_onDrop:function(t){t.dataTransfer=t.originalEvent&&t.originalEvent.dataTransfer;var i=this,e=t.dataTransfer,r={};e&&e.files&&e.files.length&&(t.preventDefault(),this._getDroppedFiles(e).always(function(e){r.files=e,!1!==i._trigger("drop",m.Event("drop",{delegatedEvent:t}),r)&&i._onAdd(t,r)}))},_onDragOver:e("dragover"),_onDragEnter:e("dragenter"),_onDragLeave:e("dragleave"),_initEventHandlers:function(){this._isXHRUpload(this.options)&&(this._on(this.options.dropZone,{dragover:this._onDragOver,drop:this._onDrop,dragenter:this._onDragEnter,dragleave:this._onDragLeave}),this._on(this.options.pasteZone,{paste:this._onPaste})),m.support.fileInput&&this._on(this.options.fileInput,{change:this._onChange})},_destroyEventHandlers:function(){this._off(this.options.dropZone,"dragenter dragleave dragover drop"),this._off(this.options.pasteZone,"paste"),this._off(this.options.fileInput,"change")},_destroy:function(){this._destroyEventHandlers()},_setOption:function(e,t){var i=-1!==m.inArray(e,this._specialOptions);i&&this._destroyEventHandlers(),this._super(e,t),i&&(this._initSpecialOptions(),this._initEventHandlers())},_initSpecialOptions:function(){var e=this.options;void 0===e.fileInput?e.fileInput=this.element.is('input[type="file"]')?this.element:this.element.find('input[type="file"]'):e.fileInput instanceof m||(e.fileInput=m(e.fileInput)),e.dropZone instanceof m||(e.dropZone=m(e.dropZone)),e.pasteZone instanceof m||(e.pasteZone=m(e.pasteZone))},_getRegExp:function(e){var t=e.split("/"),i=t.pop();return t.shift(),new RegExp(t.join("/"),i)},_isRegExpOption:function(e,t){return"url"!==e&&"string"===m.type(t)&&/^\/.*\/[igm]{0,3}$/.test(t)},_initDataAttributes:function(){var n=this,o=this.options,s=this.element.data();m.each(this.element[0].attributes,function(e,t){var i,r=t.name.toLowerCase();/^data-/.test(r)&&(r=r.slice(5).replace(/-[a-z]/g,function(e){return e.charAt(1).toUpperCase()}),i=s[r],n._isRegExpOption(r,i)&&(i=n._getRegExp(i)),o[r]=i)})},_create:function(){this._initDataAttributes(),this._initSpecialOptions(),this._slots=[],this._sequence=this._getXHRPromise(!0),this._sending=this._active=0,this._initProgressObject(this),this._initEventHandlers()},active:function(){return this._active},progress:function(){return this._progress},add:function(t){var i=this;t&&!this.options.disabled&&(t.fileInput&&!t.files?this._getFileInputFiles(t.fileInput).always(function(e){t.files=e,i._onAdd(null,t)}):(t.files=m.makeArray(t.files),this._onAdd(null,t)))},send:function(t){if(t&&!this.options.disabled){if(t.fileInput&&!t.files){var i,r,n=this,o=m.Deferred(),e=o.promise();return e.abort=function(){return r=!0,i?i.abort():(o.reject(null,"abort","abort"),e)},this._getFileInputFiles(t.fileInput).always(function(e){r||(e.length?(t.files=e,(i=n._onSend(null,t)).then(function(e,t,i){o.resolve(e,t,i)},function(e,t,i){o.reject(e,t,i)})):o.reject())}),this._enhancePromise(e)}if(t.files=m.makeArray(t.files),t.files.length)return this._onSend(null,t)}return this._getXHRPromise(!1,t&&t.context)}})}); +!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery","jquery-ui/ui/widget"],e):"object"==typeof exports?e(require("jquery"),require("./vendor/jquery.ui.widget")):e(window.jQuery)}(function(m){"use strict";function e(i){var r="dragover"===i;return function(e){e.dataTransfer=e.originalEvent&&e.originalEvent.dataTransfer;var t=e.dataTransfer;t&&-1!==m.inArray("Files",t.types)&&!1!==this._trigger(i,m.Event(i,{delegatedEvent:e}))&&(e.preventDefault(),r&&(t.dropEffect="copy"))}}m.support.fileInput=!(new RegExp("(Android (1\\.[0156]|2\\.[01]))|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)|(w(eb)?OSBrowser)|(webOS)|(Kindle/(1\\.0|2\\.[05]|3\\.0))").test(window.navigator.userAgent)||m('').prop("disabled")),m.support.xhrFileUpload=!(!window.ProgressEvent||!window.FileReader),m.support.xhrFormDataFileUpload=!!window.FormData,m.support.blobSlice=window.Blob&&(Blob.prototype.slice||Blob.prototype.webkitSlice||Blob.prototype.mozSlice),m.widget("blueimp.fileupload",{options:{dropZone:m(document),pasteZone:void 0,fileInput:void 0,replaceFileInput:!0,paramName:void 0,singleFileUploads:!0,limitMultiFileUploads:void 0,limitMultiFileUploadSize:void 0,limitMultiFileUploadSizeOverhead:512,sequentialUploads:!1,limitConcurrentUploads:void 0,forceIframeTransport:!1,redirect:void 0,redirectParamName:void 0,postMessage:void 0,multipart:!0,maxChunkSize:void 0,uploadedBytes:void 0,recalculateProgress:!0,progressInterval:100,bitrateInterval:500,autoUpload:!0,messages:{uploadedBytes:"Uploaded bytes exceed file size"},i18n:function(i,e){return i=this.messages[i]||i.toString(),e&&m.each(e,function(e,t){i=i.replace("{"+e+"}",t)}),i},formData:function(e){return e.serializeArray()},add:function(e,t){if(e.isDefaultPrevented())return!1;(t.autoUpload||!1!==t.autoUpload&&m(this).fileupload("option","autoUpload"))&&t.process().done(function(){t.submit()})},processData:!1,contentType:!1,cache:!1,timeout:0},_specialOptions:["fileInput","dropZone","pasteZone","multipart","forceIframeTransport"],_blobSlice:m.support.blobSlice&&function(){return(this.slice||this.webkitSlice||this.mozSlice).apply(this,arguments)},_BitrateTimer:function(){this.timestamp=Date.now?Date.now():(new Date).getTime(),this.loaded=0,this.bitrate=0,this.getBitrate=function(e,t,i){var r=e-this.timestamp;return this.bitrate&&i&&!(i").prop("href",e.url).prop("host");e.dataType="iframe "+(e.dataType||""),e.formData=this._getFormData(e),e.redirect&&t&&t!==location.host&&e.formData.push({name:e.redirectParamName||"redirect",value:e.redirect})},_initDataSettings:function(e){this._isXHRUpload(e)?(this._chunkedUpload(e,!0)||(e.data||this._initXHRData(e),this._initProgressListener(e)),e.postMessage&&(e.dataType="postmessage "+(e.dataType||""))):this._initIframeSettings(e)},_getParamName:function(e){var t=m(e.fileInput),r=e.paramName;return r?m.isArray(r)||(r=[r]):(r=[],t.each(function(){for(var e=m(this),t=e.prop("name")||"files[]",i=(e.prop("files")||[1]).length;i;)r.push(t),i-=1}),r.length||(r=[t.prop("name")||"files[]"])),r},_initFormSettings:function(e){e.form&&e.form.length||(e.form=m(e.fileInput.prop("form")),e.form.length||(e.form=m(this.options.fileInput.prop("form")))),e.paramName=this._getParamName(e),e.url||(e.url=e.form.prop("action")||location.href),e.type=(e.type||"string"===m.type(e.form.prop("method"))&&e.form.prop("method")||"").toUpperCase(),"POST"!==e.type&&"PUT"!==e.type&&"PATCH"!==e.type&&(e.type="POST"),e.formAcceptCharset||(e.formAcceptCharset=e.form.attr("accept-charset"))},_getAJAXSettings:function(e){var t=m.extend({},this.options,e);return this._initFormSettings(t),this._initDataSettings(t),t},_getDeferredState:function(e){return e.state?e.state():e.isResolved()?"resolved":e.isRejected()?"rejected":"pending"},_enhancePromise:function(e){return e.success=e.done,e.error=e.fail,e.complete=e.always,e},_getXHRPromise:function(e,t,i){var r=m.Deferred(),n=r.promise();return t=t||this.options.context||n,!0===e?r.resolveWith(t,i):!1===e&&r.rejectWith(t,i),n.abort=r.promise,this._enhancePromise(n)},_addConvenienceMethods:function(e,i){function r(e){return m.Deferred().resolveWith(n,e).promise()}var n=this;i.process=function(e,t){return(e||t)&&(i._processQueue=this._processQueue=(this._processQueue||r([this])).then(function(){return i.errorThrown?m.Deferred().rejectWith(n,[i]).promise():r(arguments)}).then(e,t)),this._processQueue||r([this])},i.submit=function(){return"pending"!==this.state()&&(i.jqXHR=this.jqXHR=!1!==n._trigger("submit",m.Event("submit",{delegatedEvent:e}),this)&&n._onSend(e,this)),this.jqXHR||n._getXHRPromise()},i.abort=function(){return this.jqXHR?this.jqXHR.abort():(this.errorThrown="abort",n._trigger("fail",null,this),n._getXHRPromise(!1))},i.state=function(){return this.jqXHR?n._getDeferredState(this.jqXHR):this._processQueue?n._getDeferredState(this._processQueue):void 0},i.processing=function(){return!this.jqXHR&&this._processQueue&&"pending"===n._getDeferredState(this._processQueue)},i.progress=function(){return this._progress},i.response=function(){return this._response}},_getUploadedBytes:function(e){var t=e.getResponseHeader("Range"),i=t&&t.split("-"),r=i&&1a._sending)for(var r=a._slots.shift();r;){if("pending"===a._getDeferredState(r)){r.resolve();break}r=a._slots.shift()}0===a._active&&a._trigger("stop")})}var r,n,o,s,a=this,l=a._getAJAXSettings(t);return this._beforeSend(e,l),this.options.sequentialUploads||this.options.limitConcurrentUploads&&this.options.limitConcurrentUploads<=this._sending?((s=1h||d&&d<=t+1-_)&&(s.push(p.slice(_,t+1)),(e=g.slice(_,t+1)).length||(e=g),o.push(e),_=t+1,f=0);else o=g;else for(s=[],o=[],t=0;t").append(r)[0].reset(),i.after(r).detach(),t&&r.focus(),m.cleanData(i.unbind("remove")),this.options.fileInput=this.options.fileInput.map(function(e,t){return t===i[0]?r[0]:t}),i[0]===this.element[0]&&(this.element=r)},_handleFileTreeEntry:function(t,i){function r(e){e&&!e.entry&&(e.entry=t),o.resolve([e])}var e,n=this,o=m.Deferred(),s=[],a=function(){e.readEntries(function(e){e.length?(s=s.concat(e),a()):function(e){n._handleFileTreeEntries(e,i+t.name+"/").done(function(e){o.resolve(e)}).fail(r)}(s)},r)};return i=i||"",t.isFile?t._file?(t._file.relativePath=i,o.resolve(t._file)):t.file(function(e){e.relativePath=i,o.resolve(e)},r):t.isDirectory?(e=t.createReader(),a()):o.resolve([]),o.promise()},_handleFileTreeEntries:function(e,t){var i=this;return m.when.apply(m,m.map(e,function(e){return i._handleFileTreeEntry(e,t)})).then(function(){return Array.prototype.concat.apply([],arguments)})},_getDroppedFiles:function(e){var t=(e=e||{}).items;return t&&t.length&&(t[0].webkitGetAsEntry||t[0].getAsEntry)?this._handleFileTreeEntries(m.map(t,function(e){var t;return e.webkitGetAsEntry?((t=e.webkitGetAsEntry())&&(t._file=e.getAsFile()),t):e.getAsEntry()})):m.Deferred().resolve(m.makeArray(e.files)).promise()},_getSingleFileInputFiles:function(e){var t,i,r=(e=m(e)).prop("webkitEntries")||e.prop("entries");if(r&&r.length)return this._handleFileTreeEntries(r);if((t=m.makeArray(e.prop("files"))).length)void 0===t[0].name&&t[0].fileName&&m.each(t,function(e,t){t.name=t.fileName,t.size=t.fileSize});else{if(!(i=e.prop("value")))return m.Deferred().resolve([]).promise();t=[{name:i.replace(/^.*\\/,"")}]}return m.Deferred().resolve(t).promise()},_getFileInputFiles:function(e){return e instanceof m&&1!==e.length?m.when.apply(m,m.map(e,this._getSingleFileInputFiles)).then(function(){return Array.prototype.concat.apply([],arguments)}):this._getSingleFileInputFiles(e)},_onChange:function(t){var i=this,r={fileInput:m(t.target),form:m(t.target.form)};this._getFileInputFiles(r.fileInput).always(function(e){r.files=e,i.options.replaceFileInput&&i._replaceFileInput(r),!1!==i._trigger("change",m.Event("change",{delegatedEvent:t}),r)&&i._onAdd(t,r)})},_onPaste:function(e){var t=e.originalEvent&&e.originalEvent.clipboardData&&e.originalEvent.clipboardData.items,r={files:[]};t&&t.length&&(m.each(t,function(e,t){var i=t.getAsFile&&t.getAsFile();i&&r.files.push(i)}),!1!==this._trigger("paste",m.Event("paste",{delegatedEvent:e}),r)&&this._onAdd(e,r))},_onDrop:function(t){t.dataTransfer=t.originalEvent&&t.originalEvent.dataTransfer;var i=this,e=t.dataTransfer,r={};e&&e.files&&e.files.length&&(t.preventDefault(),this._getDroppedFiles(e).always(function(e){r.files=e,!1!==i._trigger("drop",m.Event("drop",{delegatedEvent:t}),r)&&i._onAdd(t,r)}))},_onDragOver:e("dragover"),_onDragEnter:e("dragenter"),_onDragLeave:e("dragleave"),_initEventHandlers:function(){this._isXHRUpload(this.options)&&(this._on(this.options.dropZone,{dragover:this._onDragOver,drop:this._onDrop,dragenter:this._onDragEnter,dragleave:this._onDragLeave}),this._on(this.options.pasteZone,{paste:this._onPaste})),m.support.fileInput&&this._on(this.options.fileInput,{change:this._onChange})},_destroyEventHandlers:function(){this._off(this.options.dropZone,"dragenter dragleave dragover drop"),this._off(this.options.pasteZone,"paste"),this._off(this.options.fileInput,"change")},_destroy:function(){this._destroyEventHandlers()},_setOption:function(e,t){var i=-1!==m.inArray(e,this._specialOptions);i&&this._destroyEventHandlers(),this._super(e,t),i&&(this._initSpecialOptions(),this._initEventHandlers())},_initSpecialOptions:function(){var e=this.options;void 0===e.fileInput?e.fileInput=this.element.is('input[type="file"]')?this.element:this.element.find('input[type="file"]'):e.fileInput instanceof m||(e.fileInput=m(e.fileInput)),e.dropZone instanceof m||(e.dropZone=m(e.dropZone)),e.pasteZone instanceof m||(e.pasteZone=m(e.pasteZone))},_getRegExp:function(e){var t=e.split("/"),i=t.pop();return t.shift(),new RegExp(t.join("/"),i)},_isRegExpOption:function(e,t){return"url"!==e&&"string"===m.type(t)&&/^\/.*\/[igm]{0,3}$/.test(t)},_initDataAttributes:function(){var n=this,o=this.options,s=this.element.data();m.each(this.element[0].attributes,function(e,t){var i,r=t.name.toLowerCase();/^data-/.test(r)&&(r=r.slice(5).replace(/-[a-z]/g,function(e){return e.charAt(1).toUpperCase()}),i=s[r],n._isRegExpOption(r,i)&&(i=n._getRegExp(i)),o[r]=i)})},_create:function(){this._initDataAttributes(),this._initSpecialOptions(),this._slots=[],this._sequence=this._getXHRPromise(!0),this._sending=this._active=0,this._initProgressObject(this),this._initEventHandlers()},active:function(){return this._active},progress:function(){return this._progress},add:function(t){var i=this;t&&!this.options.disabled&&(t.fileInput&&!t.files?this._getFileInputFiles(t.fileInput).always(function(e){t.files=e,i._onAdd(null,t)}):(t.files=m.makeArray(t.files),this._onAdd(null,t)))},send:function(t){if(t&&!this.options.disabled){if(t.fileInput&&!t.files){var i,r,n=this,o=m.Deferred(),e=o.promise();return e.abort=function(){return r=!0,i?i.abort():(o.reject(null,"abort","abort"),e)},this._getFileInputFiles(t.fileInput).always(function(e){r||(e.length?(t.files=e,(i=n._onSend(null,t)).then(function(e,t,i){o.resolve(e,t,i)},function(e,t,i){o.reject(e,t,i)})):o.reject())}),this._enhancePromise(e)}if(t.files=m.makeArray(t.files),t.files.length)return this._onSend(null,t)}return this._getXHRPromise(!1,t&&t.context)}})}); //# sourceMappingURL=jquery.fileupload.js.map diff --git a/lib/fileupload/jquery.fileupload.js.map b/lib/fileupload/jquery.fileupload.js.map index 1dc40f8562c..a377576377c 100644 --- a/lib/fileupload/jquery.fileupload.js.map +++ b/lib/fileupload/jquery.fileupload.js.map @@ -1 +1 @@ -{"version":3,"sources":["jquery.fileupload.js"],"names":["factory","define","amd","exports","require","window","jQuery","$","getDragHandler","type","isDragOver","e","dataTransfer","originalEvent","inArray","types","this","_trigger","Event","delegatedEvent","preventDefault","dropEffect","support","fileInput","RegExp","test","navigator","userAgent","prop","xhrFileUpload","ProgressEvent","FileReader","xhrFormDataFileUpload","FormData","blobSlice","Blob","prototype","slice","webkitSlice","mozSlice","widget","options","dropZone","document","pasteZone","undefined","replaceFileInput","paramName","singleFileUploads","limitMultiFileUploads","limitMultiFileUploadSize","limitMultiFileUploadSizeOverhead","sequentialUploads","limitConcurrentUploads","forceIframeTransport","redirect","redirectParamName","postMessage","multipart","maxChunkSize","uploadedBytes","recalculateProgress","progressInterval","bitrateInterval","autoUpload","messages","i18n","message","context","toString","each","key","value","replace","formData","form","serializeArray","add","data","isDefaultPrevented","fileupload","process","done","submit","processData","contentType","cache","timeout","_specialOptions","_blobSlice","apply","arguments","_BitrateTimer","timestamp","Date","now","getTime","loaded","bitrate","getBitrate","interval","timeDiff","_isXHRUpload","_getFormData","isArray","name","push","_getTotal","files","total","index","file","size","_initProgressObject","obj","progress","_progress","extend","_initResponseObject","_response","hasOwnProperty","_onProgress","lengthComputable","_time","Math","floor","chunkSize","_bitrateTimer","_initProgressListener","that","xhr","ajaxSettings","upload","bind","oe","_deinitProgressListener","unbind","_isInstanceOf","Object","call","_initXHRData","headers","contentRange","blob","encodeURI","uploadName","field","append","_initIframeSettings","targetHost","url","dataType","location","host","_initDataSettings","_chunkedUpload","_getParamName","input","i","length","_initFormSettings","href","toUpperCase","formAcceptCharset","attr","_getAJAXSettings","_getDeferredState","deferred","state","isResolved","isRejected","_enhancePromise","promise","success","error","fail","complete","always","_getXHRPromise","resolveOrReject","args","dfd","Deferred","resolveWith","rejectWith","abort","_addConvenienceMethods","getPromise","resolveFunc","rejectFunc","_processQueue","then","errorThrown","jqXHR","_onSend","processing","response","_getUploadedBytes","range","getResponseHeader","parts","split","upperBytesPos","parseInt","testOnly","fs","ub","mcs","o","currentLoaded","ajax","result","textStatus","_beforeSend","_active","_onDone","_onFail","_onAlways","jqXHRorResult","jqXHRorError","aborted","slot","pipe","send","_sending","nextSlot","_slots","shift","resolve","_sequence","_onAdd","paramNameSet","paramNameSlice","fileSet","filesLength","limit","limitSize","overhead","batchSize","j","originalFiles","element","newData","_replaceFileInput","inputClone","clone","restoreFocus","is","activeElement","fileInputClone","reset","after","detach","focus","cleanData","map","el","_handleFileTreeEntry","entry","path","dirReader","entries","errorHandler","readEntries","results","concat","_handleFileTreeEntries","isFile","_file","relativePath","isDirectory","createReader","when","Array","_getDroppedFiles","items","webkitGetAsEntry","getAsEntry","item","getAsFile","makeArray","_getSingleFileInputFiles","fileName","fileSize","_getFileInputFiles","_onChange","target","_onPaste","clipboardData","_onDrop","_onDragOver","_onDragEnter","_onDragLeave","_initEventHandlers","_on","dragover","drop","dragenter","dragleave","paste","change","_destroyEventHandlers","_off","_destroy","_setOption","reinit","_super","_initSpecialOptions","find","_getRegExp","str","modifiers","pop","join","_isRegExpOption","_initDataAttributes","attributes","toLowerCase","charAt","_create","active","disabled","reject"],"mappings":"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","file":"jquery.fileupload.js","sourcesContent":["/*\n * jQuery File Upload Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, document, location, Blob, FormData */\n\n;(function (factory) {\n 'use strict';\n if (typeof define === 'function' && define.amd) {\n // Register as an anonymous AMD module:\n define([\n 'jquery',\n 'jquery-ui/ui/widget'\n ], factory);\n } else if (typeof exports === 'object') {\n // Node/CommonJS:\n factory(\n require('jquery'),\n require('./vendor/jquery.ui.widget')\n );\n } else {\n // Browser globals:\n factory(window.jQuery);\n }\n}(function ($) {\n 'use strict';\n\n // Detect file input support, based on\n // http://viljamis.com/blog/2012/file-upload-support-on-mobile/\n $.support.fileInput = !(new RegExp(\n // Handle devices which give false positives for the feature detection:\n '(Android (1\\\\.[0156]|2\\\\.[01]))' +\n '|(Windows Phone (OS 7|8\\\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +\n '|(w(eb)?OSBrowser)|(webOS)' +\n '|(Kindle/(1\\\\.0|2\\\\.[05]|3\\\\.0))'\n ).test(window.navigator.userAgent) ||\n // Feature detection for all other devices:\n $('').prop('disabled'));\n\n // The FileReader API is not actually used, but works as feature detection,\n // as some Safari versions (5?) support XHR file uploads via the FormData API,\n // but not non-multipart XHR file uploads.\n // window.XMLHttpRequestUpload is not available on IE10, so we check for\n // window.ProgressEvent instead to detect XHR2 file upload capability:\n $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);\n $.support.xhrFormDataFileUpload = !!window.FormData;\n\n // Detect support for Blob slicing (required for chunked uploads):\n $.support.blobSlice = window.Blob && (Blob.prototype.slice ||\n Blob.prototype.webkitSlice || Blob.prototype.mozSlice);\n\n // Helper function to create drag handlers for dragover/dragenter/dragleave:\n function getDragHandler(type) {\n var isDragOver = type === 'dragover';\n return function (e) {\n e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n var dataTransfer = e.dataTransfer;\n if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&\n this._trigger(\n type,\n $.Event(type, {delegatedEvent: e})\n ) !== false) {\n e.preventDefault();\n if (isDragOver) {\n dataTransfer.dropEffect = 'copy';\n }\n }\n };\n }\n\n // The fileupload widget listens for change events on file input fields defined\n // via fileInput setting and paste or drop events of the given dropZone.\n // In addition to the default jQuery Widget methods, the fileupload widget\n // exposes the \"add\" and \"send\" methods, to add or directly send files using\n // the fileupload API.\n // By default, files added via file input selection, paste, drag & drop or\n // \"add\" method are uploaded immediately, but it is possible to override\n // the \"add\" callback option to queue file uploads.\n $.widget('blueimp.fileupload', {\n\n options: {\n // The drop target element(s), by the default the complete document.\n // Set to null to disable drag & drop support:\n dropZone: $(document),\n // The paste target element(s), by the default undefined.\n // Set to a DOM node or jQuery object to enable file pasting:\n pasteZone: undefined,\n // The file input field(s), that are listened to for change events.\n // If undefined, it is set to the file input fields inside\n // of the widget element on plugin initialization.\n // Set to null to disable the change listener.\n fileInput: undefined,\n // By default, the file input field is replaced with a clone after\n // each input field change event. This is required for iframe transport\n // queues and allows change events to be fired for the same file\n // selection, but can be disabled by setting the following option to false:\n replaceFileInput: true,\n // The parameter name for the file form data (the request argument name).\n // If undefined or empty, the name property of the file input field is\n // used, or \"files[]\" if the file input name property is also empty,\n // can be a string or an array of strings:\n paramName: undefined,\n // By default, each file of a selection is uploaded using an individual\n // request for XHR type uploads. Set to false to upload file\n // selections in one request each:\n singleFileUploads: true,\n // To limit the number of files uploaded with one XHR request,\n // set the following option to an integer greater than 0:\n limitMultiFileUploads: undefined,\n // The following option limits the number of files uploaded with one\n // XHR request to keep the request size under or equal to the defined\n // limit in bytes:\n limitMultiFileUploadSize: undefined,\n // Multipart file uploads add a number of bytes to each uploaded file,\n // therefore the following option adds an overhead for each file used\n // in the limitMultiFileUploadSize configuration:\n limitMultiFileUploadSizeOverhead: 512,\n // Set the following option to true to issue all file upload requests\n // in a sequential order:\n sequentialUploads: false,\n // To limit the number of concurrent uploads,\n // set the following option to an integer greater than 0:\n limitConcurrentUploads: undefined,\n // Set the following option to true to force iframe transport uploads:\n forceIframeTransport: false,\n // Set the following option to the location of a redirect url on the\n // origin server, for cross-domain iframe transport uploads:\n redirect: undefined,\n // The parameter name for the redirect url, sent as part of the form\n // data and set to 'redirect' if this option is empty:\n redirectParamName: undefined,\n // Set the following option to the location of a postMessage window,\n // to enable postMessage transport uploads:\n postMessage: undefined,\n // By default, XHR file uploads are sent as multipart/form-data.\n // The iframe transport is always using multipart/form-data.\n // Set to false to enable non-multipart XHR uploads:\n multipart: true,\n // To upload large files in smaller chunks, set the following option\n // to a preferred maximum chunk size. If set to 0, null or undefined,\n // or the browser does not support the required Blob API, files will\n // be uploaded as a whole.\n maxChunkSize: undefined,\n // When a non-multipart upload or a chunked multipart upload has been\n // aborted, this option can be used to resume the upload by setting\n // it to the size of the already uploaded bytes. This option is most\n // useful when modifying the options object inside of the \"add\" or\n // \"send\" callbacks, as the options are cloned for each file upload.\n uploadedBytes: undefined,\n // By default, failed (abort or error) file uploads are removed from the\n // global progress calculation. Set the following option to false to\n // prevent recalculating the global progress data:\n recalculateProgress: true,\n // Interval in milliseconds to calculate and trigger progress events:\n progressInterval: 100,\n // Interval in milliseconds to calculate progress bitrate:\n bitrateInterval: 500,\n // By default, uploads are started automatically when adding files:\n autoUpload: true,\n\n // Error and info messages:\n messages: {\n uploadedBytes: 'Uploaded bytes exceed file size'\n },\n\n // Translation function, gets the message key to be translated\n // and an object with context specific data as arguments:\n i18n: function (message, context) {\n message = this.messages[message] || message.toString();\n if (context) {\n $.each(context, function (key, value) {\n message = message.replace('{' + key + '}', value);\n });\n }\n return message;\n },\n\n // Additional form data to be sent along with the file uploads can be set\n // using this option, which accepts an array of objects with name and\n // value properties, a function returning such an array, a FormData\n // object (for XHR file uploads), or a simple object.\n // The form of the first fileInput is given as parameter to the function:\n formData: function (form) {\n return form.serializeArray();\n },\n\n // The add callback is invoked as soon as files are added to the fileupload\n // widget (via file input selection, drag & drop, paste or add API call).\n // If the singleFileUploads option is enabled, this callback will be\n // called once for each file in the selection for XHR file uploads, else\n // once for each file selection.\n //\n // The upload starts when the submit method is invoked on the data parameter.\n // The data object contains a files property holding the added files\n // and allows you to override plugin options as well as define ajax settings.\n //\n // Listeners for this callback can also be bound the following way:\n // .bind('fileuploadadd', func);\n //\n // data.submit() returns a Promise object and allows to attach additional\n // handlers using jQuery's Deferred callbacks:\n // data.submit().done(func).fail(func).always(func);\n add: function (e, data) {\n if (e.isDefaultPrevented()) {\n return false;\n }\n if (data.autoUpload || (data.autoUpload !== false &&\n $(this).fileupload('option', 'autoUpload'))) {\n data.process().done(function () {\n data.submit();\n });\n }\n },\n\n // Other callbacks:\n\n // Callback for the submit event of each file upload:\n // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);\n\n // Callback for the start of each file upload request:\n // send: function (e, data) {}, // .bind('fileuploadsend', func);\n\n // Callback for successful uploads:\n // done: function (e, data) {}, // .bind('fileuploaddone', func);\n\n // Callback for failed (abort or error) uploads:\n // fail: function (e, data) {}, // .bind('fileuploadfail', func);\n\n // Callback for completed (success, abort or error) requests:\n // always: function (e, data) {}, // .bind('fileuploadalways', func);\n\n // Callback for upload progress events:\n // progress: function (e, data) {}, // .bind('fileuploadprogress', func);\n\n // Callback for global upload progress events:\n // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);\n\n // Callback for uploads start, equivalent to the global ajaxStart event:\n // start: function (e) {}, // .bind('fileuploadstart', func);\n\n // Callback for uploads stop, equivalent to the global ajaxStop event:\n // stop: function (e) {}, // .bind('fileuploadstop', func);\n\n // Callback for change events of the fileInput(s):\n // change: function (e, data) {}, // .bind('fileuploadchange', func);\n\n // Callback for paste events to the pasteZone(s):\n // paste: function (e, data) {}, // .bind('fileuploadpaste', func);\n\n // Callback for drop events of the dropZone(s):\n // drop: function (e, data) {}, // .bind('fileuploaddrop', func);\n\n // Callback for dragover events of the dropZone(s):\n // dragover: function (e) {}, // .bind('fileuploaddragover', func);\n\n // Callback before the start of each chunk upload request (before form data initialization):\n // chunkbeforesend: function (e, data) {}, // .bind('fileuploadchunkbeforesend', func);\n\n // Callback for the start of each chunk upload request:\n // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);\n\n // Callback for successful chunk uploads:\n // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);\n\n // Callback for failed (abort or error) chunk uploads:\n // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);\n\n // Callback for completed (success, abort or error) chunk upload requests:\n // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);\n\n // The plugin options are used as settings object for the ajax calls.\n // The following are jQuery ajax settings required for the file uploads:\n processData: false,\n contentType: false,\n cache: false,\n timeout: 0\n },\n\n // A list of options that require reinitializing event listeners and/or\n // special initialization code:\n _specialOptions: [\n 'fileInput',\n 'dropZone',\n 'pasteZone',\n 'multipart',\n 'forceIframeTransport'\n ],\n\n _blobSlice: $.support.blobSlice && function () {\n var slice = this.slice || this.webkitSlice || this.mozSlice;\n return slice.apply(this, arguments);\n },\n\n _BitrateTimer: function () {\n this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());\n this.loaded = 0;\n this.bitrate = 0;\n this.getBitrate = function (now, loaded, interval) {\n var timeDiff = now - this.timestamp;\n if (!this.bitrate || !interval || timeDiff > interval) {\n this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;\n this.loaded = loaded;\n this.timestamp = now;\n }\n return this.bitrate;\n };\n },\n\n _isXHRUpload: function (options) {\n return !options.forceIframeTransport &&\n ((!options.multipart && $.support.xhrFileUpload) ||\n $.support.xhrFormDataFileUpload);\n },\n\n _getFormData: function (options) {\n var formData;\n if ($.type(options.formData) === 'function') {\n return options.formData(options.form);\n }\n if ($.isArray(options.formData)) {\n return options.formData;\n }\n if ($.type(options.formData) === 'object') {\n formData = [];\n $.each(options.formData, function (name, value) {\n formData.push({name: name, value: value});\n });\n return formData;\n }\n return [];\n },\n\n _getTotal: function (files) {\n var total = 0;\n $.each(files, function (index, file) {\n total += file.size || 1;\n });\n return total;\n },\n\n _initProgressObject: function (obj) {\n var progress = {\n loaded: 0,\n total: 0,\n bitrate: 0\n };\n if (obj._progress) {\n $.extend(obj._progress, progress);\n } else {\n obj._progress = progress;\n }\n },\n\n _initResponseObject: function (obj) {\n var prop;\n if (obj._response) {\n for (prop in obj._response) {\n if (obj._response.hasOwnProperty(prop)) {\n delete obj._response[prop];\n }\n }\n } else {\n obj._response = {};\n }\n },\n\n _onProgress: function (e, data) {\n if (e.lengthComputable) {\n var now = ((Date.now) ? Date.now() : (new Date()).getTime()),\n loaded;\n if (data._time && data.progressInterval &&\n (now - data._time < data.progressInterval) &&\n e.loaded !== e.total) {\n return;\n }\n data._time = now;\n loaded = Math.floor(\n e.loaded / e.total * (data.chunkSize || data._progress.total)\n ) + (data.uploadedBytes || 0);\n // Add the difference from the previously loaded state\n // to the global loaded counter:\n this._progress.loaded += (loaded - data._progress.loaded);\n this._progress.bitrate = this._bitrateTimer.getBitrate(\n now,\n this._progress.loaded,\n data.bitrateInterval\n );\n data._progress.loaded = data.loaded = loaded;\n data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(\n now,\n loaded,\n data.bitrateInterval\n );\n // Trigger a custom progress event with a total data property set\n // to the file size(s) of the current upload and a loaded data\n // property calculated accordingly:\n this._trigger(\n 'progress',\n $.Event('progress', {delegatedEvent: e}),\n data\n );\n // Trigger a global progress event for all current file uploads,\n // including ajax calls queued for sequential file uploads:\n this._trigger(\n 'progressall',\n $.Event('progressall', {delegatedEvent: e}),\n this._progress\n );\n }\n },\n\n _initProgressListener: function (options) {\n var that = this,\n xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n // Accesss to the native XHR object is required to add event listeners\n // for the upload progress event:\n if (xhr.upload) {\n $(xhr.upload).bind('progress', function (e) {\n var oe = e.originalEvent;\n // Make sure the progress event properties get copied over:\n e.lengthComputable = oe.lengthComputable;\n e.loaded = oe.loaded;\n e.total = oe.total;\n that._onProgress(e, options);\n });\n options.xhr = function () {\n return xhr;\n };\n }\n },\n\n _deinitProgressListener: function (options) {\n var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n if (xhr.upload) {\n $(xhr.upload).unbind('progress');\n }\n },\n\n _isInstanceOf: function (type, obj) {\n // Cross-frame instanceof check\n return Object.prototype.toString.call(obj) === '[object ' + type + ']';\n },\n\n _initXHRData: function (options) {\n var that = this,\n formData,\n file = options.files[0],\n // Ignore non-multipart setting if not supported:\n multipart = options.multipart || !$.support.xhrFileUpload,\n paramName = $.type(options.paramName) === 'array' ?\n options.paramName[0] : options.paramName;\n options.headers = $.extend({}, options.headers);\n if (options.contentRange) {\n options.headers['Content-Range'] = options.contentRange;\n }\n if (!multipart || options.blob || !this._isInstanceOf('File', file)) {\n options.headers['Content-Disposition'] = 'attachment; filename=\"' +\n encodeURI(file.uploadName || file.name) + '\"';\n }\n if (!multipart) {\n options.contentType = file.type || 'application/octet-stream';\n options.data = options.blob || file;\n } else if ($.support.xhrFormDataFileUpload) {\n if (options.postMessage) {\n // window.postMessage does not allow sending FormData\n // objects, so we just add the File/Blob objects to\n // the formData array and let the postMessage window\n // create the FormData object out of this array:\n formData = this._getFormData(options);\n if (options.blob) {\n formData.push({\n name: paramName,\n value: options.blob\n });\n } else {\n $.each(options.files, function (index, file) {\n formData.push({\n name: ($.type(options.paramName) === 'array' &&\n options.paramName[index]) || paramName,\n value: file\n });\n });\n }\n } else {\n if (that._isInstanceOf('FormData', options.formData)) {\n formData = options.formData;\n } else {\n formData = new FormData();\n $.each(this._getFormData(options), function (index, field) {\n formData.append(field.name, field.value);\n });\n }\n if (options.blob) {\n formData.append(\n paramName,\n options.blob,\n file.uploadName || file.name\n );\n } else {\n $.each(options.files, function (index, file) {\n // This check allows the tests to run with\n // dummy objects:\n if (that._isInstanceOf('File', file) ||\n that._isInstanceOf('Blob', file)) {\n formData.append(\n ($.type(options.paramName) === 'array' &&\n options.paramName[index]) || paramName,\n file,\n file.uploadName || file.name\n );\n }\n });\n }\n }\n options.data = formData;\n }\n // Blob reference is not needed anymore, free memory:\n options.blob = null;\n },\n\n _initIframeSettings: function (options) {\n var targetHost = $('').prop('href', options.url).prop('host');\n // Setting the dataType to iframe enables the iframe transport:\n options.dataType = 'iframe ' + (options.dataType || '');\n // The iframe transport accepts a serialized array as form data:\n options.formData = this._getFormData(options);\n // Add redirect url to form data on cross-domain uploads:\n if (options.redirect && targetHost && targetHost !== location.host) {\n options.formData.push({\n name: options.redirectParamName || 'redirect',\n value: options.redirect\n });\n }\n },\n\n _initDataSettings: function (options) {\n if (this._isXHRUpload(options)) {\n if (!this._chunkedUpload(options, true)) {\n if (!options.data) {\n this._initXHRData(options);\n }\n this._initProgressListener(options);\n }\n if (options.postMessage) {\n // Setting the dataType to postmessage enables the\n // postMessage transport:\n options.dataType = 'postmessage ' + (options.dataType || '');\n }\n } else {\n this._initIframeSettings(options);\n }\n },\n\n _getParamName: function (options) {\n var fileInput = $(options.fileInput),\n paramName = options.paramName;\n if (!paramName) {\n paramName = [];\n fileInput.each(function () {\n var input = $(this),\n name = input.prop('name') || 'files[]',\n i = (input.prop('files') || [1]).length;\n while (i) {\n paramName.push(name);\n i -= 1;\n }\n });\n if (!paramName.length) {\n paramName = [fileInput.prop('name') || 'files[]'];\n }\n } else if (!$.isArray(paramName)) {\n paramName = [paramName];\n }\n return paramName;\n },\n\n _initFormSettings: function (options) {\n // Retrieve missing options from the input field and the\n // associated form, if available:\n if (!options.form || !options.form.length) {\n options.form = $(options.fileInput.prop('form'));\n // If the given file input doesn't have an associated form,\n // use the default widget file input's form:\n if (!options.form.length) {\n options.form = $(this.options.fileInput.prop('form'));\n }\n }\n options.paramName = this._getParamName(options);\n if (!options.url) {\n options.url = options.form.prop('action') || location.href;\n }\n // The HTTP request method must be \"POST\" or \"PUT\":\n options.type = (options.type ||\n ($.type(options.form.prop('method')) === 'string' &&\n options.form.prop('method')) || ''\n ).toUpperCase();\n if (options.type !== 'POST' && options.type !== 'PUT' &&\n options.type !== 'PATCH') {\n options.type = 'POST';\n }\n if (!options.formAcceptCharset) {\n options.formAcceptCharset = options.form.attr('accept-charset');\n }\n },\n\n _getAJAXSettings: function (data) {\n var options = $.extend({}, this.options, data);\n this._initFormSettings(options);\n this._initDataSettings(options);\n return options;\n },\n\n // jQuery 1.6 doesn't provide .state(),\n // while jQuery 1.8+ removed .isRejected() and .isResolved():\n _getDeferredState: function (deferred) {\n if (deferred.state) {\n return deferred.state();\n }\n if (deferred.isResolved()) {\n return 'resolved';\n }\n if (deferred.isRejected()) {\n return 'rejected';\n }\n return 'pending';\n },\n\n // Maps jqXHR callbacks to the equivalent\n // methods of the given Promise object:\n _enhancePromise: function (promise) {\n promise.success = promise.done;\n promise.error = promise.fail;\n promise.complete = promise.always;\n return promise;\n },\n\n // Creates and returns a Promise object enhanced with\n // the jqXHR methods abort, success, error and complete:\n _getXHRPromise: function (resolveOrReject, context, args) {\n var dfd = $.Deferred(),\n promise = dfd.promise();\n context = context || this.options.context || promise;\n if (resolveOrReject === true) {\n dfd.resolveWith(context, args);\n } else if (resolveOrReject === false) {\n dfd.rejectWith(context, args);\n }\n promise.abort = dfd.promise;\n return this._enhancePromise(promise);\n },\n\n // Adds convenience methods to the data callback argument:\n _addConvenienceMethods: function (e, data) {\n var that = this,\n getPromise = function (args) {\n return $.Deferred().resolveWith(that, args).promise();\n };\n data.process = function (resolveFunc, rejectFunc) {\n if (resolveFunc || rejectFunc) {\n data._processQueue = this._processQueue =\n (this._processQueue || getPromise([this])).then(\n function () {\n if (data.errorThrown) {\n return $.Deferred()\n .rejectWith(that, [data]).promise();\n }\n return getPromise(arguments);\n }\n ).then(resolveFunc, rejectFunc);\n }\n return this._processQueue || getPromise([this]);\n };\n data.submit = function () {\n if (this.state() !== 'pending') {\n data.jqXHR = this.jqXHR =\n (that._trigger(\n 'submit',\n $.Event('submit', {delegatedEvent: e}),\n this\n ) !== false) && that._onSend(e, this);\n }\n return this.jqXHR || that._getXHRPromise();\n };\n data.abort = function () {\n if (this.jqXHR) {\n return this.jqXHR.abort();\n }\n this.errorThrown = 'abort';\n that._trigger('fail', null, this);\n return that._getXHRPromise(false);\n };\n data.state = function () {\n if (this.jqXHR) {\n return that._getDeferredState(this.jqXHR);\n }\n if (this._processQueue) {\n return that._getDeferredState(this._processQueue);\n }\n };\n data.processing = function () {\n return !this.jqXHR && this._processQueue && that\n ._getDeferredState(this._processQueue) === 'pending';\n };\n data.progress = function () {\n return this._progress;\n };\n data.response = function () {\n return this._response;\n };\n },\n\n // Parses the Range header from the server response\n // and returns the uploaded bytes:\n _getUploadedBytes: function (jqXHR) {\n var range = jqXHR.getResponseHeader('Range'),\n parts = range && range.split('-'),\n upperBytesPos = parts && parts.length > 1 &&\n parseInt(parts[1], 10);\n return upperBytesPos && upperBytesPos + 1;\n },\n\n // Uploads a file in multiple, sequential requests\n // by splitting the file up in multiple blob chunks.\n // If the second parameter is true, only tests if the file\n // should be uploaded in chunks, but does not invoke any\n // upload requests:\n _chunkedUpload: function (options, testOnly) {\n options.uploadedBytes = options.uploadedBytes || 0;\n var that = this,\n file = options.files[0],\n fs = file.size,\n ub = options.uploadedBytes,\n mcs = options.maxChunkSize || fs,\n slice = this._blobSlice,\n dfd = $.Deferred(),\n promise = dfd.promise(),\n jqXHR,\n upload;\n if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) ||\n options.data) {\n return false;\n }\n if (testOnly) {\n return true;\n }\n if (ub >= fs) {\n file.error = options.i18n('uploadedBytes');\n return this._getXHRPromise(\n false,\n options.context,\n [null, 'error', file.error]\n );\n }\n // The chunk upload method:\n upload = function () {\n // Clone the options object for each chunk upload:\n var o = $.extend({}, options),\n currentLoaded = o._progress.loaded;\n o.blob = slice.call(\n file,\n ub,\n ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),\n file.type\n );\n // Store the current chunk size, as the blob itself\n // will be dereferenced after data processing:\n o.chunkSize = o.blob.size;\n // Expose the chunk bytes position range:\n o.contentRange = 'bytes ' + ub + '-' +\n (ub + o.chunkSize - 1) + '/' + fs;\n // Trigger chunkbeforesend to allow form data to be updated for this chunk\n that._trigger('chunkbeforesend', null, o);\n // Process the upload data (the blob and potential form data):\n that._initXHRData(o);\n // Add progress listeners for this chunk upload:\n that._initProgressListener(o);\n jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||\n that._getXHRPromise(false, o.context))\n .done(function (result, textStatus, jqXHR) {\n ub = that._getUploadedBytes(jqXHR) ||\n (ub + o.chunkSize);\n // Create a progress event if no final progress event\n // with loaded equaling total has been triggered\n // for this chunk:\n if (currentLoaded + o.chunkSize - o._progress.loaded) {\n that._onProgress($.Event('progress', {\n lengthComputable: true,\n loaded: ub - o.uploadedBytes,\n total: ub - o.uploadedBytes\n }), o);\n }\n options.uploadedBytes = o.uploadedBytes = ub;\n o.result = result;\n o.textStatus = textStatus;\n o.jqXHR = jqXHR;\n that._trigger('chunkdone', null, o);\n that._trigger('chunkalways', null, o);\n if (ub < fs) {\n // File upload not yet complete,\n // continue with the next chunk:\n upload();\n } else {\n dfd.resolveWith(\n o.context,\n [result, textStatus, jqXHR]\n );\n }\n })\n .fail(function (jqXHR, textStatus, errorThrown) {\n o.jqXHR = jqXHR;\n o.textStatus = textStatus;\n o.errorThrown = errorThrown;\n that._trigger('chunkfail', null, o);\n that._trigger('chunkalways', null, o);\n dfd.rejectWith(\n o.context,\n [jqXHR, textStatus, errorThrown]\n );\n })\n .always(function () {\n that._deinitProgressListener(o);\n });\n };\n this._enhancePromise(promise);\n promise.abort = function () {\n return jqXHR.abort();\n };\n upload();\n return promise;\n },\n\n _beforeSend: function (e, data) {\n if (this._active === 0) {\n // the start callback is triggered when an upload starts\n // and no other uploads are currently running,\n // equivalent to the global ajaxStart event:\n this._trigger('start');\n // Set timer for global bitrate progress calculation:\n this._bitrateTimer = new this._BitrateTimer();\n // Reset the global progress values:\n this._progress.loaded = this._progress.total = 0;\n this._progress.bitrate = 0;\n }\n // Make sure the container objects for the .response() and\n // .progress() methods on the data object are available\n // and reset to their initial state:\n this._initResponseObject(data);\n this._initProgressObject(data);\n data._progress.loaded = data.loaded = data.uploadedBytes || 0;\n data._progress.total = data.total = this._getTotal(data.files) || 1;\n data._progress.bitrate = data.bitrate = 0;\n this._active += 1;\n // Initialize the global progress values:\n this._progress.loaded += data.loaded;\n this._progress.total += data.total;\n },\n\n _onDone: function (result, textStatus, jqXHR, options) {\n var total = options._progress.total,\n response = options._response;\n if (options._progress.loaded < total) {\n // Create a progress event if no final progress event\n // with loaded equaling total has been triggered:\n this._onProgress($.Event('progress', {\n lengthComputable: true,\n loaded: total,\n total: total\n }), options);\n }\n response.result = options.result = result;\n response.textStatus = options.textStatus = textStatus;\n response.jqXHR = options.jqXHR = jqXHR;\n this._trigger('done', null, options);\n },\n\n _onFail: function (jqXHR, textStatus, errorThrown, options) {\n var response = options._response;\n if (options.recalculateProgress) {\n // Remove the failed (error or abort) file upload from\n // the global progress calculation:\n this._progress.loaded -= options._progress.loaded;\n this._progress.total -= options._progress.total;\n }\n response.jqXHR = options.jqXHR = jqXHR;\n response.textStatus = options.textStatus = textStatus;\n response.errorThrown = options.errorThrown = errorThrown;\n this._trigger('fail', null, options);\n },\n\n _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {\n // jqXHRorResult, textStatus and jqXHRorError are added to the\n // options object via done and fail callbacks\n this._trigger('always', null, options);\n },\n\n _onSend: function (e, data) {\n if (!data.submit) {\n this._addConvenienceMethods(e, data);\n }\n var that = this,\n jqXHR,\n aborted,\n slot,\n pipe,\n options = that._getAJAXSettings(data),\n send = function () {\n that._sending += 1;\n // Set timer for bitrate progress calculation:\n options._bitrateTimer = new that._BitrateTimer();\n jqXHR = jqXHR || (\n ((aborted || that._trigger(\n 'send',\n $.Event('send', {delegatedEvent: e}),\n options\n ) === false) &&\n that._getXHRPromise(false, options.context, aborted)) ||\n that._chunkedUpload(options) || $.ajax(options)\n ).done(function (result, textStatus, jqXHR) {\n that._onDone(result, textStatus, jqXHR, options);\n }).fail(function (jqXHR, textStatus, errorThrown) {\n that._onFail(jqXHR, textStatus, errorThrown, options);\n }).always(function (jqXHRorResult, textStatus, jqXHRorError) {\n that._deinitProgressListener(options);\n that._onAlways(\n jqXHRorResult,\n textStatus,\n jqXHRorError,\n options\n );\n that._sending -= 1;\n that._active -= 1;\n if (options.limitConcurrentUploads &&\n options.limitConcurrentUploads > that._sending) {\n // Start the next queued upload,\n // that has not been aborted:\n var nextSlot = that._slots.shift();\n while (nextSlot) {\n if (that._getDeferredState(nextSlot) === 'pending') {\n nextSlot.resolve();\n break;\n }\n nextSlot = that._slots.shift();\n }\n }\n if (that._active === 0) {\n // The stop callback is triggered when all uploads have\n // been completed, equivalent to the global ajaxStop event:\n that._trigger('stop');\n }\n });\n return jqXHR;\n };\n this._beforeSend(e, options);\n if (this.options.sequentialUploads ||\n (this.options.limitConcurrentUploads &&\n this.options.limitConcurrentUploads <= this._sending)) {\n if (this.options.limitConcurrentUploads > 1) {\n slot = $.Deferred();\n this._slots.push(slot);\n pipe = slot.then(send);\n } else {\n this._sequence = this._sequence.then(send, send);\n pipe = this._sequence;\n }\n // Return the piped Promise object, enhanced with an abort method,\n // which is delegated to the jqXHR object of the current upload,\n // and jqXHR callbacks mapped to the equivalent Promise methods:\n pipe.abort = function () {\n aborted = [undefined, 'abort', 'abort'];\n if (!jqXHR) {\n if (slot) {\n slot.rejectWith(options.context, aborted);\n }\n return send();\n }\n return jqXHR.abort();\n };\n return this._enhancePromise(pipe);\n }\n return send();\n },\n\n _onAdd: function (e, data) {\n var that = this,\n result = true,\n options = $.extend({}, this.options, data),\n files = data.files,\n filesLength = files.length,\n limit = options.limitMultiFileUploads,\n limitSize = options.limitMultiFileUploadSize,\n overhead = options.limitMultiFileUploadSizeOverhead,\n batchSize = 0,\n paramName = this._getParamName(options),\n paramNameSet,\n paramNameSlice,\n fileSet,\n i,\n j = 0;\n if (!filesLength) {\n return false;\n }\n if (limitSize && files[0].size === undefined) {\n limitSize = undefined;\n }\n if (!(options.singleFileUploads || limit || limitSize) ||\n !this._isXHRUpload(options)) {\n fileSet = [files];\n paramNameSet = [paramName];\n } else if (!(options.singleFileUploads || limitSize) && limit) {\n fileSet = [];\n paramNameSet = [];\n for (i = 0; i < filesLength; i += limit) {\n fileSet.push(files.slice(i, i + limit));\n paramNameSlice = paramName.slice(i, i + limit);\n if (!paramNameSlice.length) {\n paramNameSlice = paramName;\n }\n paramNameSet.push(paramNameSlice);\n }\n } else if (!options.singleFileUploads && limitSize) {\n fileSet = [];\n paramNameSet = [];\n for (i = 0; i < filesLength; i = i + 1) {\n batchSize += files[i].size + overhead;\n if (i + 1 === filesLength ||\n ((batchSize + files[i + 1].size + overhead) > limitSize) ||\n (limit && i + 1 - j >= limit)) {\n fileSet.push(files.slice(j, i + 1));\n paramNameSlice = paramName.slice(j, i + 1);\n if (!paramNameSlice.length) {\n paramNameSlice = paramName;\n }\n paramNameSet.push(paramNameSlice);\n j = i + 1;\n batchSize = 0;\n }\n }\n } else {\n paramNameSet = paramName;\n }\n data.originalFiles = files;\n $.each(fileSet || files, function (index, element) {\n var newData = $.extend({}, data);\n newData.files = fileSet ? element : [element];\n newData.paramName = paramNameSet[index];\n that._initResponseObject(newData);\n that._initProgressObject(newData);\n that._addConvenienceMethods(e, newData);\n result = that._trigger(\n 'add',\n $.Event('add', {delegatedEvent: e}),\n newData\n );\n return result;\n });\n return result;\n },\n\n _replaceFileInput: function (data) {\n var input = data.fileInput,\n inputClone = input.clone(true),\n restoreFocus = input.is(document.activeElement);\n // Add a reference for the new cloned file input to the data argument:\n data.fileInputClone = inputClone;\n $('
').append(inputClone)[0].reset();\n // Detaching allows to insert the fileInput on another form\n // without loosing the file input value:\n input.after(inputClone).detach();\n // If the fileInput had focus before it was detached,\n // restore focus to the inputClone.\n if (restoreFocus) {\n inputClone.focus();\n }\n // Avoid memory leaks with the detached file input:\n $.cleanData(input.unbind('remove'));\n // Replace the original file input element in the fileInput\n // elements set with the clone, which has been copied including\n // event handlers:\n this.options.fileInput = this.options.fileInput.map(function (i, el) {\n if (el === input[0]) {\n return inputClone[0];\n }\n return el;\n });\n // If the widget has been initialized on the file input itself,\n // override this.element with the file input clone:\n if (input[0] === this.element[0]) {\n this.element = inputClone;\n }\n },\n\n _handleFileTreeEntry: function (entry, path) {\n var that = this,\n dfd = $.Deferred(),\n entries = [],\n dirReader,\n errorHandler = function (e) {\n if (e && !e.entry) {\n e.entry = entry;\n }\n // Since $.when returns immediately if one\n // Deferred is rejected, we use resolve instead.\n // This allows valid files and invalid items\n // to be returned together in one set:\n dfd.resolve([e]);\n },\n successHandler = function (entries) {\n that._handleFileTreeEntries(\n entries,\n path + entry.name + '/'\n ).done(function (files) {\n dfd.resolve(files);\n }).fail(errorHandler);\n },\n readEntries = function () {\n dirReader.readEntries(function (results) {\n if (!results.length) {\n successHandler(entries);\n } else {\n entries = entries.concat(results);\n readEntries();\n }\n }, errorHandler);\n };\n path = path || '';\n if (entry.isFile) {\n if (entry._file) {\n // Workaround for Chrome bug #149735\n entry._file.relativePath = path;\n dfd.resolve(entry._file);\n } else {\n entry.file(function (file) {\n file.relativePath = path;\n dfd.resolve(file);\n }, errorHandler);\n }\n } else if (entry.isDirectory) {\n dirReader = entry.createReader();\n readEntries();\n } else {\n // Return an empty list for file system items\n // other than files or directories:\n dfd.resolve([]);\n }\n return dfd.promise();\n },\n\n _handleFileTreeEntries: function (entries, path) {\n var that = this;\n return $.when.apply(\n $,\n $.map(entries, function (entry) {\n return that._handleFileTreeEntry(entry, path);\n })\n ).then(function () {\n return Array.prototype.concat.apply(\n [],\n arguments\n );\n });\n },\n\n _getDroppedFiles: function (dataTransfer) {\n dataTransfer = dataTransfer || {};\n var items = dataTransfer.items;\n if (items && items.length && (items[0].webkitGetAsEntry ||\n items[0].getAsEntry)) {\n return this._handleFileTreeEntries(\n $.map(items, function (item) {\n var entry;\n if (item.webkitGetAsEntry) {\n entry = item.webkitGetAsEntry();\n if (entry) {\n // Workaround for Chrome bug #149735:\n entry._file = item.getAsFile();\n }\n return entry;\n }\n return item.getAsEntry();\n })\n );\n }\n return $.Deferred().resolve(\n $.makeArray(dataTransfer.files)\n ).promise();\n },\n\n _getSingleFileInputFiles: function (fileInput) {\n fileInput = $(fileInput);\n var entries = fileInput.prop('webkitEntries') ||\n fileInput.prop('entries'),\n files,\n value;\n if (entries && entries.length) {\n return this._handleFileTreeEntries(entries);\n }\n files = $.makeArray(fileInput.prop('files'));\n if (!files.length) {\n value = fileInput.prop('value');\n if (!value) {\n return $.Deferred().resolve([]).promise();\n }\n // If the files property is not available, the browser does not\n // support the File API and we add a pseudo File object with\n // the input value as name with path information removed:\n files = [{name: value.replace(/^.*\\\\/, '')}];\n } else if (files[0].name === undefined && files[0].fileName) {\n // File normalization for Safari 4 and Firefox 3:\n $.each(files, function (index, file) {\n file.name = file.fileName;\n file.size = file.fileSize;\n });\n }\n return $.Deferred().resolve(files).promise();\n },\n\n _getFileInputFiles: function (fileInput) {\n if (!(fileInput instanceof $) || fileInput.length === 1) {\n return this._getSingleFileInputFiles(fileInput);\n }\n return $.when.apply(\n $,\n $.map(fileInput, this._getSingleFileInputFiles)\n ).then(function () {\n return Array.prototype.concat.apply(\n [],\n arguments\n );\n });\n },\n\n _onChange: function (e) {\n var that = this,\n data = {\n fileInput: $(e.target),\n form: $(e.target.form)\n };\n this._getFileInputFiles(data.fileInput).always(function (files) {\n data.files = files;\n if (that.options.replaceFileInput) {\n that._replaceFileInput(data);\n }\n if (that._trigger(\n 'change',\n $.Event('change', {delegatedEvent: e}),\n data\n ) !== false) {\n that._onAdd(e, data);\n }\n });\n },\n\n _onPaste: function (e) {\n var items = e.originalEvent && e.originalEvent.clipboardData &&\n e.originalEvent.clipboardData.items,\n data = {files: []};\n if (items && items.length) {\n $.each(items, function (index, item) {\n var file = item.getAsFile && item.getAsFile();\n if (file) {\n data.files.push(file);\n }\n });\n if (this._trigger(\n 'paste',\n $.Event('paste', {delegatedEvent: e}),\n data\n ) !== false) {\n this._onAdd(e, data);\n }\n }\n },\n\n _onDrop: function (e) {\n e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n var that = this,\n dataTransfer = e.dataTransfer,\n data = {};\n if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {\n e.preventDefault();\n this._getDroppedFiles(dataTransfer).always(function (files) {\n data.files = files;\n if (that._trigger(\n 'drop',\n $.Event('drop', {delegatedEvent: e}),\n data\n ) !== false) {\n that._onAdd(e, data);\n }\n });\n }\n },\n\n _onDragOver: getDragHandler('dragover'),\n\n _onDragEnter: getDragHandler('dragenter'),\n\n _onDragLeave: getDragHandler('dragleave'),\n\n _initEventHandlers: function () {\n if (this._isXHRUpload(this.options)) {\n this._on(this.options.dropZone, {\n dragover: this._onDragOver,\n drop: this._onDrop,\n // event.preventDefault() on dragenter is required for IE10+:\n dragenter: this._onDragEnter,\n // dragleave is not required, but added for completeness:\n dragleave: this._onDragLeave\n });\n this._on(this.options.pasteZone, {\n paste: this._onPaste\n });\n }\n if ($.support.fileInput) {\n this._on(this.options.fileInput, {\n change: this._onChange\n });\n }\n },\n\n _destroyEventHandlers: function () {\n this._off(this.options.dropZone, 'dragenter dragleave dragover drop');\n this._off(this.options.pasteZone, 'paste');\n this._off(this.options.fileInput, 'change');\n },\n\n _destroy: function () {\n this._destroyEventHandlers();\n },\n\n _setOption: function (key, value) {\n var reinit = $.inArray(key, this._specialOptions) !== -1;\n if (reinit) {\n this._destroyEventHandlers();\n }\n this._super(key, value);\n if (reinit) {\n this._initSpecialOptions();\n this._initEventHandlers();\n }\n },\n\n _initSpecialOptions: function () {\n var options = this.options;\n if (options.fileInput === undefined) {\n options.fileInput = this.element.is('input[type=\"file\"]') ?\n this.element : this.element.find('input[type=\"file\"]');\n } else if (!(options.fileInput instanceof $)) {\n options.fileInput = $(options.fileInput);\n }\n if (!(options.dropZone instanceof $)) {\n options.dropZone = $(options.dropZone);\n }\n if (!(options.pasteZone instanceof $)) {\n options.pasteZone = $(options.pasteZone);\n }\n },\n\n _getRegExp: function (str) {\n var parts = str.split('/'),\n modifiers = parts.pop();\n parts.shift();\n return new RegExp(parts.join('/'), modifiers);\n },\n\n _isRegExpOption: function (key, value) {\n return key !== 'url' && $.type(value) === 'string' &&\n /^\\/.*\\/[igm]{0,3}$/.test(value);\n },\n\n _initDataAttributes: function () {\n var that = this,\n options = this.options,\n data = this.element.data();\n // Initialize options set via HTML5 data-attributes:\n $.each(\n this.element[0].attributes,\n function (index, attr) {\n var key = attr.name.toLowerCase(),\n value;\n if (/^data-/.test(key)) {\n // Convert hyphen-ated key to camelCase:\n key = key.slice(5).replace(/-[a-z]/g, function (str) {\n return str.charAt(1).toUpperCase();\n });\n value = data[key];\n if (that._isRegExpOption(key, value)) {\n value = that._getRegExp(value);\n }\n options[key] = value;\n }\n }\n );\n },\n\n _create: function () {\n this._initDataAttributes();\n this._initSpecialOptions();\n this._slots = [];\n this._sequence = this._getXHRPromise(true);\n this._sending = this._active = 0;\n this._initProgressObject(this);\n this._initEventHandlers();\n },\n\n // This method is exposed to the widget API and allows to query\n // the number of active uploads:\n active: function () {\n return this._active;\n },\n\n // This method is exposed to the widget API and allows to query\n // the widget upload progress.\n // It returns an object with loaded, total and bitrate properties\n // for the running uploads:\n progress: function () {\n return this._progress;\n },\n\n // This method is exposed to the widget API and allows adding files\n // using the fileupload API. The data parameter accepts an object which\n // must have a files property and can contain additional options:\n // .fileupload('add', {files: filesList});\n add: function (data) {\n var that = this;\n if (!data || this.options.disabled) {\n return;\n }\n if (data.fileInput && !data.files) {\n this._getFileInputFiles(data.fileInput).always(function (files) {\n data.files = files;\n that._onAdd(null, data);\n });\n } else {\n data.files = $.makeArray(data.files);\n this._onAdd(null, data);\n }\n },\n\n // This method is exposed to the widget API and allows sending files\n // using the fileupload API. The data parameter accepts an object which\n // must have a files or fileInput property and can contain additional options:\n // .fileupload('send', {files: filesList});\n // The method returns a Promise object for the file upload call.\n send: function (data) {\n if (data && !this.options.disabled) {\n if (data.fileInput && !data.files) {\n var that = this,\n dfd = $.Deferred(),\n promise = dfd.promise(),\n jqXHR,\n aborted;\n promise.abort = function () {\n aborted = true;\n if (jqXHR) {\n return jqXHR.abort();\n }\n dfd.reject(null, 'abort', 'abort');\n return promise;\n };\n this._getFileInputFiles(data.fileInput).always(\n function (files) {\n if (aborted) {\n return;\n }\n if (!files.length) {\n dfd.reject();\n return;\n }\n data.files = files;\n jqXHR = that._onSend(null, data);\n jqXHR.then(\n function (result, textStatus, jqXHR) {\n dfd.resolve(result, textStatus, jqXHR);\n },\n function (jqXHR, textStatus, errorThrown) {\n dfd.reject(jqXHR, textStatus, errorThrown);\n }\n );\n }\n );\n return this._enhancePromise(promise);\n }\n data.files = $.makeArray(data.files);\n if (data.files.length) {\n return this._onSend(null, data);\n }\n }\n return this._getXHRPromise(false, data && data.context);\n }\n\n });\n\n}));\n"]} \ No newline at end of file +{"version":3,"sources":["jquery.fileupload.js"],"names":["factory","define","amd","exports","require","window","jQuery","$","getDragHandler","type","isDragOver","e","dataTransfer","originalEvent","inArray","types","this","_trigger","Event","delegatedEvent","preventDefault","dropEffect","support","fileInput","RegExp","test","navigator","userAgent","prop","xhrFileUpload","ProgressEvent","FileReader","xhrFormDataFileUpload","FormData","blobSlice","Blob","prototype","slice","webkitSlice","mozSlice","widget","options","dropZone","document","pasteZone","undefined","replaceFileInput","paramName","singleFileUploads","limitMultiFileUploads","limitMultiFileUploadSize","limitMultiFileUploadSizeOverhead","sequentialUploads","limitConcurrentUploads","forceIframeTransport","redirect","redirectParamName","postMessage","multipart","maxChunkSize","uploadedBytes","recalculateProgress","progressInterval","bitrateInterval","autoUpload","messages","i18n","message","context","toString","each","key","value","replace","formData","form","serializeArray","add","data","isDefaultPrevented","fileupload","process","done","submit","processData","contentType","cache","timeout","_specialOptions","_blobSlice","apply","arguments","_BitrateTimer","timestamp","Date","now","getTime","loaded","bitrate","getBitrate","interval","timeDiff","_isXHRUpload","_getFormData","isArray","name","push","_getTotal","files","total","index","file","size","_initProgressObject","obj","progress","_progress","extend","_initResponseObject","_response","hasOwnProperty","_onProgress","lengthComputable","_time","Math","floor","chunkSize","_bitrateTimer","_initProgressListener","that","xhr","ajaxSettings","upload","bind","oe","_deinitProgressListener","unbind","_isInstanceOf","Object","call","_initXHRData","headers","contentRange","blob","encodeURI","uploadName","field","append","_initIframeSettings","targetHost","url","dataType","location","host","_initDataSettings","_chunkedUpload","_getParamName","input","i","length","_initFormSettings","href","toUpperCase","formAcceptCharset","attr","_getAJAXSettings","_getDeferredState","deferred","state","isResolved","isRejected","_enhancePromise","promise","success","error","fail","complete","always","_getXHRPromise","resolveOrReject","args","dfd","Deferred","resolveWith","rejectWith","abort","_addConvenienceMethods","getPromise","resolveFunc","rejectFunc","_processQueue","then","errorThrown","jqXHR","_onSend","processing","response","_getUploadedBytes","range","getResponseHeader","parts","split","upperBytesPos","parseInt","testOnly","fs","ub","mcs","o","currentLoaded","ajax","result","textStatus","_beforeSend","_active","_onDone","_onFail","_onAlways","jqXHRorResult","jqXHRorError","send","_sending","aborted","nextSlot","_slots","shift","resolve","slot","pipe","_sequence","_onAdd","paramNameSet","paramNameSlice","fileSet","filesLength","limit","limitSize","overhead","batchSize","j","originalFiles","element","newData","_replaceFileInput","inputClone","clone","restoreFocus","is","activeElement","fileInputClone","reset","after","detach","focus","cleanData","map","el","_handleFileTreeEntry","entry","path","errorHandler","dirReader","entries","readEntries","results","concat","_handleFileTreeEntries","successHandler","isFile","_file","relativePath","isDirectory","createReader","when","Array","_getDroppedFiles","items","webkitGetAsEntry","getAsEntry","item","getAsFile","makeArray","_getSingleFileInputFiles","fileName","fileSize","_getFileInputFiles","_onChange","target","_onPaste","clipboardData","_onDrop","_onDragOver","_onDragEnter","_onDragLeave","_initEventHandlers","_on","dragover","drop","dragenter","dragleave","paste","change","_destroyEventHandlers","_off","_destroy","_setOption","reinit","_super","_initSpecialOptions","find","_getRegExp","str","modifiers","pop","join","_isRegExpOption","_initDataAttributes","attributes","toLowerCase","charAt","_create","active","disabled","reject"],"mappings":"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","file":"jquery.fileupload.js","sourcesContent":["/*\n * jQuery File Upload Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, document, location, Blob, FormData */\n\n;(function (factory) {\n 'use strict';\n if (typeof define === 'function' && define.amd) {\n // Register as an anonymous AMD module:\n define([\n 'jquery',\n 'jquery-ui/ui/widget'\n ], factory);\n } else if (typeof exports === 'object') {\n // Node/CommonJS:\n factory(\n require('jquery'),\n require('./vendor/jquery.ui.widget')\n );\n } else {\n // Browser globals:\n factory(window.jQuery);\n }\n}(function ($) {\n 'use strict';\n\n // Detect file input support, based on\n // http://viljamis.com/blog/2012/file-upload-support-on-mobile/\n $.support.fileInput = !(new RegExp(\n // Handle devices which give false positives for the feature detection:\n '(Android (1\\\\.[0156]|2\\\\.[01]))' +\n '|(Windows Phone (OS 7|8\\\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +\n '|(w(eb)?OSBrowser)|(webOS)' +\n '|(Kindle/(1\\\\.0|2\\\\.[05]|3\\\\.0))'\n ).test(window.navigator.userAgent) ||\n // Feature detection for all other devices:\n $('').prop('disabled'));\n\n // The FileReader API is not actually used, but works as feature detection,\n // as some Safari versions (5?) support XHR file uploads via the FormData API,\n // but not non-multipart XHR file uploads.\n // window.XMLHttpRequestUpload is not available on IE10, so we check for\n // window.ProgressEvent instead to detect XHR2 file upload capability:\n $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);\n $.support.xhrFormDataFileUpload = !!window.FormData;\n\n // Detect support for Blob slicing (required for chunked uploads):\n $.support.blobSlice = window.Blob && (Blob.prototype.slice ||\n Blob.prototype.webkitSlice || Blob.prototype.mozSlice);\n\n // Helper function to create drag handlers for dragover/dragenter/dragleave:\n function getDragHandler(type) {\n var isDragOver = type === 'dragover';\n return function (e) {\n e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n var dataTransfer = e.dataTransfer;\n if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&\n this._trigger(\n type,\n $.Event(type, {delegatedEvent: e})\n ) !== false) {\n e.preventDefault();\n if (isDragOver) {\n dataTransfer.dropEffect = 'copy';\n }\n }\n };\n }\n\n // The fileupload widget listens for change events on file input fields defined\n // via fileInput setting and paste or drop events of the given dropZone.\n // In addition to the default jQuery Widget methods, the fileupload widget\n // exposes the \"add\" and \"send\" methods, to add or directly send files using\n // the fileupload API.\n // By default, files added via file input selection, paste, drag & drop or\n // \"add\" method are uploaded immediately, but it is possible to override\n // the \"add\" callback option to queue file uploads.\n $.widget('blueimp.fileupload', {\n\n options: {\n // The drop target element(s), by the default the complete document.\n // Set to null to disable drag & drop support:\n dropZone: $(document),\n // The paste target element(s), by the default undefined.\n // Set to a DOM node or jQuery object to enable file pasting:\n pasteZone: undefined,\n // The file input field(s), that are listened to for change events.\n // If undefined, it is set to the file input fields inside\n // of the widget element on plugin initialization.\n // Set to null to disable the change listener.\n fileInput: undefined,\n // By default, the file input field is replaced with a clone after\n // each input field change event. This is required for iframe transport\n // queues and allows change events to be fired for the same file\n // selection, but can be disabled by setting the following option to false:\n replaceFileInput: true,\n // The parameter name for the file form data (the request argument name).\n // If undefined or empty, the name property of the file input field is\n // used, or \"files[]\" if the file input name property is also empty,\n // can be a string or an array of strings:\n paramName: undefined,\n // By default, each file of a selection is uploaded using an individual\n // request for XHR type uploads. Set to false to upload file\n // selections in one request each:\n singleFileUploads: true,\n // To limit the number of files uploaded with one XHR request,\n // set the following option to an integer greater than 0:\n limitMultiFileUploads: undefined,\n // The following option limits the number of files uploaded with one\n // XHR request to keep the request size under or equal to the defined\n // limit in bytes:\n limitMultiFileUploadSize: undefined,\n // Multipart file uploads add a number of bytes to each uploaded file,\n // therefore the following option adds an overhead for each file used\n // in the limitMultiFileUploadSize configuration:\n limitMultiFileUploadSizeOverhead: 512,\n // Set the following option to true to issue all file upload requests\n // in a sequential order:\n sequentialUploads: false,\n // To limit the number of concurrent uploads,\n // set the following option to an integer greater than 0:\n limitConcurrentUploads: undefined,\n // Set the following option to true to force iframe transport uploads:\n forceIframeTransport: false,\n // Set the following option to the location of a redirect url on the\n // origin server, for cross-domain iframe transport uploads:\n redirect: undefined,\n // The parameter name for the redirect url, sent as part of the form\n // data and set to 'redirect' if this option is empty:\n redirectParamName: undefined,\n // Set the following option to the location of a postMessage window,\n // to enable postMessage transport uploads:\n postMessage: undefined,\n // By default, XHR file uploads are sent as multipart/form-data.\n // The iframe transport is always using multipart/form-data.\n // Set to false to enable non-multipart XHR uploads:\n multipart: true,\n // To upload large files in smaller chunks, set the following option\n // to a preferred maximum chunk size. If set to 0, null or undefined,\n // or the browser does not support the required Blob API, files will\n // be uploaded as a whole.\n maxChunkSize: undefined,\n // When a non-multipart upload or a chunked multipart upload has been\n // aborted, this option can be used to resume the upload by setting\n // it to the size of the already uploaded bytes. This option is most\n // useful when modifying the options object inside of the \"add\" or\n // \"send\" callbacks, as the options are cloned for each file upload.\n uploadedBytes: undefined,\n // By default, failed (abort or error) file uploads are removed from the\n // global progress calculation. Set the following option to false to\n // prevent recalculating the global progress data:\n recalculateProgress: true,\n // Interval in milliseconds to calculate and trigger progress events:\n progressInterval: 100,\n // Interval in milliseconds to calculate progress bitrate:\n bitrateInterval: 500,\n // By default, uploads are started automatically when adding files:\n autoUpload: true,\n\n // Error and info messages:\n messages: {\n uploadedBytes: 'Uploaded bytes exceed file size'\n },\n\n // Translation function, gets the message key to be translated\n // and an object with context specific data as arguments:\n i18n: function (message, context) {\n message = this.messages[message] || message.toString();\n if (context) {\n $.each(context, function (key, value) {\n message = message.replace('{' + key + '}', value);\n });\n }\n return message;\n },\n\n // Additional form data to be sent along with the file uploads can be set\n // using this option, which accepts an array of objects with name and\n // value properties, a function returning such an array, a FormData\n // object (for XHR file uploads), or a simple object.\n // The form of the first fileInput is given as parameter to the function:\n formData: function (form) {\n return form.serializeArray();\n },\n\n // The add callback is invoked as soon as files are added to the fileupload\n // widget (via file input selection, drag & drop, paste or add API call).\n // If the singleFileUploads option is enabled, this callback will be\n // called once for each file in the selection for XHR file uploads, else\n // once for each file selection.\n //\n // The upload starts when the submit method is invoked on the data parameter.\n // The data object contains a files property holding the added files\n // and allows you to override plugin options as well as define ajax settings.\n //\n // Listeners for this callback can also be bound the following way:\n // .bind('fileuploadadd', func);\n //\n // data.submit() returns a Promise object and allows to attach additional\n // handlers using jQuery's Deferred callbacks:\n // data.submit().done(func).fail(func).always(func);\n add: function (e, data) {\n if (e.isDefaultPrevented()) {\n return false;\n }\n if (data.autoUpload || (data.autoUpload !== false &&\n $(this).fileupload('option', 'autoUpload'))) {\n data.process().done(function () {\n data.submit();\n });\n }\n },\n\n // Other callbacks:\n\n // Callback for the submit event of each file upload:\n // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);\n\n // Callback for the start of each file upload request:\n // send: function (e, data) {}, // .bind('fileuploadsend', func);\n\n // Callback for successful uploads:\n // done: function (e, data) {}, // .bind('fileuploaddone', func);\n\n // Callback for failed (abort or error) uploads:\n // fail: function (e, data) {}, // .bind('fileuploadfail', func);\n\n // Callback for completed (success, abort or error) requests:\n // always: function (e, data) {}, // .bind('fileuploadalways', func);\n\n // Callback for upload progress events:\n // progress: function (e, data) {}, // .bind('fileuploadprogress', func);\n\n // Callback for global upload progress events:\n // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);\n\n // Callback for uploads start, equivalent to the global ajaxStart event:\n // start: function (e) {}, // .bind('fileuploadstart', func);\n\n // Callback for uploads stop, equivalent to the global ajaxStop event:\n // stop: function (e) {}, // .bind('fileuploadstop', func);\n\n // Callback for change events of the fileInput(s):\n // change: function (e, data) {}, // .bind('fileuploadchange', func);\n\n // Callback for paste events to the pasteZone(s):\n // paste: function (e, data) {}, // .bind('fileuploadpaste', func);\n\n // Callback for drop events of the dropZone(s):\n // drop: function (e, data) {}, // .bind('fileuploaddrop', func);\n\n // Callback for dragover events of the dropZone(s):\n // dragover: function (e) {}, // .bind('fileuploaddragover', func);\n\n // Callback before the start of each chunk upload request (before form data initialization):\n // chunkbeforesend: function (e, data) {}, // .bind('fileuploadchunkbeforesend', func);\n\n // Callback for the start of each chunk upload request:\n // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);\n\n // Callback for successful chunk uploads:\n // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);\n\n // Callback for failed (abort or error) chunk uploads:\n // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);\n\n // Callback for completed (success, abort or error) chunk upload requests:\n // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);\n\n // The plugin options are used as settings object for the ajax calls.\n // The following are jQuery ajax settings required for the file uploads:\n processData: false,\n contentType: false,\n cache: false,\n timeout: 0\n },\n\n // A list of options that require reinitializing event listeners and/or\n // special initialization code:\n _specialOptions: [\n 'fileInput',\n 'dropZone',\n 'pasteZone',\n 'multipart',\n 'forceIframeTransport'\n ],\n\n _blobSlice: $.support.blobSlice && function () {\n var slice = this.slice || this.webkitSlice || this.mozSlice;\n return slice.apply(this, arguments);\n },\n\n _BitrateTimer: function () {\n this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());\n this.loaded = 0;\n this.bitrate = 0;\n this.getBitrate = function (now, loaded, interval) {\n var timeDiff = now - this.timestamp;\n if (!this.bitrate || !interval || timeDiff > interval) {\n this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;\n this.loaded = loaded;\n this.timestamp = now;\n }\n return this.bitrate;\n };\n },\n\n _isXHRUpload: function (options) {\n return !options.forceIframeTransport &&\n ((!options.multipart && $.support.xhrFileUpload) ||\n $.support.xhrFormDataFileUpload);\n },\n\n _getFormData: function (options) {\n var formData;\n if ($.type(options.formData) === 'function') {\n return options.formData(options.form);\n }\n if ($.isArray(options.formData)) {\n return options.formData;\n }\n if ($.type(options.formData) === 'object') {\n formData = [];\n $.each(options.formData, function (name, value) {\n formData.push({name: name, value: value});\n });\n return formData;\n }\n return [];\n },\n\n _getTotal: function (files) {\n var total = 0;\n $.each(files, function (index, file) {\n total += file.size || 1;\n });\n return total;\n },\n\n _initProgressObject: function (obj) {\n var progress = {\n loaded: 0,\n total: 0,\n bitrate: 0\n };\n if (obj._progress) {\n $.extend(obj._progress, progress);\n } else {\n obj._progress = progress;\n }\n },\n\n _initResponseObject: function (obj) {\n var prop;\n if (obj._response) {\n for (prop in obj._response) {\n if (obj._response.hasOwnProperty(prop)) {\n delete obj._response[prop];\n }\n }\n } else {\n obj._response = {};\n }\n },\n\n _onProgress: function (e, data) {\n if (e.lengthComputable) {\n var now = ((Date.now) ? Date.now() : (new Date()).getTime()),\n loaded;\n if (data._time && data.progressInterval &&\n (now - data._time < data.progressInterval) &&\n e.loaded !== e.total) {\n return;\n }\n data._time = now;\n loaded = Math.floor(\n e.loaded / e.total * (data.chunkSize || data._progress.total)\n ) + (data.uploadedBytes || 0);\n // Add the difference from the previously loaded state\n // to the global loaded counter:\n this._progress.loaded += (loaded - data._progress.loaded);\n this._progress.bitrate = this._bitrateTimer.getBitrate(\n now,\n this._progress.loaded,\n data.bitrateInterval\n );\n data._progress.loaded = data.loaded = loaded;\n data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(\n now,\n loaded,\n data.bitrateInterval\n );\n // Trigger a custom progress event with a total data property set\n // to the file size(s) of the current upload and a loaded data\n // property calculated accordingly:\n this._trigger(\n 'progress',\n $.Event('progress', {delegatedEvent: e}),\n data\n );\n // Trigger a global progress event for all current file uploads,\n // including ajax calls queued for sequential file uploads:\n this._trigger(\n 'progressall',\n $.Event('progressall', {delegatedEvent: e}),\n this._progress\n );\n }\n },\n\n _initProgressListener: function (options) {\n var that = this,\n xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n // Accesss to the native XHR object is required to add event listeners\n // for the upload progress event:\n if (xhr.upload) {\n $(xhr.upload).bind('progress', function (e) {\n var oe = e.originalEvent;\n // Make sure the progress event properties get copied over:\n e.lengthComputable = oe.lengthComputable;\n e.loaded = oe.loaded;\n e.total = oe.total;\n that._onProgress(e, options);\n });\n options.xhr = function () {\n return xhr;\n };\n }\n },\n\n _deinitProgressListener: function (options) {\n var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n if (xhr.upload) {\n $(xhr.upload).unbind('progress');\n }\n },\n\n _isInstanceOf: function (type, obj) {\n // Cross-frame instanceof check\n return Object.prototype.toString.call(obj) === '[object ' + type + ']';\n },\n\n _initXHRData: function (options) {\n var that = this,\n formData,\n file = options.files[0],\n // Ignore non-multipart setting if not supported:\n multipart = options.multipart || !$.support.xhrFileUpload,\n paramName = $.type(options.paramName) === 'array' ?\n options.paramName[0] : options.paramName;\n options.headers = $.extend({}, options.headers);\n if (options.contentRange) {\n options.headers['Content-Range'] = options.contentRange;\n }\n if (!multipart || options.blob || !this._isInstanceOf('File', file)) {\n options.headers['Content-Disposition'] = 'attachment; filename=\"' +\n encodeURI(file.uploadName || file.name) + '\"';\n }\n if (!multipart) {\n options.contentType = file.type || 'application/octet-stream';\n options.data = options.blob || file;\n } else if ($.support.xhrFormDataFileUpload) {\n if (options.postMessage) {\n // window.postMessage does not allow sending FormData\n // objects, so we just add the File/Blob objects to\n // the formData array and let the postMessage window\n // create the FormData object out of this array:\n formData = this._getFormData(options);\n if (options.blob) {\n formData.push({\n name: paramName,\n value: options.blob\n });\n } else {\n $.each(options.files, function (index, file) {\n formData.push({\n name: ($.type(options.paramName) === 'array' &&\n options.paramName[index]) || paramName,\n value: file\n });\n });\n }\n } else {\n if (that._isInstanceOf('FormData', options.formData)) {\n formData = options.formData;\n } else {\n formData = new FormData();\n $.each(this._getFormData(options), function (index, field) {\n formData.append(field.name, field.value);\n });\n }\n if (options.blob) {\n formData.append(\n paramName,\n options.blob,\n file.uploadName || file.name\n );\n } else {\n $.each(options.files, function (index, file) {\n // This check allows the tests to run with\n // dummy objects:\n if (that._isInstanceOf('File', file) ||\n that._isInstanceOf('Blob', file)) {\n formData.append(\n ($.type(options.paramName) === 'array' &&\n options.paramName[index]) || paramName,\n file,\n file.uploadName || file.name\n );\n }\n });\n }\n }\n options.data = formData;\n }\n // Blob reference is not needed anymore, free memory:\n options.blob = null;\n },\n\n _initIframeSettings: function (options) {\n var targetHost = $('').prop('href', options.url).prop('host');\n // Setting the dataType to iframe enables the iframe transport:\n options.dataType = 'iframe ' + (options.dataType || '');\n // The iframe transport accepts a serialized array as form data:\n options.formData = this._getFormData(options);\n // Add redirect url to form data on cross-domain uploads:\n if (options.redirect && targetHost && targetHost !== location.host) {\n options.formData.push({\n name: options.redirectParamName || 'redirect',\n value: options.redirect\n });\n }\n },\n\n _initDataSettings: function (options) {\n if (this._isXHRUpload(options)) {\n if (!this._chunkedUpload(options, true)) {\n if (!options.data) {\n this._initXHRData(options);\n }\n this._initProgressListener(options);\n }\n if (options.postMessage) {\n // Setting the dataType to postmessage enables the\n // postMessage transport:\n options.dataType = 'postmessage ' + (options.dataType || '');\n }\n } else {\n this._initIframeSettings(options);\n }\n },\n\n _getParamName: function (options) {\n var fileInput = $(options.fileInput),\n paramName = options.paramName;\n if (!paramName) {\n paramName = [];\n fileInput.each(function () {\n var input = $(this),\n name = input.prop('name') || 'files[]',\n i = (input.prop('files') || [1]).length;\n while (i) {\n paramName.push(name);\n i -= 1;\n }\n });\n if (!paramName.length) {\n paramName = [fileInput.prop('name') || 'files[]'];\n }\n } else if (!$.isArray(paramName)) {\n paramName = [paramName];\n }\n return paramName;\n },\n\n _initFormSettings: function (options) {\n // Retrieve missing options from the input field and the\n // associated form, if available:\n if (!options.form || !options.form.length) {\n options.form = $(options.fileInput.prop('form'));\n // If the given file input doesn't have an associated form,\n // use the default widget file input's form:\n if (!options.form.length) {\n options.form = $(this.options.fileInput.prop('form'));\n }\n }\n options.paramName = this._getParamName(options);\n if (!options.url) {\n options.url = options.form.prop('action') || location.href;\n }\n // The HTTP request method must be \"POST\" or \"PUT\":\n options.type = (options.type ||\n ($.type(options.form.prop('method')) === 'string' &&\n options.form.prop('method')) || ''\n ).toUpperCase();\n if (options.type !== 'POST' && options.type !== 'PUT' &&\n options.type !== 'PATCH') {\n options.type = 'POST';\n }\n if (!options.formAcceptCharset) {\n options.formAcceptCharset = options.form.attr('accept-charset');\n }\n },\n\n _getAJAXSettings: function (data) {\n var options = $.extend({}, this.options, data);\n this._initFormSettings(options);\n this._initDataSettings(options);\n return options;\n },\n\n // jQuery 1.6 doesn't provide .state(),\n // while jQuery 1.8+ removed .isRejected() and .isResolved():\n _getDeferredState: function (deferred) {\n if (deferred.state) {\n return deferred.state();\n }\n if (deferred.isResolved()) {\n return 'resolved';\n }\n if (deferred.isRejected()) {\n return 'rejected';\n }\n return 'pending';\n },\n\n // Maps jqXHR callbacks to the equivalent\n // methods of the given Promise object:\n _enhancePromise: function (promise) {\n promise.success = promise.done;\n promise.error = promise.fail;\n promise.complete = promise.always;\n return promise;\n },\n\n // Creates and returns a Promise object enhanced with\n // the jqXHR methods abort, success, error and complete:\n _getXHRPromise: function (resolveOrReject, context, args) {\n var dfd = $.Deferred(),\n promise = dfd.promise();\n context = context || this.options.context || promise;\n if (resolveOrReject === true) {\n dfd.resolveWith(context, args);\n } else if (resolveOrReject === false) {\n dfd.rejectWith(context, args);\n }\n promise.abort = dfd.promise;\n return this._enhancePromise(promise);\n },\n\n // Adds convenience methods to the data callback argument:\n _addConvenienceMethods: function (e, data) {\n var that = this,\n getPromise = function (args) {\n return $.Deferred().resolveWith(that, args).promise();\n };\n data.process = function (resolveFunc, rejectFunc) {\n if (resolveFunc || rejectFunc) {\n data._processQueue = this._processQueue =\n (this._processQueue || getPromise([this])).then(\n function () {\n if (data.errorThrown) {\n return $.Deferred()\n .rejectWith(that, [data]).promise();\n }\n return getPromise(arguments);\n }\n ).then(resolveFunc, rejectFunc);\n }\n return this._processQueue || getPromise([this]);\n };\n data.submit = function () {\n if (this.state() !== 'pending') {\n data.jqXHR = this.jqXHR =\n (that._trigger(\n 'submit',\n $.Event('submit', {delegatedEvent: e}),\n this\n ) !== false) && that._onSend(e, this);\n }\n return this.jqXHR || that._getXHRPromise();\n };\n data.abort = function () {\n if (this.jqXHR) {\n return this.jqXHR.abort();\n }\n this.errorThrown = 'abort';\n that._trigger('fail', null, this);\n return that._getXHRPromise(false);\n };\n data.state = function () {\n if (this.jqXHR) {\n return that._getDeferredState(this.jqXHR);\n }\n if (this._processQueue) {\n return that._getDeferredState(this._processQueue);\n }\n };\n data.processing = function () {\n return !this.jqXHR && this._processQueue && that\n ._getDeferredState(this._processQueue) === 'pending';\n };\n data.progress = function () {\n return this._progress;\n };\n data.response = function () {\n return this._response;\n };\n },\n\n // Parses the Range header from the server response\n // and returns the uploaded bytes:\n _getUploadedBytes: function (jqXHR) {\n var range = jqXHR.getResponseHeader('Range'),\n parts = range && range.split('-'),\n upperBytesPos = parts && parts.length > 1 &&\n parseInt(parts[1], 10);\n return upperBytesPos && upperBytesPos + 1;\n },\n\n // Uploads a file in multiple, sequential requests\n // by splitting the file up in multiple blob chunks.\n // If the second parameter is true, only tests if the file\n // should be uploaded in chunks, but does not invoke any\n // upload requests:\n _chunkedUpload: function (options, testOnly) {\n options.uploadedBytes = options.uploadedBytes || 0;\n var that = this,\n file = options.files[0],\n fs = file.size,\n ub = options.uploadedBytes,\n mcs = options.maxChunkSize || fs,\n slice = this._blobSlice,\n dfd = $.Deferred(),\n promise = dfd.promise(),\n jqXHR,\n upload;\n if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) ||\n options.data) {\n return false;\n }\n if (testOnly) {\n return true;\n }\n if (ub >= fs) {\n file.error = options.i18n('uploadedBytes');\n return this._getXHRPromise(\n false,\n options.context,\n [null, 'error', file.error]\n );\n }\n // The chunk upload method:\n upload = function () {\n // Clone the options object for each chunk upload:\n var o = $.extend({}, options),\n currentLoaded = o._progress.loaded;\n o.blob = slice.call(\n file,\n ub,\n ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),\n file.type\n );\n // Store the current chunk size, as the blob itself\n // will be dereferenced after data processing:\n o.chunkSize = o.blob.size;\n // Expose the chunk bytes position range:\n o.contentRange = 'bytes ' + ub + '-' +\n (ub + o.chunkSize - 1) + '/' + fs;\n // Trigger chunkbeforesend to allow form data to be updated for this chunk\n that._trigger('chunkbeforesend', null, o);\n // Process the upload data (the blob and potential form data):\n that._initXHRData(o);\n // Add progress listeners for this chunk upload:\n that._initProgressListener(o);\n jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||\n that._getXHRPromise(false, o.context))\n .done(function (result, textStatus, jqXHR) {\n ub = that._getUploadedBytes(jqXHR) ||\n (ub + o.chunkSize);\n // Create a progress event if no final progress event\n // with loaded equaling total has been triggered\n // for this chunk:\n if (currentLoaded + o.chunkSize - o._progress.loaded) {\n that._onProgress($.Event('progress', {\n lengthComputable: true,\n loaded: ub - o.uploadedBytes,\n total: ub - o.uploadedBytes\n }), o);\n }\n options.uploadedBytes = o.uploadedBytes = ub;\n o.result = result;\n o.textStatus = textStatus;\n o.jqXHR = jqXHR;\n that._trigger('chunkdone', null, o);\n that._trigger('chunkalways', null, o);\n if (ub < fs) {\n // File upload not yet complete,\n // continue with the next chunk:\n upload();\n } else {\n dfd.resolveWith(\n o.context,\n [result, textStatus, jqXHR]\n );\n }\n })\n .fail(function (jqXHR, textStatus, errorThrown) {\n o.jqXHR = jqXHR;\n o.textStatus = textStatus;\n o.errorThrown = errorThrown;\n that._trigger('chunkfail', null, o);\n that._trigger('chunkalways', null, o);\n dfd.rejectWith(\n o.context,\n [jqXHR, textStatus, errorThrown]\n );\n })\n .always(function () {\n that._deinitProgressListener(o);\n });\n };\n this._enhancePromise(promise);\n promise.abort = function () {\n return jqXHR.abort();\n };\n upload();\n return promise;\n },\n\n _beforeSend: function (e, data) {\n if (this._active === 0) {\n // the start callback is triggered when an upload starts\n // and no other uploads are currently running,\n // equivalent to the global ajaxStart event:\n this._trigger('start');\n // Set timer for global bitrate progress calculation:\n this._bitrateTimer = new this._BitrateTimer();\n // Reset the global progress values:\n this._progress.loaded = this._progress.total = 0;\n this._progress.bitrate = 0;\n }\n // Make sure the container objects for the .response() and\n // .progress() methods on the data object are available\n // and reset to their initial state:\n this._initResponseObject(data);\n this._initProgressObject(data);\n data._progress.loaded = data.loaded = data.uploadedBytes || 0;\n data._progress.total = data.total = this._getTotal(data.files) || 1;\n data._progress.bitrate = data.bitrate = 0;\n this._active += 1;\n // Initialize the global progress values:\n this._progress.loaded += data.loaded;\n this._progress.total += data.total;\n },\n\n _onDone: function (result, textStatus, jqXHR, options) {\n var total = options._progress.total,\n response = options._response;\n if (options._progress.loaded < total) {\n // Create a progress event if no final progress event\n // with loaded equaling total has been triggered:\n this._onProgress($.Event('progress', {\n lengthComputable: true,\n loaded: total,\n total: total\n }), options);\n }\n response.result = options.result = result;\n response.textStatus = options.textStatus = textStatus;\n response.jqXHR = options.jqXHR = jqXHR;\n this._trigger('done', null, options);\n },\n\n _onFail: function (jqXHR, textStatus, errorThrown, options) {\n var response = options._response;\n if (options.recalculateProgress) {\n // Remove the failed (error or abort) file upload from\n // the global progress calculation:\n this._progress.loaded -= options._progress.loaded;\n this._progress.total -= options._progress.total;\n }\n response.jqXHR = options.jqXHR = jqXHR;\n response.textStatus = options.textStatus = textStatus;\n response.errorThrown = options.errorThrown = errorThrown;\n this._trigger('fail', null, options);\n },\n\n _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {\n // jqXHRorResult, textStatus and jqXHRorError are added to the\n // options object via done and fail callbacks\n this._trigger('always', null, options);\n },\n\n _onSend: function (e, data) {\n if (!data.submit) {\n this._addConvenienceMethods(e, data);\n }\n var that = this,\n jqXHR,\n aborted,\n slot,\n pipe,\n options = that._getAJAXSettings(data),\n send = function () {\n that._sending += 1;\n // Set timer for bitrate progress calculation:\n options._bitrateTimer = new that._BitrateTimer();\n jqXHR = jqXHR || (\n ((aborted || that._trigger(\n 'send',\n $.Event('send', {delegatedEvent: e}),\n options\n ) === false) &&\n that._getXHRPromise(false, options.context, aborted)) ||\n that._chunkedUpload(options) || $.ajax(options)\n ).done(function (result, textStatus, jqXHR) {\n that._onDone(result, textStatus, jqXHR, options);\n }).fail(function (jqXHR, textStatus, errorThrown) {\n that._onFail(jqXHR, textStatus, errorThrown, options);\n }).always(function (jqXHRorResult, textStatus, jqXHRorError) {\n that._deinitProgressListener(options);\n that._onAlways(\n jqXHRorResult,\n textStatus,\n jqXHRorError,\n options\n );\n that._sending -= 1;\n that._active -= 1;\n if (options.limitConcurrentUploads &&\n options.limitConcurrentUploads > that._sending) {\n // Start the next queued upload,\n // that has not been aborted:\n var nextSlot = that._slots.shift();\n while (nextSlot) {\n if (that._getDeferredState(nextSlot) === 'pending') {\n nextSlot.resolve();\n break;\n }\n nextSlot = that._slots.shift();\n }\n }\n if (that._active === 0) {\n // The stop callback is triggered when all uploads have\n // been completed, equivalent to the global ajaxStop event:\n that._trigger('stop');\n }\n });\n return jqXHR;\n };\n this._beforeSend(e, options);\n if (this.options.sequentialUploads ||\n (this.options.limitConcurrentUploads &&\n this.options.limitConcurrentUploads <= this._sending)) {\n if (this.options.limitConcurrentUploads > 1) {\n slot = $.Deferred();\n this._slots.push(slot);\n pipe = slot.then(send);\n } else {\n this._sequence = this._sequence.then(send, send);\n pipe = this._sequence;\n }\n // Return the piped Promise object, enhanced with an abort method,\n // which is delegated to the jqXHR object of the current upload,\n // and jqXHR callbacks mapped to the equivalent Promise methods:\n pipe.abort = function () {\n aborted = [undefined, 'abort', 'abort'];\n if (!jqXHR) {\n if (slot) {\n slot.rejectWith(options.context, aborted);\n }\n return send();\n }\n return jqXHR.abort();\n };\n return this._enhancePromise(pipe);\n }\n return send();\n },\n\n _onAdd: function (e, data) {\n var that = this,\n result = true,\n options = $.extend({}, this.options, data),\n files = data.files,\n filesLength = files.length,\n limit = options.limitMultiFileUploads,\n limitSize = options.limitMultiFileUploadSize,\n overhead = options.limitMultiFileUploadSizeOverhead,\n batchSize = 0,\n paramName = this._getParamName(options),\n paramNameSet,\n paramNameSlice,\n fileSet,\n i,\n j = 0;\n if (!filesLength) {\n return false;\n }\n if (limitSize && files[0].size === undefined) {\n limitSize = undefined;\n }\n if (!(options.singleFileUploads || limit || limitSize) ||\n !this._isXHRUpload(options)) {\n fileSet = [files];\n paramNameSet = [paramName];\n } else if (!(options.singleFileUploads || limitSize) && limit) {\n fileSet = [];\n paramNameSet = [];\n for (i = 0; i < filesLength; i += limit) {\n fileSet.push(files.slice(i, i + limit));\n paramNameSlice = paramName.slice(i, i + limit);\n if (!paramNameSlice.length) {\n paramNameSlice = paramName;\n }\n paramNameSet.push(paramNameSlice);\n }\n } else if (!options.singleFileUploads && limitSize) {\n fileSet = [];\n paramNameSet = [];\n for (i = 0; i < filesLength; i = i + 1) {\n batchSize += files[i].size + overhead;\n if (i + 1 === filesLength ||\n ((batchSize + files[i + 1].size + overhead) > limitSize) ||\n (limit && i + 1 - j >= limit)) {\n fileSet.push(files.slice(j, i + 1));\n paramNameSlice = paramName.slice(j, i + 1);\n if (!paramNameSlice.length) {\n paramNameSlice = paramName;\n }\n paramNameSet.push(paramNameSlice);\n j = i + 1;\n batchSize = 0;\n }\n }\n } else {\n paramNameSet = paramName;\n }\n data.originalFiles = files;\n $.each(fileSet || files, function (index, element) {\n var newData = $.extend({}, data);\n newData.files = fileSet ? element : [element];\n newData.paramName = paramNameSet[index];\n that._initResponseObject(newData);\n that._initProgressObject(newData);\n that._addConvenienceMethods(e, newData);\n result = that._trigger(\n 'add',\n $.Event('add', {delegatedEvent: e}),\n newData\n );\n return result;\n });\n return result;\n },\n\n _replaceFileInput: function (data) {\n var input = data.fileInput,\n inputClone = input.clone(true),\n restoreFocus = input.is(document.activeElement);\n // Add a reference for the new cloned file input to the data argument:\n data.fileInputClone = inputClone;\n $('
').append(inputClone)[0].reset();\n // Detaching allows to insert the fileInput on another form\n // without loosing the file input value:\n input.after(inputClone).detach();\n // If the fileInput had focus before it was detached,\n // restore focus to the inputClone.\n if (restoreFocus) {\n inputClone.focus();\n }\n // Avoid memory leaks with the detached file input:\n $.cleanData(input.unbind('remove'));\n // Replace the original file input element in the fileInput\n // elements set with the clone, which has been copied including\n // event handlers:\n this.options.fileInput = this.options.fileInput.map(function (i, el) {\n if (el === input[0]) {\n return inputClone[0];\n }\n return el;\n });\n // If the widget has been initialized on the file input itself,\n // override this.element with the file input clone:\n if (input[0] === this.element[0]) {\n this.element = inputClone;\n }\n },\n\n _handleFileTreeEntry: function (entry, path) {\n var that = this,\n dfd = $.Deferred(),\n entries = [],\n dirReader,\n errorHandler = function (e) {\n if (e && !e.entry) {\n e.entry = entry;\n }\n // Since $.when returns immediately if one\n // Deferred is rejected, we use resolve instead.\n // This allows valid files and invalid items\n // to be returned together in one set:\n dfd.resolve([e]);\n },\n successHandler = function (entries) {\n that._handleFileTreeEntries(\n entries,\n path + entry.name + '/'\n ).done(function (files) {\n dfd.resolve(files);\n }).fail(errorHandler);\n },\n readEntries = function () {\n dirReader.readEntries(function (results) {\n if (!results.length) {\n successHandler(entries);\n } else {\n entries = entries.concat(results);\n readEntries();\n }\n }, errorHandler);\n };\n path = path || '';\n if (entry.isFile) {\n if (entry._file) {\n // Workaround for Chrome bug #149735\n entry._file.relativePath = path;\n dfd.resolve(entry._file);\n } else {\n entry.file(function (file) {\n file.relativePath = path;\n dfd.resolve(file);\n }, errorHandler);\n }\n } else if (entry.isDirectory) {\n dirReader = entry.createReader();\n readEntries();\n } else {\n // Return an empty list for file system items\n // other than files or directories:\n dfd.resolve([]);\n }\n return dfd.promise();\n },\n\n _handleFileTreeEntries: function (entries, path) {\n var that = this;\n return $.when.apply(\n $,\n $.map(entries, function (entry) {\n return that._handleFileTreeEntry(entry, path);\n })\n ).then(function () {\n return Array.prototype.concat.apply(\n [],\n arguments\n );\n });\n },\n\n _getDroppedFiles: function (dataTransfer) {\n dataTransfer = dataTransfer || {};\n var items = dataTransfer.items;\n if (items && items.length && (items[0].webkitGetAsEntry ||\n items[0].getAsEntry)) {\n return this._handleFileTreeEntries(\n $.map(items, function (item) {\n var entry;\n if (item.webkitGetAsEntry) {\n entry = item.webkitGetAsEntry();\n if (entry) {\n // Workaround for Chrome bug #149735:\n entry._file = item.getAsFile();\n }\n return entry;\n }\n return item.getAsEntry();\n })\n );\n }\n return $.Deferred().resolve(\n $.makeArray(dataTransfer.files)\n ).promise();\n },\n\n _getSingleFileInputFiles: function (fileInput) {\n fileInput = $(fileInput);\n var entries = fileInput.prop('webkitEntries') ||\n fileInput.prop('entries'),\n files,\n value;\n if (entries && entries.length) {\n return this._handleFileTreeEntries(entries);\n }\n files = $.makeArray(fileInput.prop('files'));\n if (!files.length) {\n value = fileInput.prop('value');\n if (!value) {\n return $.Deferred().resolve([]).promise();\n }\n // If the files property is not available, the browser does not\n // support the File API and we add a pseudo File object with\n // the input value as name with path information removed:\n files = [{name: value.replace(/^.*\\\\/, '')}];\n } else if (files[0].name === undefined && files[0].fileName) {\n // File normalization for Safari 4 and Firefox 3:\n $.each(files, function (index, file) {\n file.name = file.fileName;\n file.size = file.fileSize;\n });\n }\n return $.Deferred().resolve(files).promise();\n },\n\n _getFileInputFiles: function (fileInput) {\n if (!(fileInput instanceof $) || fileInput.length === 1) {\n return this._getSingleFileInputFiles(fileInput);\n }\n return $.when.apply(\n $,\n $.map(fileInput, this._getSingleFileInputFiles)\n ).then(function () {\n return Array.prototype.concat.apply(\n [],\n arguments\n );\n });\n },\n\n _onChange: function (e) {\n var that = this,\n data = {\n fileInput: $(e.target),\n form: $(e.target.form)\n };\n this._getFileInputFiles(data.fileInput).always(function (files) {\n data.files = files;\n if (that.options.replaceFileInput) {\n that._replaceFileInput(data);\n }\n if (that._trigger(\n 'change',\n $.Event('change', {delegatedEvent: e}),\n data\n ) !== false) {\n that._onAdd(e, data);\n }\n });\n },\n\n _onPaste: function (e) {\n var items = e.originalEvent && e.originalEvent.clipboardData &&\n e.originalEvent.clipboardData.items,\n data = {files: []};\n if (items && items.length) {\n $.each(items, function (index, item) {\n var file = item.getAsFile && item.getAsFile();\n if (file) {\n data.files.push(file);\n }\n });\n if (this._trigger(\n 'paste',\n $.Event('paste', {delegatedEvent: e}),\n data\n ) !== false) {\n this._onAdd(e, data);\n }\n }\n },\n\n _onDrop: function (e) {\n e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n var that = this,\n dataTransfer = e.dataTransfer,\n data = {};\n if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {\n e.preventDefault();\n this._getDroppedFiles(dataTransfer).always(function (files) {\n data.files = files;\n if (that._trigger(\n 'drop',\n $.Event('drop', {delegatedEvent: e}),\n data\n ) !== false) {\n that._onAdd(e, data);\n }\n });\n }\n },\n\n _onDragOver: getDragHandler('dragover'),\n\n _onDragEnter: getDragHandler('dragenter'),\n\n _onDragLeave: getDragHandler('dragleave'),\n\n _initEventHandlers: function () {\n if (this._isXHRUpload(this.options)) {\n this._on(this.options.dropZone, {\n dragover: this._onDragOver,\n drop: this._onDrop,\n // event.preventDefault() on dragenter is required for IE10+:\n dragenter: this._onDragEnter,\n // dragleave is not required, but added for completeness:\n dragleave: this._onDragLeave\n });\n this._on(this.options.pasteZone, {\n paste: this._onPaste\n });\n }\n if ($.support.fileInput) {\n this._on(this.options.fileInput, {\n change: this._onChange\n });\n }\n },\n\n _destroyEventHandlers: function () {\n this._off(this.options.dropZone, 'dragenter dragleave dragover drop');\n this._off(this.options.pasteZone, 'paste');\n this._off(this.options.fileInput, 'change');\n },\n\n _destroy: function () {\n this._destroyEventHandlers();\n },\n\n _setOption: function (key, value) {\n var reinit = $.inArray(key, this._specialOptions) !== -1;\n if (reinit) {\n this._destroyEventHandlers();\n }\n this._super(key, value);\n if (reinit) {\n this._initSpecialOptions();\n this._initEventHandlers();\n }\n },\n\n _initSpecialOptions: function () {\n var options = this.options;\n if (options.fileInput === undefined) {\n options.fileInput = this.element.is('input[type=\"file\"]') ?\n this.element : this.element.find('input[type=\"file\"]');\n } else if (!(options.fileInput instanceof $)) {\n options.fileInput = $(options.fileInput);\n }\n if (!(options.dropZone instanceof $)) {\n options.dropZone = $(options.dropZone);\n }\n if (!(options.pasteZone instanceof $)) {\n options.pasteZone = $(options.pasteZone);\n }\n },\n\n _getRegExp: function (str) {\n var parts = str.split('/'),\n modifiers = parts.pop();\n parts.shift();\n return new RegExp(parts.join('/'), modifiers);\n },\n\n _isRegExpOption: function (key, value) {\n return key !== 'url' && $.type(value) === 'string' &&\n /^\\/.*\\/[igm]{0,3}$/.test(value);\n },\n\n _initDataAttributes: function () {\n var that = this,\n options = this.options,\n data = this.element.data();\n // Initialize options set via HTML5 data-attributes:\n $.each(\n this.element[0].attributes,\n function (index, attr) {\n var key = attr.name.toLowerCase(),\n value;\n if (/^data-/.test(key)) {\n // Convert hyphen-ated key to camelCase:\n key = key.slice(5).replace(/-[a-z]/g, function (str) {\n return str.charAt(1).toUpperCase();\n });\n value = data[key];\n if (that._isRegExpOption(key, value)) {\n value = that._getRegExp(value);\n }\n options[key] = value;\n }\n }\n );\n },\n\n _create: function () {\n this._initDataAttributes();\n this._initSpecialOptions();\n this._slots = [];\n this._sequence = this._getXHRPromise(true);\n this._sending = this._active = 0;\n this._initProgressObject(this);\n this._initEventHandlers();\n },\n\n // This method is exposed to the widget API and allows to query\n // the number of active uploads:\n active: function () {\n return this._active;\n },\n\n // This method is exposed to the widget API and allows to query\n // the widget upload progress.\n // It returns an object with loaded, total and bitrate properties\n // for the running uploads:\n progress: function () {\n return this._progress;\n },\n\n // This method is exposed to the widget API and allows adding files\n // using the fileupload API. The data parameter accepts an object which\n // must have a files property and can contain additional options:\n // .fileupload('add', {files: filesList});\n add: function (data) {\n var that = this;\n if (!data || this.options.disabled) {\n return;\n }\n if (data.fileInput && !data.files) {\n this._getFileInputFiles(data.fileInput).always(function (files) {\n data.files = files;\n that._onAdd(null, data);\n });\n } else {\n data.files = $.makeArray(data.files);\n this._onAdd(null, data);\n }\n },\n\n // This method is exposed to the widget API and allows sending files\n // using the fileupload API. The data parameter accepts an object which\n // must have a files or fileInput property and can contain additional options:\n // .fileupload('send', {files: filesList});\n // The method returns a Promise object for the file upload call.\n send: function (data) {\n if (data && !this.options.disabled) {\n if (data.fileInput && !data.files) {\n var that = this,\n dfd = $.Deferred(),\n promise = dfd.promise(),\n jqXHR,\n aborted;\n promise.abort = function () {\n aborted = true;\n if (jqXHR) {\n return jqXHR.abort();\n }\n dfd.reject(null, 'abort', 'abort');\n return promise;\n };\n this._getFileInputFiles(data.fileInput).always(\n function (files) {\n if (aborted) {\n return;\n }\n if (!files.length) {\n dfd.reject();\n return;\n }\n data.files = files;\n jqXHR = that._onSend(null, data);\n jqXHR.then(\n function (result, textStatus, jqXHR) {\n dfd.resolve(result, textStatus, jqXHR);\n },\n function (jqXHR, textStatus, errorThrown) {\n dfd.reject(jqXHR, textStatus, errorThrown);\n }\n );\n }\n );\n return this._enhancePromise(promise);\n }\n data.files = $.makeArray(data.files);\n if (data.files.length) {\n return this._onSend(null, data);\n }\n }\n return this._getXHRPromise(false, data && data.context);\n }\n\n });\n\n}));\n"]} \ No newline at end of file diff --git a/lib/garnishjs/garnish.js b/lib/garnishjs/garnish.js index d6d9dc100de..e1e5ad74907 100644 --- a/lib/garnishjs/garnish.js +++ b/lib/garnishjs/garnish.js @@ -1,2 +1,2 @@ -!function(T){var e,i,t,g=function(){};if(g.extend=function(t,e){var i=g.prototype.extend;g._prototyping=!0;var s=new this;i.call(s,t),s.base=function(){},delete g._prototyping;var n=s.constructor,h=s.constructor=function(){if(!g._prototyping)if(this._constructing||this.constructor==h)this._constructing=!0,n.apply(this,arguments),delete this._constructing;else if(null!=arguments[0])return(arguments[0].extend||i).call(arguments[0],s)};return h.ancestor=this,h.extend=this.extend,h.forEach=this.forEach,h.implement=this.implement,h.prototype=s,h.toString=this.toString,h.valueOf=function(t){return"object"==t?h:n.valueOf()},i.call(h,e),"function"==typeof h.init&&h.init(),h},g.prototype={extend:function(t,e){if(1=Garnish.hitTest._x1&&t=Garnish.hitTest._y1&&eGarnish.getBodyScrollTop._maxScrollTop&&(Garnish.getBodyScrollTop._scrollTop=Garnish.getBodyScrollTop._maxScrollTop)),Garnish.getBodyScrollTop._scrollTop},requestAnimationFrame:(i=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||function(t){return window.setTimeout(t,20)},function(t){return i(t)}),cancelAnimationFrame:(e=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.clearTimeout,function(t){return e(t)}),scrollContainerToElement:function(t,e){var i;if(void 0===e)s=(i=T(t)).scrollParent();else{var s=T(t);i=T(e)}"HTML"!==s.prop("nodeName")&&s[0]!==Garnish.$doc[0]||(s=Garnish.$win);var n,h=s.scrollTop(),o=i.offset().top,r=!1;if((n=s[0]===window?o-h:o-s.offset().top)<0)r=h+n-10;else{var a=i.outerHeight(),l=s[0]===window?window.innerHeight:s[0].clientHeight;l :last-child",this).addClass("last"),s().listenTo(this,n)},teardown:function(){if(this===window)return!1;s().removeListener(this,n)}}}),jQuery.each(["activate","textchange","resize"],function(t,i){jQuery.fn[i]=function(t,e){return 0this.drag._maxMouseScrollY&&(this.drag._scrollProperty="scrollTop",this.drag._scrollAxis="Y",this.drag._scrollDist=Math.round((this.mouseY-this.drag._maxMouseScrollY)/2)))),this.drag._scrollProperty||this.settings.axis===Garnish.Y_AXIS||(this.drag._winScrollLeft=Garnish.$win.scrollLeft(),this.drag._minMouseScrollX=this.drag._winScrollLeft+Garnish.BaseDrag.windowScrollTargetSize,this.mouseXthis.drag._maxMouseScrollX&&(this.drag._scrollProperty="scrollLeft",this.drag._scrollAxis="X",this.drag._scrollDist=Math.round((this.mouseX-this.drag._maxMouseScrollX)/2)))),this.drag._scrollProperty?(this.scrollProperty||(this.scrollProxy||(this.scrollProxy=T.proxy(this,"_scrollWindow")),this.scrollFrame&&(Garnish.cancelAnimationFrame(this.scrollFrame),this.scrollFrame=null),this.scrollFrame=Garnish.requestAnimationFrame(this.scrollProxy)),this.scrollProperty=this.drag._scrollProperty,this.scrollAxis=this.drag._scrollAxis,this.scrollDist=this.drag._scrollDist):this._cancelWindowScroll()),this.onDrag()},stopDragging:function(){this.dragging=!1,this.onDragStop(),this._cancelWindowScroll()},addItems:function(t){t=T.makeArray(t);for(var e=0;e=Garnish.BaseDrag.minMouseDist&&this.startDragging()),this.dragging&&this.drag(!0)},_handleMouseUp:function(t){this.removeAllListeners(Garnish.$doc),this.dragging&&this.stopDragging(),this.$targetItem=null},_scrollWindow:function(){this._.scrollPos=Garnish.$scrollContainer[this.scrollProperty](),Garnish.$scrollContainer[this.scrollProperty](this._.scrollPos+this.scrollDist),this["mouse"+this.scrollAxis]-=this._.scrollPos-Garnish.$scrollContainer[this.scrollProperty](),this["realMouse"+this.scrollAxis]=this["mouse"+this.scrollAxis],this.drag(),this.scrollFrame=Garnish.requestAnimationFrame(this.scrollProxy)},_cancelWindowScroll:function(){this.scrollFrame&&(Garnish.cancelAnimationFrame(this.scrollFrame),this.scrollFrame=null),this.scrollProperty=null,this.scrollAxis=null,this.scrollDist=null},_deinitItem:function(t){this.removeAllListeners(t),T.removeData(t,"drag")}},{minMouseDist:1,windowScrollTargetSize:25,defaults:{handle:null,axis:null,ignoreHandleSelector:"input, textarea, button, select, .btn",onDragStart:T.noop,onDrag:T.noop,onDragStop:T.noop}}),Garnish.CheckboxSelect=Garnish.Base.extend({$container:null,$all:null,$options:null,init:function(t){this.$container=T(t),this.$container.data("checkboxSelect")&&(Garnish.log("Double-instantiating a checkbox select on an element"),this.$container.data("checkbox-select").destroy()),this.$container.data("checkboxSelect",this);var e=this.$container.find("input");this.$all=e.filter(".all:first"),this.$options=e.not(this.$all),this.addListener(this.$all,"change","onAllChange")},onAllChange:function(){var t=this.$all.prop("checked");this.$options.prop({checked:t,disabled:t})},destroy:function(){this.$container.removeData("checkboxSelect"),this.base()}}),Garnish.ContextMenu=Garnish.Base.extend({$target:null,options:null,$menu:null,showingMenu:!1,init:function(t,e,i){this.$target=T(t),this.$target.data("contextmenu")&&(Garnish.log("Double-instantiating a context menu on an element"),this.$target.data("contextmenu").destroy()),this.$target.data("contextmenu",this),this.options=e,this.setSettings(i,Garnish.ContextMenu.defaults),Garnish.ContextMenu.counter++,this.enable()},buildMenu:function(){this.$menu=T('