{"version":3,"file":"common.js","sources":["webpack:///./node_modules/@fortawesome/fontawesome-svg-core/index.es.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faChevronLeft.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faEnvelope.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faFax.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faInfoCircle.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faMapMarkerAlt.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faMinus.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faPhone.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faPlus.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faSearch.js","webpack:///./node_modules/@fortawesome/free-solid-svg-icons/faUser.js","webpack:///./node_modules/@progress/kendo-ui/js/aspnetmvc/kendo.combobox.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/aspnetmvc/kendo.data.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/aspnetmvc/kendo.dropdownlist.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/aspnetmvc/kendo.dropdowntree.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/aspnetmvc/kendo.filemanager.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/aspnetmvc/kendo.imagebrowser.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/aspnetmvc/kendo.multicolumncombobox.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/aspnetmvc/kendo.multiselect.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/aspnetmvc/kendo.validator.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/chart/chart.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/chart/kendo-chart.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/core/core.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/core/kendo-core.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/diagram/dom.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/diagram/layout.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/diagram/math.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/diagram/services.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/diagram/svg.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/diagram/utils.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/gauge/kendo-gauges.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/gauge/main.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/attribution.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/crs.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/layers/base.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/layers/bing.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/layers/bubble.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/layers/marker.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/layers/shape.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/layers/tile.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/location.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/main.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/navigator.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/map/zoom.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/sparkline/kendo-sparkline.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/sparkline/sparkline.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/stock/kendo-stock-chart.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/stock/stock-chart.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/themes/auto-theme.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/themes/chart-base-theme.js","webpack:///./node_modules/@progress/kendo-ui/js/dataviz/themes/themes.js","webpack:///./node_modules/@progress/kendo-ui/js/drawing/html.js","webpack:///./node_modules/@progress/kendo-ui/js/drawing/kendo-drawing.js","webpack:///./node_modules/@progress/kendo-ui/js/drawing/surface-tooltip.js","webpack:///./node_modules/@progress/kendo-ui/js/drawing/surface.js","webpack:///./node_modules/@progress/kendo-ui/js/drawing/util.js","webpack:///./node_modules/@progress/kendo-ui/js/dropdowntree/treeview.js","webpack:///./node_modules/@progress/kendo-ui/js/excel/kendo-excel.js","webpack:///./node_modules/@progress/kendo-ui/js/excel/main.js","webpack:///./node_modules/@progress/kendo-ui/js/excel/mixins.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.angular.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.aspnetmvc.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.autocomplete.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.binder.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.calendar.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.color.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.columnmenu.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.columnsorter.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.combobox.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.core.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.data.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.data.odata.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.data.signalr.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.data.xml.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.barcode.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.chart.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.core.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.diagram.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.gauge.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.map.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.qrcode.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.sparkline.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.stock.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.themes.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dataviz.treemap.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dateinput.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.datepicker.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dialog.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.draganddrop.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.drawing.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dropdownlist.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.dropdowntree.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.editable.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.excel.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.filtermenu.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.floatinglabel.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.fx.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.grid.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.groupable.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.list.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.menu.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.mobile.scroller.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.multiselect.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.numerictextbox.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.ooxml.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.pager.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.pane.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.pdf.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.popup.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.progressbar.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.reorderable.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.resizable.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.router.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.selectable.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.sortable.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.switch.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.toolbar.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.tooltip.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.treeview.draganddrop.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.treeview.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.userevents.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.validator.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.view.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.virtuallist.js","webpack:///./node_modules/@progress/kendo-ui/js/kendo.window.js","webpack:///./node_modules/@progress/kendo-ui/js/ooxml/kendo-ooxml.js","webpack:///./node_modules/@progress/kendo-ui/js/ooxml/main.js","webpack:///./node_modules/@progress/kendo-ui/js/ooxml/utils.js","webpack:///./node_modules/@progress/kendo-ui/js/pdf/core.js","webpack:///./node_modules/@progress/kendo-ui/js/pdf/mixins.js","webpack:///./node_modules/@progress/kendo-ui/js/pdf/pako.js","webpack:///./node_modules/@progress/kendo-ui/js/util/main.js","webpack:///./node_modules/@progress/kendo-ui/js/util/text-metrics.js","webpack:///./node_modules/@progress/kendo-ui/node_modules/jquery/dist/jquery.js","webpack:///./node_modules/base64-js/index.js","webpack:///./node_modules/bootstrap/js/dist/alert.js","webpack:///./node_modules/bootstrap/js/dist/collapse.js","webpack:///./node_modules/bootstrap/js/dist/modal.js","webpack:///./node_modules/bootstrap/js/dist/util.js","webpack:///./node_modules/buffer/index.js","webpack:///./node_modules/expose-loader/dist/runtime/getGlobalThis.js","webpack:///./node_modules/ieee754/index.js","webpack:///./node_modules/isarray/index.js","webpack:///./node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js","webpack:///./node_modules/jquery-validation/dist/jquery.validate.js","webpack:///./node_modules/jquery/dist/jquery-exposed.js","webpack:///./node_modules/jquery/dist/jquery.js","webpack:///./node_modules/jszip/dist/jszip.js","webpack:///./node_modules/process/browser.js","webpack:///./node_modules/setimmediate/setImmediate.js","webpack:///./node_modules/timers-browserify/main.js","webpack:///(webpack)/buildin/global.js","webpack:///./wwwroot/scripts/components/cookies.js","webpack:///./wwwroot/scripts/components/disclaimers.js","webpack:///./wwwroot/scripts/components/dynamic-grid.js","webpack:///./wwwroot/scripts/components/footer.js","webpack:///./wwwroot/scripts/components/header.js","webpack:///./wwwroot/scripts/components/top-menu.js","webpack:///./wwwroot/scripts/selectedIcons.js"],"sourcesContent":["function _typeof(obj) {\n if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n _typeof = function (obj) {\n return typeof obj;\n };\n } else {\n _typeof = function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n }\n\n return _typeof(obj);\n}\n\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}\n\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nfunction _objectSpread(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i] != null ? arguments[i] : {};\n var ownKeys = Object.keys(source);\n\n if (typeof Object.getOwnPropertySymbols === 'function') {\n ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {\n return Object.getOwnPropertyDescriptor(source, sym).enumerable;\n }));\n }\n\n ownKeys.forEach(function (key) {\n _defineProperty(target, key, source[key]);\n });\n }\n\n return target;\n}\n\nfunction _slicedToArray(arr, i) {\n return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();\n}\n\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();\n}\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) {\n for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n return arr2;\n }\n}\n\nfunction _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n\nfunction _iterableToArray(iter) {\n if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter);\n}\n\nfunction _iterableToArrayLimit(arr, i) {\n var _arr = [];\n var _n = true;\n var _d = false;\n var _e = undefined;\n\n try {\n for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n\nfunction _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance\");\n}\n\nfunction _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n}\n\nvar noop = function noop() {};\n\nvar _WINDOW = {};\nvar _DOCUMENT = {};\nvar _MUTATION_OBSERVER = null;\nvar _PERFORMANCE = {\n mark: noop,\n measure: noop\n};\n\ntry {\n if (typeof window !== 'undefined') _WINDOW = window;\n if (typeof document !== 'undefined') _DOCUMENT = document;\n if (typeof MutationObserver !== 'undefined') _MUTATION_OBSERVER = MutationObserver;\n if (typeof performance !== 'undefined') _PERFORMANCE = performance;\n} catch (e) {}\n\nvar _ref = _WINDOW.navigator || {},\n _ref$userAgent = _ref.userAgent,\n userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\nvar WINDOW = _WINDOW;\nvar DOCUMENT = _DOCUMENT;\nvar MUTATION_OBSERVER = _MUTATION_OBSERVER;\nvar PERFORMANCE = _PERFORMANCE;\nvar IS_BROWSER = !!WINDOW.document;\nvar IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\nvar IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\nvar NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\nvar UNITS_IN_GRID = 16;\nvar DEFAULT_FAMILY_PREFIX = 'fa';\nvar DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa';\nvar DATA_FA_I2SVG = 'data-fa-i2svg';\nvar DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element';\nvar DATA_FA_PSEUDO_ELEMENT_PENDING = 'data-fa-pseudo-element-pending';\nvar DATA_PREFIX = 'data-prefix';\nvar DATA_ICON = 'data-icon';\nvar HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg';\nvar MUTATION_APPROACH_ASYNC = 'async';\nvar TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS = ['HTML', 'HEAD', 'STYLE', 'SCRIPT'];\nvar PRODUCTION = function () {\n try {\n return process.env.NODE_ENV === 'production';\n } catch (e) {\n return false;\n }\n}();\nvar PREFIX_TO_STYLE = {\n 'fas': 'solid',\n 'far': 'regular',\n 'fal': 'light',\n 'fad': 'duotone',\n 'fab': 'brands',\n 'fa': 'solid'\n};\nvar STYLE_TO_PREFIX = {\n 'solid': 'fas',\n 'regular': 'far',\n 'light': 'fal',\n 'duotone': 'fad',\n 'brands': 'fab'\n};\nvar LAYERS_TEXT_CLASSNAME = 'fa-layers-text';\nvar FONT_FAMILY_PATTERN = /Font Awesome 5 (Solid|Regular|Light|Duotone|Brands|Free|Pro)/;\nvar FONT_WEIGHT_TO_PREFIX = {\n '900': 'fas',\n '400': 'far',\n 'normal': 'far',\n '300': 'fal'\n};\nvar oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nvar oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);\nvar ATTRIBUTES_WATCHED_FOR_MUTATION = ['class', 'data-prefix', 'data-icon', 'data-fa-transform', 'data-fa-mask'];\nvar DUOTONE_CLASSES = {\n GROUP: 'group',\n SWAP_OPACITY: 'swap-opacity',\n PRIMARY: 'primary',\n SECONDARY: 'secondary'\n};\nvar RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'flip-both', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter', DUOTONE_CLASSES.GROUP, DUOTONE_CLASSES.SWAP_OPACITY, DUOTONE_CLASSES.PRIMARY, DUOTONE_CLASSES.SECONDARY].concat(oneToTen.map(function (n) {\n return \"\".concat(n, \"x\");\n})).concat(oneToTwenty.map(function (n) {\n return \"w-\".concat(n);\n}));\n\nvar initial = WINDOW.FontAwesomeConfig || {};\n\nfunction getAttrConfig(attr) {\n var element = DOCUMENT.querySelector('script[' + attr + ']');\n\n if (element) {\n return element.getAttribute(attr);\n }\n}\n\nfunction coerce(val) {\n // Getting an empty string will occur if the attribute is set on the HTML tag but without a value\n // We'll assume that this is an indication that it should be toggled to true\n // For example \n if (val === '') return true;\n if (val === 'false') return false;\n if (val === 'true') return true;\n return val;\n}\n\nif (DOCUMENT && typeof DOCUMENT.querySelector === 'function') {\n var attrs = [['data-family-prefix', 'familyPrefix'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']];\n attrs.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n attr = _ref2[0],\n key = _ref2[1];\n\n var val = coerce(getAttrConfig(attr));\n\n if (val !== undefined && val !== null) {\n initial[key] = val;\n }\n });\n}\n\nvar _default = {\n familyPrefix: DEFAULT_FAMILY_PREFIX,\n replacementClass: DEFAULT_REPLACEMENT_CLASS,\n autoReplaceSvg: true,\n autoAddCss: true,\n autoA11y: true,\n searchPseudoElements: false,\n observeMutations: true,\n mutateApproach: 'async',\n keepOriginalSource: true,\n measurePerformance: false,\n showMissingIcons: true\n};\n\nvar _config = _objectSpread({}, _default, initial);\n\nif (!_config.autoReplaceSvg) _config.observeMutations = false;\n\nvar config = _objectSpread({}, _config);\n\nWINDOW.FontAwesomeConfig = config;\n\nvar w = WINDOW || {};\nif (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\nif (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\nif (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\nif (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\nvar namespace = w[NAMESPACE_IDENTIFIER];\n\nvar functions = [];\n\nvar listener = function listener() {\n DOCUMENT.removeEventListener('DOMContentLoaded', listener);\n loaded = 1;\n functions.map(function (fn) {\n return fn();\n });\n};\n\nvar loaded = false;\n\nif (IS_DOM) {\n loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);\n if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);\n}\n\nfunction domready (fn) {\n if (!IS_DOM) return;\n loaded ? setTimeout(fn, 0) : functions.push(fn);\n}\n\nvar PENDING = 'pending';\nvar SETTLED = 'settled';\nvar FULFILLED = 'fulfilled';\nvar REJECTED = 'rejected';\n\nvar NOOP = function NOOP() {};\n\nvar isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function';\nvar asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate;\nvar asyncQueue = [];\nvar asyncTimer;\n\nfunction asyncFlush() {\n // run promise callbacks\n for (var i = 0; i < asyncQueue.length; i++) {\n asyncQueue[i][0](asyncQueue[i][1]);\n } // reset async asyncQueue\n\n\n asyncQueue = [];\n asyncTimer = false;\n}\n\nfunction asyncCall(callback, arg) {\n asyncQueue.push([callback, arg]);\n\n if (!asyncTimer) {\n asyncTimer = true;\n asyncSetTimer(asyncFlush, 0);\n }\n}\n\nfunction invokeResolver(resolver, promise) {\n function resolvePromise(value) {\n resolve(promise, value);\n }\n\n function rejectPromise(reason) {\n reject(promise, reason);\n }\n\n try {\n resolver(resolvePromise, rejectPromise);\n } catch (e) {\n rejectPromise(e);\n }\n}\n\nfunction invokeCallback(subscriber) {\n var owner = subscriber.owner;\n var settled = owner._state;\n var value = owner._data;\n var callback = subscriber[settled];\n var promise = subscriber.then;\n\n if (typeof callback === 'function') {\n settled = FULFILLED;\n\n try {\n value = callback(value);\n } catch (e) {\n reject(promise, e);\n }\n }\n\n if (!handleThenable(promise, value)) {\n if (settled === FULFILLED) {\n resolve(promise, value);\n }\n\n if (settled === REJECTED) {\n reject(promise, value);\n }\n }\n}\n\nfunction handleThenable(promise, value) {\n var resolved;\n\n try {\n if (promise === value) {\n throw new TypeError('A promises callback cannot return that same promise.');\n }\n\n if (value && (typeof value === 'function' || _typeof(value) === 'object')) {\n // then should be retrieved only once\n var then = value.then;\n\n if (typeof then === 'function') {\n then.call(value, function (val) {\n if (!resolved) {\n resolved = true;\n\n if (value === val) {\n fulfill(promise, val);\n } else {\n resolve(promise, val);\n }\n }\n }, function (reason) {\n if (!resolved) {\n resolved = true;\n reject(promise, reason);\n }\n });\n return true;\n }\n }\n } catch (e) {\n if (!resolved) {\n reject(promise, e);\n }\n\n return true;\n }\n\n return false;\n}\n\nfunction resolve(promise, value) {\n if (promise === value || !handleThenable(promise, value)) {\n fulfill(promise, value);\n }\n}\n\nfunction fulfill(promise, value) {\n if (promise._state === PENDING) {\n promise._state = SETTLED;\n promise._data = value;\n asyncCall(publishFulfillment, promise);\n }\n}\n\nfunction reject(promise, reason) {\n if (promise._state === PENDING) {\n promise._state = SETTLED;\n promise._data = reason;\n asyncCall(publishRejection, promise);\n }\n}\n\nfunction publish(promise) {\n promise._then = promise._then.forEach(invokeCallback);\n}\n\nfunction publishFulfillment(promise) {\n promise._state = FULFILLED;\n publish(promise);\n}\n\nfunction publishRejection(promise) {\n promise._state = REJECTED;\n publish(promise);\n\n if (!promise._handled && isNode) {\n global.process.emit('unhandledRejection', promise._data, promise);\n }\n}\n\nfunction notifyRejectionHandled(promise) {\n global.process.emit('rejectionHandled', promise);\n}\n/**\n * @class\n */\n\n\nfunction P(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('Promise resolver ' + resolver + ' is not a function');\n }\n\n if (this instanceof P === false) {\n throw new TypeError('Failed to construct \\'Promise\\': Please use the \\'new\\' operator, this object constructor cannot be called as a function.');\n }\n\n this._then = [];\n invokeResolver(resolver, this);\n}\n\nP.prototype = {\n constructor: P,\n _state: PENDING,\n _then: null,\n _data: undefined,\n _handled: false,\n then: function then(onFulfillment, onRejection) {\n var subscriber = {\n owner: this,\n then: new this.constructor(NOOP),\n fulfilled: onFulfillment,\n rejected: onRejection\n };\n\n if ((onRejection || onFulfillment) && !this._handled) {\n this._handled = true;\n\n if (this._state === REJECTED && isNode) {\n asyncCall(notifyRejectionHandled, this);\n }\n }\n\n if (this._state === FULFILLED || this._state === REJECTED) {\n // already resolved, call callback async\n asyncCall(invokeCallback, subscriber);\n } else {\n // subscribe\n this._then.push(subscriber);\n }\n\n return subscriber.then;\n },\n catch: function _catch(onRejection) {\n return this.then(null, onRejection);\n }\n};\n\nP.all = function (promises) {\n if (!Array.isArray(promises)) {\n throw new TypeError('You must pass an array to Promise.all().');\n }\n\n return new P(function (resolve, reject) {\n var results = [];\n var remaining = 0;\n\n function resolver(index) {\n remaining++;\n return function (value) {\n results[index] = value;\n\n if (! --remaining) {\n resolve(results);\n }\n };\n }\n\n for (var i = 0, promise; i < promises.length; i++) {\n promise = promises[i];\n\n if (promise && typeof promise.then === 'function') {\n promise.then(resolver(i), reject);\n } else {\n results[i] = promise;\n }\n }\n\n if (!remaining) {\n resolve(results);\n }\n });\n};\n\nP.race = function (promises) {\n if (!Array.isArray(promises)) {\n throw new TypeError('You must pass an array to Promise.race().');\n }\n\n return new P(function (resolve, reject) {\n for (var i = 0, promise; i < promises.length; i++) {\n promise = promises[i];\n\n if (promise && typeof promise.then === 'function') {\n promise.then(resolve, reject);\n } else {\n resolve(promise);\n }\n }\n });\n};\n\nP.resolve = function (value) {\n if (value && _typeof(value) === 'object' && value.constructor === P) {\n return value;\n }\n\n return new P(function (resolve) {\n resolve(value);\n });\n};\n\nP.reject = function (reason) {\n return new P(function (resolve, reject) {\n reject(reason);\n });\n};\n\nvar picked = typeof Promise === 'function' ? Promise : P;\n\nvar d = UNITS_IN_GRID;\nvar meaninglessTransform = {\n size: 16,\n x: 0,\n y: 0,\n rotate: 0,\n flipX: false,\n flipY: false\n};\n\nfunction isReserved(name) {\n return ~RESERVED_CLASSES.indexOf(name);\n}\nfunction insertCss(css) {\n if (!css || !IS_DOM) {\n return;\n }\n\n var style = DOCUMENT.createElement('style');\n style.setAttribute('type', 'text/css');\n style.innerHTML = css;\n var headChildren = DOCUMENT.head.childNodes;\n var beforeChild = null;\n\n for (var i = headChildren.length - 1; i > -1; i--) {\n var child = headChildren[i];\n var tagName = (child.tagName || '').toUpperCase();\n\n if (['STYLE', 'LINK'].indexOf(tagName) > -1) {\n beforeChild = child;\n }\n }\n\n DOCUMENT.head.insertBefore(style, beforeChild);\n return css;\n}\nvar idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\nfunction nextUniqueId() {\n var size = 12;\n var id = '';\n\n while (size-- > 0) {\n id += idPool[Math.random() * 62 | 0];\n }\n\n return id;\n}\nfunction toArray(obj) {\n var array = [];\n\n for (var i = (obj || []).length >>> 0; i--;) {\n array[i] = obj[i];\n }\n\n return array;\n}\nfunction classArray(node) {\n if (node.classList) {\n return toArray(node.classList);\n } else {\n return (node.getAttribute('class') || '').split(' ').filter(function (i) {\n return i;\n });\n }\n}\nfunction getIconName(familyPrefix, cls) {\n var parts = cls.split('-');\n var prefix = parts[0];\n var iconName = parts.slice(1).join('-');\n\n if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) {\n return iconName;\n } else {\n return null;\n }\n}\nfunction htmlEscape(str) {\n return \"\".concat(str).replace(/&/g, '&').replace(/\"/g, '"').replace(/'/g, ''').replace(//g, '>');\n}\nfunction joinAttributes(attributes) {\n return Object.keys(attributes || {}).reduce(function (acc, attributeName) {\n return acc + \"\".concat(attributeName, \"=\\\"\").concat(htmlEscape(attributes[attributeName]), \"\\\" \");\n }, '').trim();\n}\nfunction joinStyles(styles) {\n return Object.keys(styles || {}).reduce(function (acc, styleName) {\n return acc + \"\".concat(styleName, \": \").concat(styles[styleName], \";\");\n }, '');\n}\nfunction transformIsMeaningful(transform) {\n return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY;\n}\nfunction transformForSvg(_ref) {\n var transform = _ref.transform,\n containerWidth = _ref.containerWidth,\n iconWidth = _ref.iconWidth;\n var outer = {\n transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n };\n var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n var inner = {\n transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n };\n var path = {\n transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n };\n return {\n outer: outer,\n inner: inner,\n path: path\n };\n}\nfunction transformForCss(_ref2) {\n var transform = _ref2.transform,\n _ref2$width = _ref2.width,\n width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width,\n _ref2$height = _ref2.height,\n height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height,\n _ref2$startCentered = _ref2.startCentered,\n startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered;\n var val = '';\n\n if (startCentered && IS_IE) {\n val += \"translate(\".concat(transform.x / d - width / 2, \"em, \").concat(transform.y / d - height / 2, \"em) \");\n } else if (startCentered) {\n val += \"translate(calc(-50% + \".concat(transform.x / d, \"em), calc(-50% + \").concat(transform.y / d, \"em)) \");\n } else {\n val += \"translate(\".concat(transform.x / d, \"em, \").concat(transform.y / d, \"em) \");\n }\n\n val += \"scale(\".concat(transform.size / d * (transform.flipX ? -1 : 1), \", \").concat(transform.size / d * (transform.flipY ? -1 : 1), \") \");\n val += \"rotate(\".concat(transform.rotate, \"deg) \");\n return val;\n}\n\nvar ALL_SPACE = {\n x: 0,\n y: 0,\n width: '100%',\n height: '100%'\n};\n\nfunction fillBlack(abstract) {\n var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n if (abstract.attributes && (abstract.attributes.fill || force)) {\n abstract.attributes.fill = 'black';\n }\n\n return abstract;\n}\n\nfunction deGroup(abstract) {\n if (abstract.tag === 'g') {\n return abstract.children;\n } else {\n return [abstract];\n }\n}\n\nfunction makeIconMasking (_ref) {\n var children = _ref.children,\n attributes = _ref.attributes,\n main = _ref.main,\n mask = _ref.mask,\n explicitMaskId = _ref.maskId,\n transform = _ref.transform;\n var mainWidth = main.width,\n mainPath = main.icon;\n var maskWidth = mask.width,\n maskPath = mask.icon;\n var trans = transformForSvg({\n transform: transform,\n containerWidth: maskWidth,\n iconWidth: mainWidth\n });\n var maskRect = {\n tag: 'rect',\n attributes: _objectSpread({}, ALL_SPACE, {\n fill: 'white'\n })\n };\n var maskInnerGroupChildrenMixin = mainPath.children ? {\n children: mainPath.children.map(fillBlack)\n } : {};\n var maskInnerGroup = {\n tag: 'g',\n attributes: _objectSpread({}, trans.inner),\n children: [fillBlack(_objectSpread({\n tag: mainPath.tag,\n attributes: _objectSpread({}, mainPath.attributes, trans.path)\n }, maskInnerGroupChildrenMixin))]\n };\n var maskOuterGroup = {\n tag: 'g',\n attributes: _objectSpread({}, trans.outer),\n children: [maskInnerGroup]\n };\n var maskId = \"mask-\".concat(explicitMaskId || nextUniqueId());\n var clipId = \"clip-\".concat(explicitMaskId || nextUniqueId());\n var maskTag = {\n tag: 'mask',\n attributes: _objectSpread({}, ALL_SPACE, {\n id: maskId,\n maskUnits: 'userSpaceOnUse',\n maskContentUnits: 'userSpaceOnUse'\n }),\n children: [maskRect, maskOuterGroup]\n };\n var defs = {\n tag: 'defs',\n children: [{\n tag: 'clipPath',\n attributes: {\n id: clipId\n },\n children: deGroup(maskPath)\n }, maskTag]\n };\n children.push(defs, {\n tag: 'rect',\n attributes: _objectSpread({\n fill: 'currentColor',\n 'clip-path': \"url(#\".concat(clipId, \")\"),\n mask: \"url(#\".concat(maskId, \")\")\n }, ALL_SPACE)\n });\n return {\n children: children,\n attributes: attributes\n };\n}\n\nfunction makeIconStandard (_ref) {\n var children = _ref.children,\n attributes = _ref.attributes,\n main = _ref.main,\n transform = _ref.transform,\n styles = _ref.styles;\n var styleString = joinStyles(styles);\n\n if (styleString.length > 0) {\n attributes['style'] = styleString;\n }\n\n if (transformIsMeaningful(transform)) {\n var trans = transformForSvg({\n transform: transform,\n containerWidth: main.width,\n iconWidth: main.width\n });\n children.push({\n tag: 'g',\n attributes: _objectSpread({}, trans.outer),\n children: [{\n tag: 'g',\n attributes: _objectSpread({}, trans.inner),\n children: [{\n tag: main.icon.tag,\n children: main.icon.children,\n attributes: _objectSpread({}, main.icon.attributes, trans.path)\n }]\n }]\n });\n } else {\n children.push(main.icon);\n }\n\n return {\n children: children,\n attributes: attributes\n };\n}\n\nfunction asIcon (_ref) {\n var children = _ref.children,\n main = _ref.main,\n mask = _ref.mask,\n attributes = _ref.attributes,\n styles = _ref.styles,\n transform = _ref.transform;\n\n if (transformIsMeaningful(transform) && main.found && !mask.found) {\n var width = main.width,\n height = main.height;\n var offset = {\n x: width / height / 2,\n y: 0.5\n };\n attributes['style'] = joinStyles(_objectSpread({}, styles, {\n 'transform-origin': \"\".concat(offset.x + transform.x / 16, \"em \").concat(offset.y + transform.y / 16, \"em\")\n }));\n }\n\n return [{\n tag: 'svg',\n attributes: attributes,\n children: children\n }];\n}\n\nfunction asSymbol (_ref) {\n var prefix = _ref.prefix,\n iconName = _ref.iconName,\n children = _ref.children,\n attributes = _ref.attributes,\n symbol = _ref.symbol;\n var id = symbol === true ? \"\".concat(prefix, \"-\").concat(config.familyPrefix, \"-\").concat(iconName) : symbol;\n return [{\n tag: 'svg',\n attributes: {\n style: 'display: none;'\n },\n children: [{\n tag: 'symbol',\n attributes: _objectSpread({}, attributes, {\n id: id\n }),\n children: children\n }]\n }];\n}\n\nfunction makeInlineSvgAbstract(params) {\n var _params$icons = params.icons,\n main = _params$icons.main,\n mask = _params$icons.mask,\n prefix = params.prefix,\n iconName = params.iconName,\n transform = params.transform,\n symbol = params.symbol,\n title = params.title,\n maskId = params.maskId,\n titleId = params.titleId,\n extra = params.extra,\n _params$watchable = params.watchable,\n watchable = _params$watchable === void 0 ? false : _params$watchable;\n\n var _ref = mask.found ? mask : main,\n width = _ref.width,\n height = _ref.height;\n\n var widthClass = \"fa-w-\".concat(Math.ceil(width / height * 16));\n var attrClass = [config.replacementClass, iconName ? \"\".concat(config.familyPrefix, \"-\").concat(iconName) : '', widthClass].filter(function (c) {\n return extra.classes.indexOf(c) === -1;\n }).concat(extra.classes).join(' ');\n var content = {\n children: [],\n attributes: _objectSpread({}, extra.attributes, {\n 'data-prefix': prefix,\n 'data-icon': iconName,\n 'class': attrClass,\n 'role': extra.attributes.role || 'img',\n 'xmlns': 'http://www.w3.org/2000/svg',\n 'viewBox': \"0 0 \".concat(width, \" \").concat(height)\n })\n };\n\n if (watchable) {\n content.attributes[DATA_FA_I2SVG] = '';\n }\n\n if (title) content.children.push({\n tag: 'title',\n attributes: {\n id: content.attributes['aria-labelledby'] || \"title-\".concat(titleId || nextUniqueId())\n },\n children: [title]\n });\n\n var args = _objectSpread({}, content, {\n prefix: prefix,\n iconName: iconName,\n main: main,\n mask: mask,\n maskId: maskId,\n transform: transform,\n symbol: symbol,\n styles: extra.styles\n });\n\n var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args),\n children = _ref2.children,\n attributes = _ref2.attributes;\n\n args.children = children;\n args.attributes = attributes;\n\n if (symbol) {\n return asSymbol(args);\n } else {\n return asIcon(args);\n }\n}\nfunction makeLayersTextAbstract(params) {\n var content = params.content,\n width = params.width,\n height = params.height,\n transform = params.transform,\n title = params.title,\n extra = params.extra,\n _params$watchable2 = params.watchable,\n watchable = _params$watchable2 === void 0 ? false : _params$watchable2;\n\n var attributes = _objectSpread({}, extra.attributes, title ? {\n 'title': title\n } : {}, {\n 'class': extra.classes.join(' ')\n });\n\n if (watchable) {\n attributes[DATA_FA_I2SVG] = '';\n }\n\n var styles = _objectSpread({}, extra.styles);\n\n if (transformIsMeaningful(transform)) {\n styles['transform'] = transformForCss({\n transform: transform,\n startCentered: true,\n width: width,\n height: height\n });\n styles['-webkit-transform'] = styles['transform'];\n }\n\n var styleString = joinStyles(styles);\n\n if (styleString.length > 0) {\n attributes['style'] = styleString;\n }\n\n var val = [];\n val.push({\n tag: 'span',\n attributes: attributes,\n children: [content]\n });\n\n if (title) {\n val.push({\n tag: 'span',\n attributes: {\n class: 'sr-only'\n },\n children: [title]\n });\n }\n\n return val;\n}\nfunction makeLayersCounterAbstract(params) {\n var content = params.content,\n title = params.title,\n extra = params.extra;\n\n var attributes = _objectSpread({}, extra.attributes, title ? {\n 'title': title\n } : {}, {\n 'class': extra.classes.join(' ')\n });\n\n var styleString = joinStyles(extra.styles);\n\n if (styleString.length > 0) {\n attributes['style'] = styleString;\n }\n\n var val = [];\n val.push({\n tag: 'span',\n attributes: attributes,\n children: [content]\n });\n\n if (title) {\n val.push({\n tag: 'span',\n attributes: {\n class: 'sr-only'\n },\n children: [title]\n });\n }\n\n return val;\n}\n\nvar noop$1 = function noop() {};\n\nvar p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : {\n mark: noop$1,\n measure: noop$1\n};\nvar preamble = \"FA \\\"5.14.0\\\"\";\n\nvar begin = function begin(name) {\n p.mark(\"\".concat(preamble, \" \").concat(name, \" begins\"));\n return function () {\n return end(name);\n };\n};\n\nvar end = function end(name) {\n p.mark(\"\".concat(preamble, \" \").concat(name, \" ends\"));\n p.measure(\"\".concat(preamble, \" \").concat(name), \"\".concat(preamble, \" \").concat(name, \" begins\"), \"\".concat(preamble, \" \").concat(name, \" ends\"));\n};\n\nvar perf = {\n begin: begin,\n end: end\n};\n\n/**\n * Internal helper to bind a function known to have 4 arguments\n * to a given context.\n */\n\nvar bindInternal4 = function bindInternal4(func, thisContext) {\n return function (a, b, c, d) {\n return func.call(thisContext, a, b, c, d);\n };\n};\n\n/**\n * # Reduce\n *\n * A fast object `.reduce()` implementation.\n *\n * @param {Object} subject The object to reduce over.\n * @param {Function} fn The reducer function.\n * @param {mixed} initialValue The initial value for the reducer, defaults to subject[0].\n * @param {Object} thisContext The context for the reducer.\n * @return {mixed} The final result.\n */\n\n\nvar reduce = function fastReduceObject(subject, fn, initialValue, thisContext) {\n var keys = Object.keys(subject),\n length = keys.length,\n iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,\n i,\n key,\n result;\n\n if (initialValue === undefined) {\n i = 1;\n result = subject[keys[0]];\n } else {\n i = 0;\n result = initialValue;\n }\n\n for (; i < length; i++) {\n key = keys[i];\n result = iterator(result, subject[key], key, subject);\n }\n\n return result;\n};\n\nfunction toHex(unicode) {\n var result = '';\n\n for (var i = 0; i < unicode.length; i++) {\n var hex = unicode.charCodeAt(i).toString(16);\n result += ('000' + hex).slice(-4);\n }\n\n return result;\n}\n\nfunction defineIcons(prefix, icons) {\n var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var _params$skipHooks = params.skipHooks,\n skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n var icon = icons[iconName];\n var expanded = !!icon.icon;\n\n if (expanded) {\n acc[icon.iconName] = icon.icon;\n } else {\n acc[iconName] = icon;\n }\n\n return acc;\n }, {});\n\n if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n namespace.hooks.addPack(prefix, normalized);\n } else {\n namespace.styles[prefix] = _objectSpread({}, namespace.styles[prefix] || {}, normalized);\n }\n /**\n * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n * for `fas` so we'll easy the upgrade process for our users by automatically defining\n * this as well.\n */\n\n\n if (prefix === 'fas') {\n defineIcons('fa', icons);\n }\n}\n\nvar styles = namespace.styles,\n shims = namespace.shims;\nvar _byUnicode = {};\nvar _byLigature = {};\nvar _byOldName = {};\nvar build = function build() {\n var lookup = function lookup(reducer) {\n return reduce(styles, function (o, style, prefix) {\n o[prefix] = reduce(style, reducer, {});\n return o;\n }, {});\n };\n\n _byUnicode = lookup(function (acc, icon, iconName) {\n if (icon[3]) {\n acc[icon[3]] = iconName;\n }\n\n return acc;\n });\n _byLigature = lookup(function (acc, icon, iconName) {\n var ligatures = icon[2];\n acc[iconName] = iconName;\n ligatures.forEach(function (ligature) {\n acc[ligature] = iconName;\n });\n return acc;\n });\n var hasRegular = 'far' in styles;\n _byOldName = reduce(shims, function (acc, shim) {\n var oldName = shim[0];\n var prefix = shim[1];\n var iconName = shim[2];\n\n if (prefix === 'far' && !hasRegular) {\n prefix = 'fas';\n }\n\n acc[oldName] = {\n prefix: prefix,\n iconName: iconName\n };\n return acc;\n }, {});\n};\nbuild();\nfunction byUnicode(prefix, unicode) {\n return (_byUnicode[prefix] || {})[unicode];\n}\nfunction byLigature(prefix, ligature) {\n return (_byLigature[prefix] || {})[ligature];\n}\nfunction byOldName(name) {\n return _byOldName[name] || {\n prefix: null,\n iconName: null\n };\n}\n\nvar styles$1 = namespace.styles;\nvar emptyCanonicalIcon = function emptyCanonicalIcon() {\n return {\n prefix: null,\n iconName: null,\n rest: []\n };\n};\nfunction getCanonicalIcon(values) {\n return values.reduce(function (acc, cls) {\n var iconName = getIconName(config.familyPrefix, cls);\n\n if (styles$1[cls]) {\n acc.prefix = cls;\n } else if (config.autoFetchSvg && ['fas', 'far', 'fal', 'fad', 'fab', 'fa'].indexOf(cls) > -1) {\n acc.prefix = cls;\n } else if (iconName) {\n var shim = acc.prefix === 'fa' ? byOldName(iconName) : {};\n acc.iconName = shim.iconName || iconName;\n acc.prefix = shim.prefix || acc.prefix;\n } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) {\n acc.rest.push(cls);\n }\n\n return acc;\n }, emptyCanonicalIcon());\n}\nfunction iconFromMapping(mapping, prefix, iconName) {\n if (mapping && mapping[prefix] && mapping[prefix][iconName]) {\n return {\n prefix: prefix,\n iconName: iconName,\n icon: mapping[prefix][iconName]\n };\n }\n}\n\nfunction toHtml(abstractNodes) {\n var tag = abstractNodes.tag,\n _abstractNodes$attrib = abstractNodes.attributes,\n attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib,\n _abstractNodes$childr = abstractNodes.children,\n children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr;\n\n if (typeof abstractNodes === 'string') {\n return htmlEscape(abstractNodes);\n } else {\n return \"<\".concat(tag, \" \").concat(joinAttributes(attributes), \">\").concat(children.map(toHtml).join(''), \"\");\n }\n}\n\nvar noop$2 = function noop() {};\n\nfunction isWatched(node) {\n var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null;\n return typeof i2svg === 'string';\n}\n\nfunction getMutator() {\n if (config.autoReplaceSvg === true) {\n return mutators.replace;\n }\n\n var mutator = mutators[config.autoReplaceSvg];\n return mutator || mutators.replace;\n}\n\nvar mutators = {\n replace: function replace(mutation) {\n var node = mutation[0];\n var abstract = mutation[1];\n var newOuterHTML = abstract.map(function (a) {\n return toHtml(a);\n }).join('\\n');\n\n if (node.parentNode && node.outerHTML) {\n node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? \"\") : '');\n } else if (node.parentNode) {\n var newNode = document.createElement('span');\n node.parentNode.replaceChild(newNode, node);\n newNode.outerHTML = newOuterHTML;\n }\n },\n nest: function nest(mutation) {\n var node = mutation[0];\n var abstract = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it.\n // Short-circuit to the standard replacement\n\n if (~classArray(node).indexOf(config.replacementClass)) {\n return mutators.replace(mutation);\n }\n\n var forSvg = new RegExp(\"\".concat(config.familyPrefix, \"-.*\"));\n delete abstract[0].attributes.style;\n delete abstract[0].attributes.id;\n var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) {\n if (cls === config.replacementClass || cls.match(forSvg)) {\n acc.toSvg.push(cls);\n } else {\n acc.toNode.push(cls);\n }\n\n return acc;\n }, {\n toNode: [],\n toSvg: []\n });\n abstract[0].attributes.class = splitClasses.toSvg.join(' ');\n var newInnerHTML = abstract.map(function (a) {\n return toHtml(a);\n }).join('\\n');\n node.setAttribute('class', splitClasses.toNode.join(' '));\n node.setAttribute(DATA_FA_I2SVG, '');\n node.innerHTML = newInnerHTML;\n }\n};\n\nfunction performOperationSync(op) {\n op();\n}\n\nfunction perform(mutations, callback) {\n var callbackFunction = typeof callback === 'function' ? callback : noop$2;\n\n if (mutations.length === 0) {\n callbackFunction();\n } else {\n var frame = performOperationSync;\n\n if (config.mutateApproach === MUTATION_APPROACH_ASYNC) {\n frame = WINDOW.requestAnimationFrame || performOperationSync;\n }\n\n frame(function () {\n var mutator = getMutator();\n var mark = perf.begin('mutate');\n mutations.map(mutator);\n mark();\n callbackFunction();\n });\n }\n}\nvar disabled = false;\nfunction disableObservation() {\n disabled = true;\n}\nfunction enableObservation() {\n disabled = false;\n}\nvar mo = null;\nfunction observe(options) {\n if (!MUTATION_OBSERVER) {\n return;\n }\n\n if (!config.observeMutations) {\n return;\n }\n\n var treeCallback = options.treeCallback,\n nodeCallback = options.nodeCallback,\n pseudoElementsCallback = options.pseudoElementsCallback,\n _options$observeMutat = options.observeMutationsRoot,\n observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat;\n mo = new MUTATION_OBSERVER(function (objects) {\n if (disabled) return;\n toArray(objects).forEach(function (mutationRecord) {\n if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) {\n if (config.searchPseudoElements) {\n pseudoElementsCallback(mutationRecord.target);\n }\n\n treeCallback(mutationRecord.target);\n }\n\n if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) {\n pseudoElementsCallback(mutationRecord.target.parentNode);\n }\n\n if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) {\n if (mutationRecord.attributeName === 'class') {\n var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)),\n prefix = _getCanonicalIcon.prefix,\n iconName = _getCanonicalIcon.iconName;\n\n if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix);\n if (iconName) mutationRecord.target.setAttribute('data-icon', iconName);\n } else {\n nodeCallback(mutationRecord.target);\n }\n }\n });\n });\n if (!IS_DOM) return;\n mo.observe(observeMutationsRoot, {\n childList: true,\n attributes: true,\n characterData: true,\n subtree: true\n });\n}\nfunction disconnect() {\n if (!mo) return;\n mo.disconnect();\n}\n\nfunction styleParser (node) {\n var style = node.getAttribute('style');\n var val = [];\n\n if (style) {\n val = style.split(';').reduce(function (acc, style) {\n var styles = style.split(':');\n var prop = styles[0];\n var value = styles.slice(1);\n\n if (prop && value.length > 0) {\n acc[prop] = value.join(':').trim();\n }\n\n return acc;\n }, {});\n }\n\n return val;\n}\n\nfunction classParser (node) {\n var existingPrefix = node.getAttribute('data-prefix');\n var existingIconName = node.getAttribute('data-icon');\n var innerText = node.innerText !== undefined ? node.innerText.trim() : '';\n var val = getCanonicalIcon(classArray(node));\n\n if (existingPrefix && existingIconName) {\n val.prefix = existingPrefix;\n val.iconName = existingIconName;\n }\n\n if (val.prefix && innerText.length > 1) {\n val.iconName = byLigature(val.prefix, node.innerText);\n } else if (val.prefix && innerText.length === 1) {\n val.iconName = byUnicode(val.prefix, toHex(node.innerText));\n }\n\n return val;\n}\n\nvar parseTransformString = function parseTransformString(transformString) {\n var transform = {\n size: 16,\n x: 0,\n y: 0,\n flipX: false,\n flipY: false,\n rotate: 0\n };\n\n if (!transformString) {\n return transform;\n } else {\n return transformString.toLowerCase().split(' ').reduce(function (acc, n) {\n var parts = n.toLowerCase().split('-');\n var first = parts[0];\n var rest = parts.slice(1).join('-');\n\n if (first && rest === 'h') {\n acc.flipX = true;\n return acc;\n }\n\n if (first && rest === 'v') {\n acc.flipY = true;\n return acc;\n }\n\n rest = parseFloat(rest);\n\n if (isNaN(rest)) {\n return acc;\n }\n\n switch (first) {\n case 'grow':\n acc.size = acc.size + rest;\n break;\n\n case 'shrink':\n acc.size = acc.size - rest;\n break;\n\n case 'left':\n acc.x = acc.x - rest;\n break;\n\n case 'right':\n acc.x = acc.x + rest;\n break;\n\n case 'up':\n acc.y = acc.y - rest;\n break;\n\n case 'down':\n acc.y = acc.y + rest;\n break;\n\n case 'rotate':\n acc.rotate = acc.rotate + rest;\n break;\n }\n\n return acc;\n }, transform);\n }\n};\nfunction transformParser (node) {\n return parseTransformString(node.getAttribute('data-fa-transform'));\n}\n\nfunction symbolParser (node) {\n var symbol = node.getAttribute('data-fa-symbol');\n return symbol === null ? false : symbol === '' ? true : symbol;\n}\n\nfunction attributesParser (node) {\n var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) {\n if (acc.name !== 'class' && acc.name !== 'style') {\n acc[attr.name] = attr.value;\n }\n\n return acc;\n }, {});\n var title = node.getAttribute('title');\n var titleId = node.getAttribute('data-fa-title-id');\n\n if (config.autoA11y) {\n if (title) {\n extraAttributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n } else {\n extraAttributes['aria-hidden'] = 'true';\n extraAttributes['focusable'] = 'false';\n }\n }\n\n return extraAttributes;\n}\n\nfunction maskParser (node) {\n var mask = node.getAttribute('data-fa-mask');\n\n if (!mask) {\n return emptyCanonicalIcon();\n } else {\n return getCanonicalIcon(mask.split(' ').map(function (i) {\n return i.trim();\n }));\n }\n}\n\nfunction blankMeta() {\n return {\n iconName: null,\n title: null,\n titleId: null,\n prefix: null,\n transform: meaninglessTransform,\n symbol: false,\n mask: null,\n maskId: null,\n extra: {\n classes: [],\n styles: {},\n attributes: {}\n }\n };\n}\nfunction parseMeta(node) {\n var _classParser = classParser(node),\n iconName = _classParser.iconName,\n prefix = _classParser.prefix,\n extraClasses = _classParser.rest;\n\n var extraStyles = styleParser(node);\n var transform = transformParser(node);\n var symbol = symbolParser(node);\n var extraAttributes = attributesParser(node);\n var mask = maskParser(node);\n return {\n iconName: iconName,\n title: node.getAttribute('title'),\n titleId: node.getAttribute('data-fa-title-id'),\n prefix: prefix,\n transform: transform,\n symbol: symbol,\n mask: mask,\n maskId: node.getAttribute('data-fa-mask-id'),\n extra: {\n classes: extraClasses,\n styles: extraStyles,\n attributes: extraAttributes\n }\n };\n}\n\nfunction MissingIcon(error) {\n this.name = 'MissingIcon';\n this.message = error || 'Icon unavailable';\n this.stack = new Error().stack;\n}\nMissingIcon.prototype = Object.create(Error.prototype);\nMissingIcon.prototype.constructor = MissingIcon;\n\nvar FILL = {\n fill: 'currentColor'\n};\nvar ANIMATION_BASE = {\n attributeType: 'XML',\n repeatCount: 'indefinite',\n dur: '2s'\n};\nvar RING = {\n tag: 'path',\n attributes: _objectSpread({}, FILL, {\n d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z'\n })\n};\n\nvar OPACITY_ANIMATE = _objectSpread({}, ANIMATION_BASE, {\n attributeName: 'opacity'\n});\n\nvar DOT = {\n tag: 'circle',\n attributes: _objectSpread({}, FILL, {\n cx: '256',\n cy: '364',\n r: '28'\n }),\n children: [{\n tag: 'animate',\n attributes: _objectSpread({}, ANIMATION_BASE, {\n attributeName: 'r',\n values: '28;14;28;28;14;28;'\n })\n }, {\n tag: 'animate',\n attributes: _objectSpread({}, OPACITY_ANIMATE, {\n values: '1;0;1;1;0;1;'\n })\n }]\n};\nvar QUESTION = {\n tag: 'path',\n attributes: _objectSpread({}, FILL, {\n opacity: '1',\n d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z'\n }),\n children: [{\n tag: 'animate',\n attributes: _objectSpread({}, OPACITY_ANIMATE, {\n values: '1;0;0;0;0;1;'\n })\n }]\n};\nvar EXCLAMATION = {\n tag: 'path',\n attributes: _objectSpread({}, FILL, {\n opacity: '0',\n d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z'\n }),\n children: [{\n tag: 'animate',\n attributes: _objectSpread({}, OPACITY_ANIMATE, {\n values: '0;0;1;1;0;0;'\n })\n }]\n};\nvar missing = {\n tag: 'g',\n children: [RING, DOT, QUESTION, EXCLAMATION]\n};\n\nvar styles$2 = namespace.styles;\nfunction asFoundIcon(icon) {\n var width = icon[0];\n var height = icon[1];\n\n var _icon$slice = icon.slice(4),\n _icon$slice2 = _slicedToArray(_icon$slice, 1),\n vectorData = _icon$slice2[0];\n\n var element = null;\n\n if (Array.isArray(vectorData)) {\n element = {\n tag: 'g',\n attributes: {\n class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.GROUP)\n },\n children: [{\n tag: 'path',\n attributes: {\n class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.SECONDARY),\n fill: 'currentColor',\n d: vectorData[0]\n }\n }, {\n tag: 'path',\n attributes: {\n class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.PRIMARY),\n fill: 'currentColor',\n d: vectorData[1]\n }\n }]\n };\n } else {\n element = {\n tag: 'path',\n attributes: {\n fill: 'currentColor',\n d: vectorData\n }\n };\n }\n\n return {\n found: true,\n width: width,\n height: height,\n icon: element\n };\n}\nfunction findIcon(iconName, prefix) {\n return new picked(function (resolve, reject) {\n var val = {\n found: false,\n width: 512,\n height: 512,\n icon: missing\n };\n\n if (iconName && prefix && styles$2[prefix] && styles$2[prefix][iconName]) {\n var icon = styles$2[prefix][iconName];\n return resolve(asFoundIcon(icon));\n }\n\n var headers = {};\n\n if (_typeof(WINDOW.FontAwesomeKitConfig) === 'object' && typeof window.FontAwesomeKitConfig.token === 'string') {\n headers['fa-kit-token'] = WINDOW.FontAwesomeKitConfig.token;\n }\n\n if (iconName && prefix && !config.showMissingIcons) {\n reject(new MissingIcon(\"Icon is missing for prefix \".concat(prefix, \" with icon name \").concat(iconName)));\n } else {\n resolve(val);\n }\n });\n}\n\nvar styles$3 = namespace.styles;\n\nfunction generateSvgReplacementMutation(node, nodeMeta) {\n var iconName = nodeMeta.iconName,\n title = nodeMeta.title,\n titleId = nodeMeta.titleId,\n prefix = nodeMeta.prefix,\n transform = nodeMeta.transform,\n symbol = nodeMeta.symbol,\n mask = nodeMeta.mask,\n maskId = nodeMeta.maskId,\n extra = nodeMeta.extra;\n return new picked(function (resolve, reject) {\n picked.all([findIcon(iconName, prefix), findIcon(mask.iconName, mask.prefix)]).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n main = _ref2[0],\n mask = _ref2[1];\n\n resolve([node, makeInlineSvgAbstract({\n icons: {\n main: main,\n mask: mask\n },\n prefix: prefix,\n iconName: iconName,\n transform: transform,\n symbol: symbol,\n mask: mask,\n maskId: maskId,\n title: title,\n titleId: titleId,\n extra: extra,\n watchable: true\n })]);\n });\n });\n}\n\nfunction generateLayersText(node, nodeMeta) {\n var title = nodeMeta.title,\n transform = nodeMeta.transform,\n extra = nodeMeta.extra;\n var width = null;\n var height = null;\n\n if (IS_IE) {\n var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10);\n var boundingClientRect = node.getBoundingClientRect();\n width = boundingClientRect.width / computedFontSize;\n height = boundingClientRect.height / computedFontSize;\n }\n\n if (config.autoA11y && !title) {\n extra.attributes['aria-hidden'] = 'true';\n }\n\n return picked.resolve([node, makeLayersTextAbstract({\n content: node.innerHTML,\n width: width,\n height: height,\n transform: transform,\n title: title,\n extra: extra,\n watchable: true\n })]);\n}\n\nfunction generateMutation(node) {\n var nodeMeta = parseMeta(node);\n\n if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) {\n return generateLayersText(node, nodeMeta);\n } else {\n return generateSvgReplacementMutation(node, nodeMeta);\n }\n}\n\nfunction onTree(root) {\n var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n if (!IS_DOM) return;\n var htmlClassList = DOCUMENT.documentElement.classList;\n\n var hclAdd = function hclAdd(suffix) {\n return htmlClassList.add(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n };\n\n var hclRemove = function hclRemove(suffix) {\n return htmlClassList.remove(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n };\n\n var prefixes = config.autoFetchSvg ? Object.keys(PREFIX_TO_STYLE) : Object.keys(styles$3);\n var prefixesDomQuery = [\".\".concat(LAYERS_TEXT_CLASSNAME, \":not([\").concat(DATA_FA_I2SVG, \"])\")].concat(prefixes.map(function (p) {\n return \".\".concat(p, \":not([\").concat(DATA_FA_I2SVG, \"])\");\n })).join(', ');\n\n if (prefixesDomQuery.length === 0) {\n return;\n }\n\n var candidates = [];\n\n try {\n candidates = toArray(root.querySelectorAll(prefixesDomQuery));\n } catch (e) {// noop\n }\n\n if (candidates.length > 0) {\n hclAdd('pending');\n hclRemove('complete');\n } else {\n return;\n }\n\n var mark = perf.begin('onTree');\n var mutations = candidates.reduce(function (acc, node) {\n try {\n var mutation = generateMutation(node);\n\n if (mutation) {\n acc.push(mutation);\n }\n } catch (e) {\n if (!PRODUCTION) {\n if (e instanceof MissingIcon) {\n console.error(e);\n }\n }\n }\n\n return acc;\n }, []);\n return new picked(function (resolve, reject) {\n picked.all(mutations).then(function (resolvedMutations) {\n perform(resolvedMutations, function () {\n hclAdd('active');\n hclAdd('complete');\n hclRemove('pending');\n if (typeof callback === 'function') callback();\n mark();\n resolve();\n });\n }).catch(function () {\n mark();\n reject();\n });\n });\n}\nfunction onNode(node) {\n var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n generateMutation(node).then(function (mutation) {\n if (mutation) {\n perform([mutation], callback);\n }\n });\n}\n\nfunction replaceForPosition(node, position) {\n var pendingAttribute = \"\".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-'));\n return new picked(function (resolve, reject) {\n if (node.getAttribute(pendingAttribute) !== null) {\n // This node is already being processed\n return resolve();\n }\n\n var children = toArray(node.children);\n var alreadyProcessedPseudoElement = children.filter(function (c) {\n return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position;\n })[0];\n var styles = WINDOW.getComputedStyle(node, position);\n var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN);\n var fontWeight = styles.getPropertyValue('font-weight');\n var content = styles.getPropertyValue('content');\n\n if (alreadyProcessedPseudoElement && !fontFamily) {\n // If we've already processed it but the current computed style does not result in a font-family,\n // that probably means that a class name that was previously present to make the icon has been\n // removed. So we now should delete the icon.\n node.removeChild(alreadyProcessedPseudoElement);\n return resolve();\n } else if (fontFamily && content !== 'none' && content !== '') {\n var prefix = ~['Solid', 'Regular', 'Light', 'Duotone', 'Brands'].indexOf(fontFamily[1]) ? STYLE_TO_PREFIX[fontFamily[1].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[fontWeight];\n var hexValue = toHex(content.length === 3 ? content.substr(1, 1) : content);\n var iconName = byUnicode(prefix, hexValue);\n var iconIdentifier = iconName; // Only convert the pseudo element in this :before/:after position into an icon if we haven't\n // already done so with the same prefix and iconName\n\n if (iconName && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) {\n node.setAttribute(pendingAttribute, iconIdentifier);\n\n if (alreadyProcessedPseudoElement) {\n // Delete the old one, since we're replacing it with a new one\n node.removeChild(alreadyProcessedPseudoElement);\n }\n\n var meta = blankMeta();\n var extra = meta.extra;\n extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position;\n findIcon(iconName, prefix).then(function (main) {\n var abstract = makeInlineSvgAbstract(_objectSpread({}, meta, {\n icons: {\n main: main,\n mask: emptyCanonicalIcon()\n },\n prefix: prefix,\n iconName: iconIdentifier,\n extra: extra,\n watchable: true\n }));\n var element = DOCUMENT.createElement('svg');\n\n if (position === ':before') {\n node.insertBefore(element, node.firstChild);\n } else {\n node.appendChild(element);\n }\n\n element.outerHTML = abstract.map(function (a) {\n return toHtml(a);\n }).join('\\n');\n node.removeAttribute(pendingAttribute);\n resolve();\n }).catch(reject);\n } else {\n resolve();\n }\n } else {\n resolve();\n }\n });\n}\n\nfunction replace(node) {\n return picked.all([replaceForPosition(node, ':before'), replaceForPosition(node, ':after')]);\n}\n\nfunction processable(node) {\n return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg');\n}\n\nfunction searchPseudoElements (root) {\n if (!IS_DOM) return;\n return new picked(function (resolve, reject) {\n var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace);\n var end = perf.begin('searchPseudoElements');\n disableObservation();\n picked.all(operations).then(function () {\n end();\n enableObservation();\n resolve();\n }).catch(function () {\n end();\n enableObservation();\n reject();\n });\n });\n}\n\nvar baseStyles = \"svg:not(:root).svg-inline--fa {\\n overflow: visible;\\n}\\n\\n.svg-inline--fa {\\n display: inline-block;\\n font-size: inherit;\\n height: 1em;\\n overflow: visible;\\n vertical-align: -0.125em;\\n}\\n.svg-inline--fa.fa-lg {\\n vertical-align: -0.225em;\\n}\\n.svg-inline--fa.fa-w-1 {\\n width: 0.0625em;\\n}\\n.svg-inline--fa.fa-w-2 {\\n width: 0.125em;\\n}\\n.svg-inline--fa.fa-w-3 {\\n width: 0.1875em;\\n}\\n.svg-inline--fa.fa-w-4 {\\n width: 0.25em;\\n}\\n.svg-inline--fa.fa-w-5 {\\n width: 0.3125em;\\n}\\n.svg-inline--fa.fa-w-6 {\\n width: 0.375em;\\n}\\n.svg-inline--fa.fa-w-7 {\\n width: 0.4375em;\\n}\\n.svg-inline--fa.fa-w-8 {\\n width: 0.5em;\\n}\\n.svg-inline--fa.fa-w-9 {\\n width: 0.5625em;\\n}\\n.svg-inline--fa.fa-w-10 {\\n width: 0.625em;\\n}\\n.svg-inline--fa.fa-w-11 {\\n width: 0.6875em;\\n}\\n.svg-inline--fa.fa-w-12 {\\n width: 0.75em;\\n}\\n.svg-inline--fa.fa-w-13 {\\n width: 0.8125em;\\n}\\n.svg-inline--fa.fa-w-14 {\\n width: 0.875em;\\n}\\n.svg-inline--fa.fa-w-15 {\\n width: 0.9375em;\\n}\\n.svg-inline--fa.fa-w-16 {\\n width: 1em;\\n}\\n.svg-inline--fa.fa-w-17 {\\n width: 1.0625em;\\n}\\n.svg-inline--fa.fa-w-18 {\\n width: 1.125em;\\n}\\n.svg-inline--fa.fa-w-19 {\\n width: 1.1875em;\\n}\\n.svg-inline--fa.fa-w-20 {\\n width: 1.25em;\\n}\\n.svg-inline--fa.fa-pull-left {\\n margin-right: 0.3em;\\n width: auto;\\n}\\n.svg-inline--fa.fa-pull-right {\\n margin-left: 0.3em;\\n width: auto;\\n}\\n.svg-inline--fa.fa-border {\\n height: 1.5em;\\n}\\n.svg-inline--fa.fa-li {\\n width: 2em;\\n}\\n.svg-inline--fa.fa-fw {\\n width: 1.25em;\\n}\\n\\n.fa-layers svg.svg-inline--fa {\\n bottom: 0;\\n left: 0;\\n margin: auto;\\n position: absolute;\\n right: 0;\\n top: 0;\\n}\\n\\n.fa-layers {\\n display: inline-block;\\n height: 1em;\\n position: relative;\\n text-align: center;\\n vertical-align: -0.125em;\\n width: 1em;\\n}\\n.fa-layers svg.svg-inline--fa {\\n -webkit-transform-origin: center center;\\n transform-origin: center center;\\n}\\n\\n.fa-layers-counter, .fa-layers-text {\\n display: inline-block;\\n position: absolute;\\n text-align: center;\\n}\\n\\n.fa-layers-text {\\n left: 50%;\\n top: 50%;\\n -webkit-transform: translate(-50%, -50%);\\n transform: translate(-50%, -50%);\\n -webkit-transform-origin: center center;\\n transform-origin: center center;\\n}\\n\\n.fa-layers-counter {\\n background-color: #ff253a;\\n border-radius: 1em;\\n -webkit-box-sizing: border-box;\\n box-sizing: border-box;\\n color: #fff;\\n height: 1.5em;\\n line-height: 1;\\n max-width: 5em;\\n min-width: 1.5em;\\n overflow: hidden;\\n padding: 0.25em;\\n right: 0;\\n text-overflow: ellipsis;\\n top: 0;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: top right;\\n transform-origin: top right;\\n}\\n\\n.fa-layers-bottom-right {\\n bottom: 0;\\n right: 0;\\n top: auto;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: bottom right;\\n transform-origin: bottom right;\\n}\\n\\n.fa-layers-bottom-left {\\n bottom: 0;\\n left: 0;\\n right: auto;\\n top: auto;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: bottom left;\\n transform-origin: bottom left;\\n}\\n\\n.fa-layers-top-right {\\n right: 0;\\n top: 0;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: top right;\\n transform-origin: top right;\\n}\\n\\n.fa-layers-top-left {\\n left: 0;\\n right: auto;\\n top: 0;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: top left;\\n transform-origin: top left;\\n}\\n\\n.fa-lg {\\n font-size: 1.3333333333em;\\n line-height: 0.75em;\\n vertical-align: -0.0667em;\\n}\\n\\n.fa-xs {\\n font-size: 0.75em;\\n}\\n\\n.fa-sm {\\n font-size: 0.875em;\\n}\\n\\n.fa-1x {\\n font-size: 1em;\\n}\\n\\n.fa-2x {\\n font-size: 2em;\\n}\\n\\n.fa-3x {\\n font-size: 3em;\\n}\\n\\n.fa-4x {\\n font-size: 4em;\\n}\\n\\n.fa-5x {\\n font-size: 5em;\\n}\\n\\n.fa-6x {\\n font-size: 6em;\\n}\\n\\n.fa-7x {\\n font-size: 7em;\\n}\\n\\n.fa-8x {\\n font-size: 8em;\\n}\\n\\n.fa-9x {\\n font-size: 9em;\\n}\\n\\n.fa-10x {\\n font-size: 10em;\\n}\\n\\n.fa-fw {\\n text-align: center;\\n width: 1.25em;\\n}\\n\\n.fa-ul {\\n list-style-type: none;\\n margin-left: 2.5em;\\n padding-left: 0;\\n}\\n.fa-ul > li {\\n position: relative;\\n}\\n\\n.fa-li {\\n left: -2em;\\n position: absolute;\\n text-align: center;\\n width: 2em;\\n line-height: inherit;\\n}\\n\\n.fa-border {\\n border: solid 0.08em #eee;\\n border-radius: 0.1em;\\n padding: 0.2em 0.25em 0.15em;\\n}\\n\\n.fa-pull-left {\\n float: left;\\n}\\n\\n.fa-pull-right {\\n float: right;\\n}\\n\\n.fa.fa-pull-left,\\n.fas.fa-pull-left,\\n.far.fa-pull-left,\\n.fal.fa-pull-left,\\n.fab.fa-pull-left {\\n margin-right: 0.3em;\\n}\\n.fa.fa-pull-right,\\n.fas.fa-pull-right,\\n.far.fa-pull-right,\\n.fal.fa-pull-right,\\n.fab.fa-pull-right {\\n margin-left: 0.3em;\\n}\\n\\n.fa-spin {\\n -webkit-animation: fa-spin 2s infinite linear;\\n animation: fa-spin 2s infinite linear;\\n}\\n\\n.fa-pulse {\\n -webkit-animation: fa-spin 1s infinite steps(8);\\n animation: fa-spin 1s infinite steps(8);\\n}\\n\\n@-webkit-keyframes fa-spin {\\n 0% {\\n -webkit-transform: rotate(0deg);\\n transform: rotate(0deg);\\n }\\n 100% {\\n -webkit-transform: rotate(360deg);\\n transform: rotate(360deg);\\n }\\n}\\n\\n@keyframes fa-spin {\\n 0% {\\n -webkit-transform: rotate(0deg);\\n transform: rotate(0deg);\\n }\\n 100% {\\n -webkit-transform: rotate(360deg);\\n transform: rotate(360deg);\\n }\\n}\\n.fa-rotate-90 {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\\\";\\n -webkit-transform: rotate(90deg);\\n transform: rotate(90deg);\\n}\\n\\n.fa-rotate-180 {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\\\";\\n -webkit-transform: rotate(180deg);\\n transform: rotate(180deg);\\n}\\n\\n.fa-rotate-270 {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\\\";\\n -webkit-transform: rotate(270deg);\\n transform: rotate(270deg);\\n}\\n\\n.fa-flip-horizontal {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\\\";\\n -webkit-transform: scale(-1, 1);\\n transform: scale(-1, 1);\\n}\\n\\n.fa-flip-vertical {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\\\";\\n -webkit-transform: scale(1, -1);\\n transform: scale(1, -1);\\n}\\n\\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\\\";\\n -webkit-transform: scale(-1, -1);\\n transform: scale(-1, -1);\\n}\\n\\n:root .fa-rotate-90,\\n:root .fa-rotate-180,\\n:root .fa-rotate-270,\\n:root .fa-flip-horizontal,\\n:root .fa-flip-vertical,\\n:root .fa-flip-both {\\n -webkit-filter: none;\\n filter: none;\\n}\\n\\n.fa-stack {\\n display: inline-block;\\n height: 2em;\\n position: relative;\\n width: 2.5em;\\n}\\n\\n.fa-stack-1x,\\n.fa-stack-2x {\\n bottom: 0;\\n left: 0;\\n margin: auto;\\n position: absolute;\\n right: 0;\\n top: 0;\\n}\\n\\n.svg-inline--fa.fa-stack-1x {\\n height: 1em;\\n width: 1.25em;\\n}\\n.svg-inline--fa.fa-stack-2x {\\n height: 2em;\\n width: 2.5em;\\n}\\n\\n.fa-inverse {\\n color: #fff;\\n}\\n\\n.sr-only {\\n border: 0;\\n clip: rect(0, 0, 0, 0);\\n height: 1px;\\n margin: -1px;\\n overflow: hidden;\\n padding: 0;\\n position: absolute;\\n width: 1px;\\n}\\n\\n.sr-only-focusable:active, .sr-only-focusable:focus {\\n clip: auto;\\n height: auto;\\n margin: 0;\\n overflow: visible;\\n position: static;\\n width: auto;\\n}\\n\\n.svg-inline--fa .fa-primary {\\n fill: var(--fa-primary-color, currentColor);\\n opacity: 1;\\n opacity: var(--fa-primary-opacity, 1);\\n}\\n\\n.svg-inline--fa .fa-secondary {\\n fill: var(--fa-secondary-color, currentColor);\\n opacity: 0.4;\\n opacity: var(--fa-secondary-opacity, 0.4);\\n}\\n\\n.svg-inline--fa.fa-swap-opacity .fa-primary {\\n opacity: 0.4;\\n opacity: var(--fa-secondary-opacity, 0.4);\\n}\\n\\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\\n opacity: 1;\\n opacity: var(--fa-primary-opacity, 1);\\n}\\n\\n.svg-inline--fa mask .fa-primary,\\n.svg-inline--fa mask .fa-secondary {\\n fill: black;\\n}\\n\\n.fad.fa-inverse {\\n color: #fff;\\n}\";\n\nfunction css () {\n var dfp = DEFAULT_FAMILY_PREFIX;\n var drc = DEFAULT_REPLACEMENT_CLASS;\n var fp = config.familyPrefix;\n var rc = config.replacementClass;\n var s = baseStyles;\n\n if (fp !== dfp || rc !== drc) {\n var dPatt = new RegExp(\"\\\\.\".concat(dfp, \"\\\\-\"), 'g');\n var customPropPatt = new RegExp(\"\\\\--\".concat(dfp, \"\\\\-\"), 'g');\n var rPatt = new RegExp(\"\\\\.\".concat(drc), 'g');\n s = s.replace(dPatt, \".\".concat(fp, \"-\")).replace(customPropPatt, \"--\".concat(fp, \"-\")).replace(rPatt, \".\".concat(rc));\n }\n\n return s;\n}\n\nvar Library =\n/*#__PURE__*/\nfunction () {\n function Library() {\n _classCallCheck(this, Library);\n\n this.definitions = {};\n }\n\n _createClass(Library, [{\n key: \"add\",\n value: function add() {\n var _this = this;\n\n for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) {\n definitions[_key] = arguments[_key];\n }\n\n var additions = definitions.reduce(this._pullDefinitions, {});\n Object.keys(additions).forEach(function (key) {\n _this.definitions[key] = _objectSpread({}, _this.definitions[key] || {}, additions[key]);\n defineIcons(key, additions[key]);\n build();\n });\n }\n }, {\n key: \"reset\",\n value: function reset() {\n this.definitions = {};\n }\n }, {\n key: \"_pullDefinitions\",\n value: function _pullDefinitions(additions, definition) {\n var normalized = definition.prefix && definition.iconName && definition.icon ? {\n 0: definition\n } : definition;\n Object.keys(normalized).map(function (key) {\n var _normalized$key = normalized[key],\n prefix = _normalized$key.prefix,\n iconName = _normalized$key.iconName,\n icon = _normalized$key.icon;\n if (!additions[prefix]) additions[prefix] = {};\n additions[prefix][iconName] = icon;\n });\n return additions;\n }\n }]);\n\n return Library;\n}();\n\nfunction ensureCss() {\n if (config.autoAddCss && !_cssInserted) {\n insertCss(css());\n\n _cssInserted = true;\n }\n}\n\nfunction apiObject(val, abstractCreator) {\n Object.defineProperty(val, 'abstract', {\n get: abstractCreator\n });\n Object.defineProperty(val, 'html', {\n get: function get() {\n return val.abstract.map(function (a) {\n return toHtml(a);\n });\n }\n });\n Object.defineProperty(val, 'node', {\n get: function get() {\n if (!IS_DOM) return;\n var container = DOCUMENT.createElement('div');\n container.innerHTML = val.html;\n return container.children;\n }\n });\n return val;\n}\n\nfunction findIconDefinition(iconLookup) {\n var _iconLookup$prefix = iconLookup.prefix,\n prefix = _iconLookup$prefix === void 0 ? 'fa' : _iconLookup$prefix,\n iconName = iconLookup.iconName;\n if (!iconName) return;\n return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName);\n}\n\nfunction resolveIcons(next) {\n return function (maybeIconDefinition) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {});\n var mask = params.mask;\n\n if (mask) {\n mask = (mask || {}).icon ? mask : findIconDefinition(mask || {});\n }\n\n return next(iconDefinition, _objectSpread({}, params, {\n mask: mask\n }));\n };\n}\n\nvar library = new Library();\nvar noAuto = function noAuto() {\n config.autoReplaceSvg = false;\n config.observeMutations = false;\n disconnect();\n};\nvar _cssInserted = false;\nvar dom = {\n i2svg: function i2svg() {\n var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n if (IS_DOM) {\n ensureCss();\n var _params$node = params.node,\n node = _params$node === void 0 ? DOCUMENT : _params$node,\n _params$callback = params.callback,\n callback = _params$callback === void 0 ? function () {} : _params$callback;\n\n if (config.searchPseudoElements) {\n searchPseudoElements(node);\n }\n\n return onTree(node, callback);\n } else {\n return picked.reject('Operation requires a DOM of some kind.');\n }\n },\n css: css,\n insertCss: function insertCss$$1() {\n if (!_cssInserted) {\n insertCss(css());\n\n _cssInserted = true;\n }\n },\n watch: function watch() {\n var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var autoReplaceSvgRoot = params.autoReplaceSvgRoot,\n observeMutationsRoot = params.observeMutationsRoot;\n\n if (config.autoReplaceSvg === false) {\n config.autoReplaceSvg = true;\n }\n\n config.observeMutations = true;\n domready(function () {\n autoReplace({\n autoReplaceSvgRoot: autoReplaceSvgRoot\n });\n observe({\n treeCallback: onTree,\n nodeCallback: onNode,\n pseudoElementsCallback: searchPseudoElements,\n observeMutationsRoot: observeMutationsRoot\n });\n });\n }\n};\nvar parse = {\n transform: function transform(transformString) {\n return parseTransformString(transformString);\n }\n};\nvar icon = resolveIcons(function (iconDefinition) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$transform = params.transform,\n transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n _params$symbol = params.symbol,\n symbol = _params$symbol === void 0 ? false : _params$symbol,\n _params$mask = params.mask,\n mask = _params$mask === void 0 ? null : _params$mask,\n _params$maskId = params.maskId,\n maskId = _params$maskId === void 0 ? null : _params$maskId,\n _params$title = params.title,\n title = _params$title === void 0 ? null : _params$title,\n _params$titleId = params.titleId,\n titleId = _params$titleId === void 0 ? null : _params$titleId,\n _params$classes = params.classes,\n classes = _params$classes === void 0 ? [] : _params$classes,\n _params$attributes = params.attributes,\n attributes = _params$attributes === void 0 ? {} : _params$attributes,\n _params$styles = params.styles,\n styles = _params$styles === void 0 ? {} : _params$styles;\n if (!iconDefinition) return;\n var prefix = iconDefinition.prefix,\n iconName = iconDefinition.iconName,\n icon = iconDefinition.icon;\n return apiObject(_objectSpread({\n type: 'icon'\n }, iconDefinition), function () {\n ensureCss();\n\n if (config.autoA11y) {\n if (title) {\n attributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n } else {\n attributes['aria-hidden'] = 'true';\n attributes['focusable'] = 'false';\n }\n }\n\n return makeInlineSvgAbstract({\n icons: {\n main: asFoundIcon(icon),\n mask: mask ? asFoundIcon(mask.icon) : {\n found: false,\n width: null,\n height: null,\n icon: {}\n }\n },\n prefix: prefix,\n iconName: iconName,\n transform: _objectSpread({}, meaninglessTransform, transform),\n symbol: symbol,\n title: title,\n maskId: maskId,\n titleId: titleId,\n extra: {\n attributes: attributes,\n styles: styles,\n classes: classes\n }\n });\n });\n});\nvar text = function text(content) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$transform2 = params.transform,\n transform = _params$transform2 === void 0 ? meaninglessTransform : _params$transform2,\n _params$title2 = params.title,\n title = _params$title2 === void 0 ? null : _params$title2,\n _params$classes2 = params.classes,\n classes = _params$classes2 === void 0 ? [] : _params$classes2,\n _params$attributes2 = params.attributes,\n attributes = _params$attributes2 === void 0 ? {} : _params$attributes2,\n _params$styles2 = params.styles,\n styles = _params$styles2 === void 0 ? {} : _params$styles2;\n return apiObject({\n type: 'text',\n content: content\n }, function () {\n ensureCss();\n return makeLayersTextAbstract({\n content: content,\n transform: _objectSpread({}, meaninglessTransform, transform),\n title: title,\n extra: {\n attributes: attributes,\n styles: styles,\n classes: [\"\".concat(config.familyPrefix, \"-layers-text\")].concat(_toConsumableArray(classes))\n }\n });\n });\n};\nvar counter = function counter(content) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$title3 = params.title,\n title = _params$title3 === void 0 ? null : _params$title3,\n _params$classes3 = params.classes,\n classes = _params$classes3 === void 0 ? [] : _params$classes3,\n _params$attributes3 = params.attributes,\n attributes = _params$attributes3 === void 0 ? {} : _params$attributes3,\n _params$styles3 = params.styles,\n styles = _params$styles3 === void 0 ? {} : _params$styles3;\n return apiObject({\n type: 'counter',\n content: content\n }, function () {\n ensureCss();\n return makeLayersCounterAbstract({\n content: content.toString(),\n title: title,\n extra: {\n attributes: attributes,\n styles: styles,\n classes: [\"\".concat(config.familyPrefix, \"-layers-counter\")].concat(_toConsumableArray(classes))\n }\n });\n });\n};\nvar layer = function layer(assembler) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$classes4 = params.classes,\n classes = _params$classes4 === void 0 ? [] : _params$classes4;\n return apiObject({\n type: 'layer'\n }, function () {\n ensureCss();\n var children = [];\n assembler(function (args) {\n Array.isArray(args) ? args.map(function (a) {\n children = children.concat(a.abstract);\n }) : children = children.concat(args.abstract);\n });\n return [{\n tag: 'span',\n attributes: {\n class: [\"\".concat(config.familyPrefix, \"-layers\")].concat(_toConsumableArray(classes)).join(' ')\n },\n children: children\n }];\n });\n};\nvar api = {\n noAuto: noAuto,\n config: config,\n dom: dom,\n library: library,\n parse: parse,\n findIconDefinition: findIconDefinition,\n icon: icon,\n text: text,\n counter: counter,\n layer: layer,\n toHtml: toHtml\n};\n\nvar autoReplace = function autoReplace() {\n var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var _params$autoReplaceSv = params.autoReplaceSvgRoot,\n autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv;\n if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({\n node: autoReplaceSvgRoot\n });\n};\n\nexport { icon, noAuto, config, toHtml, layer, text, counter, library, dom, parse, findIconDefinition };\n","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'chevron-left';\nvar width = 320;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f053';\nvar svgPathData = 'M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faChevronLeft = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'envelope';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0e0';\nvar svgPathData = 'M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faEnvelope = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'fax';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1ac';\nvar svgPathData = 'M480 160V77.25a32 32 0 0 0-9.38-22.63L425.37 9.37A32 32 0 0 0 402.75 0H160a32 32 0 0 0-32 32v448a32 32 0 0 0 32 32h320a32 32 0 0 0 32-32V192a32 32 0 0 0-32-32zM288 432a16 16 0 0 1-16 16h-32a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16zm0-128a16 16 0 0 1-16 16h-32a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16zm128 128a16 16 0 0 1-16 16h-32a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16zm0-128a16 16 0 0 1-16 16h-32a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16zm0-112H192V64h160v48a16 16 0 0 0 16 16h48zM64 128H32a32 32 0 0 0-32 32v320a32 32 0 0 0 32 32h32a32 32 0 0 0 32-32V160a32 32 0 0 0-32-32z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faFax = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'info-circle';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f05a';\nvar svgPathData = 'M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faInfoCircle = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'map-marker-alt';\nvar width = 384;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f3c5';\nvar svgPathData = 'M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faMapMarkerAlt = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'minus';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f068';\nvar svgPathData = 'M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faMinus = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'phone';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f095';\nvar svgPathData = 'M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faPhone = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'plus';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f067';\nvar svgPathData = 'M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faPlus = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'search';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f002';\nvar svgPathData = 'M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faSearch = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'user';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f007';\nvar svgPathData = 'M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z';\n\nexports.definition = {\n prefix: prefix,\n iconName: iconName,\n icon: [\n width,\n height,\n ligatures,\n unicode,\n svgPathData\n ]};\n\nexports.faUser = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;","module.exports =\n/******/ (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\t__webpack_require__(1);\n\tmodule.exports = __webpack_require__(1);\n\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\r\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n\t})(function(){\r\n\r\n\t(function ($, undefined) {\r\n\t var kendo = window.kendo,\r\n\t ui = kendo.ui;\r\n\r\n\t if (ui && ui.ComboBox) {\r\n\t ui.ComboBox.requestData = function (selector) {\r\n\t var combobox = $(selector).data(\"kendoComboBox\");\r\n\r\n\t if (!combobox) {\r\n\t return;\r\n\t }\r\n\r\n\t var filter = combobox.dataSource.filter();\r\n\t var value = combobox.input.val();\r\n\r\n\t if (!filter || !filter.filters.length) {\r\n\t value = \"\";\r\n\t }\r\n\r\n\t return { text: value };\r\n\t };\r\n\t }\r\n\r\n\t})(window.kendo.jQuery);\r\n\r\n\t}, __webpack_require__(3));\r\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.aspnetmvc\");\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ })\n/******/ ]);","module.exports =\n/******/ (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\t__webpack_require__(4);\n\tmodule.exports = __webpack_require__(4);\n\n\n/***/ }),\n/* 1 */,\n/* 2 */,\n/* 3 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(5), __webpack_require__(6), __webpack_require__(7), __webpack_require__(8) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t escapeQuoteRegExp = /'/ig,\n\t extend = $.extend,\n\t isArray = $.isArray,\n\t isPlainObject = $.isPlainObject,\n\t POINT = \".\";\n\n\t function parameterMap(options, operation, serializationOptions) {\n\t var result = {};\n\n\t if (options.sort) {\n\t result[this.options.prefix + \"sort\"] = $.map(options.sort, function(sort) {\n\t return sort.field + \"-\" + sort.dir;\n\t }).join(\"~\");\n\n\t delete options.sort;\n\t } else {\n\t result[this.options.prefix + \"sort\"] = \"\";\n\t }\n\n\t if (options.page) {\n\t result[this.options.prefix + \"page\"] = options.page;\n\n\t delete options.page;\n\t }\n\n\t if (options.pageSize) {\n\t result[this.options.prefix + \"pageSize\"] = options.pageSize;\n\n\t delete options.pageSize;\n\t }\n\n\t if (options.group) {\n\t result[this.options.prefix + \"group\"] = $.map(options.group, function(group) {\n\t return group.field + \"-\" + group.dir;\n\t }).join(\"~\");\n\n\t delete options.group;\n\t } else {\n\t result[this.options.prefix + \"group\"] = \"\";\n\t }\n\n\t if (options.aggregate) {\n\t result[this.options.prefix + \"aggregate\"] = $.map(options.aggregate, function(aggregate) {\n\t return aggregate.field + \"-\" + aggregate.aggregate;\n\t }).join(\"~\");\n\n\t delete options.aggregate;\n\t }\n\n\t if (options.filter) {\n\t result[this.options.prefix + \"filter\"] = serializeFilter(options.filter, serializationOptions.encode);\n\n\t delete options.filter;\n\t } else {\n\t result[this.options.prefix + \"filter\"] = \"\";\n\t delete options.filter;\n\t }\n\n\t if (!options.groupPaging) {\n\t delete options.take;\n\t delete options.skip;\n\t }\n\n\t var serializer = new Serializer(serializationOptions);\n\t serializer.serialize(result, options, \"\");\n\n\t return result;\n\t }\n\n\t var Serializer = function(options) {\n\t options = options || {};\n\t this.culture = options.culture || kendo.culture();\n\t this.stringifyDates = options.stringifyDates;\n\t this.decimalSeparator = this.culture.numberFormat[POINT];\n\t };\n\n\t Serializer.prototype = Serializer.fn = {\n\t serialize: function(result, data, prefix) {\n\t var valuePrefix;\n\t for (var key in data) {\n\t valuePrefix = prefix ? prefix + \".\" + key : key;\n\t this.serializeField(result, data[key], data, key, valuePrefix);\n\t }\n\t },\n\n\t serializeField: function (result, value, data, key, prefix) {\n\t if (isArray(value)) {\n\t this.serializeArray(result, value, prefix);\n\t } else if (isPlainObject(value)) {\n\t this.serialize(result, value, prefix);\n\t } else {\n\t if (result[prefix] === undefined) {\n\t result[prefix] = data[key] = this.serializeValue(value);\n\t }\n\t }\n\t },\n\n\t serializeArray: function (result, data, prefix) {\n\t var value, key, valuePrefix;\n\t for (var sourceIndex = 0, destinationIndex = 0; sourceIndex < data.length; sourceIndex++) {\n\t value = data[sourceIndex];\n\t key = \"[\" + destinationIndex + \"]\";\n\t valuePrefix = prefix + key;\n\n\t this.serializeField(result, value, data, key, valuePrefix);\n\n\t destinationIndex++;\n\t }\n\t },\n\n\t serializeValue: function (value) {\n\t if (value instanceof Date) {\n\t if (this.stringifyDates) {\n\t value = kendo.stringify(value).replace(/\"/g, \"\");\n\t } else {\n\t value = kendo.toString(value, \"G\", this.culture.name);\n\t }\n\t } else if (typeof value === \"number\") {\n\t value = value.toString().replace(POINT, this.decimalSeparator);\n\t }\n\t return value;\n\t }\n\t };\n\n\t function serializeFilter(filter, encode) {\n\t if (filter.filters) {\n\t return $.map(filter.filters, function(f) {\n\t var hasChildren = f.filters && f.filters.length > 1,\n\t result = serializeFilter(f, encode);\n\n\t if (result && hasChildren) {\n\t result = \"(\" + result + \")\";\n\t }\n\n\t return result;\n\t }).join(\"~\" + filter.logic + \"~\");\n\t }\n\n\t if (filter.field) {\n\t return filter.field + \"~\" + filter.operator + \"~\" + encodeFilterValue(filter.value, encode);\n\t } else {\n\t return undefined;\n\t }\n\t }\n\n\t function encodeFilterValue(value, encode) {\n\t if (typeof value === \"string\") {\n\t if (value.indexOf('Date(') > -1) {\n\t value = new Date(parseInt(value.replace(/^\\/Date\\((.*?)\\)\\/$/, '$1'), 10));\n\t } else {\n\t value = value.replace(escapeQuoteRegExp, \"''\");\n\n\t if (encode) {\n\t value = encodeURIComponent(value);\n\t }\n\n\t return \"'\" + value + \"'\";\n\t }\n\t }\n\n\t if (value && value.getTime) {\n\t return \"datetime'\" + kendo.format(\"{0:yyyy-MM-ddTHH-mm-ss}\", value) + \"'\";\n\t }\n\t return value;\n\t }\n\n\t function valueOrDefault(value, defaultValue) {\n\t return typeof value !== \"undefined\" ? value : defaultValue;\n\t }\n\n\t function translateGroup(group) {\n\t var hasSubgroups = group.HasSubgroups || group.hasSubgroups || false;\n\t var items = group.Items || group.items;\n\t var itemCount = group.ItemCount || group.itemCount;\n\t var subgroupCount = group.SubgroupCount || group.subgroupCount;\n\n\t return {\n\t value: valueOrDefault(group.Key, valueOrDefault(group.key, group.value)),\n\t field: group.Member || group.member || group.field,\n\t hasSubgroups: hasSubgroups,\n\t aggregates: translateAggregate(group.Aggregates || group.aggregates),\n\t items: hasSubgroups ? $.map(items, translateGroup) : items,\n\t itemCount: itemCount,\n\t subgroupCount: subgroupCount,\n\t uid: kendo.guid()\n\t };\n\t }\n\n\t function translateAggregateResults(aggregate) {\n\t var obj = {};\n\t obj[aggregate.AggregateMethodName.toLowerCase()] = aggregate.Value;\n\n\t return obj;\n\t }\n\n\t function translateAggregate(aggregates) {\n\t var functionResult = {},\n\t key,\n\t functionName,\n\t aggregate;\n\n\t for (key in aggregates) {\n\t functionResult = {};\n\t aggregate = aggregates[key];\n\n\t for (functionName in aggregate) {\n\t functionResult[functionName.toLowerCase()] = aggregate[functionName];\n\t }\n\n\t aggregates[key] = functionResult;\n\t }\n\n\t return aggregates;\n\t }\n\n\t function convertAggregates(aggregates) {\n\t var idx, length, aggregate;\n\t var result = {};\n\n\t for (idx = 0, length = aggregates.length; idx < length; idx++) {\n\t aggregate = aggregates[idx];\n\t result[aggregate.Member] = extend(true, result[aggregate.Member], translateAggregateResults(aggregate));\n\t }\n\n\t return result;\n\t }\n\n\t extend(true, kendo.data, {\n\t schemas: {\n\t \"aspnetmvc-ajax\": {\n\t groups: function(data) {\n\t return $.map(this._dataAccessFunction(data), translateGroup);\n\t },\n\t aggregates: function(data) {\n\t data = data.d || data;\n\t var aggregates = data.AggregateResults || [];\n\n\t if (!$.isArray(aggregates)) {\n\t for (var key in aggregates) {\n\t aggregates[key] = convertAggregates(aggregates[key]);\n\t }\n\n\t return aggregates;\n\t }\n\n\t return convertAggregates(aggregates);\n\t }\n\t }\n\t }\n\t });\n\n\t extend(true, kendo.data, {\n\t transports: {\n\t \"aspnetmvc-ajax\": kendo.data.RemoteTransport.extend({\n\t init: function(options) {\n\t var that = this,\n\t stringifyDates = (options || {}).stringifyDates;\n\n\t kendo.data.RemoteTransport.fn.init.call(this,\n\t extend(true, {}, this.options, options, {\n\t parameterMap: function(options, operation) {\n\t return parameterMap.call(that, options, operation, {\n\t encode: false,\n\t stringifyDates: stringifyDates\n\t });\n\t }\n\t })\n\t );\n\t },\n\t read: function(options) {\n\t var data = this.options.data,\n\t url = this.options.read.url;\n\n\t if (isPlainObject(data)) {\n\t if (url) {\n\t this.options.data = null;\n\t }\n\n\t if (!data.Data.length && url) {\n\t kendo.data.RemoteTransport.fn.read.call(this, options);\n\t } else {\n\t options.success(data);\n\t }\n\t } else {\n\t kendo.data.RemoteTransport.fn.read.call(this, options);\n\t }\n\t },\n\t options: {\n\t read: {\n\t type: \"POST\"\n\t },\n\t update: {\n\t type: \"POST\"\n\t },\n\t create: {\n\t type: \"POST\"\n\t },\n\t destroy: {\n\t type: \"POST\"\n\t },\n\t parameterMap: parameterMap,\n\t prefix: \"\"\n\t }\n\t })\n\t }\n\t });\n\n\t extend(true, kendo.data, {\n\t schemas: {\n\t \"webapi\": kendo.data.schemas[\"aspnetmvc-ajax\"]\n\t }\n\t });\n\n\t extend(true, kendo.data, {\n\t transports: {\n\t \"webapi\": kendo.data.RemoteTransport.extend({\n\t init: function(options) {\n\t var that = this;\n\t var stringifyDates = (options || {}).stringifyDates;\n\t var culture = kendo.cultures[options.culture] || kendo.cultures[\"en-US\"];\n\n\t if (options.update) {\n\t var updateUrl = typeof options.update === \"string\" ? options.update : options.update.url;\n\n\t options.update = extend(options.update, {url: function (data) {\n\t return kendo.format(updateUrl, data[options.idField]);\n\t }});\n\t }\n\n\t if (options.destroy) {\n\t var destroyUrl = typeof options.destroy === \"string\" ? options.destroy : options.destroy.url;\n\n\t options.destroy = extend(options.destroy, {url: function (data) {\n\t return kendo.format(destroyUrl, data[options.idField]);\n\t }});\n\t }\n\n\t if(options.create && typeof options.create === \"string\") {\n\t options.create = {\n\t url: options.create\n\t };\n\t }\n\n\t kendo.data.RemoteTransport.fn.init.call(this,\n\t extend(true, {}, this.options, options, {\n\t parameterMap: function(options, operation) {\n\t return parameterMap.call(that, options, operation, {\n\t encode: false,\n\t stringifyDates: stringifyDates,\n\t culture: culture\n\t });\n\t }\n\t })\n\t );\n\t },\n\t read: function(options) {\n\t var data = this.options.data,\n\t url = this.options.read.url;\n\n\t if (isPlainObject(data)) {\n\t if (url) {\n\t this.options.data = null;\n\t }\n\n\t if (!data.Data.length && url) {\n\t kendo.data.RemoteTransport.fn.read.call(this, options);\n\t } else {\n\t options.success(data);\n\t }\n\t } else {\n\t kendo.data.RemoteTransport.fn.read.call(this, options);\n\t }\n\t },\n\t options: {\n\t read: {\n\t type: \"GET\"\n\t },\n\t update: {\n\t type: \"PUT\"\n\t },\n\t create: {\n\t type: \"POST\"\n\t },\n\t destroy: {\n\t type: \"DELETE\"\n\t },\n\t parameterMap: parameterMap,\n\t prefix: \"\"\n\t }\n\t })\n\t }\n\t });\n\n\t extend(true, kendo.data, {\n\t transports: {\n\t \"aspnetmvc-server\": kendo.data.RemoteTransport.extend({\n\t init: function(options) {\n\t var that = this;\n\n\t kendo.data.RemoteTransport.fn.init.call(this,\n\t extend(options, {\n\t parameterMap: function(options, operation) {\n\t return parameterMap.call(that, options, operation, {\n\t encode: true\n\t });\n\t }\n\t }\n\t ));\n\t },\n\t read: function(options) {\n\t var url,\n\t prefix = this.options.prefix,\n\t params = [prefix + \"sort\",\n\t prefix + \"page\",\n\t prefix + \"pageSize\",\n\t prefix + \"group\",\n\t prefix + \"aggregate\",\n\t prefix + \"filter\"],\n\t regExp = new RegExp(\"(\" + params.join('|') + \")=[^&]*&?\", \"g\"),\n\t query;\n\n\t query = location.search.replace(regExp, \"\").replace(\"?\", \"\");\n\n\t if (query.length && !(/&$/.test(query))) {\n\t query += \"&\";\n\t }\n\n\t options = this.setup(options, \"read\");\n\n\t url = options.url;\n\n\t if (url.indexOf(\"?\") >= 0) {\n\t query = query.replace(/(.*?=.*?)&/g, function(match){\n\t if(url.indexOf(match.substr(0, match.indexOf(\"=\"))) >= 0){\n\t return \"\";\n\t }\n\t return match;\n\t });\n\t url += \"&\" + query;\n\t } else {\n\t url += \"?\" + query;\n\t }\n\n\t url += $.map(options.data, function(value, key) {\n\t return key + \"=\" + value;\n\t }).join(\"&\");\n\n\t location.href = url;\n\t }\n\t })\n\t }\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.data\");\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.combobox\");\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.multiselect\");\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.validator\");\n\n/***/ })\n/******/ ]);","module.exports =\n/******/ (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\t__webpack_require__(9);\n\tmodule.exports = __webpack_require__(9);\n\n\n/***/ }),\n/* 1 */,\n/* 2 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.aspnetmvc\");\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n/* 4 */,\n/* 5 */,\n/* 6 */,\n/* 7 */,\n/* 8 */,\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\r\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n\t})(function(){\r\n\r\n\t(function ($, undefined) {\r\n\t var kendo = window.kendo,\r\n\t ui = kendo.ui;\r\n\r\n\t if (ui && ui.DropDownList) {\r\n\t ui.DropDownList.requestData = function (selector) {\r\n\t var dropdownlist = $(selector).data(\"kendoDropDownList\");\r\n\r\n\t if (!dropdownlist) {\r\n\t return;\r\n\t }\r\n\r\n\t var filter = dropdownlist.dataSource.filter();\r\n\t var filterInput = dropdownlist.filterInput;\r\n\t var value = filterInput ? filterInput.val() : \"\";\r\n\r\n\t if (!filter || !filter.filters.length) {\r\n\t value = \"\";\r\n\t }\r\n\r\n\t return { text: value };\r\n\t };\r\n\t }\r\n\r\n\t})(window.kendo.jQuery);\r\n\r\n\t}, __webpack_require__(3));\r\n\n\n/***/ })\n/******/ ]);","module.exports =\n/******/ (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\t__webpack_require__(10);\n\tmodule.exports = __webpack_require__(10);\n\n\n/***/ }),\n/* 1 */,\n/* 2 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.aspnetmvc\");\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n/* 4 */,\n/* 5 */,\n/* 6 */,\n/* 7 */,\n/* 8 */,\n/* 9 */,\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t ui = kendo.ui;\n\n\t if (ui && ui.DropDownTree) {\n\t ui.DropDownTree.requestData = function (selector) {\n\t var dropdowntree = $(selector).data(\"kendoDropDownTree\");\n\n\t if (!dropdowntree) {\n\t return;\n\t }\n\n\t var filter = dropdowntree.dataSource.filter();\n\t var filterInput = dropdowntree.filterInput;\n\t var value = filterInput ? filterInput.val() : \"\";\n\n\t if (!filter || !filter.filters.length) {\n\t value = \"\";\n\t }\n\n\t return { text: value };\n\t };\n\t }\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n/******/ ]);","module.exports =\n/******/ (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\t__webpack_require__(11);\n\tmodule.exports = __webpack_require__(11);\n\n\n/***/ }),\n/* 1 */,\n/* 2 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.aspnetmvc\");\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n/* 4 */,\n/* 5 */,\n/* 6 */,\n/* 7 */,\n/* 8 */,\n/* 9 */,\n/* 10 */,\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t extend = $.extend;\n\n\t extend(true, kendo.data, {\n\t schemas: {\n\t \"filemanager\": {\n\t data: function(data) {\n\t return data || [];\n\t },\n\t model: {\n\t id: \"path\",\n\t hasChildren: \"hasDirectories\",\n\t fields: {\n\t name: {field: \"Name\", editable: true, type: \"String\", defaultValue: \"New Folder\" },\n\t size: {field: \"Size\", editable: false, type: \"Number\"},\n\t path: {field: \"Path\", editable: false, type: \"String\"},\n\t extension: {field: \"Extension\", editable: false, type: \"String\"},\n\t isDirectory: {field: \"IsDirectory\", editable: false, defaultValue: true, type: \"Boolean\"},\n\t hasDirectories: {field: \"HasDirectories\", editable: false, defaultValue: false, type: \"Boolean\"},\n\t created: {field: \"Created\", type: \"Date\", editable: false},\n\t createdUtc: {field: \"CreatedUtc\", type: \"Date\", editable: false },\n\t modified: {field: \"Modified\", type: \"Date\", editable: false},\n\t modifiedUtc: {field: \"ModifiedUtc\", type: \"Date\", editable: false }\n\t }\n\t }\n\t }\n\t }\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n/******/ ]);","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(12);\n\tmodule.exports = __webpack_require__(12);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 12:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\r\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(13) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n\t})(function(){\r\n\r\n\t(function ($, undefined) {\r\n\t var kendo = window.kendo,\r\n\t extend = $.extend,\r\n\t isFunction = $.isFunction;\r\n\r\n\t extend(true, kendo.data, {\r\n\t schemas: {\r\n\t \"imagebrowser-aspnetmvc\": {\r\n\t data: function(data) {\r\n\t return data || [];\r\n\t },\r\n\t model: {\r\n\t id: \"name\",\r\n\t fields: {\r\n\t name: { field: \"Name\" },\r\n\t size: { field: \"Size\" },\r\n\t type: { field: \"EntryType\", parse: function(value) { return value == 0 ? \"f\" : \"d\"; } } // jshint ignore:line, afraid to break something with strict equality\r\n\t }\r\n\t }\r\n\t }\r\n\t }\r\n\t });\r\n\r\n\t extend(true, kendo.data, {\r\n\t schemas: {\r\n\t \"filebrowser-aspnetmvc\": kendo.data.schemas[\"imagebrowser-aspnetmvc\"]\r\n\t }\r\n\t });\r\n\r\n\t extend(true, kendo.data, {\r\n\t transports: {\r\n\t \"imagebrowser-aspnetmvc\": kendo.data.RemoteTransport.extend({\r\n\t init: function(options) {\r\n\t kendo.data.RemoteTransport.fn.init.call(this, $.extend(true, {}, this.options, options));\r\n\t },\r\n\t _call: function(type, options) {\r\n\t options.data = $.extend({}, options.data, { path: this.options.path() });\r\n\r\n\t if (isFunction(this.options[type])) {\r\n\t this.options[type].call(this, options);\r\n\t } else {\r\n\t kendo.data.RemoteTransport.fn[type].call(this, options);\r\n\t }\r\n\t },\r\n\t read: function(options) {\r\n\t this._call(\"read\", options);\r\n\t },\r\n\t create: function(options) {\r\n\t this._call(\"create\", options);\r\n\t },\r\n\t destroy: function(options) {\r\n\t this._call(\"destroy\", options);\r\n\t },\r\n\t update: function() {\r\n\t //updates are handled by the upload\r\n\t },\r\n\t options: {\r\n\t read: {\r\n\t type: \"POST\"\r\n\t },\r\n\t update: {\r\n\t type: \"POST\"\r\n\t },\r\n\t create: {\r\n\t type: \"POST\"\r\n\t },\r\n\t destroy: {\r\n\t type: \"POST\"\r\n\t },\r\n\t parameterMap: function(options, type) {\r\n\t if (type != \"read\") {\r\n\t options.EntryType = options.EntryType === \"f\" ? 0 : 1;\r\n\t }\r\n\t return options;\r\n\t }\r\n\t }\r\n\t })\r\n\t }\r\n\t });\r\n\r\n\t extend(true, kendo.data, {\r\n\t transports: {\r\n\t \"filebrowser-aspnetmvc\": kendo.data.transports[\"imagebrowser-aspnetmvc\"]\r\n\t }\r\n\t });\r\n\r\n\t})(window.kendo.jQuery);\r\n\r\n\t}, __webpack_require__(3));\r\n\n\n/***/ }),\n\n/***/ 13:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.multiselect.aspnetmvc\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(14);\n\tmodule.exports = __webpack_require__(14);\n\n\n/***/ }),\n\n/***/ 2:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.aspnetmvc\");\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 14:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t ui = kendo.ui;\n\n\t if (ui && ui.MultiColumnComboBox) {\n\t ui.MultiColumnComboBox.requestData = function (selector) {\n\n\t var multicolumncombobox = $(selector).data(\"kendoMultiColumnComboBox\");\n\n\t if (!multicolumncombobox) {\n\t return;\n\t }\n\n\t var filter = multicolumncombobox.dataSource.filter();\n\t var value = multicolumncombobox.input.val();\n\n\t if (!filter || !filter.filters.length) {\n\t value = \"\";\n\t }\n\n\t return { text: value };\n\t };\n\t }\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(15);\n\tmodule.exports = __webpack_require__(15);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 15:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\r\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(16) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n\t})(function(){\r\n\r\n\t(function ($, undefined) {\r\n\t var kendo = window.kendo,\r\n\t ui = kendo.ui;\r\n\r\n\t if (ui && ui.MultiSelect) {\r\n\t ui.MultiSelect.requestData = function (selector) {\r\n\t var multiselect = $(selector).data(\"kendoMultiSelect\");\r\n\r\n\t if (!multiselect) {\r\n\t return;\r\n\t }\r\n\r\n\t var text = multiselect.input.val();\r\n\r\n\t return { text: text !== multiselect.options.placeholder ? text : \"\" };\r\n\t };\r\n\t }\r\n\r\n\t})(window.kendo.jQuery);\r\n\r\n\t}, __webpack_require__(3));\r\n\n\n/***/ }),\n\n/***/ 16:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.combobox.aspnetmvc\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(17);\n\tmodule.exports = __webpack_require__(17);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 17:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(18) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t var nameSpecialCharRegExp = /(\"|\\%|'|\\[|\\]|\\$|\\.|\\,|\\:|\\;|\\+|\\*|\\&|\\!|\\#|\\(|\\)|<|>|\\=|\\?|\\@|\\^|\\{|\\}|\\~|\\/|\\||`)/g;\n\t var SWITCHSELECTOR = \".k-switch\";\n\n\t function generateMessages() {\n\t var name,\n\t messages = {};\n\n\t for (name in validationRules) {\n\t messages[\"mvc\" + name] = createMessage(name);\n\t }\n\t return messages;\n\t }\n\n\t function generateRules() {\n\t var name,\n\t rules = {};\n\n\t for (name in validationRules) {\n\t rules[\"mvc\" + name] = createRule(name);\n\t }\n\t return rules;\n\t }\n\n\t function extractParams(input, ruleName) {\n\t var params = {},\n\t index,\n\t data = input.data(),\n\t length = ruleName.length,\n\t rule,\n\t key,\n\t start;\n\n\t for (key in data) {\n\t rule = key.toLowerCase();\n\t index = rule.indexOf(ruleName);\n\t if (index > -1) {\n\t start = rule === \"valserver\" ? index : index + length;\n\t rule = rule.substring(start, key.length);\n\n\t if (rule) {\n\t params[rule] = data[key];\n\t }\n\t }\n\t }\n\t return params;\n\t }\n\n\t function rulesFromData(metadata) {\n\t var idx,\n\t length,\n\t fields = metadata.Fields || [],\n\t rules = {};\n\n\t for (idx = 0, length = fields.length; idx < length; idx++) {\n\t $.extend(true, rules, rulesForField(fields[idx]));\n\t }\n\t return rules;\n\t }\n\n\t function rulesForField(field) {\n\t var rules = {},\n\t messages = {},\n\t fieldName = field.FieldName,\n\t fieldRules = field.ValidationRules,\n\t validationType,\n\t validationParams,\n\t idx,\n\t length;\n\n\t for (idx = 0, length = fieldRules.length; idx < length; idx++) {\n\t validationType = fieldRules[idx].ValidationType;\n\t validationParams = fieldRules[idx].ValidationParameters;\n\n\t rules[fieldName + validationType] = createMetaRule(fieldName, validationType, validationParams);\n\n\t messages[fieldName + validationType] = createMetaMessage(fieldRules[idx].ErrorMessage);\n\t }\n\t return { rules: rules, messages: messages };\n\t }\n\n\t function createMessage(rule) {\n\t return function (input) {\n\t return input.attr(\"data-val-\" + rule);\n\t };\n\t }\n\n\t function createRule(ruleName) {\n\t return function (input) {\n\t if (input.filter(\"[data-val-\" + ruleName + \"]\").length) {\n\t return validationRules[ruleName](input, extractParams(input, ruleName));\n\t }\n\t return true;\n\t };\n\t }\n\n\t function createMetaMessage(message) {\n\t return function() { return message; };\n\t }\n\n\t function createMetaRule(fieldName, type, params) {\n\t return function (input) {\n\t if (input.filter(\"[name=\" + fieldName + \"]\").length) {\n\t return validationRules[type](input, params);\n\t }\n\t return true;\n\t };\n\t }\n\n\t function patternMatcher(value, pattern) {\n\t if (typeof pattern === \"string\") {\n\t pattern = new RegExp('^(?:' + pattern + ')$');\n\t }\n\t return pattern.test(value);\n\t }\n\n\t var validationRules = {\n\t required: function (input) {\n\t var value = input.val(),\n\t checkbox = input.filter(\"[type=checkbox]\"),\n\t name;\n\n\t if (checkbox.length) {\n\t name = checkbox[0].name.replace(nameSpecialCharRegExp, \"\\\\$1\");\n\t var hiddenSelector = \"input:hidden[name='\" + name + \"']\";\n\n\t if (checkbox.closest(SWITCHSELECTOR).length) {\n\t checkbox = checkbox.closest(SWITCHSELECTOR);\n\t }\n\n\t var hidden = checkbox.next(hiddenSelector);\n\n\t if (!hidden.length) {\n\t hidden = checkbox.next(\"label.k-checkbox-label\").next(hiddenSelector);\n\t }\n\n\t if (hidden.length) {\n\t value = hidden.val();\n\t } else {\n\t value = input.prop(\"checked\") === true;\n\t }\n\t }\n\n\t return !(value === \"\" || !value || value.length === 0);\n\t },\n\t number: function (input) {\n\t /* jshint eqnull:true */\n\t return input.val() === \"\" || input.val() == null || kendo.parseFloat(input.val()) !== null;\n\t },\n\t regex: function (input, params) {\n\t if (input.val() !== \"\") {\n\t return patternMatcher(input.val(), params.pattern);\n\t }\n\t return true;\n\t },\n\t range: function(input, params) {\n\t if (input.val() !== \"\") {\n\t return this.min(input, params) && this.max(input, params);\n\t }\n\t return true;\n\t },\n\t min: function(input, params) {\n\t var min = parseFloat(params.min) || 0,\n\t val = kendo.parseFloat(input.val());\n\n\t return min <= val;\n\t },\n\t max: function(input, params) {\n\t var max = parseFloat(params.max) || 0,\n\t val = kendo.parseFloat(input.val());\n\n\t return val <= max;\n\t },\n\t date: function(input) {\n\t return input.val() === \"\" || kendo.parseDate(input.val()) !== null;\n\t },\n\t length: function(input, params) {\n\t if (input.val() !== \"\") {\n\t var len = kendo.trim(input.val()).length;\n\t return (!params.min || len >= (params.min || 0)) && (!params.max || len <= (params.max || 0));\n\t }\n\t return true;\n\t },\n\t server: function(input, params) {\n\t if (params.server) {\n\t return false;\n\t }\n\n\t return true;\n\t }\n\t };\n\n\t $.extend(true, kendo.ui.validator, {\n\t rules: generateRules(),\n\t messages: generateMessages(),\n\t messageLocators: {\n\t mvcLocator: {\n\t locate: function (element, fieldName) {\n\t fieldName = fieldName.replace(nameSpecialCharRegExp, \"\\\\$1\");\n\t return element.find(\".field-validation-valid[data-valmsg-for='\" + fieldName + \"'], .field-validation-error[data-valmsg-for='\" + fieldName + \"']\");\n\t },\n\t decorate: function (message, fieldName) {\n\t message.addClass(\"field-validation-error\").attr(\"data-valmsg-for\", fieldName || \"\");\n\t }\n\t },\n\t mvcMetadataLocator: {\n\t locate: function (element, fieldName) {\n\t fieldName = fieldName.replace(nameSpecialCharRegExp, \"\\\\$1\");\n\t return element.find(\"#\" + fieldName + \"_validationMessage.field-validation-valid\");\n\t },\n\t decorate: function (message, fieldName) {\n\t message.addClass(\"field-validation-error\").attr(\"id\", fieldName + \"_validationMessage\");\n\t }\n\t }\n\t },\n\t ruleResolvers: {\n\t mvcMetaDataResolver: {\n\t resolve: function (element) {\n\t var metadata = window.mvcClientValidationMetadata || [];\n\n\t if (metadata.length) {\n\t element = $(element);\n\t for (var idx = 0; idx < metadata.length; idx++) {\n\t if (metadata[idx].FormId == element.attr(\"id\")) {\n\t return rulesFromData(metadata[idx]);\n\t }\n\t }\n\t }\n\t return {};\n\t }\n\t }\n\t },\n\t validateOnInit: function(element) {\n\t return !!element.find(\"input[data-val-server]\").length;\n\t },\n\t allowSubmit: function(element, errors) {\n\t return !!errors && errors.length === element.find(\"input[data-val-server]\").length;\n\t }\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 18:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.imagebrowser.aspnetmvc\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(855);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 855:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(856),\n\t __webpack_require__(857),\n\t __webpack_require__(858),\n\t __webpack_require__(859),\n\t __webpack_require__(860),\n\t __webpack_require__(861)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\n\t var NS = \".kendoChart\";\n\t var kendo = window.kendo;\n\t var Class = kendo.Class;\n\t var outerWidth = kendo._outerWidth;\n\t var outerHeight = kendo._outerHeight;\n\t var dataviz = kendo.dataviz;\n\t var constants = dataviz.constants;\n\t var KendoChart = dataviz.Chart;\n\t var SeriesBinder = dataviz.SeriesBinder;\n\t var Widget = kendo.ui.Widget;\n\t var DataSource = kendo.data.DataSource;\n\t var deepExtend = kendo.deepExtend;\n\t var defined = dataviz.defined;\n\t var getField = dataviz.getField;\n\t var InstanceObserver = dataviz.InstanceObserver;\n\t var inArray = dataviz.inArray;\n\t var services = dataviz.services;\n\t var proxy = $.proxy;\n\t var isArray = $.isArray;\n\t var extend = $.extend;\n\t var template = kendo.template;\n\n\t var MOUSELEAVE_NS = \"mouseleave\" + NS;\n\t var AXIS_LABEL_CLICK = constants.AXIS_LABEL_CLICK;\n\t var LEGEND_ITEM_CLICK = constants.LEGEND_ITEM_CLICK;\n\t var LEGEND_ITEM_HOVER = constants.LEGEND_ITEM_HOVER;\n\t var LEGEND_ITEM_LEAVE = constants.LEGEND_ITEM_LEAVE;\n\t var SERIES_CLICK = constants.SERIES_CLICK;\n\t var SERIES_HOVER = constants.SERIES_HOVER;\n\t var SERIES_OVER = constants.SERIES_OVER;\n\t var SERIES_LEAVE = constants.SERIES_LEAVE;\n\t var PANE_RENDER = constants.PANE_RENDER;\n\t var PLOT_AREA_CLICK = constants.PLOT_AREA_CLICK;\n\t var PLOT_AREA_HOVER = constants.PLOT_AREA_HOVER;\n\t var PLOT_AREA_LEAVE = constants.PLOT_AREA_LEAVE;\n\t var DRAG = constants.DRAG;\n\t var DRAG_END = constants.DRAG_END;\n\t var DRAG_START = constants.DRAG_START;\n\t var ZOOM_START = constants.ZOOM_START;\n\t var ZOOM = constants.ZOOM;\n\t var ZOOM_END = constants.ZOOM_END;\n\t var SELECT_START = constants.SELECT_START;\n\t var SELECT = constants.SELECT;\n\t var SELECT_END = constants.SELECT_END;\n\t var RENDER = constants.RENDER;\n\t var NOTE_CLICK = constants.NOTE_CLICK;\n\t var NOTE_HOVER = constants.NOTE_HOVER;\n\t var NOTE_LEAVE = constants.NOTE_LEAVE;\n\n\t var CHANGE = \"change\";\n\t var DATABOUND = \"dataBound\";\n\t var LEAVE = \"leave\";\n\n\t var VALUE = constants.VALUE;\n\t var PIE = constants.PIE;\n\t var DONUT = constants.DONUT;\n\t var FUNNEL = constants.FUNNEL;\n\n\t var Observable = kendo.Observable;\n\t var TOOLTIP_ANIMATION_DURATION = 150;\n\t var TOOLTIP_SHOW_DELAY = 100;\n\t var TOOLTIP_INVERSE = \"k-chart-tooltip-inverse\";\n\t var SHARED_TOOLTIP_CLASS = \"k-chart-shared-tooltip\";\n\t var RTL = \"rtl\";\n\n\t services.DomEventsBuilder.register({\n\t create: function(element, events) {\n\t return new kendo.UserEvents(element, deepExtend({\n\t global: true,\n\t multiTouch: true,\n\t fastTap: true\n\t }, events));\n\t }\n\t });\n\n\t var ChartInstanceObserver = InstanceObserver.extend({\n\t handlerMap: {\n\t showTooltip: '_showTooltip',\n\t hideTooltip: '_hideTooltip',\n\t legendItemClick: '_onLegendItemClick',\n\t render: '_onRender',\n\t init: '_onInit'\n\t }\n\t });\n\n\t var Chart = Widget.extend({\n\t init: function(element, userOptions) {\n\t var dataSource;\n\n\t kendo.destroy(element);\n\n\t Widget.fn.init.call(this, element);\n\n\t if (userOptions) {\n\t dataSource = userOptions.dataSource;\n\t delete userOptions.dataSource;\n\t }\n\n\t this.options = deepExtend({}, this.options, userOptions);\n\n\t this.wrapper = this.element;\n\t this._attachEvents();\n\n\t if (userOptions) {\n\t userOptions.dataSource = dataSource;\n\t }\n\n\t this._seriesVisibility = new SeriesVisibilityState();\n\n\t this.bind(this.events, this.options);\n\t this._initDataSource(userOptions);\n\n\t kendo.notify(this, dataviz.ui);\n\t },\n\n\t events:[\n\t DATABOUND,\n\t SERIES_CLICK,\n\t SERIES_HOVER,\n\t SERIES_OVER,\n\t SERIES_LEAVE,\n\t AXIS_LABEL_CLICK,\n\t LEGEND_ITEM_CLICK,\n\t LEGEND_ITEM_HOVER,\n\t LEGEND_ITEM_LEAVE,\n\t PANE_RENDER,\n\t PLOT_AREA_CLICK,\n\t PLOT_AREA_HOVER,\n\t PLOT_AREA_LEAVE,\n\t DRAG_START,\n\t DRAG,\n\t DRAG_END,\n\t ZOOM_START,\n\t ZOOM,\n\t ZOOM_END,\n\t SELECT_START,\n\t SELECT,\n\t SELECT_END,\n\t NOTE_CLICK,\n\t NOTE_HOVER,\n\t NOTE_LEAVE,\n\t RENDER\n\t ],\n\n\t options: {\n\t name: \"Chart\",\n\t renderAs: \"\",\n\t theme: \"default\",\n\t axisDefaults: {},\n\t chartArea: {},\n\t legend: {},\n\t categoryAxis: {},\n\t autoBind: true,\n\t seriesDefaults: {},\n\t series: [],\n\t seriesColors: null,\n\t tooltip: {},\n\t transitions: true,\n\t valueAxis: {},\n\t plotArea: {},\n\t title: {},\n\t xAxis: {},\n\t yAxis: {},\n\t panes: [{}],\n\t pannable: false,\n\t zoomable: false\n\t },\n\n\t items: function() {\n\t return $();\n\t },\n\n\t refresh: function() {\n\t var chart = this;\n\t var instance = chart._instance;\n\t instance.applyDefaults(chart.options);\n\t instance.applySeriesColors();\n\n\t chart._bindSeries();\n\t chart._bindCategories();\n\n\t chart.trigger(DATABOUND);\n\t chart._redraw();\n\t },\n\n\t getSize: function() {\n\t return kendo.dimensions(this.element);\n\t },\n\n\t redraw: function(paneName) {\n\t this._size = null;\n\t this._instance.redraw(paneName);\n\t },\n\n\t setOptions: function(options) {\n\t var chart = this,\n\t dataSource = options.dataSource;\n\n\t delete options.dataSource;\n\n\t Widget.fn._setEvents.call(chart, options);\n\n\t this._instance.applyOptions(options, this._getThemeOptions(options));\n\t this.options = this._instance.options;\n\t this._tooltip.setOptions(this.options.tooltip);\n\t this._seriesVisibility.setOptions(this.options);\n\t this._sourceSeries = null;\n\n\t if (dataSource) {\n\t chart.setDataSource(dataSource);\n\t }\n\n\t if (chart._hasDataSource) {\n\t chart._onDataChanged();\n\t } else {\n\t chart._bindCategories();\n\t chart.redraw();\n\t }\n\n\t chart._instance.updateMouseMoveHandler();\n\n\t },\n\n\t setDataSource: function(dataSource) {\n\t var chart = this;\n\n\t chart.dataSource.unbind(CHANGE, chart._dataChangeHandler);\n\t chart.dataSource = dataSource = DataSource.create(dataSource);\n\t chart._hasDataSource = true;\n\t chart._hasData = false;\n\n\t dataSource.bind(CHANGE, chart._dataChangeHandler);\n\n\t if (chart.options.autoBind) {\n\t dataSource.fetch();\n\t }\n\t },\n\n\t destroy: function() {\n\t var chart = this,\n\t dataSource = chart.dataSource;\n\n\t chart.element.off(NS);\n\n\t if (dataSource) {\n\t dataSource.unbind(CHANGE, chart._dataChangeHandler);\n\t }\n\n\t if (chart._instance) {\n\t chart._instance.destroy();\n\t delete this._instance;\n\t }\n\n\t if (this._tooltip) {\n\t this._tooltip.destroy();\n\t delete this._tooltip;\n\t }\n\n\t this._destroyCrosshairTooltips();\n\n\t Widget.fn.destroy.call(chart);\n\t },\n\n\t findPaneByName: function(name) {\n\t var panes = this._plotArea.panes;\n\n\t for (var idx = 0; idx < panes.length; idx++) {\n\t if (panes[idx].options.name === name) {\n\t return new ChartPane(this, panes[idx]);\n\t }\n\t }\n\t },\n\n\t findPaneByIndex: function(idx) {\n\t var panes = this._plotArea.panes;\n\t if (panes[idx]) {\n\t return new ChartPane(this, panes[idx]);\n\t }\n\t },\n\n\t findSeries: function(callback) {\n\t var plotArea = this._plotArea;\n\t var series = plotArea.srcSeries || plotArea.series;\n\t for (var idx = 0; idx < series.length; idx++) {\n\t if (callback(series[idx])) {\n\t return new ChartSeries(this, series[idx]);\n\t }\n\t }\n\t },\n\n\t findSeriesByName: function(name) {\n\t return this._createSeries({ name: name });\n\t },\n\n\t findSeriesByIndex: function(index) {\n\t return this._createSeries({ index: index });\n\t },\n\n\t exportVisual: function(options) {\n\t var instance = this._instance;\n\t if (!instance) {\n\t return;\n\t }\n\n\t var visual;\n\n\t //TO DO: support for setting any options. already available in kendo-charts\n\t if (options && (options.width || options.height)) {\n\t var chartArea = instance.options.chartArea;\n\t var originalChartArea = instance._originalOptions.chartArea;\n\n\t deepExtend(chartArea, options);\n\n\t var model = instance._getModel();\n\n\t chartArea.width = originalChartArea.width;\n\t chartArea.height = originalChartArea.height;\n\n\t model.renderVisual();\n\n\t triggerPaneRender(model._plotArea.panes);\n\n\t visual = model.visual;\n\t } else {\n\t visual = instance.exportVisual();\n\t }\n\n\t return visual;\n\t },\n\n\t _createSeries: function(options) {\n\t var seriesOptions = this._seriesOptions(options);\n\t if (seriesOptions) {\n\t return new ChartSeries(this, seriesOptions);\n\t }\n\t },\n\n\t _seriesOptions: function(options) {\n\t var plotArea = this._plotArea;\n\t var series = plotArea.srcSeries || plotArea.series;\n\t var seriesOptions;\n\n\t if (defined(options.index)) {\n\t seriesOptions = series[options.index];\n\t } else if (defined(options.name)) {\n\t for (var idx = 0; idx < series.length; idx++) {\n\t if (series[idx].name === options.name) {\n\t seriesOptions = series[idx];\n\t break;\n\t }\n\t }\n\t }\n\n\t return seriesOptions;\n\t },\n\n\t _attachEvents: function() {\n\t this.element.on(MOUSELEAVE_NS, proxy(this._mouseleave, this));\n\t },\n\n\t _mouseleave: function(e) {\n\t var instance = this._instance;\n\t var tooltip = this._tooltip;\n\t var target = e.relatedTarget;\n\n\t if (!(target && $(target).closest(tooltip.element).length) && instance && !instance.handlingTap) {\n\t instance.hideElements();\n\t }\n\t },\n\n\t _getThemeOptions: function(userOptions) {\n\t var themeName = (userOptions || {}).theme;\n\n\t if (themeName && dataviz.SASS_THEMES.indexOf(themeName.toLowerCase()) !== -1) {\n\t return dataviz.autoTheme().chart;\n\t }\n\n\t if (defined(themeName)) {\n\t var themes = dataviz.ui.themes || {};\n\t var theme = themes[themeName] || themes[themeName.toLowerCase()] || {};\n\t return theme.chart || {};\n\t }\n\t },\n\n\t _initChart: function() {\n\t this._createChart(this.options, this._getThemeOptions(this.options));\n\t this.options = this._instance.options;\n\t this._seriesVisibility.setOptions(this.options);\n\t },\n\n\t _createChart: function(options, themeOptions) {\n\t this._instance = new KendoChart(this.element[0], options, themeOptions, {\n\t observer: new ChartInstanceObserver(this),\n\t sender: this,\n\t rtl: this._isRtl()\n\t });\n\t },\n\n\t _onInit: function(e) {\n\t this._instance = e.sender;\n\t },\n\n\t _initDataSource: function(userOptions) {\n\t var chart = this,\n\t dataSource = (userOptions || {}).dataSource;\n\n\t chart._dataChangeHandler = proxy(chart._onDataChanged, chart);\n\n\t chart.dataSource = DataSource\n\t .create(dataSource)\n\t .bind(\"change\", chart._dataChangeHandler);\n\n\t chart._bindCategories();\n\n\t if (dataSource) {\n\t chart._hasDataSource = true;\n\t }\n\n\t this._initChart();\n\t this._initTooltip();\n\n\t if (dataSource) {\n\t if (chart.options.autoBind) {\n\t chart.dataSource.fetch();\n\t }\n\t }\n\t },\n\n\t _destroyCrosshairTooltips: function() {\n\t var tooltips = this._crosshairTooltips;\n\t if (tooltips) {\n\t for (var key in tooltips) {\n\t tooltips[key].destroy();\n\t }\n\t }\n\t this._crosshairTooltips = {};\n\t },\n\n\t _getCrosshairTooltip: function(name, index) {\n\t var tooltips = this._crosshairTooltips = this._crosshairTooltips || {};\n\t var key = name + index;\n\t var tooltip = tooltips[key];\n\t if (!tooltip) {\n\t tooltip = tooltips[key] = new CrosshairTooltip(this.element);\n\t }\n\t return tooltip;\n\t },\n\n\t _showTooltip: function(e) {\n\t if (e.crosshair) {\n\t var tooltip = this._getCrosshairTooltip(e.axisName, e.axisIndex);\n\t tooltip.show(e);\n\t } else if (this._tooltip) {\n\t this._tooltip.show(e);\n\t }\n\t },\n\n\t _hideTooltip: function(e) {\n\t if (e.crosshair) {\n\t var tooltip = this._getCrosshairTooltip(e.axisName, e.axisIndex);\n\t tooltip.hide();\n\t } else if (this._tooltip) {\n\t this._tooltip.hide(e);\n\t }\n\t },\n\n\t _onRender: function(e) {\n\t this._destroyCrosshairTooltips();\n\t this._copyMembers(e.sender);\n\t if (!this._hasDataSource || this._hasData || !this.options.autoBind) {\n\t this.trigger(RENDER);\n\t }\n\t },\n\n\t _copyMembers: function(instance) {\n\t this.options = instance.options;\n\t this._originalOptions = instance._originalOptions;\n\t this.surface = instance.surface;\n\t this._plotArea = instance._plotArea;\n\t this._model = instance._model;\n\t this._highlight = instance._highlight;\n\t this._selections = instance._selections;\n\t this._pannable = instance._pannable;\n\t this._zoomSelection = instance._zoomSelection;\n\t this._mousewheelZoom = instance._mousewheelZoom;\n\t },\n\n\t requiresHandlers: function(names) {\n\t var events = this._events;\n\t for (var idx = 0; idx < names.length; idx++) {\n\t if (defined(events[names[idx]])) {\n\t return true;\n\t }\n\t }\n\t },\n\n\t _initTooltip: function() {\n\t this._tooltip = this._createTooltip();\n\n\t this._tooltip.bind(LEAVE, proxy(this._tooltipleave, this));\n\t },\n\n\t _onLegendItemClick: function(e) {\n\t if (!this.trigger(LEGEND_ITEM_CLICK, e)) {\n\t this._legendItemClick(e.seriesIndex, e.pointIndex);\n\t }\n\t },\n\n\t _legendItemClick: function(seriesIndex, pointIndex) {\n\t var chart = this._instance,\n\t plotArea = chart._plotArea,\n\t currentSeries = (plotArea.srcSeries || plotArea.series)[seriesIndex];\n\n\t if ($.inArray(currentSeries.type, [PIE, DONUT, FUNNEL]) >= 0) {\n\t var point = currentSeries.data[pointIndex];\n\t if (point && defined(point.visible)) {\n\t point.visible = !point.visible;\n\t } else {\n\t var pointVisibility = currentSeries.pointVisibility = currentSeries.pointVisibility || {};\n\t var visible = pointVisibility[pointIndex];\n\t pointVisibility[pointIndex] = defined(visible) ? !visible : false;\n\t }\n\t } else {\n\t currentSeries.visible = !currentSeries.visible;\n\t this._seriesVisibility.save(currentSeries);\n\t }\n\n\t chart._noTransitionsRedraw();\n\t },\n\n\t _createTooltip: function() {\n\t return new Tooltip(this.element, extend({}, this.options.tooltip, {\n\t rtl: this._isRtl()\n\t }));\n\t },\n\n\t _tooltipleave: function() {\n\t if (this._instance) {\n\t this._instance.hideElements();\n\t }\n\t },\n\n\t _bindData: function(e) {\n\t var chart = this,\n\t options = chart.options,\n\t series = chart._sourceSeries || options.series,\n\t seriesIx,\n\t seriesLength = series.length,\n\t data = chart.dataSource.view(),\n\t grouped = (chart.dataSource.group() || []).length > 0,\n\t processedSeries = [],\n\t seriesVisibility = this._seriesVisibility,\n\t currentSeries,\n\t groupedSeries;\n\n\t seriesVisibility.read();\n\n\t for (seriesIx = 0; seriesIx < seriesLength; seriesIx++) {\n\t currentSeries = series[seriesIx];\n\n\t if (chart._isBindable(currentSeries) && grouped) {\n\t groupedSeries = groupSeries(currentSeries, data);\n\t processedSeries = processedSeries.concat(groupedSeries);\n\n\t seriesVisibility.applyByGroup(groupedSeries, e);\n\t } else {\n\t currentSeries = extend({}, currentSeries);\n\t processedSeries.push(currentSeries);\n\n\t seriesVisibility.applyByIndex(currentSeries, e);\n\t }\n\t }\n\n\t chart._sourceSeries = series;\n\t options.series = processedSeries;\n\t this._instance.applySeriesColors();\n\n\t chart._bindSeries();\n\t chart._bindCategories();\n\n\t this._hasData = true;\n\t },\n\n\t _onDataChanged: function(e) {\n\t this._bindData(e);\n\n\t this.trigger(DATABOUND);\n\t if (this._instance && this._instance.fontLoaded) {\n\t this._redraw();\n\t }\n\t },\n\n\t _bindSeries: function() {\n\t var chart = this,\n\t data = chart.dataSource.view(),\n\t series = chart.options.series,\n\t seriesIx,\n\t seriesLength = series.length,\n\t currentSeries,\n\t groupIx,\n\t seriesData;\n\n\t for (seriesIx = 0; seriesIx < seriesLength; seriesIx++) {\n\t currentSeries = series[seriesIx];\n\n\t if (chart._isBindable(currentSeries)) {\n\t groupIx = currentSeries._groupIx;\n\t seriesData = defined(groupIx) ? (data[groupIx] || {}).items : data;\n\n\t if (currentSeries.autoBind !== false) {\n\t currentSeries.data = seriesData;\n\t }\n\t }\n\t }\n\t },\n\n\t _bindCategories: function() {\n\t var chart = this,\n\t data = chart.dataSource.view() || [],\n\t grouped = (chart.dataSource.group() || []).length > 0,\n\t categoriesData = data,\n\t options = chart.options,\n\t definitions = [].concat(options.categoryAxis),\n\t axisIx,\n\t axis;\n\n\t if (grouped) {\n\t if (data.length) {\n\t categoriesData = data[0].items;\n\t }\n\t }\n\n\t for (axisIx = 0; axisIx < definitions.length; axisIx++) {\n\t axis = definitions[axisIx];\n\t if (axis.autoBind !== false) {\n\t chart._bindCategoryAxis(axis, categoriesData, axisIx);\n\t }\n\t }\n\t },\n\n\t _bindCategoryAxis: function(axis, data, axisIx) {\n\t var count = (data || []).length,\n\t categoryIx,\n\t category,\n\t row;\n\n\t if (axis.field) {\n\t axis.categories = [];\n\t for (categoryIx = 0; categoryIx < count; categoryIx++) {\n\t row = data[categoryIx];\n\n\t category = getField(axis.field, row);\n\t if (categoryIx === 0) {\n\t axis.categories = [category];\n\t axis.dataItems = [row];\n\t } else {\n\t axis.categories.push(category);\n\t axis.dataItems.push(row);\n\t }\n\t }\n\t } else if (this._instance) {\n\t this._instance.bindCategoryAxisFromSeries(axis, axisIx);\n\t }\n\t },\n\n\t _isBindable: function(series) {\n\t var valueFields = SeriesBinder.current.valueFields(series),\n\t result = true,\n\t field, i;\n\n\t for (i = 0; i < valueFields.length; i++) {\n\t field = valueFields[i];\n\t if (field === VALUE) {\n\t field = \"field\";\n\t } else {\n\t field = field + \"Field\";\n\t }\n\n\t if (!defined(series[field])) {\n\t result = false;\n\t break;\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t _isRtl: function() {\n\t return kendo.support.isRtl(this.element) && this.element.css(\"direction\") === RTL;\n\t }\n\t });\n\n\t var proxyMembers = [\"getAxis\", \"findAxisByName\", \"plotArea\", \"toggleHighlight\", \"showTooltip\",\n\t \"hideTooltip\", \"_resize\", \"_redraw\", \"_noTransitionsRedraw\", \"_legendItemHover\", \"_eventCoordinates\"];\n\n\t function createProxyMember(name) {\n\t Chart.fn[name] = function() {\n\t var instance = this._instance;\n\t if (instance) {\n\t return instance[name].apply(instance, arguments);\n\t }\n\t };\n\t }\n\n\t for (var idx = 0; idx < proxyMembers.length; idx++) {\n\t createProxyMember(proxyMembers[idx]);\n\t }\n\n\t function groupSeries(series, data) {\n\t var result = [],\n\t nameTemplate,\n\t legacyTemplate = series.groupNameTemplate,\n\t groupIx,\n\t dataLength = data.length,\n\t seriesClone;\n\n\t if (dataLength === 0) {\n\t seriesClone = deepExtend({}, series);\n\t seriesClone.visibleInLegend = false;\n\t return [seriesClone];\n\t }\n\n\t if (defined(legacyTemplate)) {\n\t kendo.logToConsole(\n\t \"'groupNameTemplate' is obsolete and will be removed in future versions. \" +\n\t \"Specify the group name template as 'series.name'\"\n\t );\n\n\t if (legacyTemplate) {\n\t nameTemplate = template(legacyTemplate);\n\t }\n\t } else {\n\t nameTemplate = template(series.name || \"\");\n\t if (nameTemplate._slotCount === 0) {\n\t nameTemplate = template(defined(series.name) ?\n\t \"#= group.value #: #= series.name #\" :\n\t \"#= group.value #\"\n\t );\n\t }\n\t }\n\n\t for (groupIx = 0; groupIx < dataLength; groupIx++) {\n\t seriesClone = deepExtend({}, series);\n\n\t if (!kendo.isFunction(seriesClone.color)) {\n\t seriesClone.color = undefined;\n\t }\n\n\t seriesClone._groupIx = groupIx;\n\t seriesClone._groupValue = data[groupIx].value;\n\t result.push(seriesClone);\n\n\t if (nameTemplate) {\n\t seriesClone.name = nameTemplate({\n\t series: seriesClone, group: data[groupIx]\n\t });\n\t }\n\t }\n\n\t return result;\n\t }\n\n\t dataviz.ExportMixin.extend(Chart.fn);\n\n\t if (kendo.PDFMixin) {\n\t kendo.PDFMixin.extend(Chart.fn);\n\t }\n\n\t dataviz.ui.plugin(Chart);\n\n\t var SeriesVisibilityState = Class.extend({\n\t init: function() {\n\t this.groups = {};\n\t this.index = {};\n\t this.options = {};\n\t },\n\n\t applyByGroup: function(series, e) {\n\t if ((e && e.action) || this.options.persistSeriesVisibility) {\n\t for (var idx = 0; idx < series.length; idx++) {\n\t if (this.groups[series[idx]._groupValue] === false) {\n\t series[idx].visible = false;\n\t }\n\t }\n\t } else {\n\t this.groups = {};\n\t }\n\t },\n\n\t applyByIndex: function(series, e) {\n\t if ((e && e.action) || this.options.persistSeriesVisibility) {\n\t if (this.index[series.index] === false) {\n\t series.visible = false;\n\t }\n\t } else {\n\t this.index = {};\n\t }\n\t },\n\n\t save: function(series) {\n\t if (!series) {\n\t return;\n\t }\n\n\t if (this.options.persistSeriesVisibility) {\n\t this.options.series[series.index].visible = series.visible;\n\t } else {\n\t this.saveState(series);\n\t }\n\t },\n\n\t setOptions: function(options) {\n\t this.options = options;\n\t this.groups = {};\n\t this.index = {};\n\t },\n\n\t read: function() {\n\t var options = this.options;\n\t if (options.persistSeriesVisibility) {\n\t var series = options.series;\n\t for (var idx = 0; idx < series.length; idx++) {\n\t this.saveState(series[idx]);\n\t }\n\t }\n\t },\n\n\t saveState: function(series) {\n\t if (defined(series._groupValue)) {\n\t this.groups[series._groupValue] = series.visible;\n\t } else {\n\t this.index[series.index] = series.visible;\n\t }\n\t }\n\t });\n\n\t var geom = kendo.geometry;\n\n\t function normalizeStyle(style) {\n\t for (var field in style) {\n\t if (style[field] === undefined) {\n\t style[field] = '';\n\t }\n\t }\n\n\t return style;\n\t }\n\n\t var Tooltip = Observable.extend({\n\t init: function(chartElement, options) {\n\t var tooltip = this;\n\n\t Observable.fn.init.call(tooltip);\n\n\t this.setOptions(options);\n\n\t tooltip.chartElement = chartElement;\n\n\t tooltip.template = Tooltip.template;\n\t if (!tooltip.template) {\n\t tooltip.template = Tooltip.template = kendo.template(\n\t \"
\" +\n\t \"
\", { useWithBlock: false, paramName: \"d\" });\n\t }\n\n\t tooltip.element = $(tooltip.template(tooltip.options));\n\n\t tooltip.move = proxy(tooltip.move, tooltip);\n\t tooltip._mouseleave = proxy(tooltip._mouseleave, tooltip);\n\n\t var mobileScrollerSelector = kendo.format(\"[{0}='content'],[{0}='scroller']\", kendo.attr(\"role\"));\n\t tooltip._mobileScroller = chartElement.closest(mobileScrollerSelector).data(\"kendoMobileScroller\");\n\t },\n\n\t destroy: function() {\n\t this._clearShowTimeout();\n\n\t if (this.element) {\n\t this.element.off(MOUSELEAVE_NS).remove();\n\t this.element = null;\n\t }\n\t },\n\n\t setOptions: function(options) {\n\t this.options = deepExtend({}, this.options, options);\n\t },\n\n\t options: {\n\t opacity: 1,\n\t animation: {\n\t duration: TOOLTIP_ANIMATION_DURATION\n\t },\n\t sharedTemplate:\n\t \"\" +\n\t \"\" +\n\t \"# for(var i = 0; i < points.length; i++) { #\" +\n\t \"# var point = points[i]; #\" +\n\t \"\" +\n\t \"# if(colorMarker) { # \" +\n\t \"\" +\n\t \"# } #\" +\n\t \"# if(nameColumn) { # \" +\n\t \"\" +\n\t \"# } #\" +\n\t \"\" +\n\t \"\" +\n\t \"# } #\" +\n\t \"
#= categoryText #
#if (point.series.name) {# #: point.series.name #: #} else {#   #}##= content(point) #
\",\n\t categoryFormat: \"{0:d}\"\n\t },\n\n\t move: function() {\n\t var tooltip = this,\n\t options = tooltip.options,\n\t element = tooltip.element,\n\t offset;\n\n\t if (!tooltip.anchor || !tooltip.element) {\n\t return;\n\t }\n\n\t offset = tooltip._offset();\n\t if (!tooltip.visible) {\n\t element.css({ top: offset.top, left: offset.left });\n\t }\n\n\t tooltip.visible = true;\n\t tooltip._ensureElement(document.body);\n\t element\n\t .stop(true, true)\n\t .show()\n\t .animate({\n\t left: offset.left,\n\t top: offset.top\n\t }, options.animation.duration);\n\t },\n\n\t _clearShowTimeout: function() {\n\t if (this.showTimeout) {\n\t clearTimeout(this.showTimeout);\n\t this.showTimeout = null;\n\t }\n\t },\n\n\t getAnchor: function(size) {\n\t var anchor = this.anchor;\n\t var point = anchor.point;\n\t var align = anchor.align;\n\t var x = point.left;\n\t var y = point.top;\n\t if (align.horizontal === \"center\") {\n\t x -= size.width / 2;\n\t } else if (align.horizontal === \"right\") {\n\t x -= size.width;\n\t }\n\n\t if (align.vertical === \"center\") {\n\t y -= size.height / 2;\n\t } else if (align.vertical === \"bottom\") {\n\t y -= size.height;\n\t }\n\n\t return {\n\t x: x,\n\t y: y\n\t };\n\t },\n\n\t _offset: function() {\n\t var tooltip = this,\n\t size = tooltip._measure(),\n\t anchor = tooltip.getAnchor(size),\n\t top = anchor.y,\n\t left = anchor.x,\n\t zoomLevel = kendo.support.zoomLevel(),\n\t viewport = $(window),\n\t scrollTop = window.pageYOffset || document.documentElement.scrollTop || 0,\n\t scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || 0,\n\t movable = (this._mobileScroller || {}).movable;\n\n\t if (!movable || movable.scale === 1) {\n\t top += tooltip._fit(top - scrollTop, size.height, outerHeight(viewport) / zoomLevel);\n\t left += tooltip._fit(left - scrollLeft, size.width, outerWidth(viewport) / zoomLevel);\n\t } else {\n\t var transform = geom.transform().scale(movable.scale, movable.scale, [movable.x, movable.y]);\n\t var point = new geom.Point(left, top).transform(transform);\n\t left = point.x;\n\t top = point.y;\n\t }\n\n\t return {\n\t top: top,\n\t left: left\n\t };\n\t },\n\n\t show: function(e) {\n\t this.anchor = e.anchor;\n\t this.element.css(normalizeStyle(e.style));\n\t this.element.toggleClass(TOOLTIP_INVERSE, !!e.className);\n\t this.element.toggleClass(SHARED_TOOLTIP_CLASS, !!e.shared);\n\n\t var content = e.shared ? this._sharedContent(e) : this._pointContent(e.point);\n\t this.element.html(content);\n\n\t this._clearShowTimeout();\n\t this.showTimeout = setTimeout(this.move, TOOLTIP_SHOW_DELAY);\n\t },\n\n\t hide: function() {\n\t var tooltip = this;\n\n\t clearTimeout(tooltip.showTimeout);\n\t tooltip._hideElement();\n\n\t if (tooltip.visible) {\n\t tooltip.point = null;\n\t tooltip.visible = false;\n\t tooltip.index = null;\n\t }\n\t },\n\n\t _sharedContent: function(e) {\n\t var points = e.points;\n\t var nameColumn = dataviz.grep(points, function(point) {\n\t return defined(point.series.name);\n\t }).length;\n\n\t var colorMarker = e.series.length > 1;\n\t var colspan = 1;\n\t if (nameColumn) {\n\t colspan++;\n\t }\n\t if (colorMarker) {\n\t colspan++;\n\t }\n\n\t var template = kendo.template(this.options.sharedTemplate);\n\t var content = template({\n\t points: points,\n\t category: e.category,\n\t categoryText: e.categoryText,\n\t content: this._pointContent,\n\t colorMarker: colorMarker,\n\t nameColumn: nameColumn,\n\t colspan: colspan\n\t });\n\n\t return content;\n\t },\n\n\t _measure: function() {\n\t this._ensureElement();\n\n\t var size = {\n\t width: outerWidth(this.element),\n\t height: outerHeight(this.element)\n\t };\n\n\t return size;\n\t },\n\n\t _ensureElement: function() {\n\t if (this.element) {\n\t this.element\n\t .appendTo(document.body)\n\t .on(MOUSELEAVE_NS, this._mouseleave);\n\t }\n\t },\n\n\t _mouseleave: function(e) {\n\t var target = e.relatedTarget;\n\t var chart = this.chartElement[0];\n\t if (target && target !== chart && !$.contains(chart, target)) {\n\t this.trigger(LEAVE);\n\t }\n\t },\n\n\t _hideElement: function() {\n\t var tooltip = this;\n\t var element = this.element;\n\t if (element) {\n\t element.fadeOut({\n\t always: function(){\n\t if (!tooltip.visible) {\n\t element.off(MOUSELEAVE_NS).remove();\n\t }\n\t }\n\t });\n\t }\n\t },\n\n\t _pointContent: function(point) {\n\t var tooltip = this,\n\t options = deepExtend({}, tooltip.options, point.options.tooltip),\n\t content, tooltipTemplate;\n\n\t if (defined(point.value)) {\n\t content = point.value.toString();\n\t }\n\n\t if (options.template) {\n\t tooltipTemplate = template(options.template);\n\t content = tooltipTemplate({\n\t value: point.value,\n\t category: point.category,\n\t series: point.series,\n\t dataItem: point.dataItem,\n\t percentage: point.percentage,\n\t runningTotal: point.runningTotal,\n\t total: point.total,\n\t low: point.low,\n\t high: point.high,\n\t xLow: point.xLow,\n\t xHigh: point.xHigh,\n\t yLow: point.yLow,\n\t yHigh: point.yHigh\n\t });\n\t } else if (options.format) {\n\t content = point.formatValue(options.format);\n\t }\n\n\t return content;\n\t },\n\n\t _fit: function(offset, size, viewPortSize) {\n\t var output = 0;\n\n\t if (offset + size > viewPortSize) {\n\t output = viewPortSize - (offset + size);\n\t }\n\n\t if (offset < 0) {\n\t output = -offset;\n\t }\n\n\t return output;\n\t }\n\t });\n\n\t var CrosshairTooltip = Tooltip.extend({\n\t init: function(chartElement, options) {\n\t Tooltip.fn.init.call(this, chartElement, options);\n\t this.element.addClass(\"k-chart-crosshair-tooltip\");\n\t },\n\n\t show: function(e) {\n\t var element = this.element;\n\n\t if (element) {\n\t this.anchor = e.anchor;\n\t this.element.css(e.style);\n\t this.element.html(this.content(e));\n\n\t this.move();\n\t }\n\t },\n\n\t move: function() {\n\t var tooltip = this,\n\t element = tooltip.element,\n\t offset = tooltip._offset();\n\n\t tooltip._ensureElement();\n\t element.css({ top: offset.top, left: offset.left }).show();\n\t },\n\n\t content: function(e) {\n\t var content = e.value,\n\t options = e.crosshair.options.tooltip;\n\n\t if (options.template) {\n\t content = template(options.template)({\n\t value: content\n\t });\n\t }\n\n\t return content;\n\t },\n\n\t hide: function() {\n\t this.element.hide();\n\t }\n\t });\n\n\t var ChartPane = Class.extend({\n\t init: function(chart, pane) {\n\t this._chart = chart;\n\t this._pane = pane;\n\t this.visual = pane.visual;\n\t this.chartsVisual = pane.chartContainer.visual;\n\t this.name = pane.options.name;\n\t },\n\n\t series: function() {\n\t var chart = this._chart;\n\t var seriesByPane = chart._plotArea.groupSeriesByPane();\n\t var series = seriesByPane[this.name || \"default\"];\n\n\t var result = [];\n\t if (series) {\n\t for (var idx = 0; idx < series.length; idx++) {\n\t result.push(new ChartSeries(chart, series[idx]));\n\t }\n\t }\n\n\t return result;\n\t }\n\t });\n\n\t var ChartSeries = Class.extend({\n\t init: function(chart, options) {\n\t this._chart = chart;\n\t this._options = options;\n\t },\n\n\t points: function(filter) {\n\t var points = this._points;\n\t if (!points) {\n\t var series = this._seriesOptions();\n\t var plotArea = this._chart._plotArea;\n\t this._points = points = plotArea.pointsBySeriesIndex(series.index);\n\t }\n\t if (kendo.isFunction(filter)) {\n\t points = this._filterPoints(points, filter);\n\t }\n\n\n\t return points;\n\t },\n\n\t data: function(data) {\n\t var series = this._seriesOptions();\n\t if (data) {\n\t var chart = this._chart;\n\t var plotArea = chart._plotArea;\n\n\t series.data = data;\n\n\t if (series.categoryField) {\n\t var axis = plotArea.seriesCategoryAxis(series);\n\t var options = [].concat(chart.options.categoryAxis);\n\n\t chart._instance.bindCategoryAxisFromSeries(options[axis.axisIndex], axis.axisIndex);\n\t }\n\n\t chart._noTransitionsRedraw();\n\t this._clearFields();\n\t }\n\n\t return series.data;\n\t },\n\n\t findPoint: function(filter) {\n\t var points = this.points();\n\t for (var idx = 0; idx < points.length; idx++) {\n\t if (filter(points[idx])) {\n\t return points[idx];\n\t }\n\t }\n\t },\n\n\t toggleHighlight: function(show, elements) {\n\t if (!elements) {\n\t elements = this.points();\n\t } else if (kendo.isFunction(elements)) {\n\t elements = this.points(elements);\n\t } else {\n\t elements = isArray(elements) ? elements : [elements];\n\t }\n\n\t this._chart._instance.togglePointsHighlight(show, elements);\n\t },\n\n\t toggleVisibility: function(visible, filter) {\n\t var chart = this._chart;\n\t var seriesOptions = this._seriesOptions();\n\t var hasFilter = kendo.isFunction(filter);\n\t if (!hasFilter) {\n\t seriesOptions.visible = visible;\n\t chart._seriesVisibility.save(seriesOptions);\n\t } else {\n\t if (inArray(seriesOptions.type, [PIE, DONUT, FUNNEL])) {\n\t var data = this._filterData(filter);\n\t for (var idx = 0; idx < data.length; idx++) {\n\t data[idx].visible = visible;\n\t }\n\t } else {\n\t seriesOptions.visible = function(data) {\n\t return filter(data.dataItem) ? visible : true;\n\t };\n\t }\n\t }\n\n\t chart._noTransitionsRedraw();\n\n\t this._clearFields();\n\t },\n\n\t _filterData: function(filter) {\n\t var data = this._seriesOptions().data;\n\t var length = data.length;\n\t var result = [];\n\n\t for (var idx = 0; idx < length; idx++) {\n\t if (filter(data[idx])) {\n\t result.push(data[idx]);\n\t }\n\t }\n\t return result;\n\t },\n\n\t _filterPoints: function(points, filter) {\n\t var result = [];\n\t var length = points.length;\n\t for (var idx = 0; idx < length; idx++) {\n\t if (filter(points[idx])) {\n\t result.push(points[idx]);\n\t }\n\t }\n\t return result;\n\t },\n\n\t _seriesOptions: function() {\n\t var series = this._series;\n\t if (!series) {\n\t series = this._series = this._chart._seriesOptions(this._options);\n\t }\n\t return series;\n\t },\n\n\t _clearFields: function() {\n\t delete this._points;\n\t delete this._series;\n\t }\n\t });\n\n\t function triggerPaneRender(panes) {\n\t for (var idx = 0; idx < panes.length; idx++) {\n\t panes[idx].notifyRender();\n\t }\n\t }\n\n\t dataviz.Tooltip = Tooltip;\n\t dataviz.CrosshairTooltip = CrosshairTooltip;\n\t dataviz.ChartInstanceObserver = ChartInstanceObserver;\n\t dataviz.ChartPane = ChartPane;\n\t dataviz.ChartSeries = ChartSeries;\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 856:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo-chart\");\n\n/***/ }),\n\n/***/ 857:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.data\");\n\n/***/ }),\n\n/***/ 858:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 859:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.themes\");\n\n/***/ }),\n\n/***/ 860:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.drawing\");\n\n/***/ }),\n\n/***/ 861:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.userevents\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(862);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 858:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 860:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.drawing\");\n\n/***/ }),\n\n/***/ 862:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/***********************************************************************\n\t * WARNING: this file is auto-generated. If you change it directly,\n\t * your modifications will eventually be lost. The source code is in\n\t * `kendo-charts` repository, you should make your changes there and\n\t * run `src-modules/sync.sh` in this repository.\n\t */\n\t(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(863),\n\t __webpack_require__(864),\n\t __webpack_require__(860),\n\t __webpack_require__(858)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\twindow.kendo.dataviz = window.kendo.dataviz || {};\n\tvar dataviz = kendo.dataviz;\n\tvar Class = dataviz.Class;\n\tvar isNumber = dataviz.isNumber;\n\tvar datavizConstants = dataviz.constants;\n\tvar MAX_VALUE = datavizConstants.MAX_VALUE;\n\tvar MIN_VALUE = datavizConstants.MIN_VALUE;\n\tvar VALUE = datavizConstants.VALUE;\n\tvar CENTER = datavizConstants.CENTER;\n\tvar TOP = datavizConstants.TOP;\n\tvar BOTTOM = datavizConstants.BOTTOM;\n\tvar LEFT = datavizConstants.LEFT;\n\tvar WHITE = datavizConstants.WHITE;\n\tvar CIRCLE = datavizConstants.CIRCLE;\n\tvar X = datavizConstants.X;\n\tvar Y = datavizConstants.Y;\n\tvar RIGHT = datavizConstants.RIGHT;\n\tvar BLACK = datavizConstants.BLACK;\n\tvar DATE = datavizConstants.DATE;\n\tvar DEFAULT_PRECISION = datavizConstants.DEFAULT_PRECISION;\n\tvar ARC = datavizConstants.ARC;\n\tvar defined = dataviz.defined;\n\tvar getter = dataviz.getter;\n\tvar isArray = dataviz.isArray;\n\tvar ChartElement = dataviz.ChartElement;\n\tvar Point = dataviz.Point;\n\tvar Box = dataviz.Box;\n\tvar alignPathToPixel = dataviz.alignPathToPixel;\n\tvar setDefaultOptions = dataviz.setDefaultOptions;\n\tvar inArray = dataviz.inArray;\n\tvar isFunction = dataviz.isFunction;\n\tvar valueOrDefault = dataviz.valueOrDefault;\n\tvar isObject = dataviz.isObject;\n\tvar deepExtend = dataviz.deepExtend;\n\tvar last = dataviz.last;\n\tvar eventElement = dataviz.eventElement;\n\tvar getTemplate = dataviz.getTemplate;\n\tvar TextBox = dataviz.TextBox;\n\tvar ShapeElement = dataviz.ShapeElement;\n\tvar getSpacing = dataviz.getSpacing;\n\tvar CurveProcessor = dataviz.CurveProcessor;\n\tvar append = dataviz.append;\n\tvar isString = dataviz.isString;\n\tvar parseDate = dataviz.parseDate;\n\tvar styleValue = dataviz.styleValue;\n\tvar CategoryAxis = dataviz.CategoryAxis;\n\tvar BoxElement = dataviz.BoxElement;\n\tvar round = dataviz.round;\n\tvar limitValue = dataviz.limitValue;\n\tvar grep = dataviz.grep;\n\tvar elementStyles = dataviz.elementStyles;\n\tvar hasClasses = dataviz.hasClasses;\n\tvar bindEvents = dataviz.bindEvents;\n\tvar services = dataviz.services;\n\tvar unbindEvents = dataviz.unbindEvents;\n\tvar support = kendo.support;\n\tvar drawing = kendo.drawing;\n\tvar Path = drawing.Path;\n\tvar Animation = drawing.Animation;\n\tvar AnimationFactory = drawing.AnimationFactory;\n\tvar Group = drawing.Group;\n\tvar Color = kendo.Color;\n\tvar geometry = kendo.geometry;\n\tvar GeometryPoint = geometry.Point;\n\tvar transform = geometry.transform;\n\n\tvar ChartAxis = Class.extend({\n\t init: function(axis) {\n\n\t this._axis = axis;\n\t this.options = axis.options;\n\t },\n\n\t value: function(point) {\n\t var axis = this._axis;\n\t var value = axis.getCategory ? axis.getCategory(point) : axis.getValue(point);\n\n\t return value;\n\t },\n\n\t slot: function(from, to, limit) {\n\t if (limit === void 0) { limit = true; }\n\n\t return this._axis.slot(from, to, limit);\n\t },\n\n\t range: function() {\n\t return this._axis.range();\n\t },\n\n\t valueRange: function() {\n\t return this._axis.valueRange();\n\t }\n\t});\n\n\tfunction findAxisByName(name, axes) {\n\t for (var idx = 0; idx < axes.length; idx++) {\n\t if (axes[idx].options.name === name) {\n\t axes[idx].prepareUserOptions();\n\t return new ChartAxis(axes[idx]);\n\t }\n\t }\n\t}\n\n\tvar ChartPane = kendo.Class.extend({\n\t init: function(pane) {\n\t this.visual = pane.visual;\n\t this.chartsVisual = pane.chartContainer.visual;\n\t this._pane = pane;\n\t },\n\n\t findAxisByName: function(name) {\n\t return findAxisByName(name, this._pane.axes);\n\t }\n\t});\n\n\tvar ChartPlotArea = Class.extend({\n\t init: function(plotArea) {\n\n\t this._plotArea = plotArea;\n\t this.visual = plotArea.visual;\n\t this.backgroundVisual = plotArea._bgVisual;\n\t }\n\t});\n\n\tfunction countNumbers(values) {\n\t var length = values.length;\n\t var count = 0;\n\n\t for (var i = 0; i < length; i++) {\n\t var num = values[i];\n\t if (isNumber(num)) {\n\t count++;\n\t }\n\t }\n\n\t return count;\n\t}\n\n\tvar Aggregates = {\n\t min: function(values) {\n\t var length = values.length;\n\t var min = MAX_VALUE;\n\n\t for (var i = 0; i < length; i++) {\n\t var value = values[i];\n\t if (isNumber(value)) {\n\t min = Math.min(min, value);\n\t }\n\t }\n\n\t return min === MAX_VALUE ? values[0] : min;\n\t },\n\n\t max: function(values) {\n\t var length = values.length;\n\t var max = MIN_VALUE;\n\n\t for (var i = 0; i < length; i++) {\n\t var value = values[i];\n\t if (isNumber(value)) {\n\t max = Math.max(max, value);\n\t }\n\t }\n\n\t return max === MIN_VALUE ? values[0] : max;\n\t },\n\n\t sum: function(values) {\n\t var length = values.length;\n\t var sum = 0;\n\n\t for (var i = 0; i < length; i++) {\n\t var value = values[i];\n\t if (isNumber(value)) {\n\t sum += value;\n\t }\n\t }\n\n\t return sum;\n\t },\n\n\t sumOrNull: function(values) {\n\t var result = null;\n\n\t if (countNumbers(values)) {\n\t result = Aggregates.sum(values);\n\t }\n\n\t return result;\n\t },\n\n\t count: function(values) {\n\t var length = values.length;\n\t var count = 0;\n\n\t for (var i = 0; i < length; i++) {\n\t var value = values[i];\n\t if (value !== null && defined(value)) {\n\t count++;\n\t }\n\t }\n\n\t return count;\n\t },\n\n\t avg: function(values) {\n\t var count = countNumbers(values);\n\t var result = values[0];\n\n\t if (count > 0) {\n\t result = Aggregates.sum(values) / count;\n\t }\n\n\t return result;\n\t },\n\n\t first: function(values) {\n\t var length = values.length;\n\n\t for (var i = 0; i < length; i++) {\n\t var value = values[i];\n\t if (value !== null && defined(value)) {\n\t return value;\n\t }\n\t }\n\n\t return values[0];\n\t }\n\t};\n\n\tfunction getField(field, row) {\n\t if (row === null) {\n\t return row;\n\t }\n\n\t var get = getter(field, true);\n\t return get(row);\n\t}\n\n\tvar SeriesBinder = Class.extend({\n\t init: function() {\n\n\t this._valueFields = {};\n\t this._otherFields = {};\n\t this._nullValue = {};\n\t this._undefinedValue = {};\n\t },\n\n\t register: function(seriesTypes, valueFields, otherFields) {\n\t var this$1 = this;\n\t if (valueFields === void 0) { valueFields = [ VALUE ]; }\n\t if (otherFields === void 0) { otherFields = {}; }\n\n\t for (var i = 0; i < seriesTypes.length; i++) {\n\t var type = seriesTypes[i];\n\n\t this$1._valueFields[type] = valueFields;\n\t this$1._otherFields[type] = otherFields;\n\t this$1._nullValue[type] = this$1._makeValue(valueFields, null);\n\t this$1._undefinedValue[type] = this$1._makeValue(valueFields, undefined);\n\t }\n\t },\n\n\t canonicalFields: function(series) {\n\t return this.valueFields(series).concat(this.otherFields(series));\n\t },\n\n\t valueFields: function(series) {\n\t return this._valueFields[series.type] || [ VALUE ];\n\t },\n\n\t otherFields: function(series) {\n\t return this._otherFields[series.type] || [ VALUE ];\n\t },\n\n\t bindPoint: function(series, pointIx, item) {\n\t var data = series.data;\n\t var pointData = defined(item) ? item : data[pointIx];\n\t var result = { valueFields: { value: pointData } };\n\t var valueFields = this.valueFields(series);\n\t var otherFields = this._otherFields[series.type];\n\t var fields, value;\n\n\t if (pointData === null) {\n\t value = this._nullValue[series.type];\n\t } else if (!defined(pointData)) {\n\t value = this._undefinedValue[series.type];\n\t } else if (Array.isArray(pointData)) {\n\t var fieldData = pointData.slice(valueFields.length);\n\t value = this._bindFromArray(pointData, valueFields);\n\t fields = this._bindFromArray(fieldData, otherFields);\n\t } else if (typeof pointData === \"object\") {\n\t var srcValueFields = this.sourceFields(series, valueFields);\n\t var srcPointFields = this.sourceFields(series, otherFields);\n\n\t value = this._bindFromObject(pointData, valueFields, srcValueFields);\n\t fields = this._bindFromObject(pointData, otherFields, srcPointFields);\n\t }\n\n\t if (defined(value)) {\n\t if (valueFields.length === 1) {\n\t result.valueFields.value = value[valueFields[0]];\n\t } else {\n\t result.valueFields = value;\n\t }\n\t }\n\n\t result.fields = fields || {};\n\n\t return result;\n\t },\n\n\t _makeValue: function(fields, initialValue) {\n\t var value = {};\n\t var length = fields.length;\n\n\t for (var i = 0; i < length; i++) {\n\t var fieldName = fields[i];\n\t value[fieldName] = initialValue;\n\t }\n\n\t return value;\n\t },\n\n\t _bindFromArray: function(array, fields) {\n\t var value = {};\n\n\t if (fields) {\n\t var length = Math.min(fields.length, array.length);\n\n\t for (var i = 0; i < length; i++) {\n\t value[fields[i]] = array[i];\n\t }\n\t }\n\n\t return value;\n\t },\n\n\t _bindFromObject: function(object, fields, srcFields) {\n\t if (srcFields === void 0) { srcFields = fields; }\n\n\t var value = {};\n\n\t if (fields) {\n\t var length = fields.length;\n\n\t for (var i = 0; i < length; i++) {\n\t var fieldName = fields[i];\n\t var srcFieldName = srcFields[i];\n\t if (srcFieldName !== null) {\n\t value[fieldName] = getField(srcFieldName, object);\n\t }\n\t }\n\t }\n\n\t return value;\n\t },\n\n\t sourceFields: function(series, canonicalFields) {\n\t var sourceFields = [];\n\n\t if (canonicalFields) {\n\t var length = canonicalFields.length;\n\n\t for (var i = 0; i < length; i++) {\n\t var fieldName = canonicalFields[i];\n\t var sourceFieldName = fieldName === VALUE ? \"field\" : fieldName + \"Field\";\n\n\t sourceFields.push(series[sourceFieldName] !== null ? (series[sourceFieldName] || fieldName) : null);\n\t }\n\t }\n\n\t return sourceFields;\n\t }\n\t});\n\n\tSeriesBinder.current = new SeriesBinder();\n\n\tvar STD_ERR = \"stderr\";\n\tvar STD_DEV = \"stddev\";\n\tvar percentRegex = /percent(?:\\w*)\\((\\d+)\\)/;\n\tvar standardDeviationRegex = new RegExp(\"^\" + STD_DEV + \"(?:\\\\((\\\\d+(?:\\\\.\\\\d+)?)\\\\))?$\");\n\n\tvar ErrorRangeCalculator = Class.extend({\n\t init: function(errorValue, series, field) {\n\n\t this.initGlobalRanges(errorValue, series, field);\n\t },\n\n\t initGlobalRanges: function(errorValue, series, field) {\n\t var data = series.data;\n\t var deviationMatch = standardDeviationRegex.exec(errorValue);\n\n\t if (deviationMatch) {\n\t this.valueGetter = this.createValueGetter(series, field);\n\n\t var average = this.getAverage(data);\n\t var deviation = this.getStandardDeviation(data, average, false);\n\t var multiple = deviationMatch[1] ? parseFloat(deviationMatch[1]) : 1;\n\t var errorRange = { low: average.value - deviation * multiple, high: average.value + deviation * multiple };\n\n\t this.globalRange = function() {\n\t return errorRange;\n\t };\n\t } else if (errorValue.indexOf && errorValue.indexOf(STD_ERR) >= 0) {\n\t this.valueGetter = this.createValueGetter(series, field);\n\t var standardError = this.getStandardError(data, this.getAverage(data));\n\n\t this.globalRange = function(value) {\n\t return { low: value - standardError, high: value + standardError };\n\t };\n\t }\n\t },\n\n\t createValueGetter: function(series, field) {\n\t var data = series.data;\n\t var binder = SeriesBinder.current;\n\t var valueFields = binder.valueFields(series);\n\t var item = defined(data[0]) ? data[0] : {};\n\t var valueGetter;\n\n\t if (isArray(item)) {\n\t var index = field ? valueFields.indexOf(field) : 0;\n\t valueGetter = getter(\"[\" + index + \"]\");\n\t } else if (isNumber(item)) {\n\t valueGetter = getter();\n\t } else if (typeof item === datavizConstants.OBJECT) {\n\t var srcValueFields = binder.sourceFields(series, valueFields);\n\t valueGetter = getter(srcValueFields[valueFields.indexOf(field)]);\n\t }\n\n\t return valueGetter;\n\t },\n\n\t getErrorRange: function(pointValue, errorValue) {\n\t var low, high, value;\n\n\t if (!defined(errorValue)) {\n\t return null;\n\t }\n\n\t if (this.globalRange) {\n\t return this.globalRange(pointValue);\n\t }\n\n\t if (isArray(errorValue)) {\n\t low = pointValue - errorValue[0];\n\t high = pointValue + errorValue[1];\n\t } else if (isNumber(value = parseFloat(errorValue))) {\n\t low = pointValue - value;\n\t high = pointValue + value;\n\t } else if ((value = percentRegex.exec(errorValue))) {\n\t var percentValue = pointValue * (parseFloat(value[1]) / 100);\n\t low = pointValue - Math.abs(percentValue);\n\t high = pointValue + Math.abs(percentValue);\n\t } else {\n\t throw new Error(\"Invalid ErrorBar value: \" + errorValue);\n\t }\n\n\t return { low: low, high: high };\n\t },\n\n\t getStandardError: function(data, average) {\n\t return this.getStandardDeviation(data, average, true) / Math.sqrt(average.count);\n\t },\n\n\t getStandardDeviation: function(data, average, isSample) {\n\t var this$1 = this;\n\n\t var length = data.length;\n\t var total = isSample ? average.count - 1 : average.count;\n\t var squareDifferenceSum = 0;\n\n\t for (var idx = 0; idx < length; idx++) {\n\t var value = this$1.valueGetter(data[idx]);\n\t if (isNumber(value)) {\n\t squareDifferenceSum += Math.pow(value - average.value, 2);\n\t }\n\t }\n\n\t return Math.sqrt(squareDifferenceSum / total);\n\t },\n\n\t getAverage: function(data) {\n\t var this$1 = this;\n\n\t var length = data.length;\n\t var sum = 0;\n\t var count = 0;\n\n\t for (var idx = 0; idx < length; idx++) {\n\t var value = this$1.valueGetter(data[idx]);\n\t if (isNumber(value)) {\n\t sum += value;\n\t count++;\n\t }\n\t }\n\n\t return {\n\t value: sum / count,\n\t count: count\n\t };\n\t }\n\t});\n\n\tvar browser = support.browser || {};\n\n\tvar INITIAL_ANIMATION_DURATION = 600;\n\tvar FADEIN = \"fadeIn\";\n\n\tvar GLASS = \"glass\";\n\tvar BORDER_BRIGHTNESS = 0.8;\n\tvar TOOLTIP_OFFSET = 5;\n\tvar START_SCALE = browser.msie ? 0.001 : 0;\n\tvar ERROR_LOW_FIELD = \"errorLow\";\n\tvar ERROR_HIGH_FIELD = \"errorHigh\";\n\tvar X_ERROR_LOW_FIELD = \"xErrorLow\";\n\tvar X_ERROR_HIGH_FIELD = \"xErrorHigh\";\n\tvar Y_ERROR_LOW_FIELD = \"yErrorLow\";\n\tvar Y_ERROR_HIGH_FIELD = \"yErrorHigh\";\n\tvar LINE_MARKER_SIZE = 8;\n\tvar ZERO = \"zero\";\n\tvar INTERPOLATE = \"interpolate\";\n\tvar GAP = \"gap\";\n\tvar ABOVE = \"above\";\n\tvar BELOW = \"below\";\n\n\tvar SMOOTH = \"smooth\";\n\tvar STEP = \"step\";\n\n\tvar AREA = \"area\";\n\tvar BAR = \"bar\";\n\tvar BOX_PLOT = \"boxPlot\";\n\tvar BUBBLE = \"bubble\";\n\tvar BULLET = \"bullet\";\n\tvar CANDLESTICK = \"candlestick\";\n\tvar COLUMN = \"column\";\n\tvar DONUT = \"donut\";\n\tvar FUNNEL = \"funnel\";\n\tvar HORIZONTAL_WATERFALL = \"horizontalWaterfall\";\n\tvar LINE = \"line\";\n\tvar OHLC = \"ohlc\";\n\tvar PIE = \"pie\";\n\tvar POLAR_AREA = \"polarArea\";\n\tvar POLAR_LINE = \"polarLine\";\n\tvar POLAR_SCATTER = \"polarScatter\";\n\tvar RADAR_AREA = \"radarArea\";\n\tvar RADAR_COLUMN = \"radarColumn\";\n\tvar RADAR_LINE = \"radarLine\";\n\tvar RANGE_AREA = \"rangeArea\";\n\tvar RANGE_BAR = \"rangeBar\";\n\tvar RANGE_COLUMN = \"rangeColumn\";\n\tvar SCATTER = \"scatter\";\n\tvar SCATTER_LINE = \"scatterLine\";\n\tvar VERTICAL_AREA = \"verticalArea\";\n\tvar VERTICAL_BOX_PLOT = \"verticalBoxPlot\";\n\tvar VERTICAL_BULLET = \"verticalBullet\";\n\tvar VERTICAL_LINE = \"verticalLine\";\n\tvar VERTICAL_RANGE_AREA = \"verticalRangeArea\";\n\tvar WATERFALL = \"waterfall\";\n\tvar EQUALLY_SPACED_SERIES = [\n\t BAR, COLUMN, OHLC, CANDLESTICK, BOX_PLOT, VERTICAL_BOX_PLOT,\n\t BULLET, RANGE_COLUMN, RANGE_BAR, WATERFALL, HORIZONTAL_WATERFALL\n\t];\n\n\tvar LEGEND_ITEM_CLICK = \"legendItemClick\";\n\tvar LEGEND_ITEM_HOVER = \"legendItemHover\";\n\tvar LEGEND_ITEM_LEAVE = \"legendItemLeave\";\n\tvar SERIES_CLICK = \"seriesClick\";\n\tvar SERIES_HOVER = \"seriesHover\";\n\tvar SERIES_OVER = \"seriesOver\";\n\tvar SERIES_LEAVE = \"seriesLeave\";\n\tvar PLOT_AREA_CLICK = \"plotAreaClick\";\n\tvar PLOT_AREA_HOVER = \"plotAreaHover\";\n\tvar PLOT_AREA_LEAVE = \"plotAreaLeave\";\n\tvar DRAG = \"drag\";\n\tvar DRAG_END = \"dragEnd\";\n\tvar DRAG_START = \"dragStart\";\n\tvar ZOOM_START = \"zoomStart\";\n\tvar ZOOM = \"zoom\";\n\tvar ZOOM_END = \"zoomEnd\";\n\tvar SELECT_START = \"selectStart\";\n\tvar SELECT = \"select\";\n\tvar SELECT_END = \"selectEnd\";\n\tvar RENDER = \"render\";\n\tvar SHOW_TOOLTIP = \"showTooltip\";\n\tvar HIDE_TOOLTIP = \"hideTooltip\";\n\tvar PANE_RENDER = \"paneRender\";\n\n\tvar LOGARITHMIC = \"log\";\n\tvar CATEGORY = \"category\";\n\n\tvar INSIDE_END = \"insideEnd\";\n\tvar INSIDE_BASE = \"insideBase\";\n\tvar OUTSIDE_END = \"outsideEnd\";\n\n\tvar MOUSEWHEEL = \"DOMMouseScroll mousewheel\";\n\tvar MOUSEWHEEL_DELAY = 150;\n\n\tvar constants = {\n\t\tINITIAL_ANIMATION_DURATION: INITIAL_ANIMATION_DURATION,\n\t\tFADEIN: FADEIN,\n\t\tLEGEND_ITEM_CLICK: LEGEND_ITEM_CLICK,\n\t\tLEGEND_ITEM_HOVER: LEGEND_ITEM_HOVER,\n\t\tLEGEND_ITEM_LEAVE: LEGEND_ITEM_LEAVE,\n\t\tSERIES_CLICK: SERIES_CLICK,\n\t\tSERIES_HOVER: SERIES_HOVER,\n\t\tSERIES_OVER: SERIES_OVER,\n\t\tSERIES_LEAVE: SERIES_LEAVE,\n\t\tGLASS: GLASS,\n\t\tBORDER_BRIGHTNESS: BORDER_BRIGHTNESS,\n\t\tTOOLTIP_OFFSET: TOOLTIP_OFFSET,\n\t\tSTART_SCALE: START_SCALE,\n\t\tERROR_LOW_FIELD: ERROR_LOW_FIELD,\n\t\tERROR_HIGH_FIELD: ERROR_HIGH_FIELD,\n\t\tX_ERROR_LOW_FIELD: X_ERROR_LOW_FIELD,\n\t\tX_ERROR_HIGH_FIELD: X_ERROR_HIGH_FIELD,\n\t\tY_ERROR_LOW_FIELD: Y_ERROR_LOW_FIELD,\n\t\tY_ERROR_HIGH_FIELD: Y_ERROR_HIGH_FIELD,\n\t\tLINE_MARKER_SIZE: LINE_MARKER_SIZE,\n\t\tINTERPOLATE: INTERPOLATE,\n\t\tZERO: ZERO,\n\t\tSMOOTH: SMOOTH,\n\t\tSTEP: STEP,\n\t\tCATEGORY: CATEGORY,\n\t\tFUNNEL: FUNNEL,\n\t\tBAR: BAR,\n\t\tCANDLESTICK: CANDLESTICK,\n\t\tPIE: PIE,\n\t\tCOLUMN: COLUMN,\n\t\tAREA: AREA,\n\t\tVERTICAL_BULLET: VERTICAL_BULLET,\n\t\tBOX_PLOT: BOX_PLOT,\n\t\tOHLC: OHLC,\n\t\tWATERFALL: WATERFALL,\n\t\tLINE: LINE,\n\t\tBULLET: BULLET,\n\t\tVERTICAL_LINE: VERTICAL_LINE,\n\t\tVERTICAL_AREA: VERTICAL_AREA,\n\t\tRANGE_AREA: RANGE_AREA,\n\t\tVERTICAL_RANGE_AREA: VERTICAL_RANGE_AREA,\n\t\tRANGE_COLUMN: RANGE_COLUMN,\n\t\tVERTICAL_BOX_PLOT: VERTICAL_BOX_PLOT,\n\t\tRANGE_BAR: RANGE_BAR,\n\t\tHORIZONTAL_WATERFALL: HORIZONTAL_WATERFALL,\n\t\tSCATTER: SCATTER,\n\t\tSCATTER_LINE: SCATTER_LINE,\n\t\tBUBBLE: BUBBLE,\n\t\tRADAR_AREA: RADAR_AREA,\n\t\tRADAR_LINE: RADAR_LINE,\n\t\tRADAR_COLUMN: RADAR_COLUMN,\n\t\tPOLAR_LINE: POLAR_LINE,\n\t\tPOLAR_AREA: POLAR_AREA,\n\t\tPOLAR_SCATTER: POLAR_SCATTER,\n\t\tRENDER: RENDER,\n\t\tPLOT_AREA_CLICK: PLOT_AREA_CLICK,\n\t\tPLOT_AREA_HOVER: PLOT_AREA_HOVER,\n\t\tPLOT_AREA_LEAVE: PLOT_AREA_LEAVE,\n\t\tLOGARITHMIC: LOGARITHMIC,\n\t\tDRAG: DRAG,\n\t\tDRAG_START: DRAG_START,\n\t\tDRAG_END: DRAG_END,\n\t\tZOOM_START: ZOOM_START,\n\t\tZOOM: ZOOM,\n\t\tZOOM_END: ZOOM_END,\n\t\tSELECT_START: SELECT_START,\n\t\tSELECT: SELECT,\n\t\tSELECT_END: SELECT_END,\n\t\tPANE_RENDER: PANE_RENDER,\n\t\tGAP: GAP,\n\t\tDONUT: DONUT,\n\t\tINSIDE_END: INSIDE_END,\n\t\tINSIDE_BASE: INSIDE_BASE,\n\t\tOUTSIDE_END: OUTSIDE_END,\n\t\tMOUSEWHEEL: MOUSEWHEEL,\n\t\tMOUSEWHEEL_DELAY: MOUSEWHEEL_DELAY,\n\t\tSHOW_TOOLTIP: SHOW_TOOLTIP,\n\t\tHIDE_TOOLTIP: HIDE_TOOLTIP,\n\t\tEQUALLY_SPACED_SERIES: EQUALLY_SPACED_SERIES,\n\t\tABOVE: ABOVE,\n\t\tBELOW: BELOW\n\t};\n\n\tvar DEFAULT_ERROR_BAR_WIDTH = 4;\n\n\tvar ErrorBarBase = ChartElement.extend({\n\t init: function(low, high, isVertical, chart, series, options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.low = low;\n\t this.high = high;\n\t this.isVertical = isVertical;\n\t this.chart = chart;\n\t this.series = series;\n\t },\n\n\t reflow: function(targetBox) {\n\t var endCaps = this.options.endCaps;\n\t var isVertical = this.isVertical;\n\t var axis = this.getAxis();\n\t var valueBox = axis.getSlot(this.low, this.high);\n\t var centerBox = targetBox.center();\n\t var capsWidth = this.getCapsWidth(targetBox, isVertical);\n\t var capValue = isVertical ? centerBox.x : centerBox.y;\n\t var capStart = capValue - capsWidth;\n\t var capEnd = capValue + capsWidth;\n\t var linePoints;\n\n\t if (isVertical) {\n\t linePoints = [\n\t new Point(centerBox.x, valueBox.y1),\n\t new Point(centerBox.x, valueBox.y2)\n\t ];\n\t if (endCaps) {\n\t linePoints.push(new Point(capStart, valueBox.y1),\n\t new Point(capEnd, valueBox.y1),\n\t new Point(capStart, valueBox.y2),\n\t new Point(capEnd, valueBox.y2));\n\t }\n\t this.box = new Box(capStart, valueBox.y1, capEnd, valueBox.y2);\n\t } else {\n\t linePoints = [\n\t new Point(valueBox.x1, centerBox.y),\n\t new Point(valueBox.x2, centerBox.y)\n\t ];\n\t if (endCaps) {\n\t linePoints.push(new Point(valueBox.x1, capStart),\n\t new Point(valueBox.x1, capEnd),\n\t new Point(valueBox.x2, capStart),\n\t new Point(valueBox.x2, capEnd));\n\t }\n\t this.box = new Box(valueBox.x1, capStart, valueBox.x2, capEnd);\n\t }\n\n\t this.linePoints = linePoints;\n\t },\n\n\t getCapsWidth: function(box, isVertical) {\n\t var boxSize = isVertical ? box.width() : box.height();\n\t var capsWidth = Math.min(Math.floor(boxSize / 2), DEFAULT_ERROR_BAR_WIDTH) || DEFAULT_ERROR_BAR_WIDTH;\n\n\t return capsWidth;\n\t },\n\n\t createVisual: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var visual = options.visual;\n\n\t if (visual) {\n\t this.visual = visual({\n\t low: this.low,\n\t high: this.high,\n\t rect: this.box.toRect(),\n\t sender: this.getSender(),\n\t options: {\n\t endCaps: options.endCaps,\n\t color: options.color,\n\t line: options.line\n\t },\n\t createVisual: function () {\n\t this$1.createDefaultVisual();\n\t var defaultVisual = this$1.visual;\n\t delete this$1.visual;\n\t return defaultVisual;\n\t }\n\t });\n\t } else {\n\t this.createDefaultVisual();\n\t }\n\t },\n\n\t createDefaultVisual: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var options = ref.options;\n\t var linePoints = ref.linePoints;\n\t var lineOptions = {\n\t stroke: {\n\t color: options.color,\n\t width: options.line.width,\n\t dashType: options.line.dashType\n\t }\n\t };\n\n\t ChartElement.fn.createVisual.call(this);\n\n\t for (var idx = 0; idx < linePoints.length; idx += 2) {\n\t var line = new Path(lineOptions)\n\t .moveTo(linePoints[idx].x, linePoints[idx].y)\n\t .lineTo(linePoints[idx + 1].x, linePoints[idx + 1].y);\n\n\t alignPathToPixel(line);\n\t this$1.visual.append(line);\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(ErrorBarBase, {\n\t animation: {\n\t type: FADEIN,\n\t delay: INITIAL_ANIMATION_DURATION\n\t },\n\t endCaps: true,\n\t line: {\n\t width: 2\n\t },\n\t zIndex: 1\n\t});\n\n\tvar CategoricalErrorBar = ErrorBarBase.extend({\n\t getAxis: function() {\n\t var axis = this.chart.seriesValueAxis(this.series);\n\n\t return axis;\n\t }\n\t});\n\n\tvar MAX_EXPAND_DEPTH = 5;\n\n\tfunction evalOptions(options, context, state, dryRun) {\n\t if (state === void 0) { state = {}; }\n\t if (dryRun === void 0) { dryRun = false; }\n\n\t var defaults = state.defaults = state.defaults || {};\n\t var depth = state.depth = state.depth || 0;\n\t var needsEval = false;\n\n\t state.excluded = state.excluded || [];\n\n\t if (depth > MAX_EXPAND_DEPTH) {\n\t return null;\n\t }\n\n\t for (var property in options) {\n\t if (!inArray(property, state.excluded) && options.hasOwnProperty(property)) {\n\t var propValue = options[property];\n\t if (isFunction(propValue)) {\n\t needsEval = true;\n\t if (!dryRun) {\n\t options[property] = valueOrDefault(propValue(context), defaults[property]);\n\t }\n\t } else if (isObject(propValue)) {\n\t if (!dryRun) {\n\t state.defaults = defaults[property];\n\t }\n\t state.depth++;\n\t needsEval = evalOptions(propValue, context, state, dryRun) || needsEval;\n\t state.depth--;\n\t }\n\t }\n\t }\n\n\t return needsEval;\n\t}\n\n\tfunction categoriesCount(series) {\n\t var seriesCount = series.length;\n\t var categories = 0;\n\n\t for (var i = 0; i < seriesCount; i++) {\n\t categories = Math.max(categories, series[i].data.length);\n\t }\n\n\t return categories;\n\t}\n\n\tvar CategoricalChart = ChartElement.extend({\n\t init: function(plotArea, options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.plotArea = plotArea;\n\t this.chartService = plotArea.chartService;\n\t this.categoryAxis = plotArea.seriesCategoryAxis(options.series[0]);\n\n\t // Value axis ranges grouped by axis name, e.g.:\n\t // primary: { min: 0, max: 1 }\n\t this.valueAxisRanges = {};\n\n\t this.points = [];\n\t this.categoryPoints = [];\n\t this.seriesPoints = [];\n\t this.seriesOptions = [];\n\t this._evalSeries = [];\n\n\t this.render();\n\t },\n\n\t render: function() {\n\t this.traverseDataPoints(this.addValue.bind(this));\n\t },\n\n\t pointOptions: function(series, seriesIx) {\n\t var options = this.seriesOptions[seriesIx];\n\t if (!options) {\n\t var defaults = this.pointType().prototype.defaults;\n\t this.seriesOptions[seriesIx] = options = deepExtend({ }, defaults, {\n\t vertical: !this.options.invertAxes\n\t }, series);\n\t }\n\n\t return options;\n\t },\n\n\t plotValue: function(point) {\n\t if (!point) {\n\t return 0;\n\t }\n\n\t if (this.options.isStacked100 && isNumber(point.value)) {\n\t var categoryIx = point.categoryIx;\n\t var categoryPoints = this.categoryPoints[categoryIx];\n\t var otherValues = [];\n\t var categorySum = 0;\n\n\t for (var i = 0; i < categoryPoints.length; i++) {\n\t var other = categoryPoints[i];\n\t if (other) {\n\t var stack = point.series.stack;\n\t var otherStack = other.series.stack;\n\n\t if ((stack && otherStack) && stack.group !== otherStack.group) {\n\t continue;\n\t }\n\n\t if (isNumber(other.value)) {\n\t categorySum += Math.abs(other.value);\n\t otherValues.push(Math.abs(other.value));\n\t }\n\t }\n\t }\n\n\t if (categorySum > 0) {\n\t return point.value / categorySum;\n\t }\n\t }\n\n\t return point.value;\n\t },\n\n\t plotRange: function(point, startValue) {\n\t var this$1 = this;\n\t if (startValue === void 0) { startValue = 0; }\n\n\t var categoryPoints = this.categoryPoints[point.categoryIx];\n\n\t if (this.options.isStacked) {\n\t var plotValue = this.plotValue(point);\n\t var positive = plotValue >= 0;\n\t var prevValue = startValue;\n\t var isStackedBar = false;\n\n\t for (var i = 0; i < categoryPoints.length; i++) {\n\t var other = categoryPoints[i];\n\n\t if (point === other) {\n\t break;\n\t }\n\n\t var stack = point.series.stack;\n\t var otherStack = other.series.stack;\n\t if (stack && otherStack) {\n\t if (typeof stack === datavizConstants.STRING && stack !== otherStack) {\n\t continue;\n\t }\n\n\t if (stack.group && stack.group !== otherStack.group) {\n\t continue;\n\t }\n\t }\n\n\t var otherValue = this$1.plotValue(other);\n\t if ((otherValue >= 0 && positive) ||\n\t (otherValue < 0 && !positive)) {\n\t prevValue += otherValue;\n\t plotValue += otherValue;\n\t isStackedBar = true;\n\n\t if (this$1.options.isStacked100) {\n\t plotValue = Math.min(plotValue, 1);\n\t }\n\t }\n\t }\n\n\t if (isStackedBar) {\n\t prevValue -= startValue;\n\t }\n\n\t return [ prevValue, plotValue ];\n\t }\n\n\t var series = point.series;\n\t var valueAxis = this.seriesValueAxis(series);\n\t var axisCrossingValue = this.categoryAxisCrossingValue(valueAxis);\n\n\t return [ axisCrossingValue, dataviz.convertableToNumber(point.value) ? point.value : axisCrossingValue ];\n\t },\n\n\t stackLimits: function(axisName, stackName) {\n\t var this$1 = this;\n\n\t var min = MAX_VALUE;\n\t var max = MIN_VALUE;\n\n\t for (var i = 0; i < this.categoryPoints.length; i++) {\n\t var categoryPoints = this$1.categoryPoints[i];\n\t if (!categoryPoints) {\n\t continue;\n\t }\n\n\t for (var pIx = 0; pIx < categoryPoints.length; pIx++) {\n\t var point = categoryPoints[pIx];\n\t if (point) {\n\t if (point.series.stack === stackName || point.series.axis === axisName) {\n\t var to = this$1.plotRange(point, 0)[1];\n\t if (defined(to) && isFinite(to)) {\n\t max = Math.max(max, to);\n\t min = Math.min(min, to);\n\t }\n\t }\n\t }\n\t }\n\t }\n\n\t return { min: min, max: max };\n\t },\n\n\t updateStackRange: function() {\n\t var this$1 = this;\n\n\t var ref = this.options;\n\t var isStacked = ref.isStacked;\n\t var chartSeries = ref.series;\n\t var limitsCache = {};\n\n\t if (isStacked) {\n\t for (var i = 0; i < chartSeries.length; i++) {\n\t var series = chartSeries[i];\n\t var axisName = series.axis;\n\t var key = axisName + series.stack;\n\n\t var limits = limitsCache[key];\n\t if (!limits) {\n\t limits = this$1.stackLimits(axisName, series.stack);\n\n\t var errorTotals = this$1.errorTotals;\n\t if (errorTotals) {\n\t if (errorTotals.negative.length) {\n\t limits.min = Math.min(limits.min, dataviz.sparseArrayLimits(errorTotals.negative).min);\n\t }\n\t if (errorTotals.positive.length) {\n\t limits.max = Math.max(limits.max, dataviz.sparseArrayLimits(errorTotals.positive).max);\n\t }\n\t }\n\n\t if (limits.min !== MAX_VALUE || limits.max !== MIN_VALUE) {\n\t limitsCache[key] = limits;\n\t } else {\n\t limits = null;\n\t }\n\t }\n\n\t if (limits) {\n\t this$1.valueAxisRanges[axisName] = limits;\n\t }\n\t }\n\t }\n\t },\n\n\t addErrorBar: function(point, data, categoryIx) {\n\t var value = point.value;\n\t var series = point.series;\n\t var seriesIx = point.seriesIx;\n\t var errorBars = point.options.errorBars;\n\t var lowValue = data.fields[ERROR_LOW_FIELD];\n\t var highValue = data.fields[ERROR_HIGH_FIELD];\n\t var errorRange;\n\n\t if (isNumber(lowValue) && isNumber(highValue)) {\n\t errorRange = { low: lowValue, high: highValue };\n\t } else if (errorBars && defined(errorBars.value)) {\n\t this.seriesErrorRanges = this.seriesErrorRanges || [];\n\t this.seriesErrorRanges[seriesIx] = this.seriesErrorRanges[seriesIx] ||\n\t new ErrorRangeCalculator(errorBars.value, series, VALUE);\n\n\t errorRange = this.seriesErrorRanges[seriesIx].getErrorRange(value, errorBars.value);\n\t }\n\n\t if (errorRange) {\n\t point.low = errorRange.low;\n\t point.high = errorRange.high;\n\t this.addPointErrorBar(point, categoryIx);\n\t }\n\t },\n\n\t addPointErrorBar: function(point, categoryIx) {\n\t var isVertical = !this.options.invertAxes;\n\t var options = point.options.errorBars;\n\t var series = point.series;\n\t var low = point.low;\n\t var high = point.high;\n\n\t if (this.options.isStacked) {\n\t var stackedErrorRange = this.stackedErrorRange(point, categoryIx);\n\t low = stackedErrorRange.low;\n\t high = stackedErrorRange.high;\n\t } else {\n\t var fields = { categoryIx: categoryIx, series: series };\n\t this.updateRange({ value: low }, fields);\n\t this.updateRange({ value: high }, fields);\n\t }\n\n\t var errorBar = new CategoricalErrorBar(low, high, isVertical, this, series, options);\n\t point.errorBars = [ errorBar ];\n\t point.append(errorBar);\n\t },\n\n\t stackedErrorRange: function(point, categoryIx) {\n\t var plotValue = this.plotRange(point, 0)[1] - point.value;\n\t var low = point.low + plotValue;\n\t var high = point.high + plotValue;\n\n\t this.errorTotals = this.errorTotals || { positive: [], negative: [] };\n\n\t if (low < 0) {\n\t this.errorTotals.negative[categoryIx] = Math.min(this.errorTotals.negative[categoryIx] || 0, low);\n\t }\n\n\t if (high > 0) {\n\t this.errorTotals.positive[categoryIx] = Math.max(this.errorTotals.positive[categoryIx] || 0, high);\n\t }\n\n\t return { low: low, high: high };\n\t },\n\n\t addValue: function(data, fields) {\n\t var categoryIx = fields.categoryIx;\n\t var series = fields.series;\n\t var seriesIx = fields.seriesIx;\n\n\t var categoryPoints = this.categoryPoints[categoryIx];\n\t if (!categoryPoints) {\n\t this.categoryPoints[categoryIx] = categoryPoints = [];\n\t }\n\n\t var seriesPoints = this.seriesPoints[seriesIx];\n\t if (!seriesPoints) {\n\t this.seriesPoints[seriesIx] = seriesPoints = [];\n\t }\n\n\t var point = this.createPoint(data, fields);\n\t if (point) {\n\t $.extend(point, fields);\n\n\t point.owner = this;\n\t point.noteText = data.fields.noteText;\n\t if (!defined(point.dataItem)) {\n\t point.dataItem = series.data[categoryIx];\n\t }\n\t this.addErrorBar(point, data, categoryIx);\n\t }\n\n\t this.points.push(point);\n\t seriesPoints.push(point);\n\t categoryPoints.push(point);\n\n\t this.updateRange(data.valueFields, fields);\n\t },\n\n\t evalPointOptions: function(options, value, category, categoryIx, series, seriesIx) {\n\t var state = { defaults: series._defaults, excluded: [ \"data\", \"aggregate\", \"_events\", \"tooltip\", \"content\", \"template\", \"visual\", \"toggle\", \"_outOfRangeMinPoint\", \"_outOfRangeMaxPoint\" ] };\n\n\t var doEval = this._evalSeries[seriesIx];\n\t if (!defined(doEval)) {\n\t this._evalSeries[seriesIx] = doEval = evalOptions(options, {}, state, true);\n\t }\n\n\t var pointOptions = options;\n\t if (doEval) {\n\t pointOptions = deepExtend({}, pointOptions);\n\t evalOptions(pointOptions, {\n\t value: value,\n\t category: category,\n\t index: categoryIx,\n\t series: series,\n\t dataItem: series.data[categoryIx]\n\t }, state);\n\t }\n\n\t return pointOptions;\n\t },\n\n\t updateRange: function(data, fields) {\n\t var axisName = fields.series.axis;\n\t var value = data.value;\n\t var axisRange = this.valueAxisRanges[axisName];\n\n\t if (isFinite(value) && value !== null) {\n\t axisRange = this.valueAxisRanges[axisName] =\n\t axisRange || { min: MAX_VALUE, max: MIN_VALUE };\n\n\t axisRange.min = Math.min(axisRange.min, value);\n\t axisRange.max = Math.max(axisRange.max, value);\n\t }\n\t },\n\n\t seriesValueAxis: function(series) {\n\t var plotArea = this.plotArea;\n\t var axisName = series.axis;\n\t var axis = axisName ? plotArea.namedValueAxes[axisName] : plotArea.valueAxis;\n\n\t if (!axis) {\n\t throw new Error(\"Unable to locate value axis with name \" + axisName);\n\t }\n\n\t return axis;\n\t },\n\n\t reflow: function(targetBox) {\n\t var this$1 = this;\n\n\t var categorySlots = this.categorySlots = [];\n\t var chartPoints = this.points;\n\t var categoryAxis = this.categoryAxis;\n\t var pointIx = 0;\n\n\t this.traverseDataPoints(function (data, fields) {\n\t var categoryIx = fields.categoryIx;\n\t var currentSeries = fields.series;\n\n\t var valueAxis = this$1.seriesValueAxis(currentSeries);\n\t var point = chartPoints[pointIx++];\n\n\t var categorySlot = categorySlots[categoryIx];\n\t if (!categorySlot) {\n\t categorySlots[categoryIx] = categorySlot =\n\t this$1.categorySlot(categoryAxis, categoryIx, valueAxis);\n\t }\n\n\t if (point) {\n\t var plotRange = this$1.plotRange(point, valueAxis.startValue());\n\t var valueSlot = this$1.valueSlot(valueAxis, plotRange);\n\t if (valueSlot) {\n\t var pointSlot = this$1.pointSlot(categorySlot, valueSlot);\n\n\t point.aboveAxis = this$1.aboveAxis(point, valueAxis);\n\t point.stackValue = plotRange[1];\n\n\t if (this$1.options.isStacked100) {\n\t point.percentage = this$1.plotValue(point);\n\t }\n\n\t this$1.reflowPoint(point, pointSlot);\n\t } else {\n\t point.visible = false;\n\t }\n\t }\n\t });\n\n\t this.reflowCategories(categorySlots);\n\t if (!this.options.clip && this.options.limitPoints && this.points.length) {\n\t this.limitPoints();\n\t }\n\n\t this.box = targetBox;\n\t },\n\n\t valueSlot: function(valueAxis, plotRange) {\n\t return valueAxis.getSlot(plotRange[0], plotRange[1], !this.options.clip);\n\t },\n\n\t limitPoints: function() {\n\t var this$1 = this;\n\n\t var categoryPoints = this.categoryPoints;\n\t var points = categoryPoints[0].concat(last(categoryPoints));\n\t for (var idx = 0; idx < points.length; idx++) {\n\t if (points[idx]) {\n\t this$1.limitPoint(points[idx]);\n\t }\n\t }\n\t },\n\n\t limitPoint: function(point) {\n\t var limittedSlot = this.categoryAxis.limitSlot(point.box);\n\t if (!limittedSlot.equals(point.box)) {\n\t point.reflow(limittedSlot);\n\t }\n\t },\n\n\t aboveAxis: function(point, valueAxis) {\n\t var axisCrossingValue = this.categoryAxisCrossingValue(valueAxis);\n\t var value = point.value;\n\n\t return valueAxis.options.reverse ?\n\t value < axisCrossingValue : value >= axisCrossingValue;\n\t },\n\n\t categoryAxisCrossingValue: function(valueAxis) {\n\t var categoryAxis = this.categoryAxis;\n\t var options = valueAxis.options;\n\t var crossingValues = [].concat(\n\t options.axisCrossingValues || options.axisCrossingValue\n\t );\n\n\t return crossingValues[categoryAxis.axisIndex || 0] || 0;\n\t },\n\n\t reflowPoint: function(point, pointSlot) {\n\t point.reflow(pointSlot);\n\t },\n\n\t reflowCategories: function() { },\n\n\t pointSlot: function(categorySlot, valueSlot) {\n\t var options = this.options;\n\t var invertAxes = options.invertAxes;\n\t var slotX = invertAxes ? valueSlot : categorySlot;\n\t var slotY = invertAxes ? categorySlot : valueSlot;\n\n\t return new Box(slotX.x1, slotY.y1, slotX.x2, slotY.y2);\n\t },\n\n\t categorySlot: function(categoryAxis, categoryIx) {\n\t return categoryAxis.getSlot(categoryIx);\n\t },\n\n\t traverseDataPoints: function(callback) {\n\t var this$1 = this;\n\n\t var series = this.options.series;\n\t var count = categoriesCount(series);\n\t var seriesCount = series.length;\n\n\t for (var seriesIx = 0; seriesIx < seriesCount; seriesIx++) {\n\t this$1._outOfRangeCallback(series[seriesIx], \"_outOfRangeMinPoint\", seriesIx, callback);\n\t }\n\n\t for (var categoryIx = 0; categoryIx < count; categoryIx++) {\n\t for (var seriesIx$1 = 0; seriesIx$1 < seriesCount; seriesIx$1++) {\n\t var currentSeries = series[seriesIx$1];\n\t var currentCategory = this$1.categoryAxis.categoryAt(categoryIx);\n\t var pointData = this$1._bindPoint(currentSeries, seriesIx$1, categoryIx);\n\n\t callback(pointData, {\n\t category: currentCategory,\n\t categoryIx: categoryIx,\n\t categoriesCount: count,\n\t series: currentSeries,\n\t seriesIx: seriesIx$1\n\t });\n\t }\n\t }\n\n\t for (var seriesIx$2 = 0; seriesIx$2 < seriesCount; seriesIx$2++) {\n\t this$1._outOfRangeCallback(series[seriesIx$2], \"_outOfRangeMaxPoint\", seriesIx$2, callback);\n\t }\n\t },\n\n\t _outOfRangeCallback: function(series, field, seriesIx, callback) {\n\t var outOfRangePoint = series[field];\n\t if (outOfRangePoint) {\n\t var categoryIx = outOfRangePoint.categoryIx;\n\t var pointData = this._bindPoint(series, seriesIx, categoryIx, outOfRangePoint.item);\n\n\t callback(pointData, {\n\t category: outOfRangePoint.category,\n\t categoryIx: categoryIx,\n\t series: series,\n\t seriesIx: seriesIx,\n\t dataItem: outOfRangePoint.item\n\t });\n\t }\n\t },\n\n\t _bindPoint: function(series, seriesIx, categoryIx, item) {\n\t if (!this._bindCache) {\n\t this._bindCache = [];\n\t }\n\n\t var bindCache = this._bindCache[seriesIx];\n\t if (!bindCache) {\n\t bindCache = this._bindCache[seriesIx] = [];\n\t }\n\n\t var data = bindCache[categoryIx];\n\t if (!data) {\n\t data = bindCache[categoryIx] = SeriesBinder.current.bindPoint(series, categoryIx, item);\n\t }\n\n\t return data;\n\t },\n\n\t formatPointValue: function(point, format) {\n\t if (point.value === null) {\n\t return \"\";\n\t }\n\n\t return this.chartService.format.auto(format, point.value);\n\t },\n\n\t pointValue: function(data) {\n\t return data.valueFields.value;\n\t }\n\t});\n\n\tsetDefaultOptions(CategoricalChart, {\n\t series: [],\n\t invertAxes: false,\n\t isStacked: false,\n\t clip: true,\n\t limitPoints: true\n\t});\n\n\tvar PointEventsMixin = {\n\t click: function(chart, e) {\n\t return chart.trigger(\n\t SERIES_CLICK,\n\t this.eventArgs(e)\n\t );\n\t },\n\n\t hover: function(chart, e) {\n\t return chart.trigger(\n\t SERIES_HOVER,\n\t this.eventArgs(e)\n\t );\n\t },\n\n\t over: function(chart, e) {\n\t return chart.trigger(\n\t SERIES_OVER,\n\t this.eventArgs(e)\n\t );\n\t },\n\n\t out: function(chart, e) {\n\t return chart.trigger(\n\t SERIES_LEAVE,\n\t this.eventArgs(e)\n\t );\n\t },\n\n\t eventArgs: function(e) {\n\t return {\n\t value: this.value,\n\t percentage: this.percentage,\n\t stackValue: this.stackValue,\n\t category: this.category,\n\t series: this.series,\n\t dataItem: this.dataItem,\n\t runningTotal: this.runningTotal,\n\t total: this.total,\n\t element: eventElement(e),\n\t originalEvent: e,\n\t point: this\n\t };\n\t }\n\t};\n\n\tvar NoteMixin = {\n\t createNote: function() {\n\t var options = this.options.notes;\n\t var text = this.noteText || options.label.text;\n\n\t if (options.visible !== false && defined(text) && text !== null) {\n\t this.note = new dataviz.Note({\n\t value: this.value,\n\t text: text,\n\t dataItem: this.dataItem,\n\t category: this.category,\n\t series: this.series\n\t }, this.options.notes, this.owner.chartService);\n\n\t this.append(this.note);\n\t }\n\t }\n\t};\n\n\tvar LinePoint = ChartElement.extend({\n\t init: function(value, options) {\n\t ChartElement.fn.init.call(this);\n\n\t this.value = value;\n\t this.options = options;\n\t this.aboveAxis = valueOrDefault(this.options.aboveAxis, true);\n\t this.tooltipTracking = true;\n\t },\n\n\t render: function() {\n\t var ref = this.options;\n\t var markers = ref.markers;\n\t var labels = ref.labels;\n\n\t if (this._rendered) {\n\t return;\n\t }\n\n\t this._rendered = true;\n\n\t if (markers.visible && markers.size) {\n\t this.marker = this.createMarker();\n\t this.append(this.marker);\n\t }\n\n\t if (labels.visible) {\n\t var labelTemplate = getTemplate(labels);\n\t var pointData = this.pointData();\n\t var labelText = this.value;\n\t if (labelTemplate) {\n\t labelText = labelTemplate(pointData);\n\t } else if (labels.format) {\n\t labelText = this.formatValue(labels.format);\n\t }\n\t this.label = new TextBox(labelText,\n\t deepExtend({\n\t align: CENTER,\n\t vAlign: CENTER,\n\t margin: {\n\t left: 5,\n\t right: 5\n\t },\n\t zIndex: valueOrDefault(labels.zIndex, this.series.zIndex)\n\t }, labels),\n\t pointData\n\t );\n\t this.append(this.label);\n\t }\n\n\t this.createNote();\n\n\t if (this.errorBar) {\n\t this.append(this.errorBar);\n\t }\n\t },\n\n\t markerBorder: function() {\n\t var options = this.options.markers;\n\t var background = options.background;\n\t var border = deepExtend({ color: this.color }, options.border);\n\n\t if (!defined(border.color)) {\n\t border.color = new Color(background).brightness(BORDER_BRIGHTNESS).toHex();\n\t }\n\n\t return border;\n\t },\n\n\t createVisual: function() {},\n\n\t createMarker: function() {\n\t var options = this.options.markers;\n\t var marker = new ShapeElement({\n\t type: options.type,\n\t width: options.size,\n\t height: options.size,\n\t rotation: options.rotation,\n\t background: options.background,\n\t border: this.markerBorder(),\n\t opacity: options.opacity,\n\t zIndex: valueOrDefault(options.zIndex, this.series.zIndex),\n\t animation: options.animation,\n\t visual: options.visual\n\t }, {\n\t dataItem: this.dataItem,\n\t value: this.value,\n\t series: this.series,\n\t category: this.category\n\t });\n\n\t return marker;\n\t },\n\n\t markerBox: function() {\n\t if (!this.marker) {\n\t this.marker = this.createMarker();\n\t this.marker.reflow(this._childBox);\n\t }\n\n\t return this.marker.box;\n\t },\n\n\t reflow: function(targetBox) {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var options = ref.options;\n\t var aboveAxis = ref.aboveAxis;\n\t var vertical = options.vertical;\n\n\t this.render();\n\n\t this.box = targetBox;\n\t var childBox = targetBox.clone();\n\n\t if (vertical) {\n\t if (aboveAxis) {\n\t childBox.y1 -= childBox.height();\n\t } else {\n\t childBox.y2 += childBox.height();\n\t }\n\t } else {\n\t if (aboveAxis) {\n\t childBox.x1 += childBox.width();\n\t } else {\n\t childBox.x2 -= childBox.width();\n\t }\n\t }\n\n\t this._childBox = childBox;\n\t if (this.marker) {\n\t this.marker.reflow(childBox);\n\t }\n\n\t this.reflowLabel(childBox);\n\n\t if (this.errorBars) {\n\t for (var i = 0; i < this.errorBars.length; i++) {\n\t this$1.errorBars[i].reflow(childBox);\n\t }\n\t }\n\n\t if (this.note) {\n\t var noteTargetBox = this.markerBox();\n\n\t if (!(options.markers.visible && options.markers.size)) {\n\t var center = noteTargetBox.center();\n\t noteTargetBox = new Box(center.x, center.y, center.x, center.y);\n\t }\n\n\t this.note.reflow(noteTargetBox);\n\t }\n\t },\n\n\t reflowLabel: function(box) {\n\t var ref = this;\n\t var options = ref.options;\n\t var label = ref.label;\n\t var anchor = options.labels.position;\n\n\t if (label) {\n\t anchor = anchor === ABOVE ? TOP : anchor;\n\t anchor = anchor === BELOW ? BOTTOM : anchor;\n\n\t label.reflow(box);\n\t label.box.alignTo(this.markerBox(), anchor);\n\t label.reflow(label.box);\n\t }\n\t },\n\n\t createHighlight: function() {\n\t var markers = this.options.highlight.markers;\n\t var defaultColor = this.markerBorder().color;\n\t var options = this.options.markers;\n\t var size = options.size + (options.border.width || 0) + (markers.border.width || 0);\n\n\t var shadow = new ShapeElement({\n\t type: options.type,\n\t width: size,\n\t height: size,\n\t rotation: options.rotation,\n\t background: markers.color || defaultColor,\n\t border: {\n\t color: markers.border.color,\n\t width: markers.border.width,\n\t opacity: valueOrDefault(markers.border.opacity, 1)\n\t },\n\t opacity: valueOrDefault(markers.opacity, 1)\n\t });\n\t shadow.reflow(this._childBox);\n\n\t return shadow.getElement();\n\t },\n\n\t highlightVisual: function() {\n\t return (this.marker || {}).visual;\n\t },\n\n\t highlightVisualArgs: function() {\n\t var marker = this.marker;\n\t var visual, rect;\n\n\t if (marker) {\n\t rect = marker.paddingBox.toRect();\n\t visual = marker.visual;\n\t } else {\n\t var size = this.options.markers.size;\n\t var halfSize = size / 2;\n\t var center = this.box.center();\n\t rect = new geometry.Rect([ center.x - halfSize, center.y - halfSize ], [ size, size ]);\n\t }\n\n\t return {\n\t options: this.options,\n\t rect: rect,\n\t visual: visual\n\t };\n\t },\n\n\t tooltipAnchor: function() {\n\t var markerBox = this.markerBox();\n\t var clipBox = this.owner.pane.clipBox();\n\t var showTooltip = !clipBox || clipBox.overlaps(markerBox);\n\n\t if (showTooltip) {\n\t var x = markerBox.x2 + TOOLTIP_OFFSET;\n\t var horizontalAlign = LEFT;\n\t var y, verticalAlign;\n\n\t if (this.aboveAxis) {\n\t y = markerBox.y1;\n\t verticalAlign = BOTTOM;\n\t } else {\n\t y = markerBox.y2;\n\t verticalAlign = TOP;\n\t }\n\n\t return {\n\t point: new Point(x, y),\n\t align: {\n\t horizontal: horizontalAlign,\n\t vertical: verticalAlign\n\t }\n\t };\n\t }\n\t },\n\n\t formatValue: function(format) {\n\t return this.owner.formatPointValue(this, format);\n\t },\n\n\t overlapsBox: function(box) {\n\t var markerBox = this.markerBox();\n\t return markerBox.overlaps(box);\n\t },\n\n\t unclipElements: function() {\n\t if (this.label) {\n\t this.label.options.noclip = true;\n\t }\n\n\t if (this.note) {\n\t this.note.options.noclip = true;\n\t }\n\t },\n\n\t pointData: function() {\n\t return {\n\t dataItem: this.dataItem,\n\t category: this.category,\n\t value: this.value,\n\t percentage: this.percentage,\n\t stackValue: this.stackValue,\n\t series: this.series\n\t };\n\t }\n\t});\n\n\tLinePoint.prototype.defaults = {\n\t vertical: true,\n\t markers: {\n\t visible: true,\n\t background: WHITE,\n\t size: LINE_MARKER_SIZE,\n\t type: CIRCLE,\n\t border: {\n\t width: 2\n\t },\n\t opacity: 1\n\t },\n\t labels: {\n\t visible: false,\n\t position: ABOVE,\n\t margin: getSpacing(3),\n\t padding: getSpacing(4),\n\t animation: {\n\t type: FADEIN,\n\t delay: INITIAL_ANIMATION_DURATION\n\t }\n\t },\n\t notes: {\n\t label: {}\n\t },\n\t highlight: {\n\t markers: {\n\t border: {\n\t color: \"#fff\",\n\t width: 2\n\t }\n\t },\n\t zIndex: datavizConstants.HIGHLIGHT_ZINDEX\n\t },\n\t errorBars: {\n\t line: {\n\t width: 1\n\t }\n\t }\n\t};\n\n\tdeepExtend(LinePoint.prototype, PointEventsMixin);\n\tdeepExtend(LinePoint.prototype, NoteMixin);\n\n\tvar LineSegment = ChartElement.extend({\n\t init: function(linePoints, series, seriesIx) {\n\t ChartElement.fn.init.call(this);\n\n\t this.linePoints = linePoints;\n\t this.series = series;\n\t this.seriesIx = seriesIx;\n\t },\n\n\t points: function() {\n\t return this.toGeometryPoints(this.linePoints);\n\t },\n\n\t toGeometryPoints: function(points) {\n\t var result = [];\n\t for (var i = 0, length = points.length; i < length; i++) {\n\t if (points[i] && points[i].visible !== false) {\n\t result.push(points[i]._childBox.toRect().center());\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t createVisual: function() {\n\t var this$1 = this;\n\n\t var customVisual = this.series.visual;\n\t if (customVisual) {\n\t this.visual = customVisual({\n\t points: this.toGeometryPoints(this.linePoints),\n\t series: this.series,\n\t sender: this.getSender(),\n\t createVisual: function () {\n\t this$1.segmentVisual();\n\n\t return this$1.visual;\n\t }\n\t });\n\t if (this.visual && !defined(this.visual.options.zIndex)) {\n\t this.visual.options.zIndex = this.series.zIndex;\n\t }\n\t } else {\n\t this.segmentVisual();\n\t }\n\t },\n\n\t segmentVisual: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var series = ref.series;\n\t var color = series.color;\n\t var defaults = series._defaults;\n\n\t if (isFunction(color) && defaults) {\n\t color = defaults.color;\n\t }\n\n\t var line = Path.fromPoints(this.points(), {\n\t stroke: {\n\t color: color,\n\t width: series.width,\n\t opacity: series.opacity,\n\t dashType: series.dashType\n\t },\n\t zIndex: series.zIndex\n\t });\n\n\t if (options.closed) {\n\t line.close();\n\t }\n\n\t this.visual = line;\n\t },\n\n\t aliasFor: function(e, coords) {\n\t return this.parent.getNearestPoint(coords.x, coords.y, this.seriesIx);\n\t }\n\t});\n\n\tsetDefaultOptions(LineSegment, {\n\t closed: false\n\t});\n\n\tvar StepLineMixin = {\n\t calculateStepPoints: function(points) {\n\t var categoryAxis = this.parent.plotArea.seriesCategoryAxis(this.series);\n\t var ref = categoryAxis.options;\n\t var justified = ref.justified;\n\t var vertical = ref.vertical;\n\t var reverse = ref.reverse;\n\n\t var stepAxis = vertical ? X : Y;\n\t var axis = vertical ? Y : X;\n\t var stepDir = reverse ? 2 : 1;\n\t var dir = stepDir;\n\n\t var previousPoint = toGeometryPoint(points[0], stepAxis, stepDir, axis, dir);\n\t var result = [ previousPoint ];\n\n\t for (var idx = 1; idx < points.length; idx++) {\n\t var point = toGeometryPoint(points[idx], stepAxis, stepDir, axis, dir);\n\n\t if (previousPoint[stepAxis] !== point[stepAxis]) {\n\t var stepPoint = new GeometryPoint();\n\t stepPoint[stepAxis] = previousPoint[stepAxis];\n\t stepPoint[axis] = point[axis];\n\n\t result.push(stepPoint, point);\n\t }\n\n\t previousPoint = point;\n\t }\n\n\t if (!justified) {\n\t result.push(toGeometryPoint(last(points), stepAxis, stepDir, axis, reverse ? 1 : 2));\n\t } else if (previousPoint !== last(result)) {\n\t result.push(previousPoint);\n\t }\n\n\t return result;\n\n\t }\n\t};\n\n\tfunction toGeometryPoint(lintPoint, stepAxis, stepDir, axis, dir) {\n\t var box = lintPoint.box;\n\t var result = new GeometryPoint();\n\n\t result[stepAxis] = box[stepAxis + stepDir];\n\t result[axis] = box[axis + dir];\n\n\t return result;\n\t}\n\n\tvar StepLineSegment = LineSegment.extend({\n\t points: function() {\n\t return this.calculateStepPoints(this.linePoints);\n\t }\n\t});\n\n\tdeepExtend(StepLineSegment.prototype, StepLineMixin);\n\n\tvar SplineSegment = LineSegment.extend({\n\t segmentVisual: function() {\n\t var series = this.series;\n\t var defaults = series._defaults;\n\t var color = series.color;\n\n\t if (isFunction(color) && defaults) {\n\t color = defaults.color;\n\t }\n\n\t var curveProcessor = new CurveProcessor(this.options.closed);\n\t var segments = curveProcessor.process(this.points());\n\t var curve = new Path({\n\t stroke: {\n\t color: color,\n\t width: series.width,\n\t opacity: series.opacity,\n\t dashType: series.dashType\n\t },\n\t zIndex: series.zIndex\n\t });\n\n\t curve.segments.push.apply(curve.segments, segments);\n\n\t this.visual = curve;\n\t }\n\t});\n\n\tvar LineChartMixin = {\n\t renderSegments: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var options = ref.options;\n\t var seriesPoints = ref.seriesPoints;\n\t var series = options.series;\n\t var seriesCount = seriesPoints.length;\n\t var lastSegment;\n\n\t this._segments = [];\n\n\t for (var seriesIx = 0; seriesIx < seriesCount; seriesIx++) {\n\t var currentSeries = series[seriesIx];\n\t var sortedPoints = this$1.sortPoints(seriesPoints[seriesIx]);\n\t var pointCount = sortedPoints.length;\n\t var linePoints = [];\n\n\t for (var pointIx = 0; pointIx < pointCount; pointIx++) {\n\t var point = sortedPoints[pointIx];\n\t if (point) {\n\t linePoints.push(point);\n\t } else if (this$1.seriesMissingValues(currentSeries) !== INTERPOLATE) {\n\t if (linePoints.length > 1) {\n\t lastSegment = this$1.createSegment(\n\t linePoints, currentSeries, seriesIx, lastSegment\n\t );\n\t this$1._addSegment(lastSegment);\n\t }\n\t linePoints = [];\n\t }\n\t }\n\n\t if (linePoints.length > 1) {\n\t lastSegment = this$1.createSegment(\n\t linePoints, currentSeries, seriesIx, lastSegment\n\t );\n\t this$1._addSegment(lastSegment);\n\t }\n\t }\n\n\t this.children.unshift.apply(this.children, this._segments);\n\t },\n\n\t _addSegment: function(segment) {\n\t this._segments.push(segment);\n\t segment.parent = this;\n\t },\n\n\t sortPoints: function(points) {\n\t return points;\n\t },\n\n\t seriesMissingValues: function(series) {\n\t var missingValues = series.missingValues;\n\t var assumeZero = !missingValues && this.options.isStacked;\n\n\t return assumeZero ? ZERO : missingValues || INTERPOLATE;\n\t },\n\n\t getNearestPoint: function(x, y, seriesIx) {\n\t var target = new Point(x, y);\n\t var allPoints = this.seriesPoints[seriesIx];\n\t var nearestPointDistance = MAX_VALUE;\n\t var nearestPoint;\n\n\t for (var i = 0; i < allPoints.length; i++) {\n\t var point = allPoints[i];\n\n\t if (point && defined(point.value) && point.value !== null && point.visible !== false) {\n\t var pointBox = point.box;\n\t var pointDistance = pointBox.center().distanceTo(target);\n\n\t if (pointDistance < nearestPointDistance) {\n\t nearestPoint = point;\n\t nearestPointDistance = pointDistance;\n\t }\n\t }\n\t }\n\n\t return nearestPoint;\n\t }\n\t};\n\n\tvar ClipAnimation = Animation.extend({\n\t setup: function() {\n\t this._setEnd(this.options.box.x1);\n\t },\n\n\t step: function(pos) {\n\t var box = this.options.box;\n\t this._setEnd(dataviz.interpolateValue(box.x1, box.x2, pos));\n\t },\n\n\t _setEnd: function(x) {\n\t var element = this.element;\n\t var segments = element.segments;\n\t var topRight = segments[1].anchor();\n\t var bottomRight = segments[2].anchor();\n\n\t element.suspend();\n\t topRight.setX(x);\n\t element.resume();\n\t bottomRight.setX(x);\n\t }\n\t});\n\n\tsetDefaultOptions(ClipAnimation, {\n\t duration: INITIAL_ANIMATION_DURATION\n\t});\n\n\tAnimationFactory.current.register(\"clip\", ClipAnimation);\n\n\tfunction anyHasZIndex(elements) {\n\t for (var idx = 0; idx < elements.length; idx++) {\n\t if (defined(elements[idx].zIndex)) {\n\t return true;\n\t }\n\t }\n\t}\n\n\tvar ClipAnimationMixin = {\n\t createAnimation: function() {\n\t var root = this.getRoot();\n\t if (root && (root.options || {}).transitions !== false) {\n\t var box = root.size();\n\t var clipPath = Path.fromRect(box.toRect());\n\t this.visual.clip(clipPath);\n\t this.animation = new ClipAnimation(clipPath, {\n\t box: box\n\t });\n\t if (anyHasZIndex(this.options.series)) {\n\t this._setChildrenAnimation(clipPath);\n\t }\n\t }\n\t },\n\n\t _setChildrenAnimation: function(clipPath) {\n\t var points = this.animationPoints();\n\n\t for (var idx = 0; idx < points.length; idx++) {\n\t var point = points[idx];\n\t if (point && point.visual && defined(point.visual.options.zIndex)) {\n\t point.visual.clip(clipPath);\n\t }\n\t }\n\t }\n\t};\n\n\tvar LineChart = CategoricalChart.extend({\n\t render: function() {\n\n\t CategoricalChart.fn.render.call(this);\n\n\t this.updateStackRange();\n\t this.renderSegments();\n\t },\n\n\t pointType: function() {\n\t return LinePoint;\n\t },\n\n\t createPoint: function(data, fields) {\n\t var categoryIx = fields.categoryIx;\n\t var category = fields.category;\n\t var series = fields.series;\n\t var seriesIx = fields.seriesIx;\n\t var missingValues = this.seriesMissingValues(series);\n\t var value = data.valueFields.value;\n\n\t if (!defined(value) || value === null) {\n\t if (missingValues === ZERO) {\n\t value = 0;\n\t } else {\n\t return null;\n\t }\n\t }\n\n\t var pointOptions = this.pointOptions(series, seriesIx);\n\t pointOptions = this.evalPointOptions(\n\t pointOptions, value, category, categoryIx, series, seriesIx\n\t );\n\n\t var color = data.fields.color || series.color;\n\t if (isFunction(series.color)) {\n\t color = pointOptions.color;\n\t }\n\n\t var point = new LinePoint(value, pointOptions);\n\t point.color = color;\n\n\t this.append(point);\n\n\t return point;\n\t },\n\n\t plotRange: function(point) {\n\t var this$1 = this;\n\n\t var plotValue = this.plotValue(point);\n\n\t if (this.options.isStacked) {\n\t var categoryIx = point.categoryIx;\n\t var categoryPoints = this.categoryPoints[categoryIx];\n\n\t for (var i = 0; i < categoryPoints.length; i++) {\n\t var other = categoryPoints[i];\n\n\t if (point === other) {\n\t break;\n\t }\n\n\t plotValue += this$1.plotValue(other);\n\n\t if (this$1.options.isStacked100) {\n\t plotValue = Math.min(plotValue, 1);\n\t }\n\t }\n\n\t }\n\n\t return [ plotValue, plotValue ];\n\t },\n\n\t createSegment: function(linePoints, currentSeries, seriesIx) {\n\t var style = currentSeries.style;\n\t var pointType;\n\n\t if (style === STEP) {\n\t pointType = StepLineSegment;\n\t } else if (style === SMOOTH) {\n\t pointType = SplineSegment;\n\t } else {\n\t pointType = LineSegment;\n\t }\n\n\t return new pointType(linePoints, currentSeries, seriesIx);\n\t },\n\n\t animationPoints: function() {\n\t var points = this.points;\n\t var result = [];\n\t for (var idx = 0; idx < points.length; idx++) {\n\t result.push((points[idx] || {}).marker);\n\t }\n\t return result.concat(this._segments);\n\t }\n\t});\n\n\tdeepExtend(LineChart.prototype, LineChartMixin, ClipAnimationMixin);\n\n\tvar AreaSegment = LineSegment.extend({\n\t init: function(linePoints, currentSeries, seriesIx, prevSegment, stackPoints) {\n\t LineSegment.fn.init.call(this, linePoints, currentSeries, seriesIx);\n\n\t this.prevSegment = prevSegment;\n\t this.stackPoints = stackPoints;\n\t },\n\n\t createVisual: function() {\n\t var series = this.series;\n\t var defaults = series._defaults;\n\t var lineOptions = series.line || {};\n\t var color = series.color;\n\n\t if (isFunction(color) && defaults) {\n\t color = defaults.color;\n\t }\n\n\t this.visual = new Group({\n\t zIndex: series.zIndex\n\t });\n\n\t this.createFill({\n\t fill: {\n\t color: color,\n\t opacity: series.opacity\n\t },\n\t stroke: null\n\t });\n\n\t if (lineOptions.width > 0 && lineOptions.visible !== false) {\n\t this.createStroke({\n\t stroke: deepExtend({\n\t color: color,\n\t opacity: series.opacity,\n\t lineCap: \"butt\"\n\t }, lineOptions)\n\t });\n\t }\n\t },\n\n\t strokeSegments: function() {\n\t var segments = this._strokeSegments;\n\n\t if (!segments) {\n\t segments = this._strokeSegments = this.createStrokeSegments();\n\t }\n\n\t return segments;\n\t },\n\n\t createStrokeSegments: function() {\n\t return this.segmentsFromPoints(this.points());\n\t },\n\n\t stackSegments: function() {\n\t if (this.prevSegment) {\n\t return this.prevSegment.createStackSegments(this.stackPoints);\n\t }\n\n\t return this.createStackSegments(this.stackPoints);\n\t },\n\n\t createStackSegments: function(stackPoints) {\n\t return this.segmentsFromPoints(this.toGeometryPoints(stackPoints)).reverse();\n\t },\n\n\t segmentsFromPoints: function(points) {\n\t return points.map(function (point) { return new geometry.Segment(point); });\n\t },\n\n\t createStroke: function(style) {\n\t var stroke = new Path(style);\n\t stroke.segments.push.apply(stroke.segments, this.strokeSegments());\n\n\t this.visual.append(stroke);\n\t },\n\n\t hasStackSegment: function() {\n\t return this.prevSegment || (this.stackPoints && this.stackPoints.length);\n\t },\n\n\t createFill: function(style) {\n\t var strokeSegments = this.strokeSegments();\n\t var fillSegments = strokeSegments.slice(0);\n\t var hasStackSegments = this.hasStackSegment();\n\n\t if (hasStackSegments) {\n\t var stackSegments = this.stackSegments();\n\n\t append(fillSegments, stackSegments);\n\t }\n\n\t var fill = new Path(style);\n\t fill.segments.push.apply(fill.segments, fillSegments);\n\n\t if (!hasStackSegments && strokeSegments.length > 1) {\n\t this.fillToAxes(fill);\n\t }\n\n\t this.visual.append(fill);\n\t },\n\n\t fillToAxes: function(fillPath) {\n\t var chart = this.parent;\n\t var invertAxes = chart.options.invertAxes;\n\t var valueAxis = chart.seriesValueAxis(this.series);\n\t var crossingValue = chart.categoryAxisCrossingValue(valueAxis);\n\t var endSlot = valueAxis.getSlot(crossingValue, crossingValue, true);\n\t var segments = this.strokeSegments();\n\t var firstPoint = segments[0].anchor();\n\t var lastPoint = last(segments).anchor();\n\t var end = invertAxes ? endSlot.x1 : endSlot.y1;\n\n\t if (invertAxes) {\n\t fillPath.lineTo(end, lastPoint.y)\n\t .lineTo(end, firstPoint.y);\n\t } else {\n\t fillPath.lineTo(lastPoint.x, end)\n\t .lineTo(firstPoint.x, end);\n\t }\n\t }\n\t});\n\n\tvar StepAreaSegment = AreaSegment.extend({\n\t createStrokeSegments: function() {\n\t return this.segmentsFromPoints(this.calculateStepPoints(this.linePoints));\n\t },\n\n\t createStackSegments: function(stackPoints) {\n\t return this.segmentsFromPoints(this.calculateStepPoints(stackPoints)).reverse();\n\t }\n\t});\n\n\tdeepExtend(StepAreaSegment.prototype, StepLineMixin);\n\n\tvar SplineAreaSegment = AreaSegment.extend({\n\t createStrokeSegments: function() {\n\t var curveProcessor = new CurveProcessor(this.options.closed);\n\t var linePoints = this.points();\n\n\t return curveProcessor.process(linePoints);\n\t },\n\n\t createStackSegments: function() {\n\t var strokeSegments = this.strokeSegments();\n\t var stackSegments = [];\n\t for (var idx = strokeSegments.length - 1; idx >= 0; idx--) {\n\t var segment = strokeSegments[idx];\n\t stackSegments.push(new geometry.Segment(\n\t segment.anchor(),\n\t segment.controlOut(),\n\t segment.controlIn()\n\t ));\n\t }\n\n\t return stackSegments;\n\t }\n\t});\n\n\tvar AreaChart = LineChart.extend({\n\t createSegment: function(linePoints, currentSeries, seriesIx, prevSegment) {\n\t var isStacked = this.options.isStacked;\n\t var style = (currentSeries.line || {}).style;\n\t var previousSegment;\n\n\t var stackPoints;\n\t if (isStacked && seriesIx > 0 && prevSegment) {\n\t var missingValues = this.seriesMissingValues(currentSeries);\n\t if (missingValues !== \"gap\") {\n\t stackPoints = prevSegment.linePoints;\n\t previousSegment = prevSegment;\n\t } else {\n\t stackPoints = this._gapStackPoints(linePoints, seriesIx, style);\n\t }\n\t }\n\n\t var pointType;\n\t if (style === STEP) {\n\t pointType = StepAreaSegment;\n\t } else if (style === SMOOTH) {\n\t pointType = SplineAreaSegment;\n\t } else {\n\t pointType = AreaSegment;\n\t }\n\n\t return new pointType(linePoints, currentSeries, seriesIx, previousSegment, stackPoints);\n\t },\n\n\t reflow: function(targetBox) {\n\t var this$1 = this;\n\n\t LineChart.fn.reflow.call(this, targetBox);\n\n\t var stackPoints = this._stackPoints;\n\t if (stackPoints) {\n\t for (var idx = 0; idx < stackPoints.length; idx++) {\n\t var stackPoint = stackPoints[idx];\n\t var pointSlot = this$1.categoryAxis.getSlot(stackPoint.categoryIx);\n\t stackPoint.reflow(pointSlot);\n\t }\n\t }\n\t },\n\n\t _gapStackPoints: function(linePoints, seriesIx, style) {\n\t var this$1 = this;\n\n\t var seriesPoints = this.seriesPoints;\n\t var startIdx = linePoints[0].categoryIx;\n\t var length = linePoints.length;\n\t if (startIdx < 0) {\n\t startIdx = 0;\n\t length--;\n\t }\n\n\t var endIdx = startIdx + length;\n\t var pointOffset = this.seriesOptions[0]._outOfRangeMinPoint ? 1 : 0;\n\t var stackPoints = [];\n\n\t this._stackPoints = this._stackPoints || [];\n\t for (var categoryIx = startIdx; categoryIx < endIdx; categoryIx++) {\n\t var pointIx = categoryIx + pointOffset;\n\t var currentSeriesIx = seriesIx;\n\t var point = (void 0);\n\n\t do {\n\t currentSeriesIx--;\n\t point = seriesPoints[currentSeriesIx][pointIx];\n\t } while (currentSeriesIx > 0 && !point);\n\n\t if (point) {\n\t if (style !== STEP && categoryIx > startIdx && !seriesPoints[currentSeriesIx][pointIx - 1]) {\n\t stackPoints.push(this$1._previousSegmentPoint(categoryIx, pointIx, pointIx - 1, currentSeriesIx));\n\t }\n\n\t stackPoints.push(point);\n\n\t if (style !== STEP && categoryIx + 1 < endIdx && !seriesPoints[currentSeriesIx][pointIx + 1]) {\n\t stackPoints.push(this$1._previousSegmentPoint(categoryIx, pointIx, pointIx + 1, currentSeriesIx));\n\t }\n\t } else {\n\t var gapStackPoint = this$1._createGapStackPoint(categoryIx);\n\t this$1._stackPoints.push(gapStackPoint);\n\t stackPoints.push(gapStackPoint);\n\t }\n\t }\n\n\t return stackPoints;\n\t },\n\n\t _previousSegmentPoint: function(categoryIx, pointIx, segmentIx, seriesIdx) {\n\t var seriesPoints = this.seriesPoints;\n\t var index = seriesIdx;\n\t var point;\n\n\t while (index > 0 && !point) {\n\t index--;\n\t point = seriesPoints[index][segmentIx];\n\t }\n\n\t if (!point) {\n\t point = this._createGapStackPoint(categoryIx);\n\t this._stackPoints.push(point);\n\t } else {\n\t point = seriesPoints[index][pointIx];\n\t }\n\n\t return point;\n\t },\n\n\t _createGapStackPoint: function(categoryIx) {\n\t var options = this.pointOptions({}, 0);\n\t var point = new LinePoint(0, options);\n\t point.categoryIx = categoryIx;\n\t point.series = {};\n\n\t return point;\n\t },\n\n\t seriesMissingValues: function(series) {\n\t return series.missingValues || ZERO;\n\t }\n\t});\n\n\tvar AxisGroupRangeTracker = Class.extend({\n\t init: function() {\n\n\t this.axisRanges = {};\n\t },\n\n\t update: function(chartAxisRanges) {\n\t var axisRanges = this.axisRanges;\n\n\t for (var axisName in chartAxisRanges) {\n\t var chartRange = chartAxisRanges[axisName];\n\t var range = axisRanges[axisName];\n\t axisRanges[axisName] = range = range || { min: MAX_VALUE, max: MIN_VALUE };\n\n\t range.min = Math.min(range.min, chartRange.min);\n\t range.max = Math.max(range.max, chartRange.max);\n\t }\n\t },\n\n\t reset: function(axisName) {\n\t this.axisRanges[axisName] = undefined;\n\t },\n\n\t query: function(axisName) {\n\t return this.axisRanges[axisName];\n\t }\n\t});\n\n\tvar BarLabel = ChartElement.extend({\n\t init: function(content, options, pointData) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.textBox = new TextBox(content, this.options, pointData);\n\t this.append(this.textBox);\n\t },\n\n\t createVisual: function() {\n\t this.textBox.options.noclip = this.options.noclip;\n\t },\n\n\t reflow: function(targetBox) {\n\t var options = this.options;\n\t var vertical = options.vertical;\n\t var aboveAxis = options.aboveAxis;\n\t var text = this.children[0];\n\t var textOptions = text.options;\n\t var box = text.box;\n\t var padding = text.options.padding;\n\t var labelBox = targetBox;\n\n\t textOptions.align = vertical ? CENTER : LEFT;\n\t textOptions.vAlign = vertical ? TOP : CENTER;\n\n\t if (options.position === INSIDE_END) {\n\t if (vertical) {\n\t textOptions.vAlign = TOP;\n\n\t if (!aboveAxis && box.height() < targetBox.height()) {\n\t textOptions.vAlign = BOTTOM;\n\t }\n\t } else {\n\t textOptions.align = aboveAxis ? RIGHT : LEFT;\n\t }\n\t } else if (options.position === CENTER) {\n\t textOptions.vAlign = CENTER;\n\t textOptions.align = CENTER;\n\t } else if (options.position === INSIDE_BASE) {\n\t if (vertical) {\n\t textOptions.vAlign = aboveAxis ? BOTTOM : TOP;\n\t } else {\n\t textOptions.align = aboveAxis ? LEFT : RIGHT;\n\t }\n\t } else if (options.position === OUTSIDE_END) {\n\t if (vertical) {\n\t if (aboveAxis) {\n\t labelBox = new Box(\n\t targetBox.x1, targetBox.y1 - box.height(),\n\t targetBox.x2, targetBox.y1\n\t );\n\t } else {\n\t labelBox = new Box(\n\t targetBox.x1, targetBox.y2,\n\t targetBox.x2, targetBox.y2 + box.height()\n\t );\n\t }\n\t } else {\n\t textOptions.align = CENTER;\n\t if (aboveAxis) {\n\t labelBox = new Box(\n\t targetBox.x2, targetBox.y1,\n\t targetBox.x2 + box.width(), targetBox.y2\n\t );\n\t } else {\n\t labelBox = new Box(\n\t targetBox.x1 - box.width(), targetBox.y1,\n\t targetBox.x1, targetBox.y2\n\t );\n\t }\n\t }\n\t }\n\n\t if (!options.rotation) {\n\t if (vertical) {\n\t padding.left = padding.right =\n\t (labelBox.width() - text.contentBox.width()) / 2;\n\t } else {\n\t padding.top = padding.bottom =\n\t (labelBox.height() - text.contentBox.height()) / 2;\n\t }\n\t }\n\n\t text.reflow(labelBox);\n\t },\n\n\t alignToClipBox: function(clipBox) {\n\t var vertical = this.options.vertical;\n\t var field = vertical ? Y : X;\n\t var start = field + \"1\";\n\t var end = field + \"2\";\n\t var text = this.children[0];\n\t var parentBox = this.parent.box;\n\n\t if (parentBox[start] < clipBox[start] || clipBox[end] < parentBox[end]) {\n\t var targetBox = text.paddingBox.clone();\n\t targetBox[start] = Math.max(parentBox[start], clipBox[start]);\n\t targetBox[end] = Math.min(parentBox[end], clipBox[end]);\n\n\t this.reflow(targetBox);\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(BarLabel, {\n\t position: OUTSIDE_END,\n\t margin: getSpacing(3),\n\t padding: getSpacing(4),\n\t color: BLACK,\n\t background: \"\",\n\t border: {\n\t width: 1,\n\t color: \"\"\n\t },\n\t aboveAxis: true,\n\t vertical: false,\n\t animation: {\n\t type: FADEIN,\n\t delay: INITIAL_ANIMATION_DURATION\n\t },\n\t zIndex: 2\n\t});\n\n\tfunction hasGradientOverlay(options) {\n\t var overlay = options.overlay;\n\n\t return overlay && overlay.gradient && overlay.gradient !== \"none\";\n\t}\n\n\tvar BAR_ALIGN_MIN_WIDTH = 6;\n\n\tvar Bar = ChartElement.extend({\n\t init: function(value, options) {\n\t ChartElement.fn.init.call(this);\n\n\t this.options = options;\n\t this.color = options.color || WHITE;\n\t this.aboveAxis = valueOrDefault(this.options.aboveAxis, true);\n\t this.value = value;\n\t },\n\n\t render: function() {\n\t if (this._rendered) {\n\t return;\n\t }\n\n\t this._rendered = true;\n\n\t this.createLabel();\n\t this.createNote();\n\n\t if (this.errorBar) {\n\t this.append(this.errorBar);\n\t }\n\t },\n\n\t createLabel: function() {\n\t var options = this.options;\n\t var labels = options.labels;\n\n\t if (labels.visible) {\n\t var pointData = this.pointData();\n\t var labelTemplate = getTemplate(labels);\n\t var labelText;\n\n\t if (labelTemplate) {\n\t labelText = labelTemplate(pointData);\n\t } else {\n\t labelText = this.formatValue(labels.format);\n\t }\n\n\t this.label = new BarLabel(labelText,\n\t deepExtend({\n\t vertical: options.vertical\n\t },\n\t labels\n\t ), pointData);\n\t this.append(this.label);\n\t }\n\t },\n\n\t formatValue: function(format) {\n\t return this.owner.formatPointValue(this, format);\n\t },\n\n\t reflow: function(targetBox) {\n\t var this$1 = this;\n\n\t this.render();\n\n\t var label = this.label;\n\n\t this.box = targetBox;\n\n\t if (label) {\n\t label.options.aboveAxis = this.aboveAxis;\n\t label.reflow(targetBox);\n\t }\n\n\t if (this.note) {\n\t this.note.reflow(targetBox);\n\t }\n\n\t if (this.errorBars) {\n\t for (var i = 0; i < this.errorBars.length; i++) {\n\t this$1.errorBars[i].reflow(targetBox);\n\t }\n\t }\n\t },\n\n\t createVisual: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var box = ref.box;\n\t var options = ref.options;\n\t var customVisual = options.visual;\n\n\t if (this.visible !== false) {\n\t ChartElement.fn.createVisual.call(this);\n\n\t if (customVisual) {\n\t var visual = this.rectVisual = customVisual({\n\t category: this.category,\n\t dataItem: this.dataItem,\n\t value: this.value,\n\t sender: this.getSender(),\n\t series: this.series,\n\t percentage: this.percentage,\n\t stackValue: this.stackValue,\n\t runningTotal: this.runningTotal,\n\t total: this.total,\n\t rect: box.toRect(),\n\t createVisual: function () {\n\t var group = new Group();\n\t this$1.createRect(group);\n\t return group;\n\t },\n\t options: options\n\t });\n\n\t if (visual) {\n\t this.visual.append(visual);\n\t }\n\t } else if (box.width() > 0 && box.height() > 0) {\n\t this.createRect(this.visual);\n\t }\n\t }\n\t },\n\n\t createRect: function(visual) {\n\t var options = this.options;\n\t var border = options.border;\n\t var strokeOpacity = defined(border.opacity) ? border.opacity : options.opacity;\n\t var rect = this.box.toRect();\n\n\t rect.size.width = Math.round(rect.size.width);\n\n\t var path = this.rectVisual = Path.fromRect(rect, {\n\t fill: {\n\t color: this.color,\n\t opacity: options.opacity\n\t },\n\t stroke: {\n\t color: this.getBorderColor(),\n\t width: border.width,\n\t opacity: strokeOpacity,\n\t dashType: border.dashType\n\t }\n\t });\n\n\t var width = this.box.width();\n\t var height = this.box.height();\n\n\t var size = options.vertical ? width : height;\n\n\t if (size > BAR_ALIGN_MIN_WIDTH) {\n\t alignPathToPixel(path);\n\n\t // Fixes lineJoin issue in firefox when the joined lines are parallel\n\t if (width < 1 || height < 1) {\n\t path.options.stroke.lineJoin = \"round\";\n\t }\n\t }\n\n\t visual.append(path);\n\n\t if (hasGradientOverlay(options)) {\n\t var overlay = this.createGradientOverlay(path, { baseColor: this.color }, deepExtend({\n\t end: !options.vertical ? [ 0, 1 ] : undefined\n\t }, options.overlay));\n\n\t visual.append(overlay);\n\t }\n\t },\n\n\t createHighlight: function(style) {\n\t var highlight = Path.fromRect(this.box.toRect(), style);\n\n\t return alignPathToPixel(highlight);\n\t },\n\n\t highlightVisual: function() {\n\t return this.rectVisual;\n\t },\n\n\t highlightVisualArgs: function() {\n\t return {\n\t options: this.options,\n\t rect: this.box.toRect(),\n\t visual: this.rectVisual\n\t };\n\t },\n\n\t getBorderColor: function() {\n\t var color = this.color;\n\t var border = this.options.border;\n\t var brightness = border._brightness || BORDER_BRIGHTNESS;\n\t var borderColor = border.color;\n\n\t if (!defined(borderColor)) {\n\t borderColor = new Color(color).brightness(brightness).toHex();\n\t }\n\n\t return borderColor;\n\t },\n\n\t tooltipAnchor: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var box = ref.box;\n\t var aboveAxis = ref.aboveAxis;\n\t var clipBox = this.owner.pane.clipBox() || box;\n\t var horizontalAlign = LEFT;\n\t var verticalAlign = TOP;\n\t var x, y;\n\n\t if (options.vertical) {\n\t x = Math.min(box.x2, clipBox.x2) + TOOLTIP_OFFSET;\n\t if (aboveAxis) {\n\t y = Math.max(box.y1, clipBox.y1);\n\t } else {\n\t y = Math.min(box.y2, clipBox.y2);\n\t verticalAlign = BOTTOM;\n\t }\n\t } else {\n\t var x1 = Math.max(box.x1, clipBox.x1);\n\t var x2 = Math.min(box.x2, clipBox.x2);\n\n\t if (options.isStacked) {\n\t verticalAlign = BOTTOM;\n\t if (aboveAxis) {\n\t horizontalAlign = RIGHT;\n\t x = x2;\n\t } else {\n\t x = x1;\n\t }\n\t y = Math.max(box.y1, clipBox.y1) - TOOLTIP_OFFSET;\n\t } else {\n\t if (aboveAxis) {\n\t x = x2 + TOOLTIP_OFFSET;\n\t } else {\n\t x = x1 - TOOLTIP_OFFSET;\n\t horizontalAlign = RIGHT;\n\t }\n\t y = Math.max(box.y1, clipBox.y1);\n\t }\n\t }\n\n\t return {\n\t point: new Point(x, y),\n\t align: {\n\t horizontal: horizontalAlign,\n\t vertical: verticalAlign\n\t }\n\t };\n\t },\n\n\t overlapsBox: function(box) {\n\t return this.box.overlaps(box);\n\t },\n\n\t pointData: function() {\n\t return {\n\t dataItem: this.dataItem,\n\t category: this.category,\n\t value: this.value,\n\t percentage: this.percentage,\n\t stackValue: this.stackValue,\n\t runningTotal: this.runningTotal,\n\t total: this.total,\n\t series: this.series\n\t };\n\t }\n\t});\n\n\tdeepExtend(Bar.prototype, PointEventsMixin);\n\tdeepExtend(Bar.prototype, NoteMixin);\n\n\tBar.prototype.defaults = {\n\t border: {\n\t width: 1\n\t },\n\t vertical: true,\n\t overlay: {\n\t gradient: \"glass\"\n\t },\n\t labels: {\n\t visible: false,\n\t format: \"{0}\"\n\t },\n\t opacity: 1,\n\t notes: {\n\t label: {}\n\t }\n\t};\n\n\tfunction forEach(elements, callback) {\n\t elements.forEach(callback);\n\t}\n\n\tfunction forEachReverse(elements, callback) {\n\t var length = elements.length;\n\n\t for (var idx = length - 1; idx >= 0; idx--) {\n\t callback(elements[idx], idx - length - 1);\n\t }\n\t}\n\n\tvar ClusterLayout = ChartElement.extend({\n\t init: function(options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.forEach = options.rtl ? forEachReverse : forEach;\n\t },\n\n\t reflow: function(box) {\n\t var ref = this.options;\n\t var vertical = ref.vertical;\n\t var gap = ref.gap;\n\t var spacing = ref.spacing;\n\t var children = this.children;\n\t var count = children.length;\n\t var axis = vertical ? Y : X;\n\t var slots = count + gap + (spacing * (count - 1));\n\t var slotSize = (vertical ? box.height() : box.width()) / slots;\n\t var position = box[axis + 1] + slotSize * (gap / 2);\n\n\t this.forEach(children, function (child, idx) {\n\t var childBox = (child.box || box).clone();\n\n\t childBox[axis + 1] = position;\n\t childBox[axis + 2] = position + slotSize;\n\n\t child.reflow(childBox);\n\t if (idx < count - 1) {\n\t position += (slotSize * spacing);\n\t }\n\n\t position += slotSize;\n\t });\n\t }\n\t});\n\n\tsetDefaultOptions(ClusterLayout, {\n\t vertical: false,\n\t gap: 0,\n\t spacing: 0\n\t});\n\n\tvar StackWrap = ChartElement.extend({\n\t reflow: function(targetBox) {\n\t var this$1 = this;\n\n\t var positionAxis = this.options.vertical ? X : Y;\n\t var children = this.children;\n\t var childrenCount = children.length;\n\t var box = this.box = new Box();\n\n\t for (var i = 0; i < childrenCount; i++) {\n\t var currentChild = children[i];\n\n\t if (currentChild.visible !== false) {\n\t var childBox = currentChild.box.clone();\n\t childBox.snapTo(targetBox, positionAxis);\n\n\t if (i === 0) {\n\t box = this$1.box = childBox.clone();\n\t }\n\n\t currentChild.reflow(childBox);\n\t box.wrap(childBox);\n\t }\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(StackWrap, {\n\t vertical: true\n\t});\n\n\tvar BarChart = CategoricalChart.extend({\n\t render: function() {\n\t CategoricalChart.fn.render.call(this);\n\t this.updateStackRange();\n\t },\n\n\t pointType: function() {\n\t return Bar;\n\t },\n\n\t clusterType: function() {\n\t return ClusterLayout;\n\t },\n\n\t stackType: function() {\n\t return StackWrap;\n\t },\n\n\t stackLimits: function(axisName, stackName) {\n\t var limits = CategoricalChart.fn.stackLimits.call(this, axisName, stackName);\n\n\t return limits;\n\t },\n\n\t createPoint: function(data, fields) {\n\t var categoryIx = fields.categoryIx;\n\t var category = fields.category;\n\t var series = fields.series;\n\t var seriesIx = fields.seriesIx;\n\t var ref = this;\n\t var options = ref.options;\n\t var children = ref.children;\n\t var isStacked = options.isStacked;\n\t var value = this.pointValue(data);\n\t var pointOptions = this.pointOptions(series, seriesIx);\n\n\t var labelOptions = pointOptions.labels;\n\t if (isStacked) {\n\t if (labelOptions.position === OUTSIDE_END) {\n\t labelOptions.position = INSIDE_END;\n\t }\n\t }\n\n\t pointOptions.isStacked = isStacked;\n\n\t var color = data.fields.color || series.color;\n\t if (value < 0 && pointOptions.negativeColor) {\n\t color = pointOptions.negativeColor;\n\t }\n\n\t pointOptions = this.evalPointOptions(\n\t pointOptions, value, category, categoryIx, series, seriesIx\n\t );\n\n\t if (isFunction(series.color)) {\n\t color = pointOptions.color;\n\t }\n\n\t var pointType = this.pointType();\n\t var point = new pointType(value, pointOptions);\n\t point.color = color;\n\n\t var cluster = children[categoryIx];\n\t if (!cluster) {\n\t var clusterType = this.clusterType();\n\t cluster = new clusterType({\n\t vertical: options.invertAxes,\n\t gap: options.gap,\n\t spacing: options.spacing,\n\t rtl: !options.invertAxes && (this.chartService || {}).rtl\n\t });\n\t this.append(cluster);\n\t }\n\n\t if (isStacked) {\n\t var stackWrap = this.getStackWrap(series, cluster);\n\t stackWrap.append(point);\n\t } else {\n\t cluster.append(point);\n\t }\n\n\t return point;\n\t },\n\n\t getStackWrap: function(series, cluster) {\n\t var stack = series.stack;\n\t var stackGroup = stack ? stack.group || stack : stack;\n\t var wraps = cluster.children;\n\t var stackWrap;\n\n\t if (typeof stackGroup === datavizConstants.STRING) {\n\t for (var i = 0; i < wraps.length; i++) {\n\t if (wraps[i]._stackGroup === stackGroup) {\n\t stackWrap = wraps[i];\n\t break;\n\t }\n\t }\n\t } else {\n\t stackWrap = wraps[0];\n\t }\n\n\t if (!stackWrap) {\n\t var stackType = this.stackType();\n\t stackWrap = new stackType({\n\t vertical: !this.options.invertAxes\n\t });\n\t stackWrap._stackGroup = stackGroup;\n\t cluster.append(stackWrap);\n\t }\n\n\t return stackWrap;\n\t },\n\n\t categorySlot: function(categoryAxis, categoryIx, valueAxis) {\n\t var options = this.options;\n\t var categorySlot = categoryAxis.getSlot(categoryIx);\n\t var startValue = valueAxis.startValue();\n\n\t if (options.isStacked) {\n\t var zeroSlot = valueAxis.getSlot(startValue, startValue, true);\n\t var stackAxis = options.invertAxes ? X : Y;\n\t categorySlot[stackAxis + 1] = categorySlot[stackAxis + 2] = zeroSlot[stackAxis + 1];\n\t }\n\n\t return categorySlot;\n\t },\n\n\t reflowCategories: function(categorySlots) {\n\t var children = this.children;\n\t var childrenLength = children.length;\n\n\t for (var i = 0; i < childrenLength; i++) {\n\t children[i].reflow(categorySlots[i]);\n\t }\n\t },\n\n\t createAnimation: function() {\n\t this._setAnimationOptions();\n\t CategoricalChart.fn.createAnimation.call(this);\n\n\t if (anyHasZIndex(this.options.series)) {\n\t this._setChildrenAnimation();\n\t }\n\t },\n\n\t _setChildrenAnimation: function() {\n\t var this$1 = this;\n\n\t var points = this.points;\n\n\t for (var idx = 0; idx < points.length; idx++) {\n\t var point = points[idx];\n\t var pointVisual = point.visual;\n\t if (pointVisual && defined(pointVisual.options.zIndex)) {\n\t point.options.animation = this$1.options.animation;\n\t point.createAnimation();\n\t }\n\t }\n\t },\n\n\t _setAnimationOptions: function() {\n\t var options = this.options;\n\t var animation = options.animation || {};\n\t var origin;\n\n\t if (options.isStacked) {\n\t var valueAxis = this.seriesValueAxis(options.series[0]);\n\t origin = valueAxis.getSlot(valueAxis.startValue());\n\t } else {\n\t origin = this.categoryAxis.getSlot(0);\n\t }\n\n\t animation.origin = new GeometryPoint(origin.x1, origin.y1);\n\t animation.vertical = !options.invertAxes;\n\t }\n\t});\n\n\tsetDefaultOptions(BarChart, {\n\t animation: {\n\t type: BAR\n\t }\n\t});\n\n\tvar Candlestick = ChartElement.extend({\n\t init: function(value, options) {\n\t ChartElement.fn.init.call(this, options);\n\t this.value = value;\n\t },\n\n\t reflow: function(box) {\n\t var ref = this;\n\t var options = ref.options;\n\t var value = ref.value;\n\t var chart = ref.owner;\n\t var valueAxis = chart.seriesValueAxis(options);\n\t var ocSlot = valueAxis.getSlot(value.open, value.close);\n\t var lhSlot = valueAxis.getSlot(value.low, value.high);\n\n\t ocSlot.x1 = lhSlot.x1 = box.x1;\n\t ocSlot.x2 = lhSlot.x2 = box.x2;\n\n\t this.realBody = ocSlot;\n\n\t var mid = lhSlot.center().x;\n\t var points = [];\n\n\t points.push([ [ mid, lhSlot.y1 ], [ mid, ocSlot.y1 ] ]);\n\t points.push([ [ mid, ocSlot.y2 ], [ mid, lhSlot.y2 ] ]);\n\n\t this.lines = points;\n\n\t this.box = lhSlot.clone().wrap(ocSlot);\n\n\t if (!this._rendered) {\n\t this._rendered = true;\n\t this.createNote();\n\t }\n\n\t this.reflowNote();\n\t },\n\n\t reflowNote: function() {\n\t if (this.note) {\n\t this.note.reflow(this.box);\n\t }\n\t },\n\n\t createVisual: function() {\n\t ChartElement.fn.createVisual.call(this);\n\t this._mainVisual = this.mainVisual(this.options);\n\t this.visual.append(\n\t this._mainVisual\n\t );\n\n\t this.createOverlay();\n\t },\n\n\t mainVisual: function(options) {\n\t var group = new Group();\n\n\t this.createBody(group, options);\n\t this.createLines(group, options);\n\n\t return group;\n\t },\n\n\t createBody: function(container, options) {\n\t var body = Path.fromRect(this.realBody.toRect(), {\n\t fill: {\n\t color: this.color,\n\t opacity: options.opacity\n\t },\n\t stroke: null\n\t });\n\n\t if (options.border.width > 0) {\n\t body.options.set(\"stroke\", {\n\t color: this.getBorderColor(),\n\t width: options.border.width,\n\t dashType: options.border.dashType,\n\t opacity: valueOrDefault(options.border.opacity, options.opacity)\n\t });\n\t }\n\n\t alignPathToPixel(body);\n\t container.append(body);\n\n\t if (hasGradientOverlay(options)) {\n\t container.append(this.createGradientOverlay(body, { baseColor: this.color }, deepExtend({\n\t end: !options.vertical ? [ 0, 1 ] : undefined\n\t }, options.overlay)));\n\t }\n\t },\n\n\t createLines: function(container, options) {\n\t this.drawLines(container, options, this.lines, options.line);\n\t },\n\n\t drawLines: function(container, options, lines, lineOptions) {\n\t if (!lines) {\n\t return;\n\t }\n\n\t var lineStyle = {\n\t stroke: {\n\t color: lineOptions.color || this.color,\n\t opacity: valueOrDefault(lineOptions.opacity, options.opacity),\n\t width: lineOptions.width,\n\t dashType: lineOptions.dashType,\n\t lineCap: \"butt\"\n\t }\n\t };\n\n\t for (var i = 0; i < lines.length; i++) {\n\t var line = Path.fromPoints(lines[i], lineStyle);\n\t alignPathToPixel(line);\n\t container.append(line);\n\t }\n\t },\n\n\t getBorderColor: function() {\n\t var border = this.options.border;\n\t var borderColor = border.color;\n\n\t if (!defined(borderColor)) {\n\t borderColor = new Color(this.color).brightness(border._brightness).toHex();\n\t }\n\n\t return borderColor;\n\t },\n\n\t createOverlay: function() {\n\t var overlay = Path.fromRect(this.box.toRect(), {\n\t fill: {\n\t color: WHITE,\n\t opacity: 0\n\t },\n\t stroke: null\n\t });\n\n\t this.visual.append(overlay);\n\t },\n\n\t createHighlight: function() {\n\t var highlight = this.options.highlight;\n\t var normalColor = this.color;\n\n\t this.color = highlight.color || this.color;\n\t var overlay = this.mainVisual(\n\t deepExtend({}, this.options, {\n\t line: {\n\t color: this.getBorderColor()\n\t }\n\t }, highlight)\n\t );\n\t this.color = normalColor;\n\n\t return overlay;\n\t },\n\n\t highlightVisual: function() {\n\t return this._mainVisual;\n\t },\n\n\t highlightVisualArgs: function() {\n\t return {\n\t options: this.options,\n\t rect: this.box.toRect(),\n\t visual: this._mainVisual\n\t };\n\t },\n\n\t tooltipAnchor: function() {\n\t var box = this.box;\n\t var clipBox = this.owner.pane.clipBox() || box;\n\n\t return {\n\t point: new Point(box.x2 + TOOLTIP_OFFSET, Math.max(box.y1, clipBox.y1) + TOOLTIP_OFFSET),\n\t align: {\n\t horizontal: LEFT,\n\t vertical: TOP\n\t }\n\t };\n\t },\n\n\t formatValue: function(format) {\n\t return this.owner.formatPointValue(this, format);\n\t },\n\n\t overlapsBox: function(box) {\n\t return this.box.overlaps(box);\n\t }\n\t});\n\n\tsetDefaultOptions(Candlestick, {\n\t vertical: true,\n\t border: {\n\t _brightness: 0.8\n\t },\n\t line: {\n\t width: 2\n\t },\n\t overlay: {\n\t gradient: \"glass\"\n\t },\n\t tooltip: {\n\t format: \"\" +\n\t \"\" +\n\t \"\" +\n\t \"\" +\n\t \"\" +\n\t \"\" +\n\t \"
{4:d}
Open:{0:C}
High:{1:C}
Low:{2:C}
Close:{3:C}
\"\n\t },\n\t highlight: {\n\t opacity: 1,\n\t border: {\n\t width: 1,\n\t opacity: 1\n\t },\n\t line: {\n\t width: 1,\n\t opacity: 1\n\t }\n\t },\n\t notes: {\n\t visible: true,\n\t label: {}\n\t }\n\t});\n\n\tdeepExtend(Candlestick.prototype, PointEventsMixin);\n\tdeepExtend(Candlestick.prototype, NoteMixin);\n\n\tfunction areNumbers(values) {\n\t return countNumbers(values) === values.length;\n\t}\n\n\tvar CandlestickChart = CategoricalChart.extend({\n\t reflowCategories: function(categorySlots) {\n\t var children = this.children;\n\t var childrenLength = children.length;\n\n\t for (var i = 0; i < childrenLength; i++) {\n\t children[i].reflow(categorySlots[i]);\n\t }\n\t },\n\n\t addValue: function(data, fields) {\n\t var categoryIx = fields.categoryIx;\n\t var category = fields.category;\n\t var series = fields.series;\n\t var seriesIx = fields.seriesIx;\n\t var ref = this;\n\t var children = ref.children;\n\t var options = ref.options;\n\t var value = data.valueFields;\n\t var valueParts = this.splitValue(value);\n\t var hasValue = areNumbers(valueParts);\n\t var dataItem = series.data[categoryIx];\n\t var categoryPoints = this.categoryPoints[categoryIx];\n\t var point;\n\n\t if (!categoryPoints) {\n\t this.categoryPoints[categoryIx] = categoryPoints = [];\n\t }\n\n\t if (hasValue) {\n\t point = this.createPoint(data, fields);\n\t }\n\n\t var cluster = children[categoryIx];\n\t if (!cluster) {\n\t cluster = new ClusterLayout({\n\t vertical: options.invertAxes,\n\t gap: options.gap,\n\t spacing: options.spacing,\n\t rtl: !options.invertAxes && (this.chartService || {}).rtl\n\t });\n\t this.append(cluster);\n\t }\n\n\t if (point) {\n\t this.updateRange(value, fields);\n\n\t cluster.append(point);\n\n\t point.categoryIx = categoryIx;\n\t point.category = category;\n\t point.series = series;\n\t point.seriesIx = seriesIx;\n\t point.owner = this;\n\t point.dataItem = dataItem;\n\t point.noteText = data.fields.noteText;\n\t }\n\n\t this.points.push(point);\n\t categoryPoints.push(point);\n\t },\n\n\t pointType: function() {\n\t return Candlestick;\n\t },\n\n\t createPoint: function(data, fields) {\n\t var categoryIx = fields.categoryIx;\n\t var category = fields.category;\n\t var series = fields.series;\n\t var seriesIx = fields.seriesIx;\n\t var pointType = this.pointType();\n\t var value = data.valueFields;\n\t var pointOptions = deepExtend({}, series);\n\t var color = data.fields.color || series.color;\n\n\t pointOptions = this.evalPointOptions(\n\t pointOptions, value, category, categoryIx, series, seriesIx\n\t );\n\n\t if (series.type === CANDLESTICK) {\n\t if (value.open > value.close) {\n\t color = data.fields.downColor || series.downColor || series.color;\n\t }\n\t }\n\n\t if (isFunction(series.color)) {\n\t color = pointOptions.color;\n\t }\n\n\t pointOptions.vertical = !this.options.invertAxes;\n\n\t var point = new pointType(value, pointOptions);\n\t point.color = color;\n\n\t return point;\n\t },\n\n\t splitValue: function(value) {\n\t return [ value.low, value.open, value.close, value.high ];\n\t },\n\n\t updateRange: function(value, fields) {\n\t var axisName = fields.series.axis;\n\t var parts = this.splitValue(value);\n\t var axisRange = this.valueAxisRanges[axisName];\n\n\t axisRange = this.valueAxisRanges[axisName] =\n\t axisRange || { min: MAX_VALUE, max: MIN_VALUE };\n\n\t axisRange = this.valueAxisRanges[axisName] = {\n\t min: Math.min.apply(Math, parts.concat([ axisRange.min ])),\n\t max: Math.max.apply(Math, parts.concat([ axisRange.max ]))\n\t };\n\t },\n\n\t formatPointValue: function(point, format) {\n\t var value = point.value;\n\n\t return this.chartService.format.auto(format,\n\t value.open, value.high,\n\t value.low, value.close, point.category\n\t );\n\t },\n\n\t animationPoints: function() {\n\t return this.points;\n\t }\n\t});\n\n\tdeepExtend(CandlestickChart.prototype, ClipAnimationMixin);\n\n\tvar BoxPlot = Candlestick.extend({\n\t init: function(value, options) {\n\t Candlestick.fn.init.call(this, value, options);\n\n\t this.createNote();\n\t },\n\n\t reflow: function(box) {\n\t var ref = this;\n\t var options = ref.options;\n\t var value = ref.value;\n\t var chart = ref.owner;\n\t var valueAxis = chart.seriesValueAxis(options);\n\t var whiskerSlot, boxSlot;\n\n\t this.boxSlot = boxSlot = valueAxis.getSlot(value.q1, value.q3);\n\t this.realBody = boxSlot;\n\t this.reflowBoxSlot(box);\n\n\t this.whiskerSlot = whiskerSlot = valueAxis.getSlot(value.lower, value.upper);\n\t this.reflowWhiskerSlot(box);\n\n\t var medianSlot = valueAxis.getSlot(value.median);\n\n\t if (value.mean) {\n\t var meanSlot = valueAxis.getSlot(value.mean);\n\t this.meanPoints = this.calcMeanPoints(box, meanSlot);\n\t }\n\n\t this.whiskerPoints = this.calcWhiskerPoints(boxSlot, whiskerSlot);\n\t this.medianPoints = this.calcMedianPoints(box, medianSlot);\n\n\t this.box = whiskerSlot.clone().wrap(boxSlot);\n\t this.reflowNote();\n\t },\n\n\t reflowBoxSlot: function(box) {\n\t this.boxSlot.x1 = box.x1;\n\t this.boxSlot.x2 = box.x2;\n\t },\n\n\t reflowWhiskerSlot: function(box) {\n\t this.whiskerSlot.x1 = box.x1;\n\t this.whiskerSlot.x2 = box.x2;\n\t },\n\n\t calcMeanPoints: function(box, meanSlot) {\n\t return [\n\t [ [ box.x1, meanSlot.y1 ], [ box.x2, meanSlot.y1 ] ]\n\t ];\n\t },\n\n\t calcWhiskerPoints: function(boxSlot, whiskerSlot) {\n\t var mid = whiskerSlot.center().x;\n\t return [ [\n\t [ mid - 5, whiskerSlot.y1 ], [ mid + 5, whiskerSlot.y1 ],\n\t [ mid, whiskerSlot.y1 ], [ mid, boxSlot.y1 ]\n\t ], [\n\t [ mid - 5, whiskerSlot.y2 ], [ mid + 5, whiskerSlot.y2 ],\n\t [ mid, whiskerSlot.y2 ], [ mid, boxSlot.y2 ]\n\t ] ];\n\t },\n\n\t calcMedianPoints: function(box, medianSlot) {\n\t return [\n\t [ [ box.x1, medianSlot.y1 ], [ box.x2, medianSlot.y1 ] ]\n\t ];\n\t },\n\n\t renderOutliers: function(options) {\n\t var this$1 = this;\n\n\t var value = this.value;\n\t var outliers = value.outliers || [];\n\t var outerFence = Math.abs(value.q3 - value.q1) * 3;\n\t var elements = [];\n\t var markers = options.markers || {};\n\n\t for (var i = 0; i < outliers.length; i++) {\n\t var outlierValue = outliers[i];\n\t if (outlierValue < value.q3 + outerFence && outlierValue > value.q1 - outerFence) {\n\t markers = options.outliers;\n\t } else {\n\t markers = options.extremes;\n\t }\n\t var markersBorder = deepExtend({}, markers.border);\n\n\t if (!defined(markersBorder.color)) {\n\t if (defined(this$1.color)) {\n\t markersBorder.color = this$1.color;\n\t } else {\n\t markersBorder.color =\n\t new Color(markers.background).brightness(BORDER_BRIGHTNESS).toHex();\n\t }\n\t }\n\n\t var shape = new ShapeElement({\n\t type: markers.type,\n\t width: markers.size,\n\t height: markers.size,\n\t rotation: markers.rotation,\n\t background: markers.background,\n\t border: markersBorder,\n\t opacity: markers.opacity\n\t });\n\n\t shape.value = outlierValue;\n\n\t elements.push(shape);\n\t }\n\n\t this.reflowOutliers(elements);\n\t return elements;\n\t },\n\n\t reflowOutliers: function(outliers) {\n\t var this$1 = this;\n\n\t var valueAxis = this.owner.seriesValueAxis(this.options);\n\t var center = this.box.center();\n\n\t for (var i = 0; i < outliers.length; i++) {\n\t var outlierValue = outliers[i].value;\n\t var markerBox = valueAxis.getSlot(outlierValue);\n\n\t if (this$1.options.vertical) {\n\t markerBox.move(center.x);\n\t } else {\n\t markerBox.move(undefined, center.y);\n\t }\n\n\t this$1.box = this$1.box.wrap(markerBox);\n\t outliers[i].reflow(markerBox);\n\t }\n\t },\n\n\t mainVisual: function(options) {\n\t var group = Candlestick.fn.mainVisual.call(this, options);\n\t var outliers = this.renderOutliers(options);\n\n\t for (var i = 0; i < outliers.length; i++) {\n\t var element = outliers[i].getElement();\n\t if (element) {\n\t group.append(element);\n\t }\n\t }\n\n\t return group;\n\t },\n\n\t createLines: function(container, options) {\n\t this.drawLines(container, options, this.whiskerPoints, options.whiskers);\n\t this.drawLines(container, options, this.medianPoints, options.median);\n\t this.drawLines(container, options, this.meanPoints, options.mean);\n\t },\n\n\t getBorderColor: function() {\n\t if ((this.options.border || {}).color) {\n\t return this.options.border.color;\n\t }\n\n\t if (this.color) {\n\t return this.color;\n\t }\n\n\t return Candlestick.fn.getBorderColor.call(this);\n\t }\n\t});\n\n\tsetDefaultOptions(BoxPlot, {\n\t border: {\n\t _brightness: 0.8\n\t },\n\t line: {\n\t width: 2\n\t },\n\t median: {\n\t color: \"#f6f6f6\"\n\t },\n\t mean: {\n\t width: 2,\n\t dashType: \"dash\",\n\t color: \"#f6f6f6\"\n\t },\n\t overlay: {\n\t gradient: \"glass\"\n\t },\n\t tooltip: {\n\t format: \"\" +\n\t \"\" +\n\t \"\" +\n\t \"\" +\n\t \"\" +\n\t \"\" +\n\t \"\" +\n\t \"\" +\n\t \"
{6:d}
Lower:{0:C}
Q1:{1:C}
Median:{2:C}
Mean:{5:C}
Q3:{3:C}
Upper:{4:C}
\"\n\t },\n\t highlight: {\n\t opacity: 1,\n\t border: {\n\t width: 1,\n\t opacity: 1\n\t },\n\t line: {\n\t width: 1,\n\t opacity: 1\n\t }\n\t },\n\t notes: {\n\t visible: true,\n\t label: {}\n\t },\n\t outliers: {\n\t visible: true,\n\t size: LINE_MARKER_SIZE,\n\t type: datavizConstants.CROSS,\n\t background: WHITE,\n\t border: {\n\t width: 2,\n\t opacity: 1\n\t },\n\t opacity: 0\n\t },\n\t extremes: {\n\t visible: true,\n\t size: LINE_MARKER_SIZE,\n\t type: CIRCLE,\n\t background: WHITE,\n\t border: {\n\t width: 2,\n\t opacity: 1\n\t },\n\t opacity: 0\n\t }\n\t});\n\n\tdeepExtend(BoxPlot.prototype, PointEventsMixin);\n\n\tvar VerticalBoxPlot = BoxPlot.extend({\n\t reflowBoxSlot: function(box) {\n\t this.boxSlot.y1 = box.y1;\n\t this.boxSlot.y2 = box.y2;\n\t },\n\n\t reflowWhiskerSlot: function(box) {\n\t this.whiskerSlot.y1 = box.y1;\n\t this.whiskerSlot.y2 = box.y2;\n\t },\n\n\t calcMeanPoints: function(box, meanSlot) {\n\t return [\n\t [ [ meanSlot.x1, box.y1 ], [ meanSlot.x1, box.y2 ] ]\n\t ];\n\t },\n\n\t calcWhiskerPoints: function(boxSlot, whiskerSlot) {\n\t var mid = whiskerSlot.center().y;\n\t return [ [\n\t [ whiskerSlot.x1, mid - 5 ], [ whiskerSlot.x1, mid + 5 ],\n\t [ whiskerSlot.x1, mid ], [ boxSlot.x1, mid ]\n\t ], [\n\t [ whiskerSlot.x2, mid - 5 ], [ whiskerSlot.x2, mid + 5 ],\n\t [ whiskerSlot.x2, mid ], [ boxSlot.x2, mid ]\n\t ] ];\n\t },\n\n\t calcMedianPoints: function(box, medianSlot) {\n\t return [\n\t [ [ medianSlot.x1, box.y1 ], [ medianSlot.x1, box.y2 ] ]\n\t ];\n\t }\n\t});\n\n\tvar BoxPlotChart = CandlestickChart.extend({\n\t addValue: function(data, fields) {\n\t var categoryIx = fields.categoryIx;\n\t var category = fields.category;\n\t var series = fields.series;\n\t var seriesIx = fields.seriesIx;\n\t var ref = this;\n\t var children = ref.children;\n\t var options = ref.options;\n\t var value = data.valueFields;\n\t var valueParts = this.splitValue(value);\n\t var hasValue = areNumbers(valueParts);\n\t var dataItem = series.data[categoryIx];\n\t var categoryPoints = this.categoryPoints[categoryIx];\n\t var point;\n\n\t if (!categoryPoints) {\n\t this.categoryPoints[categoryIx] = categoryPoints = [];\n\t }\n\n\t if (hasValue) {\n\t point = this.createPoint(data, fields);\n\t }\n\n\t var cluster = children[categoryIx];\n\t if (!cluster) {\n\t cluster = new ClusterLayout({\n\t vertical: options.invertAxes,\n\t gap: options.gap,\n\t spacing: options.spacing,\n\t rtl: !options.invertAxes && (this.chartService || {}).rtl\n\t });\n\t this.append(cluster);\n\t }\n\n\t if (point) {\n\t this.updateRange(value, fields);\n\n\t cluster.append(point);\n\n\t point.categoryIx = categoryIx;\n\t point.category = category;\n\t point.series = series;\n\t point.seriesIx = seriesIx;\n\t point.owner = this;\n\t point.dataItem = dataItem;\n\t }\n\n\t this.points.push(point);\n\t categoryPoints.push(point);\n\t },\n\n\t pointType: function() {\n\t if (this.options.invertAxes) {\n\t return VerticalBoxPlot;\n\t }\n\n\t return BoxPlot;\n\t },\n\n\t splitValue: function(value) {\n\t return [\n\t value.lower, value.q1, value.median,\n\t value.q3, value.upper\n\t ];\n\t },\n\n\t updateRange: function(value, fields) {\n\t var axisName = fields.series.axis;\n\t var axisRange = this.valueAxisRanges[axisName];\n\t var parts = this.splitValue(value).concat(this.filterOutliers(value.outliers));\n\n\t if (defined(value.mean)) {\n\t parts = parts.concat(value.mean);\n\t }\n\n\t axisRange = this.valueAxisRanges[axisName] =\n\t axisRange || { min: MAX_VALUE, max: MIN_VALUE };\n\n\t axisRange = this.valueAxisRanges[axisName] = {\n\t min: Math.min.apply(Math, parts.concat([ axisRange.min ])),\n\t max: Math.max.apply(Math, parts.concat([ axisRange.max ]))\n\t };\n\t },\n\n\t formatPointValue: function(point, format) {\n\t var value = point.value;\n\n\t return this.chartService.format.auto(format,\n\t value.lower, value.q1, value.median,\n\t value.q3, value.upper, value.mean, point.category\n\t );\n\t },\n\n\t filterOutliers: function(items) {\n\t var length = (items || []).length;\n\t var result = [];\n\n\t for (var i = 0; i < length; i++) {\n\t var item = items[i];\n\t if (defined(item) && item !== null) {\n\t result.push(item);\n\t }\n\t }\n\n\t return result;\n\t }\n\t});\n\n\tvar ScatterErrorBar = ErrorBarBase.extend({\n\t getAxis: function() {\n\t var axes = this.chart.seriesAxes(this.series);\n\t var axis = this.isVertical ? axes.y : axes.x;\n\n\t return axis;\n\t }\n\t});\n\n\tfunction hasValue(value) {\n\t return defined(value) && value !== null;\n\t}\n\n\tvar ScatterChart = ChartElement.extend({\n\t init: function(plotArea, options) {\n\n\t ChartElement.fn.init.call(this, options);\n\n\t this.plotArea = plotArea;\n\t this.chartService = plotArea.chartService;\n\t this._initFields();\n\n\t this.render();\n\t },\n\n\t _initFields: function() {\n\t // X and Y axis ranges grouped by name, e.g.:\n\t // primary: { min: 0, max: 1 }\n\t this.xAxisRanges = {};\n\t this.yAxisRanges = {};\n\n\t this.points = [];\n\t this.seriesPoints = [];\n\t this.seriesOptions = [];\n\t this._evalSeries = [];\n\t },\n\n\t render: function() {\n\t this.traverseDataPoints(this.addValue.bind(this));\n\t },\n\n\t addErrorBar: function(point, field, fields) {\n\t var value = point.value[field];\n\t var valueErrorField = field + \"Value\";\n\t var lowField = field + \"ErrorLow\";\n\t var highField = field + \"ErrorHigh\";\n\t var seriesIx = fields.seriesIx;\n\t var series = fields.series;\n\t var errorBars = point.options.errorBars;\n\t var lowValue = fields[lowField];\n\t var highValue = fields[highField];\n\n\t if (isNumber(value)) {\n\t var errorRange;\n\t if (isNumber(lowValue) && isNumber(highValue)) {\n\t errorRange = { low: lowValue, high: highValue };\n\t }\n\n\t if (errorBars && defined(errorBars[valueErrorField])) {\n\t this.seriesErrorRanges = this.seriesErrorRanges || { x: [], y: [] };\n\t this.seriesErrorRanges[field][seriesIx] = this.seriesErrorRanges[field][seriesIx] ||\n\t new ErrorRangeCalculator(errorBars[valueErrorField], series, field);\n\n\t errorRange = this.seriesErrorRanges[field][seriesIx].getErrorRange(value, errorBars[valueErrorField]);\n\t }\n\n\t if (errorRange) {\n\t this.addPointErrorBar(errorRange, point, field);\n\t }\n\t }\n\t },\n\n\t addPointErrorBar: function(errorRange, point, field) {\n\t var low = errorRange.low;\n\t var high = errorRange.high;\n\t var series = point.series;\n\t var options = point.options.errorBars;\n\t var isVertical = field === Y;\n\t var item = {};\n\n\t point[field + \"Low\"] = low;\n\t point[field + \"High\"] = high;\n\n\t point.errorBars = point.errorBars || [];\n\t var errorBar = new ScatterErrorBar(low, high, isVertical, this, series, options);\n\t point.errorBars.push(errorBar);\n\t point.append(errorBar);\n\n\t item[field] = low;\n\t this.updateRange(item, series);\n\t item[field] = high;\n\t this.updateRange(item, series);\n\t },\n\n\t addValue: function(value, fields) {\n\t var x = value.x;\n\t var y = value.y;\n\t var seriesIx = fields.seriesIx;\n\t var series = this.options.series[seriesIx];\n\t var missingValues = this.seriesMissingValues(series);\n\t var seriesPoints = this.seriesPoints[seriesIx];\n\n\t var pointValue = value;\n\t if (!(hasValue(x) && hasValue(y))) {\n\t pointValue = this.createMissingValue(pointValue, missingValues);\n\t }\n\n\t var point;\n\t if (pointValue) {\n\t point = this.createPoint(pointValue, fields);\n\t if (point) {\n\t $.extend(point, fields);\n\t this.addErrorBar(point, X, fields);\n\t this.addErrorBar(point, Y, fields);\n\t }\n\t this.updateRange(pointValue, fields.series);\n\t }\n\n\t this.points.push(point);\n\t seriesPoints.push(point);\n\t },\n\n\t seriesMissingValues: function(series) {\n\t return series.missingValues;\n\t },\n\n\t createMissingValue: function() {},\n\n\t updateRange: function(value, series) {\n\t var intlService = this.chartService.intl;\n\t var xAxisName = series.xAxis;\n\t var yAxisName = series.yAxis;\n\t var x = value.x;\n\t var y = value.y;\n\t var xAxisRange = this.xAxisRanges[xAxisName];\n\t var yAxisRange = this.yAxisRanges[yAxisName];\n\n\t if (hasValue(x)) {\n\t xAxisRange = this.xAxisRanges[xAxisName] =\n\t xAxisRange || { min: MAX_VALUE, max: MIN_VALUE };\n\n\t if (isString(x)) {\n\t x = parseDate(intlService, x);\n\t }\n\n\t xAxisRange.min = Math.min(xAxisRange.min, x);\n\t xAxisRange.max = Math.max(xAxisRange.max, x);\n\t }\n\n\t if (hasValue(y)) {\n\t yAxisRange = this.yAxisRanges[yAxisName] =\n\t yAxisRange || { min: MAX_VALUE, max: MIN_VALUE };\n\n\t if (isString(y)) {\n\t y = parseDate(intlService, y);\n\t }\n\n\t yAxisRange.min = Math.min(yAxisRange.min, y);\n\t yAxisRange.max = Math.max(yAxisRange.max, y);\n\t }\n\t },\n\n\t evalPointOptions: function(options, value, fields) {\n\t var series = fields.series;\n\t var seriesIx = fields.seriesIx;\n\t var state = { defaults: series._defaults, excluded: [ \"data\", \"tooltip\", \"content\", \"template\", \"visual\", \"toggle\", \"_outOfRangeMinPoint\", \"_outOfRangeMaxPoint\" ] };\n\n\t var doEval = this._evalSeries[seriesIx];\n\t if (!defined(doEval)) {\n\t this._evalSeries[seriesIx] = doEval = evalOptions(options, {}, state, true);\n\t }\n\n\t var pointOptions = options;\n\t if (doEval) {\n\t pointOptions = deepExtend({}, options);\n\t evalOptions(pointOptions, {\n\t value: value,\n\t series: series,\n\t dataItem: fields.dataItem\n\t }, state);\n\t }\n\n\t return pointOptions;\n\t },\n\n\t pointType: function() {\n\t return LinePoint;\n\t },\n\n\t pointOptions: function(series, seriesIx) {\n\t var options = this.seriesOptions[seriesIx];\n\t if (!options) {\n\t var defaults = this.pointType().prototype.defaults;\n\t this.seriesOptions[seriesIx] = options = deepExtend({}, defaults, {\n\t markers: {\n\t opacity: series.opacity\n\t },\n\t tooltip: {\n\t format: this.options.tooltip.format\n\t },\n\t labels: {\n\t format: this.options.labels.format\n\t }\n\t }, series);\n\t }\n\n\t return options;\n\t },\n\n\t createPoint: function(value, fields) {\n\t var series = fields.series;\n\t var pointOptions = this.pointOptions(series, fields.seriesIx);\n\t var color = fields.color || series.color;\n\n\t pointOptions = this.evalPointOptions(pointOptions, value, fields);\n\n\t if (isFunction(series.color)) {\n\t color = pointOptions.color;\n\t }\n\n\t var point = new LinePoint(value, pointOptions);\n\t point.color = color;\n\n\t this.append(point);\n\n\t return point;\n\t },\n\n\t seriesAxes: function(series) {\n\t var xAxisName = series.xAxis;\n\t var yAxisName = series.yAxis;\n\t var plotArea = this.plotArea;\n\t var xAxis = xAxisName ? plotArea.namedXAxes[xAxisName] : plotArea.axisX;\n\t var yAxis = yAxisName ? plotArea.namedYAxes[yAxisName] : plotArea.axisY;\n\n\t if (!xAxis) {\n\t throw new Error(\"Unable to locate X axis with name \" + xAxisName);\n\t }\n\n\t if (!yAxis) {\n\t throw new Error(\"Unable to locate Y axis with name \" + yAxisName);\n\t }\n\n\t return {\n\t x: xAxis,\n\t y: yAxis\n\t };\n\t },\n\n\t reflow: function(targetBox) {\n\t var this$1 = this;\n\n\t var chartPoints = this.points;\n\t var limit = !this.options.clip;\n\t var pointIx = 0;\n\n\t this.traverseDataPoints(function (value, fields) {\n\t var point = chartPoints[pointIx++];\n\t var seriesAxes = this$1.seriesAxes(fields.series);\n\t var slotX = seriesAxes.x.getSlot(value.x, value.x, limit);\n\t var slotY = seriesAxes.y.getSlot(value.y, value.y, limit);\n\n\t if (point) {\n\t if (slotX && slotY) {\n\t var pointSlot = this$1.pointSlot(slotX, slotY);\n\t point.reflow(pointSlot);\n\t } else {\n\t point.visible = false;\n\t }\n\t }\n\t });\n\n\t this.box = targetBox;\n\t },\n\n\t pointSlot: function(slotX, slotY) {\n\t return new Box(slotX.x1, slotY.y1, slotX.x2, slotY.y2);\n\t },\n\n\t traverseDataPoints: function(callback) {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var series = ref.options.series;\n\t var seriesPoints = ref.seriesPoints;\n\n\t for (var seriesIx = 0; seriesIx < series.length; seriesIx++) {\n\t var currentSeries = series[seriesIx];\n\t var currentSeriesPoints = seriesPoints[seriesIx];\n\t if (!currentSeriesPoints) {\n\t seriesPoints[seriesIx] = [];\n\t }\n\n\t for (var pointIx = 0; pointIx < currentSeries.data.length; pointIx++) {\n\t var ref$1 = this$1._bindPoint(currentSeries, seriesIx, pointIx);\n\t var value = ref$1.valueFields;\n\t var fields = ref$1.fields;\n\n\t callback(value, deepExtend({\n\t pointIx: pointIx,\n\t series: currentSeries,\n\t seriesIx: seriesIx,\n\t dataItem: currentSeries.data[pointIx],\n\t owner: this$1\n\t }, fields));\n\t }\n\t }\n\t },\n\n\t formatPointValue: function(point, format) {\n\t var value = point.value;\n\t return this.chartService.format.auto(format, value.x, value.y);\n\t },\n\n\t animationPoints: function() {\n\t var points = this.points;\n\t var result = [];\n\t for (var idx = 0; idx < points.length; idx++) {\n\t result.push((points[idx] || {}).marker);\n\t }\n\t return result;\n\t }\n\t});\n\tsetDefaultOptions(ScatterChart, {\n\t series: [],\n\t tooltip: {\n\t format: \"{0}, {1}\"\n\t },\n\t labels: {\n\t format: \"{0}, {1}\"\n\t },\n\t clip: true\n\t});\n\tdeepExtend(ScatterChart.prototype, ClipAnimationMixin, {\n\t _bindPoint: CategoricalChart.prototype._bindPoint\n\t});\n\n\tvar Bubble = LinePoint.extend({\n\t init: function(value, options) {\n\t LinePoint.fn.init.call(this, value, options);\n\n\t this.category = value.category;\n\t },\n\n\t createHighlight: function() {\n\t var highlight = this.options.highlight;\n\t var border = highlight.border;\n\t var markers = this.options.markers;\n\t var center = this.box.center();\n\t var radius = (markers.size + markers.border.width + border.width) / 2;\n\t var highlightGroup = new Group();\n\t var shadow = new drawing.Circle(new geometry.Circle([ center.x, center.y + radius / 5 + border.width / 2 ], radius + border.width / 2), {\n\t stroke: {\n\t color: 'none'\n\t },\n\t fill: this.createGradient({\n\t gradient: 'bubbleShadow',\n\t color: markers.background,\n\t stops: [ {\n\t offset: 0,\n\t color: markers.background,\n\t opacity: 0.3\n\t }, {\n\t offset: 1,\n\t color: markers.background,\n\t opacity: 0\n\t } ]\n\t })\n\t });\n\t var overlay = new drawing.Circle(new geometry.Circle([ center.x, center.y ], radius), {\n\t stroke: {\n\t color: border.color ||\n\t new Color(markers.background).brightness(BORDER_BRIGHTNESS).toHex(),\n\t width: border.width,\n\t opacity: border.opacity\n\t },\n\t fill: {\n\t color: markers.background,\n\t opacity: highlight.opacity\n\t }\n\t });\n\n\t highlightGroup.append(shadow, overlay);\n\n\t return highlightGroup;\n\t }\n\t});\n\n\tBubble.prototype.defaults = deepExtend({}, Bubble.prototype.defaults, {\n\t labels: {\n\t position: CENTER\n\t },\n\t highlight: {\n\t opacity: 1,\n\t border: {\n\t color: \"#fff\",\n\t width: 2,\n\t opacity: 1\n\t }\n\t }\n\t});\n\n\tBubble.prototype.defaults.highlight.zIndex = undefined;\n\n\tvar BubbleChart = ScatterChart.extend({\n\t _initFields: function() {\n\t this._maxSize = MIN_VALUE;\n\t ScatterChart.fn._initFields.call(this);\n\t },\n\n\t addValue: function(value, fields) {\n\t if (value.size !== null && (value.size > 0 || (value.size < 0 && fields.series.negativeValues.visible))) {\n\t this._maxSize = Math.max(this._maxSize, Math.abs(value.size));\n\t ScatterChart.fn.addValue.call(this, value, fields);\n\t } else {\n\t this.points.push(null);\n\t this.seriesPoints[fields.seriesIx].push(null);\n\t }\n\t },\n\n\t reflow: function(box) {\n\t this.updateBubblesSize(box);\n\t ScatterChart.fn.reflow.call(this, box);\n\t },\n\n\t pointType: function() {\n\t return Bubble;\n\t },\n\n\t createPoint: function(value, fields) {\n\t var series = fields.series;\n\t var pointsCount = series.data.length;\n\t var delay = fields.pointIx * (INITIAL_ANIMATION_DURATION / pointsCount);\n\t var animationOptions = {\n\t delay: delay,\n\t duration: INITIAL_ANIMATION_DURATION - delay,\n\t type: BUBBLE\n\t };\n\n\t var color = fields.color || series.color;\n\t if (value.size < 0 && series.negativeValues.visible) {\n\t color = valueOrDefault(\n\t series.negativeValues.color, color\n\t );\n\t }\n\n\t var pointOptions = deepExtend({\n\t labels: {\n\t animation: {\n\t delay: delay,\n\t duration: INITIAL_ANIMATION_DURATION - delay\n\t }\n\t }\n\t }, this.pointOptions(series, fields.seriesIx), {\n\t markers: {\n\t type: CIRCLE,\n\t border: series.border,\n\t opacity: series.opacity,\n\t animation: animationOptions\n\t }\n\t });\n\n\t pointOptions = this.evalPointOptions(pointOptions, value, fields);\n\t if (isFunction(series.color)) {\n\t color = pointOptions.color;\n\t }\n\n\t pointOptions.markers.background = color;\n\n\t var point = new Bubble(value, pointOptions);\n\t point.color = color;\n\n\t this.append(point);\n\n\t return point;\n\t },\n\n\t updateBubblesSize: function(box) {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var series = ref.options.series;\n\t var boxSize = Math.min(box.width(), box.height());\n\n\t for (var seriesIx = 0; seriesIx < series.length; seriesIx++) {\n\t var currentSeries = series[seriesIx];\n\t var seriesPoints = this$1.seriesPoints[seriesIx];\n\t var minSize = currentSeries.minSize || Math.max(boxSize * 0.02, 10);\n\t var maxSize = currentSeries.maxSize || boxSize * 0.2;\n\t var minR = minSize / 2;\n\t var maxR = maxSize / 2;\n\t var minArea = Math.PI * minR * minR;\n\t var maxArea = Math.PI * maxR * maxR;\n\t var areaRange = maxArea - minArea;\n\t var areaRatio = areaRange / this$1._maxSize;\n\n\t for (var pointIx = 0; pointIx < seriesPoints.length; pointIx++) {\n\t var point = seriesPoints[pointIx];\n\t if (point) {\n\t var area = Math.abs(point.value.size) * areaRatio;\n\t var radius = Math.sqrt((minArea + area) / Math.PI);\n\t var baseZIndex = valueOrDefault(point.options.zIndex, 0);\n\t var zIndex = baseZIndex + (1 - radius / maxR);\n\n\t deepExtend(point.options, {\n\t zIndex: zIndex,\n\t markers: {\n\t size: radius * 2,\n\t zIndex: zIndex\n\t },\n\t labels: {\n\t zIndex: zIndex + 1\n\t }\n\t });\n\t }\n\t }\n\t }\n\t },\n\n\t formatPointValue: function(point, format) {\n\t var value = point.value;\n\t return this.chartService.format.auto(format, value.x, value.y, value.size, point.category);\n\t },\n\n\t createAnimation: function() {},\n\n\t createVisual: function() {}\n\t});\n\n\tsetDefaultOptions(BubbleChart, {\n\t tooltip: {\n\t format: \"{3}\"\n\t },\n\t labels: {\n\t format: \"{3}\"\n\t }\n\t});\n\n\tvar Target = ShapeElement.extend({\n\n\t});\n\n\tdeepExtend(Target.prototype, PointEventsMixin);\n\n\tvar Bullet = ChartElement.extend({\n\t init: function(value, options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.aboveAxis = this.options.aboveAxis;\n\t this.color = options.color || WHITE;\n\t this.value = value;\n\t },\n\n\t render: function() {\n\t var options = this.options;\n\n\t if (!this._rendered) {\n\t this._rendered = true;\n\n\t if (defined(this.value.target)) {\n\t this.target = new Target({\n\t type: options.target.shape,\n\t background: options.target.color || this.color,\n\t opacity: options.opacity,\n\t zIndex: options.zIndex,\n\t border: options.target.border,\n\t vAlign: TOP,\n\t align: RIGHT\n\t });\n\n\t this.target.value = this.value;\n\t this.target.dataItem = this.dataItem;\n\t this.target.series = this.series;\n\n\t this.append(this.target);\n\t }\n\n\t this.createNote();\n\t }\n\t },\n\n\t reflow: function(box) {\n\t this.render();\n\n\t var ref = this;\n\t var options = ref.options;\n\t var target = ref.target;\n\t var chart = ref.owner;\n\t var invertAxes = options.invertAxes;\n\t var valueAxis = chart.seriesValueAxis(this.options);\n\t var categorySlot = chart.categorySlot(chart.categoryAxis, options.categoryIx, valueAxis);\n\t var targetValueSlot = valueAxis.getSlot(this.value.target);\n\t var targetSlotX = invertAxes ? targetValueSlot : categorySlot;\n\t var targetSlotY = invertAxes ? categorySlot : targetValueSlot;\n\n\t if (target) {\n\t var targetSlot = new Box(\n\t targetSlotX.x1, targetSlotY.y1,\n\t targetSlotX.x2, targetSlotY.y2\n\t );\n\t target.options.height = invertAxes ? targetSlot.height() : options.target.line.width;\n\t target.options.width = invertAxes ? options.target.line.width : targetSlot.width();\n\t target.reflow(targetSlot);\n\t }\n\n\t if (this.note) {\n\t this.note.reflow(box);\n\t }\n\n\t this.box = box;\n\t },\n\n\t createVisual: function() {\n\t ChartElement.fn.createVisual.call(this);\n\n\t var options = this.options;\n\t var body = Path.fromRect(this.box.toRect(), {\n\t fill: {\n\t color: this.color,\n\t opacity: options.opacity\n\t },\n\t stroke: null\n\t });\n\n\t if (options.border.width > 0) {\n\t body.options.set(\"stroke\", {\n\t color: options.border.color || this.color,\n\t width: options.border.width,\n\t dashType: options.border.dashType,\n\t opacity: valueOrDefault(options.border.opacity, options.opacity)\n\t });\n\t }\n\n\t this.bodyVisual = body;\n\n\t alignPathToPixel(body);\n\t this.visual.append(body);\n\t },\n\n\t createAnimation: function() {\n\t if (this.bodyVisual) {\n\t this.animation = Animation.create(\n\t this.bodyVisual, this.options.animation\n\t );\n\t }\n\t },\n\n\t createHighlight: function(style) {\n\t return Path.fromRect(this.box.toRect(), style);\n\t },\n\n\t highlightVisual: function() {\n\t return this.bodyVisual;\n\t },\n\n\t highlightVisualArgs: function() {\n\t return {\n\t rect: this.box.toRect(),\n\t visual: this.bodyVisual,\n\t options: this.options\n\t };\n\t },\n\n\t formatValue: function(format) {\n\t return this.owner.formatPointValue(this, format);\n\t }\n\t});\n\n\tBullet.prototype.tooltipAnchor = Bar.prototype.tooltipAnchor;\n\n\tsetDefaultOptions(Bullet, {\n\t border: {\n\t width: 1\n\t },\n\t vertical: false,\n\t opacity: 1,\n\t target: {\n\t shape: \"\",\n\t border: {\n\t width: 0,\n\t color: \"green\"\n\t },\n\t line: {\n\t width: 2\n\t }\n\t },\n\t tooltip: {\n\t format: \"Current: {0}
Target: {1}\"\n\t }\n\t});\n\n\tdeepExtend(Bullet.prototype, PointEventsMixin);\n\tdeepExtend(Bullet.prototype, NoteMixin);\n\n\tvar BulletChart = CategoricalChart.extend({\n\t init: function(plotArea, options) {\n\n\t wrapData(options);\n\n\t CategoricalChart.fn.init.call(this, plotArea, options);\n\t },\n\n\t reflowCategories: function(categorySlots) {\n\t var children = this.children;\n\t var childrenLength = children.length;\n\n\t for (var i = 0; i < childrenLength; i++) {\n\t children[i].reflow(categorySlots[i]);\n\t }\n\t },\n\n\t plotRange: function(point) {\n\t var series = point.series;\n\t var valueAxis = this.seriesValueAxis(series);\n\t var axisCrossingValue = this.categoryAxisCrossingValue(valueAxis);\n\n\t return [ axisCrossingValue, point.value.current || axisCrossingValue ];\n\t },\n\n\t createPoint: function(data, fields) {\n\t var categoryIx = fields.categoryIx;\n\t var category = fields.category;\n\t var series = fields.series;\n\t var seriesIx = fields.seriesIx;\n\t var ref = this;\n\t var options = ref.options;\n\t var children = ref.children;\n\t var value = data.valueFields;\n\n\t var bulletOptions = deepExtend({\n\t vertical: !options.invertAxes,\n\t overlay: series.overlay,\n\t categoryIx: categoryIx,\n\t invertAxes: options.invertAxes\n\t }, series);\n\n\t var color = data.fields.color || series.color;\n\t bulletOptions = this.evalPointOptions(\n\t bulletOptions, value, category, categoryIx, series, seriesIx\n\t );\n\n\t if (isFunction(series.color)) {\n\t color = bulletOptions.color;\n\t }\n\n\t var bullet = new Bullet(value, bulletOptions);\n\t bullet.color = color;\n\n\t var cluster = children[categoryIx];\n\t if (!cluster) {\n\t cluster = new ClusterLayout({\n\t vertical: options.invertAxes,\n\t gap: options.gap,\n\t spacing: options.spacing,\n\t rtl: !options.invertAxes && (this.chartService || {}).rtl\n\t });\n\t this.append(cluster);\n\t }\n\n\t cluster.append(bullet);\n\n\t return bullet;\n\t },\n\n\t updateRange: function(value, fields) {\n\t var current = value.current;\n\t var target = value.target;\n\t var axisName = fields.series.axis;\n\t var axisRange = this.valueAxisRanges[axisName];\n\n\t if (defined(current) && !isNaN(current) && defined(target && !isNaN(target))) {\n\t axisRange = this.valueAxisRanges[axisName] =\n\t axisRange || { min: MAX_VALUE, max: MIN_VALUE };\n\n\t axisRange.min = Math.min(axisRange.min, current, target);\n\t axisRange.max = Math.max(axisRange.max, current, target);\n\t }\n\t },\n\n\t formatPointValue: function(point, format) {\n\t return this.chartService.format.auto(format, point.value.current, point.value.target);\n\t },\n\n\t pointValue: function(data) {\n\t return data.valueFields.current;\n\t },\n\n\t aboveAxis: function(point) {\n\t var value = point.value.current;\n\n\t return value > 0;\n\t },\n\n\t createAnimation: function() {\n\t var this$1 = this;\n\n\t var points = this.points;\n\n\t this._setAnimationOptions();\n\n\t for (var idx = 0; idx < points.length; idx++) {\n\t var point = points[idx];\n\t point.options.animation = this$1.options.animation;\n\t point.createAnimation();\n\t }\n\t }\n\t});\n\n\tBulletChart.prototype._setAnimationOptions = BarChart.prototype._setAnimationOptions;\n\n\tsetDefaultOptions(BulletChart, {\n\t animation: {\n\t type: BAR\n\t }\n\t});\n\n\tfunction wrapData(options) {\n\t var series = options.series;\n\n\t for (var i = 0; i < series.length; i++) {\n\t var seriesItem = series[i];\n\t var data = seriesItem.data;\n\t if (data && !isArray(data[0]) && !isObject(data[0])) {\n\t seriesItem.data = [ data ];\n\t }\n\t }\n\t}\n\n\tvar BaseTooltip = Class.extend({\n\t init: function(chartService, options) {\n\n\t this.chartService = chartService;\n\t this.options = deepExtend({}, this.options, options);\n\t },\n\n\t getStyle: function(options, point) {\n\t var background = options.background;\n\t var border = options.border.color;\n\n\t if (point) {\n\t var pointColor = point.color || point.options.color;\n\t background = valueOrDefault(background, pointColor);\n\t border = valueOrDefault(border, pointColor);\n\t }\n\n\t var padding = getSpacing(options.padding || {}, \"auto\");\n\n\t return {\n\t backgroundColor: background,\n\t borderColor: border,\n\t font: options.font,\n\t color: options.color,\n\t opacity: options.opacity,\n\t borderWidth: styleValue(options.border.width),\n\t paddingTop: styleValue(padding.top),\n\t paddingBottom: styleValue(padding.bottom),\n\t paddingLeft: styleValue(padding.left),\n\t paddingRight: styleValue(padding.right)\n\t };\n\t },\n\n\t show: function(options, tooltipOptions, point) {\n\t options.format = tooltipOptions.format;\n\n\t var style = this.getStyle(tooltipOptions, point);\n\t options.style = style;\n\n\t if (!defined(tooltipOptions.color) && new Color(style.backgroundColor).percBrightness() > 180) {\n\t options.className = \"k-chart-tooltip-inverse\";\n\t }\n\n\t this.chartService.notify(SHOW_TOOLTIP, options);\n\n\t this.visible = true;\n\t },\n\n\t hide: function() {\n\t if (this.chartService) {\n\t this.chartService.notify(HIDE_TOOLTIP);\n\t }\n\n\t this.visible = false;\n\t },\n\n\t destroy: function() {\n\t delete this.chartService;\n\t }\n\t});\n\n\tsetDefaultOptions(BaseTooltip, {\n\t border: {\n\t width: 1\n\t },\n\t opacity: 1\n\t});\n\n\tvar CrosshairTooltip = BaseTooltip.extend({\n\t init: function(chartService, crosshair, options) {\n\t BaseTooltip.fn.init.call(this, chartService, options);\n\n\t this.crosshair = crosshair;\n\t this.formatService = chartService.format;\n\t this.initAxisName();\n\t },\n\n\t initAxisName: function() {\n\t var axis = this.crosshair.axis;\n\t var plotArea = axis.plotArea;\n\t var name;\n\t if (plotArea.categoryAxis) {\n\t name = axis.getCategory ? \"categoryAxis\" : \"valueAxis\";\n\t } else {\n\t name = axis.options.vertical ? \"yAxis\" : \"xAxis\";\n\t }\n\t this.axisName = name;\n\t },\n\n\t showAt: function(point) {\n\t var ref = this;\n\t var axis = ref.crosshair.axis;\n\t var options = ref.options;\n\t var value = axis[options.stickyMode ? \"getCategory\" : \"getValue\"](point);\n\t var formattedValue = value;\n\n\t if (options.format) {\n\t formattedValue = this.formatService.auto(options.format, value);\n\t } else if (axis.options.type === DATE) {\n\t formattedValue = this.formatService.auto(axis.options.labels.dateFormats[axis.options.baseUnit], value);\n\t }\n\n\t this.show({\n\t point: point,\n\t anchor: this.getAnchor(),\n\t crosshair: this.crosshair,\n\t value: formattedValue,\n\t axisName: this.axisName,\n\t axisIndex: this.crosshair.axis.axisIndex\n\t }, this.options);\n\t },\n\n\t hide: function() {\n\t this.chartService.notify(HIDE_TOOLTIP, {\n\t crosshair: this.crosshair,\n\t axisName: this.axisName,\n\t axisIndex: this.crosshair.axis.axisIndex\n\t });\n\t },\n\n\t getAnchor: function() {\n\t var ref = this;\n\t var crosshair = ref.crosshair;\n\t var ref_options = ref.options;\n\t var position = ref_options.position;\n\t var padding = ref_options.padding;\n\t var vertical = !crosshair.axis.options.vertical;\n\t var lineBox = crosshair.line.bbox();\n\t var horizontalAlign, verticalAlign, point;\n\n\t if (vertical) {\n\t horizontalAlign = CENTER;\n\t if (position === BOTTOM) {\n\t verticalAlign = TOP;\n\t point = lineBox.bottomLeft().translate(0, padding);\n\t } else {\n\t verticalAlign = BOTTOM;\n\t point = lineBox.topLeft().translate(0, -padding);\n\t }\n\t } else {\n\t verticalAlign = CENTER;\n\t if (position === LEFT) {\n\t horizontalAlign = RIGHT;\n\t point = lineBox.topLeft().translate(-padding, 0);\n\t } else {\n\t horizontalAlign = LEFT;\n\t point = lineBox.topRight().translate(padding, 0);\n\t }\n\t }\n\n\t return {\n\t point: point,\n\t align: {\n\t horizontal: horizontalAlign,\n\t vertical: verticalAlign\n\t }\n\t };\n\t }\n\t});\n\n\tsetDefaultOptions(CrosshairTooltip, {\n\t padding: 10\n\t});\n\n\tvar Crosshair = ChartElement.extend({\n\t init: function(chartService, axis, options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.axis = axis;\n\t this.stickyMode = axis instanceof CategoryAxis;\n\n\t var tooltipOptions = this.options.tooltip;\n\n\t if (tooltipOptions.visible) {\n\t this.tooltip = new CrosshairTooltip(chartService, this,\n\t deepExtend({}, tooltipOptions, { stickyMode: this.stickyMode })\n\t );\n\t }\n\t },\n\n\t showAt: function(point) {\n\t this.point = point;\n\t this.moveLine();\n\t this.line.visible(true);\n\n\t if (this.tooltip) {\n\t this.tooltip.showAt(point);\n\t }\n\t },\n\n\t hide: function() {\n\t this.line.visible(false);\n\n\t if (this.tooltip) {\n\t this.tooltip.hide();\n\t }\n\t },\n\n\t moveLine: function() {\n\t var ref = this;\n\t var axis = ref.axis;\n\t var point = ref.point;\n\t var vertical = axis.options.vertical;\n\t var box = this.getBox();\n\t var dim = vertical ? Y : X;\n\t var lineStart = new GeometryPoint(box.x1, box.y1);\n\t var lineEnd;\n\n\t if (vertical) {\n\t lineEnd = new GeometryPoint(box.x2, box.y1);\n\t } else {\n\t lineEnd = new GeometryPoint(box.x1, box.y2);\n\t }\n\n\t if (point) {\n\t if (this.stickyMode) {\n\t var slot = axis.getSlot(axis.pointCategoryIndex(point));\n\t lineStart[dim] = lineEnd[dim] = slot.center()[dim];\n\t } else {\n\t lineStart[dim] = lineEnd[dim] = point[dim];\n\t }\n\t }\n\n\t this.box = box;\n\n\t this.line.moveTo(lineStart).lineTo(lineEnd);\n\t },\n\n\t getBox: function() {\n\t var axis = this.axis;\n\t var axes = axis.pane.axes;\n\t var length = axes.length;\n\t var vertical = axis.options.vertical;\n\t var box = axis.lineBox().clone();\n\t var dim = vertical ? X : Y;\n\t var axisLineBox;\n\n\t for (var i = 0; i < length; i++) {\n\t var currentAxis = axes[i];\n\t if (currentAxis.options.vertical !== vertical) {\n\t if (!axisLineBox) {\n\t axisLineBox = currentAxis.lineBox().clone();\n\t } else {\n\t axisLineBox.wrap(currentAxis.lineBox());\n\t }\n\t }\n\t }\n\n\t box[dim + 1] = axisLineBox[dim + 1];\n\t box[dim + 2] = axisLineBox[dim + 2];\n\n\t return box;\n\t },\n\n\t createVisual: function() {\n\t ChartElement.fn.createVisual.call(this);\n\n\t var options = this.options;\n\t this.line = new Path({\n\t stroke: {\n\t color: options.color,\n\t width: options.width,\n\t opacity: options.opacity,\n\t dashType: options.dashType\n\t },\n\t visible: false\n\t });\n\n\t this.moveLine();\n\t this.visual.append(this.line);\n\t },\n\n\t destroy: function() {\n\t if (this.tooltip) {\n\t this.tooltip.destroy();\n\t }\n\n\t ChartElement.fn.destroy.call(this);\n\t }\n\t});\n\n\tsetDefaultOptions(Crosshair, {\n\t color: BLACK,\n\t width: 2,\n\t zIndex: -1,\n\t tooltip: {\n\t visible: false\n\t }\n\t});\n\n\tvar ChartContainer = ChartElement.extend({\n\t init: function(options, pane) {\n\t ChartElement.fn.init.call(this, options);\n\t this.pane = pane;\n\t },\n\n\t shouldClip: function() {\n\t var children = this.children;\n\t var length = children.length;\n\n\t for (var i = 0; i < length; i++) {\n\t if (children[i].options.clip === true) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t },\n\n\t _clipBox: function() {\n\t return this.pane.chartsBox();\n\t },\n\n\t createVisual: function() {\n\t this.visual = new Group({\n\t zIndex: 0\n\t });\n\n\t if (this.shouldClip()) {\n\t var clipBox = this.clipBox = this._clipBox();\n\t var clipRect = clipBox.toRect();\n\t var clipPath = Path.fromRect(clipRect);\n\t alignPathToPixel(clipPath);\n\n\t this.visual.clip(clipPath);\n\t this.unclipLabels();\n\t }\n\t },\n\n\t stackRoot: function() {\n\t return this;\n\t },\n\n\t unclipLabels: function() {\n\t var ref = this;\n\t var charts = ref.children;\n\t var clipBox = ref.clipBox;\n\n\t for (var i = 0; i < charts.length; i++) {\n\t var points = charts[i].points || {};\n\t var length = points.length;\n\n\t for (var j = 0; j < length; j++) {\n\t var point = points[j];\n\t if (point && point.visible !== false && point.overlapsBox && point.overlapsBox(clipBox)) {\n\t if (point.unclipElements) {\n\t point.unclipElements();\n\t } else {\n\t var label = point.label;\n\t var note = point.note;\n\n\t if (label && label.options.visible) {\n\t if (label.alignToClipBox) {\n\t label.alignToClipBox(clipBox);\n\t }\n\t label.options.noclip = true;\n\t }\n\n\t if (note && note.options.visible) {\n\t note.options.noclip = true;\n\t }\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t destroy: function() {\n\t ChartElement.fn.destroy.call(this);\n\n\t delete this.parent;\n\t }\n\t});\n\n\tChartContainer.prototype.isStackRoot = true;\n\n\tvar Pane = BoxElement.extend({\n\t init: function(options) {\n\t BoxElement.fn.init.call(this, options);\n\n\t this.id = paneID();\n\n\t this.createTitle();\n\n\t this.content = new ChartElement();\n\n\t this.chartContainer = new ChartContainer({}, this);\n\t this.append(this.content);\n\n\t this.axes = [];\n\t this.charts = [];\n\t },\n\n\t createTitle: function() {\n\t var titleOptions = this.options.title;\n\t if (isObject(titleOptions)) {\n\t titleOptions = deepExtend({}, titleOptions, {\n\t align: titleOptions.position,\n\t position: TOP\n\t });\n\t }\n\n\t this.title = dataviz.Title.buildTitle(titleOptions, this, Pane.prototype.options.title);\n\t },\n\n\t appendAxis: function(axis) {\n\t this.content.append(axis);\n\t this.axes.push(axis);\n\t axis.pane = this;\n\t },\n\n\t appendAxisAt: function(axis, pos) {\n\t this.content.append(axis);\n\t this.axes.splice(pos, 0, axis);\n\t axis.pane = this;\n\t },\n\n\t appendChart: function(chart) {\n\t if (this.chartContainer.parent !== this.content) {\n\t this.content.append(this.chartContainer);\n\t }\n\n\t this.charts.push(chart);\n\t this.chartContainer.append(chart);\n\t chart.pane = this;\n\t },\n\n\t empty: function() {\n\t var this$1 = this;\n\n\t var plotArea = this.parent;\n\n\t if (plotArea) {\n\t for (var i = 0; i < this.axes.length; i++) {\n\t plotArea.removeAxis(this$1.axes[i]);\n\t }\n\n\t for (var i$1 = 0; i$1 < this.charts.length; i$1++) {\n\t plotArea.removeChart(this$1.charts[i$1]);\n\t }\n\t }\n\n\t this.axes = [];\n\t this.charts = [];\n\n\t this.content.destroy();\n\t this.content.children = [];\n\t this.chartContainer.children = [];\n\t },\n\n\t reflow: function(targetBox) {\n\t // Content (such as charts) is rendered, but excluded from reflows\n\t var content;\n\t if (last(this.children) === this.content) {\n\t content = this.children.pop();\n\t }\n\n\t BoxElement.fn.reflow.call(this, targetBox);\n\n\t if (content) {\n\t this.children.push(content);\n\t }\n\n\t if (this.title) {\n\t this.contentBox.y1 += this.title.box.height();\n\t }\n\t },\n\n\t visualStyle: function() {\n\t var style = BoxElement.fn.visualStyle.call(this);\n\t style.zIndex = -10;\n\n\t return style;\n\t },\n\n\t renderComplete: function() {\n\t if (this.options.visible) {\n\t this.createGridLines();\n\t }\n\t },\n\n\t stackRoot: function() {\n\t return this;\n\t },\n\n\t clipRoot: function() {\n\t return this;\n\t },\n\n\t createGridLines: function() {\n\t var axes = this.axes;\n\t var allAxes = axes.concat(this.parent.axes);\n\t var vGridLines = [];\n\t var hGridLines = [];\n\n\t // TODO\n\t // Is full combination really necessary?\n\t for (var i = 0; i < axes.length; i++) {\n\t var axis = axes[i];\n\t var vertical = axis.options.vertical;\n\t var gridLines = vertical ? vGridLines : hGridLines;\n\t for (var j = 0; j < allAxes.length; j++) {\n\t if (gridLines.length === 0) {\n\t var altAxis = allAxes[j];\n\t if (vertical !== altAxis.options.vertical) {\n\t append(gridLines, axis.createGridLines(altAxis));\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t refresh: function() {\n\t this.visual.clear();\n\n\t this.content.parent = null;\n\t this.content.createGradient = this.createGradient.bind(this);\n\t this.content.renderVisual();\n\t this.content.parent = this;\n\n\t if (this.title) {\n\t this.visual.append(this.title.visual);\n\t }\n\n\t this.visual.append(this.content.visual);\n\n\t this.renderComplete();\n\t this.notifyRender();\n\t },\n\n\t chartsBox: function() {\n\t var axes = this.axes;\n\t var length = axes.length;\n\t var chartsBox = new Box();\n\n\t for (var idx = 0; idx < length; idx++) {\n\t var axis = axes[idx];\n\t var axisValueField = axis.options.vertical ? Y : X;\n\t var lineBox = axis.lineBox();\n\t chartsBox[axisValueField + 1] = lineBox[axisValueField + 1];\n\t chartsBox[axisValueField + 2] = lineBox[axisValueField + 2];\n\t }\n\n\t if (chartsBox.x2 === 0) {\n\t var allAxes = this.parent.axes;\n\t var length$1 = allAxes.length;\n\n\t for (var idx$1 = 0; idx$1 < length$1; idx$1++) {\n\t var axis$1 = allAxes[idx$1];\n\t if (!axis$1.options.vertical) {\n\t var lineBox$1 = axis$1.lineBox();\n\t chartsBox.x1 = lineBox$1.x1;\n\t chartsBox.x2 = lineBox$1.x2;\n\t }\n\t }\n\t }\n\t return chartsBox;\n\t },\n\n\t clipBox: function() {\n\t return this.chartContainer.clipBox;\n\t },\n\n\t notifyRender: function() {\n\t var service = this.getService();\n\t if (service) {\n\t service.notify(PANE_RENDER, {\n\t pane: new ChartPane(this),\n\t index: this.paneIndex,\n\t name: this.options.name\n\t });\n\t }\n\t }\n\t});\n\n\tvar ID = 1;\n\n\tfunction paneID() {\n\t return \"pane\" + ID++;\n\t}\n\n\tPane.prototype.isStackRoot = true;\n\n\tsetDefaultOptions(Pane, {\n\t zIndex: -1,\n\t shrinkToFit: true,\n\t title: {\n\t align: LEFT\n\t },\n\t visible: true\n\t});\n\n\tfunction appendIfNotNull(array, element) {\n\t if (element !== null) {\n\t array.push(element);\n\t }\n\t}\n\n\tfunction segmentVisible(series, fields, index) {\n\t var visible = fields.visible;\n\t if (defined(visible)) {\n\t return visible;\n\t }\n\n\t var pointVisibility = series.pointVisibility;\n\t if (pointVisibility) {\n\t return pointVisibility[index];\n\t }\n\t}\n\n\tfunction bindSegments(series) {\n\t var data = series.data;\n\t var points = [];\n\t var sum = 0;\n\t var count = 0;\n\n\t for (var idx = 0; idx < data.length; idx++) {\n\t var pointData = SeriesBinder.current.bindPoint(series, idx);\n\t var value = pointData.valueFields.value;\n\n\t if (isString(value)) {\n\t value = parseFloat(value);\n\t }\n\n\t if (isNumber(value)) {\n\t pointData.visible = segmentVisible(series, pointData.fields, idx) !== false;\n\n\t pointData.value = Math.abs(value);\n\t points.push(pointData);\n\n\t if (pointData.visible) {\n\t sum += pointData.value;\n\t }\n\n\t if (value !== 0) {\n\t count++;\n\t }\n\t } else {\n\t points.push(null);\n\t }\n\t }\n\n\t return {\n\t total: sum,\n\t points: points,\n\t count: count\n\t };\n\t}\n\n\tfunction equalsIgnoreCase(a, b) {\n\t if (a && b) {\n\t return a.toLowerCase() === b.toLowerCase();\n\t }\n\n\t return a === b;\n\t}\n\n\tfunction filterSeriesByType(series, types) {\n\t var result = [];\n\n\t var seriesTypes = [].concat(types);\n\t for (var idx = 0; idx < series.length; idx++) {\n\t var currentSeries = series[idx];\n\t if (inArray(currentSeries.type, seriesTypes)) {\n\t result.push(currentSeries);\n\t }\n\t }\n\n\t return result;\n\t}\n\n\tfunction getDateField(field, row, intlService) {\n\t if (row === null) {\n\t return row;\n\t }\n\n\t var key = \"_date_\" + field;\n\t var value = row[key];\n\n\t if (!value) {\n\t value = parseDate(intlService, getter(field, true)(row));\n\t row[key] = value;\n\t }\n\n\t return value;\n\t}\n\n\tfunction isDateAxis(axisOptions, sampleCategory) {\n\t var type = axisOptions.type;\n\t var dateCategory = sampleCategory instanceof Date;\n\n\t return (!type && dateCategory) || equalsIgnoreCase(type, DATE);\n\t}\n\n\tfunction singleItemOrArray(array) {\n\t return array.length === 1 ? array[0] : array;\n\t}\n\n\tvar AREA_REGEX = /area/i;\n\n\tfunction seriesMissingValues(series) {\n\t if (series.missingValues) {\n\t return series.missingValues;\n\t }\n\n\t return AREA_REGEX.test(series.type) || series.stack ? ZERO : INTERPOLATE;\n\t}\n\n\tfunction hasValue$1(series, item) {\n\t var fields = SeriesBinder.current.bindPoint(series, null, item);\n\t var valueFields = fields.valueFields;\n\n\t for (var field in valueFields) {\n\t if (dataviz.convertableToNumber(valueFields[field])) {\n\t return true;\n\t }\n\t }\n\t}\n\n\tfunction findNext(ref) {\n\t var start = ref.start;\n\t var dir = ref.dir;\n\t var min = ref.min;\n\t var max = ref.max;\n\t var getter$$1 = ref.getter;\n\t var hasItem = ref.hasItem;\n\t var series = ref.series;\n\n\t var pointHasValue, outPoint;\n\t var idx = start;\n\t do {\n\t idx += dir;\n\t //aggregating and binding the item takes too much time for large number of categories\n\t //will assume that if the aggregation does not create value for a missing item for one it will not create for others\n\t if (hasItem(idx)) {\n\t outPoint = getter$$1(idx);\n\t pointHasValue = hasValue$1(series, outPoint.item);\n\t }\n\t } while (min <= idx && idx <= max && !pointHasValue);\n\n\t if (pointHasValue) {\n\t return outPoint;\n\t }\n\t}\n\n\tfunction createOutOfRangePoints(series, range, count, getter$$1, hasItem) {\n\t var min = range.min;\n\t var max = range.max;\n\t var hasMinPoint = min > 0 && min < count;\n\t var hasMaxPoint = max + 1 < count;\n\n\t if (hasMinPoint || hasMaxPoint) {\n\t var missingValues = seriesMissingValues(series);\n\t var minPoint, maxPoint;\n\t if (missingValues !== INTERPOLATE) {\n\t if (hasMinPoint) {\n\t minPoint = getter$$1(min - 1);\n\t }\n\n\t if (hasMaxPoint) {\n\t maxPoint = getter$$1(max + 1);\n\t }\n\t } else {\n\t var outPoint, pointHasValue;\n\t if (hasMinPoint) {\n\t outPoint = getter$$1(min - 1);\n\t pointHasValue = hasValue$1(series, outPoint.item);\n\t if (!pointHasValue) {\n\t minPoint = findNext({\n\t start: min,\n\t dir: -1,\n\t min: 0,\n\t max: count - 1,\n\t getter: getter$$1,\n\t hasItem: hasItem,\n\t series: series\n\t });\n\t } else {\n\t minPoint = outPoint;\n\t }\n\t }\n\n\t if (hasMaxPoint) {\n\t outPoint = getter$$1(max + 1);\n\t pointHasValue = hasValue$1(series, outPoint.item);\n\t if (!pointHasValue) {\n\t maxPoint = findNext({\n\t start: max,\n\t dir: 1,\n\t min: 0,\n\t max: count - 1,\n\t getter: getter$$1,\n\t hasItem: hasItem,\n\t series: series\n\t });\n\t } else {\n\t maxPoint = outPoint;\n\t }\n\t }\n\t }\n\n\t if (minPoint) {\n\t series._outOfRangeMinPoint = minPoint;\n\t }\n\n\t if (maxPoint) {\n\t series._outOfRangeMaxPoint = maxPoint;\n\t }\n\t }\n\t}\n\n\tvar PlotAreaBase = ChartElement.extend({\n\t init: function(series, options, chartService) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.initFields(series, options);\n\t this.series = series;\n\t this.initSeries();\n\t this.charts = [];\n\t this.options.legend = this.options.legend || {};\n\t this.options.legend.items = [];\n\t this.axes = [];\n\t this.crosshairs = [];\n\t this.chartService = chartService;\n\t this.originalOptions = options;\n\n\t this.createPanes();\n\t this.render();\n\t this.createCrosshairs();\n\t },\n\n\t initFields: function() { },\n\n\t initSeries: function() {\n\t var series = this.series;\n\n\t for (var i = 0; i < series.length; i++) {\n\t series[i].index = i;\n\t }\n\t },\n\n\t createPanes: function() {\n\t var this$1 = this;\n\n\t var defaults = { title: { color: (this.options.title || {}).color } };\n\t var panes = [];\n\t var paneOptions = this.options.panes || [];\n\t var panesLength = Math.max(paneOptions.length, 1);\n\n\t function setTitle(options, defaults) {\n\t if (isString(options.title)) {\n\t options.title = {\n\t text: options.title\n\t };\n\t }\n\n\t options.title = deepExtend({}, defaults.title, options.title);\n\t }\n\n\t for (var i = 0; i < panesLength; i++) {\n\t var options = paneOptions[i] || {};\n\t setTitle(options, defaults);\n\n\t var currentPane = new Pane(options);\n\t currentPane.paneIndex = i;\n\n\t panes.push(currentPane);\n\t this$1.append(currentPane);\n\t }\n\n\t this.panes = panes;\n\t },\n\n\t createCrosshairs: function(panes) {\n\t var this$1 = this;\n\t if (panes === void 0) { panes = this.panes; }\n\n\t for (var i = 0; i < panes.length; i++) {\n\t var pane = panes[i];\n\t for (var j = 0; j < pane.axes.length; j++) {\n\t var axis = pane.axes[j];\n\t if (axis.options.crosshair && axis.options.crosshair.visible) {\n\t var currentCrosshair = new Crosshair(this$1.chartService, axis, axis.options.crosshair);\n\n\t this$1.crosshairs.push(currentCrosshair);\n\t pane.content.append(currentCrosshair);\n\t }\n\t }\n\t }\n\t },\n\n\t removeCrosshairs: function(pane) {\n\t var crosshairs = this.crosshairs;\n\t var axes = pane.axes;\n\n\t for (var i = crosshairs.length - 1; i >= 0; i--) {\n\t for (var j = 0; j < axes.length; j++) {\n\t if (crosshairs[i].axis === axes[j]) {\n\t crosshairs.splice(i, 1);\n\t break;\n\t }\n\t }\n\t }\n\t },\n\n\t hideCrosshairs: function() {\n\t var crosshairs = this.crosshairs;\n\t for (var idx = 0; idx < crosshairs.length; idx++) {\n\t crosshairs[idx].hide();\n\t }\n\t },\n\n\t findPane: function(name) {\n\t var panes = this.panes;\n\t var matchingPane;\n\n\t for (var i = 0; i < panes.length; i++) {\n\t if (panes[i].options.name === name) {\n\t matchingPane = panes[i];\n\t break;\n\t }\n\t }\n\n\t return matchingPane || panes[0];\n\t },\n\n\t findPointPane: function(point) {\n\t var panes = this.panes;\n\t var matchingPane;\n\n\t for (var i = 0; i < panes.length; i++) {\n\t if (panes[i].box.containsPoint(point)) {\n\t matchingPane = panes[i];\n\t break;\n\t }\n\t }\n\n\t return matchingPane;\n\t },\n\n\t appendAxis: function(axis) {\n\t var pane = this.findPane(axis.options.pane);\n\n\t pane.appendAxis(axis);\n\t this.axes.push(axis);\n\t axis.plotArea = this;\n\t },\n\n\t removeAxis: function(axisToRemove) {\n\t var this$1 = this;\n\n\t var filteredAxes = [];\n\n\t for (var i = 0; i < this.axes.length; i++) {\n\t var axis = this$1.axes[i];\n\t if (axisToRemove !== axis) {\n\t filteredAxes.push(axis);\n\t } else {\n\t axis.destroy();\n\t }\n\t }\n\n\t this.axes = filteredAxes;\n\t },\n\n\t appendChart: function(chart, pane) {\n\t this.charts.push(chart);\n\t if (pane) {\n\t pane.appendChart(chart);\n\t } else {\n\t this.append(chart);\n\t }\n\t },\n\n\t removeChart: function(chartToRemove) {\n\t var this$1 = this;\n\n\t var filteredCharts = [];\n\n\t for (var i = 0; i < this.charts.length; i++) {\n\t var chart = this$1.charts[i];\n\t if (chart !== chartToRemove) {\n\t filteredCharts.push(chart);\n\t } else {\n\t chart.destroy();\n\t }\n\t }\n\n\t this.charts = filteredCharts;\n\t },\n\n\t addToLegend: function(series) {\n\t var count = series.length;\n\t var legend = this.options.legend;\n\t var labels = legend.labels || {};\n\t var inactiveItems = legend.inactiveItems || {};\n\t var inactiveItemsLabels = inactiveItems.labels || {};\n\t var data = [];\n\n\t for (var i = 0; i < count; i++) {\n\t var currentSeries = series[i];\n\t var seriesVisible = currentSeries.visible !== false;\n\t if (currentSeries.visibleInLegend === false) {\n\t continue;\n\t }\n\n\t var text = currentSeries.name;\n\t var labelTemplate = seriesVisible ? getTemplate(labels) : getTemplate(inactiveItemsLabels) || getTemplate(labels);\n\t if (labelTemplate) {\n\t text = labelTemplate({\n\t text: hasValue(text) ? text : \"\",\n\t series: currentSeries\n\t });\n\t }\n\n\t var defaults = currentSeries._defaults;\n\t var color = currentSeries.color;\n\t if (isFunction(color) && defaults) {\n\t color = defaults.color;\n\t }\n\n\t var itemLabelOptions = (void 0), markerColor = (void 0);\n\t if (seriesVisible) {\n\t itemLabelOptions = {};\n\t markerColor = color;\n\t } else {\n\t itemLabelOptions = {\n\t color: inactiveItemsLabels.color,\n\t font: inactiveItemsLabels.font\n\t };\n\t markerColor = inactiveItems.markers.color;\n\t }\n\n\t if (hasValue(text) && text !== \"\") {\n\t data.push({\n\t text: text,\n\t labels: itemLabelOptions,\n\t markerColor: markerColor,\n\t series: currentSeries,\n\t active: seriesVisible\n\t });\n\t }\n\t }\n\n\t append(legend.items, data);\n\t },\n\n\t groupAxes: function(panes) {\n\t var xAxes = [];\n\t var yAxes = [];\n\n\t for (var paneIx = 0; paneIx < panes.length; paneIx++) {\n\t var paneAxes = panes[paneIx].axes;\n\t for (var axisIx = 0; axisIx < paneAxes.length; axisIx++) {\n\t var axis = paneAxes[axisIx];\n\t if (axis.options.vertical) {\n\t yAxes.push(axis);\n\t } else {\n\t xAxes.push(axis);\n\t }\n\t }\n\t }\n\n\t return { x: xAxes, y: yAxes, any: xAxes.concat(yAxes) };\n\t },\n\n\t groupSeriesByPane: function() {\n\t var this$1 = this;\n\n\t var series = this.series;\n\t var seriesByPane = {};\n\n\t for (var i = 0; i < series.length; i++) {\n\t var currentSeries = series[i];\n\t var pane = this$1.seriesPaneName(currentSeries);\n\n\t if (seriesByPane[pane]) {\n\t seriesByPane[pane].push(currentSeries);\n\t } else {\n\t seriesByPane[pane] = [ currentSeries ];\n\t }\n\t }\n\n\t return seriesByPane;\n\t },\n\n\t filterVisibleSeries: function(series) {\n\t var result = [];\n\n\t for (var i = 0; i < series.length; i++) {\n\t var currentSeries = series[i];\n\t if (currentSeries.visible !== false) {\n\t result.push(currentSeries);\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t reflow: function(targetBox) {\n\t var options = this.options.plotArea;\n\t var panes = this.panes;\n\t var margin = getSpacing(options.margin);\n\n\t this.box = targetBox.clone().unpad(margin);\n\t this.reflowPanes();\n\n\t this.detachLabels();\n\t this.reflowAxes(panes);\n\t this.reflowCharts(panes);\n\t },\n\n\t redraw: function(panes) {\n\t var this$1 = this;\n\n\t var panesArray = [].concat(panes);\n\t this.initSeries();\n\n\t //prevents leak during partial redraws. the cached gradients observers retain reference to the destroyed elements.\n\t var root = this.getRoot();\n\t if (root) {\n\t root.cleanGradients();\n\t }\n\n\t for (var i = 0; i < panesArray.length; i++) {\n\t this$1.removeCrosshairs(panesArray[i]);\n\t panesArray[i].empty();\n\t }\n\n\t this.render(panesArray);\n\t this.detachLabels();\n\t this.reflowAxes(this.panes);\n\t this.reflowCharts(panesArray);\n\n\t this.createCrosshairs(panesArray);\n\n\t for (var i$1 = 0; i$1 < panesArray.length; i$1++) {\n\t panesArray[i$1].refresh();\n\t }\n\t },\n\n\t axisCrossingValues: function(axis, crossingAxes) {\n\t var options = axis.options;\n\t var crossingValues = [].concat(\n\t options.axisCrossingValues || options.axisCrossingValue\n\t );\n\t var valuesToAdd = crossingAxes.length - crossingValues.length;\n\t var defaultValue = crossingValues[0] || 0;\n\n\t for (var i = 0; i < valuesToAdd; i++) {\n\t crossingValues.push(defaultValue);\n\t }\n\n\t return crossingValues;\n\t },\n\n\t alignAxisTo: function(axis, targetAxis, crossingValue, targetCrossingValue) {\n\t var slot = axis.getSlot(crossingValue, crossingValue, true);\n\t var slotEdge = axis.options.reverse ? 2 : 1;\n\t var targetSlot = targetAxis.getSlot(targetCrossingValue, targetCrossingValue, true);\n\t var targetEdge = targetAxis.options.reverse ? 2 : 1;\n\t var axisBox = axis.box.translate(\n\t targetSlot[X + targetEdge] - slot[X + slotEdge],\n\t targetSlot[Y + targetEdge] - slot[Y + slotEdge]\n\t );\n\n\t if (axis.pane !== targetAxis.pane) {\n\t axisBox.translate(0, axis.pane.box.y1 - targetAxis.pane.box.y1);\n\t }\n\n\t axis.reflow(axisBox);\n\t },\n\n\t alignAxes: function(xAxes, yAxes) {\n\t var this$1 = this;\n\n\t var xAnchor = xAxes[0];\n\t var yAnchor = yAxes[0];\n\t var xAnchorCrossings = this.axisCrossingValues(xAnchor, yAxes);\n\t var yAnchorCrossings = this.axisCrossingValues(yAnchor, xAxes);\n\t var leftAnchors = {};\n\t var rightAnchors = {};\n\t var topAnchors = {};\n\t var bottomAnchors = {};\n\n\t for (var i = 0; i < yAxes.length; i++) {\n\t var axis = yAxes[i];\n\t var pane = axis.pane;\n\t var paneId = pane.id;\n\t var visible = axis.options.visible !== false;\n\n\t // Locate pane anchor, if any, and use its axisCrossingValues\n\t var anchor = paneAnchor(xAxes, pane) || xAnchor;\n\t var anchorCrossings = xAnchorCrossings;\n\n\t if (anchor !== xAnchor) {\n\t anchorCrossings = this$1.axisCrossingValues(anchor, yAxes);\n\t }\n\n\t this$1.alignAxisTo(axis, anchor, yAnchorCrossings[i], anchorCrossings[i]);\n\n\t if (axis.options._overlap) {\n\t continue;\n\t }\n\n\t if (round(axis.lineBox().x1) === round(anchor.lineBox().x1)) {\n\t // Push the axis to the left the previous y-axis so they don't overlap\n\t if (leftAnchors[paneId]) {\n\t axis.reflow(axis.box\n\t .alignTo(leftAnchors[paneId].box, LEFT)\n\t .translate(-axis.options.margin, 0)\n\t );\n\t }\n\n\t if (visible) {\n\t leftAnchors[paneId] = axis;\n\t }\n\t }\n\n\t if (round(axis.lineBox().x2) === round(anchor.lineBox().x2)) {\n\t // Flip the labels on the right if we're at the right end of the pane\n\t if (!axis._mirrored) {\n\t axis.options.labels.mirror = !axis.options.labels.mirror;\n\t axis._mirrored = true;\n\t }\n\n\t this$1.alignAxisTo(axis, anchor, yAnchorCrossings[i], anchorCrossings[i]);\n\n\t // Push the axis to the right the previous y-axis so they don't overlap\n\t if (rightAnchors[paneId]) {\n\t axis.reflow(axis.box\n\t .alignTo(rightAnchors[paneId].box, RIGHT)\n\t .translate(axis.options.margin, 0)\n\t );\n\t }\n\n\t if (visible) {\n\t rightAnchors[paneId] = axis;\n\t }\n\t }\n\n\t if (i !== 0 && yAnchor.pane === axis.pane) {\n\t axis.alignTo(yAnchor);\n\t axis.reflow(axis.box);\n\t }\n\t }\n\n\t for (var i$1 = 0; i$1 < xAxes.length; i$1++) {\n\t var axis$1 = xAxes[i$1];\n\t var pane$1 = axis$1.pane;\n\t var paneId$1 = pane$1.id;\n\t var visible$1 = axis$1.options.visible !== false;\n\n\t // Locate pane anchor and use its axisCrossingValues\n\t var anchor$1 = paneAnchor(yAxes, pane$1) || yAnchor;\n\t var anchorCrossings$1 = yAnchorCrossings;\n\t if (anchor$1 !== yAnchor) {\n\t anchorCrossings$1 = this$1.axisCrossingValues(anchor$1, xAxes);\n\t }\n\n\t this$1.alignAxisTo(axis$1, anchor$1, xAnchorCrossings[i$1], anchorCrossings$1[i$1]);\n\n\t if (axis$1.options._overlap) {\n\t continue;\n\t }\n\n\t if (round(axis$1.lineBox().y1) === round(anchor$1.lineBox().y1)) {\n\t // Flip the labels on top if we're at the top of the pane\n\t if (!axis$1._mirrored) {\n\t axis$1.options.labels.mirror = !axis$1.options.labels.mirror;\n\t axis$1._mirrored = true;\n\t }\n\t this$1.alignAxisTo(axis$1, anchor$1, xAnchorCrossings[i$1], anchorCrossings$1[i$1]);\n\n\t // Push the axis above the previous x-axis so they don't overlap\n\t if (topAnchors[paneId$1]) {\n\t axis$1.reflow(axis$1.box\n\t .alignTo(topAnchors[paneId$1].box, TOP)\n\t .translate(0, -axis$1.options.margin)\n\t );\n\t }\n\n\t if (visible$1) {\n\t topAnchors[paneId$1] = axis$1;\n\t }\n\t }\n\n\t if (round(axis$1.lineBox().y2, datavizConstants.COORD_PRECISION) === round(anchor$1.lineBox().y2, datavizConstants.COORD_PRECISION)) {\n\t // Push the axis below the previous x-axis so they don't overlap\n\t if (bottomAnchors[paneId$1]) {\n\t axis$1.reflow(axis$1.box\n\t .alignTo(bottomAnchors[paneId$1].box, BOTTOM)\n\t .translate(0, axis$1.options.margin)\n\t );\n\t }\n\n\t if (visible$1) {\n\t bottomAnchors[paneId$1] = axis$1;\n\t }\n\t }\n\n\t if (i$1 !== 0) {\n\t axis$1.alignTo(xAnchor);\n\t axis$1.reflow(axis$1.box);\n\t }\n\t }\n\t },\n\n\t shrinkAxisWidth: function(panes) {\n\t var axes = this.groupAxes(panes).any;\n\t var axisBox = axisGroupBox(axes);\n\t var overflowX = 0;\n\n\t for (var i = 0; i < panes.length; i++) {\n\t var currentPane = panes[i];\n\n\t if (currentPane.axes.length > 0) {\n\t overflowX = Math.max(\n\t overflowX,\n\t axisBox.width() - currentPane.contentBox.width()\n\t );\n\t }\n\t }\n\n\t if (overflowX !== 0) {\n\t for (var i$1 = 0; i$1 < axes.length; i$1++) {\n\t var currentAxis = axes[i$1];\n\n\t if (!currentAxis.options.vertical) {\n\t currentAxis.reflow(currentAxis.box.shrink(overflowX, 0));\n\t }\n\t }\n\t }\n\t },\n\n\t shrinkAxisHeight: function(panes) {\n\t var shrinked;\n\n\t for (var i = 0; i < panes.length; i++) {\n\t var currentPane = panes[i];\n\t var axes = currentPane.axes;\n\t var overflowY = Math.max(0, axisGroupBox(axes).height() - currentPane.contentBox.height());\n\n\t if (overflowY !== 0) {\n\t for (var j = 0; j < axes.length; j++) {\n\t var currentAxis = axes[j];\n\n\t if (currentAxis.options.vertical) {\n\t currentAxis.reflow(\n\t currentAxis.box.shrink(0, overflowY)\n\t );\n\t }\n\t }\n\t shrinked = true;\n\t }\n\t }\n\n\t return shrinked;\n\t },\n\n\t fitAxes: function(panes) {\n\t var axes = this.groupAxes(panes).any;\n\t var offsetX = 0;\n\n\t for (var i = 0; i < panes.length; i++) {\n\t var currentPane = panes[i];\n\t var paneAxes = currentPane.axes;\n\t var paneBox = currentPane.contentBox;\n\n\t if (paneAxes.length > 0) {\n\t var axisBox = axisGroupBox(paneAxes);\n\t // OffsetY is calculated and applied per pane\n\t var offsetY = Math.max(paneBox.y1 - axisBox.y1, paneBox.y2 - axisBox.y2);\n\n\t // OffsetX is calculated and applied globally\n\t offsetX = Math.max(offsetX, paneBox.x1 - axisBox.x1);\n\n\t for (var j = 0; j < paneAxes.length; j++) {\n\t var currentAxis = paneAxes[j];\n\n\t currentAxis.reflow(\n\t currentAxis.box.translate(0, offsetY)\n\t );\n\t }\n\t }\n\t }\n\n\t for (var i$1 = 0; i$1 < axes.length; i$1++) {\n\t var currentAxis$1 = axes[i$1];\n\n\t currentAxis$1.reflow(\n\t currentAxis$1.box.translate(offsetX, 0)\n\t );\n\t }\n\t },\n\n\t reflowAxes: function(panes) {\n\t var this$1 = this;\n\n\t var axes = this.groupAxes(panes);\n\n\t for (var i = 0; i < panes.length; i++) {\n\t this$1.reflowPaneAxes(panes[i]);\n\t }\n\n\t if (axes.x.length > 0 && axes.y.length > 0) {\n\t this.alignAxes(axes.x, axes.y);\n\t this.shrinkAxisWidth(panes);\n\n\t this.autoRotateAxisLabels(axes);\n\n\t this.alignAxes(axes.x, axes.y);\n\t if (this.shrinkAxisWidth(panes)) {\n\t this.alignAxes(axes.x, axes.y);\n\t }\n\n\t this.shrinkAxisHeight(panes);\n\t this.alignAxes(axes.x, axes.y);\n\n\t if (this.shrinkAxisHeight(panes)) {\n\t this.alignAxes(axes.x, axes.y);\n\t }\n\n\t this.fitAxes(panes);\n\t }\n\t },\n\n\t autoRotateAxisLabels: function(groupedAxes) {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var panes = ref.panes;\n\t var axes = allPaneAxes(panes);\n\t var rotated;\n\n\t for (var idx = 0; idx < axes.length; idx++) {\n\t var axis = axes[idx];\n\t if (axis.autoRotateLabels()) {\n\t rotated = true;\n\t }\n\t }\n\n\t if (rotated) {\n\t for (var idx$1 = 0; idx$1 < panes.length; idx$1++) {\n\t this$1.reflowPaneAxes(panes[idx$1]);\n\t }\n\n\t if (groupedAxes.x.length > 0 && groupedAxes.y.length > 0) {\n\t this.alignAxes(groupedAxes.x, groupedAxes.y);\n\t this.shrinkAxisWidth(panes);\n\t }\n\t }\n\t },\n\n\t reflowPaneAxes: function(pane) {\n\t var axes = pane.axes;\n\t var length = axes.length;\n\n\t if (length > 0) {\n\t for (var i = 0; i < length; i++) {\n\t axes[i].reflow(pane.contentBox);\n\t }\n\t }\n\t },\n\n\t reflowCharts: function(panes) {\n\t var charts = this.charts;\n\t var count = charts.length;\n\t var box = this.box;\n\n\t for (var i = 0; i < count; i++) {\n\t var chartPane = charts[i].pane;\n\t if (!chartPane || inArray(chartPane, panes)) {\n\t charts[i].reflow(box);\n\t }\n\t }\n\t },\n\n\t reflowPanes: function() {\n\t var ref = this;\n\t var box = ref.box;\n\t var panes = ref.panes;\n\t var panesLength = panes.length;\n\t var remainingHeight = box.height();\n\t var remainingPanes = panesLength;\n\t var autoHeightPanes = 0;\n\t var top = box.y1;\n\n\t for (var i = 0; i < panesLength; i++) {\n\t var currentPane = panes[i];\n\t var height = currentPane.options.height;\n\n\t currentPane.options.width = box.width();\n\n\t if (!currentPane.options.height) {\n\t autoHeightPanes++;\n\t } else {\n\t if (height.indexOf && height.indexOf(\"%\")) {\n\t var percents = parseInt(height, 10) / 100;\n\t currentPane.options.height = percents * box.height();\n\t }\n\n\t currentPane.reflow(box.clone());\n\n\t remainingHeight -= currentPane.options.height;\n\t }\n\t }\n\n\t for (var i$1 = 0; i$1 < panesLength; i$1++) {\n\t var currentPane$1 = panes[i$1];\n\n\t if (!currentPane$1.options.height) {\n\t currentPane$1.options.height = remainingHeight / autoHeightPanes;\n\t }\n\t }\n\n\t for (var i$2 = 0; i$2 < panesLength; i$2++) {\n\t var currentPane$2 = panes[i$2];\n\t var paneBox = box\n\t .clone()\n\t .move(box.x1, top);\n\n\t currentPane$2.reflow(paneBox);\n\n\t remainingPanes--;\n\t top += currentPane$2.options.height;\n\t }\n\t },\n\n\t backgroundBox: function() {\n\t var axes = this.axes;\n\t var axesCount = axes.length;\n\t var box;\n\n\t for (var i = 0; i < axesCount; i++) {\n\t var axisA = axes[i];\n\n\t for (var j = 0; j < axesCount; j++) {\n\t var axisB = axes[j];\n\n\t if (axisA.options.vertical !== axisB.options.vertical) {\n\t var lineBox = axisA.lineBox().clone().wrap(axisB.lineBox());\n\n\t if (!box) {\n\t box = lineBox;\n\t } else {\n\t box = box.wrap(lineBox);\n\t }\n\t }\n\t }\n\t }\n\n\t return box || this.box;\n\t },\n\n\t chartsBoxes: function() {\n\t var panes = this.panes;\n\t var boxes = [];\n\n\t for (var idx = 0; idx < panes.length; idx++) {\n\t boxes.push(panes[idx].chartsBox());\n\t }\n\n\t return boxes;\n\t },\n\n\t addBackgroundPaths: function(multipath) {\n\t var boxes = this.chartsBoxes();\n\t for (var idx = 0; idx < boxes.length; idx++) {\n\t multipath.paths.push(Path.fromRect(boxes[idx].toRect()));\n\t }\n\t },\n\n\t backgroundContainsPoint: function(point) {\n\t var boxes = this.chartsBoxes();\n\t for (var idx = 0; idx < boxes.length; idx++) {\n\t if (boxes[idx].containsPoint(point)) {\n\t return true;\n\t }\n\t }\n\t },\n\n\t createVisual: function() {\n\t ChartElement.fn.createVisual.call(this);\n\n\t var options = this.options.plotArea;\n\t var opacity = options.opacity;\n\t var background = options.background;\n\t var border = options.border; if (border === void 0) { border = {}; }\n\t if (isTransparent(background)) {\n\t background = WHITE;\n\t opacity = 0;\n\t }\n\n\t var bg = this._bgVisual = new drawing.MultiPath({\n\t fill: {\n\t color: background,\n\t opacity: opacity\n\t },\n\t stroke: {\n\t color: border.width ? border.color : \"\",\n\t width: border.width,\n\t dashType: border.dashType\n\t },\n\t zIndex: -1\n\t });\n\n\t this.addBackgroundPaths(bg);\n\n\t this.appendVisual(bg);\n\t },\n\n\t pointsByCategoryIndex: function(categoryIndex) {\n\t var charts = this.charts;\n\t var result = [];\n\n\t if (categoryIndex !== null) {\n\t for (var i = 0; i < charts.length; i++) {\n\t var chart = charts[i];\n\t if (chart.pane.options.name === \"_navigator\") {\n\t continue;\n\t }\n\n\t var points = charts[i].categoryPoints[categoryIndex];\n\t if (points && points.length) {\n\t for (var j = 0; j < points.length; j++) {\n\t var point = points[j];\n\t if (point && defined(point.value) && point.value !== null) {\n\t result.push(point);\n\t }\n\t }\n\t }\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t pointsBySeriesIndex: function(seriesIndex) {\n\t return this.filterPoints(function(point) {\n\t return point.series.index === seriesIndex;\n\t });\n\t },\n\n\t pointsBySeriesName: function(name) {\n\t return this.filterPoints(function(point) {\n\t return point.series.name === name;\n\t });\n\t },\n\n\t filterPoints: function(callback) {\n\t var charts = this.charts;\n\t var result = [];\n\n\t for (var i = 0; i < charts.length; i++) {\n\t var chart = charts[i];\n\t var points = chart.points;\n\t for (var j = 0; j < points.length; j++) {\n\t var point = points[j];\n\t if (point && point.visible !== false && callback(point)) {\n\t result.push(point);\n\t }\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t findPoint: function(callback) {\n\t var charts = this.charts;\n\n\t for (var i = 0; i < charts.length; i++) {\n\t var chart = charts[i];\n\t var points = chart.points;\n\t for (var j = 0; j < points.length; j++) {\n\t var point = points[j];\n\t if (point && point.visible !== false && callback(point)) {\n\t return point;\n\t }\n\t }\n\t }\n\t },\n\n\t paneByPoint: function(point) {\n\t var panes = this.panes;\n\n\t for (var i = 0; i < panes.length; i++) {\n\t var pane = panes[i];\n\t if (pane.box.containsPoint(point)) {\n\t return pane;\n\t }\n\t }\n\t },\n\n\t detachLabels: function() {\n\t var axes = this.groupAxes(this.panes);\n\t var xAxes = axes.x;\n\t var yAxes = axes.y;\n\n\t this.detachAxisGroupLabels(yAxes, xAxes);\n\t this.detachAxisGroupLabels(xAxes, yAxes);\n\t },\n\n\t detachAxisGroupLabels: function(axes, crossingAxes) {\n\t var this$1 = this;\n\n\t var labelAxisCount = 0;\n\n\t for (var i = 0; i < axes.length; i++) {\n\t var axis = axes[i];\n\t var pane = axis.pane;\n\t var anchor = paneAnchor(crossingAxes, pane) || crossingAxes[0];\n\t var axisIndex = i + labelAxisCount;\n\t var labelAxis = this$1.createLabelAxis(axis, axisIndex, anchor);\n\n\t if (labelAxis) {\n\t labelAxisCount++;\n\n\t var pos = pane.axes.indexOf(axis) + labelAxisCount;\n\t pane.appendAxisAt(labelAxis, pos);\n\t }\n\t }\n\t },\n\n\t createLabelAxis: function(axis, axisIndex, anchor) {\n\t var labelOptions = axis.options.labels;\n\t var position = labelOptions.position;\n\t var onAxis = position !== datavizConstants.END && position !== datavizConstants.START;\n\t var visible = labelOptions.visible;\n\n\t if (onAxis || visible === false) {\n\t return null;\n\t }\n\n\t var allAxes = this.groupAxes(this.panes);\n\t var crossingAxes = anchor.options.vertical ? allAxes.x : allAxes.y;\n\t var anchorCrossings = this.axisCrossingValues(anchor, crossingAxes);\n\t var end = position === datavizConstants.END;\n\t var range = anchor.range();\n\t var edge = end ? range.max : range.min;\n\t var crossingValue = limitValue(anchorCrossings[axisIndex], range.min, range.max);\n\n\t if (crossingValue - edge === 0) {\n\t return null;\n\t }\n\n\t anchorCrossings.splice(axisIndex + 1, 0, edge);\n\t anchor.options.axisCrossingValues = anchorCrossings;\n\n\t var labelAxis = axis.clone();\n\t axis.clear();\n\n\t labelAxis.options.name = undefined;\n\t labelAxis.options.line.visible = false;\n\n\t labelAxis.options.crosshair = undefined;\n\t labelAxis.options.notes = undefined;\n\t labelAxis.options.plotBands = undefined;\n\n\t return labelAxis;\n\t }\n\t});\n\n\tfunction isSingleAxis(axis) {\n\t return !axis.pane.axes.some(function (a) { return a.options.vertical === axis.options.vertical && a !== axis && a.options.visible !== false; }\n\t );\n\t}\n\n\tfunction axisGroupBox(axes) {\n\t var length = axes.length;\n\t var box;\n\n\t for (var i = 0; i < length; i++) {\n\t var axis = axes[i];\n\t var visible = axis.options.visible !== false;\n\t if (visible || isSingleAxis(axis)) {\n\t var axisBox = visible ? axis.contentBox() : axis.lineBox();\n\n\t if (!box) {\n\t box = axisBox.clone();\n\t } else {\n\t box.wrap(axisBox);\n\t }\n\t }\n\t }\n\n\t return box || new Box();\n\t}\n\n\tfunction paneAnchor(axes, pane) {\n\t for (var i = 0; i < axes.length; i++) {\n\t var anchor = axes[i];\n\t if (anchor && anchor.pane === pane) {\n\t return anchor;\n\t }\n\t }\n\t}\n\n\tfunction isTransparent(color) {\n\t return color === \"\" || color === null || color === \"none\" || color === \"transparent\" || !defined(color);\n\t}\n\n\tvar allPaneAxes = function (panes) { return panes.reduce(function (acc, pane) { return acc.concat(pane.axes); }, []); };\n\n\tsetDefaultOptions(PlotAreaBase, {\n\t series: [],\n\t plotArea: {\n\t margin: {}\n\t },\n\t background: \"\",\n\t border: {\n\t color: BLACK,\n\t width: 0\n\t },\n\t legend: {\n\t inactiveItems: {\n\t labels: {\n\t color: \"#919191\"\n\t },\n\t markers: {\n\t color: \"#919191\"\n\t }\n\t }\n\t }\n\t});\n\n\tvar PlotAreaEventsMixin = {\n\t hover: function(chart, e) {\n\t this._dispatchEvent(chart, e, PLOT_AREA_HOVER);\n\t },\n\n\t click: function(chart, e) {\n\t this._dispatchEvent(chart, e, PLOT_AREA_CLICK);\n\t }\n\t};\n\n\tvar SeriesAggregator = Class.extend({\n\t init: function(series, binder, defaultAggregates) {\n\n\t var canonicalFields = binder.canonicalFields(series);\n\t var valueFields = binder.valueFields(series);\n\t var sourceFields = binder.sourceFields(series, canonicalFields);\n\t var seriesFields = this._seriesFields = [];\n\t var defaults = defaultAggregates.query(series.type);\n\t var rootAggregate = series.aggregate || defaults;\n\n\t this._series = series;\n\t this._binder = binder;\n\n\t for (var i = 0; i < canonicalFields.length; i++) {\n\t var field = canonicalFields[i];\n\t var fieldAggregate = (void 0);\n\n\t if (isObject(rootAggregate)) {\n\t fieldAggregate = rootAggregate[field];\n\t } else if (i === 0 || inArray(field, valueFields)) {\n\t fieldAggregate = rootAggregate;\n\t } else {\n\t break;\n\t }\n\n\t if (fieldAggregate) {\n\t seriesFields.push({\n\t canonicalName: field,\n\t name: sourceFields[i],\n\t transform: isFunction(fieldAggregate) ? fieldAggregate : Aggregates[fieldAggregate]\n\t });\n\t }\n\t }\n\t },\n\n\t aggregatePoints: function(srcPoints, group) {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var series = ref._series;\n\t var seriesFields = ref._seriesFields;\n\t var data = this._bindPoints(srcPoints || []);\n\t var firstDataItem = data.dataItems[0];\n\t var result = {};\n\n\t if (firstDataItem && !isNumber(firstDataItem) && !isArray(firstDataItem)) {\n\t var fn = function() {};\n\t fn.prototype = firstDataItem;\n\t result = new fn();\n\t }\n\n\t for (var i = 0; i < seriesFields.length; i++) {\n\t var field = seriesFields[i];\n\t var srcValues = this$1._bindField(data.values, field.canonicalName);\n\t var value = field.transform(srcValues, series, data.dataItems, group);\n\n\t if (value !== null && isObject(value) && !defined(value.length) && !(value instanceof Date)) {\n\t result = value;\n\t break;\n\t } else {\n\t if (defined(value)) {\n\t setValue(field.name, result, value);\n\t }\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t _bindPoints: function(points) {\n\t var ref = this;\n\t var binder = ref._binder;\n\t var series = ref._series;\n\t var values = [];\n\t var dataItems = [];\n\n\t for (var i = 0; i < points.length; i++) {\n\t var pointIx = points[i];\n\n\t values.push(binder.bindPoint(series, pointIx));\n\t dataItems.push(series.data[pointIx]);\n\t }\n\n\t return {\n\t values: values,\n\t dataItems: dataItems\n\t };\n\t },\n\n\t _bindField: function(data, field) {\n\t var values = [];\n\t var count = data.length;\n\n\t for (var i = 0; i < count; i++) {\n\t var item = data[i];\n\t var valueFields = item.valueFields;\n\t var value = (void 0);\n\n\t if (defined(valueFields[field])) {\n\t value = valueFields[field];\n\t } else {\n\t value = item.fields[field];\n\t }\n\n\t values.push(value);\n\t }\n\n\t return values;\n\t }\n\t});\n\n\tfunction setValue(fieldName, target, value) {\n\t var parentObj = target;\n\t var field = fieldName;\n\n\t if (fieldName.indexOf(\".\") > -1) {\n\t var parts = fieldName.split(\".\");\n\n\t while (parts.length > 1) {\n\t field = parts.shift();\n\t if (!defined(parentObj[field])) {\n\t parentObj[field] = {};\n\t }\n\t parentObj = parentObj[field];\n\t }\n\t field = parts.shift();\n\t }\n\n\t parentObj[field] = value;\n\t}\n\n\tvar DefaultAggregates = Class.extend({\n\t init: function() {\n\n\t this._defaults = {};\n\t },\n\n\t register: function(seriesTypes, aggregates) {\n\t var this$1 = this;\n\n\t for (var i = 0; i < seriesTypes.length; i++) {\n\t this$1._defaults[seriesTypes[i]] = aggregates;\n\t }\n\t },\n\n\t query: function(seriesType) {\n\t return this._defaults[seriesType];\n\t }\n\t});\n\n\tDefaultAggregates.current = new DefaultAggregates();\n\n\tvar RangeBar = Bar.extend({\n\t createLabel: function() {\n\t var labels = this.options.labels;\n\t var fromOptions = deepExtend({}, labels, labels.from);\n\t var toOptions = deepExtend({}, labels, labels.to);\n\n\t if (fromOptions.visible) {\n\t this.labelFrom = this._createLabel(fromOptions);\n\t this.append(this.labelFrom);\n\t }\n\n\t if (toOptions.visible) {\n\t this.labelTo = this._createLabel(toOptions);\n\t this.append(this.labelTo);\n\t }\n\t },\n\n\t _createLabel: function(options) {\n\t var labelTemplate = getTemplate(options);\n\t var pointData = this.pointData();\n\n\t var labelText;\n\n\t if (labelTemplate) {\n\t labelText = labelTemplate(pointData);\n\t } else {\n\t labelText = this.formatValue(options.format);\n\t }\n\n\t return new BarLabel(labelText,\n\t deepExtend({\n\t vertical: this.options.vertical\n\t },\n\t options\n\t ), pointData);\n\t },\n\n\t reflow: function(targetBox) {\n\t this.render();\n\n\t var ref = this;\n\t var labelFrom = ref.labelFrom;\n\t var labelTo = ref.labelTo;\n\t var value = ref.value;\n\n\t this.box = targetBox;\n\n\t if (labelFrom) {\n\t labelFrom.options.aboveAxis = value.from > value.to;\n\t labelFrom.reflow(targetBox);\n\t }\n\n\t if (labelTo) {\n\t labelTo.options.aboveAxis = value.to > value.from;\n\t labelTo.reflow(targetBox);\n\t }\n\n\t if (this.note) {\n\t this.note.reflow(targetBox);\n\t }\n\t }\n\t});\n\n\tRangeBar.prototype.defaults = deepExtend({}, RangeBar.prototype.defaults, {\n\t labels: {\n\t format: \"{0} - {1}\"\n\t },\n\t tooltip: {\n\t format: \"{1}\"\n\t }\n\t});\n\n\tvar RangeBarChart = BarChart.extend({\n\t pointType: function() {\n\t return RangeBar;\n\t },\n\n\t pointValue: function(data) {\n\t return data.valueFields;\n\t },\n\n\t formatPointValue: function(point, format) {\n\t if (point.value.from === null && point.value.to === null) {\n\t return \"\";\n\t }\n\n\t return this.chartService.format.auto(format, point.value.from, point.value.to);\n\t },\n\n\t plotRange: function(point) {\n\t if (!point) {\n\t return 0;\n\t }\n\n\t return [ point.value.from, point.value.to ];\n\t },\n\n\t updateRange: function(value, fields) {\n\t var axisName = fields.series.axis;\n\t var from = value.from;\n\t var to = value.to;\n\t var axisRange = this.valueAxisRanges[axisName];\n\n\t if (value !== null && isNumber(from) && isNumber(to)) {\n\t axisRange = this.valueAxisRanges[axisName] = axisRange || { min: MAX_VALUE, max: MIN_VALUE };\n\n\t axisRange.min = Math.min(axisRange.min, from);\n\t axisRange.max = Math.max(axisRange.max, from);\n\n\t axisRange.min = Math.min(axisRange.min, to);\n\t axisRange.max = Math.max(axisRange.max, to);\n\t }\n\t },\n\n\t aboveAxis: function(point) {\n\t var value = point.value;\n\t return value.from < value.to;\n\t }\n\t});\n\n\tRangeBarChart.prototype.plotLimits = CategoricalChart.prototype.plotLimits;\n\n\tvar RangeLinePoint = LinePoint.extend({\n\t aliasFor: function() {\n\t return this.parent;\n\t }\n\t});\n\n\tvar AUTO = 'auto';\n\tvar DEFAULT_FROM_FORMAT = '{0}';\n\tvar DEFAULT_TO_FORMAT = '{1}';\n\n\tvar RangeAreaPoint = ChartElement.extend({\n\t init: function(value, options) {\n\t ChartElement.fn.init.call(this);\n\n\t this.value = value;\n\t this.options = options;\n\t this.aboveAxis = valueOrDefault(this.options.aboveAxis, true);\n\t this.tooltipTracking = true;\n\t this.initLabelsFormat();\n\t },\n\n\t render: function() {\n\t if (this._rendered) {\n\t return;\n\t }\n\n\t this._rendered = true;\n\n\t var ref = this.options;\n\t var markers = ref.markers;\n\t var labels = ref.labels;\n\t var value = this.value;\n\n\t var fromPoint = this.fromPoint = new RangeLinePoint(value, deepExtend({}, this.options, {\n\t labels: labels.from,\n\t markers: markers.from\n\t }));\n\n\t var toPoint = this.toPoint = new RangeLinePoint(value, deepExtend({}, this.options, {\n\t labels: labels.to,\n\t markers: markers.to\n\t }));\n\n\t this.copyFields(fromPoint);\n\t this.copyFields(toPoint);\n\n\t this.append(fromPoint);\n\t this.append(toPoint);\n\t },\n\n\t reflow: function(targetBox) {\n\t this.render();\n\n\t var fromBox = targetBox.from;\n\t var toBox = targetBox.to;\n\n\t this.positionLabels(fromBox, toBox);\n\n\t this.fromPoint.reflow(fromBox);\n\t this.toPoint.reflow(toBox);\n\n\t this.box = this.fromPoint.markerBox().clone().wrap(this.toPoint.markerBox());\n\t },\n\n\t createHighlight: function() {\n\t var group = new Group();\n\t group.append(this.fromPoint.createHighlight());\n\t group.append(this.toPoint.createHighlight());\n\n\t return group;\n\t },\n\n\t highlightVisual: function() {\n\t return this.visual;\n\t },\n\n\t highlightVisualArgs: function() {\n\t return {\n\t options: this.options,\n\t from: this.fromPoint.highlightVisualArgs(),\n\t to: this.toPoint.highlightVisualArgs()\n\t };\n\t },\n\n\t tooltipAnchor: function() {\n\t var clipBox = this.owner.pane.clipBox();\n\t var showTooltip = !clipBox || clipBox.overlaps(this.box);\n\n\t if (showTooltip) {\n\t var box = this.box;\n\t var center = box.center();\n\t var horizontalAlign = LEFT;\n\t var x, y, verticalAlign;\n\n\t if (this.options.vertical) {\n\t x = center.x;\n\t y = box.y1 - TOOLTIP_OFFSET;\n\t verticalAlign = BOTTOM;\n\t } else {\n\t x = box.x2 + TOOLTIP_OFFSET;\n\t y = center.y;\n\t verticalAlign = CENTER;\n\t }\n\n\t return {\n\t point: new Point(x, y),\n\t align: {\n\t horizontal: horizontalAlign,\n\t vertical: verticalAlign\n\t }\n\t };\n\t }\n\t },\n\n\t formatValue: function(format) {\n\t return this.owner.formatPointValue(this, format);\n\t },\n\n\t overlapsBox: function(box) {\n\t return this.box.overlaps(box);\n\t },\n\n\t unclipElements: function() {\n\t this.fromPoint.unclipElements();\n\t this.toPoint.unclipElements();\n\t },\n\n\t initLabelsFormat: function() {\n\t var labels = this.options.labels;\n\t if (!labels.format) {\n\t if (!labels.from || !labels.from.format) {\n\t labels.from = $.extend({}, labels.from, {\n\t format: DEFAULT_FROM_FORMAT\n\t });\n\t }\n\n\t if (!labels.to || !labels.to.format) {\n\t labels.to = $.extend({}, labels.to, {\n\t format: DEFAULT_TO_FORMAT\n\t });\n\t }\n\t }\n\t },\n\n\t positionLabels: function(fromBox, toBox) {\n\t var ref = this.options;\n\t var labels = ref.labels;\n\t var vertical = ref.vertical;\n\n\t if (labels.position === AUTO) {\n\t var fromLabelPosition, toLabelPosition;\n\t if (vertical) {\n\t if (toBox.y1 <= fromBox.y1) {\n\t toLabelPosition = ABOVE;\n\t fromLabelPosition = BELOW;\n\t } else {\n\t toLabelPosition = BELOW;\n\t fromLabelPosition = ABOVE;\n\t }\n\t } else {\n\t if (toBox.x1 <= fromBox.x1) {\n\t toLabelPosition = LEFT;\n\t fromLabelPosition = RIGHT;\n\t } else {\n\t toLabelPosition = RIGHT;\n\t fromLabelPosition = LEFT;\n\t }\n\t }\n\n\t if (!labels.from || !labels.from.position) {\n\t this.fromPoint.options.labels.position = fromLabelPosition;\n\t }\n\n\t if (!labels.to || !labels.to.position) {\n\t this.toPoint.options.labels.position = toLabelPosition;\n\t }\n\t }\n\t },\n\n\t copyFields: function(point) {\n\t point.dataItem = this.dataItem;\n\t point.category = this.category;\n\t point.series = this.series;\n\t point.color = this.color;\n\t point.owner = this.owner;\n\t }\n\t});\n\n\tdeepExtend(RangeAreaPoint.prototype, PointEventsMixin);\n\tdeepExtend(RangeAreaPoint.prototype, NoteMixin);\n\n\tRangeAreaPoint.prototype.defaults = {\n\t markers: {\n\t visible: false,\n\t background: WHITE,\n\t size: LINE_MARKER_SIZE,\n\t type: CIRCLE,\n\t border: {\n\t width: 2\n\t },\n\t opacity: 1\n\t },\n\t labels: {\n\t visible: false,\n\t margin: getSpacing(3),\n\t padding: getSpacing(4),\n\t animation: {\n\t type: FADEIN,\n\t delay: INITIAL_ANIMATION_DURATION\n\t },\n\t position: AUTO\n\t },\n\t notes: {\n\t label: {}\n\t },\n\t highlight: {\n\t markers: {\n\t border: {\n\t color: WHITE,\n\t width: 2\n\t }\n\t },\n\t zIndex: datavizConstants.HIGHLIGHT_ZINDEX\n\t },\n\t tooltip: {\n\t format: '{0} - {1}'\n\t }\n\t};\n\n\tvar RangeAreaSegment = AreaSegment.extend({\n\t createStrokeSegments: function() {\n\t return this.segmentsFromPoints(this.toGeometryPoints(this.toPoints()));\n\t },\n\n\t stackSegments: function() {\n\t var fromSegments = this.fromSegments;\n\t if (!this.fromSegments) {\n\t fromSegments = this.fromSegments = this.segmentsFromPoints(this.toGeometryPoints(this.fromPoints().reverse()));\n\t }\n\n\t return fromSegments;\n\t },\n\n\t createStroke: function(style) {\n\t var toPath = new Path(style);\n\t var fromPath = new Path(style);\n\n\t toPath.segments.push.apply(toPath.segments, this.strokeSegments());\n\t fromPath.segments.push.apply(fromPath.segments, this.stackSegments());\n\n\t this.visual.append(toPath);\n\t this.visual.append(fromPath);\n\t },\n\n\t hasStackSegment: function() {\n\t return true;\n\t },\n\n\t fromPoints: function() {\n\t return this.linePoints.map(function (point) { return point.fromPoint; });\n\t },\n\n\t toPoints: function() {\n\t return this.linePoints.map(function (point) { return point.toPoint; });\n\t }\n\t});\n\n\tvar SplineRangeAreaSegment = RangeAreaSegment.extend({\n\t createStrokeSegments: function() {\n\t return this.createCurveSegments(this.toPoints());\n\t },\n\n\t stackSegments: function() {\n\t var fromSegments = this.fromSegments;\n\t if (!this.fromSegments) {\n\t fromSegments = this.fromSegments = this.createCurveSegments(this.fromPoints().reverse());\n\t }\n\n\t return fromSegments;\n\t },\n\n\t createCurveSegments: function(points) {\n\t var curveProcessor = new CurveProcessor();\n\n\t return curveProcessor.process(this.toGeometryPoints(points));\n\t }\n\t});\n\n\tvar StepRangeAreaSegment = RangeAreaSegment.extend({\n\t createStrokeSegments: function() {\n\t return this.segmentsFromPoints(this.calculateStepPoints(this.toPoints()));\n\t },\n\n\t stackSegments: function() {\n\t var fromSegments = this.fromSegments;\n\t if (!this.fromSegments) {\n\t fromSegments = this.fromSegments = this.segmentsFromPoints(this.calculateStepPoints(this.fromPoints()));\n\t fromSegments.reverse();\n\t }\n\n\t return fromSegments;\n\t }\n\t});\n\n\tdeepExtend(StepRangeAreaSegment.prototype, StepLineMixin);\n\n\tvar RangeAreaChart = CategoricalChart.extend({\n\t render: function() {\n\t CategoricalChart.fn.render.call(this);\n\n\t this.renderSegments();\n\t },\n\n\t pointType: function() {\n\t return RangeAreaPoint;\n\t },\n\n\t createPoint: function(data, fields) {\n\t var categoryIx = fields.categoryIx;\n\t var category = fields.category;\n\t var series = fields.series;\n\t var seriesIx = fields.seriesIx;\n\t var value = data.valueFields;\n\n\t if (!hasValue(value.from) && !hasValue(value.to)) {\n\t if (this.seriesMissingValues(series) === ZERO) {\n\t value = {\n\t from: 0,\n\t to: 0\n\t };\n\t } else {\n\t return null;\n\t }\n\t }\n\n\t var pointOptions = this.pointOptions(series, seriesIx);\n\t pointOptions = this.evalPointOptions(\n\t pointOptions, value, category, categoryIx, series, seriesIx\n\t );\n\n\t var color = data.fields.color || series.color;\n\t if (isFunction(series.color)) {\n\t color = pointOptions.color;\n\t }\n\n\t var point = new RangeAreaPoint(value, pointOptions);\n\t point.color = color;\n\n\t this.append(point);\n\n\t return point;\n\t },\n\n\t createSegment: function(linePoints, currentSeries, seriesIx) {\n\t var style = (currentSeries.line || {}).style;\n\t var segmentType;\n\t if (style === \"smooth\") {\n\t segmentType = SplineRangeAreaSegment;\n\t } else if (style === \"step\") {\n\t segmentType = StepRangeAreaSegment;\n\t } else {\n\t segmentType = RangeAreaSegment;\n\t }\n\n\t return new segmentType(linePoints, currentSeries, seriesIx);\n\t },\n\n\t plotRange: function(point, startValue) {\n\t if (!point) {\n\t return [ startValue, startValue ];\n\t }\n\n\t return [ point.value.from, point.value.to ];\n\t },\n\n\t valueSlot: function(valueAxis, plotRange) {\n\t var fromSlot = valueAxis.getSlot(plotRange[0], plotRange[0], !this.options.clip);\n\t var toSlot = valueAxis.getSlot(plotRange[1], plotRange[1], !this.options.clip);\n\t if (fromSlot && toSlot) {\n\t return {\n\t from: fromSlot,\n\t to: toSlot\n\t };\n\t }\n\t },\n\n\t pointSlot: function(categorySlot, valueSlot) {\n\t var from = valueSlot.from;\n\t var to = valueSlot.to;\n\t var fromSlot, toSlot;\n\n\t if (this.options.invertAxes) {\n\t fromSlot = new Box(from.x1, categorySlot.y1, from.x2, categorySlot.y2);\n\t toSlot = new Box(to.x1, categorySlot.y1, to.x2, categorySlot.y2);\n\t } else {\n\t fromSlot = new Box(categorySlot.x1, from.y1, categorySlot.x2, from.y2);\n\t toSlot = new Box(categorySlot.x1, to.y1, categorySlot.x2, to.y2);\n\t }\n\n\t return {\n\t from: fromSlot,\n\t to: toSlot\n\t };\n\t },\n\n\t addValue: function(data, fields) {\n\t var valueFields = data.valueFields;\n\t if (!isNumber(valueFields.from)) {\n\t valueFields.from = valueFields.to;\n\t }\n\n\t if (!isNumber(valueFields.to)) {\n\t valueFields.to = valueFields.from;\n\t }\n\n\t CategoricalChart.fn.addValue.call(this, data, fields);\n\t },\n\n\t updateRange: function(value, fields) {\n\t if (value !== null && isNumber(value.from) && isNumber(value.to)) {\n\t var axisName = fields.series.axis;\n\t var axisRange = this.valueAxisRanges[axisName] = this.valueAxisRanges[axisName] || { min: MAX_VALUE, max: MIN_VALUE };\n\t var from = value.from;\n\t var to = value.to;\n\n\t axisRange.min = Math.min(axisRange.min, from, to);\n\t axisRange.max = Math.max(axisRange.max, from, to);\n\t }\n\t },\n\n\t formatPointValue: function(point, format) {\n\t var value = point.value;\n\n\t return this.chartService.format.auto(format, value.from, value.to);\n\t },\n\n\t animationPoints: function() {\n\t var points = this.points;\n\t var result = [];\n\t for (var idx = 0; idx < points.length; idx++) {\n\t var point = points[idx];\n\t if (point) {\n\t result.push((point.fromPoint || {}).marker);\n\t result.push((point.toPoint || {}).marker);\n\t }\n\t }\n\n\t return result.concat(this._segments);\n\t }\n\t});\n\n\tdeepExtend(RangeAreaChart.prototype, LineChartMixin, ClipAnimationMixin);\n\n\tvar OHLCPoint = Candlestick.extend({\n\t reflow: function(box) {\n\t var ref = this;\n\t var options = ref.options;\n\t var value = ref.value;\n\t var chart = ref.owner;\n\t var valueAxis = chart.seriesValueAxis(options);\n\t var oPoints = [];\n\t var cPoints = [];\n\t var lhPoints = [];\n\n\t var lhSlot = valueAxis.getSlot(value.low, value.high);\n\t var oSlot = valueAxis.getSlot(value.open, value.open);\n\t var cSlot = valueAxis.getSlot(value.close, value.close);\n\n\t oSlot.x1 = cSlot.x1 = lhSlot.x1 = box.x1;\n\t oSlot.x2 = cSlot.x2 = lhSlot.x2 = box.x2;\n\n\t var mid = lhSlot.center().x;\n\n\t oPoints.push([ oSlot.x1, oSlot.y1 ]);\n\t oPoints.push([ mid, oSlot.y1 ]);\n\t cPoints.push([ mid, cSlot.y1 ]);\n\t cPoints.push([ cSlot.x2, cSlot.y1 ]);\n\t lhPoints.push([ mid, lhSlot.y1 ]);\n\t lhPoints.push([ mid, lhSlot.y2 ]);\n\n\t this.lines = [\n\t oPoints, cPoints, lhPoints\n\t ];\n\n\t this.box = lhSlot.clone().wrap(oSlot.clone().wrap(cSlot));\n\n\t this.reflowNote();\n\t },\n\n\t createBody: function() {}\n\t});\n\n\tvar OHLCChart = CandlestickChart.extend({\n\t pointType: function() {\n\t return OHLCPoint;\n\t }\n\t});\n\n\tvar WaterfallSegment = ChartElement.extend({\n\t init: function(from, to, series) {\n\t ChartElement.fn.init.call(this);\n\n\t this.from = from;\n\t this.to = to;\n\t this.series = series;\n\t },\n\n\t linePoints: function() {\n\t var from = this.from;\n\t var ref = this;\n\t var fromBox = ref.from.box;\n\t var toBox = ref.to.box;\n\t var points = [];\n\n\t if (from.isVertical) {\n\t var y = from.aboveAxis ? fromBox.y1 : fromBox.y2;\n\t points.push(\n\t [ fromBox.x1, y ],\n\t [ toBox.x2, y ]\n\t );\n\t } else {\n\t var x = from.aboveAxis ? fromBox.x2 : fromBox.x1;\n\t points.push(\n\t [ x, fromBox.y1 ],\n\t [ x, toBox.y2 ]\n\t );\n\t }\n\n\t return points;\n\t },\n\n\t createVisual: function() {\n\t ChartElement.fn.createVisual.call(this);\n\n\t var line = this.series.line || {};\n\n\t var path = Path.fromPoints(this.linePoints(), {\n\t stroke: {\n\t color: line.color,\n\t width: line.width,\n\t opacity: line.opacity,\n\t dashType: line.dashType\n\t }\n\t });\n\n\t alignPathToPixel(path);\n\t this.visual.append(path);\n\t }\n\t});\n\n\tsetDefaultOptions(WaterfallSegment, {\n\t animation: {\n\t type: FADEIN,\n\t delay: INITIAL_ANIMATION_DURATION\n\t }\n\t});\n\n\tvar WaterfallChart = BarChart.extend({\n\t render: function() {\n\t BarChart.fn.render.call(this);\n\t this.createSegments();\n\t },\n\n\t traverseDataPoints: function(callback) {\n\t var this$1 = this;\n\n\t var series = this.options.series;\n\t var totalCategories = categoriesCount(series);\n\t var isVertical = !this.options.invertAxes;\n\n\t for (var seriesIx = 0; seriesIx < series.length; seriesIx++) {\n\t var currentSeries = series[seriesIx];\n\t var total = 0;\n\t var runningTotal = 0;\n\n\t for (var categoryIx = 0; categoryIx < totalCategories; categoryIx++) {\n\t var data = SeriesBinder.current.bindPoint(currentSeries, categoryIx);\n\t var value = data.valueFields.value;\n\t var summary = data.fields.summary;\n\t var from = total;\n\t var to = (void 0);\n\n\t if (summary) {\n\t if (summary.toLowerCase() === \"total\") {\n\t data.valueFields.value = total;\n\t from = 0;\n\t to = total;\n\t } else {\n\t data.valueFields.value = runningTotal;\n\t to = from - runningTotal;\n\t runningTotal = 0;\n\t }\n\t } else if (isNumber(value)) {\n\t runningTotal += value;\n\t total += value;\n\t to = total;\n\t }\n\n\t callback(data, {\n\t category: this$1.categoryAxis.categoryAt(categoryIx),\n\t categoryIx: categoryIx,\n\t series: currentSeries,\n\t seriesIx: seriesIx,\n\t total: total,\n\t runningTotal: runningTotal,\n\t from: from,\n\t to: to,\n\t isVertical: isVertical\n\t });\n\t }\n\t }\n\t },\n\n\t updateRange: function(value, fields) {\n\t BarChart.fn.updateRange.call(this, { value: fields.to }, fields);\n\t },\n\n\t aboveAxis: function(point) {\n\t return point.value >= 0;\n\t },\n\n\t plotRange: function(point) {\n\t return [ point.from, point.to ];\n\t },\n\n\t createSegments: function() {\n\t var this$1 = this;\n\n\t var series = this.options.series;\n\t var seriesPoints = this.seriesPoints;\n\t var segments = this.segments = [];\n\n\t for (var seriesIx = 0; seriesIx < series.length; seriesIx++) {\n\t var currentSeries = series[seriesIx];\n\t var points = seriesPoints[seriesIx];\n\n\t if (points) {\n\t var prevPoint = (void 0);\n\t for (var pointIx = 0; pointIx < points.length; pointIx++) {\n\t var point = points[pointIx];\n\n\t if (point && prevPoint) {\n\t var segment = new WaterfallSegment(prevPoint, point, currentSeries);\n\t segments.push(segment);\n\t this$1.append(segment);\n\t }\n\n\t prevPoint = point;\n\t }\n\t }\n\t }\n\t }\n\t});\n\n\tvar AREA_SERIES = [ AREA, VERTICAL_AREA, RANGE_AREA, VERTICAL_RANGE_AREA ];\n\tvar OUT_OF_RANGE_SERIES = [ LINE, VERTICAL_LINE ].concat(AREA_SERIES);\n\n\tvar CategoricalPlotArea = PlotAreaBase.extend({\n\t initFields: function(series) {\n\t var this$1 = this;\n\n\t this.namedCategoryAxes = {};\n\t this.namedValueAxes = {};\n\t this.valueAxisRangeTracker = new AxisGroupRangeTracker();\n\n\t if (series.length > 0) {\n\t this.invertAxes = inArray(\n\t series[0].type, [ BAR, BULLET, VERTICAL_LINE, VERTICAL_AREA, VERTICAL_RANGE_AREA,\n\t RANGE_BAR, HORIZONTAL_WATERFALL, VERTICAL_BOX_PLOT ]\n\t );\n\n\t for (var i = 0; i < series.length; i++) {\n\t var stack = series[i].stack;\n\t if (stack && stack.type === \"100%\") {\n\t this$1.stack100 = true;\n\t break;\n\t }\n\t }\n\t }\n\n\t },\n\n\t render: function(panes) {\n\t if (panes === void 0) { panes = this.panes; }\n\n\t this.createCategoryAxes(panes);\n\t this.aggregateCategories(panes);\n\t this.createCategoryAxesLabels(panes);\n\t this.createCharts(panes);\n\t this.createValueAxes(panes);\n\t },\n\n\t removeAxis: function(axis) {\n\t var axisName = axis.options.name;\n\n\t PlotAreaBase.fn.removeAxis.call(this, axis);\n\n\t if (axis instanceof CategoryAxis) {\n\t delete this.namedCategoryAxes[axisName];\n\t } else {\n\t this.valueAxisRangeTracker.reset(axisName);\n\t delete this.namedValueAxes[axisName];\n\t }\n\n\t if (axis === this.categoryAxis) {\n\t delete this.categoryAxis;\n\t }\n\n\t if (axis === this.valueAxis) {\n\t delete this.valueAxis;\n\t }\n\t },\n\n\t createCharts: function(panes) {\n\t var this$1 = this;\n\n\t var seriesByPane = this.groupSeriesByPane();\n\n\t for (var i = 0; i < panes.length; i++) {\n\t var pane = panes[i];\n\t var paneSeries = seriesByPane[pane.options.name || \"default\"] || [];\n\t this$1.addToLegend(paneSeries);\n\n\t var visibleSeries = this$1.filterVisibleSeries(paneSeries);\n\t if (!visibleSeries) {\n\t continue;\n\t }\n\n\t var groups = this$1.groupSeriesByCategoryAxis(visibleSeries);\n\t for (var groupIx = 0; groupIx < groups.length; groupIx++) {\n\t this$1.createChartGroup(groups[groupIx], pane);\n\t }\n\t }\n\t },\n\n\t createChartGroup: function(series, pane) {\n\t this.createAreaChart(\n\t filterSeriesByType(series, [ AREA, VERTICAL_AREA ]), pane\n\t );\n\n\t this.createRangeAreaChart(\n\t filterSeriesByType(series, [ RANGE_AREA, VERTICAL_RANGE_AREA ]), pane\n\t );\n\n\t this.createBarChart(\n\t filterSeriesByType(series, [ COLUMN, BAR ]), pane\n\t );\n\n\t this.createRangeBarChart(\n\t filterSeriesByType(series, [ RANGE_COLUMN, RANGE_BAR ]), pane\n\t );\n\n\t this.createBulletChart(\n\t filterSeriesByType(series, [ BULLET, VERTICAL_BULLET ]), pane\n\t );\n\n\t this.createCandlestickChart(\n\t filterSeriesByType(series, CANDLESTICK), pane\n\t );\n\n\t this.createBoxPlotChart(\n\t filterSeriesByType(series, [ BOX_PLOT, VERTICAL_BOX_PLOT ]), pane\n\t );\n\n\t this.createOHLCChart(\n\t filterSeriesByType(series, OHLC), pane\n\t );\n\n\t this.createWaterfallChart(\n\t filterSeriesByType(series, [ WATERFALL, HORIZONTAL_WATERFALL ]), pane\n\t );\n\n\t this.createLineChart(\n\t filterSeriesByType(series, [ LINE, VERTICAL_LINE ]), pane\n\t );\n\t },\n\n\t aggregateCategories: function(panes) {\n\t var this$1 = this;\n\n\t var series = this.srcSeries || this.series;\n\t var processedSeries = [];\n\t this._currentPointsCache = {};\n\t this._seriesPointsCache = this._seriesPointsCache || {};\n\n\t for (var i = 0; i < series.length; i++) {\n\t var currentSeries = series[i];\n\t var categoryAxis = this$1.seriesCategoryAxis(currentSeries);\n\t var axisPane = this$1.findPane(categoryAxis.options.pane);\n\t var dateAxis = equalsIgnoreCase(categoryAxis.options.type, DATE);\n\n\t if ((dateAxis || currentSeries.categoryField) && inArray(axisPane, panes)) {\n\t currentSeries = this$1.aggregateSeries(currentSeries, categoryAxis);\n\t } else {\n\t currentSeries = this$1.filterSeries(currentSeries, categoryAxis);\n\t }\n\n\t processedSeries.push(currentSeries);\n\t }\n\n\t this._seriesPointsCache = this._currentPointsCache;\n\t this._currentPointsCache = null;\n\n\t this.srcSeries = series;\n\t this.series = processedSeries;\n\t },\n\n\t filterSeries: function(series, categoryAxis) {\n\t var dataLength = (series.data || {}).length;\n\t categoryAxis._seriesMax = Math.max(categoryAxis._seriesMax || 0, dataLength);\n\n\t if (!(isNumber(categoryAxis.options.min) || isNumber(categoryAxis.options.max))) {\n\t return series;\n\t }\n\n\t var range = categoryAxis.currentRangeIndices();\n\t var outOfRangePoints = inArray(series.type, OUT_OF_RANGE_SERIES);\n\t var currentSeries = deepExtend({}, series);\n\n\t currentSeries.data = (currentSeries.data || []).slice(range.min, range.max + 1);\n\n\t if (outOfRangePoints) {\n\t createOutOfRangePoints(currentSeries, range, dataLength, function (idx) { return ({\n\t item: series.data[idx],\n\t category: categoryAxis.categoryAt(idx, true),\n\t categoryIx: idx - range.min\n\t }); }, function (idx) { return defined(series.data[idx]); });\n\t }\n\n\t return currentSeries;\n\t },\n\n\t clearSeriesPointsCache: function() {\n\t this._seriesPointsCache = {};\n\t },\n\n\t seriesSourcePoints: function(series, categoryAxis) {\n\t var this$1 = this;\n\n\t var key = (series.index) + \";\" + (categoryAxis.categoriesHash());\n\t if (this._seriesPointsCache[key]) {\n\t this._currentPointsCache[key] = this._seriesPointsCache[key];\n\t return this._seriesPointsCache[key];\n\t }\n\n\t var axisOptions = categoryAxis.options;\n\t var srcCategories = axisOptions.srcCategories;\n\t var dateAxis = equalsIgnoreCase(axisOptions.type, DATE);\n\t var srcData = series.data;\n\t var getFn = dateAxis ? getDateField : getField;\n\t var result = [];\n\t if (!dateAxis) {\n\t categoryAxis.mapCategories();//fixes major performance issue caused by searching for the index for large data\n\t }\n\n\t for (var idx = 0; idx < srcData.length; idx++) {\n\t var category = (void 0);\n\t if (series.categoryField) {\n\t category = getFn(series.categoryField, srcData[idx], this$1.chartService.intl);\n\t } else {\n\t category = srcCategories[idx];\n\t }\n\n\t if (defined(category) && category !== null) {\n\t var categoryIx = categoryAxis.totalIndex(category);\n\t result[categoryIx] = result[categoryIx] || { items: [], category: category };\n\t result[categoryIx].items.push(idx);\n\t }\n\t }\n\n\t this._currentPointsCache[key] = result;\n\n\t return result;\n\t },\n\n\t aggregateSeries: function(series, categoryAxis) {\n\t var srcData = series.data;\n\t if (!srcData.length) {\n\t return series;\n\t }\n\n\t var srcPoints = this.seriesSourcePoints(series, categoryAxis);\n\t var result = deepExtend({}, series);\n\t var aggregator = new SeriesAggregator(deepExtend({}, series), SeriesBinder.current, DefaultAggregates.current);\n\t var data = result.data = [];\n\t var dataItems = categoryAxis.options.dataItems || [];\n\n\t var range = categoryAxis.currentRangeIndices();\n\t var categoryItem = function (idx) {\n\t var categoryIdx = idx - range.min;\n\t var point = srcPoints[idx];\n\t if (!point) {\n\t point = srcPoints[idx] = {};\n\t }\n\n\t point.categoryIx = categoryIdx;\n\n\t if (!point.item) {\n\t var category = categoryAxis.categoryAt(idx, true);\n\t point.category = category;\n\t point.item = aggregator.aggregatePoints(point.items, category);\n\t }\n\n\t return point;\n\t };\n\n\t for (var idx = range.min; idx <= range.max; idx++) {\n\t var point = categoryItem(idx);\n\t data[point.categoryIx] = point.item;\n\n\t if (point.items && point.items.length) {\n\t dataItems[point.categoryIx] = point.item;\n\t }\n\t }\n\n\t if (inArray(result.type, OUT_OF_RANGE_SERIES)) {\n\t createOutOfRangePoints(result, range, categoryAxis.totalCount(), categoryItem, function (idx) { return srcPoints[idx]; });\n\t }\n\n\t categoryAxis.options.dataItems = dataItems;\n\n\t return result;\n\t },\n\n\t appendChart: function(chart, pane) {\n\t var series = chart.options.series;\n\t var categoryAxis = this.seriesCategoryAxis(series[0]);\n\t var categories = categoryAxis.options.categories;\n\t var categoriesToAdd = Math.max(0, categoriesCount(series) - categories.length);\n\n\t if (categoriesToAdd > 0) {//consider setting an option to axis instead of adding fake categories\n\t categories = categoryAxis.options.categories = categoryAxis.options.categories.slice(0);\n\t while (categoriesToAdd--) {\n\t categories.push(\"\");\n\t }\n\t }\n\n\t this.valueAxisRangeTracker.update(chart.valueAxisRanges);\n\n\t PlotAreaBase.fn.appendChart.call(this, chart, pane);\n\t },\n\n\t seriesPaneName: function(series) {\n\t var options = this.options;\n\t var axisName = series.axis;\n\t var axisOptions = [].concat(options.valueAxis);\n\t var axis = grep(axisOptions, function(a) { return a.name === axisName; })[0];\n\t var panes = options.panes || [ {} ];\n\t var defaultPaneName = (panes[0] || {}).name || \"default\";\n\t var paneName = (axis || {}).pane || defaultPaneName;\n\n\t return paneName;\n\t },\n\n\t seriesCategoryAxis: function(series) {\n\t var axisName = series.categoryAxis;\n\t var axis = axisName ? this.namedCategoryAxes[axisName] : this.categoryAxis;\n\n\t if (!axis) {\n\t throw new Error(\"Unable to locate category axis with name \" + axisName);\n\t }\n\n\t return axis;\n\t },\n\n\t stackableChartOptions: function(firstSeries, pane) {\n\t var stack = firstSeries.stack;\n\t var isStacked100 = stack && stack.type === \"100%\";\n\t var clip = pane.options.clip;\n\n\t return {\n\t isStacked: stack,\n\t isStacked100: isStacked100,\n\t clip: clip\n\t };\n\t },\n\n\t groupSeriesByCategoryAxis: function(series) {\n\t var categoryAxes = [];\n\t var unique = {};\n\t for (var idx = 0; idx < series.length; idx++) {\n\t var name = series[idx].categoryAxis || \"$$default$$\";\n\t if (!unique.hasOwnProperty(name)) {\n\t unique[name] = true;\n\t categoryAxes.push(name);\n\t }\n\t }\n\n\t var groups = [];\n\t for (var axisIx = 0; axisIx < categoryAxes.length; axisIx++) {\n\t var axis = categoryAxes[axisIx];\n\t var axisSeries = groupSeries(series, axis, axisIx);\n\t if (axisSeries.length === 0) {\n\t continue;\n\t }\n\n\t groups.push(axisSeries);\n\t }\n\n\t return groups;\n\t },\n\n\t createBarChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var barChart = new BarChart(this, $.extend({\n\t series: series,\n\t invertAxes: this.invertAxes,\n\t gap: firstSeries.gap,\n\t spacing: firstSeries.spacing\n\t }, this.stackableChartOptions(firstSeries, pane)));\n\n\t this.appendChart(barChart, pane);\n\t },\n\n\t createRangeBarChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var rangeColumnChart = new RangeBarChart(this, {\n\t series: series,\n\t invertAxes: this.invertAxes,\n\t gap: firstSeries.gap,\n\t spacing: firstSeries.spacing\n\t });\n\n\t this.appendChart(rangeColumnChart, pane);\n\t },\n\n\t createBulletChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var bulletChart = new BulletChart(this, {\n\t series: series,\n\t invertAxes: this.invertAxes,\n\t gap: firstSeries.gap,\n\t spacing: firstSeries.spacing,\n\t clip: pane.options.clip\n\t });\n\n\t this.appendChart(bulletChart, pane);\n\t },\n\n\t createLineChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var lineChart = new LineChart(this, $.extend({\n\t invertAxes: this.invertAxes,\n\t series: series\n\t }, this.stackableChartOptions(firstSeries, pane)));\n\n\t this.appendChart(lineChart, pane);\n\t },\n\n\t createAreaChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var areaChart = new AreaChart(this, $.extend({\n\t invertAxes: this.invertAxes,\n\t series: series\n\t }, this.stackableChartOptions(firstSeries, pane)));\n\n\t this.appendChart(areaChart, pane);\n\t },\n\n\t createRangeAreaChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var rangeAreaChart = new RangeAreaChart(this, {\n\t invertAxes: this.invertAxes,\n\t series: series,\n\t clip: pane.options.clip\n\t });\n\n\t this.appendChart(rangeAreaChart, pane);\n\t },\n\n\t createOHLCChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var chart = new OHLCChart(this, {\n\t invertAxes: this.invertAxes,\n\t gap: firstSeries.gap,\n\t series: series,\n\t spacing: firstSeries.spacing,\n\t clip: pane.options.clip\n\t });\n\n\t this.appendChart(chart, pane);\n\t },\n\n\t createCandlestickChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var chart = new CandlestickChart(this, {\n\t invertAxes: this.invertAxes,\n\t gap: firstSeries.gap,\n\t series: series,\n\t spacing: firstSeries.spacing,\n\t clip: pane.options.clip\n\t });\n\n\t this.appendChart(chart, pane);\n\t },\n\n\t createBoxPlotChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var chart = new BoxPlotChart(this, {\n\t invertAxes: this.invertAxes,\n\t gap: firstSeries.gap,\n\t series: series,\n\t spacing: firstSeries.spacing,\n\t clip: pane.options.clip\n\t });\n\n\t this.appendChart(chart, pane);\n\t },\n\n\t createWaterfallChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var waterfallChart = new WaterfallChart(this, {\n\t series: series,\n\t invertAxes: this.invertAxes,\n\t gap: firstSeries.gap,\n\t spacing: firstSeries.spacing\n\t });\n\n\t this.appendChart(waterfallChart, pane);\n\t },\n\n\t axisRequiresRounding: function(categoryAxisName, categoryAxisIndex) {\n\t var this$1 = this;\n\n\t var centeredSeries = filterSeriesByType(this.series, EQUALLY_SPACED_SERIES);\n\n\t for (var seriesIx = 0; seriesIx < this.series.length; seriesIx++) {\n\t var currentSeries = this$1.series[seriesIx];\n\t if (inArray(currentSeries.type, AREA_SERIES)) {\n\t var line = currentSeries.line;\n\t if (line && line.style === STEP) {\n\t centeredSeries.push(currentSeries);\n\t }\n\t }\n\t }\n\n\t for (var seriesIx$1 = 0; seriesIx$1 < centeredSeries.length; seriesIx$1++) {\n\t var seriesAxis = centeredSeries[seriesIx$1].categoryAxis || \"\";\n\t if (seriesAxis === categoryAxisName || (!seriesAxis && categoryAxisIndex === 0)) {\n\t return true;\n\t }\n\t }\n\t },\n\n\t aggregatedAxis: function(categoryAxisName, categoryAxisIndex) {\n\t var series = this.series;\n\n\t for (var seriesIx = 0; seriesIx < series.length; seriesIx++) {\n\t var seriesAxis = series[seriesIx].categoryAxis || \"\";\n\t if ((seriesAxis === categoryAxisName || (!seriesAxis && categoryAxisIndex === 0)) && series[seriesIx].categoryField) {\n\t return true;\n\t }\n\t }\n\t },\n\n\t createCategoryAxesLabels: function() {\n\t var axes = this.axes;\n\t for (var i = 0; i < axes.length; i++) {\n\t if (axes[i] instanceof CategoryAxis) {\n\t axes[i].createLabels();\n\t }\n\t }\n\t },\n\n\t createCategoryAxes: function(panes) {\n\t var this$1 = this;\n\n\t var invertAxes = this.invertAxes;\n\t var definitions = [].concat(this.options.categoryAxis);\n\t var axes = [];\n\n\t for (var i = 0; i < definitions.length; i++) {\n\t var axisOptions = definitions[i];\n\t var axisPane = this$1.findPane(axisOptions.pane);\n\n\t if (inArray(axisPane, panes)) {\n\t var name = axisOptions.name;\n\t var categories = axisOptions.categories; if (categories === void 0) { categories = []; }\n\t axisOptions = deepExtend({\n\t vertical: invertAxes,\n\t reverse: !invertAxes && this$1.chartService.rtl,\n\t axisCrossingValue: invertAxes ? MAX_VALUE : 0\n\t }, axisOptions);\n\n\t if (!defined(axisOptions.justified)) {\n\t axisOptions.justified = this$1.isJustified();\n\t }\n\n\t if (this$1.axisRequiresRounding(name, i)) {\n\t axisOptions.justified = false;\n\t }\n\n\t var categoryAxis = (void 0);\n\n\t if (isDateAxis(axisOptions, categories[0])) {\n\t categoryAxis = new dataviz.DateCategoryAxis(axisOptions, this$1.chartService);\n\t } else {\n\t categoryAxis = new CategoryAxis(axisOptions, this$1.chartService);\n\t }\n\n\t definitions[i].categories = categoryAxis.options.srcCategories;\n\n\t if (name) {\n\t if (this$1.namedCategoryAxes[name]) {\n\t throw new Error((\"Category axis with name \" + name + \" is already defined\"));\n\t }\n\t this$1.namedCategoryAxes[name] = categoryAxis;\n\t }\n\n\t categoryAxis.axisIndex = i;\n\t axes.push(categoryAxis);\n\t this$1.appendAxis(categoryAxis);\n\t }\n\t }\n\n\t var primaryAxis = this.categoryAxis || axes[0];\n\t this.categoryAxis = primaryAxis;\n\n\t if (invertAxes) {\n\t this.axisY = primaryAxis;\n\t } else {\n\t this.axisX = primaryAxis;\n\t }\n\t },\n\n\t isJustified: function() {\n\t var series = this.series;\n\n\t for (var i = 0; i < series.length; i++) {\n\t var currentSeries = series[i];\n\t if (!inArray(currentSeries.type, AREA_SERIES)) {\n\t return false;\n\t }\n\t }\n\n\t return true;\n\t },\n\n\t createValueAxes: function(panes) {\n\t var this$1 = this;\n\n\t var tracker = this.valueAxisRangeTracker;\n\t var defaultRange = tracker.query();\n\t var definitions = [].concat(this.options.valueAxis);\n\t var invertAxes = this.invertAxes;\n\t var baseOptions = { vertical: !invertAxes, reverse: invertAxes && this.chartService.rtl };\n\t var axes = [];\n\n\t if (this.stack100) {\n\t baseOptions.roundToMajorUnit = false;\n\t baseOptions.labels = { format: \"P0\" };\n\t }\n\n\t for (var i = 0; i < definitions.length; i++) {\n\t var axisOptions = definitions[i];\n\t var axisPane = this$1.findPane(axisOptions.pane);\n\n\t if (inArray(axisPane, panes)) {\n\t var name = axisOptions.name;\n\t var defaultAxisRange = equalsIgnoreCase(axisOptions.type, LOGARITHMIC) ? { min: 0.1, max: 1 } : { min: 0, max: 1 };\n\t var range = tracker.query(name) || defaultRange || defaultAxisRange;\n\n\t if (i === 0 && range && defaultRange) {\n\t range.min = Math.min(range.min, defaultRange.min);\n\t range.max = Math.max(range.max, defaultRange.max);\n\t }\n\n\t var axisType = (void 0);\n\t if (equalsIgnoreCase(axisOptions.type, LOGARITHMIC)) {\n\t axisType = dataviz.LogarithmicAxis;\n\t } else {\n\t axisType = dataviz.NumericAxis;\n\t }\n\n\t var valueAxis = new axisType(range.min, range.max,\n\t deepExtend({}, baseOptions, axisOptions),\n\t this$1.chartService\n\t );\n\n\t if (name) {\n\t if (this$1.namedValueAxes[name]) {\n\t throw new Error((\"Value axis with name \" + name + \" is already defined\"));\n\t }\n\t this$1.namedValueAxes[name] = valueAxis;\n\t }\n\t valueAxis.axisIndex = i;\n\n\t axes.push(valueAxis);\n\t this$1.appendAxis(valueAxis);\n\t }\n\t }\n\n\t var primaryAxis = this.valueAxis || axes[0];\n\t this.valueAxis = primaryAxis;\n\n\t if (invertAxes) {\n\t this.axisX = primaryAxis;\n\t } else {\n\t this.axisY = primaryAxis;\n\t }\n\t },\n\n\t _dispatchEvent: function(chart, e, eventType) {\n\t var coords = chart._eventCoordinates(e);\n\t var point = new Point(coords.x, coords.y);\n\t var pane = this.pointPane(point);\n\t var categories = [];\n\t var values = [];\n\n\t if (!pane) {\n\t return;\n\t }\n\n\t var allAxes = pane.axes;\n\t for (var i = 0; i < allAxes.length; i++) {\n\t var axis = allAxes[i];\n\t if (axis.getValue) {\n\t appendIfNotNull(values, axis.getValue(point));\n\t } else {\n\t appendIfNotNull(categories, axis.getCategory(point));\n\t }\n\t }\n\n\t if (categories.length === 0) {\n\t appendIfNotNull(categories, this.categoryAxis.getCategory(point));\n\t }\n\n\t if (categories.length > 0 && values.length > 0) {\n\t chart.trigger(eventType, {\n\t element: eventElement(e),\n\t originalEvent: e,\n\t category: singleItemOrArray(categories),\n\t value: singleItemOrArray(values)\n\t });\n\t }\n\t },\n\n\t pointPane: function(point) {\n\t var panes = this.panes;\n\n\t for (var i = 0; i < panes.length; i++) {\n\t var currentPane = panes[i];\n\t if (currentPane.contentBox.containsPoint(point)) {\n\t return currentPane;\n\t }\n\t }\n\t },\n\n\t updateAxisOptions: function(axis, options) {\n\t updateAxisOptions(this.options, axis, options);\n\t updateAxisOptions(this.originalOptions, axis, options);\n\t }\n\t});\n\n\tfunction updateAxisOptions(targetOptions, axis, options) {\n\t var axesOptions = axis instanceof CategoryAxis ? [].concat(targetOptions.categoryAxis) : [].concat(targetOptions.valueAxis);\n\t deepExtend(axesOptions[axis.axisIndex], options);\n\t}\n\n\tfunction groupSeries(series, axis, axisIx) {\n\t return grep(series, function(s) {\n\t return (axisIx === 0 && !s.categoryAxis) || (s.categoryAxis === axis);\n\t });\n\t}\n\n\tsetDefaultOptions(CategoricalPlotArea, {\n\t categoryAxis: {},\n\t valueAxis: {}\n\t});\n\n\tdeepExtend(CategoricalPlotArea.prototype, PlotAreaEventsMixin);\n\n\tvar Highlight = Class.extend({\n\t init: function() {\n\n\t this._points = [];\n\t },\n\n\t destroy: function() {\n\t this._points = [];\n\t },\n\n\t show: function(points) {\n\t var this$1 = this;\n\n\t var arrayPoints = [].concat(points);\n\t this.hide();\n\n\t for (var i = 0; i < arrayPoints.length; i++) {\n\t var point = arrayPoints[i];\n\t if (point && point.toggleHighlight && point.hasHighlight()) {\n\t this$1.togglePointHighlight(point, true);\n\t this$1._points.push(point);\n\t }\n\t }\n\t },\n\n\t togglePointHighlight: function(point, show) {\n\t var toggleHandler = (point.options.highlight || {}).toggle;\n\t if (toggleHandler) {\n\t var eventArgs = {\n\t category: point.category,\n\t series: point.series,\n\t dataItem: point.dataItem,\n\t value: point.value,\n\t stackValue: point.stackValue,\n\t preventDefault: preventDefault,\n\t visual: point.highlightVisual(),\n\t show: show\n\t };\n\t toggleHandler(eventArgs);\n\t if (!eventArgs._defaultPrevented) {\n\t point.toggleHighlight(show);\n\t }\n\t } else {\n\t point.toggleHighlight(show);\n\t }\n\t },\n\n\t hide: function() {\n\t var this$1 = this;\n\n\t var points = this._points;\n\t while (points.length) {\n\t this$1.togglePointHighlight(points.pop(), false);\n\t }\n\t },\n\n\t isHighlighted: function(element) {\n\t var points = this._points;\n\n\t for (var i = 0; i < points.length; i++) {\n\t var point = points[i];\n\t if (element === point) {\n\t return true;\n\t }\n\t }\n\n\t return false;\n\t }\n\t});\n\n\tfunction preventDefault() {\n\t this._defaultPrevented = true;\n\t}\n\n\tfunction acceptKey(e, mouseKey) {\n\t var key = (mouseKey || \"\").toLowerCase();\n\t var event = e.event;\n\t var accept = (key === \"none\" && !(event.ctrlKey || event.shiftKey || event.altKey)) || event[key + \"Key\"];\n\n\t return accept;\n\t}\n\n\tfunction toChartAxisRanges(axisRanges) {\n\t var ranges = {};\n\t for (var idx = 0; idx < axisRanges.length; idx++) {\n\t var axisRange = axisRanges[idx];\n\t if (axisRange.axis.options.name) {\n\t ranges[axisRange.axis.options.name] = {\n\t min: axisRange.range.min,\n\t max: axisRange.range.max\n\t };\n\t }\n\t }\n\t return ranges;\n\t}\n\n\tvar Pannable = Class.extend({\n\t init: function(plotArea, options) {\n\n\t this.plotArea = plotArea;\n\t this.options = deepExtend({}, this.options, options);\n\t },\n\n\t start: function(e) {\n\t this._active = acceptKey(e, this.options.key);\n\t return this._active;\n\t },\n\n\t move: function(e) {\n\t if (this._active) {\n\t var axisRanges = this.axisRanges = this._panAxes(e, X).concat(this._panAxes(e, Y));\n\t if (axisRanges.length) {\n\t this.axisRanges = axisRanges;\n\t return toChartAxisRanges(axisRanges);\n\t }\n\t }\n\t },\n\n\t end: function() {\n\t var active = this._active;\n\t this._active = false;\n\n\t return active;\n\t },\n\n\t pan: function() {\n\t var ref = this;\n\t var plotArea = ref.plotArea;\n\t var axisRanges = ref.axisRanges;\n\t if (axisRanges.length) {\n\t for (var idx = 0; idx < axisRanges.length; idx++) {\n\t var range = axisRanges[idx];\n\t plotArea.updateAxisOptions(range.axis, range.range);\n\t }\n\t plotArea.redraw(plotArea.panes);\n\t }\n\t },\n\n\t destroy: function() {\n\t delete this.plotArea;\n\t },\n\n\t _panAxes: function(e, position) {\n\t var plotArea = this.plotArea;\n\t var delta = -e[position].delta;\n\t var lock = (this.options.lock || \"\").toLowerCase();\n\t var updatedAxes = [];\n\n\t if (delta !== 0 && (lock || \"\").toLowerCase() !== position) {\n\t var axes = plotArea.axes;\n\t for (var idx = 0; idx < axes.length; idx++) {\n\t var axis = axes[idx];\n\n\t if (position === X && !axis.options.vertical || position === Y && axis.options.vertical) {\n\t var range = axis.pan(delta);\n\n\t if (range) {\n\t range.limitRange = true;\n\t updatedAxes.push({\n\t axis: axis,\n\t range: range\n\t });\n\t }\n\t }\n\t }\n\t }\n\n\t return updatedAxes;\n\t }\n\t});\n\n\tPannable.prototype.options = {\n\t key: \"none\",\n\t lock: \"none\"\n\t};\n\n\tvar ZoomSelection = Class.extend({\n\t init: function(chart, options) {\n\n\t this.chart = chart;\n\t this.options = deepExtend({}, this.options, options);\n\t this.createElement();\n\t },\n\n\t createElement: function() {\n\t var marquee = this._marquee = document.createElement(\"div\");\n\t marquee.className = \"k-marquee\";\n\t var marqueeColor = document.createElement(\"div\");\n\t marqueeColor.className = \"k-marquee-color\";\n\t marquee.appendChild(marqueeColor);\n\t },\n\n\t removeElement: function() {\n\t if (this._marquee.parentNode) {\n\t this._marquee.parentNode.removeChild(this._marquee);\n\t }\n\t },\n\n\t setStyles: function(styles) {\n\t elementStyles(this._marquee, styles);\n\t },\n\n\t start: function(e) {\n\t if (acceptKey(e, this.options.key)) {\n\t var chart = this.chart;\n\t var point = chart._eventCoordinates(e);\n\t var zoomPane = this._zoomPane = chart._plotArea.paneByPoint(point);\n\t var clipBox = zoomPane ? zoomPane.chartsBox().clone() : null;\n\n\t if (zoomPane && clipBox) {\n\t var offset = this._elementOffset();\n\n\t clipBox.translate(offset.left, offset.top);\n\t this._zoomPaneClipBox = clipBox;\n\n\t document.body.appendChild(this._marquee);\n\t this.setStyles({\n\t left: e.pageX + 1,\n\t top: e.pageY + 1,\n\t width: 0,\n\t height: 0\n\t });\n\n\t return true;\n\t }\n\t }\n\t return false;\n\t },\n\n\t _elementOffset: function() {\n\t var chartElement = this.chart.element;\n\t var ref = elementStyles(chartElement, [ \"paddingLeft\", \"paddingTop\" ]);\n\t var paddingLeft = ref.paddingLeft;\n\t var paddingTop = ref.paddingTop;\n\t var offset = dataviz.elementOffset(chartElement);\n\n\t return {\n\t left: paddingLeft + offset.left,\n\t top: paddingTop + offset.top\n\t };\n\t },\n\n\t move: function(e) {\n\t var zoomPane = this._zoomPane;\n\t if (zoomPane) {\n\t this.setStyles(this._selectionPosition(e));\n\t }\n\t },\n\n\t end: function(e) {\n\t var zoomPane = this._zoomPane;\n\t if (zoomPane) {\n\t var elementOffset$$1 = this._elementOffset();\n\t var selectionPosition = this._selectionPosition(e);\n\t selectionPosition.left -= elementOffset$$1.left;\n\t selectionPosition.top -= elementOffset$$1.top;\n\n\t var start = { x: selectionPosition.left, y: selectionPosition.top };\n\t var end = { x: selectionPosition.left + selectionPosition.width, y: selectionPosition.top + selectionPosition.height };\n\t this._updateAxisRanges(start, end);\n\n\t this.removeElement();\n\t delete this._zoomPane;\n\n\t return toChartAxisRanges(this.axisRanges);\n\t }\n\t },\n\n\t zoom: function() {\n\t var axisRanges = this.axisRanges;\n\t if (axisRanges && axisRanges.length) {\n\t var plotArea = this.chart._plotArea;\n\t for (var idx = 0; idx < axisRanges.length; idx++) {\n\t var axisRange = axisRanges[idx];\n\t plotArea.updateAxisOptions(axisRange.axis, axisRange.range);\n\t }\n\t plotArea.redraw(plotArea.panes);\n\t }\n\t },\n\n\t destroy: function() {\n\t this.removeElement();\n\t delete this._marquee;\n\t delete this.chart;\n\t },\n\n\t _updateAxisRanges: function(start, end) {\n\t var lock = (this.options.lock || \"\").toLowerCase();\n\t var axisRanges = [];\n\n\t var axes = this._zoomPane.axes;\n\t for (var idx = 0; idx < axes.length; idx++) {\n\t var axis = axes[idx];\n\t var vertical = axis.options.vertical;\n\t if (!(lock === X && !vertical) && !(lock === Y && vertical) && defined(axis.axisIndex)) {\n\t var range = axis.pointsRange(start, end);\n\t if (range) {\n\t axisRanges.push({\n\t axis: axis,\n\t range: range\n\t });\n\t }\n\t }\n\t }\n\n\t this.axisRanges = axisRanges;\n\t },\n\n\t _selectionPosition: function(e) {\n\t var clipBox = this._zoomPaneClipBox;\n\t var startLocation = {\n\t x: e.x.startLocation,\n\t y: e.y.startLocation\n\t };\n\t var pageX = e.x.location;\n\t var pageY = e.y.location;\n\t var lock = (this.options.lock || \"\").toLowerCase();\n\t var left = Math.min(startLocation.x, pageX);\n\t var top = Math.min(startLocation.y, pageY);\n\t var width = Math.abs(startLocation.x - pageX);\n\t var height = Math.abs(startLocation.y - pageY);\n\n\t if (lock === X) {\n\t left = clipBox.x1;\n\t width = clipBox.width();\n\t }\n\t if (lock === Y) {\n\t top = clipBox.y1;\n\t height = clipBox.height();\n\t }\n\n\t if (pageX > clipBox.x2) {\n\t width = clipBox.x2 - startLocation.x;\n\t }\n\n\t if (pageX < clipBox.x1) {\n\t width = startLocation.x - clipBox.x1;\n\t }\n\n\t if (pageY > clipBox.y2) {\n\t height = clipBox.y2 - startLocation.y;\n\t }\n\n\t if (pageY < clipBox.y1) {\n\t height = startLocation.y - clipBox.y1;\n\t }\n\n\t return {\n\t left: Math.max(left, clipBox.x1),\n\t top: Math.max(top, clipBox.y1),\n\t width: width,\n\t height: height\n\t };\n\t }\n\t});\n\n\tZoomSelection.prototype.options = {\n\t key: \"shift\",\n\t lock: \"none\"\n\t};\n\n\tvar MousewheelZoom = Class.extend({\n\t init: function(chart, options) {\n\n\t this.chart = chart;\n\t this.options = deepExtend({}, this.options, options);\n\t },\n\n\t updateRanges: function(delta) {\n\t var lock = (this.options.lock || \"\").toLowerCase();\n\t var axisRanges = [];\n\t var axes = this.chart._plotArea.axes;\n\n\t for (var idx = 0; idx < axes.length; idx++) {\n\t var axis = axes[idx];\n\t var vertical = axis.options.vertical;\n\n\t if (!(lock === X && !vertical) && !(lock === Y && vertical) && axis.zoomRange) {\n\t var range = axis.zoomRange(-delta);\n\n\t if (range) {\n\t axisRanges.push({\n\t axis: axis,\n\t range: range\n\t });\n\t }\n\t }\n\t }\n\n\t this.axisRanges = axisRanges;\n\t return toChartAxisRanges(axisRanges);\n\t },\n\n\t zoom: function() {\n\t var axisRanges = this.axisRanges;\n\t var plotArea = this.chart._plotArea;\n\n\t if (axisRanges && axisRanges.length && plotArea.updateAxisOptions) {\n\t for (var idx = 0; idx < axisRanges.length; idx++) {\n\t var axisRange = axisRanges[idx];\n\t plotArea.updateAxisOptions(axisRange.axis, axisRange.range);\n\t }\n\t plotArea.redraw(plotArea.panes);\n\t }\n\t },\n\n\t destroy: function() {\n\t delete this.chart;\n\t }\n\t});\n\n\tvar LegendLayout = ChartElement.extend({\n\t init: function(options, chartService) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.chartService = chartService;\n\t },\n\n\t render: function() {\n\t var ref = this;\n\t var children = ref.children;\n\t var options = ref.options;\n\t var vertical = options.vertical;\n\n\t this.visual = new drawing.Layout(null, {\n\t spacing: vertical ? 0 : options.spacing,\n\t lineSpacing: vertical ? options.spacing : 0,\n\t orientation: vertical ? \"vertical\" : \"horizontal\",\n\t reverse: options.rtl,\n\t alignItems: vertical ? \"start\" : \"center\"\n\t });\n\n\t for (var idx = 0; idx < children.length; idx++) {\n\t var legendItem = children[idx];\n\t legendItem.reflow(new Box());\n\t legendItem.renderVisual();\n\t }\n\t },\n\n\t reflow: function(box) {\n\t this.visual.rect(box.toRect());\n\t this.visual.reflow();\n\t var bbox = this.visual.clippedBBox();\n\n\t if (bbox) {\n\t this.box = dataviz.rectToBox(bbox);\n\t } else {\n\t this.box = new Box();\n\t }\n\t },\n\n\t renderVisual: function() {\n\t this.addVisual();\n\t },\n\n\t createVisual: function() {}\n\t});\n\n\tvar LegendItem = BoxElement.extend({\n\t init: function(options) {\n\t BoxElement.fn.init.call(this, options);\n\n\t this.createContainer();\n\t if (!options.rtl) {\n\t this.createMarker();\n\t this.createLabel();\n\t } else {\n\t this.createLabel();\n\t this.createMarker();\n\t }\n\t },\n\n\t createContainer: function() {\n\t this.container = new dataviz.FloatElement({ vertical: false, wrap: false, align: CENTER, spacing: this.options.spacing });\n\t this.append(this.container);\n\t },\n\n\t createMarker: function() {\n\t this.container.append(new ShapeElement(this.markerOptions()));\n\t },\n\n\t markerOptions: function() {\n\t var options = this.options;\n\t var markerColor = options.markerColor;\n\t return deepExtend({}, options.markers, {\n\t background: markerColor,\n\t border: {\n\t color: markerColor\n\t }\n\t });\n\t },\n\n\t createLabel: function() {\n\t var options = this.options;\n\t var labelOptions = deepExtend({}, options.labels);\n\n\t this.container.append(new TextBox(options.text, labelOptions));\n\t },\n\n\t renderComplete: function() {\n\t BoxElement.fn.renderComplete.call(this);\n\n\t var cursor = this.options.cursor || {};\n\t var eventSink = this._itemOverlay = Path.fromRect(this.container.box.toRect(), {\n\t fill: {\n\t color: WHITE,\n\t opacity: 0\n\t },\n\t stroke: null,\n\t cursor: cursor.style || cursor\n\t });\n\n\t this.appendVisual(eventSink);\n\t },\n\n\t click: function(widget, e) {\n\t var args = this.eventArgs(e);\n\n\t if (!widget.trigger(LEGEND_ITEM_CLICK, args) && e && e.type === 'contextmenu') {\n\t e.preventDefault();\n\t }\n\t },\n\n\t over: function(widget, e) {\n\t var args = this.eventArgs(e);\n\n\t if (!widget.trigger(LEGEND_ITEM_HOVER, args)) {\n\t widget._legendItemHover(args.seriesIndex, args.pointIndex);\n\t }\n\n\t // Don't trigger point hover for legend items\n\t return true;\n\t },\n\n\t out: function(widget, e) {\n\t widget._unsetActivePoint();\n\n\t widget.trigger(LEGEND_ITEM_LEAVE, this.eventArgs(e));\n\t },\n\n\t eventArgs: function(e) {\n\t var options = this.options;\n\n\t return {\n\t element: eventElement(e),\n\t text: options.text,\n\t series: options.series,\n\t seriesIndex: options.series.index,\n\t pointIndex: options.pointIndex\n\t };\n\t },\n\n\t renderVisual: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var customVisual = options.visual;\n\n\t if (customVisual) {\n\t this.visual = customVisual({\n\t active: options.active,\n\t series: options.series,\n\t sender: this.getSender(),\n\t pointIndex: options.pointIndex,\n\t options: {\n\t markers: this.markerOptions(),\n\t labels: options.labels\n\t },\n\t createVisual: function () {\n\t this$1.createVisual();\n\t this$1.renderChildren();\n\t this$1.renderComplete();\n\n\t var defaultVisual = this$1.visual;\n\n\t delete this$1.visual;\n\n\t return defaultVisual;\n\t }\n\t });\n\t this.addVisual();\n\t } else {\n\t BoxElement.fn.renderVisual.call(this);\n\t }\n\t }\n\t});\n\n\tvar HORIZONTAL = \"horizontal\";\n\tvar POINTER = \"pointer\";\n\tvar CUSTOM = \"custom\";\n\n\tvar Legend = ChartElement.extend({\n\t init: function(options, chartService) {\n\t if (chartService === void 0) { chartService = {}; }\n\n\t ChartElement.fn.init.call(this, options);\n\n\t this.chartService = chartService;\n\n\t if (!inArray(this.options.position, [ TOP, RIGHT, BOTTOM, LEFT, CUSTOM ])) {\n\t this.options.position = RIGHT;\n\t }\n\n\t this.createContainer();\n\n\t this.createItems();\n\t },\n\n\t createContainer: function() {\n\t var options = this.options;\n\t var position = options.position;\n\t var userAlign = options.align;\n\t var align = position;\n\t var vAlign = CENTER;\n\n\t if (position === CUSTOM) {\n\t align = LEFT;\n\t } else if (inArray(position, [ TOP, BOTTOM ])) {\n\t if (userAlign === \"start\") {\n\t align = LEFT;\n\t } else if (userAlign === \"end\") {\n\t align = RIGHT;\n\t } else {\n\t align = CENTER;\n\t }\n\t vAlign = position;\n\t } else if (userAlign) {\n\t if (userAlign === \"start\") {\n\t vAlign = TOP;\n\t } else if (userAlign === \"end\") {\n\t vAlign = BOTTOM;\n\t }\n\t }\n\n\t this.container = new BoxElement({\n\t margin: options.margin,\n\t padding: options.padding,\n\t background: options.background,\n\t border: options.border,\n\t vAlign: vAlign,\n\t align: align,\n\t zIndex: options.zIndex,\n\t shrinkToFit: true\n\t });\n\n\t this.append(this.container);\n\t },\n\n\t createItems: function() {\n\t var chartService = this.getService();\n\t var options = this.options;\n\t var vertical = this.isVertical();\n\t var innerElement = new LegendLayout({\n\t vertical: vertical,\n\t spacing: options.spacing,\n\t rtl: chartService.rtl\n\t }, chartService);\n\t var items = options.items;\n\n\t if (options.reverse) {\n\t items = items.slice(0).reverse();\n\t }\n\n\t var count = items.length;\n\n\t for (var i = 0; i < count; i++) {\n\t var item = items[i];\n\n\t innerElement.append(new LegendItem(deepExtend({}, {\n\t markers: options.markers,\n\t labels: options.labels,\n\t rtl: chartService.rtl\n\t }, options.item, item)));\n\t }\n\n\t innerElement.render();\n\n\t this.container.append(innerElement);\n\t },\n\n\t isVertical: function() {\n\t var ref = this.options;\n\t var orientation = ref.orientation;\n\t var position = ref.position;\n\t var vertical = (position === CUSTOM && orientation !== HORIZONTAL) ||\n\t (defined(orientation) ? orientation !== HORIZONTAL : inArray(position, [ LEFT, RIGHT ]));\n\n\t return vertical;\n\t },\n\n\t hasItems: function() {\n\t return this.container.children[0].children.length > 0;\n\t },\n\n\t reflow: function(targetBox) {\n\t var options = this.options;\n\t var legendBox = targetBox.clone();\n\n\t if (!this.hasItems()) {\n\t this.box = legendBox;\n\t return;\n\t }\n\n\t if (options.position === CUSTOM) {\n\t this.containerCustomReflow(legendBox);\n\t this.box = legendBox;\n\t } else {\n\t this.containerReflow(legendBox);\n\t }\n\t },\n\n\t containerReflow: function(targetBox) {\n\t var ref = this;\n\t var options = ref.options;\n\t var container = ref.container;\n\t var position = options.position;\n\t var width = options.width;\n\t var height = options.height;\n\t var pos = position === TOP || position === BOTTOM ? X : Y;\n\t var vertical = this.isVertical();\n\t var alignTarget = targetBox.clone();\n\t var containerBox = targetBox.clone();\n\n\t if (position === LEFT || position === RIGHT) {\n\t containerBox.y1 = alignTarget.y1 = 0;\n\t }\n\n\t if (vertical && height) {\n\t containerBox.y2 = containerBox.y1 + height;\n\t containerBox.align(alignTarget, Y, container.options.vAlign);\n\t } else if (!vertical && width) {\n\t containerBox.x2 = containerBox.x1 + width;\n\t containerBox.align(alignTarget, X, container.options.align);\n\t }\n\n\t container.reflow(containerBox);\n\t containerBox = container.box;\n\n\t var box = containerBox.clone();\n\n\t if (options.offsetX || options.offsetY) {\n\t containerBox.translate(options.offsetX, options.offsetY);\n\t this.container.reflow(containerBox);\n\t }\n\n\t box[pos + 1] = targetBox[pos + 1];\n\t box[pos + 2] = targetBox[pos + 2];\n\n\t this.box = box;\n\t },\n\n\t containerCustomReflow: function(targetBox) {\n\t var ref = this;\n\t var options = ref.options;\n\t var container = ref.container;\n\t var offsetX = options.offsetX;\n\t var offsetY = options.offsetY;\n\t var width = options.width;\n\t var height = options.height;\n\t var vertical = this.isVertical();\n\t var containerBox = targetBox.clone();\n\n\t if (vertical && height) {\n\t containerBox.y2 = containerBox.y1 + height;\n\t } else if (!vertical && width) {\n\t containerBox.x2 = containerBox.x1 + width;\n\t }\n\t container.reflow(containerBox);\n\t containerBox = container.box;\n\n\t container.reflow(new Box(\n\t offsetX, offsetY,\n\t offsetX + containerBox.width(), offsetY + containerBox.height()\n\t ));\n\t },\n\n\t renderVisual: function() {\n\t if (this.hasItems()) {\n\t ChartElement.fn.renderVisual.call(this);\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(Legend, {\n\t position: RIGHT,\n\t items: [],\n\t offsetX: 0,\n\t offsetY: 0,\n\t margin: getSpacing(5),\n\t padding: getSpacing(5),\n\t border: {\n\t color: BLACK,\n\t width: 0\n\t },\n\t item: {\n\t cursor: POINTER,\n\t spacing: 6\n\t },\n\t spacing: 6,\n\t background: \"\",\n\t zIndex: 1,\n\t markers: {\n\t border: {\n\t width: 0\n\t },\n\t width: 15,\n\t height: 3,\n\t type: \"rect\",\n\t align: LEFT,\n\t vAlign: CENTER\n\t }\n\t});\n\n\tvar PlotAreaFactory = Class.extend({\n\t init: function() {\n\n\t this._registry = [];\n\t },\n\n\t register: function(type, seriesTypes) {\n\t this._registry.push({\n\t type: type,\n\t seriesTypes: seriesTypes\n\t });\n\t },\n\n\t create: function(srcSeries, options, chartService) {\n\t var registry = this._registry;\n\t var match = registry[0];\n\t var series;\n\n\t for (var idx = 0; idx < registry.length; idx++) {\n\t var entry = registry[idx];\n\t series = filterSeriesByType(srcSeries, entry.seriesTypes);\n\n\t if (series.length > 0) {\n\t match = entry;\n\t break;\n\t }\n\t }\n\n\t return new match.type(series, options, chartService);\n\t }\n\t});\n\n\tPlotAreaFactory.current = new PlotAreaFactory();\n\n\tvar ZOOM_ACCELERATION = 3;\n\tvar SELECTOR_HEIGHT_ADJUST = 0.1;\n\n\tfunction createDiv(className) {\n\t var element = document.createElement(\"div\");\n\t if (className) {\n\t element.className = className;\n\t }\n\n\t return element;\n\t}\n\n\tfunction closestHandle(element) {\n\t var current = element;\n\t while (current && !hasClasses(current, \"k-handle\")) {\n\t current = current.parentNode;\n\t }\n\n\t return current;\n\t}\n\n\tvar Selection = Class.extend({\n\t init: function(chart, categoryAxis, options, observer) {\n\n\t var chartElement = chart.element;\n\n\t this.options = deepExtend({}, this.options, options);\n\t this.chart = chart;\n\t this.observer = observer;\n\t this.chartElement = chartElement;\n\t this.categoryAxis = categoryAxis;\n\t this._dateAxis = this.categoryAxis instanceof dataviz.DateCategoryAxis;\n\n\t this.initOptions();\n\n\t this.visible = this.options.visible && chartElement.offsetHeight;\n\n\t if (this.visible) {\n\t this.createElements();\n\n\t this.set(this._index(this.options.from), this._index(this.options.to));\n\n\t this.bindEvents();\n\t }\n\t },\n\n\t onPane: function(pane) {\n\t return this.categoryAxis.pane === pane;\n\t },\n\n\t createElements: function() {\n\t var options = this.options;\n\t var wrapper = this.wrapper = createDiv(\"k-selector\");\n\t elementStyles(wrapper, {\n\t top: options.offset.top,\n\t left: options.offset.left,\n\t width: options.width,\n\t height: options.height,\n\t direction: 'ltr'\n\t });\n\t var selection = this.selection = createDiv(\"k-selection\");\n\t this.leftMask = createDiv(\"k-mask\");\n\t this.rightMask = createDiv(\"k-mask\");\n\n\t wrapper.appendChild(this.leftMask);\n\t wrapper.appendChild(this.rightMask);\n\t wrapper.appendChild(selection);\n\n\t selection.appendChild(createDiv(\"k-selection-bg\"));\n\n\t var leftHandle = this.leftHandle = createDiv(\"k-handle k-left-handle\");\n\t var rightHandle = this.rightHandle = createDiv(\"k-handle k-right-handle\");\n\t leftHandle.appendChild(createDiv());\n\t rightHandle.appendChild(createDiv());\n\n\t selection.appendChild(leftHandle);\n\t selection.appendChild(rightHandle);\n\n\t this.chartElement.appendChild(wrapper);\n\t var selectionStyles = elementStyles(selection, [ \"borderLeftWidth\", \"borderRightWidth\", \"height\" ]);\n\t var leftHandleHeight = elementStyles(leftHandle, \"height\").height;\n\t var rightHandleHeight = elementStyles(rightHandle, \"height\").height;\n\n\t options.selection = {\n\t border: {\n\t left: selectionStyles.borderLeftWidth,\n\t right: selectionStyles.borderRightWidth\n\t }\n\t };\n\n\t elementStyles(leftHandle, {\n\t top: (selectionStyles.height - leftHandleHeight) / 2\n\t });\n\n\t elementStyles(rightHandle, {\n\t top: (selectionStyles.height - rightHandleHeight) / 2\n\t });\n\n\t wrapper.style.cssText = wrapper.style.cssText;\n\t },\n\n\t bindEvents: function() {\n\t if (this.options.mousewheel !== false) {\n\t this._mousewheelHandler = this._mousewheel.bind(this);\n\t var obj;\n\t bindEvents(this.wrapper, ( obj = {}, obj[ MOUSEWHEEL ] = this._mousewheelHandler, obj ));\n\t }\n\n\t this._domEvents = services.DomEventsBuilder.create(this.wrapper, {\n\t stopPropagation: true, // applicable for the jQuery UserEvents\n\t start: this._start.bind(this),\n\t move: this._move.bind(this),\n\t end: this._end.bind(this),\n\t tap: this._tap.bind(this),\n\t press: this._press.bind(this),\n\t gesturestart: this._gesturestart.bind(this),\n\t gesturechange: this._gesturechange.bind(this),\n\t gestureend: this._gestureend.bind(this)\n\t });\n\t },\n\n\t initOptions: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var categoryAxis = ref.categoryAxis;\n\t var box = categoryAxis.pane.chartsBox();\n\t var intlService = this.chart.chartService.intl;\n\n\t if (this._dateAxis) {\n\t deepExtend(options, {\n\t min: parseDate(intlService, options.min),\n\t max: parseDate(intlService, options.max),\n\t from: parseDate(intlService, options.from),\n\t to: parseDate(intlService, options.to)\n\t });\n\t }\n\n\t var ref$1 = elementStyles(this.chartElement, [ \"paddingLeft\", \"paddingTop\" ]);\n\t var paddingLeft = ref$1.paddingLeft;\n\t var paddingTop = ref$1.paddingTop;\n\n\t this.options = deepExtend({}, {\n\t width: box.width(),\n\t height: box.height() + SELECTOR_HEIGHT_ADJUST, //workaround for sub-pixel hover on the paths in chrome\n\t padding: {\n\t left: paddingLeft,\n\t top: paddingTop\n\t },\n\t offset: {\n\t left: box.x1 + paddingLeft,\n\t top: box.y1 + paddingTop\n\t },\n\t from: options.min,\n\t to: options.max\n\t }, options);\n\t },\n\n\t destroy: function() {\n\t if (this._domEvents) {\n\t this._domEvents.destroy();\n\t delete this._domEvents;\n\t }\n\n\t clearTimeout(this._mwTimeout);\n\t this._state = null;\n\n\t if (this.wrapper) {\n\t if (this._mousewheelHandler) {\n\t var obj;\n\t unbindEvents(this.wrapper, ( obj = {}, obj[ MOUSEWHEEL ] = this._mousewheelHandler, obj ));\n\t this._mousewheelHandler = null;\n\t }\n\t this.chartElement.removeChild(this.wrapper);\n\t this.wrapper = null;\n\t }\n\t },\n\n\t _rangeEventArgs: function(range) {\n\n\t return {\n\t axis: this.categoryAxis.options,\n\t from: this._value(range.from),\n\t to: this._value(range.to)\n\t };\n\t },\n\n\t _start: function(e) {\n\t var options = this.options;\n\t var target = eventElement(e);\n\n\t if (this._state || !target) {\n\t return;\n\t }\n\n\t this.chart._unsetActivePoint();\n\t this._state = {\n\t moveTarget: closestHandle(target) || target,\n\t startLocation: e.x ? e.x.location : 0,\n\t range: {\n\t from: this._index(options.from),\n\t to: this._index(options.to)\n\t }\n\t };\n\n\t var args = this._rangeEventArgs({\n\t from: this._index(options.from),\n\t to: this._index(options.to)\n\t });\n\n\t if (this.trigger(SELECT_START, args)) {\n\t this._state = null;\n\t }\n\t },\n\n\t _press: function(e) {\n\t var handle;\n\t if (this._state) {\n\t handle = this._state.moveTarget;\n\t } else {\n\t handle = closestHandle(eventElement(e));\n\t }\n\t if (handle) {\n\t dataviz.addClass(handle, \"k-handle-active\");\n\t }\n\t },\n\n\t _move: function(e) {\n\t if (!this._state) {\n\t return;\n\t }\n\n\t var ref = this;\n\t var state = ref._state;\n\t var options = ref.options;\n\t var categoryAxis = ref.categoryAxis;\n\t var range = state.range;\n\t var target = state.moveTarget;\n\t var reverse = categoryAxis.options.reverse;\n\t var from = this._index(options.from);\n\t var to = this._index(options.to);\n\t var min = this._index(options.min);\n\t var max = this._index(options.max);\n\t var delta = state.startLocation - e.x.location;\n\t var oldRange = { from: range.from, to: range.to };\n\t var span = range.to - range.from;\n\t var scale = elementStyles(this.wrapper, \"width\").width / (categoryAxis.categoriesCount() - 1);\n\t var offset = Math.round(delta / scale) * (reverse ? -1 : 1);\n\n\t if (!target) {\n\t return;\n\t }\n\n\t var leftHandle = hasClasses(target, \"k-left-handle\");\n\t var rightHandle = hasClasses(target, \"k-right-handle\");\n\n\t if (hasClasses(target, \"k-selection k-selection-bg\")) {\n\t range.from = Math.min(\n\t Math.max(min, from - offset),\n\t max - span\n\t );\n\t range.to = Math.min(\n\t range.from + span,\n\t max\n\t );\n\t } else if ((leftHandle && !reverse) || (rightHandle && reverse)) {\n\t range.from = Math.min(\n\t Math.max(min, from - offset),\n\t max - 1\n\t );\n\t range.to = Math.max(range.from + 1, range.to);\n\t } else if ((leftHandle && reverse) || (rightHandle && !reverse)) {\n\t range.to = Math.min(\n\t Math.max(min + 1, to - offset),\n\t max\n\t );\n\t range.from = Math.min(range.to - 1, range.from);\n\t }\n\n\t if (range.from !== oldRange.from || range.to !== oldRange.to) {\n\t this.move(range.from, range.to);\n\t this.trigger(SELECT, this._rangeEventArgs(range));\n\t }\n\t },\n\n\t _end: function() {\n\t if (this._state) {\n\t var moveTarget = this._state.moveTarget;\n\t if (moveTarget) {\n\t dataviz.removeClass(moveTarget, \"k-handle-active\");\n\t }\n\n\t var range = this._state.range;\n\t this.set(range.from, range.to);\n\t this.trigger(SELECT_END, this._rangeEventArgs(range));\n\n\t delete this._state;\n\t }\n\t },\n\n\t _tap: function(e) {\n\t var ref = this;\n\t var options = ref.options;\n\t var categoryAxis = ref.categoryAxis;\n\t var coords = this.chart._eventCoordinates(e);\n\t var categoryIx = categoryAxis.pointCategoryIndex(new Point(coords.x, categoryAxis.box.y1));\n\t var from = this._index(options.from);\n\t var to = this._index(options.to);\n\t var min = this._index(options.min);\n\t var max = this._index(options.max);\n\t var span = to - from;\n\t var mid = from + span / 2;\n\t var range = {};\n\t var rightClick = e.event.which === 3;\n\t var offset = Math.round(mid - categoryIx);\n\n\t if (this._state || rightClick) {\n\t return;\n\t }\n\n\t this.chart._unsetActivePoint();\n\n\t if (!categoryAxis.options.justified) {\n\t offset--;\n\t }\n\n\t range.from = Math.min(\n\t Math.max(min, from - offset),\n\t max - span\n\t );\n\n\t range.to = Math.min(range.from + span, max);\n\n\t this._start(e);\n\t if (this._state) {\n\t this._state.range = range;\n\t this.trigger(SELECT, this._rangeEventArgs(range));\n\t this._end();\n\t }\n\t },\n\n\t _mousewheel: function(e) {\n\t var this$1 = this;\n\n\t var delta = dataviz.mousewheelDelta(e);\n\n\t this._start({ target: this.selection });\n\n\t if (this._state) {\n\t var range = this._state.range;\n\n\t e.preventDefault();\n\t e.stopPropagation();\n\n\t if (Math.abs(delta) > 1) {\n\t delta *= ZOOM_ACCELERATION;\n\t }\n\n\t if (this.options.mousewheel.reverse) {\n\t delta *= -1;\n\t }\n\n\t if (this.expand(delta)) {\n\t this.trigger(SELECT, {\n\t axis: this.categoryAxis.options,\n\t delta: delta,\n\t originalEvent: e,\n\t from: this._value(range.from),\n\t to: this._value(range.to)\n\t });\n\t }\n\n\t if (this._mwTimeout) {\n\t clearTimeout(this._mwTimeout);\n\t }\n\n\t this._mwTimeout = setTimeout(function () {\n\t this$1._end();\n\t }, MOUSEWHEEL_DELAY);\n\t }\n\t },\n\n\t _gesturestart: function(e) {\n\t var options = this.options;\n\n\t this._state = {\n\t range: {\n\t from: this._index(options.from),\n\t to: this._index(options.to)\n\t }\n\t };\n\t var args = this._rangeEventArgs(this._state.range);\n\n\t if (this.trigger(SELECT_START, args)) {\n\t this._state = null;\n\t } else {\n\t e.preventDefault();\n\t }\n\t },\n\n\t _gestureend: function() {\n\t if (this._state) {\n\t this.trigger(SELECT_END, this._rangeEventArgs(this._state.range));\n\t delete this._state;\n\t }\n\t },\n\n\t _gesturechange: function(e) {\n\t var ref = this;\n\t var chart = ref.chart;\n\t var state = ref._state;\n\t var options = ref.options;\n\t var categoryAxis = ref.categoryAxis;\n\t var range = state.range;\n\t var p0 = chart._toModelCoordinates(e.touches[0].x.location).x;\n\t var p1 = chart._toModelCoordinates(e.touches[1].x.location).x;\n\t var left = Math.min(p0, p1);\n\t var right = Math.max(p0, p1);\n\n\t e.preventDefault();\n\n\t range.from = categoryAxis.pointCategoryIndex(new Point(left)) || options.min;\n\n\t range.to = categoryAxis.pointCategoryIndex(new Point(right)) || options.max;\n\n\t this.move(range.from, range.to);\n\n\t this.trigger(SELECT, this._rangeEventArgs(range));\n\t },\n\n\t _index: function(value) {\n\t var index = value;\n\n\t if (value instanceof Date) {\n\t index = this.categoryAxis.categoryIndex(value);\n\t }\n\n\t return index;\n\t },\n\n\t _value: function(index) {\n\t var value = index;\n\t if (this._dateAxis) {\n\t value = this.categoryAxis.categoryAt(index);\n\t if (value > this.options.max) {\n\t value = this.options.max;\n\t }\n\t }\n\n\t return value;\n\t },\n\n\t _slot: function(value) {\n\t var categoryAxis = this.categoryAxis;\n\t var index = this._index(value);\n\n\t return categoryAxis.getSlot(index, index, true);\n\t },\n\n\t move: function(from, to) {\n\t var options = this.options;\n\t var reverse = this.categoryAxis.options.reverse;\n\t var offset = options.offset;\n\t var padding = options.padding;\n\t var border = options.selection.border;\n\t var left = reverse ? to : from;\n\t var right = reverse ? from : to;\n\t var edge = 'x' + (reverse ? 2 : 1);\n\n\t var box = this._slot(left);\n\t var leftMaskWidth = round(box[edge] - offset.left + padding.left);\n\n\t elementStyles(this.leftMask, {\n\t width: leftMaskWidth\n\t });\n\t elementStyles(this.selection, {\n\t left: leftMaskWidth\n\t });\n\n\t box = this._slot(right);\n\n\t var rightMaskWidth = round(options.width - (box[edge] - offset.left + padding.left));\n\t elementStyles(this.rightMask, {\n\t width: rightMaskWidth\n\t });\n\n\t var distance = options.width - rightMaskWidth;\n\t if (distance !== options.width) {\n\t distance += border.right;\n\t }\n\n\t elementStyles(this.rightMask, {\n\t left: distance\n\t });\n\t elementStyles(this.selection, {\n\t width: Math.max(options.width - (leftMaskWidth + rightMaskWidth) - border.right, 0)\n\t });\n\t },\n\n\t set: function(from, to) {\n\t var options = this.options;\n\t var min = this._index(options.min);\n\t var max = this._index(options.max);\n\t var fromValue = limitValue(this._index(from), min, max);\n\t var toValue = limitValue(this._index(to), fromValue + 1, max);\n\n\t if (options.visible) {\n\t this.move(fromValue, toValue);\n\t }\n\n\t options.from = this._value(fromValue);\n\t options.to = this._value(toValue);\n\t },\n\n\t expand: function(delta) {\n\t var options = this.options;\n\t var min = this._index(options.min);\n\t var max = this._index(options.max);\n\t var zDir = options.mousewheel.zoom;\n\t var from = this._index(options.from);\n\t var to = this._index(options.to);\n\t var range = { from: from, to: to };\n\t var oldRange = deepExtend({}, range);\n\n\t if (this._state) {\n\t range = this._state.range;\n\t }\n\n\t if (zDir !== RIGHT) {\n\t range.from = limitValue(\n\t limitValue(from - delta, 0, to - 1),\n\t min, max\n\t );\n\t }\n\n\t if (zDir !== LEFT) {\n\t range.to = limitValue(\n\t limitValue(to + delta, range.from + 1, max),\n\t min,\n\t max\n\t );\n\t }\n\n\t if (range.from !== oldRange.from || range.to !== oldRange.to) {\n\t this.set(range.from, range.to);\n\t return true;\n\t }\n\t },\n\n\t trigger: function(name, args) {\n\t return (this.observer || this.chart).trigger(name, args);\n\t }\n\t});\n\n\tsetDefaultOptions(Selection, {\n\t visible: true,\n\t mousewheel: {\n\t zoom: \"both\"\n\t },\n\t min: MIN_VALUE,\n\t max: MAX_VALUE\n\t});\n\n\tvar Tooltip = BaseTooltip.extend({\n\t show: function(point) {\n\t if (!point || !point.tooltipAnchor || (this._current && this._current === point)) {\n\t return;\n\t }\n\n\t var options = deepExtend({}, this.options, point.options.tooltip);\n\t var anchor = point.tooltipAnchor();\n\n\t if (anchor) {\n\t this._current = point;\n\t BaseTooltip.fn.show.call(this, {\n\t point: point,\n\t anchor: anchor\n\t }, options, point);\n\t } else {\n\t this.hide();\n\t }\n\t },\n\n\t hide: function() {\n\t delete this._current;\n\t BaseTooltip.fn.hide.call(this);\n\t }\n\t});\n\n\tvar SharedTooltip = BaseTooltip.extend({\n\t init: function(plotArea, options) {\n\t BaseTooltip.fn.init.call(this, plotArea.chartService, options);\n\n\t this.plotArea = plotArea;\n\t this.formatService = plotArea.chartService.format;\n\t },\n\n\t showAt: function(points, coords) {\n\t var tooltipPoints = grep(points, function(point) {\n\t var tooltip = point.series.tooltip;\n\t var excluded = tooltip && tooltip.visible === false;\n\n\t return !excluded;\n\t });\n\n\t if (tooltipPoints.length > 0) {\n\t var point = tooltipPoints[0];\n\t var slot = this.plotArea.categoryAxis.getSlot(point.categoryIx);\n\n\t var anchor = coords ? this._slotAnchor(coords, slot) : this._defaultAnchor(point, slot);\n\n\t this.show({\n\t anchor: anchor,\n\t shared: true,\n\t points: points,\n\t category: point.category,\n\t categoryText: this.formatService.auto(this.options.categoryFormat, point.category),\n\t series: this.plotArea.series\n\t }, this.options);\n\t }\n\t },\n\n\t _slotAnchor: function(point, slot) {\n\t var axis = this.plotArea.categoryAxis;\n\t var align = {\n\t horizontal: \"left\",\n\t vertical: \"center\"\n\t };\n\n\t if (!axis.options.vertical) {\n\t point.x = slot.center().x;\n\t }\n\n\t return {\n\t point: point,\n\t align: align\n\t };\n\t },\n\n\t _defaultAnchor: function(point, slot) {\n\t var box = point.owner.pane.chartsBox();\n\t var vertical = this.plotArea.categoryAxis.options.vertical;\n\t var center = box.center();\n\t var slotCenter = slot.center();\n\t var align = {\n\t horizontal: \"center\",\n\t vertical: \"center\"\n\t };\n\n\t var centerPoint;\n\t if (vertical) {\n\t centerPoint = new Point(center.x, slotCenter.y);\n\t } else {\n\t centerPoint = new Point(slotCenter.x, center.y);\n\t }\n\n\t return {\n\t point: centerPoint,\n\t align: align\n\t };\n\t }\n\t});\n\n\tsetDefaultOptions(SharedTooltip, {\n\t categoryFormat: '{0:d}'\n\t});\n\n\tvar BarChartAnimation = Animation.extend({\n\t setup: function() {\n\t var ref = this;\n\t var element = ref.element;\n\t var options = ref.options;\n\t var bbox = element.bbox();\n\n\t if (bbox) {\n\t this.origin = options.origin;\n\t var axis = options.vertical ? Y : X;\n\n\t var fromScale = this.fromScale = new GeometryPoint(1, 1);\n\t fromScale[axis] = START_SCALE;\n\n\t element.transform(transform()\n\t .scale(fromScale.x, fromScale.y)\n\t );\n\t } else {\n\t this.abort();\n\t }\n\t },\n\n\t step: function(pos) {\n\t var scaleX = dataviz.interpolateValue(this.fromScale.x, 1, pos);\n\t var scaleY = dataviz.interpolateValue(this.fromScale.y, 1, pos);\n\n\t this.element.transform(transform()\n\t .scale(scaleX, scaleY, this.origin)\n\t );\n\t },\n\n\t abort: function() {\n\t Animation.fn.abort.call(this);\n\t this.element.transform(null);\n\t }\n\t});\n\n\tsetDefaultOptions(BarChartAnimation, {\n\t duration: INITIAL_ANIMATION_DURATION\n\t});\n\n\tAnimationFactory.current.register(BAR, BarChartAnimation);\n\n\tvar BubbleAnimation = Animation.extend({\n\t setup: function() {\n\t var center = this.center = this.element.bbox().center();\n\t this.element.transform(transform()\n\t .scale(START_SCALE, START_SCALE, center)\n\t );\n\t },\n\n\t step: function(pos) {\n\t this.element.transform(transform()\n\t .scale(pos, pos, this.center)\n\t );\n\t }\n\t});\n\n\tsetDefaultOptions(BubbleAnimation, {\n\t easing: \"easeOutElastic\"\n\t});\n\n\tAnimationFactory.current.register(BUBBLE, BubbleAnimation);\n\n\tvar FadeInAnimation = Animation.extend({\n\t setup: function() {\n\t this.fadeTo = this.element.opacity();\n\t this.element.opacity(0);\n\t },\n\n\t step: function(pos) {\n\t this.element.opacity(pos * this.fadeTo);\n\t }\n\t});\n\n\tsetDefaultOptions(FadeInAnimation, {\n\t duration: 200,\n\t easing: \"linear\"\n\t});\n\n\tAnimationFactory.current.register(FADEIN, FadeInAnimation);\n\n\tvar PieAnimation = Animation.extend({\n\t setup: function() {\n\t this.element.transform(transform()\n\t .scale(START_SCALE, START_SCALE, this.options.center)\n\t );\n\t },\n\n\t step: function(pos) {\n\t this.element.transform(transform()\n\t .scale(pos, pos, this.options.center)\n\t );\n\t }\n\t});\n\n\tsetDefaultOptions(PieAnimation, {\n\t easing: \"easeOutElastic\",\n\t duration: INITIAL_ANIMATION_DURATION\n\t});\n\n\tAnimationFactory.current.register(PIE, PieAnimation);\n\n\tvar ScatterLineChart = ScatterChart.extend({\n\t render: function() {\n\t ScatterChart.fn.render.call(this);\n\n\t this.renderSegments();\n\t },\n\n\t createSegment: function(linePoints, currentSeries, seriesIx) {\n\t var style = currentSeries.style;\n\t var pointType;\n\n\t if (style === SMOOTH) {\n\t pointType = SplineSegment;\n\t } else {\n\t pointType = LineSegment;\n\t }\n\n\t return new pointType(linePoints, currentSeries, seriesIx);\n\t },\n\n\t animationPoints: function() {\n\t var points = ScatterChart.fn.animationPoints.call(this);\n\t return points.concat(this._segments);\n\t },\n\n\t createMissingValue: function(value, missingValues) {\n\t if (missingValues === ZERO) {\n\t var missingValue = {\n\t x: value.x,\n\t y: value.y\n\t };\n\t if (!hasValue(missingValue.x)) {\n\t missingValue.x = 0;\n\t }\n\t if (!hasValue(missingValue.y)) {\n\t missingValue.y = 0;\n\t }\n\t return missingValue;\n\t }\n\t }\n\t});\n\n\tdeepExtend(ScatterLineChart.prototype, LineChartMixin);\n\n\tvar XYPlotArea = PlotAreaBase.extend({\n\t initFields: function() {\n\t this.namedXAxes = {};\n\t this.namedYAxes = {};\n\n\t this.xAxisRangeTracker = new AxisGroupRangeTracker();\n\t this.yAxisRangeTracker = new AxisGroupRangeTracker();\n\t },\n\n\t render: function(panes) {\n\t var this$1 = this;\n\t if (panes === void 0) { panes = this.panes; }\n\n\t var seriesByPane = this.groupSeriesByPane();\n\n\t for (var i = 0; i < panes.length; i++) {\n\t var pane = panes[i];\n\t var paneSeries = seriesByPane[pane.options.name || \"default\"] || [];\n\t this$1.addToLegend(paneSeries);\n\t var filteredSeries = this$1.filterVisibleSeries(paneSeries);\n\n\t if (!filteredSeries) {\n\t continue;\n\t }\n\n\t this$1.createScatterChart(\n\t filterSeriesByType(filteredSeries, SCATTER),\n\t pane\n\t );\n\n\t this$1.createScatterLineChart(\n\t filterSeriesByType(filteredSeries, SCATTER_LINE),\n\t pane\n\t );\n\n\t this$1.createBubbleChart(\n\t filterSeriesByType(filteredSeries, BUBBLE),\n\t pane\n\t );\n\t }\n\n\t this.createAxes(panes);\n\t },\n\n\t appendChart: function(chart, pane) {\n\t this.xAxisRangeTracker.update(chart.xAxisRanges);\n\t this.yAxisRangeTracker.update(chart.yAxisRanges);\n\n\t PlotAreaBase.fn.appendChart.call(this, chart, pane);\n\t },\n\n\t removeAxis: function(axis) {\n\t var axisName = axis.options.name;\n\n\t PlotAreaBase.fn.removeAxis.call(this, axis);\n\n\t if (axis.options.vertical) {\n\t this.yAxisRangeTracker.reset(axisName);\n\t delete this.namedYAxes[axisName];\n\t } else {\n\t this.xAxisRangeTracker.reset(axisName);\n\t delete this.namedXAxes[axisName];\n\t }\n\n\t if (axis === this.axisX) {\n\t delete this.axisX;\n\t }\n\n\t if (axis === this.axisY) {\n\t delete this.axisY;\n\t }\n\t },\n\n\t seriesPaneName: function(series) {\n\t var options = this.options;\n\t var xAxisName = series.xAxis;\n\t var xAxisOptions = [].concat(options.xAxis);\n\t var xAxis = grep(xAxisOptions, function(a) { return a.name === xAxisName; })[0];\n\t var yAxisName = series.yAxis;\n\t var yAxisOptions = [].concat(options.yAxis);\n\t var yAxis = grep(yAxisOptions, function(a) { return a.name === yAxisName; })[0];\n\t var panes = options.panes || [ {} ];\n\t var defaultPaneName = panes[0].name || \"default\";\n\t var paneName = (xAxis || {}).pane || (yAxis || {}).pane || defaultPaneName;\n\n\t return paneName;\n\t },\n\n\t createScatterChart: function(series, pane) {\n\t if (series.length > 0) {\n\t this.appendChart(\n\t new ScatterChart(this, { series: series, clip: pane.options.clip }),\n\t pane\n\t );\n\t }\n\t },\n\n\t createScatterLineChart: function(series, pane) {\n\t if (series.length > 0) {\n\t this.appendChart(\n\t new ScatterLineChart(this, { series: series, clip: pane.options.clip }),\n\t pane\n\t );\n\t }\n\t },\n\n\t createBubbleChart: function(series, pane) {\n\t if (series.length > 0) {\n\t this.appendChart(\n\t new BubbleChart(this, { series: series, clip: pane.options.clip }),\n\t pane\n\t );\n\t }\n\t },\n\n\t createXYAxis: function(options, vertical, axisIndex) {\n\t var axisName = options.name;\n\t var namedAxes = vertical ? this.namedYAxes : this.namedXAxes;\n\t var tracker = vertical ? this.yAxisRangeTracker : this.xAxisRangeTracker;\n\t var axisOptions = deepExtend({ reverse: !vertical && this.chartService.rtl }, options, { vertical: vertical });\n\t var isLog = equalsIgnoreCase(axisOptions.type, LOGARITHMIC);\n\t var defaultRange = tracker.query();\n\t var defaultAxisRange = isLog ? { min: 0.1, max: 1 } : { min: 0, max: 1 };\n\t var range = tracker.query(axisName) || defaultRange || defaultAxisRange;\n\t var typeSamples = [ axisOptions.min, axisOptions.max ];\n\t var series = this.series;\n\n\t for (var seriesIx = 0; seriesIx < series.length; seriesIx++) {\n\t var currentSeries = series[seriesIx];\n\t var seriesAxisName = currentSeries[vertical ? \"yAxis\" : \"xAxis\"];\n\t if ((seriesAxisName === axisOptions.name) || (axisIndex === 0 && !seriesAxisName)) {\n\t var firstPointValue = SeriesBinder.current.bindPoint(currentSeries, 0).valueFields;\n\t typeSamples.push(firstPointValue[vertical ? \"y\" : \"x\"]);\n\n\t break;\n\t }\n\t }\n\n\t if (axisIndex === 0 && defaultRange) {\n\t range.min = Math.min(range.min, defaultRange.min);\n\t range.max = Math.max(range.max, defaultRange.max);\n\t }\n\n\t var inferredDate;\n\n\t for (var i = 0; i < typeSamples.length; i++) {\n\t if (typeSamples[i] instanceof Date) {\n\t inferredDate = true;\n\t break;\n\t }\n\t }\n\n\t var axisType;\n\t if (equalsIgnoreCase(axisOptions.type, DATE) || (!axisOptions.type && inferredDate)) {\n\t axisType = dataviz.DateValueAxis;\n\t } else if (isLog) {\n\t axisType = dataviz.LogarithmicAxis;\n\t } else {\n\t axisType = dataviz.NumericAxis;\n\t }\n\n\t var axis = new axisType(range.min, range.max, axisOptions, this.chartService);\n\t axis.axisIndex = axisIndex;\n\n\t if (axisName) {\n\t if (namedAxes[axisName]) {\n\t throw new Error(((vertical ? \"Y\" : \"X\") + \" axis with name \" + axisName + \" is already defined\"));\n\t }\n\t namedAxes[axisName] = axis;\n\t }\n\n\t this.appendAxis(axis);\n\n\t return axis;\n\t },\n\n\t createAxes: function(panes) {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var xAxesOptions = [].concat(options.xAxis);\n\t var xAxes = [];\n\t var yAxesOptions = [].concat(options.yAxis);\n\t var yAxes = [];\n\n\t for (var idx = 0; idx < xAxesOptions.length; idx++) {\n\t var axisPane = this$1.findPane(xAxesOptions[idx].pane);\n\t if (inArray(axisPane, panes)) {\n\t xAxes.push(this$1.createXYAxis(xAxesOptions[idx], false, idx));\n\t }\n\t }\n\n\t for (var idx$1 = 0; idx$1 < yAxesOptions.length; idx$1++) {\n\t var axisPane$1 = this$1.findPane(yAxesOptions[idx$1].pane);\n\t if (inArray(axisPane$1, panes)) {\n\t yAxes.push(this$1.createXYAxis(yAxesOptions[idx$1], true, idx$1));\n\t }\n\t }\n\n\t this.axisX = this.axisX || xAxes[0];\n\t this.axisY = this.axisY || yAxes[0];\n\t },\n\n\t _dispatchEvent: function(chart, e, eventType) {\n\t var coords = chart._eventCoordinates(e);\n\t var point = new Point(coords.x, coords.y);\n\t var allAxes = this.axes;\n\t var length = allAxes.length;\n\t var xValues = [];\n\t var yValues = [];\n\n\t for (var i = 0; i < length; i++) {\n\t var axis = allAxes[i];\n\t var values = axis.options.vertical ? yValues : xValues;\n\t var currentValue = axis.getValue(point);\n\t if (currentValue !== null) {\n\t values.push(currentValue);\n\t }\n\t }\n\n\t if (xValues.length > 0 && yValues.length > 0) {\n\t chart.trigger(eventType, {\n\t element: eventElement(e),\n\t originalEvent: e,\n\t x: singleItemOrArray(xValues),\n\t y: singleItemOrArray(yValues)\n\t });\n\t }\n\t },\n\n\t updateAxisOptions: function(axis, options) {\n\t var vertical = axis.options.vertical;\n\t var axes = this.groupAxes(this.panes);\n\t var index = (vertical ? axes.y : axes.x).indexOf(axis);\n\n\t updateAxisOptions$1(this.options, index, vertical, options);\n\t updateAxisOptions$1(this.originalOptions, index, vertical, options);\n\t }\n\t});\n\n\tfunction updateAxisOptions$1(targetOptions, axisIndex, vertical, options) {\n\t var axisOptions = ([].concat(vertical ? targetOptions.yAxis : targetOptions.xAxis))[axisIndex];\n\t deepExtend(axisOptions, options);\n\t}\n\n\tsetDefaultOptions(XYPlotArea, {\n\t xAxis: {},\n\t yAxis: {}\n\t});\n\n\tdeepExtend(XYPlotArea.prototype, PlotAreaEventsMixin);\n\n\tvar PieSegment = ChartElement.extend({\n\t init: function(value, sector, options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.value = value;\n\t this.sector = sector;\n\t },\n\n\t render: function() {\n\t var labels = this.options.labels;\n\t var chartService = this.owner.chartService;\n\t var labelText = this.value;\n\n\t if (this._rendered || this.visible === false) {\n\t return;\n\t }\n\t this._rendered = true;\n\n\t var labelTemplate = getTemplate(labels);\n\t var pointData = this.pointData();\n\n\t if (labelTemplate) {\n\t labelText = labelTemplate(pointData);\n\t } else if (labels.format) {\n\t labelText = chartService.format.auto(labels.format, labelText);\n\t }\n\n\t if (labels.visible && (labelText || labelText === 0)) {\n\t if (labels.position === CENTER || labels.position === INSIDE_END) {\n\t if (!labels.color) {\n\t var brightnessValue = new Color(this.options.color).percBrightness();\n\t if (brightnessValue > 180) {\n\t labels.color = BLACK;\n\t } else {\n\t labels.color = WHITE;\n\t }\n\t }\n\t if (!labels.background) {\n\t labels.background = this.options.color;\n\t }\n\t } else {\n\t var themeLabels = chartService.theme.seriesDefaults.labels;\n\t labels.color = labels.color || themeLabels.color;\n\t labels.background = labels.background || themeLabels.background;\n\t }\n\n\t this.label = new TextBox(labelText, deepExtend({}, labels, {\n\t align: CENTER,\n\t vAlign: \"\",\n\t animation: {\n\t type: FADEIN,\n\t delay: this.animationDelay\n\t }\n\t }), pointData);\n\n\t this.append(this.label);\n\t }\n\t },\n\n\t reflow: function(targetBox) {\n\t this.render();\n\t this.box = targetBox;\n\t this.reflowLabel();\n\t },\n\n\t reflowLabel: function() {\n\t var ref = this;\n\t var labelsOptions = ref.options.labels;\n\t var label = ref.label;\n\t var sector = this.sector.clone();\n\t var labelsDistance = labelsOptions.distance;\n\t var angle = sector.middle();\n\n\t if (label) {\n\t var labelHeight = label.box.height();\n\t var labelWidth = label.box.width();\n\t var lp;\n\n\t if (labelsOptions.position === CENTER) {\n\t sector.radius = Math.abs((sector.radius - labelHeight) / 2) + labelHeight;\n\t lp = sector.point(angle);\n\t label.reflow(new Box(lp.x, lp.y - labelHeight / 2, lp.x, lp.y));\n\t } else if (labelsOptions.position === INSIDE_END) {\n\t sector.radius = sector.radius - labelHeight / 2;\n\t lp = sector.point(angle);\n\t label.reflow(new Box(lp.x, lp.y - labelHeight / 2, lp.x, lp.y));\n\t } else {\n\t var x1;\n\t lp = sector.clone().expand(labelsDistance).point(angle);\n\t if (lp.x >= sector.center.x) {\n\t x1 = lp.x + labelWidth;\n\t label.orientation = RIGHT;\n\t } else {\n\t x1 = lp.x - labelWidth;\n\t label.orientation = LEFT;\n\t }\n\t label.reflow(new Box(x1, lp.y - labelHeight, lp.x, lp.y));\n\t }\n\t }\n\t },\n\n\t createVisual: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var sector = ref.sector;\n\t var options = ref.options;\n\n\t ChartElement.fn.createVisual.call(this);\n\n\t if (this.value) {\n\t if (options.visual) {\n\t var startAngle = (sector.startAngle + 180) % 360;\n\t var visual = options.visual({\n\t category: this.category,\n\t dataItem: this.dataItem,\n\t value: this.value,\n\t series: this.series,\n\t percentage: this.percentage,\n\t center: new GeometryPoint(sector.center.x, sector.center.y),\n\t radius: sector.radius,\n\t innerRadius: sector.innerRadius,\n\t startAngle: startAngle,\n\t endAngle: startAngle + sector.angle,\n\t options: options,\n\t sender: this.getSender(),\n\t createVisual: function () {\n\t var group = new Group();\n\t this$1.createSegmentVisual(group);\n\n\t return group;\n\t }\n\t });\n\n\t if (visual) {\n\t this.visual.append(visual);\n\t }\n\t } else {\n\t this.createSegmentVisual(this.visual);\n\t }\n\t }\n\t },\n\n\t createSegmentVisual: function(group) {\n\t var ref = this;\n\t var sector = ref.sector;\n\t var options = ref.options;\n\t var borderOptions = options.border || {};\n\t var border = borderOptions.width > 0 ? {\n\t stroke: {\n\t color: borderOptions.color,\n\t width: borderOptions.width,\n\t opacity: borderOptions.opacity,\n\t dashType: borderOptions.dashType\n\t }\n\t } : {};\n\t var color = options.color;\n\t var fill = {\n\t color: color,\n\t opacity: options.opacity\n\t };\n\t var visual = this.createSegment(sector, deepExtend({\n\t fill: fill,\n\t stroke: {\n\t opacity: options.opacity\n\t },\n\t zIndex: options.zIndex\n\t }, border));\n\n\t group.append(visual);\n\n\t if (hasGradientOverlay(options)) {\n\t group.append(this.createGradientOverlay(visual, {\n\t baseColor: color,\n\t fallbackFill: fill\n\t }, deepExtend({\n\t center: [ sector.center.x, sector.center.y ],\n\t innerRadius: sector.innerRadius,\n\t radius: sector.radius,\n\t userSpace: true\n\t }, options.overlay)));\n\t }\n\t },\n\n\t createSegment: function(sector, options) {\n\t if (options.singleSegment) {\n\t return new drawing.Circle(new geometry.Circle(new GeometryPoint(sector.center.x, sector.center.y), sector.radius), options);\n\t }\n\n\t return dataviz.ShapeBuilder.current.createRing(sector, options);\n\t },\n\n\t createAnimation: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var center = ref.sector.center;\n\n\t deepExtend(options, {\n\t animation: {\n\t center: [ center.x, center.y ],\n\t delay: this.animationDelay\n\t }\n\t });\n\n\t ChartElement.fn.createAnimation.call(this);\n\t },\n\n\t createHighlight: function(options) {\n\t var highlight = this.options.highlight || {};\n\t var border = highlight.border || {};\n\n\t return this.createSegment(this.sector, deepExtend({}, options, {\n\t fill: {\n\t color: highlight.color,\n\t opacity: highlight.opacity\n\t },\n\t stroke: {\n\t opacity: border.opacity,\n\t width: border.width,\n\t color: border.color\n\t }\n\t }));\n\t },\n\n\t highlightVisual: function() {\n\t return this.visual.children[0];\n\t },\n\n\t highlightVisualArgs: function() {\n\t var sector = this.sector;\n\n\t return {\n\t options: this.options,\n\t radius: sector.radius,\n\t innerRadius: sector.innerRadius,\n\t center: new GeometryPoint(sector.center.x, sector.center.y),\n\t startAngle: sector.startAngle,\n\t endAngle: sector.angle + sector.startAngle,\n\t visual: this.visual\n\t };\n\t },\n\n\t tooltipAnchor: function() {\n\t var sector = this.sector.clone().expand(TOOLTIP_OFFSET);\n\t var midAndle = sector.middle();\n\t var midPoint = sector.point(midAndle);\n\n\t return {\n\t point: midPoint,\n\t align: tooltipAlignment(midAndle + 180)\n\t };\n\t },\n\n\t formatValue: function(format) {\n\t return this.owner.formatPointValue(this, format);\n\t },\n\n\t pointData: function() {\n\t return {\n\t dataItem: this.dataItem,\n\t category: this.category,\n\t value: this.value,\n\t series: this.series,\n\t percentage: this.percentage\n\t };\n\t }\n\t});\n\n\tvar RAD_30 = round(dataviz.rad(30), DEFAULT_PRECISION);\n\tvar RAD_60 = round(dataviz.rad(60), DEFAULT_PRECISION);\n\n\tfunction tooltipAlignment(angle) {\n\t var radians = dataviz.rad(angle);\n\t var sine = round(Math.sin(radians), DEFAULT_PRECISION);\n\t var cosine = round(Math.cos(radians), DEFAULT_PRECISION);\n\n\t var horizontal;\n\t if (Math.abs(sine) > RAD_60) {\n\t horizontal = CENTER;\n\t } else if (cosine < 0) {\n\t horizontal = RIGHT;\n\t } else {\n\t horizontal = LEFT;\n\t }\n\n\t var vertical;\n\t if (Math.abs(sine) < RAD_30) {\n\t vertical = CENTER;\n\t } else if (sine < 0) {\n\t vertical = BOTTOM;\n\t } else {\n\t vertical = TOP;\n\t }\n\n\t return {\n\t horizontal: horizontal,\n\t vertical: vertical\n\t };\n\t}\n\n\tsetDefaultOptions(PieSegment, {\n\t color: WHITE,\n\t overlay: {\n\t gradient: \"roundedBevel\"\n\t },\n\t border: {\n\t width: 0.5\n\t },\n\t labels: {\n\t visible: false,\n\t distance: 35,\n\t font: datavizConstants.DEFAULT_FONT,\n\t margin: getSpacing(0.5),\n\t align: CIRCLE,\n\t zIndex: 1,\n\t position: OUTSIDE_END\n\t },\n\t animation: {\n\t type: PIE\n\t },\n\t highlight: {\n\t visible: true,\n\t border: {\n\t width: 1\n\t }\n\t },\n\t visible: true\n\t});\n\n\tdeepExtend(PieSegment.prototype, PointEventsMixin);\n\n\tvar PieChartMixin = {\n\t createLegendItem: function(value, point, options) {\n\t var legendOptions = this.options.legend || {};\n\t var labelsOptions = legendOptions.labels || {};\n\t var inactiveItems = legendOptions.inactiveItems || {};\n\t var inactiveItemsLabels = inactiveItems.labels || {};\n\n\t if (options && options.visibleInLegend !== false) {\n\t var pointVisible = options.visible !== false;\n\t var labelTemplate = pointVisible ? getTemplate(labelsOptions) :\n\t getTemplate(inactiveItemsLabels) || getTemplate(labelsOptions);\n\t var text = options.category;\n\n\t if (labelTemplate) {\n\t text = labelTemplate({\n\t text: text,\n\t series: options.series,\n\t dataItem: options.dataItem,\n\t percentage: options.percentage,\n\t value: value\n\t });\n\t }\n\n\t var itemLabelOptions, markerColor;\n\t if (pointVisible) {\n\t itemLabelOptions = {};\n\t markerColor = point.color;\n\t } else {\n\t itemLabelOptions = {\n\t color: inactiveItemsLabels.color,\n\t font: inactiveItemsLabels.font\n\t };\n\t markerColor = (inactiveItems.markers || {}).color;\n\t }\n\n\t if (hasValue(text) && text !== \"\") {\n\t this.legendItems.push({\n\t active: pointVisible,\n\t pointIndex: options.index,\n\t text: text,\n\t series: options.series,\n\t markerColor: markerColor,\n\t labels: itemLabelOptions\n\t });\n\t }\n\t }\n\t }\n\t};\n\n\tvar PIE_SECTOR_ANIM_DELAY = 70;\n\n\tvar PieChart = ChartElement.extend({\n\t init: function(plotArea, options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.plotArea = plotArea;\n\t this.chartService = plotArea.chartService;\n\t this.points = [];\n\t this.legendItems = [];\n\t this.render();\n\t },\n\n\t render: function() {\n\t this.traverseDataPoints(this.addValue.bind(this));\n\t },\n\n\t traverseDataPoints: function(callback) {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var options = ref.options;\n\t var seriesColors = ref.plotArea.options.seriesColors; if (seriesColors === void 0) { seriesColors = []; }\n\t var colorsCount = seriesColors.length;\n\t var series = options.series;\n\t var seriesCount = series.length;\n\n\t for (var seriesIx = 0; seriesIx < seriesCount; seriesIx++) {\n\t var currentSeries = series[seriesIx];\n\t var data = currentSeries.data;\n\t var ref$1 = bindSegments(currentSeries);\n\t var total = ref$1.total;\n\t var points = ref$1.points;\n\t var count = ref$1.count;\n\t var anglePerValue = 360 / total;\n\t var constantAngle = (void 0);\n\t if (!isFinite(anglePerValue)) {\n\t constantAngle = 360 / count;\n\t }\n\t var currentAngle = (void 0);\n\n\t if (defined(currentSeries.startAngle)) {\n\t currentAngle = currentSeries.startAngle;\n\t } else {\n\t currentAngle = options.startAngle;\n\t }\n\n\t if (seriesIx !== seriesCount - 1) {\n\t if (currentSeries.labels.position === OUTSIDE_END) {\n\t currentSeries.labels.position = CENTER;\n\t }\n\t }\n\n\t for (var i = 0; i < points.length; i++) {\n\t var pointData = points[i];\n\t if (!pointData) {\n\t continue;\n\t }\n\n\t var fields = pointData.fields;\n\t var value = pointData.value;\n\t var visible = pointData.visible;\n\t var angle = value !== 0 ? (constantAngle || (value * anglePerValue)) : 0;\n\t var explode = data.length !== 1 && Boolean(fields.explode);\n\n\t if (!isFunction(currentSeries.color)) {\n\t currentSeries.color = fields.color || seriesColors[i % colorsCount];\n\t }\n\n\t callback(pointData.valueFields.value, new dataviz.Ring(null, 0, 0, currentAngle, angle), {\n\t owner: this$1,\n\t category: defined(fields.category) ? fields.category : \"\",\n\t index: i,\n\t series: currentSeries,\n\t seriesIx: seriesIx,\n\t dataItem: data[i],\n\t percentage: total !== 0 ? value / total : 0,\n\t explode: explode,\n\t visibleInLegend: fields.visibleInLegend,\n\t visible: visible,\n\t zIndex: seriesCount - seriesIx,\n\t animationDelay: this$1.animationDelay(i, seriesIx, seriesCount)\n\t });\n\n\t if (visible !== false) {\n\t currentAngle += angle;\n\t }\n\t }\n\t }\n\t },\n\n\t evalSegmentOptions: function(options, value, fields) {\n\t var series = fields.series;\n\n\t evalOptions(options, {\n\t value: value,\n\t series: series,\n\t dataItem: fields.dataItem,\n\t category: fields.category,\n\t percentage: fields.percentage\n\t }, { defaults: series._defaults, excluded: [ \"data\", \"content\", \"template\", \"visual\", \"toggle\" ] });\n\t },\n\n\t addValue: function(value, sector, fields) {\n\t var segmentOptions = deepExtend({}, fields.series, { index: fields.index });\n\t this.evalSegmentOptions(segmentOptions, value, fields);\n\n\t this.createLegendItem(value, segmentOptions, fields);\n\n\t if (fields.visible === false) {\n\t return;\n\t }\n\n\t var segment = new PieSegment(value, sector, segmentOptions);\n\t $.extend(segment, fields);\n\t this.append(segment);\n\t this.points.push(segment);\n\t },\n\n\t reflow: function(targetBox) {\n\t var ref = this;\n\t var options = ref.options;\n\t var points = ref.points;\n\t var seriesConfigs = ref.seriesConfigs; if (seriesConfigs === void 0) { seriesConfigs = []; }\n\t var count = points.length;\n\t var box = targetBox.clone();\n\t var space = 5;\n\t var minWidth = Math.min(box.width(), box.height());\n\t var halfMinWidth = minWidth / 2;\n\t var defaultPadding = minWidth - minWidth * 0.85;\n\t var newBox = new Box(box.x1, box.y1, box.x1 + minWidth, box.y1 + minWidth);\n\t var newBoxCenter = newBox.center();\n\t var boxCenter = box.center();\n\t var seriesCount = options.series.length;\n\t var leftSideLabels = [];\n\t var rightSideLabels = [];\n\t var padding = valueOrDefault(options.padding, defaultPadding);\n\n\t this.targetBox = targetBox;\n\n\t padding = padding > halfMinWidth - space ? halfMinWidth - space : padding;\n\t newBox.translate(boxCenter.x - newBoxCenter.x, boxCenter.y - newBoxCenter.y);\n\n\t var radius = halfMinWidth - padding;\n\t var center = new Point(\n\t radius + newBox.x1 + padding,\n\t radius + newBox.y1 + padding\n\t );\n\n\t for (var i = 0; i < count; i++) {\n\t var segment = points[i];\n\t var sector = segment.sector;\n\t var seriesIndex = segment.seriesIx;\n\t sector.radius = radius;\n\t sector.center = center;\n\n\t if (seriesConfigs.length) {\n\t var seriesConfig = seriesConfigs[seriesIndex];\n\t sector.innerRadius = seriesConfig.innerRadius;\n\t sector.radius = seriesConfig.radius;\n\t }\n\n\t if (seriesIndex === seriesCount - 1 && segment.explode) {\n\t sector.center = sector.clone().setRadius(sector.radius * 0.15).point(sector.middle());\n\t }\n\n\t segment.reflow(newBox);\n\n\t var label = segment.label;\n\t if (label) {\n\t if (label.options.position === OUTSIDE_END) {\n\t if (seriesIndex === seriesCount - 1) {\n\t if (label.orientation === RIGHT) {\n\t rightSideLabels.push(label);\n\t } else {\n\t leftSideLabels.push(label);\n\t }\n\t }\n\t }\n\t }\n\t }\n\n\t if (leftSideLabels.length > 0) {\n\t leftSideLabels.sort(this.labelComparator(true));\n\t this.leftLabelsReflow(leftSideLabels);\n\t }\n\n\t if (rightSideLabels.length > 0) {\n\t rightSideLabels.sort(this.labelComparator(false));\n\t this.rightLabelsReflow(rightSideLabels);\n\t }\n\n\t this.box = newBox;\n\t },\n\n\t leftLabelsReflow: function(labels) {\n\t var distances = this.distanceBetweenLabels(labels);\n\n\t this.distributeLabels(distances, labels);\n\t },\n\n\t rightLabelsReflow: function(labels) {\n\t var distances = this.distanceBetweenLabels(labels);\n\n\t this.distributeLabels(distances, labels);\n\t },\n\n\t distanceBetweenLabels: function(labels) {\n\t var segment = last(this.points);\n\t var sector = segment.sector;\n\t var count = labels.length - 1;\n\t var lr = sector.radius + segment.options.labels.distance;\n\t var distances = [];\n\t var firstBox = labels[0].box;\n\t var distance = round(firstBox.y1 - (sector.center.y - lr - firstBox.height() - firstBox.height() / 2));\n\n\t distances.push(distance);\n\n\t for (var i = 0; i < count; i++) {\n\t var secondBox = labels[i + 1].box;\n\n\t firstBox = labels[i].box;\n\t distance = round(secondBox.y1 - firstBox.y2);\n\t distances.push(distance);\n\t }\n\t distance = round(sector.center.y + lr - labels[count].box.y2 - labels[count].box.height() / 2);\n\t distances.push(distance);\n\n\t return distances;\n\t },\n\n\t distributeLabels: function(distances, labels) {\n\t var this$1 = this;\n\n\t var count = distances.length;\n\t var left, right, remaining;\n\n\t for (var i = 0; i < count; i++) {\n\t remaining = -distances[i];\n\t left = right = i;\n\n\t while (remaining > 0 && (left >= 0 || right < count)) {\n\t remaining = this$1._takeDistance(distances, i, --left, remaining);\n\t remaining = this$1._takeDistance(distances, i, ++right, remaining);\n\t }\n\t }\n\n\t this.reflowLabels(distances, labels);\n\t },\n\n\t _takeDistance: function(distances, anchor, position, amount) {\n\t var result = amount;\n\t if (distances[position] > 0) {\n\t var available = Math.min(distances[position], result);\n\t result -= available;\n\t distances[position] -= available;\n\t distances[anchor] += available;\n\t }\n\n\t return result;\n\t },\n\n\t reflowLabels: function(distances, labels) {\n\t var this$1 = this;\n\n\t var segment = last(this.points);\n\t var sector = segment.sector;\n\t var labelOptions = segment.options.labels;\n\t var labelsCount = labels.length;\n\t var labelDistance = labelOptions.distance;\n\t var boxY = sector.center.y - (sector.radius + labelDistance) - labels[0].box.height();\n\t var boxX;\n\n\t distances[0] += 2;\n\t for (var i = 0; i < labelsCount; i++) {\n\t var label = labels[i];\n\t var box = label.box;\n\n\t boxY += distances[i];\n\t boxX = this$1.hAlignLabel(\n\t box.x2,\n\t sector.clone().expand(labelDistance),\n\t boxY,\n\t boxY + box.height(),\n\t label.orientation === RIGHT);\n\n\t if (label.orientation === RIGHT) {\n\t if (labelOptions.align !== CIRCLE) {\n\t boxX = sector.radius + sector.center.x + labelDistance;\n\t }\n\t label.reflow(new Box(boxX + box.width(), boxY, boxX, boxY));\n\t } else {\n\t if (labelOptions.align !== CIRCLE) {\n\t boxX = sector.center.x - sector.radius - labelDistance;\n\t }\n\t label.reflow(new Box(boxX - box.width(), boxY, boxX, boxY));\n\t }\n\n\t boxY += box.height();\n\t }\n\t },\n\n\t createVisual: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var connectors = ref.options.connectors;\n\t var points = ref.points;\n\t var count = points.length;\n\t var space = 4;\n\n\t ChartElement.fn.createVisual.call(this);\n\n\t this._connectorLines = [];\n\n\t for (var i = 0; i < count; i++) {\n\t var segment = points[i];\n\t var sector = segment.sector;\n\t var label = segment.label;\n\t var angle = sector.middle();\n\t var connectorsColor = (segment.options.connectors || {}).color || connectors.color;\n\n\t if (label) {\n\t var connectorLine = new Path({\n\t stroke: {\n\t color: connectorsColor,\n\t width: connectors.width\n\t },\n\t animation: {\n\t type: FADEIN,\n\t delay: segment.animationDelay\n\t }\n\t });\n\n\t if (label.options.position === OUTSIDE_END) {\n\t var box = label.box;\n\t var centerPoint = sector.center;\n\t var start = sector.point(angle);\n\t var middle = new Point(box.x1, box.center().y);\n\t var sr = (void 0), end = (void 0), crossing = (void 0);\n\n\t start = sector.clone().expand(connectors.padding).point(angle);\n\t connectorLine.moveTo(start.x, start.y);\n\t // TODO: Extract into a method to remove duplication\n\t if (label.orientation === RIGHT) {\n\t end = new Point(box.x1 - connectors.padding, box.center().y);\n\t crossing = intersection(centerPoint, start, middle, end);\n\t middle = new Point(end.x - space, end.y);\n\t crossing = crossing || middle;\n\t crossing.x = Math.min(crossing.x, middle.x);\n\n\t if (this$1.pointInCircle(crossing, sector.center, sector.radius + space) ||\n\t crossing.x < sector.center.x) {\n\t sr = sector.center.x + sector.radius + space;\n\t if (segment.options.labels.align !== COLUMN) {\n\t if (sr < middle.x) {\n\t connectorLine.lineTo(sr, start.y);\n\t } else {\n\t connectorLine.lineTo(start.x + space * 2, start.y);\n\t }\n\t } else {\n\t connectorLine.lineTo(sr, start.y);\n\t }\n\t connectorLine.lineTo(middle.x, end.y);\n\t } else {\n\t crossing.y = end.y;\n\t connectorLine.lineTo(crossing.x, crossing.y);\n\t }\n\t } else {\n\t end = new Point(box.x2 + connectors.padding, box.center().y);\n\t crossing = intersection(centerPoint, start, middle, end);\n\t middle = new Point(end.x + space, end.y);\n\t crossing = crossing || middle;\n\t crossing.x = Math.max(crossing.x, middle.x);\n\n\t if (this$1.pointInCircle(crossing, sector.center, sector.radius + space) ||\n\t crossing.x > sector.center.x) {\n\t sr = sector.center.x - sector.radius - space;\n\t if (segment.options.labels.align !== COLUMN) {\n\t if (sr > middle.x) {\n\t connectorLine.lineTo(sr, start.y);\n\t } else {\n\t connectorLine.lineTo(start.x - space * 2, start.y);\n\t }\n\t } else {\n\t connectorLine.lineTo(sr, start.y);\n\t }\n\t connectorLine.lineTo(middle.x, end.y);\n\t } else {\n\t crossing.y = end.y;\n\t connectorLine.lineTo(crossing.x, crossing.y);\n\t }\n\t }\n\n\t connectorLine.lineTo(end.x, end.y);\n\n\t this$1._connectorLines.push(connectorLine);\n\t this$1.visual.append(connectorLine);\n\t }\n\t }\n\t }\n\t },\n\n\t renderVisual: function() {\n\t ChartElement.fn.renderVisual.call(this);\n\n\t if (dataviz.find(this.options.series, function (options) { return options.autoFit; })) {\n\t var targetBox = this.targetBox;\n\t var pieCenter = this.box.center();\n\t var bbox = this.visual.bbox();\n\t if (!bbox) {\n\t return;\n\t }\n\n\t var bboxBottom = bbox.bottomRight();\n\n\t var scale = Math.min(\n\t (pieCenter.y - targetBox.y1) / (pieCenter.y - bbox.origin.y),\n\t (targetBox.y2 - pieCenter.y) / (bboxBottom.y - pieCenter.y),\n\t (pieCenter.x - targetBox.x1) / (pieCenter.x - bbox.origin.x),\n\t (targetBox.x2 - pieCenter.x) / (bboxBottom.x - pieCenter.x)\n\t );\n\n\t if (scale < 1) {\n\t this.visual.transform(transform().scale(scale, scale, [ pieCenter.x, pieCenter.y ]));\n\t }\n\t }\n\t },\n\n\t labelComparator: function(reverse) {\n\t var reverseValue = reverse ? -1 : 1;\n\n\t return function(a, b) {\n\t var first = (a.parent.sector.middle() + 270) % 360;\n\t var second = (b.parent.sector.middle() + 270) % 360;\n\t return (first - second) * reverseValue;\n\t };\n\t },\n\n\t hAlignLabel: function(originalX, sector, y1, y2, direction) {\n\t var radius = sector.radius;\n\t var sector_center = sector.center;\n\t var cx = sector_center.x;\n\t var cy = sector_center.y;\n\t var t = Math.min(Math.abs(cy - y1), Math.abs(cy - y2));\n\n\t if (t > radius) {\n\t return originalX;\n\t }\n\n\t return cx + Math.sqrt((radius * radius) - (t * t)) * (direction ? 1 : -1);\n\t },\n\n\t pointInCircle: function(point, center, radius) {\n\t return Math.pow(center.x - point.x, 2) + Math.pow(center.y - point.y, 2) < Math.pow(radius, 2);\n\t },\n\n\t formatPointValue: function(point, format) {\n\t return this.chartService.format.auto(format, point.value);\n\t },\n\n\t animationDelay: function(categoryIndex) {\n\t return categoryIndex * PIE_SECTOR_ANIM_DELAY;\n\t },\n\n\t stackRoot: function() {\n\t return this;\n\t }\n\t});\n\n\tfunction intersection(a1, a2, b1, b2) {\n\t var uat = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x);\n\t var ub = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);\n\n\t var result;\n\t if (ub !== 0) {\n\t var ua = (uat / ub);\n\n\t result = new Point(\n\t a1.x + ua * (a2.x - a1.x),\n\t a1.y + ua * (a2.y - a1.y)\n\t );\n\t }\n\n\t return result;\n\t}\n\n\tsetDefaultOptions(PieChart, {\n\t startAngle: 90,\n\t connectors: {\n\t width: 2,\n\t color: \"#939393\",\n\t padding: 8\n\t },\n\t inactiveItems: {\n\t markers: {},\n\t labels: {}\n\t }\n\t});\n\n\tdeepExtend(PieChart.prototype, PieChartMixin);\n\n\tPieChart.prototype.isStackRoot = true;\n\n\tvar PiePlotArea = PlotAreaBase.extend({\n\t render: function() {\n\t this.createPieChart(this.series);\n\t },\n\n\t createPieChart: function(series) {\n\t var firstSeries = series[0];\n\t var pieChart = new PieChart(this, {\n\t series: series,\n\t padding: firstSeries.padding,\n\t startAngle: firstSeries.startAngle,\n\t connectors: firstSeries.connectors,\n\t legend: this.options.legend\n\t });\n\n\t this.appendChart(pieChart);\n\t },\n\n\t appendChart: function(chart, pane) {\n\t PlotAreaBase.fn.appendChart.call(this, chart, pane);\n\t append(this.options.legend.items, chart.legendItems);\n\t }\n\t});\n\n\tvar DonutSegment = PieSegment.extend({\n\t reflowLabel: function() {\n\t var ref = this;\n\t var labelsOptions = ref.options.labels;\n\t var label = ref.label;\n\t var sector = this.sector.clone();\n\t var angle = sector.middle();\n\n\t if (label) {\n\t var labelHeight = label.box.height();\n\t if (labelsOptions.position === CENTER) {\n\t sector.radius -= (sector.radius - sector.innerRadius) / 2;\n\n\t var lp = sector.point(angle);\n\n\t label.reflow(new Box(lp.x, lp.y - labelHeight / 2, lp.x, lp.y));\n\t } else {\n\t PieSegment.fn.reflowLabel.call(this);\n\t }\n\t }\n\t },\n\n\t createSegment: function(sector, options) {\n\t return dataviz.ShapeBuilder.current.createRing(sector, options);\n\t }\n\t});\n\n\tsetDefaultOptions(DonutSegment, {\n\t overlay: {\n\t gradient: \"roundedGlass\"\n\t },\n\t labels: {\n\t position: CENTER\n\t },\n\t animation: {\n\t type: PIE\n\t }\n\t});\n\n\tdeepExtend(DonutSegment.prototype, PointEventsMixin);\n\n\tvar DONUT_SECTOR_ANIM_DELAY = 50;\n\n\tvar DonutChart = PieChart.extend({\n\t addValue: function(value, sector, fields) {\n\t var segmentOptions = deepExtend({}, fields.series, { index: fields.index });\n\t this.evalSegmentOptions(segmentOptions, value, fields);\n\n\t this.createLegendItem(value, segmentOptions, fields);\n\n\t if (!value || fields.visible === false) {\n\t return;\n\t }\n\n\t var segment = new DonutSegment(value, sector, segmentOptions);\n\n\t $.extend(segment, fields);\n\t this.append(segment);\n\t this.points.push(segment);\n\t },\n\n\t reflow: function(targetBox) {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var box = targetBox.clone();\n\t var space = 5;\n\t var minWidth = Math.min(box.width(), box.height());\n\t var halfMinWidth = minWidth / 2;\n\t var defaultPadding = minWidth - minWidth * 0.85;\n\t var series = options.series;\n\t var seriesCount = series.length;\n\n\t var padding = valueOrDefault(options.padding, defaultPadding);\n\t padding = padding > halfMinWidth - space ? halfMinWidth - space : padding;\n\n\t var totalSize = halfMinWidth - padding;\n\t var seriesWithoutSize = 0;\n\t var holeSize;\n\n\t for (var i = 0; i < seriesCount; i++) {\n\t var currentSeries = series[i];\n\t if (i === 0) {\n\t if (defined(currentSeries.holeSize)) {\n\t holeSize = currentSeries.holeSize;\n\t totalSize -= currentSeries.holeSize;\n\t }\n\t }\n\n\t if (defined(currentSeries.size)) {\n\t totalSize -= currentSeries.size;\n\t } else {\n\t seriesWithoutSize++;\n\t }\n\n\t if (defined(currentSeries.margin) && i !== seriesCount - 1) {\n\t totalSize -= currentSeries.margin;\n\t }\n\t }\n\n\t if (!defined(holeSize)) {\n\t var currentSize = (halfMinWidth - padding) / (seriesCount + 0.75);\n\t holeSize = currentSize * 0.75;\n\t totalSize -= holeSize;\n\t }\n\n\t var innerRadius = holeSize;\n\t var margin = 0;\n\t var size, radius;\n\n\t this.seriesConfigs = [];\n\n\t for (var i$1 = 0; i$1 < seriesCount; i$1++) {\n\t var currentSeries$1 = series[i$1];\n\t size = valueOrDefault(currentSeries$1.size, totalSize / seriesWithoutSize);\n\t innerRadius += margin;\n\t radius = innerRadius + size;\n\t this$1.seriesConfigs.push({ innerRadius: innerRadius, radius: radius });\n\t margin = currentSeries$1.margin || 0;\n\t innerRadius = radius;\n\t }\n\n\t PieChart.fn.reflow.call(this, targetBox);\n\t },\n\n\t animationDelay: function(categoryIndex, seriesIndex, seriesCount) {\n\t return categoryIndex * DONUT_SECTOR_ANIM_DELAY +\n\t (INITIAL_ANIMATION_DURATION * (seriesIndex + 1) / (seriesCount + 1));\n\t }\n\t});\n\n\tsetDefaultOptions(DonutChart, {\n\t startAngle: 90,\n\t connectors: {\n\t width: 2,\n\t color: \"#939393\",\n\t padding: 8\n\t }\n\t});\n\n\tvar DonutPlotArea = PiePlotArea.extend({\n\t render: function() {\n\t this.createDonutChart(this.series);\n\t },\n\n\t createDonutChart: function(series) {\n\t var firstSeries = series[0];\n\t var donutChart = new DonutChart(this, {\n\t series: series,\n\t padding: firstSeries.padding,\n\t connectors: firstSeries.connectors,\n\t legend: this.options.legend\n\t });\n\n\t this.appendChart(donutChart);\n\t }\n\t});\n\n\tvar DEFAULT_PADDING = 0.15;\n\n\tvar PolarPlotAreaBase = PlotAreaBase.extend({\n\t initFields: function() {\n\t this.valueAxisRangeTracker = new AxisGroupRangeTracker();\n\t },\n\n\t render: function() {\n\t this.addToLegend(this.series);\n\t this.createPolarAxis();\n\t this.createCharts();\n\t this.createValueAxis();\n\t },\n\n\t alignAxes: function() {\n\t var axis = this.valueAxis;\n\t var range = axis.range();\n\t var crossingValue = axis.options.reverse ? range.max : range.min;\n\t var slot = axis.getSlot(crossingValue);\n\t var center = this.polarAxis.getSlot(0).center;\n\t var axisBox = axis.box.translate(\n\t center.x - slot.x1,\n\t center.y - slot.y1\n\t );\n\n\t axis.reflow(axisBox);\n\t },\n\n\t createValueAxis: function() {\n\t var tracker = this.valueAxisRangeTracker;\n\t var defaultRange = tracker.query();\n\t var axisOptions = this.valueAxisOptions({\n\t roundToMajorUnit: false,\n\t zIndex: -1\n\t });\n\t var axisType, axisDefaultRange;\n\n\t if (axisOptions.type === LOGARITHMIC) {\n\t axisType = dataviz.RadarLogarithmicAxis;\n\t axisDefaultRange = { min: 0.1, max: 1 };\n\t } else {\n\t axisType = dataviz.RadarNumericAxis;\n\t axisDefaultRange = { min: 0, max: 1 };\n\t }\n\n\t var range = tracker.query(name) || defaultRange || axisDefaultRange;\n\n\t if (range && defaultRange) {\n\t range.min = Math.min(range.min, defaultRange.min);\n\t range.max = Math.max(range.max, defaultRange.max);\n\t }\n\n\t var valueAxis = new axisType(\n\t range.min, range.max,\n\t axisOptions,\n\t this.chartService\n\t );\n\n\t this.valueAxis = valueAxis;\n\t this.appendAxis(valueAxis);\n\t },\n\n\t reflowAxes: function() {\n\t var ref = this;\n\t var options = ref.options.plotArea;\n\t var valueAxis = ref.valueAxis;\n\t var polarAxis = ref.polarAxis;\n\t var box = ref.box;\n\t var defaultPadding = Math.min(box.width(), box.height()) * DEFAULT_PADDING;\n\t var padding = getSpacing(options.padding || {}, defaultPadding);\n\t var paddingBox = box.clone().unpad(padding);\n\t var axisBox = paddingBox.clone();\n\n\t axisBox.y2 = axisBox.y1 + Math.min(axisBox.width(), axisBox.height());\n\t axisBox.align(paddingBox, Y, CENTER);\n\n\t var valueAxisBox = axisBox.clone().shrink(0, axisBox.height() / 2);\n\n\t polarAxis.reflow(axisBox);\n\t valueAxis.reflow(valueAxisBox);\n\t var heightDiff = valueAxis.lineBox().height() - valueAxis.box.height();\n\t valueAxis.reflow(valueAxis.box.unpad({ top: heightDiff }));\n\n\t this.axisBox = axisBox;\n\t this.alignAxes(axisBox);\n\t },\n\n\t backgroundBox: function() {\n\t return this.box;\n\t },\n\n\t detachLabels: function() {}\n\t});\n\n\tvar PolarScatterChart = ScatterChart.extend({\n\t pointSlot: function(slotX, slotY) {\n\t var valueRadius = slotX.center.y - slotY.y1;\n\t var slot = Point.onCircle(slotX.center, slotX.startAngle, valueRadius);\n\n\t return new Box(slot.x, slot.y, slot.x, slot.y);\n\t }\n\t});\n\n\tsetDefaultOptions(PolarScatterChart, {\n\t clip: false\n\t});\n\n\tvar PolarLineChart = ScatterLineChart.extend({\n\n\t});\n\n\tPolarLineChart.prototype.pointSlot = PolarScatterChart.prototype.pointSlot;\n\n\tsetDefaultOptions(PolarLineChart, {\n\t clip: false\n\t});\n\n\tvar SplinePolarAreaSegment = SplineAreaSegment.extend({\n\t fillToAxes: function(fillPath) {\n\t var center = this._polarAxisCenter();\n\t fillPath.lineTo(center.x, center.y);\n\t },\n\n\t _polarAxisCenter: function() {\n\t var polarAxis = this.parent.plotArea.polarAxis;\n\t var center = polarAxis.box.center();\n\t return center;\n\t },\n\n\t strokeSegments: function() {\n\t var segments = this._strokeSegments;\n\n\t if (!segments) {\n\t var center = this._polarAxisCenter();\n\t var curveProcessor = new CurveProcessor(false);\n\t var linePoints = this.points();\n\n\t linePoints.push(center);\n\t segments = this._strokeSegments = curveProcessor.process(linePoints);\n\t segments.pop();\n\t }\n\n\t return segments;\n\t }\n\t});\n\n\tvar PolarAreaSegment = AreaSegment.extend({\n\t fillToAxes: function(fillPath) {\n\t var polarAxis = this.parent.plotArea.polarAxis;\n\t var center = polarAxis.box.center();\n\t var centerSegment = new geometry.Segment([ center.x, center.y ]);\n\n\t fillPath.segments.unshift(centerSegment);\n\t fillPath.segments.push(centerSegment);\n\t }\n\t});\n\n\tvar PolarAreaChart = PolarLineChart.extend({\n\t createSegment: function(linePoints, currentSeries, seriesIx) {\n\t var style = (currentSeries.line || {}).style;\n\t var segment;\n\n\t if (style === SMOOTH) {\n\t segment = new SplinePolarAreaSegment(linePoints, currentSeries, seriesIx);\n\t } else {\n\t segment = new PolarAreaSegment(linePoints, currentSeries, seriesIx);\n\t }\n\t return segment;\n\t },\n\n\t createMissingValue: function(value, missingValues) {\n\t var missingValue;\n\n\t if (hasValue(value.x) && missingValues !== INTERPOLATE) {\n\t missingValue = {\n\t x: value.x,\n\t y: value.y\n\t };\n\t if (missingValues === ZERO) {\n\t missingValue.y = 0;\n\t }\n\t }\n\n\t return missingValue;\n\t },\n\n\t seriesMissingValues: function(series) {\n\t return series.missingValues || ZERO;\n\t },\n\n\t _hasMissingValuesGap: function() {\n\t var this$1 = this;\n\n\t var series = this.options.series;\n\n\t for (var idx = 0; idx < series.length; idx++) {\n\t if (this$1.seriesMissingValues(series[idx]) === GAP) {\n\t return true;\n\t }\n\t }\n\t },\n\n\t sortPoints: function(points) {\n\t var this$1 = this;\n\n\t points.sort(xComparer);\n\n\t if (this._hasMissingValuesGap()) {\n\t for (var idx = 0; idx < points.length; idx++) {\n\t var point = points[idx];\n\t if (point) {\n\t var value = point.value;\n\t if (!hasValue(value.y) && this$1.seriesMissingValues(point.series) === GAP) {\n\t delete points[idx];\n\t }\n\t }\n\t }\n\t }\n\n\t return points;\n\t }\n\t});\n\n\tfunction xComparer(a, b) {\n\t return a.value.x - b.value.x;\n\t}\n\n\tvar PolarPlotArea = PolarPlotAreaBase.extend({\n\t createPolarAxis: function() {\n\t var polarAxis = new dataviz.PolarAxis(this.options.xAxis, this.chartService);\n\n\t this.polarAxis = polarAxis;\n\t this.axisX = polarAxis;\n\t this.appendAxis(polarAxis);\n\t },\n\n\t valueAxisOptions: function(defaults) {\n\t return deepExtend(defaults, {\n\t majorGridLines: { type: ARC },\n\t minorGridLines: { type: ARC }\n\t }, this.options.yAxis);\n\t },\n\n\t createValueAxis: function() {\n\t PolarPlotAreaBase.fn.createValueAxis.call(this);\n\t this.axisY = this.valueAxis;\n\t },\n\n\t appendChart: function(chart, pane) {\n\t this.valueAxisRangeTracker.update(chart.yAxisRanges);\n\n\t PlotAreaBase.prototype.appendChart.call(this, chart, pane);\n\t },\n\n\t createCharts: function() {\n\t var series = this.filterVisibleSeries(this.series);\n\t var pane = this.panes[0];\n\n\t this.createLineChart(\n\t filterSeriesByType(series, [ POLAR_LINE ]),\n\t pane\n\t );\n\n\t this.createScatterChart(\n\t filterSeriesByType(series, [ POLAR_SCATTER ]),\n\t pane\n\t );\n\n\t this.createAreaChart(\n\t filterSeriesByType(series, [ POLAR_AREA ]),\n\t pane\n\t );\n\t },\n\n\t createLineChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var lineChart = new PolarLineChart(this, { series: series });\n\n\t this.appendChart(lineChart, pane);\n\t },\n\n\t createScatterChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var scatterChart = new PolarScatterChart(this, { series: series });\n\n\t this.appendChart(scatterChart, pane);\n\t },\n\n\t createAreaChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var areaChart = new PolarAreaChart(this, { series: series });\n\n\t this.appendChart(areaChart, pane);\n\t },\n\n\t _dispatchEvent: function(chart, e, eventType) {\n\t var coords = chart._eventCoordinates(e);\n\t var point = new Point(coords.x, coords.y);\n\t var xValue = this.axisX.getValue(point);\n\t var yValue = this.axisY.getValue(point);\n\n\t if (xValue !== null && yValue !== null) {\n\t chart.trigger(eventType, {\n\t element: eventElement(e),\n\t x: xValue,\n\t y: yValue\n\t });\n\t }\n\t },\n\n\t createCrosshairs: function() {}\n\t});\n\n\tsetDefaultOptions(PolarPlotArea, {\n\t xAxis: {},\n\t yAxis: {}\n\t});\n\n\tdeepExtend(PolarPlotArea.prototype, PlotAreaEventsMixin);\n\n\tfunction groupBySeriesIx(segments) {\n\t var seriesSegments = [];\n\t for (var idx = 0; idx < segments.length; idx++) {\n\t var segment = segments[idx];\n\t seriesSegments[segment.seriesIx] = seriesSegments[segment.seriesIx] || [];\n\t seriesSegments[segment.seriesIx].push(segment);\n\t }\n\n\t return seriesSegments;\n\t}\n\n\tvar RadarLineChart = LineChart.extend({\n\t pointSlot: function(categorySlot, valueSlot) {\n\t var valueRadius = categorySlot.center.y - valueSlot.y1;\n\t var slot = Point.onCircle(categorySlot.center, categorySlot.middle(), valueRadius);\n\n\t return new Box(slot.x, slot.y, slot.x, slot.y);\n\t },\n\n\t renderSegments: function() {\n\t LineChart.fn.renderSegments.call(this);\n\n\t if (this._segments && this._segments.length > 1) {\n\t var seriesSegments = groupBySeriesIx(this._segments);\n\n\t for (var idx = 0; idx < seriesSegments.length; idx++) {\n\t var segments = seriesSegments[idx];\n\t if (segments && segments.length > 1) {\n\t var firstPoint = segments[0].linePoints[0];\n\t var lastSegment = last(segments);\n\t var lastPoint = last(lastSegment.linePoints);\n\t var isFirstDataPoint = firstPoint.categoryIx === 0;\n\t var isLastDataPoint = lastPoint.categoryIx === lastPoint.categoriesCount - 1;\n\t if (isFirstDataPoint && isLastDataPoint) {\n\t last(segments).linePoints.push(firstPoint);\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t createSegment: function(linePoints, currentSeries, seriesIx) {\n\t var style = currentSeries.style;\n\t var pointType;\n\n\t if (style === SMOOTH) {\n\t pointType = SplineSegment;\n\t } else {\n\t pointType = LineSegment;\n\t }\n\n\t var segment = new pointType(linePoints, currentSeries, seriesIx);\n\n\t if (linePoints.length === currentSeries.data.length) {\n\t segment.options.closed = true;\n\t }\n\n\t return segment;\n\t }\n\t});\n\n\tsetDefaultOptions(RadarLineChart, {\n\t clip: false,\n\t limitPoints: false\n\t});\n\n\tvar SplineRadarAreaSegment = SplineAreaSegment.extend({\n\t fillToAxes: function() {}\n\t});\n\n\tvar RadarAreaSegment = AreaSegment.extend({\n\t fillToAxes: function() {}\n\t});\n\n\tvar RadarAreaChart = RadarLineChart.extend({\n\t createSegment: function(linePoints, currentSeries, seriesIx, prevSegment) {\n\t var isStacked = this.options.isStacked;\n\t var style = (currentSeries.line || {}).style;\n\t var previousSegment;\n\t var stackPoints;\n\t var segment;\n\n\t if (isStacked && seriesIx > 0 && prevSegment) {\n\t stackPoints = prevSegment.linePoints.slice(0);\n\t previousSegment = prevSegment;\n\t }\n\n\t if (style === SMOOTH) {\n\t segment = new SplineRadarAreaSegment(linePoints, currentSeries, seriesIx, previousSegment, stackPoints);\n\t segment.options.closed = true;\n\t } else {\n\t linePoints.push(linePoints[0]);\n\t segment = new RadarAreaSegment(linePoints, currentSeries, seriesIx, previousSegment, stackPoints);\n\t }\n\n\t return segment;\n\t },\n\n\t seriesMissingValues: function(series) {\n\t return series.missingValues || ZERO;\n\t }\n\t});\n\n\tvar RadarSegment = DonutSegment.extend({\n\t init: function(value, options) {\n\t DonutSegment.fn.init.call(this, value, null, options);\n\t }\n\t});\n\n\tsetDefaultOptions(RadarSegment, {\n\t overlay: {\n\t gradient: \"none\"\n\t },\n\t labels: {\n\t distance: 10\n\t }\n\t});\n\n\tvar RadarClusterLayout = ChartElement.extend({\n\t init: function(options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.forEach = options.rtl ? forEachReverse : forEach;\n\t },\n\n\t reflow: function(sector) {\n\t var ref = this;\n\t var options = ref.options;\n\t var children = ref.children;\n\t var gap = options.gap;\n\t var spacing = options.spacing;\n\t var count = children.length;\n\t var slots = count + gap + (spacing * (count - 1));\n\t var slotAngle = sector.angle / slots;\n\t var angle = sector.startAngle + slotAngle * (gap / 2);\n\n\t this.forEach(children, function (child) {\n\t var slotSector = sector.clone();\n\t slotSector.startAngle = angle;\n\t slotSector.angle = slotAngle;\n\n\t if (child.sector) {\n\t slotSector.radius = child.sector.radius;\n\t }\n\n\t child.reflow(slotSector);\n\t child.sector = slotSector;\n\n\t angle += slotAngle + (slotAngle * spacing);\n\t });\n\t }\n\t});\n\n\tsetDefaultOptions(RadarClusterLayout, {\n\t gap: 1,\n\t spacing: 0\n\t});\n\n\tvar RadarStackLayout = ChartElement.extend({\n\t reflow: function(sector) {\n\t var ref = this;\n\t var reverse = ref.options.reverse;\n\t var children = ref.children;\n\t var childrenCount = children.length;\n\t var first = reverse ? childrenCount - 1 : 0;\n\t var step = reverse ? -1 : 1;\n\n\t this.box = new Box();\n\n\t for (var i = first; i >= 0 && i < childrenCount; i += step) {\n\t var childSector = children[i].sector;\n\t childSector.startAngle = sector.startAngle;\n\t childSector.angle = sector.angle;\n\t }\n\t }\n\t});\n\n\tvar RadarBarChart = BarChart.extend({\n\t pointType: function() {\n\t return RadarSegment;\n\t },\n\n\t clusterType: function() {\n\t return RadarClusterLayout;\n\t },\n\n\t stackType: function() {\n\t return RadarStackLayout;\n\t },\n\n\t categorySlot: function(categoryAxis, categoryIx) {\n\t return categoryAxis.getSlot(categoryIx);\n\t },\n\n\t pointSlot: function(categorySlot, valueSlot) {\n\t var slot = categorySlot.clone();\n\t var y = categorySlot.center.y;\n\n\t slot.radius = y - valueSlot.y1;\n\t slot.innerRadius = y - valueSlot.y2;\n\n\t return slot;\n\t },\n\n\t reflowPoint: function(point, pointSlot) {\n\t point.sector = pointSlot;\n\t point.reflow();\n\t },\n\n\t createAnimation: function() {\n\t this.options.animation.center = this.box.toRect().center();\n\t BarChart.fn.createAnimation.call(this);\n\t }\n\t});\n\n\tRadarBarChart.prototype.reflow = CategoricalChart.prototype.reflow;\n\n\tsetDefaultOptions(RadarBarChart, {\n\t clip: false,\n\t limitPoints: false,\n\t animation: {\n\t type: \"pie\"\n\t }\n\t});\n\n\tvar RadarPlotArea = PolarPlotAreaBase.extend({\n\t createPolarAxis: function() {\n\t var categoryAxis = new dataviz.RadarCategoryAxis(this.options.categoryAxis, this.chartService);\n\n\t this.polarAxis = categoryAxis;\n\t this.categoryAxis = categoryAxis;\n\t this.appendAxis(categoryAxis);\n\t this.aggregateCategories();\n\t this.createCategoryAxesLabels();\n\t },\n\n\t valueAxisOptions: function(defaults) {\n\t if (this._hasBarCharts) {\n\t deepExtend(defaults, {\n\t majorGridLines: { type: ARC },\n\t minorGridLines: { type: ARC }\n\t });\n\t }\n\n\t if (this._isStacked100) {\n\t deepExtend(defaults, {\n\t roundToMajorUnit: false,\n\t labels: { format: \"P0\" }\n\t });\n\t }\n\n\t return deepExtend(defaults, this.options.valueAxis);\n\t },\n\n\t aggregateCategories: function() {\n\t // No separate panes in radar charts\n\t CategoricalPlotArea.prototype.aggregateCategories.call(this, this.panes);\n\t },\n\n\t createCategoryAxesLabels: function() {\n\t CategoricalPlotArea.prototype.createCategoryAxesLabels.call(this, this.panes);\n\t },\n\n\t filterSeries: function(currentSeries) {\n\t // Not supported for radar charts\n\t return currentSeries;\n\t },\n\n\t createCharts: function() {\n\t var series = this.filterVisibleSeries(this.series);\n\t var pane = this.panes[0];\n\n\t this.createAreaChart(\n\t filterSeriesByType(series, [ RADAR_AREA ]),\n\t pane\n\t );\n\n\t this.createLineChart(\n\t filterSeriesByType(series, [ RADAR_LINE ]),\n\t pane\n\t );\n\n\t this.createBarChart(\n\t filterSeriesByType(series, [ RADAR_COLUMN ]),\n\t pane\n\t );\n\t },\n\n\t chartOptions: function(series) {\n\t var options = { series: series };\n\t var firstSeries = series[0];\n\t if (firstSeries) {\n\t var filteredSeries = this.filterVisibleSeries(series);\n\t var stack = firstSeries.stack;\n\t options.isStacked = stack && filteredSeries.length > 1;\n\t options.isStacked100 = stack && stack.type === \"100%\" && filteredSeries.length > 1;\n\n\t if (options.isStacked100) {\n\t this._isStacked100 = true;\n\t }\n\t }\n\n\t return options;\n\t },\n\n\t createAreaChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var areaChart = new RadarAreaChart(this, this.chartOptions(series));\n\t this.appendChart(areaChart, pane);\n\t },\n\n\t createLineChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var lineChart = new RadarLineChart(this, this.chartOptions(series));\n\t this.appendChart(lineChart, pane);\n\t },\n\n\t createBarChart: function(series, pane) {\n\t if (series.length === 0) {\n\t return;\n\t }\n\n\t var firstSeries = series[0];\n\t var options = this.chartOptions(series);\n\t options.gap = firstSeries.gap;\n\t options.spacing = firstSeries.spacing;\n\n\t var barChart = new RadarBarChart(this, options);\n\t this.appendChart(barChart, pane);\n\n\t this._hasBarCharts = true;\n\t },\n\n\t seriesCategoryAxis: function() {\n\t return this.categoryAxis;\n\t },\n\n\t _dispatchEvent: function(chart, e, eventType) {\n\t var coords = chart._eventCoordinates(e);\n\t var point = new Point(coords.x, coords.y);\n\t var category = this.categoryAxis.getCategory(point);\n\t var value = this.valueAxis.getValue(point);\n\n\t if (category !== null && value !== null) {\n\t chart.trigger(eventType, {\n\t element: eventElement(e),\n\t category: category,\n\t value: value\n\t });\n\t }\n\t },\n\n\t createCrosshairs: function() {}\n\t});\n\n\tdeepExtend(RadarPlotArea.prototype, PlotAreaEventsMixin, {\n\t appendChart: CategoricalPlotArea.prototype.appendChart,\n\t aggregateSeries: CategoricalPlotArea.prototype.aggregateSeries,\n\t seriesSourcePoints: CategoricalPlotArea.prototype.seriesSourcePoints\n\t});\n\n\tsetDefaultOptions(RadarPlotArea, {\n\t categoryAxis: {\n\t categories: []\n\t },\n\t valueAxis: {}\n\t});\n\n\tvar FunnelSegment = ChartElement.extend({\n\t init: function(value, options, segmentOptions) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.value = value;\n\t this.options.index = segmentOptions.index;\n\t },\n\n\t reflow: function(chartBox) {\n\t var points = this.points;\n\t var label = this.children[0];\n\n\t this.box = new Box(points[0].x, points[0].y, points[1].x, points[2].y);\n\n\t if (label) {\n\t label.reflow(new Box(chartBox.x1, points[0].y, chartBox.x2, points[2].y));\n\t }\n\t },\n\n\t createVisual: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var visual;\n\n\t ChartElement.fn.createVisual.call(this);\n\n\t if (options.visual) {\n\t visual = options.visual({\n\t category: this.category,\n\t dataItem: this.dataItem,\n\t value: this.value,\n\t series: this.series,\n\t percentage: this.percentage,\n\t points: this.points,\n\t options: options,\n\t sender: this.getSender(),\n\t createVisual: function () { return this$1.createPath(); }\n\t });\n\t } else {\n\t visual = this.createPath();\n\t }\n\n\t if (visual) {\n\t this.visual.append(visual);\n\t }\n\t },\n\n\t createPath: function() {\n\t var options = this.options;\n\t var border = options.border;\n\t var path = Path.fromPoints(this.points, {\n\t fill: {\n\t color: options.color,\n\t opacity: options.opacity\n\t },\n\t stroke: {\n\t color: border.color,\n\t opacity: border.opacity,\n\t width: border.width\n\t }\n\t }).close();\n\n\t return path;\n\t },\n\n\t createHighlight: function(style) {\n\t return Path.fromPoints(this.points, style);\n\t },\n\n\t highlightVisual: function() {\n\t return this.visual.children[0];\n\t },\n\n\t highlightVisualArgs: function() {\n\t var path = Path.fromPoints(this.points).close();\n\n\t return {\n\t options: this.options,\n\t path: path\n\t };\n\t },\n\n\t tooltipAnchor: function() {\n\t var box = this.box;\n\t return {\n\t point: new Point(box.center().x, box.y1),\n\t align: {\n\t horizontal: \"center\",\n\t vertical: \"top\"\n\t }\n\t };\n\t },\n\n\t formatValue: function(format) {\n\t var point = this;\n\t return point.owner.formatPointValue(point, format);\n\t }\n\t});\n\n\tsetDefaultOptions(FunnelSegment, {\n\t color: WHITE,\n\t border: {\n\t width: 1\n\t }\n\t});\n\n\tdeepExtend(FunnelSegment.prototype, PointEventsMixin);\n\n\tvar FunnelChart = ChartElement.extend({\n\t init: function(plotArea, options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.plotArea = plotArea;\n\t this.points = [];\n\t this.labels = [];\n\t this.legendItems = [];\n\t this.render();\n\t },\n\n\t formatPointValue: function(point, format) {\n\t return this.chartService.format.auto(format,point.value);\n\t },\n\n\t render: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var options = ref.options;\n\t var seriesColors = ref.plotArea.options.seriesColors; if (seriesColors === void 0) { seriesColors = []; }\n\t var series = options.series[0];\n\t var data = series.data;\n\n\t if (!data) {\n\t return;\n\t }\n\n\t var ref$1 = bindSegments(series);\n\t var total = ref$1.total;\n\t var points = ref$1.points;\n\n\t for (var i = 0; i < points.length; i++) {\n\t var pointData = points[i];\n\n\t if (!pointData) {\n\t continue;\n\t }\n\n\t var fields = pointData.fields;\n\n\t if (!isFunction(series.color)) {\n\t series.color = fields.color || seriesColors[i % seriesColors.length];\n\t }\n\n\t fields = deepExtend({\n\t index: i,\n\t owner: this$1,\n\t series: series,\n\t dataItem: data[i],\n\t percentage: pointData.value / total\n\t }, fields, { visible: pointData.visible });\n\n\t var value = pointData.valueFields.value;\n\t var segment = this$1.createSegment(value, fields);\n\t var label = this$1.createLabel(value, fields);\n\n\t if (segment && label) {\n\t segment.append(label);\n\t }\n\t }\n\t },\n\n\t evalSegmentOptions: function(options, value, fields) {\n\t var series = fields.series;\n\n\t evalOptions(options, {\n\t value: value,\n\t series: series,\n\t dataItem: fields.dataItem,\n\t index: fields.index\n\t }, { defaults: series._defaults, excluded: [ \"data\", \"content\", \"template\", \"toggle\", \"visual\" ] });\n\t },\n\n\t createSegment: function(value, fields) {\n\t var seriesOptions = deepExtend({}, fields.series);\n\t this.evalSegmentOptions(seriesOptions, value, fields);\n\n\t this.createLegendItem(value, seriesOptions, fields);\n\n\t if (fields.visible !== false) {\n\n\t var segment = new FunnelSegment(value, seriesOptions, fields);\n\t $.extend(segment, fields);\n\n\t this.append(segment);\n\t this.points.push(segment);\n\n\t return segment;\n\t }\n\t },\n\n\t createLabel: function(value, fields) {\n\t var series = fields.series;\n\t var dataItem = fields.dataItem;\n\t var labels = deepExtend({}, this.options.labels, series.labels);\n\t var text = value;\n\n\t if (labels.visible) {\n\t var labelTemplate = getTemplate(labels);\n\t var data = {\n\t dataItem: dataItem,\n\t value: value,\n\t percentage: fields.percentage,\n\t category: fields.category,\n\t series: series\n\t };\n\t if (labelTemplate) {\n\t text = labelTemplate(data);\n\t } else if (labels.format) {\n\t text = this.plotArea.chartService.format.auto(labels.format, text);\n\t }\n\n\t if (!labels.color) {\n\t var brightnessValue = new Color(series.color).percBrightness();\n\t if (brightnessValue > 180) {\n\t labels.color = BLACK;\n\t } else {\n\t labels.color = WHITE;\n\t }\n\t if (!labels.background) {\n\t labels.background = series.color;\n\t }\n\t }\n\n\t this.evalSegmentOptions(labels, value, fields);\n\t var textBox = new TextBox(text, deepExtend({\n\t vAlign: labels.position\n\t }, labels), data);\n\n\t this.labels.push(textBox);\n\n\t return textBox;\n\t }\n\t },\n\n\t labelPadding: function() {\n\t var labels = this.labels;\n\t var padding = { left: 0, right: 0 };\n\n\t for (var i = 0; i < labels.length; i++) {\n\t var label = labels[i];\n\t var align = label.options.align;\n\t if (align !== CENTER) {\n\t var width = labels[i].box.width();\n\n\t if (align === LEFT) {\n\t padding.left = Math.max(padding.left, width);\n\t } else {\n\t padding.right = Math.max(padding.right, width);\n\t }\n\t }\n\t }\n\n\t return padding;\n\t },\n\n\t dynamicSlopeReflow: function(box, width, totalHeight) {\n\t var ref = this;\n\t var options = ref.options;\n\t var segments = ref.points;\n\t var count = segments.length;\n\t var firstSegment = segments[0];\n\t var maxSegment = firstSegment;\n\n\t for (var idx = 0; idx < segments.length; idx++) {\n\t if (segments[idx].percentage > maxSegment.percentage) {\n\t maxSegment = segments[idx];\n\t }\n\t }\n\n\t var lastUpperSide = (firstSegment.percentage / maxSegment.percentage) * width;\n\t var previousOffset = (width - lastUpperSide) / 2;\n\t var previousHeight = 0;\n\n\t for (var idx$1 = 0; idx$1 < count; idx$1++) {\n\t var percentage = segments[idx$1].percentage;\n\t var nextSegment = segments[idx$1 + 1];\n\t var nextPercentage = (nextSegment ? nextSegment.percentage : percentage);\n\t var points = segments[idx$1].points = [];\n\t var height = (options.dynamicHeight) ? (totalHeight * percentage) : (totalHeight / count);\n\t var offset = (void 0);\n\n\t if (!percentage) {\n\t offset = nextPercentage ? 0 : width / 2;\n\t } else {\n\t offset = (width - lastUpperSide * (nextPercentage / percentage)) / 2;\n\t }\n\n\t offset = limitValue(offset, 0, width);\n\n\t points.push(new GeometryPoint(box.x1 + previousOffset, box.y1 + previousHeight));\n\t points.push(new GeometryPoint(box.x1 + width - previousOffset, box.y1 + previousHeight));\n\t points.push(new GeometryPoint(box.x1 + width - offset, box.y1 + height + previousHeight));\n\t points.push(new GeometryPoint(box.x1 + offset, box.y1 + height + previousHeight));\n\n\t previousOffset = offset;\n\t previousHeight += height + options.segmentSpacing;\n\t lastUpperSide = limitValue(width - 2 * offset, 0, width);\n\t }\n\t },\n\n\t constantSlopeReflow: function(box, width, totalHeight) {\n\t var ref = this;\n\t var options = ref.options;\n\t var segments = ref.points;\n\t var count = segments.length;\n\t var decreasingWidth = options.neckRatio <= 1;\n\t var neckRatio = decreasingWidth ? options.neckRatio * width : width;\n\t var previousOffset = decreasingWidth ? 0 : (width - width / options.neckRatio) / 2;\n\t var topMostWidth = decreasingWidth ? width : width - previousOffset * 2;\n\t var finalNarrow = (topMostWidth - neckRatio) / 2;\n\t var previousHeight = 0;\n\n\t for (var idx = 0; idx < count; idx++) {\n\t var points = segments[idx].points = [];\n\t var percentage = segments[idx].percentage;\n\t var offset = (options.dynamicHeight) ? (finalNarrow * percentage) : (finalNarrow / count);\n\t var height = (options.dynamicHeight) ? (totalHeight * percentage) : (totalHeight / count);\n\n\t points.push(new GeometryPoint(box.x1 + previousOffset, box.y1 + previousHeight));\n\t points.push(new GeometryPoint(box.x1 + width - previousOffset, box.y1 + previousHeight));\n\t points.push(new GeometryPoint(box.x1 + width - previousOffset - offset, box.y1 + height + previousHeight));\n\t points.push(new GeometryPoint(box.x1 + previousOffset + offset,box.y1 + height + previousHeight));\n\t previousOffset += offset;\n\t previousHeight += height + options.segmentSpacing;\n\t }\n\t },\n\n\t reflow: function(chartBox) {\n\t var points = this.points;\n\t var count = points.length;\n\n\t if (!count) {\n\t return;\n\t }\n\n\t var options = this.options;\n\t var box = chartBox.clone().unpad(this.labelPadding());\n\t var totalHeight = box.height() - options.segmentSpacing * (count - 1);\n\t var width = box.width();\n\n\t if (options.dynamicSlope) {\n\t this.dynamicSlopeReflow(box, width, totalHeight);\n\t } else {\n\t this.constantSlopeReflow(box, width, totalHeight);\n\t }\n\n\t for (var idx = 0; idx < count; idx++) {\n\t points[idx].reflow(chartBox);\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(FunnelChart, {\n\t neckRatio: 0.3,\n\t width: 300,\n\t dynamicSlope: false,\n\t dynamicHeight: true,\n\t segmentSpacing: 0,\n\t labels: {\n\t visible: false,\n\t align: CENTER,\n\t position: CENTER,\n\t zIndex: 1\n\t }\n\t});\n\n\tdeepExtend(FunnelChart.prototype, PieChartMixin);\n\n\tvar FunnelPlotArea = PlotAreaBase.extend({\n\t render: function() {\n\t this.createFunnelChart(this.series);\n\t },\n\n\t createFunnelChart: function(series) {\n\t var firstSeries = series[0];\n\t var funnelChart = new FunnelChart(this, {\n\t series: series,\n\t legend: this.options.legend,\n\t neckRatio: firstSeries.neckRatio,\n\t dynamicHeight: firstSeries.dynamicHeight,\n\t dynamicSlope: firstSeries.dynamicSlope,\n\t segmentSpacing: firstSeries.segmentSpacing,\n\t highlight: firstSeries.highlight\n\t });\n\n\t this.appendChart(funnelChart);\n\t },\n\n\t appendChart: function(chart, pane) {\n\t PlotAreaBase.fn.appendChart.call(this, chart, pane);\n\t append(this.options.legend.items, chart.legendItems);\n\t }\n\t});\n\n\tvar COLOR = \"color\";\n\tvar FIRST = \"first\";\n\tvar FROM = \"from\";\n\tvar MAX = \"max\";\n\tvar MIN = \"min\";\n\tvar NOTE_TEXT = \"noteText\";\n\tvar SUMMARY_FIELD = \"summary\";\n\tvar TO = \"to\";\n\n\tPlotAreaFactory.current.register(CategoricalPlotArea, [\n\t BAR, COLUMN, LINE, VERTICAL_LINE, AREA, VERTICAL_AREA,\n\t CANDLESTICK, OHLC, BULLET, VERTICAL_BULLET, BOX_PLOT, VERTICAL_BOX_PLOT,\n\t RANGE_COLUMN, RANGE_BAR, WATERFALL, HORIZONTAL_WATERFALL, RANGE_AREA, VERTICAL_RANGE_AREA\n\t]);\n\n\tPlotAreaFactory.current.register(XYPlotArea, [\n\t SCATTER, SCATTER_LINE, BUBBLE\n\t]);\n\n\tPlotAreaFactory.current.register(PiePlotArea, [ PIE ]);\n\tPlotAreaFactory.current.register(DonutPlotArea, [ DONUT ]);\n\tPlotAreaFactory.current.register(FunnelPlotArea, [ FUNNEL ]);\n\n\tPlotAreaFactory.current.register(PolarPlotArea, [ POLAR_AREA, POLAR_LINE, POLAR_SCATTER ]);\n\tPlotAreaFactory.current.register(RadarPlotArea, [ RADAR_AREA, RADAR_COLUMN, RADAR_LINE ]);\n\n\tSeriesBinder.current.register(\n\t [ BAR, COLUMN, LINE, VERTICAL_LINE, AREA, VERTICAL_AREA ],\n\t [ VALUE ], [ CATEGORY, COLOR, NOTE_TEXT, ERROR_LOW_FIELD, ERROR_HIGH_FIELD ]\n\t);\n\n\tSeriesBinder.current.register(\n\t [ RANGE_COLUMN, RANGE_BAR, RANGE_AREA, VERTICAL_RANGE_AREA ],\n\t [ FROM, TO ], [ CATEGORY, COLOR, NOTE_TEXT ]\n\t);\n\n\tSeriesBinder.current.register(\n\t [ WATERFALL, HORIZONTAL_WATERFALL ],\n\t [ VALUE ], [ CATEGORY, COLOR, NOTE_TEXT, SUMMARY_FIELD ]\n\t);\n\n\tSeriesBinder.current.register([ POLAR_AREA, POLAR_LINE, POLAR_SCATTER ], [ X, Y ], [ COLOR ]);\n\tSeriesBinder.current.register([ RADAR_AREA, RADAR_COLUMN, RADAR_LINE ], [ VALUE ], [ COLOR ]);\n\n\tSeriesBinder.current.register(\n\t [ FUNNEL ],\n\t [ VALUE ], [ CATEGORY, COLOR, \"visibleInLegend\", \"visible\" ]\n\t);\n\n\tDefaultAggregates.current.register(\n\t [ BAR, COLUMN, LINE, VERTICAL_LINE, AREA, VERTICAL_AREA, WATERFALL, HORIZONTAL_WATERFALL ],\n\t { value: MAX, color: FIRST, noteText: FIRST, errorLow: MIN, errorHigh: MAX }\n\t);\n\n\tDefaultAggregates.current.register(\n\t [ RANGE_COLUMN, RANGE_BAR, RANGE_AREA, VERTICAL_RANGE_AREA ],\n\t { from: MIN, to: MAX, color: FIRST, noteText: FIRST }\n\t);\n\n\tDefaultAggregates.current.register(\n\t [ RADAR_AREA, RADAR_COLUMN, RADAR_LINE ],\n\t { value: MAX, color: FIRST }\n\t);\n\n\tSeriesBinder.current.register(\n\t [ SCATTER, SCATTER_LINE, BUBBLE ],\n\t [ X, Y ], [ COLOR, NOTE_TEXT, X_ERROR_LOW_FIELD, X_ERROR_HIGH_FIELD, Y_ERROR_LOW_FIELD, Y_ERROR_HIGH_FIELD ]\n\t);\n\n\tSeriesBinder.current.register(\n\t [ BUBBLE ], [ X, Y, \"size\" ], [ COLOR, CATEGORY, NOTE_TEXT ]\n\t);\n\n\tSeriesBinder.current.register(\n\t [ CANDLESTICK, OHLC ],\n\t [ \"open\", \"high\", \"low\", \"close\" ], [ CATEGORY, COLOR, \"downColor\", NOTE_TEXT ]\n\t);\n\n\tDefaultAggregates.current.register(\n\t [ CANDLESTICK, OHLC ],\n\t { open: MAX, high: MAX, low: MIN, close: MAX,\n\t color: FIRST, downColor: FIRST, noteText: FIRST }\n\t);\n\n\tSeriesBinder.current.register(\n\t [ BOX_PLOT, VERTICAL_BOX_PLOT ],\n\t [ \"lower\", \"q1\", \"median\", \"q3\", \"upper\", \"mean\", \"outliers\" ], [ CATEGORY, COLOR, NOTE_TEXT ]\n\t);\n\n\tDefaultAggregates.current.register(\n\t [ BOX_PLOT, VERTICAL_BOX_PLOT ],\n\t { lower: MAX, q1: MAX, median: MAX, q3: MAX, upper: MAX, mean: MAX, outliers: FIRST,\n\t color: FIRST, noteText: FIRST }\n\t);\n\n\tSeriesBinder.current.register(\n\t [ BULLET, VERTICAL_BULLET ],\n\t [ \"current\", \"target\" ], [ CATEGORY, COLOR, \"visibleInLegend\", NOTE_TEXT ]\n\t);\n\n\tDefaultAggregates.current.register(\n\t [ BULLET, VERTICAL_BULLET ],\n\t { current: MAX, target: MAX, color: FIRST, noteText: FIRST }\n\t);\n\n\tSeriesBinder.current.register(\n\t [ PIE, DONUT ],\n\t [ VALUE ], [ CATEGORY, COLOR, \"explode\", \"visibleInLegend\", \"visible\" ]\n\t);\n\n\tvar AXIS_NAMES = [ CATEGORY, VALUE, X, Y ];\n\n\tvar MOUSEMOVE = \"mousemove\";\n\tvar CONTEXTMENU = \"contextmenu\";\n\tvar MOUSELEAVE = \"mouseleave\";\n\tvar MOUSEMOVE_DELAY = 20;\n\n\tvar Chart = Class.extend({\n\t init: function(element, userOptions, themeOptions, context) {\n\t var this$1 = this;\n\t if (context === void 0) { context = {}; }\n\n\t this.observers = [];\n\t this.addObserver(context.observer);\n\t this.chartService = new services.ChartService(this, context);\n\t this.chartService.theme = themeOptions;\n\n\t this._initElement(element);\n\n\t var options = deepExtend({}, this.options, userOptions);\n\t this._originalOptions = deepExtend({}, options);\n\t this._theme = themeOptions;\n\t this._initTheme(options, themeOptions);\n\n\t this._initHandlers();\n\t this._initSurface();\n\n\t this.bindCategories();\n\t dataviz.FontLoader.preloadFonts(userOptions, function () {\n\t this$1.fontLoaded = true;\n\t if (!this$1._destroyed) {\n\t this$1.trigger('init');\n\t this$1._redraw();\n\t this$1._attachEvents();\n\t }\n\t });\n\t },\n\n\t _initElement: function(element) {\n\t this._setElementClass(element);\n\t element.style.position = \"relative\";\n\t while (element.firstChild) {\n\t element.removeChild(element.firstChild);\n\t }\n\t this.element = element;\n\t },\n\n\t _setElementClass: function(element) {\n\t dataviz.addClass(element, \"k-chart\");\n\t },\n\n\t _initTheme: function(options, themeOptions) {\n\t var seriesCopies = [];\n\t var series = options.series || [];\n\n\t for (var i = 0; i < series.length; i++) {\n\t seriesCopies.push($.extend({}, series[i]));\n\t }\n\t options.series = seriesCopies;\n\n\t resolveAxisAliases(options);\n\t this.applyDefaults(options, themeOptions);\n\n\t // Clean up default if not overriden by data attributes\n\t if (options.seriesColors === null) {\n\t delete options.seriesColors;\n\t }\n\n\t this.options = deepExtend({}, themeOptions, options);\n\t this.applySeriesColors();\n\t },\n\n\t getSize: function() {\n\t var chartArea = this.options.chartArea || {};\n\t var width = chartArea.width ? parseInt(chartArea.width, 10) : Math.floor(this.element.offsetWidth);\n\t var height = chartArea.height ? parseInt(chartArea.height, 10) : Math.floor(this.element.offsetHeight);\n\n\t return {\n\t width: width,\n\t height: height\n\t };\n\t },\n\n\t resize: function(force) {\n\t var size = this.getSize();\n\t var currentSize = this._size;\n\t var hasSize = size.width > 0 || size.height > 0;\n\n\t if (force || hasSize && (!currentSize || size.width !== currentSize.width || size.height !== currentSize.height)) {\n\t this._size = size;\n\t this._resize(size, force);\n\t this.trigger(\"resize\", size);\n\t } else if (hasSize && this._selections && dataviz.find(this._selections, function (s) { return !s.visible; })) {\n\t this._destroySelections();\n\t this._setupSelection();\n\t }\n\t },\n\n\t _resize: function() {\n\t this._noTransitionsRedraw();\n\t },\n\n\t redraw: function(paneName) {\n\t this.applyDefaults(this.options);\n\t this.applySeriesColors();\n\n\t if (paneName) {\n\t var plotArea = this._model._plotArea;\n\t var pane = plotArea.findPane(paneName);\n\t plotArea.redraw(pane);\n\t } else {\n\t this._redraw();\n\t }\n\t },\n\n\t getAxis: function(name) {\n\t return findAxisByName(name, this._plotArea.axes);\n\t },\n\n\t findAxisByName: function(name) {\n\t return this.getAxis(name);\n\t },\n\n\t findPaneByName: function(name) {\n\t var panes = this._plotArea.panes;\n\n\t for (var idx = 0; idx < panes.length; idx++) {\n\t if (panes[idx].options.name === name) {\n\t return new ChartPane(panes[idx]);\n\t }\n\t }\n\t },\n\n\t findPaneByIndex: function(idx) {\n\t var panes = this._plotArea.panes;\n\t if (panes[idx]) {\n\t return new ChartPane(panes[idx]);\n\t }\n\t },\n\n\t plotArea: function() {\n\t return new ChartPlotArea(this._plotArea);\n\t },\n\n\t toggleHighlight: function(show, filter) {\n\t var plotArea = this._plotArea;\n\t var firstSeries = (plotArea.srcSeries || plotArea.series || [])[0];\n\t var points;\n\n\t if (isFunction(filter)) {\n\t points = plotArea.filterPoints(filter);\n\t } else {\n\t var seriesName, categoryName;\n\t if (isObject(filter)) {\n\t seriesName = filter.series;\n\t categoryName = filter.category;\n\t } else {\n\t seriesName = categoryName = filter;\n\t }\n\n\t if (firstSeries.type === DONUT) {\n\t points = pointByCategoryName(plotArea.pointsBySeriesName(seriesName), categoryName);\n\t } else if (firstSeries.type === PIE || firstSeries.type === FUNNEL) {\n\t points = pointByCategoryName((plotArea.charts[0] || {}).points, categoryName);\n\t } else {\n\t points = plotArea.pointsBySeriesName(seriesName);\n\t }\n\t }\n\n\t if (points) {\n\t this.togglePointsHighlight(show, points);\n\t }\n\t },\n\n\t togglePointsHighlight: function(show, points) {\n\t var highlight = this._highlight;\n\t for (var idx = 0; idx < points.length; idx++) {\n\t highlight.togglePointHighlight(points[idx], show);\n\t }\n\t },\n\n\t showTooltip: function(filter) {\n\t var shared = this._sharedTooltip();\n\t var ref = this;\n\t var tooltip = ref._tooltip;\n\t var plotArea = ref._plotArea;\n\t var point, categoryIndex;\n\n\t if (isFunction(filter)) {\n\t point = plotArea.findPoint(filter);\n\t if (point && shared) {\n\t categoryIndex = point.categoryIx;\n\t }\n\t } else if (shared && defined(filter)) {\n\t categoryIndex = plotArea.categoryAxis.categoryIndex(filter);\n\t }\n\n\t if (shared) {\n\t if (categoryIndex >= 0) {\n\t var points = this._plotArea.pointsByCategoryIndex(categoryIndex);\n\t tooltip.showAt(points);\n\t }\n\t } else if (point) {\n\t tooltip.show(point);\n\t }\n\t },\n\n\t hideTooltip: function() {\n\t this._tooltip.hide();\n\t },\n\n\t _initSurface: function() {\n\t var surface = this.surface;\n\t var wrap = this._surfaceWrap();\n\n\t var chartArea = this.options.chartArea || {};\n\t if (chartArea.width) {\n\t dataviz.elementSize(wrap, { width: chartArea.width });\n\t }\n\t if (chartArea.height) {\n\t dataviz.elementSize(wrap, { height: chartArea.height });\n\t }\n\n\t if (!surface || surface.options.type !== this.options.renderAs) {\n\t this._destroySurface();\n\n\t this.surface = drawing.Surface.create(wrap, {\n\t type: this.options.renderAs\n\t });\n\n\t this.surface.bind(\"mouseenter\", this._surfaceMouseenterHandler);\n\t this.surface.bind(\"mouseleave\", this._surfaceMouseleaveHandler);\n\n\t } else {\n\t this.surface.clear();\n\t this.surface.resize();\n\t }\n\t },\n\n\t _surfaceWrap: function() {\n\t return this.element;\n\t },\n\n\t _redraw: function() {\n\t var model = this._getModel();\n\t this._size = {\n\t width: model.options.width,\n\t height: model.options.height\n\t };\n\n\t this._destroyView();\n\n\t this._model = model;\n\t this._plotArea = model._plotArea;\n\n\t model.renderVisual();\n\n\t if (this.options.transitions !== false) {\n\t model.traverse(function(element) {\n\t if (element.animation) {\n\t element.animation.setup();\n\t }\n\t });\n\t }\n\n\t this._initSurface();\n\t this.surface.draw(model.visual);\n\n\t if (this.options.transitions !== false) {\n\t model.traverse(function(element) {\n\t if (element.animation) {\n\t element.animation.play();\n\t }\n\t });\n\t }\n\n\t this._tooltip = this._createTooltip();\n\t this._highlight = new Highlight();\n\t this._setupSelection();\n\t this._createPannable();\n\t this._createZoomSelection();\n\t this._createMousewheelZoom();\n\n\t this.trigger(RENDER);\n\t triggerPaneRender(this._plotArea.panes);\n\n\t if (!this._navState) {\n\t this._cancelDomEvents();\n\t }\n\t },\n\n\t exportVisual: function(exportOptions) {\n\t var visual;\n\t if (exportOptions && (exportOptions.width || exportOptions.height || exportOptions.options)) {\n\t var currentOptions = this.options;\n\t var options = deepExtend({}, exportOptions.options, {\n\t chartArea: {\n\t width: exportOptions.width,\n\t height: exportOptions.height\n\t }\n\t });\n\n\t clearMissingValues(this._originalOptions, options);\n\t this.options = deepExtend({}, this._originalOptions, options);\n\t this._initTheme(this.options, this._theme);\n\t this.bindCategories();\n\n\t var model = this._getModel();\n\n\t model.renderVisual();\n\t triggerPaneRender(model._plotArea.panes);\n\n\t visual = model.visual;\n\n\t this.options = currentOptions;\n\t } else {\n\t visual = this.surface.exportVisual();\n\t }\n\n\t return visual;\n\t },\n\n\t _sharedTooltip: function() {\n\t return this._plotArea instanceof CategoricalPlotArea && this.options.tooltip && this.options.tooltip.shared;\n\t },\n\n\t _createPannable: function() {\n\t var options = this.options;\n\t if (options.pannable !== false) {\n\t this._pannable = new Pannable(this._plotArea, options.pannable);\n\t }\n\t },\n\n\t _createZoomSelection: function() {\n\t var zoomable = this.options.zoomable;\n\t var selection = (zoomable || {}).selection;\n\t if (zoomable !== false && selection !== false) {\n\t this._zoomSelection = new ZoomSelection(this, selection);\n\t }\n\t },\n\n\t _createMousewheelZoom: function() {\n\t var zoomable = this.options.zoomable;\n\t var mousewheel = (zoomable || {}).mousewheel;\n\t if (zoomable !== false && mousewheel !== false) {\n\t this._mousewheelZoom = new MousewheelZoom(this, mousewheel);\n\t }\n\t },\n\n\t _toggleDragZoomEvents: function() {\n\t var pannable = this.options.pannable;\n\t var zoomable = this.options.zoomable;\n\t var selection = (zoomable || {}).selection;\n\t var mousewheel = (zoomable || {}).mousewheel;\n\t var allowDrag = !pannable && (zoomable === false || selection === false) && !this.requiresHandlers([ DRAG_START, DRAG, DRAG_END ]);\n\t var allowZoom = (zoomable === false || mousewheel === false) && !this.requiresHandlers([ ZOOM_START, ZOOM, ZOOM_END ]);\n\t var element = this.element;\n\n\t if (this._dragZoomEnabled && allowDrag && allowZoom) {\n\t element.style.touchAction = this._touchAction || '';\n\t this._dragZoomEnabled = false;\n\t } else if (!this._dragZoomEnabled && !(allowDrag && allowZoom)) {\n\t element.style.touchAction = \"none\";\n\n\t this._dragZoomEnabled = true;\n\t }\n\n\t this._toggleDomEvents(!allowDrag, !allowZoom);\n\t },\n\n\t _toggleDomEvents: function(drag, zoom) {\n\t var domEvents = this.domEvents;\n\t if (!domEvents) {\n\t return;\n\t }\n\n\t if (domEvents.toggleDrag) {\n\t domEvents.toggleDrag(drag);\n\t }\n\n\t if (domEvents.toggleZoom) {\n\t domEvents.toggleZoom(zoom);\n\t }\n\t },\n\n\t _createTooltip: function() {\n\t var ref = this;\n\t var tooltipOptions = ref.options.tooltip;\n\t var tooltip;\n\n\t if (this._sharedTooltip()) {\n\t tooltip = this._createSharedTooltip(tooltipOptions);\n\t } else {\n\t tooltip = new Tooltip(this.chartService, tooltipOptions);\n\t }\n\n\t return tooltip;\n\t },\n\n\t _createSharedTooltip: function(options) {\n\t return new SharedTooltip(this._plotArea, options);\n\t },\n\n\t applyDefaults: function(options, themeOptions) {\n\t applyAxisDefaults(options, themeOptions);\n\t applySeriesDefaults(options, themeOptions);\n\t },\n\n\t applySeriesColors: function() {\n\t var options = this.options;\n\t var series = options.series;\n\t var colors = options.seriesColors || [];\n\n\t for (var i = 0; i < series.length; i++) {\n\t var currentSeries = series[i];\n\t var seriesColor = colors[i % colors.length];\n\t var defaults = currentSeries._defaults;\n\n\t currentSeries.color = currentSeries.color || seriesColor;\n\t if (defaults) {\n\t defaults.color = defaults.color || seriesColor;\n\t }\n\t }\n\t },\n\n\t _getModel: function() {\n\t var options = this.options;\n\t var plotArea = this._createPlotArea();\n\t var model = new dataviz.RootElement(this._modelOptions());\n\t model.chart = this;\n\t model._plotArea = plotArea;\n\n\t dataviz.Title.buildTitle(options.title, model);\n\n\t if (options.legend && options.legend.visible) {\n\t model.append(new Legend(plotArea.options.legend, this.chartService));\n\t }\n\t model.append(plotArea);\n\t model.reflow();\n\n\t return model;\n\t },\n\n\t _modelOptions: function() {\n\t var options = this.options;\n\t var size = this.getSize();\n\n\t return deepExtend({\n\t transitions: options.transitions,\n\t width: size.width || datavizConstants.DEFAULT_WIDTH,\n\t height: size.height || datavizConstants.DEFAULT_HEIGHT\n\t }, options.chartArea);\n\t },\n\n\t _createPlotArea: function(skipSeries) {\n\t var options = this.options;\n\n\t var plotArea = PlotAreaFactory.current.create(skipSeries ? [] : options.series, options, this.chartService);\n\n\t return plotArea;\n\t },\n\n\t _setupSelection: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var axes = ref._plotArea.axes;\n\t var selections = this._selections = [];\n\n\t for (var i = 0; i < axes.length; i++) {\n\t var axis = axes[i];\n\t var options = axis.options;\n\t if (axis instanceof CategoryAxis && options.select && !options.vertical) {\n\t var range = axis.range();\n\n\t var selection = new Selection(this$1, axis,\n\t deepExtend({ min: range.min, max: range.max }, options.select)\n\t );\n\n\t selections.push(selection);\n\t }\n\t }\n\t },\n\n\t _selectStart: function(e) {\n\t return this.trigger(SELECT_START, e);\n\t },\n\n\t _select: function(e) {\n\t return this.trigger(SELECT, e);\n\t },\n\n\t _selectEnd: function(e) {\n\t return this.trigger(SELECT_END, e);\n\t },\n\n\t _initHandlers: function() {\n\t this._clickHandler = this._click.bind(this);\n\t this._mousewheelHandler = this._mousewheel.bind(this);\n\t this._mouseleaveHandler = this._mouseleave.bind(this);\n\t this._surfaceMouseenterHandler = this._mouseover.bind(this);\n\t this._surfaceMouseleaveHandler = this._mouseout.bind(this);\n\n\t this._mousemove = kendo.throttle(\n\t this._mousemove.bind(this),\n\t MOUSEMOVE_DELAY\n\t );\n\t },\n\n\t addObserver: function(observer) {\n\t if (observer) {\n\t this.observers.push(observer);\n\t }\n\t },\n\n\t removeObserver: function(observer) {\n\t var index = this.observers.indexOf(observer);\n\t if (index >= 0) {\n\t this.observers.splice(index, 1);\n\t }\n\t },\n\n\t requiresHandlers: function(eventNames) {\n\t var observers = this.observers;\n\t for (var idx = 0; idx < observers.length; idx++) {\n\t if (observers[idx].requiresHandlers(eventNames)) {\n\t return true;\n\t }\n\t }\n\t },\n\n\t trigger: function(name, args) {\n\t if (args === void 0) { args = {}; }\n\n\t if (name === SHOW_TOOLTIP) {\n\t args.anchor.point = this._toDocumentCoordinates(args.anchor.point);\n\t }\n\t args.sender = this;\n\n\t var observers = this.observers;\n\t var isDefaultPrevented = false;\n\t for (var idx = 0; idx < observers.length; idx++) {\n\t if (observers[idx].trigger(name, args)) {\n\t isDefaultPrevented = true;\n\t }\n\t }\n\n\t return isDefaultPrevented;\n\t },\n\n\t _attachEvents: function() {\n\t var element = this.element;\n\n\t this._touchAction = element.style.touchAction;\n\n\t var obj;\n\t bindEvents(element, ( obj = {}, obj[ CONTEXTMENU ] = this._clickHandler, obj[ MOUSEWHEEL ] = this._mousewheelHandler, obj[ MOUSELEAVE ] = this._mouseleaveHandler, obj ));\n\n\t if (this._shouldAttachMouseMove()) {\n\t var obj$1;\n\t bindEvents(element, ( obj$1 = {}, obj$1[ MOUSEMOVE ] = this._mousemove, obj$1 ));\n\t }\n\n\t this.domEvents = services.DomEventsBuilder.create(this.element, {\n\t start: this._start.bind(this),\n\t move: this._move.bind(this),\n\t end: this._end.bind(this),\n\t tap: this._tap.bind(this),\n\t gesturestart: this._gesturestart.bind(this),\n\t gesturechange: this._gesturechange.bind(this),\n\t gestureend: this._gestureend.bind(this)\n\t });\n\n\t this._toggleDragZoomEvents();\n\t },\n\n\t _mouseleave: function(e) {\n\t if (this._hoveredPoint) {\n\t this._hoveredPoint.out(this, e);\n\t this._hoveredPoint = null;\n\t }\n\n\t if (this._plotArea.hovered) {\n\t this.trigger(PLOT_AREA_LEAVE);\n\t this._plotArea.hovered = false;\n\t }\n\t },\n\n\t _cancelDomEvents: function() {\n\t if (this.domEvents && this.domEvents.cancel) {\n\t this.domEvents.cancel();\n\t }\n\t },\n\n\t _gesturestart: function(e) {\n\t if (this._mousewheelZoom && !this._stopChartHandlers(e)) {\n\t this._gestureDistance = e.distance;\n\t this._unsetActivePoint();\n\t this.surface.suspendTracking();\n\t }\n\t },\n\n\t _gestureend: function(e) {\n\t if (this._zooming && !this._stopChartHandlers(e)) {\n\t if (this.surface) {\n\t this.surface.resumeTracking();\n\t }\n\t this._zooming = false;\n\t this.trigger(ZOOM_END, {});\n\t }\n\t },\n\n\t _gesturechange: function(e) {\n\t var mousewheelZoom = this._mousewheelZoom;\n\n\t if (mousewheelZoom && !this._stopChartHandlers(e)) {\n\t e.preventDefault();\n\t var previousGestureDistance = this._gestureDistance;\n\t var scaleDelta = -e.distance / previousGestureDistance + 1;\n\n\t if (Math.abs(scaleDelta) >= 0.1) {\n\t scaleDelta = Math.round(scaleDelta * 10);\n\n\t this._gestureDistance = e.distance;\n\t var args = { delta: scaleDelta, axisRanges: axisRanges(this._plotArea.axes), originalEvent: e };\n\t if (this._zooming || !this.trigger(ZOOM_START, args)) {\n\n\t if (!this._zooming) {\n\t this._zooming = true;\n\t }\n\n\t var ranges = args.axisRanges = mousewheelZoom.updateRanges(scaleDelta);\n\t if (ranges && !this.trigger(ZOOM, args)) {\n\t mousewheelZoom.zoom();\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t _mouseout: function(e) {\n\t if (e.element) {\n\t var element = this._drawingChartElement(e.element, e);\n\n\t if (element && element.leave) {\n\t element.leave(this, e.originalEvent);\n\t }\n\t }\n\t },\n\n\t _start: function(e) {\n\t var coords = this._eventCoordinates(e);\n\n\t if (this._stopChartHandlers(e) || !this._plotArea.backgroundContainsPoint(coords)) {\n\t return;\n\t }\n\n\t if (this.requiresHandlers([ DRAG_START, DRAG, DRAG_END ])) {\n\t this._startNavigation(e, coords, DRAG_START);\n\t }\n\n\t if (this._pannable && this._pannable.start(e)) {\n\t this.surface.suspendTracking();\n\t this._unsetActivePoint();\n\t this._suppressHover = true;\n\t this.chartService.panning = true;\n\t }\n\n\t if (this._zoomSelection) {\n\t if (this._zoomSelection.start(e)) {\n\t this.trigger(ZOOM_START, { axisRanges: axisRanges(this._plotArea.axes), originalEvent: e });\n\t }\n\t }\n\t },\n\n\t _move: function(e) {\n\t var ref = this;\n\t var state = ref._navState;\n\t var pannable = ref._pannable;\n\n\t if (this._stopChartHandlers(e)) {\n\t return;\n\t }\n\n\t if (pannable) {\n\t var ranges = pannable.move(e);\n\n\t if (ranges && !this.trigger(DRAG, { axisRanges: ranges, originalEvent: e })) {\n\t pannable.pan();\n\t }\n\t } else if (state) {\n\t var ranges$1 = {};\n\t var axes = state.axes;\n\n\t for (var i = 0; i < axes.length; i++) {\n\t var currentAxis = axes[i];\n\t var axisName = currentAxis.options.name;\n\t if (axisName) {\n\t var axis = currentAxis.options.vertical ? e.y : e.x;\n\t var delta = axis.startLocation - axis.location;\n\n\t if (delta !== 0) {\n\t ranges$1[currentAxis.options.name] = currentAxis.translateRange(delta);\n\t }\n\t }\n\t }\n\n\t state.axisRanges = ranges$1;\n\t this.trigger(DRAG, {\n\t axisRanges: ranges$1,\n\t originalEvent: e\n\t });\n\t }\n\n\t if (this._zoomSelection) {\n\t this._zoomSelection.move(e);\n\t }\n\t },\n\n\t _end: function(e) {\n\t if (this._stopChartHandlers(e)) {\n\t return;\n\t }\n\n\t var pannable = this._pannable;\n\t if (pannable && pannable.end(e)) {\n\t this.surface.resumeTracking();\n\t this.trigger(DRAG_END, {\n\t axisRanges: axisRanges(this._plotArea.axes),\n\t originalEvent: e\n\t });\n\t this._suppressHover = false;\n\t this.chartService.panning = false;\n\t } else {\n\t this._endNavigation(e, DRAG_END);\n\t }\n\n\t if (this._zoomSelection) {\n\t var ranges = this._zoomSelection.end(e);\n\t if (ranges && !this.trigger(ZOOM, { axisRanges: ranges, originalEvent: e })) {\n\t this._zoomSelection.zoom();\n\t this.trigger(ZOOM_END, { axisRanges: ranges, originalEvent: e });\n\t }\n\t }\n\t },\n\n\t _stopChartHandlers: function(e) {\n\t var selections = this._selections || [];\n\t if (!selections.length) {\n\t return false;\n\t }\n\n\t var coords = this._eventCoordinates(e);\n\t var pane = this._plotArea.paneByPoint(coords);\n\t if (pane) {\n\t for (var idx = 0; idx < selections.length; idx++) {\n\t if (selections[idx].onPane(pane)) {\n\t return true;\n\t }\n\t }\n\t }\n\t },\n\n\t _mousewheel: function(e) {\n\t var this$1 = this;\n\n\t var delta = dataviz.mousewheelDelta(e);\n\t var mousewheelZoom = this._mousewheelZoom;\n\t var coords = this._eventCoordinates(e);\n\n\t if (this._stopChartHandlers(e) || !this._plotArea.backgroundContainsPoint(coords)) {\n\t return;\n\t }\n\n\t if (mousewheelZoom) {\n\t var args = { delta: delta, axisRanges: axisRanges(this._plotArea.axes), originalEvent: e };\n\t if (this._zooming || !this.trigger(ZOOM_START, args)) {\n\t e.preventDefault();\n\n\t if (!this._zooming) {\n\t this._unsetActivePoint();\n\t this.surface.suspendTracking();\n\t this._zooming = true;\n\t }\n\n\t if (this._mwTimeout) {\n\t clearTimeout(this._mwTimeout);\n\t }\n\n\t args.axisRanges = mousewheelZoom.updateRanges(delta);\n\t if (args.axisRanges && !this.trigger(ZOOM, args)) {\n\t mousewheelZoom.zoom();\n\t }\n\n\t this._mwTimeout = setTimeout(function () {\n\t this$1.trigger(ZOOM_END, args);\n\t this$1._zooming = false;\n\t if (this$1.surface) {\n\t this$1.surface.resumeTracking();\n\t }\n\t }, MOUSEWHEEL_DELAY);\n\t }\n\t } else {\n\t var state = this._navState;\n\t if (!state) {\n\t var prevented = this._startNavigation(e, coords, ZOOM_START);\n\t if (!prevented) {\n\t state = this._navState;\n\t }\n\t }\n\n\t if (state) {\n\t var totalDelta = state.totalDelta || delta;\n\t state.totalDelta = totalDelta + delta;\n\n\t var axes = this._navState.axes;\n\t var ranges = {};\n\n\t for (var i = 0; i < axes.length; i++) {\n\t var currentAxis = axes[i];\n\t var axisName = currentAxis.options.name;\n\t if (axisName) {\n\t ranges[axisName] = currentAxis.scaleRange(-totalDelta);\n\t }\n\t }\n\n\t this.trigger(ZOOM, {\n\t delta: delta,\n\t axisRanges: ranges,\n\t originalEvent: e\n\t });\n\n\t if (this._mwTimeout) {\n\t clearTimeout(this._mwTimeout);\n\t }\n\n\t this._mwTimeout = setTimeout(function () {\n\t this$1._endNavigation(e, ZOOM_END);\n\t }, MOUSEWHEEL_DELAY);\n\t }\n\t }\n\t },\n\n\t _startNavigation: function(e, coords, chartEvent) {\n\t var plotArea = this._model._plotArea;\n\t var pane = plotArea.findPointPane(coords);\n\t var axes = plotArea.axes.slice(0);\n\n\t if (!pane) {\n\t return;\n\t }\n\n\t var ranges = axisRanges(axes);\n\n\t var prevented = this.trigger(chartEvent, {\n\t axisRanges: ranges,\n\t originalEvent: e\n\t });\n\n\t if (prevented) {\n\t this._cancelDomEvents();\n\t } else {\n\t this._suppressHover = true;\n\t this._unsetActivePoint();\n\t this._navState = {\n\t axisRanges: ranges,\n\t pane: pane,\n\t axes: axes\n\t };\n\t }\n\t },\n\n\t _endNavigation: function(e, chartEvent) {\n\t if (this._navState) {\n\t this.trigger(chartEvent, {\n\t axisRanges: this._navState.axisRanges,\n\t originalEvent: e\n\t });\n\t this._suppressHover = false;\n\t this._navState = null;\n\t }\n\t },\n\n\t _getChartElement: function(e, match) {\n\t var element = this.surface.eventTarget(e);\n\t if (element) {\n\t return this._drawingChartElement(element, e, match);\n\t }\n\t },\n\n\t _drawingChartElement: function(element, e, match) {\n\t var current = element;\n\t var chartElement;\n\t while (current && !chartElement) {\n\t chartElement = current.chartElement;\n\t current = current.parent;\n\t }\n\n\t if (chartElement) {\n\t if (chartElement.aliasFor) {\n\t chartElement = chartElement.aliasFor(e, this._eventCoordinates(e));\n\t }\n\n\t if (match) {\n\t chartElement = chartElement.closest(match);\n\t if (chartElement && chartElement.aliasFor) {\n\t chartElement = chartElement.aliasFor();\n\t }\n\t }\n\n\t return chartElement;\n\t }\n\t },\n\n\t _eventCoordinates: function(e) {\n\t var coordinates = dataviz.eventCoordinates(e);\n\t return this._toModelCoordinates(coordinates.x, coordinates.y);\n\t },\n\n\t _elementPadding: function() {\n\t if (!this._padding) {\n\t var ref = elementStyles(this.element, [ \"paddingLeft\", \"paddingTop\" ]);\n\t var paddingLeft = ref.paddingLeft;\n\t var paddingTop = ref.paddingTop;\n\t this._padding = {\n\t top: paddingTop,\n\t left: paddingLeft\n\t };\n\t }\n\n\t return this._padding;\n\t },\n\n\t _toDocumentCoordinates: function(point) {\n\t var padding = this._elementPadding();\n\t var offset = dataviz.elementOffset(this.element);\n\n\t return {\n\t left: round(point.x + padding.left + offset.left),\n\t top: round(point.y + padding.top + offset.top)\n\t };\n\t },\n\n\t _toModelCoordinates: function(clientX, clientY) {\n\t var element = this.element;\n\t var offset = dataviz.elementOffset(element);\n\t var padding = this._elementPadding();\n\n\t return new Point(\n\t clientX - offset.left - padding.left,\n\t clientY - offset.top - padding.top\n\t );\n\t },\n\n\t _tap: function(e) {\n\t var this$1 = this;\n\n\t var drawingElement = this.surface.eventTarget(e);\n\t var element = this._drawingChartElement(drawingElement, e);\n\t var sharedTooltip = this._sharedTooltip();\n\n\t if (!this._startHover(drawingElement, e) && !sharedTooltip) {\n\t this._unsetActivePoint();\n\t }\n\n\t if (sharedTooltip) {\n\t this._trackSharedTooltip(this._eventCoordinates(e), e, true);\n\t }\n\n\t this._propagateClick(element, e);\n\n\t //part of fix for hover issue on windows touch\n\t this.handlingTap = true;\n\t setTimeout(function () {\n\t this$1.handlingTap = false;\n\t }, 0);\n\t },\n\n\t _click: function(e) {\n\t var element = this._getChartElement(e);\n\t this._propagateClick(element, e);\n\t },\n\n\t _propagateClick: function(element, e) {\n\t var this$1 = this;\n\n\t var current = element;\n\t while (current) {\n\t if (current.click) {\n\t current.click(this$1, e);\n\t }\n\n\t current = current.parent;\n\t }\n\t },\n\n\t _startHover: function(element, e) {\n\t if (this._suppressHover) {\n\t return false;\n\t }\n\n\t var point = this._drawingChartElement(element, e, function(element) {\n\t return (element.hover || element.over) && !(element instanceof PlotAreaBase);\n\t });\n\n\t var activePoint = this._activePoint;\n\t var hoveredPoint = this._hoveredPoint;\n\n\t if (hoveredPoint && hoveredPoint !== point) {\n\t hoveredPoint.out(this, e);\n\t this._hoveredPoint = null;\n\t }\n\n\t if (point && hoveredPoint !== point && point.over) {\n\t this._hoveredPoint = point;\n\t point.over(this, e);\n\t }\n\n\t if (point && activePoint !== point && point.hover) {\n\t this._activePoint = point;\n\n\t if (!this._sharedTooltip() && !point.hover(this, e)) {\n\t var tooltipOptions = deepExtend({}, this.options.tooltip, point.options.tooltip);\n\t if (tooltipOptions.visible) {\n\t this._tooltip.show(point);\n\t }\n\n\t this._highlight.show(point);\n\t }\n\t }\n\n\t return point;\n\t },\n\n\t _mouseover: function(e) {\n\t var point = this._startHover(e.element, e.originalEvent);\n\n\t if (point && point.tooltipTracking && !this._mouseMoveTrackHandler && !this._sharedTooltip()) {\n\t this._mouseMoveTrackHandler = this._mouseMoveTracking.bind(this);\n\t var obj;\n\t bindEvents(document, ( obj = {}, obj[ MOUSEMOVE ] = this._mouseMoveTrackHandler, obj ));\n\t }\n\t },\n\n\t _mouseMoveTracking: function(e) {\n\t var ref = this;\n\t var options = ref.options;\n\t var tooltip = ref._tooltip;\n\t var highlight = ref._highlight;\n\t var point = ref._activePoint;\n\t var coords = this._eventCoordinates(e);\n\n\t if (this._plotArea.box.containsPoint(coords)) {\n\t if (point && point.tooltipTracking && point.series && point.parent.getNearestPoint) {\n\t var seriesPoint = point.parent.getNearestPoint(coords.x, coords.y, point.seriesIx);\n\t if (seriesPoint && seriesPoint !== point) {\n\t this._activePoint = seriesPoint;\n\n\t if (!seriesPoint.hover(this, e)) {\n\t var tooltipOptions = deepExtend({}, options.tooltip, seriesPoint.options.tooltip);\n\t if (tooltipOptions.visible) {\n\t tooltip.show(seriesPoint);\n\t }\n\n\t highlight.show(seriesPoint);\n\t }\n\t }\n\t }\n\t } else {\n\t var obj;\n\t unbindEvents(document, ( obj = {}, obj[ MOUSEMOVE ] = this._mouseMoveTrackHandler, obj ));\n\t this._unsetActivePoint();\n\t this._mouseMoveTrackHandler = null;\n\t }\n\t },\n\n\t _mousemove: function(e) {\n\t var coords = this._eventCoordinates(e);\n\t var plotArea = this._plotArea;\n\n\t this._trackCrosshairs(coords);\n\n\t if (plotArea.hover) {\n\t var overPlotArea = plotArea.backgroundContainsPoint(coords);\n\t if (overPlotArea) {\n\t plotArea.hovered = true;\n\t this._plotArea.hover(this, e);\n\t } else if (plotArea.hovered && !overPlotArea) {\n\t this.trigger(PLOT_AREA_LEAVE);\n\t plotArea.hovered = false;\n\t }\n\t }\n\n\t if (this._sharedTooltip()) {\n\t this._trackSharedTooltip(coords, e);\n\t }\n\t },\n\n\t _trackCrosshairs: function(coords) {\n\t var crosshairs = this._plotArea.crosshairs;\n\n\t for (var i = 0; i < crosshairs.length; i++) {\n\t var current = crosshairs[i];\n\n\t if (current.box.containsPoint(coords)) {\n\t current.showAt(coords);\n\t } else {\n\t current.hide();\n\t }\n\t }\n\t },\n\n\t _trackSharedTooltip: function(coords, e, toggle) {\n\t if (this._suppressHover) {\n\t return;\n\t }\n\n\t var ref = this;\n\t var tooltipOptions = ref.options.tooltip;\n\t var plotArea = ref._plotArea;\n\t var categoryAxis = ref._plotArea.categoryAxis;\n\t var tooltip = ref._tooltip;\n\t var highlight = ref._highlight;\n\n\t if (plotArea.backgroundContainsPoint(coords)) {\n\t var index = categoryAxis.pointCategoryIndex(coords);\n\t if (index !== this._tooltipCategoryIx || (!this._sharedHighlight && toggle)) {\n\t var points = plotArea.pointsByCategoryIndex(index);\n\t var pointArgs = points.map(function(point) {\n\t return point.eventArgs(e);\n\t });\n\t var hoverArgs = pointArgs[0] || {};\n\t hoverArgs.categoryPoints = pointArgs;\n\n\t if (points.length > 0 && !this.trigger(SERIES_HOVER, hoverArgs)) {\n\t if (tooltipOptions.visible) {\n\t tooltip.showAt(points, coords);\n\t }\n\n\t highlight.show(points);\n\n\t this._sharedHighlight = true;\n\t } else {\n\t tooltip.hide();\n\t }\n\n\t this._tooltipCategoryIx = index;\n\t } else if (toggle && this._sharedHighlight) {\n\t highlight.hide();\n\t tooltip.hide();\n\t this._sharedHighlight = false;\n\t }\n\t } else if (this._sharedHighlight) {\n\t highlight.hide();\n\t tooltip.hide();\n\t this._tooltipCategoryIx = null;\n\t this._sharedHighlight = false;\n\t }\n\t },\n\n\t hideElements: function() {\n\t var plotArea = this._plotArea;\n\t this._mousemove.cancel();\n\n\t plotArea.hideCrosshairs();\n\n\t this._unsetActivePoint();\n\t },\n\n\t _unsetActivePoint: function() {\n\t var ref = this;\n\t var tooltip = ref._tooltip;\n\t var highlight = ref._highlight;\n\n\t this._activePoint = null;\n\t this._hoveredPoint = null;\n\n\t if (tooltip) {\n\t tooltip.hide();\n\t }\n\n\t this._tooltipCategoryIx = null;\n\t this._sharedHighlight = false;\n\n\t if (highlight) {\n\t highlight.hide();\n\t }\n\t },\n\n\t _deferRedraw: function() {\n\t this._redraw();\n\t },\n\n\t _clearRedrawTimeout: function() {\n\t if (this._redrawTimeout) {\n\t clearInterval(this._redrawTimeout);\n\t this._redrawTimeout = null;\n\t }\n\t },\n\n\t bindCategories: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var definitions = [].concat(options.categoryAxis);\n\n\t for (var axisIx = 0; axisIx < definitions.length; axisIx++) {\n\t var axis = definitions[axisIx];\n\t if (axis.autoBind !== false) {\n\t this$1.bindCategoryAxisFromSeries(axis, axisIx);\n\t }\n\t }\n\t },\n\n\t bindCategoryAxisFromSeries: function(axis, axisIx) {\n\t var this$1 = this;\n\n\t var series = this.options.series;\n\t var seriesLength = series.length;\n\t var uniqueCategories = new dataviz.HashMap();//perf improvement in case type category with dates\n\t var items = [];\n\t var bindable = false;\n\t var dateAxis;\n\n\t for (var seriesIx = 0; seriesIx < seriesLength; seriesIx++) {\n\t var s = series[seriesIx];\n\t var onAxis = s.categoryAxis === axis.name || (!s.categoryAxis && axisIx === 0);\n\t var data = s.data;\n\t var dataLength = data.length;\n\t var bind = s.categoryField && onAxis;\n\t bindable = bind || bindable;\n\n\t if (bind && dataLength > 0) {\n\t dateAxis = isDateAxis(axis, getField(s.categoryField, data[0]));\n\n\t var getFn = dateAxis ? getDateField : getField;\n\n\t for (var dataIx = 0; dataIx < dataLength; dataIx++) {\n\t var dataRow = data[dataIx];\n\t var category = getFn(s.categoryField, dataRow, this$1.chartService.intl);\n\n\t if (dateAxis || !uniqueCategories.get(category)) {\n\t items.push([ category, dataRow ]);\n\n\t if (!dateAxis) {\n\t uniqueCategories.set(category, true);\n\t }\n\t }\n\t }\n\t }\n\t }\n\n\t if (items.length > 0) {\n\t if (dateAxis) {\n\t items = uniqueDates(items, function(a, b) {\n\t return dataviz.dateComparer(a[0], b[0]);\n\t });\n\t }\n\n\t var result = transpose(items);\n\t axis.categories = result[0];\n\t } else if (bindable) {\n\t axis.categories = [];\n\t }\n\t },\n\n\t _isBindable: function(series) {\n\t var valueFields = SeriesBinder.current.valueFields(series);\n\t var result = true;\n\n\t for (var i = 0; i < valueFields.length; i++) {\n\t var field = valueFields[i];\n\t if (field === VALUE) {\n\t field = \"field\";\n\t } else {\n\t field = field + \"Field\";\n\t }\n\n\t if (!defined(series[field])) {\n\t result = false;\n\t break;\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t _noTransitionsRedraw: function() {\n\t var options = this.options;\n\t var transitionsState;\n\n\t if (options.transitions !== false) {\n\t options.transitions = false;\n\t transitionsState = true;\n\t }\n\n\t this._redraw();\n\n\t if (transitionsState) {\n\t options.transitions = true;\n\t }\n\t },\n\n\t _legendItemHover: function(seriesIndex, pointIndex) {\n\t var ref = this;\n\t var plotArea = ref._plotArea;\n\t var highlight = ref._highlight;\n\t var currentSeries = (plotArea.srcSeries || plotArea.series)[seriesIndex];\n\t var items;\n\n\t if (inArray(currentSeries.type, [ PIE, DONUT, FUNNEL ])) {\n\t items = plotArea.findPoint(function(point) {\n\t return point.series.index === seriesIndex && point.index === pointIndex;\n\t });\n\t } else {\n\t items = plotArea.pointsBySeriesIndex(seriesIndex);\n\t }\n\n\t highlight.show(items);\n\t },\n\n\t _shouldAttachMouseMove: function() {\n\t return this._plotArea.crosshairs.length || (this._tooltip && this._sharedTooltip()) || this.requiresHandlers([ PLOT_AREA_HOVER, PLOT_AREA_LEAVE ]);\n\t },\n\n\t updateMouseMoveHandler: function() {\n\t var obj;\n\t unbindEvents(this.element, ( obj = {}, obj[ MOUSEMOVE ] = this._mousemove, obj ));\n\n\t if (this._shouldAttachMouseMove()) {\n\t var obj$1;\n\t bindEvents(this.element, ( obj$1 = {}, obj$1[ MOUSEMOVE ] = this._mousemove, obj$1 ));\n\t }\n\t },\n\n\t applyOptions: function(options, theme) {\n\t clearMissingValues(this._originalOptions, options);\n\t this._originalOptions = deepExtend(this._originalOptions, options);\n\t this.options = deepExtend({}, this._originalOptions);\n\n\t if (theme) {\n\t this._theme = theme;\n\t this.chartService.theme = theme;\n\t }\n\t this._initTheme(this.options, this._theme);\n\n\t this._toggleDragZoomEvents();\n\t },\n\n\t setOptions: function(options, theme) {\n\t this.applyOptions(options, theme);\n\t this.bindCategories();\n\t this.redraw();\n\t this.updateMouseMoveHandler();\n\t },\n\n\t setDirection: function(rtl) {\n\t this.chartService.rtl = Boolean(rtl);\n\t if (this.surface && this.surface.type === 'svg') {\n\t this._destroySurface();\n\t }\n\t },\n\n\t setIntlService: function(intl) {\n\t this.chartService.intl = intl;\n\t },\n\n\t noTransitionsRedraw: function() {\n\t this._noTransitionsRedraw();\n\t },\n\n\t destroy: function() {\n\t this._destroyed = true;\n\n\t var obj;\n\t unbindEvents(this.element, ( obj = {}, obj[ CONTEXTMENU ] = this._clickHandler, obj[ MOUSEWHEEL ] = this._mousewheelHandler, obj[ MOUSEMOVE ] = this._mousemove, obj[ MOUSELEAVE ] = this._mouseleaveHandler, obj ));\n\n\t if (this.domEvents) {\n\t this.domEvents.destroy();\n\t delete this.domEvents;\n\t }\n\n\t if (this._mouseMoveTrackHandler) {\n\t var obj$1;\n\t unbindEvents(document, ( obj$1 = {}, obj$1[ MOUSEMOVE ] = this._mouseMoveTrackHandler, obj$1 ));\n\t }\n\n\t this._destroyView();\n\n\t this._destroySurface();\n\n\t this._clearRedrawTimeout();\n\t },\n\n\t _destroySurface: function() {\n\t var surface = this.surface;\n\t if (surface) {\n\t surface.unbind(\"mouseenter\", this._surfaceMouseenterHandler);\n\t surface.unbind(\"mouseleave\", this._surfaceMouseleaveHandler);\n\t surface.destroy();\n\n\t this.surface = null;\n\t }\n\t },\n\n\t _destroySelections: function() {\n\t var selections = this._selections;\n\n\t if (selections) {\n\t while (selections.length > 0) {\n\t selections.shift().destroy();\n\t }\n\t }\n\t },\n\n\t _destroyView: function() {\n\t var model = this._model;\n\n\t if (model) {\n\t model.destroy();\n\t this._model = null;\n\t }\n\n\t this._unsetActivePoint();\n\n\t this._destroySelections();\n\n\t if (this._tooltip) {\n\t this._tooltip.destroy();\n\t }\n\n\t if (this._highlight) {\n\t this._highlight.destroy();\n\t }\n\n\t if (this._zoomSelection) {\n\t this._zoomSelection.destroy();\n\t delete this._zoomSelection;\n\t }\n\n\t if (this._pannable) {\n\t this._pannable.destroy();\n\t delete this._pannable;\n\t }\n\n\t if (this._mousewheelZoom) {\n\t this._mousewheelZoom.destroy();\n\t delete this._mousewheelZoom;\n\t }\n\t }\n\t});\n\n\tfunction resolveAxisAliases(options) {\n\t var aliases = AXIS_NAMES;\n\n\t for (var idx = 0; idx < aliases.length; idx++) {\n\t var alias = aliases[idx] + \"Axes\";\n\t if (options[alias]) {\n\t options[aliases[idx] + \"Axis\"] = options[alias];\n\t delete options[alias];\n\t }\n\t }\n\t}\n\n\tfunction pointByCategoryName(points, name) {\n\t if (points) {\n\t for (var idx = 0; idx < points.length; idx++) {\n\t if (points[idx].category === name) {\n\t return [ points[idx] ];\n\t }\n\t }\n\t }\n\t}\n\n\tfunction applyAxisDefaults(options, themeOptions) {\n\t var themeAxisDefaults = ((themeOptions || {}).axisDefaults) || {};\n\t var axisName, axisDefaults, axes;\n\n\t function mapAxisOptions(axisOptions) {\n\t var axisColor = (axisOptions || {}).color || axisDefaults.color;\n\t var result = deepExtend({},\n\t themeAxisDefaults,\n\t themeAxisDefaults[axisName],\n\t axisDefaults,\n\t axisDefaults[axisName], {\n\t line: { color: axisColor },\n\t labels: { color: axisColor },\n\t title: { color: axisColor }\n\t },\n\t axisOptions\n\t );\n\n\t delete result[axisName];\n\n\t return result;\n\t }\n\n\t for (var idx = 0; idx < AXIS_NAMES.length; idx++) {\n\t axisName = AXIS_NAMES[idx] + \"Axis\";\n\t axisDefaults = options.axisDefaults || {};\n\t axes = [].concat(options[axisName]);\n\n\t axes = axes.map(mapAxisOptions);\n\n\t options[axisName] = axes.length > 1 ? axes : axes[0];\n\t }\n\t}\n\n\tfunction applySeriesDefaults(options, themeOptions) {\n\t var series = options.series;\n\t var seriesLength = series.length;\n\t var seriesDefaults = options.seriesDefaults;\n\t var commonDefaults = deepExtend({}, options.seriesDefaults);\n\t var themeSeriesDefaults = themeOptions ? deepExtend({}, themeOptions.seriesDefaults) : {};\n\t var commonThemeDefaults = deepExtend({}, themeSeriesDefaults);\n\n\t cleanupNestedSeriesDefaults(commonDefaults);\n\t cleanupNestedSeriesDefaults(commonThemeDefaults);\n\n\t for (var i = 0; i < seriesLength; i++) {\n\t var seriesType = series[i].type || options.seriesDefaults.type;\n\n\t var baseOptions = deepExtend(\n\t { data: [] },\n\t commonThemeDefaults,\n\t themeSeriesDefaults[seriesType],\n\t { tooltip: options.tooltip },\n\t commonDefaults,\n\t seriesDefaults[seriesType]\n\t );\n\n\t series[i]._defaults = baseOptions;\n\t series[i] = deepExtend({}, baseOptions, series[i]);\n\t series[i].data = series[i].data || [];\n\t }\n\t}\n\n\tfunction cleanupNestedSeriesDefaults(seriesDefaults) {\n\t delete seriesDefaults.bar;\n\t delete seriesDefaults.column;\n\t delete seriesDefaults.rangeColumn;\n\t delete seriesDefaults.line;\n\t delete seriesDefaults.verticalLine;\n\t delete seriesDefaults.pie;\n\t delete seriesDefaults.donut;\n\t delete seriesDefaults.area;\n\t delete seriesDefaults.verticalArea;\n\t delete seriesDefaults.scatter;\n\t delete seriesDefaults.scatterLine;\n\t delete seriesDefaults.bubble;\n\t delete seriesDefaults.candlestick;\n\t delete seriesDefaults.ohlc;\n\t delete seriesDefaults.boxPlot;\n\t delete seriesDefaults.bullet;\n\t delete seriesDefaults.verticalBullet;\n\t delete seriesDefaults.polarArea;\n\t delete seriesDefaults.polarLine;\n\t delete seriesDefaults.radarArea;\n\t delete seriesDefaults.radarLine;\n\t delete seriesDefaults.waterfall;\n\t}\n\n\tfunction axisRanges(axes) {\n\t var ranges = {};\n\n\t for (var i = 0; i < axes.length; i++) {\n\t var axis = axes[i];\n\t var axisName = axis.options.name;\n\t if (axisName) {\n\t ranges[axisName] = axis.range();\n\t }\n\t }\n\n\t return ranges;\n\t}\n\n\tfunction sortDates(dates, comparer) {\n\t if (comparer === void 0) { comparer = dataviz.dateComparer; }\n\n\t for (var i = 1, length = dates.length; i < length; i++) {\n\t if (comparer(dates[i], dates[i - 1]) < 0) {\n\t dates.sort(comparer);\n\t break;\n\t }\n\t }\n\n\t return dates;\n\t}\n\n\tfunction uniqueDates(srcDates, comparer) {\n\t if (comparer === void 0) { comparer = dataviz.dateComparer; }\n\n\t var dates = sortDates(srcDates, comparer);\n\t var length = dates.length;\n\t var result = length > 0 ? [ dates[0] ] : [];\n\n\t for (var i = 1; i < length; i++) {\n\t if (comparer(dates[i], last(result)) !== 0) {\n\t result.push(dates[i]);\n\t }\n\t }\n\n\t return result;\n\t}\n\n\tfunction transpose(rows) {\n\t var rowCount = rows.length;\n\t var result = [];\n\n\t for (var rowIx = 0; rowIx < rowCount; rowIx++) {\n\t var row = rows[rowIx];\n\t var colCount = row.length;\n\n\t for (var colIx = 0; colIx < colCount; colIx++) {\n\t result[colIx] = result[colIx] || [];\n\t result[colIx].push(row[colIx]);\n\t }\n\t }\n\n\t return result;\n\t}\n\n\tvar DATA_FIELDS = [ 'data', 'categories' ];\n\n\tfunction clearMissingValues(originalOptions, options) {\n\t for (var field in options) {\n\t if (!inArray(field, DATA_FIELDS) && options.hasOwnProperty(field)) {\n\t var fieldValue = options[field];\n\t var originalValue = originalOptions[field];\n\t if (defined(originalValue)) {\n\t var nullValue = fieldValue === null;\n\t if ((nullValue || !defined(fieldValue))) {\n\t delete originalOptions[field];\n\t if (nullValue) {\n\t delete options[field];\n\t }\n\t } else if (originalValue && isObject(fieldValue)) {\n\t if (isObject(originalValue)) {\n\t clearMissingValues(originalValue, fieldValue);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t}\n\n\tfunction triggerPaneRender(panes) {\n\t for (var idx = 0; idx < panes.length; idx++) {\n\t panes[idx].notifyRender();\n\t }\n\t}\n\n\tsetDefaultOptions(Chart, {\n\t renderAs: \"\",\n\t chartArea: {},\n\t legend: {\n\t visible: true,\n\t labels: {}\n\t },\n\t categoryAxis: {},\n\t seriesDefaults: {\n\t type: COLUMN,\n\t data: [],\n\t highlight: {\n\t visible: true\n\t },\n\t labels: {},\n\t negativeValues: {\n\t visible: false\n\t }\n\t },\n\t series: [],\n\t seriesColors: null,\n\t tooltip: {\n\t visible: false\n\t },\n\t transitions: true,\n\t valueAxis: {},\n\t plotArea: {},\n\t title: {},\n\t xAxis: {},\n\t yAxis: {},\n\t panes: [ {} ],\n\t pannable: false,\n\t zoomable: false\n\t});\n\n\tkendo.deepExtend(kendo.dataviz, {\n\t constants: constants,\n\t Aggregates: Aggregates,\n\t AreaChart: AreaChart,\n\t AreaSegment: AreaSegment,\n\t AxisGroupRangeTracker: AxisGroupRangeTracker,\n\t Bar: Bar,\n\t BarChart: BarChart,\n\t BarLabel: BarLabel,\n\t BoxPlotChart: BoxPlotChart,\n\t BoxPlot: BoxPlot,\n\t BubbleChart: BubbleChart,\n\t Bullet: Bullet,\n\t BulletChart: BulletChart,\n\t CandlestickChart: CandlestickChart,\n\t Candlestick: Candlestick,\n\t CategoricalChart: CategoricalChart,\n\t CategoricalErrorBar: CategoricalErrorBar,\n\t CategoricalPlotArea: CategoricalPlotArea,\n\t Chart: Chart,\n\t ChartContainer: ChartContainer,\n\t ClipAnimation: ClipAnimation,\n\t ClusterLayout: ClusterLayout,\n\t Crosshair: Crosshair,\n\t CrosshairTooltip: CrosshairTooltip,\n\t DefaultAggregates: DefaultAggregates,\n\t DonutChart: DonutChart,\n\t DonutPlotArea: DonutPlotArea,\n\t DonutSegment: DonutSegment,\n\t ErrorBarBase: ErrorBarBase,\n\t ErrorRangeCalculator: ErrorRangeCalculator,\n\t Highlight: Highlight,\n\t SharedTooltip: SharedTooltip,\n\t Legend: Legend,\n\t LegendItem: LegendItem,\n\t LegendLayout: LegendLayout,\n\t LineChart: LineChart,\n\t LinePoint: LinePoint,\n\t LineSegment: LineSegment,\n\t Pane: Pane,\n\t PieAnimation: PieAnimation,\n\t PieChart: PieChart,\n\t PieChartMixin: PieChartMixin,\n\t PiePlotArea: PiePlotArea,\n\t PieSegment: PieSegment,\n\t PlotAreaBase: PlotAreaBase,\n\t PlotAreaEventsMixin: PlotAreaEventsMixin,\n\t PlotAreaFactory: PlotAreaFactory,\n\t PointEventsMixin: PointEventsMixin,\n\t RangeBar: RangeBar,\n\t RangeBarChart: RangeBarChart,\n\t RangeAreaPoint: RangeAreaPoint,\n\t RangeAreaChart: RangeAreaChart,\n\t ScatterChart: ScatterChart,\n\t ScatterErrorBar: ScatterErrorBar,\n\t ScatterLineChart: ScatterLineChart,\n\t Selection: Selection,\n\t SeriesAggregator: SeriesAggregator,\n\t SeriesBinder: SeriesBinder,\n\t SplineSegment: SplineSegment,\n\t SplineAreaSegment: SplineAreaSegment,\n\t StackWrap: StackWrap,\n\t Tooltip: Tooltip,\n\t OHLCChart: OHLCChart,\n\t OHLCPoint: OHLCPoint,\n\t WaterfallChart: WaterfallChart,\n\t WaterfallSegment: WaterfallSegment,\n\t XYPlotArea: XYPlotArea,\n\t MousewheelZoom: MousewheelZoom,\n\t ZoomSelection: ZoomSelection,\n\t Pannable: Pannable,\n\t ChartAxis: ChartAxis,\n\t ChartPane: ChartPane,\n\t ChartPlotArea: ChartPlotArea,\n\t findAxisByName: findAxisByName,\n\t anyHasZIndex: anyHasZIndex,\n\t appendIfNotNull: appendIfNotNull,\n\t areNumbers: areNumbers,\n\t bindSegments: bindSegments,\n\t categoriesCount: categoriesCount,\n\t countNumbers: countNumbers,\n\t equalsIgnoreCase: equalsIgnoreCase,\n\t evalOptions: evalOptions,\n\t filterSeriesByType: filterSeriesByType,\n\t getDateField: getDateField,\n\t getField: getField,\n\t hasGradientOverlay: hasGradientOverlay,\n\t hasValue: hasValue,\n\t isDateAxis: isDateAxis,\n\t segmentVisible: segmentVisible,\n\t singleItemOrArray: singleItemOrArray,\n\t createOutOfRangePoints: createOutOfRangePoints\n\t});\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ }),\n\n/***/ 863:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.core\");\n\n/***/ }),\n\n/***/ 864:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.color\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(865);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 865:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(866)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\t var dataviz = kendo.dataviz;\n\t var services = dataviz.services;\n\t var draw = kendo.drawing;\n\n\t dataviz.SASS_THEMES = [\"sass\", \"default-v2\", \"bootstrap-v4\", \"material-v2\"];\n\n\t dataviz.ExportMixin = {\n\t extend: function(proto, skipLegacy) {\n\t if (!proto.exportVisual) {\n\t throw new Error(\"Mixin target has no exportVisual method defined.\");\n\t }\n\n\t proto.exportSVG = this.exportSVG;\n\t proto.exportImage = this.exportImage;\n\t proto.exportPDF = this.exportPDF;\n\n\t if (!skipLegacy) {\n\t proto.svg = this.svg;\n\t proto.imageDataURL = this.imageDataURL;\n\t }\n\t },\n\n\t exportSVG: function(options) {\n\t return draw.exportSVG(this.exportVisual(), options);\n\t },\n\n\t exportImage: function(options) {\n\t return draw.exportImage(this.exportVisual(options), options);\n\t },\n\n\t exportPDF: function(options) {\n\t return draw.exportPDF(this.exportVisual(), options);\n\t },\n\n\t svg: function() {\n\t if (draw.svg.Surface) {\n\t return draw.svg.exportGroup(this.exportVisual());\n\t } else {\n\t throw new Error(\"SVG Export failed. Unable to export instantiate kendo.drawing.svg.Surface\");\n\t }\n\t },\n\n\t imageDataURL: function() {\n\t if (!kendo.support.canvas) {\n\t return null;\n\t }\n\n\t if (draw.canvas.Surface) {\n\t var container = $(\"
\").css({\n\t display: \"none\",\n\t width: this.element.width(),\n\t height: this.element.height()\n\t }).appendTo(document.body);\n\n\t var surface = new draw.canvas.Surface(container[0]);\n\t surface.draw(this.exportVisual());\n\t var image = surface._rootElement.toDataURL();\n\n\t surface.destroy();\n\t container.remove();\n\n\t return image;\n\t } else {\n\t throw new Error(\"Image Export failed. Unable to export instantiate kendo.drawing.canvas.Surface\");\n\t }\n\t }\n\t };\n\n\t services.IntlService.register({\n\t format: function(format) {\n\t return kendo.format.apply(null, [format].concat(Array.prototype.slice.call(arguments, 1)));\n\t },\n\t toString: kendo.toString,\n\t parseDate: kendo.parseDate\n\t });\n\n\t services.TemplateService.register({\n\t compile: kendo.template\n\t });\n\n\t dataviz.Point2D = dataviz.Point;\n\t dataviz.Box2D = dataviz.Box;\n\t dataviz.mwDelta = function(e) {\n\t return dataviz.mousewheelDelta(e.originalEvent);\n\t };\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ }),\n\n/***/ 866:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo-core\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(867);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 860:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.drawing\");\n\n/***/ }),\n\n/***/ 863:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.core\");\n\n/***/ }),\n\n/***/ 867:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/***********************************************************************\n\t * WARNING: this file is auto-generated. If you change it directly,\n\t * your modifications will eventually be lost. The source code is in\n\t * `kendo-charts` repository, you should make your changes there and\n\t * run `src-modules/sync.sh` in this repository.\n\t */\n\t(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(863),\n\t __webpack_require__(860)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\t/* jshint curly:false */\n\n\twindow.kendo.dataviz = window.kendo.dataviz || {};\n\tvar drawing = kendo.drawing;\n\tvar util = drawing.util;\n\tvar Path = drawing.Path;\n\tvar Group = drawing.Group;\n\tvar Class = kendo.Class;\n\tvar geometry = kendo.geometry;\n\tvar Rect = geometry.Rect;\n\tvar Circle = geometry.Circle;\n\tvar geometryTransform = geometry.transform;\n\tvar Segment = geometry.Segment;\n\tvar dataviz = kendo.dataviz;\n\n\tvar deepExtend = kendo.deepExtend;\n\tvar isFunction = kendo.isFunction;\n\tvar __common_getter_js = kendo.getter;\n\n\tvar ARC = \"arc\";\n\tvar AXIS_LABEL_CLICK = \"axisLabelClick\";\n\tvar BLACK = \"#000\";\n\tvar BOTTOM = \"bottom\";\n\tvar CENTER = \"center\";\n\tvar CIRCLE = \"circle\";\n\tvar COORD_PRECISION = 3;\n\tvar CROSS = \"cross\";\n\tvar DATE = \"date\";\n\tvar DEFAULT_FONT = \"12px sans-serif\";\n\tvar DEFAULT_HEIGHT = 400;\n\tvar DEFAULT_PRECISION = 10;\n\tvar DEFAULT_WIDTH = 600;\n\tvar END = \"end\";\n\tvar FORMAT_REGEX = /\\{\\d+:?/;\n\tvar HEIGHT = \"height\";\n\tvar HIGHLIGHT_ZINDEX = 100;\n\tvar INSIDE = \"inside\";\n\tvar LEFT = \"left\";\n\tvar MAX_VALUE = Number.MAX_VALUE;\n\tvar MIN_VALUE = -Number.MAX_VALUE;\n\tvar NONE = \"none\";\n\tvar NOTE_CLICK = \"noteClick\";\n\tvar NOTE_HOVER = \"noteHover\";\n\tvar NOTE_LEAVE = \"noteLeave\";\n\tvar OBJECT = \"object\";\n\tvar OUTSIDE = \"outside\";\n\tvar RIGHT = \"right\";\n\tvar START = \"start\";\n\tvar STRING = \"string\";\n\tvar TOP = \"top\";\n\tvar TRIANGLE = \"triangle\";\n\tvar VALUE = \"value\";\n\tvar WHITE = \"#fff\";\n\tvar WIDTH = \"width\";\n\tvar X = \"x\";\n\tvar Y = \"y\";\n\n\tvar constants = {\n\t\tARC: ARC,\n\t\tAXIS_LABEL_CLICK: AXIS_LABEL_CLICK,\n\t\tBLACK: BLACK,\n\t\tBOTTOM: BOTTOM,\n\t\tCENTER: CENTER,\n\t\tCIRCLE: CIRCLE,\n\t\tCOORD_PRECISION: COORD_PRECISION,\n\t\tCROSS: CROSS,\n\t\tDATE: DATE,\n\t\tDEFAULT_FONT: DEFAULT_FONT,\n\t\tDEFAULT_HEIGHT: DEFAULT_HEIGHT,\n\t\tDEFAULT_PRECISION: DEFAULT_PRECISION,\n\t\tDEFAULT_WIDTH: DEFAULT_WIDTH,\n\t\tEND: END,\n\t\tFORMAT_REGEX: FORMAT_REGEX,\n\t\tHEIGHT: HEIGHT,\n\t\tHIGHLIGHT_ZINDEX: HIGHLIGHT_ZINDEX,\n\t\tINSIDE: INSIDE,\n\t\tLEFT: LEFT,\n\t\tMAX_VALUE: MAX_VALUE,\n\t\tMIN_VALUE: MIN_VALUE,\n\t\tNONE: NONE,\n\t\tNOTE_CLICK: NOTE_CLICK,\n\t\tNOTE_HOVER: NOTE_HOVER,\n\t\tNOTE_LEAVE: NOTE_LEAVE,\n\t\tOBJECT: OBJECT,\n\t\tOUTSIDE: OUTSIDE,\n\t\tRIGHT: RIGHT,\n\t\tSTART: START,\n\t\tSTRING: STRING,\n\t\tTOP: TOP,\n\t\tTRIANGLE: TRIANGLE,\n\t\tVALUE: VALUE,\n\t\tWHITE: WHITE,\n\t\tWIDTH: WIDTH,\n\t\tX: X,\n\t\tY: Y\n\t};\n\n\tfunction isArray(value) {\n\t return Array.isArray(value);\n\t}\n\n\tfunction addClass(element, classes) {\n\t var classArray = isArray(classes) ? classes : [ classes ];\n\n\t for (var idx = 0; idx < classArray.length; idx++) {\n\t var className = classArray[idx];\n\t if (element.className.indexOf(className) === -1) {\n\t element.className += \" \" + className;\n\t }\n\t }\n\t}\n\n\tvar SPACE_REGEX = /\\s+/g;\n\n\tfunction removeClass(element, className) {\n\t if (element && element.className) {\n\t element.className = element.className.replace(className, \"\").replace(SPACE_REGEX, \" \");\n\t }\n\t}\n\n\tfunction alignPathToPixel(path) {\n\t var offset = 0.5;\n\t if (path.options.stroke && kendo.drawing.util.defined(path.options.stroke.width)) {\n\t if (path.options.stroke.width % 2 === 0) {\n\t offset = 0;\n\t }\n\t }\n\n\t for (var i = 0; i < path.segments.length; i++) {\n\t path.segments[i].anchor().round(0).translate(offset, offset);\n\t }\n\n\t return path;\n\t}\n\n\tfunction clockwise(angle1, angle2) {\n\t // True if angle2 is clockwise of angle1\n\t // assuming angles grow in clock-wise direction\n\t // (as in the pie and radar charts)\n\t return -angle1.x * angle2.y + angle1.y * angle2.x < 0;\n\t}\n\n\tfunction isNumber(value) {\n\t return typeof value === \"number\" && !isNaN(value);\n\t}\n\n\tfunction isString(value) {\n\t return typeof value === STRING;\n\t}\n\n\tfunction convertableToNumber(value) {\n\t return isNumber(value) || (isString(value) && isFinite(value));\n\t}\n\n\tfunction isObject(value) {\n\t return typeof value === \"object\";\n\t}\n\n\tfunction styleValue(value) {\n\t if (isNumber(value)) {\n\t return value + \"px\";\n\t }\n\t return value;\n\t}\n\n\tvar SIZE_STYLES_REGEX = /width|height|top|left|bottom|right/i;\n\n\tfunction isSizeField(field) {\n\t return SIZE_STYLES_REGEX.test(field);\n\t}\n\n\tfunction elementStyles(element, styles) {\n\t var stylesArray = isString(styles) ? [ styles ] : styles;\n\n\t if (isArray(stylesArray)) {\n\t var result = {};\n\t var style = window.getComputedStyle(element);\n\n\t for (var idx = 0; idx < stylesArray.length; idx++) {\n\t var field = stylesArray[idx];\n\t result[field] = isSizeField(field) ? parseFloat(style[field]) : style[field];\n\t }\n\n\t return result;\n\t } else if (isObject(styles)) {\n\t for (var field$1 in styles) {\n\t element.style[field$1] = styleValue(styles[field$1]);\n\t }\n\t }\n\t}\n\n\tfunction getSpacing(value, defaultSpacing) {\n\t if (defaultSpacing === void 0) { defaultSpacing = 0; }\n\n\t var spacing = { top: 0, right: 0, bottom: 0, left: 0 };\n\n\t if (typeof(value) === \"number\") {\n\t spacing[TOP] = spacing[RIGHT] = spacing[BOTTOM] = spacing[LEFT] = value;\n\t } else {\n\t spacing[TOP] = value[TOP] || defaultSpacing;\n\t spacing[RIGHT] = value[RIGHT] || defaultSpacing;\n\t spacing[BOTTOM] = value[BOTTOM] || defaultSpacing;\n\t spacing[LEFT] = value[LEFT] || defaultSpacing;\n\t }\n\n\t return spacing;\n\t}\n\n\tvar defaultImplementation = {\n\t format: function (format, value) { return value; },\n\n\t toString: function (value) { return value; },\n\n\t parseDate: function (value) { return new Date(value); }\n\t};\n\n\tvar current = defaultImplementation;\n\n\tvar IntlService = Class.extend({\n\n\t});\n\n\tIntlService.register = function(userImplementation) {\n\t current = userImplementation;\n\t};\n\n\tif (Object.defineProperties) {\n\t Object.defineProperties(IntlService, {\n\t implementation: {\n\t get: function() {\n\t return current;\n\t }\n\t }\n\t });\n\t}\n\n\tvar FORMAT_REPLACE_REGEX = /\\{(\\d+)(:[^\\}]+)?\\}/g;\n\n\tvar FormatService = Class.extend({\n\t init: function(intlService) {\n\t this._intlService = intlService;\n\t },\n\n\t auto: function(formatString) {\n\t var values = [], len = arguments.length - 1;\n\t while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];\n\n\t var intl = this.intl;\n\n\t if (isString(formatString) && formatString.match(FORMAT_REGEX)) {\n\t return intl.format.apply(intl, [ formatString ].concat( values ));\n\t }\n\n\t return intl.toString(values[0], formatString);\n\t },\n\n\t localeAuto: function(formatString, values, locale) {\n\t var intl = this.intl;\n\t var result;\n\n\t if (isString(formatString) && formatString.match(FORMAT_REGEX)) {\n\t result = formatString.replace(FORMAT_REPLACE_REGEX, function(match, index, placeholderFormat) {\n\t var value = values[parseInt(index, 10)];\n\n\t return intl.toString(value, placeholderFormat ? placeholderFormat.substring(1) : \"\", locale);\n\t });\n\t } else {\n\t result = intl.toString(values[0], formatString, locale);\n\t }\n\n\t return result;\n\t }\n\t});\n\n\tif (Object.defineProperties) {\n\t Object.defineProperties(FormatService.fn, {\n\t intl: {\n\t get: function() {\n\t return this._intlService || IntlService.implementation;\n\t },\n\t set: function(value) {\n\t this._intlService = value;\n\t }\n\t }\n\t });\n\t}\n\n\tvar ChartService = Class.extend({\n\t init: function(chart, context) {\n\t if (context === void 0) { context = {}; }\n\n\t this._intlService = context.intlService;\n\t this.sender = context.sender || chart;\n\t this.format = new FormatService(context.intlService);\n\t this.chart = chart;\n\t this.rtl = Boolean(context.rtl);\n\t },\n\n\t notify: function(name, args) {\n\t if (this.chart) {\n\t this.chart.trigger(name, args);\n\t }\n\t },\n\n\t isPannable: function(axis) {\n\t var pannable = ((this.chart || {}).options || {}).pannable;\n\t return pannable && pannable.lock !== axis;\n\t }\n\t});\n\n\tif (Object.defineProperties) {\n\t Object.defineProperties(ChartService.fn, {\n\t intl: {\n\t get: function() {\n\t return this._intlService || IntlService.implementation;\n\t },\n\t set: function(value) {\n\t this._intlService = value;\n\t this.format.intl = value;\n\t }\n\t }\n\t });\n\t}\n\n\tvar current$1;\n\n\tvar DomEventsBuilder = Class.extend({\n\n\t});\n\n\tDomEventsBuilder.register = function(userImplementation) {\n\t current$1 = userImplementation;\n\t};\n\n\tDomEventsBuilder.create = function(element, events) {\n\t if (current$1) {\n\t return current$1.create(element, events);\n\t }\n\t};\n\n\tvar current$2 = {\n\t compile: function(template) {\n\t return template;\n\t }\n\t};\n\n\tvar TemplateService = Class.extend({\n\n\t});\n\n\tTemplateService.register = function(userImplementation) {\n\t current$2 = userImplementation;\n\t};\n\n\tTemplateService.compile = function(template) {\n\t return current$2.compile(template);\n\t};\n\n\tvar services = {\n\t\tChartService: ChartService,\n\t\tDomEventsBuilder: DomEventsBuilder,\n\t\tFormatService: FormatService,\n\t\tIntlService: IntlService,\n\t\tTemplateService: TemplateService\n\t};\n\n\tfunction getTemplate(options) {\n\t if (options === void 0) { options = {}; }\n\n\t var template;\n\t if (options.template) {\n\t options.template = template = TemplateService.compile(options.template);\n\t } else if (isFunction(options.content)) {\n\t template = options.content;\n\t }\n\n\t return template;\n\t}\n\n\tfunction grep(array, callback) {\n\t var length = array.length;\n\t var result = [];\n\t for (var idx = 0; idx < length; idx++) {\n\t if (callback(array[idx])) {\n\t result .push(array[idx]);\n\t }\n\t }\n\n\t return result;\n\t}\n\n\tfunction hasClasses(element, classNames) {\n\t if (element.className) {\n\t var names = classNames.split(\" \");\n\t for (var idx = 0; idx < names.length; idx++) {\n\t if (element.className.indexOf(names[idx]) !== -1) {\n\t return true;\n\t }\n\t }\n\t }\n\t}\n\n\tvar HashMap = function HashMap() {\n\t this._map = {};\n\t};\n\n\tHashMap.prototype.get = function get (name) {\n\t return this._map[this._key(name)];\n\t};\n\n\tHashMap.prototype.set = function set (name, value) {\n\t this._map[this._key(name)] = value;\n\t};\n\n\tHashMap.prototype._key = function _key (name) {\n\t return name instanceof Date ? name.getTime() : name;\n\t};\n\n\tfunction inArray(value, array) {\n\t if (array) {\n\t return array.indexOf(value) !== -1;\n\t }\n\t}\n\n\tfunction interpolateValue(start, end, progress) {\n\t return kendo.drawing.util.round(start + (end - start) * progress, COORD_PRECISION);\n\t}\n\n\tvar TRIGGER = 'trigger';\n\n\tvar InstanceObserver = Class.extend({\n\t init: function(observer, handlers) {\n\t this.observer = observer;\n\t this.handlerMap = deepExtend({}, this.handlerMap, handlers);\n\t },\n\n\t trigger: function(name, args) {\n\t var ref = this;\n\t var observer = ref.observer;\n\t var handlerMap = ref.handlerMap;\n\t var isDefaultPrevented;\n\t if (handlerMap[name]) {\n\t isDefaultPrevented = this.callObserver(handlerMap[name], args);\n\t } else if (observer[TRIGGER]) {\n\t isDefaultPrevented = this.callObserver(TRIGGER, name, args);\n\t }\n\n\t return isDefaultPrevented;\n\t },\n\n\t callObserver: function(fnName) {\n\t var args = [], len = arguments.length - 1;\n\t while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];\n\n\t return this.observer[fnName].apply(this.observer, args);\n\t },\n\n\t requiresHandlers: function(names) {\n\t var this$1 = this;\n\n\t if (this.observer.requiresHandlers) {\n\t return this.observer.requiresHandlers(names);\n\t }\n\n\t for (var idx = 0; idx < names.length; idx++) {\n\t if (this$1.handlerMap[names[idx]]) {\n\t return true;\n\t }\n\t }\n\t }\n\t});\n\n\tfunction map(array, callback) {\n\t var length = array.length;\n\t var result = [];\n\t for (var idx = 0; idx < length; idx++) {\n\t var value = callback(array[idx]);\n\t if (kendo.drawing.util.defined(value)) {\n\t result.push(value);\n\t }\n\t }\n\t return result;\n\t}\n\n\tfunction mousewheelDelta(e) {\n\t var delta = 0;\n\n\t if (e.wheelDelta) {\n\t delta = -e.wheelDelta / 120;\n\t delta = delta > 0 ? Math.ceil(delta) : Math.floor(delta);\n\t }\n\n\t if (e.detail) {\n\t delta = kendo.drawing.util.round(e.detail / 3);\n\t }\n\n\t return delta;\n\t}\n\n\tvar ref = kendo.drawing.util;\n\tvar append = ref.append;\n\tvar bindEvents = ref.bindEvents;\n\tvar defined = ref.defined;\n\tvar deg = ref.deg;\n\tvar elementOffset = ref.elementOffset;\n\tvar elementSize = ref.elementSize;\n\tvar eventElement = ref.eventElement;\n\tvar eventCoordinates = ref.eventCoordinates;\n\tvar last = ref.last;\n\tvar limitValue = ref.limitValue;\n\tvar objectKey = ref.objectKey;\n\tvar rad = ref.rad;\n\tvar round = ref.round;\n\tvar unbindEvents = ref.unbindEvents;\n\tvar valueOrDefault = ref.valueOrDefault;\n\n\tvar FontLoader = Class.extend({\n\n\t});\n\n\tFontLoader.fetchFonts = function(options, fonts, state) {\n\t if (state === void 0) { state = { depth: 0 }; }\n\n\t var MAX_DEPTH = 5;\n\n\t if (!options || state.depth > MAX_DEPTH || !document.fonts) {\n\t return;\n\t }\n\n\t Object.keys(options).forEach(function(key) {\n\t var value = options[key];\n\t if (key === \"dataSource\" || key[0] === \"$\" || !value) {\n\t return;\n\t }\n\n\t if (key === \"font\") {\n\t fonts.push(value);\n\t } else if (typeof value === \"object\") {\n\t state.depth++;\n\t FontLoader.fetchFonts(value, fonts, state);\n\t state.depth--;\n\t }\n\t });\n\t};\n\n\tFontLoader.loadFonts = function(fonts, callback) {\n\t var promises = [];\n\n\t if (fonts.length > 0 && document.fonts) {\n\t try {\n\t promises = fonts.map(function(font) {\n\t return document.fonts.load(font);\n\t });\n\t } catch (e) {\n\t // Silence font-loading errors\n\t kendo.logToConsole(e);\n\t }\n\n\t Promise.all(promises).then(callback, callback);\n\t } else {\n\t callback();\n\t }\n\t};\n\n\tFontLoader.preloadFonts = function(options, callback) {\n\t var fonts = [];\n\t FontLoader.fetchFonts(options, fonts);\n\n\t FontLoader.loadFonts(fonts, callback);\n\t};\n\n\tfunction setDefaultOptions(type, options) {\n\t var proto = type.prototype;\n\t if (proto.options) {\n\t proto.options = deepExtend({}, proto.options, options);\n\t } else {\n\t proto.options = options;\n\t }\n\t}\n\n\tfunction sparseArrayLimits(arr) {\n\t var min = MAX_VALUE;\n\t var max = MIN_VALUE;\n\n\t for (var idx = 0, length = arr.length; idx < length; idx++) {\n\t var value = arr[idx];\n\t if (value !== null && isFinite(value)) {\n\t min = Math.min(min, value);\n\t max = Math.max(max, value);\n\t }\n\t }\n\n\t return {\n\t min: min === MAX_VALUE ? undefined : min,\n\t max: max === MIN_VALUE ? undefined : max\n\t };\n\t}\n\n\tfunction find(array, predicate) {\n\t for (var i = 0; i < array.length; i++) {\n\t var item = array[i];\n\t if (predicate(item, i, array)) {\n\t return item;\n\t }\n\t }\n\t}\n\n\tfunction autoMajorUnit(min, max) {\n\t var diff = round(max - min, DEFAULT_PRECISION - 1);\n\n\t if (diff === 0) {\n\t if (max === 0) {\n\t return 0.1;\n\t }\n\n\t diff = Math.abs(max);\n\t }\n\n\t var scale = Math.pow(10, Math.floor(Math.log(diff) / Math.log(10)));\n\t var relativeValue = round((diff / scale), DEFAULT_PRECISION);\n\t var scaleMultiplier = 1;\n\n\t if (relativeValue < 1.904762) {\n\t scaleMultiplier = 0.2;\n\t } else if (relativeValue < 4.761904) {\n\t scaleMultiplier = 0.5;\n\t } else if (relativeValue < 9.523809) {\n\t scaleMultiplier = 1;\n\t } else {\n\t scaleMultiplier = 2;\n\t }\n\n\t return round(scale * scaleMultiplier, DEFAULT_PRECISION);\n\t}\n\n\tvar Point = Class.extend({\n\t init: function(x, y) {\n\n\t this.x = x || 0;\n\t this.y = y || 0;\n\t },\n\n\t clone: function() {\n\t return new Point(this.x, this.y);\n\t },\n\n\t equals: function(point) {\n\t return point && this.x === point.x && this.y === point.y;\n\t },\n\n\t rotate: function(center, degrees) {\n\t var theta = rad(degrees);\n\t var cosT = Math.cos(theta);\n\t var sinT = Math.sin(theta);\n\t var cx = center.x;\n\t var cy = center.y;\n\t var ref = this;\n\t var x = ref.x;\n\t var y = ref.y;\n\n\t this.x = round(\n\t cx + (x - cx) * cosT + (y - cy) * sinT,\n\t COORD_PRECISION\n\t );\n\n\t this.y = round(\n\t cy + (y - cy) * cosT - (x - cx) * sinT,\n\t COORD_PRECISION\n\t );\n\n\t return this;\n\t },\n\n\t multiply: function(a) {\n\n\t this.x *= a;\n\t this.y *= a;\n\n\t return this;\n\t },\n\n\t distanceTo: function(point) {\n\t var dx = this.x - point.x;\n\t var dy = this.y - point.y;\n\n\t return Math.sqrt(dx * dx + dy * dy);\n\t }\n\t});\n\n\tPoint.onCircle = function(center, angle, radius) {\n\t var radians = rad(angle);\n\n\t return new Point(\n\t center.x - radius * Math.cos(radians),\n\t center.y - radius * Math.sin(radians)\n\t );\n\t};\n\n\tvar Box = Class.extend({\n\t init: function(x1, y1, x2, y2) {\n\n\t this.x1 = x1 || 0;\n\t this.y1 = y1 || 0;\n\t this.x2 = x2 || 0;\n\t this.y2 = y2 || 0;\n\t },\n\n\t equals: function(box) {\n\t return this.x1 === box.x1 && this.x2 === box.x2 &&\n\t this.y1 === box.y1 && this.y2 === box.y2;\n\t },\n\n\t width: function() {\n\t return this.x2 - this.x1;\n\t },\n\n\t height: function() {\n\t return this.y2 - this.y1;\n\t },\n\n\t translate: function(dx, dy) {\n\t this.x1 += dx;\n\t this.x2 += dx;\n\t this.y1 += dy;\n\t this.y2 += dy;\n\n\t return this;\n\t },\n\n\t move: function(x, y) {\n\t var height = this.height();\n\t var width = this.width();\n\n\t if (defined(x)) {\n\t this.x1 = x;\n\t this.x2 = this.x1 + width;\n\t }\n\n\t if (defined(y)) {\n\t this.y1 = y;\n\t this.y2 = this.y1 + height;\n\t }\n\n\t return this;\n\t },\n\n\t wrap: function(targetBox) {\n\t this.x1 = Math.min(this.x1, targetBox.x1);\n\t this.y1 = Math.min(this.y1, targetBox.y1);\n\t this.x2 = Math.max(this.x2, targetBox.x2);\n\t this.y2 = Math.max(this.y2, targetBox.y2);\n\n\t return this;\n\t },\n\n\t wrapPoint: function(point) {\n\t var arrayPoint = isArray(point);\n\t var x = arrayPoint ? point[0] : point.x;\n\t var y = arrayPoint ? point[1] : point.y;\n\t this.wrap(new Box(x, y, x, y));\n\n\t return this;\n\t },\n\n\t snapTo: function(targetBox, axis) {\n\n\t if (axis === X || !axis) {\n\t this.x1 = targetBox.x1;\n\t this.x2 = targetBox.x2;\n\t }\n\n\t if (axis === Y || !axis) {\n\t this.y1 = targetBox.y1;\n\t this.y2 = targetBox.y2;\n\t }\n\n\t return this;\n\t },\n\n\t alignTo: function(targetBox, anchor) {\n\t var height = this.height();\n\t var width = this.width();\n\t var axis = anchor === TOP || anchor === BOTTOM ? Y : X;\n\t var offset = axis === Y ? height : width;\n\n\t if (anchor === CENTER) {\n\t var targetCenter = targetBox.center();\n\t var center = this.center();\n\n\t this.x1 += targetCenter.x - center.x;\n\t this.y1 += targetCenter.y - center.y;\n\t } else if (anchor === TOP || anchor === LEFT) {\n\t this[axis + 1] = targetBox[axis + 1] - offset;\n\t } else {\n\t this[axis + 1] = targetBox[axis + 2];\n\t }\n\n\t this.x2 = this.x1 + width;\n\t this.y2 = this.y1 + height;\n\n\t return this;\n\t },\n\n\t shrink: function(dw, dh) {\n\n\t this.x2 -= dw;\n\t this.y2 -= dh;\n\n\t return this;\n\t },\n\n\t expand: function(dw, dh) {\n\t this.shrink(-dw, -dh);\n\t return this;\n\t },\n\n\t pad: function(padding) {\n\t var spacing = getSpacing(padding);\n\n\t this.x1 -= spacing.left;\n\t this.x2 += spacing.right;\n\t this.y1 -= spacing.top;\n\t this.y2 += spacing.bottom;\n\n\t return this;\n\t },\n\n\t unpad: function(padding) {\n\t var spacing = getSpacing(padding);\n\n\t spacing.left = -spacing.left;\n\t spacing.top = -spacing.top;\n\t spacing.right = -spacing.right;\n\t spacing.bottom = -spacing.bottom;\n\n\t return this.pad(spacing);\n\t },\n\n\t clone: function() {\n\t return new Box(this.x1, this.y1, this.x2, this.y2);\n\t },\n\n\t center: function() {\n\t return new Point(\n\t this.x1 + this.width() / 2,\n\t this.y1 + this.height() / 2\n\t );\n\t },\n\n\t containsPoint: function(point) {\n\n\t return point.x >= this.x1 && point.x <= this.x2 &&\n\t point.y >= this.y1 && point.y <= this.y2;\n\t },\n\n\t points: function() {\n\t return [\n\t new Point(this.x1, this.y1),\n\t new Point(this.x2, this.y1),\n\t new Point(this.x2, this.y2),\n\t new Point(this.x1, this.y2)\n\t ];\n\t },\n\n\t getHash: function() {\n\t return [ this.x1, this.y1, this.x2, this.y2 ].join(\",\");\n\t },\n\n\t overlaps: function(box) {\n\t return !(box.y2 < this.y1 || this.y2 < box.y1 || box.x2 < this.x1 || this.x2 < box.x1);\n\t },\n\n\t rotate: function(rotation) {\n\t var width = this.width();\n\t var height = this.height();\n\t var ref = this.center();\n\t var cx = ref.x;\n\t var cy = ref.y;\n\n\t var r1 = rotatePoint(0, 0, cx, cy, rotation);\n\t var r2 = rotatePoint(width, 0, cx, cy, rotation);\n\t var r3 = rotatePoint(width, height, cx, cy, rotation);\n\t var r4 = rotatePoint(0, height, cx, cy, rotation);\n\n\t width = Math.max(r1.x, r2.x, r3.x, r4.x) - Math.min(r1.x, r2.x, r3.x, r4.x);\n\t height = Math.max(r1.y, r2.y, r3.y, r4.y) - Math.min(r1.y, r2.y, r3.y, r4.y);\n\n\t this.x2 = this.x1 + width;\n\t this.y2 = this.y1 + height;\n\n\t return this;\n\t },\n\n\t toRect: function() {\n\t return new Rect([ this.x1, this.y1 ], [ this.width(), this.height() ]);\n\t },\n\n\t hasSize: function() {\n\t return this.width() !== 0 && this.height() !== 0;\n\t },\n\n\t align: function(targetBox, axis, alignment) {\n\t var c1 = axis + 1;\n\t var c2 = axis + 2;\n\t var sizeFunc = axis === X ? WIDTH : HEIGHT;\n\t var size = this[sizeFunc]();\n\n\t if (inArray(alignment, [ LEFT, TOP ])) {\n\t this[c1] = targetBox[c1];\n\t this[c2] = this[c1] + size;\n\t } else if (inArray(alignment, [ RIGHT, BOTTOM ])) {\n\t this[c2] = targetBox[c2];\n\t this[c1] = this[c2] - size;\n\t } else if (alignment === CENTER) {\n\t this[c1] = targetBox[c1] + (targetBox[sizeFunc]() - size) / 2;\n\t this[c2] = this[c1] + size;\n\t }\n\t }\n\t});\n\n\tfunction rotatePoint(x, y, cx, cy, angle) {\n\t var theta = rad(angle);\n\n\t return new Point(\n\t cx + (x - cx) * Math.cos(theta) + (y - cy) * Math.sin(theta),\n\t cy - (x - cx) * Math.sin(theta) + (y - cy) * Math.cos(theta)\n\t );\n\t}\n\n\tvar Ring = Class.extend({\n\t init: function(center, innerRadius, radius, startAngle, angle) {\n\n\t this.center = center;\n\t this.innerRadius = innerRadius;\n\t this.radius = radius;\n\t this.startAngle = startAngle;\n\t this.angle = angle;\n\t },\n\n\t clone: function() {\n\t return new Ring(this.center, this.innerRadius, this.radius, this.startAngle, this.angle);\n\t },\n\n\t middle: function() {\n\t return this.startAngle + this.angle / 2;\n\t },\n\n\t setRadius: function(newRadius, innerRadius) {\n\t if (innerRadius) {\n\t this.innerRadius = newRadius;\n\t } else {\n\t this.radius = newRadius;\n\t }\n\n\t return this;\n\t },\n\n\t point: function(angle, innerRadius) {\n\t var radianAngle = rad(angle);\n\t var ax = Math.cos(radianAngle);\n\t var ay = Math.sin(radianAngle);\n\t var radius = innerRadius ? this.innerRadius : this.radius;\n\t var x = round(this.center.x - (ax * radius), COORD_PRECISION);\n\t var y = round(this.center.y - (ay * radius), COORD_PRECISION);\n\n\t return new Point(x, y);\n\t },\n\n\t adjacentBox: function(distance, width, height) {\n\t var sector = this.clone().expand(distance);\n\t var midAndle = sector.middle();\n\t var midPoint = sector.point(midAndle);\n\t var hw = width / 2;\n\t var hh = height / 2;\n\t var sa = Math.sin(rad(midAndle));\n\t var ca = Math.cos(rad(midAndle));\n\t var x = midPoint.x - hw;\n\t var y = midPoint.y - hh;\n\n\t if (Math.abs(sa) < 0.9) {\n\t x += hw * -ca / Math.abs(ca);\n\t }\n\n\t if (Math.abs(ca) < 0.9) {\n\t y += hh * -sa / Math.abs(sa);\n\t }\n\n\t return new Box(x, y, x + width, y + height);\n\t },\n\n\t containsPoint: function(p) {\n\t var center = this.center;\n\t var innerRadius = this.innerRadius;\n\t var radius = this.radius;\n\t var startAngle = this.startAngle;\n\t var endAngle = this.startAngle + this.angle;\n\t var dx = p.x - center.x;\n\t var dy = p.y - center.y;\n\t var vector = new Point(dx, dy);\n\t var startPoint = this.point(startAngle);\n\t var startVector = new Point(startPoint.x - center.x, startPoint.y - center.y);\n\t var endPoint = this.point(endAngle);\n\t var endVector = new Point(endPoint.x - center.x, endPoint.y - center.y);\n\t var dist = round(dx * dx + dy * dy, COORD_PRECISION);\n\n\t return (startVector.equals(vector) || clockwise(startVector, vector)) &&\n\t !clockwise(endVector, vector) &&\n\t dist >= innerRadius * innerRadius && dist <= radius * radius;\n\t },\n\n\t getBBox: function() {\n\t var this$1 = this;\n\n\t var box = new Box(MAX_VALUE, MAX_VALUE, MIN_VALUE, MIN_VALUE);\n\t var startAngle = round(this.startAngle % 360);\n\t var endAngle = round((startAngle + this.angle) % 360);\n\t var innerRadius = this.innerRadius;\n\t var allAngles = [ 0, 90, 180, 270, startAngle, endAngle ].sort(numericComparer);\n\t var startAngleIndex = allAngles.indexOf(startAngle);\n\t var endAngleIndex = allAngles.indexOf(endAngle);\n\t var angles;\n\n\t if (startAngle === endAngle) {\n\t angles = allAngles;\n\t } else {\n\t if (startAngleIndex < endAngleIndex) {\n\t angles = allAngles.slice(startAngleIndex, endAngleIndex + 1);\n\t } else {\n\t angles = [].concat(\n\t allAngles.slice(0, endAngleIndex + 1),\n\t allAngles.slice(startAngleIndex, allAngles.length)\n\t );\n\t }\n\t }\n\n\t for (var i = 0; i < angles.length; i++) {\n\t var point = this$1.point(angles[i]);\n\t box.wrapPoint(point);\n\t box.wrapPoint(point, innerRadius);\n\t }\n\n\t if (!innerRadius) {\n\t box.wrapPoint(this.center);\n\t }\n\n\t return box;\n\t },\n\n\t expand: function(value) {\n\t this.radius += value;\n\t return this;\n\t }\n\t});\n\n\tfunction numericComparer(a, b) {\n\t return a - b;\n\t}\n\n\tvar Sector = Ring.extend({\n\t init: function(center, radius, startAngle, angle) {\n\t Ring.fn.init.call(this, center, 0, radius, startAngle, angle);\n\t },\n\n\t expand: function(value) {\n\t return Ring.fn.expand.call(this, value);\n\t },\n\n\t clone: function() {\n\t return new Sector(this.center, this.radius, this.startAngle, this.angle);\n\t },\n\n\t setRadius: function(newRadius) {\n\t this.radius = newRadius;\n\n\t return this;\n\t }\n\t});\n\n\tvar DIRECTION_ANGLE = 0.001; //any value that will make the endAngle bigger than the start angle will work here.\n\n\tvar ShapeBuilder = Class.extend({\n\t createRing: function(sector, options) {\n\t var startAngle = sector.startAngle + 180;\n\t var endAngle = sector.angle + startAngle;\n\n\t //required in order to avoid reversing the arc direction in cases like 0.000000000000001 + 100 === 100\n\t if (sector.angle > 0 && startAngle === endAngle) {\n\t endAngle += DIRECTION_ANGLE;\n\t }\n\n\t var center = new geometry.Point(sector.center.x, sector.center.y);\n\t var radius = Math.max(sector.radius, 0);\n\t var innerRadius = Math.max(sector.innerRadius, 0);\n\t var arc = new geometry.Arc(center, {\n\t startAngle: startAngle,\n\t endAngle: endAngle,\n\t radiusX: radius,\n\t radiusY: radius\n\t });\n\t var path = Path.fromArc(arc, options).close();\n\n\t if (innerRadius) {\n\t arc.radiusX = arc.radiusY = innerRadius;\n\t var innerEnd = arc.pointAt(endAngle);\n\t path.lineTo(innerEnd.x, innerEnd.y);\n\t path.arc(endAngle, startAngle, innerRadius, innerRadius, true);\n\t } else {\n\t path.lineTo(center.x, center.y);\n\t }\n\n\t return path;\n\t }\n\t});\n\n\tShapeBuilder.current = new ShapeBuilder();\n\n\tvar ChartElement = Class.extend({\n\t init: function(options) {\n\n\t this.children = [];\n\n\t this.options = deepExtend({}, this.options, this.initUserOptions(options));\n\t },\n\n\t initUserOptions: function(options) {\n\t return options;\n\t },\n\n\t reflow: function(targetBox) {\n\t var children = this.children;\n\t var box;\n\n\t for (var i = 0; i < children.length; i++) {\n\t var currentChild = children[i];\n\t currentChild.reflow(targetBox);\n\n\t box = box ? box.wrap(currentChild.box) : currentChild.box.clone();\n\t }\n\n\t this.box = box || targetBox;\n\t },\n\n\t destroy: function() {\n\t var children = this.children;\n\n\t if (this.animation) {\n\t this.animation.destroy();\n\t }\n\n\t for (var i = 0; i < children.length; i++) {\n\t children[i].destroy();\n\t }\n\t },\n\n\t getRoot: function() {\n\t var parent = this.parent;\n\n\t return parent ? parent.getRoot() : null;\n\t },\n\n\t getSender: function() {\n\t var service = this.getService();\n\t if (service) {\n\t return service.sender;\n\t }\n\t },\n\n\t getService: function() {\n\t var element = this;\n\t while (element) {\n\t if (element.chartService) {\n\t return element.chartService;\n\t }\n\t element = element.parent;\n\t }\n\t },\n\n\t translateChildren: function(dx, dy) {\n\t var children = this.children;\n\t var childrenCount = children.length;\n\n\t for (var i = 0; i < childrenCount; i++) {\n\t children[i].box.translate(dx, dy);\n\t }\n\t },\n\n\t append: function() {\n\t var arguments$1 = arguments;\n\t var this$1 = this;\n\n\t for (var i = 0; i < arguments.length; i++) {\n\t var item = arguments$1[i];\n\t this$1.children.push(item);\n\t item.parent = this$1;\n\t }\n\t },\n\n\t renderVisual: function() {\n\t if (this.options.visible === false) {\n\t return;\n\t }\n\n\t this.createVisual();\n\n\t this.addVisual();\n\n\t this.renderChildren();\n\n\t this.createAnimation();\n\t this.renderComplete();\n\t },\n\n\t addVisual: function() {\n\t if (this.visual) {\n\t this.visual.chartElement = this;\n\n\t if (this.parent) {\n\t this.parent.appendVisual(this.visual);\n\t }\n\t }\n\t },\n\n\t renderChildren: function() {\n\t var children = this.children;\n\t var length = children.length;\n\t for (var i = 0; i < length; i++) {\n\t children[i].renderVisual();\n\t }\n\t },\n\n\t createVisual: function() {\n\t this.visual = new Group({\n\t zIndex: this.options.zIndex,\n\t visible: valueOrDefault(this.options.visible, true)\n\t });\n\t },\n\n\t createAnimation: function() {\n\t if (this.visual && this.options.animation) {\n\t this.animation = drawing.Animation.create(\n\t this.visual, this.options.animation\n\t );\n\t }\n\t },\n\n\t appendVisual: function(childVisual) {\n\t if (!childVisual.chartElement) {\n\t childVisual.chartElement = this;\n\t }\n\n\t if (childVisual.options.noclip) {\n\t this.clipRoot().visual.append(childVisual);\n\t } else if (defined(childVisual.options.zIndex)) {\n\t this.stackRoot().stackVisual(childVisual);\n\t } else if (this.isStackRoot) {\n\t this.stackVisual(childVisual);\n\t } else if (this.visual) {\n\t this.visual.append(childVisual);\n\t } else {\n\t // Allow chart elements without visuals to\n\t // pass through child visuals\n\t this.parent.appendVisual(childVisual);\n\t }\n\t },\n\n\t clipRoot: function() {\n\t if (this.parent) {\n\t return this.parent.clipRoot();\n\t }\n\n\t return this;\n\t },\n\n\t stackRoot: function() {\n\t if (this.parent) {\n\t return this.parent.stackRoot();\n\t }\n\n\t return this;\n\t },\n\n\t stackVisual: function(childVisual) {\n\t var zIndex = childVisual.options.zIndex || 0;\n\t var visuals = this.visual.children;\n\t var length = visuals.length;\n\t var pos;\n\n\t for (pos = 0; pos < length; pos++) {\n\t var sibling = visuals[pos];\n\t var here = valueOrDefault(sibling.options.zIndex, 0);\n\t if (here > zIndex) {\n\t break;\n\t }\n\t }\n\n\t this.visual.insert(pos, childVisual);\n\t },\n\n\t traverse: function(callback) {\n\t var children = this.children;\n\t var length = children.length;\n\n\t for (var i = 0; i < length; i++) {\n\t var child = children[i];\n\n\t callback(child);\n\t if (child.traverse) {\n\t child.traverse(callback);\n\t }\n\t }\n\t },\n\n\t closest: function(match) {\n\t var element = this;\n\t var matched = false;\n\n\t while (element && !matched) {\n\t matched = match(element);\n\n\t if (!matched) {\n\t element = element.parent;\n\t }\n\t }\n\n\t if (matched) {\n\t return element;\n\t }\n\t },\n\n\t renderComplete: function() {},\n\n\t hasHighlight: function() {\n\t var options = (this.options || {}).highlight;\n\t return !(!this.createHighlight || (options && options.visible === false));\n\t },\n\n\t toggleHighlight: function(show) {\n\t var this$1 = this;\n\n\t var options = (this.options || {}).highlight || {};\n\t var customVisual = options.visual;\n\t var highlight = this._highlight;\n\n\t if (!highlight) {\n\t var highlightOptions = {\n\t fill: {\n\t color: WHITE,\n\t opacity: 0.2\n\t },\n\t stroke: {\n\t color: WHITE,\n\t width: 1,\n\t opacity: 0.2\n\t }\n\t };\n\n\t if (customVisual) {\n\t highlight = this._highlight = customVisual(\n\t $.extend(this.highlightVisualArgs(), {\n\t createVisual: function () { return this$1.createHighlight(highlightOptions); },\n\t sender: this.getSender(),\n\t series: this.series,\n\t dataItem: this.dataItem,\n\t category: this.category,\n\t value: this.value,\n\t percentage: this.percentage,\n\t runningTotal: this.runningTotal,\n\t total: this.total\n\t }\n\t ));\n\n\t if (!highlight) {\n\t return;\n\t }\n\t } else {\n\t highlight = this._highlight = this.createHighlight(highlightOptions);\n\t }\n\n\t if (!defined(highlight.options.zIndex)) {\n\t highlight.options.zIndex = valueOrDefault(options.zIndex, this.options.zIndex);\n\t }\n\n\t this.appendVisual(highlight);\n\t }\n\n\t highlight.visible(show);\n\t },\n\n\t createGradientOverlay: function(element, options, gradientOptions) {\n\t var overlay = new Path($.extend({\n\t stroke: {\n\t color: \"none\"\n\t },\n\t fill: this.createGradient(gradientOptions),\n\t closed: element.options.closed\n\t }, options));\n\n\t overlay.segments.elements(element.segments.elements());\n\n\t return overlay;\n\t },\n\n\t createGradient: function(options) {\n\t if (this.parent) {\n\t return this.parent.createGradient(options);\n\t }\n\t }\n\t});\n\n\tChartElement.prototype.options = { };\n\n\tvar BoxElement = ChartElement.extend({\n\t init: function(options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.options.margin = getSpacing(this.options.margin);\n\t this.options.padding = getSpacing(this.options.padding);\n\t },\n\n\t reflow: function(targetBox) {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var width = options.width;\n\t var height = options.height;\n\t var shrinkToFit = options.shrinkToFit;\n\t var hasSetSize = width && height;\n\t var margin = options.margin;\n\t var padding = options.padding;\n\t var borderWidth = options.border.width;\n\t var box;\n\n\t var reflowPaddingBox = function () {\n\t this$1.align(targetBox, X, options.align);\n\t this$1.align(targetBox, Y, options.vAlign);\n\t this$1.paddingBox = box.clone().unpad(margin).unpad(borderWidth);\n\t };\n\n\t var contentBox = targetBox.clone();\n\t if (hasSetSize) {\n\t contentBox.x2 = contentBox.x1 + width;\n\t contentBox.y2 = contentBox.y1 + height;\n\t }\n\n\t if (shrinkToFit) {\n\t contentBox.unpad(margin).unpad(borderWidth).unpad(padding);\n\t }\n\n\t ChartElement.fn.reflow.call(this, contentBox);\n\n\t if (hasSetSize) {\n\t box = this.box = new Box(0, 0, width, height);\n\t } else {\n\t box = this.box;\n\t }\n\n\t if (shrinkToFit && hasSetSize) {\n\t reflowPaddingBox();\n\t contentBox = this.contentBox = this.paddingBox.clone().unpad(padding);\n\t } else {\n\t contentBox = this.contentBox = box.clone();\n\t box.pad(padding).pad(borderWidth).pad(margin);\n\t reflowPaddingBox();\n\t }\n\n\t this.translateChildren(\n\t box.x1 - contentBox.x1 + margin.left + borderWidth + padding.left,\n\t box.y1 - contentBox.y1 + margin.top + borderWidth + padding.top\n\t );\n\n\t var children = this.children;\n\t for (var i = 0; i < children.length; i++) {\n\t var item = children[i];\n\t item.reflow(item.box);\n\t }\n\t },\n\n\t align: function(targetBox, axis, alignment) {\n\t this.box.align(targetBox, axis, alignment);\n\t },\n\n\t hasBox: function() {\n\t var options = this.options;\n\t return options.border.width || options.background;\n\t },\n\n\t createVisual: function() {\n\t ChartElement.fn.createVisual.call(this);\n\n\t var options = this.options;\n\t if (options.visible && this.hasBox()) {\n\t this.visual.append(Path.fromRect(\n\t this.paddingBox.toRect(),\n\t this.visualStyle()\n\t ));\n\t }\n\t },\n\n\t visualStyle: function() {\n\t var options = this.options;\n\t var border = options.border || {};\n\n\t return {\n\t stroke: {\n\t width: border.width,\n\t color: border.color,\n\t opacity: valueOrDefault(border.opacity, options.opacity),\n\t dashType: border.dashType\n\t },\n\t fill: {\n\t color: options.background,\n\t opacity: options.opacity\n\t },\n\t cursor: options.cursor\n\t };\n\t }\n\t});\n\n\tsetDefaultOptions(BoxElement, {\n\t align: LEFT,\n\t vAlign: TOP,\n\t margin: {},\n\t padding: {},\n\t border: {\n\t color: BLACK,\n\t width: 0\n\t },\n\t background: \"\",\n\t shrinkToFit: false,\n\t width: 0,\n\t height: 0,\n\t visible: true\n\t});\n\n\tvar ShapeElement = BoxElement.extend({\n\t init: function(options, pointData) {\n\t BoxElement.fn.init.call(this, options);\n\n\t this.pointData = pointData;\n\t },\n\n\t getElement: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var box = ref.paddingBox;\n\t var type = options.type;\n\t var rotation = options.rotation;\n\t var center = box.center();\n\t var halfWidth = box.width() / 2;\n\n\t if (!options.visible || !this.hasBox()) {\n\t return null;\n\t }\n\n\t var style = this.visualStyle();\n\t var element;\n\n\t if (type === CIRCLE) {\n\t element = new drawing.Circle(\n\t new Circle([\n\t round(box.x1 + halfWidth, COORD_PRECISION),\n\t round(box.y1 + box.height() / 2, COORD_PRECISION)\n\t ], halfWidth),\n\t style\n\t );\n\t } else if (type === TRIANGLE) {\n\t element = Path.fromPoints([\n\t [ box.x1 + halfWidth, box.y1 ],\n\t [ box.x1, box.y2 ],\n\t [ box.x2, box.y2 ]\n\t ], style).close();\n\t } else if (type === CROSS) {\n\t element = new drawing.MultiPath(style);\n\n\t element.moveTo(box.x1, box.y1).lineTo(box.x2, box.y2);\n\t element.moveTo(box.x1, box.y2).lineTo(box.x2, box.y1);\n\t } else {\n\t element = Path.fromRect(box.toRect(), style);\n\t }\n\n\t if (rotation) {\n\t element.transform(geometryTransform()\n\t .rotate(-rotation, [ center.x, center.y ])\n\t );\n\t }\n\n\t element.options.zIndex = options.zIndex;\n\t return element;\n\t },\n\n\t createElement: function() {\n\t var this$1 = this;\n\n\t var customVisual = this.options.visual;\n\t var pointData = this.pointData || {};\n\t var visual;\n\n\t if (customVisual) {\n\t visual = customVisual({\n\t value: pointData.value,\n\t dataItem: pointData.dataItem,\n\t sender: this.getSender(),\n\t series: pointData.series,\n\t category: pointData.category,\n\t rect: this.paddingBox.toRect(),\n\t options: this.visualOptions(),\n\t createVisual: function () { return this$1.getElement(); }\n\t });\n\t } else {\n\t visual = this.getElement();\n\t }\n\n\t return visual;\n\t },\n\n\t visualOptions: function() {\n\t var options = this.options;\n\t return {\n\t background: options.background,\n\t border: options.border,\n\t margin: options.margin,\n\t padding: options.padding,\n\t type: options.type,\n\t size: options.width,\n\t visible: options.visible\n\t };\n\t },\n\n\t createVisual: function() {\n\t this.visual = this.createElement();\n\t }\n\t});\n\n\tsetDefaultOptions(ShapeElement, {\n\t type: CIRCLE,\n\t align: CENTER,\n\t vAlign: CENTER\n\t});\n\n\tvar LINEAR = \"linear\";\n\tvar RADIAL = \"radial\";\n\n\tvar GRADIENTS = {\n\t glass: {\n\t type: LINEAR,\n\t rotation: 0,\n\t stops: [ {\n\t offset: 0,\n\t color: WHITE,\n\t opacity: 0\n\t }, {\n\t offset: 0.25,\n\t color: WHITE,\n\t opacity: 0.3\n\t }, {\n\t offset: 1,\n\t color: WHITE,\n\t opacity: 0\n\t } ]\n\t },\n\t sharpBevel: {\n\t type: RADIAL,\n\t stops: [ {\n\t offset: 0,\n\t color: WHITE,\n\t opacity: 0.55\n\t }, {\n\t offset: 0.65,\n\t color: WHITE,\n\t opacity: 0\n\t }, {\n\t offset: 0.95,\n\t color: WHITE,\n\t opacity: 0.25\n\t } ]\n\t },\n\t roundedBevel: {\n\t type: RADIAL,\n\t stops: [ {\n\t offset: 0.33,\n\t color: WHITE,\n\t opacity: 0.06\n\t }, {\n\t offset: 0.83,\n\t color: WHITE,\n\t opacity: 0.2\n\t }, {\n\t offset: 0.95,\n\t color: WHITE,\n\t opacity: 0\n\t } ]\n\t },\n\t roundedGlass: {\n\t type: RADIAL,\n\t supportVML: false,\n\t stops: [ {\n\t offset: 0,\n\t color: WHITE,\n\t opacity: 0\n\t }, {\n\t offset: 0.5,\n\t color: WHITE,\n\t opacity: 0.3\n\t }, {\n\t offset: 0.99,\n\t color: WHITE,\n\t opacity: 0\n\t } ]\n\t },\n\t sharpGlass: {\n\t type: RADIAL,\n\t supportVML: false,\n\t stops: [ {\n\t offset: 0,\n\t color: WHITE,\n\t opacity: 0.2\n\t }, {\n\t offset: 0.15,\n\t color: WHITE,\n\t opacity: 0.15\n\t }, {\n\t offset: 0.17,\n\t color: WHITE,\n\t opacity: 0.35\n\t }, {\n\t offset: 0.85,\n\t color: WHITE,\n\t opacity: 0.05\n\t }, {\n\t offset: 0.87,\n\t color: WHITE,\n\t opacity: 0.15\n\t }, {\n\t offset: 0.99,\n\t color: WHITE,\n\t opacity: 0\n\t } ]\n\t },\n\t bubbleShadow: {\n\t type: RADIAL,\n\t center: [ 0.5, 0.5 ],\n\t radius: 0.5\n\t }\n\t};\n\n\tfunction boxDiff(r, s) {\n\t if (r.x1 === s.x1 && r.y1 === s.y1 && r.x2 === s.x2 && r.y2 === s.y2) {\n\t return s;\n\t }\n\n\t var a = Math.min(r.x1, s.x1);\n\t var b = Math.max(r.x1, s.x1);\n\t var c = Math.min(r.x2, s.x2);\n\t var d = Math.max(r.x2, s.x2);\n\t var e = Math.min(r.y1, s.y1);\n\t var f = Math.max(r.y1, s.y1);\n\t var g = Math.min(r.y2, s.y2);\n\t var h = Math.max(r.y2, s.y2);\n\t var boxes = [];\n\n\t // X = intersection, 0-7 = possible difference areas\n\t // h +-+-+-+\n\t // . |5|6|7|\n\t // g +-+-+-+\n\t // . |3|X|4|\n\t // f +-+-+-+\n\t // . |0|1|2|\n\t // e +-+-+-+\n\t // . a b c d\n\n\t // we'll always have rectangles 1, 3, 4 and 6\n\t boxes[0] = new Box(b, e, c, f);\n\t boxes[1] = new Box(a, f, b, g);\n\t boxes[2] = new Box(c, f, d, g);\n\t boxes[3] = new Box(b, g, c, h);\n\n\t // decide which corners\n\t if (r.x1 === a && r.y1 === e || s.x1 === a && s.y1 === e) { // corners 0 and 7\n\t boxes[4] = new Box(a, e, b, f);\n\t boxes[5] = new Box(c, g, d, h);\n\t } else { // corners 2 and 5\n\t boxes[4] = new Box(c, e, d, f);\n\t boxes[5] = new Box(a, g, b, h);\n\t }\n\n\t return grep(boxes, function(box) {\n\t return box.height() > 0 && box.width() > 0;\n\t })[0];\n\t}\n\n\tvar RootElement = ChartElement.extend({\n\t init: function(options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t var rootOptions = this.options;\n\t rootOptions.width = parseInt(rootOptions.width, 10);\n\t rootOptions.height = parseInt(rootOptions.height, 10);\n\n\t this.gradients = {};\n\t },\n\n\t reflow: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var children = ref.children;\n\t var currentBox = new Box(0, 0, options.width, options.height);\n\n\t this.box = currentBox.unpad(options.margin);\n\n\t for (var i = 0; i < children.length; i++) {\n\t children[i].reflow(currentBox);\n\t currentBox = boxDiff(currentBox, children[i].box) || new Box();\n\t }\n\t },\n\n\t createVisual: function() {\n\t this.visual = new Group();\n\t this.createBackground();\n\t },\n\n\t createBackground: function() {\n\t var options = this.options;\n\t var border = options.border || {};\n\t var box = this.box.clone().pad(options.margin).unpad(border.width);\n\n\t var background = Path.fromRect(box.toRect(), {\n\t stroke: {\n\t color: border.width ? border.color : \"\",\n\t width: border.width,\n\t dashType: border.dashType\n\t },\n\t fill: {\n\t color: options.background,\n\t opacity: options.opacity\n\t },\n\t zIndex: -10\n\t });\n\n\t this.visual.append(background);\n\t },\n\n\t getRoot: function() {\n\t return this;\n\t },\n\n\t createGradient: function(options) {\n\t var gradients = this.gradients;\n\t var hashCode = objectKey(options);\n\t var gradient = GRADIENTS[options.gradient];\n\t var drawingGradient;\n\n\t if (gradients[hashCode]) {\n\t drawingGradient = gradients[hashCode];\n\t } else {\n\t var gradientOptions = $.extend({}, gradient, options);\n\t if (gradient.type === \"linear\") {\n\t drawingGradient = new drawing.LinearGradient(gradientOptions);\n\t } else {\n\t if (options.innerRadius) {\n\t gradientOptions.stops = innerRadialStops(gradientOptions);\n\t }\n\t drawingGradient = new drawing.RadialGradient(gradientOptions);\n\t drawingGradient.supportVML = gradient.supportVML !== false;\n\t }\n\t gradients[hashCode] = drawingGradient;\n\t }\n\n\t return drawingGradient;\n\t },\n\n\t cleanGradients: function() {\n\t var gradients = this.gradients;\n\t for (var hashCode in gradients) {\n\t gradients[hashCode]._observers = [];//add clear observers method in drawing ObserversMixin\n\t }\n\t },\n\n\t size: function() {\n\t var options = this.options;\n\t return new Box(0, 0, options.width, options.height);\n\t }\n\t});\n\n\tsetDefaultOptions(RootElement, {\n\t width: DEFAULT_WIDTH,\n\t height: DEFAULT_HEIGHT,\n\t background: WHITE,\n\t border: {\n\t color: BLACK,\n\t width: 0\n\t },\n\t margin: getSpacing(5),\n\t zIndex: -2\n\t});\n\n\tfunction innerRadialStops(options) {\n\t var stops = options.stops;\n\t var usedSpace = ((options.innerRadius / options.radius) * 100);\n\t var length = stops.length;\n\t var currentStops = [];\n\n\t for (var i = 0; i < length; i++) {\n\t var currentStop = $.extend({}, stops[i]);\n\t currentStop.offset = (currentStop.offset * (100 - usedSpace) + usedSpace) / 100;\n\t currentStops.push(currentStop);\n\t }\n\n\t return currentStops;\n\t}\n\n\tvar FloatElement = ChartElement.extend({\n\t init: function(options) {\n\t ChartElement.fn.init.call(this, options);\n\t this._initDirection();\n\t },\n\n\t _initDirection: function() {\n\t var options = this.options;\n\t if (options.vertical) {\n\t this.groupAxis = X;\n\t this.elementAxis = Y;\n\t this.groupSizeField = WIDTH;\n\t this.elementSizeField = HEIGHT;\n\t this.groupSpacing = options.spacing;\n\t this.elementSpacing = options.vSpacing;\n\t } else {\n\t this.groupAxis = Y;\n\t this.elementAxis = X;\n\t this.groupSizeField = HEIGHT;\n\t this.elementSizeField = WIDTH;\n\t this.groupSpacing = options.vSpacing;\n\t this.elementSpacing = options.spacing;\n\t }\n\t },\n\n\t reflow: function(targetBox) {\n\t this.box = targetBox.clone();\n\t this.reflowChildren();\n\t },\n\n\t reflowChildren: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var box = ref.box;\n\t var elementAxis = ref.elementAxis;\n\t var groupAxis = ref.groupAxis;\n\t var elementSizeField = ref.elementSizeField;\n\t var groupSizeField = ref.groupSizeField;\n\t var ref$1 = this.groupOptions();\n\t var groups = ref$1.groups;\n\t var groupsSize = ref$1.groupsSize;\n\t var maxGroupElementsSize = ref$1.maxGroupElementsSize;\n\t var groupsCount = groups.length;\n\t var groupsStart = box[groupAxis + 1] + this.alignStart(groupsSize, box[groupSizeField]());\n\n\t if (groupsCount) {\n\t var groupStart = groupsStart;\n\n\t for (var groupIdx = 0; groupIdx < groupsCount; groupIdx++) {\n\t var group = groups[groupIdx];\n\t var groupElements = group.groupElements;\n\t var elementStart = box[elementAxis + 1];\n\t var groupElementsCount = groupElements.length;\n\n\t for (var idx = 0; idx < groupElementsCount; idx++) {\n\t var element = groupElements[idx];\n\t var elementSize$$1 = this$1.elementSize(element);\n\t var groupElementStart = groupStart + this$1.alignStart(elementSize$$1[groupSizeField], group.groupSize);\n\n\t var elementBox = new Box();\n\t elementBox[groupAxis + 1] = groupElementStart;\n\t elementBox[groupAxis + 2] = groupElementStart + elementSize$$1[groupSizeField];\n\t elementBox[elementAxis + 1] = elementStart;\n\t elementBox[elementAxis + 2] = elementStart + elementSize$$1[elementSizeField];\n\n\t element.reflow(elementBox);\n\n\t elementStart += elementSize$$1[elementSizeField] + this$1.elementSpacing;\n\t }\n\t groupStart += group.groupSize + this$1.groupSpacing;\n\t }\n\t box[groupAxis + 1] = groupsStart;\n\t box[groupAxis + 2] = groupsStart + groupsSize;\n\t box[elementAxis + 2] = box[elementAxis + 1] + maxGroupElementsSize;\n\t }\n\t },\n\n\t alignStart: function(size, maxSize) {\n\t var start = 0;\n\t var align = this.options.align;\n\t if (align === RIGHT || align === BOTTOM) {\n\t start = maxSize - size;\n\t } else if (align === CENTER) {\n\t start = (maxSize - size) / 2;\n\t }\n\t return start;\n\t },\n\n\t groupOptions: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var box = ref.box;\n\t var children = ref.children;\n\t var elementSizeField = ref.elementSizeField;\n\t var groupSizeField = ref.groupSizeField;\n\t var elementSpacing = ref.elementSpacing;\n\t var groupSpacing = ref.groupSpacing;\n\t var maxSize = round(box[elementSizeField]());\n\t var childrenCount = children.length;\n\t var groups = [];\n\n\t var groupSize = 0;\n\t var groupElementsSize = 0;\n\t var groupsSize = 0;\n\t var maxGroupElementsSize = 0;\n\t var groupElements = [];\n\n\t for (var idx = 0; idx < childrenCount; idx++) {\n\t var element = children[idx];\n\t if (!element.box) {\n\t element.reflow(box);\n\t }\n\n\t var elementSize$$1 = this$1.elementSize(element);\n\t if (this$1.options.wrap && round(groupElementsSize + elementSpacing + elementSize$$1[elementSizeField]) > maxSize) {\n\t groups.push({\n\t groupElements: groupElements,\n\t groupSize: groupSize,\n\t groupElementsSize: groupElementsSize\n\t });\n\t maxGroupElementsSize = Math.max(maxGroupElementsSize, groupElementsSize);\n\t groupsSize += groupSpacing + groupSize;\n\t groupSize = 0;\n\t groupElementsSize = 0;\n\t groupElements = [];\n\t }\n\t groupSize = Math.max(groupSize, elementSize$$1[groupSizeField]);\n\t if (groupElementsSize > 0) {\n\t groupElementsSize += elementSpacing;\n\t }\n\t groupElementsSize += elementSize$$1[elementSizeField];\n\t groupElements.push(element);\n\t }\n\n\t groups.push({\n\t groupElements: groupElements,\n\t groupSize: groupSize,\n\t groupElementsSize: groupElementsSize\n\t });\n\t maxGroupElementsSize = Math.max(maxGroupElementsSize, groupElementsSize);\n\t groupsSize += groupSize;\n\n\t return {\n\t groups: groups,\n\t groupsSize: groupsSize,\n\t maxGroupElementsSize: maxGroupElementsSize\n\t };\n\t },\n\n\t elementSize: function(element) {\n\t return {\n\t width: element.box.width(),\n\t height: element.box.height()\n\t };\n\t },\n\n\t createVisual: function() {}\n\t});\n\n\tsetDefaultOptions(FloatElement, {\n\t vertical: true,\n\t wrap: true,\n\t vSpacing: 0,\n\t spacing: 0\n\t});\n\n\tvar DrawingText = drawing.Text;\n\n\tvar Text = ChartElement.extend({\n\t init: function(content, options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.content = content;\n\n\t // Calculate size\n\t this.reflow(new Box());\n\t },\n\n\t reflow: function(targetBox) {\n\t var options = this.options;\n\t var size = options.size = util.measureText(this.content, { font: options.font });\n\n\t this.baseline = size.baseline;\n\n\t this.box = new Box(targetBox.x1, targetBox.y1,\n\t targetBox.x1 + size.width, targetBox.y1 + size.height);\n\t },\n\n\t createVisual: function() {\n\t var ref = this.options;\n\t var font = ref.font;\n\t var color = ref.color;\n\t var opacity = ref.opacity;\n\t var cursor = ref.cursor;\n\n\t this.visual = new DrawingText(this.content, this.box.toRect().topLeft(), {\n\t font: font,\n\t fill: { color: color, opacity: opacity },\n\t cursor: cursor\n\t });\n\t }\n\t});\n\n\tsetDefaultOptions(Text, {\n\t font: DEFAULT_FONT,\n\t color: BLACK\n\t});\n\n\tfunction rectToBox(rect) {\n\t var origin = rect.origin;\n\t var bottomRight = rect.bottomRight();\n\n\t return new Box(origin.x, origin.y, bottomRight.x, bottomRight.y);\n\t}\n\n\tvar ROWS_SPLIT_REGEX = /\\n/m;\n\n\tvar TextBox = BoxElement.extend({\n\t init: function(content, options, data) {\n\t BoxElement.fn.init.call(this, options);\n\t this.content = content;\n\t this.data = data;\n\n\t this._initContainer();\n\t if (this.options._autoReflow !== false) {\n\t this.reflow(new Box());\n\t }\n\t },\n\n\t _initContainer: function() {\n\t var options = this.options;\n\t var rows = String(this.content).split(ROWS_SPLIT_REGEX);\n\t var floatElement = new FloatElement({ vertical: true, align: options.align, wrap: false });\n\t var textOptions = deepExtend({ }, options, { opacity: 1, animation: null });\n\n\t this.container = floatElement;\n\t this.append(floatElement);\n\n\t for (var rowIdx = 0; rowIdx < rows.length; rowIdx++) {\n\t var text = new Text(rows[rowIdx].trim(), textOptions);\n\t floatElement.append(text);\n\t }\n\t },\n\n\t reflow: function(targetBox) {\n\t var options = this.options;\n\t var visualFn = options.visual;\n\t this.container.options.align = options.align;\n\n\t if (visualFn && !this._boxReflow) {\n\t var visualBox = targetBox;\n\t if (!visualBox.hasSize()) {\n\t this._boxReflow = true;\n\t this.reflow(visualBox);\n\t this._boxReflow = false;\n\t visualBox = this.box;\n\t }\n\t var visual = this.visual = visualFn(this.visualContext(visualBox));\n\n\t if (visual) {\n\t visualBox = rectToBox(visual.clippedBBox() || new Rect());\n\n\t visual.options.zIndex = options.zIndex;\n\t }\n\n\t this.box = this.contentBox = this.paddingBox = visualBox;\n\t } else {\n\t BoxElement.fn.reflow.call(this, targetBox);\n\n\t if (options.rotation) {\n\t var margin = getSpacing(options.margin);\n\t var box = this.box.unpad(margin);\n\n\t this.targetBox = targetBox;\n\t this.normalBox = box.clone();\n\n\t box = this.rotate();\n\t box.translate(margin.left - margin.right, margin.top - margin.bottom);\n\n\t this.rotatedBox = box.clone();\n\n\t box.pad(margin);\n\t }\n\t }\n\t },\n\n\t createVisual: function() {\n\t var options = this.options;\n\n\t this.visual = new Group({\n\t transform: this.rotationTransform(),\n\t zIndex: options.zIndex,\n\t noclip: options.noclip\n\t });\n\n\t if (this.hasBox()) {\n\t var box = Path.fromRect(this.paddingBox.toRect(), this.visualStyle());\n\t this.visual.append(box);\n\t }\n\t },\n\n\t renderVisual: function() {\n\t if (!this.options.visible) {\n\t return;\n\t }\n\n\t if (this.options.visual) {\n\t var visual = this.visual;\n\t if (visual && !defined(visual.options.noclip)) {\n\t visual.options.noclip = this.options.noclip;\n\t }\n\t this.addVisual();\n\t this.createAnimation();\n\t } else {\n\t BoxElement.fn.renderVisual.call(this);\n\t }\n\t },\n\n\t visualContext: function(targetBox) {\n\t var this$1 = this;\n\n\t var context = {\n\t text: this.content,\n\t rect: targetBox.toRect(),\n\t sender: this.getSender(),\n\t options: this.options,\n\t createVisual: function () {\n\t this$1._boxReflow = true;\n\t this$1.reflow(targetBox);\n\t this$1._boxReflow = false;\n\t return this$1.getDefaultVisual();\n\t }\n\t };\n\t if (this.data) {\n\t $.extend(context, this.data);\n\t }\n\n\t return context;\n\t },\n\n\t getDefaultVisual: function() {\n\t this.createVisual();\n\t this.renderChildren();\n\t var visual = this.visual;\n\t delete this.visual;\n\t return visual;\n\t },\n\n\t rotate: function() {\n\t var options = this.options;\n\t this.box.rotate(options.rotation);\n\t this.align(this.targetBox, X, options.align);\n\t this.align(this.targetBox, Y, options.vAlign);\n\t return this.box;\n\t },\n\n\t rotationTransform: function() {\n\t var rotation = this.options.rotation;\n\t if (!rotation) {\n\t return null;\n\t }\n\n\t var ref = this.normalBox.center();\n\t var cx = ref.x;\n\t var cy = ref.y;\n\t var boxCenter = this.rotatedBox.center();\n\n\t return geometryTransform()\n\t .translate(boxCenter.x - cx, boxCenter.y - cy)\n\t .rotate(rotation, [ cx, cy ]);\n\t }\n\t});\n\n\tvar Title = ChartElement.extend({\n\t init: function(options) {\n\t ChartElement.fn.init.call(this, options);\n\n\t this.append(\n\t new TextBox(this.options.text, $.extend({}, this.options, {\n\t vAlign: this.options.position\n\t }))\n\t );\n\t },\n\n\t reflow: function(targetBox) {\n\t ChartElement.fn.reflow.call(this, targetBox);\n\t this.box.snapTo(targetBox, X);\n\t }\n\t});\n\n\tTitle.buildTitle = function(options, parent, defaultOptions) {\n\t var titleOptions = options;\n\n\t if (typeof options === \"string\") {\n\t titleOptions = { text: options };\n\t }\n\n\t titleOptions = $.extend({ visible: true }, defaultOptions, titleOptions);\n\n\t var title;\n\t if (titleOptions && titleOptions.visible && titleOptions.text) {\n\t title = new Title(titleOptions);\n\t parent.append(title);\n\t }\n\n\t return title;\n\t};\n\n\tsetDefaultOptions(Title, {\n\t color: BLACK,\n\t position: TOP,\n\t align: CENTER,\n\t margin: getSpacing(5),\n\t padding: getSpacing(5)\n\t});\n\n\tvar AxisLabel = TextBox.extend({\n\t init: function(value, text, index, dataItem, options) {\n\t TextBox.fn.init.call(this, text, options);\n\n\t this.text = text;\n\t this.value = value;\n\t this.index = index;\n\t this.dataItem = dataItem;\n\t this.reflow(new Box());\n\t },\n\n\t visualContext: function(targetBox) {\n\t var context = TextBox.fn.visualContext.call(this, targetBox);\n\n\t context.value = this.value;\n\t context.dataItem = this.dataItem;\n\t context.format = this.options.format;\n\t context.culture = this.options.culture;\n\n\t return context;\n\t },\n\n\t click: function(widget, e) {\n\n\t widget.trigger(AXIS_LABEL_CLICK, {\n\t element: eventElement(e),\n\t value: this.value,\n\t text: this.text,\n\t index: this.index,\n\t dataItem: this.dataItem,\n\t axis: this.parent.options\n\t });\n\t },\n\n\t rotate: function() {\n\t if (this.options.alignRotation !== CENTER) {\n\t var box = this.normalBox.toRect();\n\t var transform = this.rotationTransform();\n\n\t this.box = rectToBox(box.bbox(transform.matrix()));\n\t } else {\n\t TextBox.fn.rotate.call(this);\n\t }\n\n\t return this.box;\n\t },\n\n\t rotationTransform: function() {\n\t var options = this.options;\n\t var rotation = options.rotation;\n\t if (!rotation) {\n\t return null;\n\t }\n\n\t if (options.alignRotation === CENTER) {\n\t return TextBox.fn.rotationTransform.call(this);\n\t }\n\n\t var rotationMatrix = geometryTransform().rotate(rotation).matrix();\n\t var box = this.normalBox.toRect();\n\t var rect = this.targetBox.toRect();\n\n\t var rotationOrigin = options.rotationOrigin || TOP;\n\t var alignAxis = rotationOrigin === TOP || rotationOrigin === BOTTOM ? X : Y;\n\t var distanceAxis = rotationOrigin === TOP || rotationOrigin === BOTTOM ? Y : X;\n\t var axisAnchor = rotationOrigin === TOP || rotationOrigin === LEFT ? rect.origin : rect.bottomRight();\n\n\t var topLeft = box.topLeft().transformCopy(rotationMatrix);\n\t var topRight = box.topRight().transformCopy(rotationMatrix);\n\t var bottomRight = box.bottomRight().transformCopy(rotationMatrix);\n\t var bottomLeft = box.bottomLeft().transformCopy(rotationMatrix);\n\t var rotatedBox = Rect.fromPoints(topLeft, topRight, bottomRight, bottomLeft);\n\n\t var translate = {};\n\t translate[distanceAxis] = rect.origin[distanceAxis] - rotatedBox.origin[distanceAxis];\n\n\t var distanceLeft = Math.abs(topLeft[distanceAxis] + translate[distanceAxis] - axisAnchor[distanceAxis]);\n\t var distanceRight = Math.abs(topRight[distanceAxis] + translate[distanceAxis] - axisAnchor[distanceAxis]);\n\n\t var alignStart, alignEnd;\n\n\t if (round(distanceLeft, DEFAULT_PRECISION) === round(distanceRight, DEFAULT_PRECISION)) {\n\t alignStart = topLeft;\n\t alignEnd = topRight;\n\t } else if (distanceRight < distanceLeft) {\n\t alignStart = topRight;\n\t alignEnd = bottomRight;\n\t } else {\n\t alignStart = topLeft;\n\t alignEnd = bottomLeft;\n\t }\n\n\t var alignCenter = alignStart[alignAxis] + (alignEnd[alignAxis] - alignStart[alignAxis]) / 2;\n\t translate[alignAxis] = rect.center()[alignAxis] - alignCenter;\n\n\t return geometryTransform()\n\t .translate(translate.x, translate.y)\n\t .rotate(rotation);\n\t }\n\t});\n\n\tsetDefaultOptions(AxisLabel, {\n\t _autoReflow: false\n\t});\n\n\tvar DEFAULT_ICON_SIZE = 7;\n\tvar DEFAULT_LABEL_COLOR = \"#fff\";\n\n\tvar Note = BoxElement.extend({\n\t init: function(fields, options, chartService) {\n\t BoxElement.fn.init.call(this, options);\n\n\t this.fields = fields;\n\t this.chartService = chartService;\n\n\t this.render();\n\t },\n\n\t hide: function() {\n\t this.options.visible = false;\n\t },\n\n\t show: function() {\n\t this.options.visible = true;\n\t },\n\n\t render: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\n\t if (options.visible) {\n\t var label = options.label;\n\t var icon = options.icon;\n\t var box = new Box();\n\t var childAlias = function () { return this$1; };\n\t var size = icon.size;\n\t var text = this.fields.text;\n\t var width, height;\n\n\t if (defined(label) && label.visible) {\n\t var noteTemplate = getTemplate(label);\n\t if (noteTemplate) {\n\t text = noteTemplate(this.fields);\n\t } else if (label.format) {\n\t text = this.chartService.format.auto(label.format, text);\n\t }\n\n\t if (!label.color) {\n\t label.color = label.position === INSIDE ? DEFAULT_LABEL_COLOR : icon.background;\n\t }\n\n\t this.label = new TextBox(text, deepExtend({}, label));\n\t this.label.aliasFor = childAlias;\n\n\t if (label.position === INSIDE && !defined(size)) {\n\t if (icon.type === CIRCLE) {\n\t size = Math.max(this.label.box.width(), this.label.box.height());\n\t } else {\n\t width = this.label.box.width();\n\t height = this.label.box.height();\n\t }\n\t box.wrap(this.label.box);\n\t }\n\t }\n\n\t icon.width = width || size || DEFAULT_ICON_SIZE;\n\t icon.height = height || size || DEFAULT_ICON_SIZE;\n\n\t var marker = new ShapeElement(deepExtend({}, icon));\n\t marker.aliasFor = childAlias;\n\n\t this.marker = marker;\n\t this.append(marker);\n\n\t if (this.label) {\n\t this.append(this.label);\n\t }\n\n\t marker.reflow(new Box());\n\t this.wrapperBox = box.wrap(marker.box);\n\t }\n\t },\n\n\t reflow: function(targetBox) {\n\t var ref = this;\n\t var options = ref.options;\n\t var label = ref.label;\n\t var marker = ref.marker;\n\t var wrapperBox = ref.wrapperBox;\n\t var center = targetBox.center();\n\t var length = options.line.length;\n\t var position = options.position;\n\n\t // TODO: Review\n\t if (options.visible) {\n\t var lineStart, box, contentBox;\n\n\t if (inArray(position, [ LEFT, RIGHT ])) {\n\t if (position === LEFT) {\n\t contentBox = wrapperBox.alignTo(targetBox, position).translate(-length, targetBox.center().y - wrapperBox.center().y);\n\n\t if (options.line.visible) {\n\t lineStart = [ targetBox.x1, center.y ];\n\t this.linePoints = [\n\t lineStart,\n\t [ contentBox.x2, center.y ]\n\t ];\n\t box = contentBox.clone().wrapPoint(lineStart);\n\t }\n\t } else {\n\t contentBox = wrapperBox.alignTo(targetBox, position).translate(length, targetBox.center().y - wrapperBox.center().y);\n\n\t if (options.line.visible) {\n\t lineStart = [ targetBox.x2, center.y ];\n\t this.linePoints = [\n\t lineStart,\n\t [ contentBox.x1, center.y ]\n\t ];\n\t box = contentBox.clone().wrapPoint(lineStart);\n\t }\n\t }\n\t } else {\n\t if (position === BOTTOM) {\n\t contentBox = wrapperBox.alignTo(targetBox, position).translate(targetBox.center().x - wrapperBox.center().x, length);\n\n\t if (options.line.visible) {\n\t lineStart = [ center.x, targetBox.y2 ];\n\t this.linePoints = [\n\t lineStart,\n\t [ center.x, contentBox.y1 ]\n\t ];\n\t box = contentBox.clone().wrapPoint(lineStart);\n\t }\n\t } else {\n\t contentBox = wrapperBox.alignTo(targetBox, position).translate(targetBox.center().x - wrapperBox.center().x, -length);\n\n\t if (options.line.visible) {\n\t lineStart = [ center.x, targetBox.y1 ];\n\t this.linePoints = [\n\t lineStart,\n\t [ center.x, contentBox.y2 ]\n\t ];\n\t box = contentBox.clone().wrapPoint(lineStart);\n\t }\n\t }\n\t }\n\n\t if (marker) {\n\t marker.reflow(contentBox);\n\t }\n\n\t if (label) {\n\t label.reflow(contentBox);\n\t if (marker) {\n\t if (options.label.position === OUTSIDE) {\n\t label.box.alignTo(marker.box, position);\n\t }\n\t label.reflow(label.box);\n\t }\n\t }\n\n\t this.contentBox = contentBox;\n\t this.targetBox = targetBox;\n\t this.box = box || contentBox;\n\t }\n\t },\n\n\t createVisual: function() {\n\t BoxElement.fn.createVisual.call(this);\n\t this.visual.options.noclip = this.options.noclip;\n\n\t if (this.options.visible) {\n\t this.createLine();\n\t }\n\t },\n\n\t renderVisual: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var customVisual = options.visual;\n\t if (options.visible && customVisual) {\n\t this.visual = customVisual($.extend(this.fields, {\n\t sender: this.getSender(),\n\t rect: this.targetBox.toRect(),\n\t options: {\n\t background: options.background,\n\t border: options.background,\n\t icon: options.icon,\n\t label: options.label,\n\t line: options.line,\n\t position: options.position,\n\t visible: options.visible\n\t },\n\t createVisual: function () {\n\t this$1.createVisual();\n\t this$1.renderChildren();\n\t var defaultVisual = this$1.visual;\n\t delete this$1.visual;\n\t return defaultVisual;\n\t }\n\t }));\n\t this.addVisual();\n\t } else {\n\t BoxElement.fn.renderVisual.call(this);\n\t }\n\t },\n\n\t createLine: function() {\n\t var options = this.options.line;\n\n\t if (this.linePoints) {\n\t var path = Path.fromPoints(this.linePoints, {\n\t stroke: {\n\t color: options.color,\n\t width: options.width,\n\t dashType: options.dashType\n\t }\n\t });\n\n\t alignPathToPixel(path);\n\t this.visual.append(path);\n\t }\n\t },\n\n\t click: function(widget, e) {\n\t var args = this.eventArgs(e);\n\n\t if (!widget.trigger(NOTE_CLICK, args)) {\n\t e.preventDefault();\n\t }\n\t },\n\n\t over: function(widget, e) {\n\t var args = this.eventArgs(e);\n\n\t if (!widget.trigger(NOTE_HOVER, args)) {\n\t e.preventDefault();\n\t }\n\t },\n\n\t out: function(widget, e) {\n\t var args = this.eventArgs(e);\n\n\t widget.trigger(NOTE_LEAVE, args);\n\t },\n\n\t eventArgs: function(e) {\n\t var options = this.options;\n\n\t return $.extend(this.fields, {\n\t element: eventElement(e),\n\t text: defined(options.label) ? options.label.text : \"\",\n\t visual: this.visual\n\t });\n\t }\n\t});\n\n\tsetDefaultOptions(Note, {\n\t icon: {\n\t visible: true,\n\t type: CIRCLE\n\t },\n\t label: {\n\t position: INSIDE,\n\t visible: true,\n\t align: CENTER,\n\t vAlign: CENTER\n\t },\n\t line: {\n\t visible: true\n\t },\n\t visible: true,\n\t position: TOP,\n\t zIndex: 2\n\t});\n\n\tfunction createAxisTick(options, tickOptions) {\n\t var tickX = options.tickX;\n\t var tickY = options.tickY;\n\t var position = options.position;\n\n\t var tick = new Path({\n\t stroke: {\n\t width: tickOptions.width,\n\t color: tickOptions.color\n\t }\n\t });\n\n\t if (options.vertical) {\n\t tick.moveTo(tickX, position)\n\t .lineTo(tickX + tickOptions.size, position);\n\t } else {\n\t tick.moveTo(position, tickY)\n\t .lineTo(position, tickY + tickOptions.size);\n\t }\n\n\t alignPathToPixel(tick);\n\n\t return tick;\n\t}\n\n\tfunction createAxisGridLine(options, gridLine) {\n\t var lineStart = options.lineStart;\n\t var lineEnd = options.lineEnd;\n\t var position = options.position;\n\n\t var line = new Path({\n\t stroke: {\n\t width: gridLine.width,\n\t color: gridLine.color,\n\t dashType: gridLine.dashType\n\t }\n\t });\n\n\t if (options.vertical) {\n\t line.moveTo(lineStart, position)\n\t .lineTo(lineEnd, position);\n\t } else {\n\t line.moveTo(position, lineStart)\n\t .lineTo(position, lineEnd);\n\t }\n\n\t alignPathToPixel(line);\n\n\t return line;\n\t}\n\n\tvar Axis = ChartElement.extend({\n\t init: function(options, chartService) {\n\t if (chartService === void 0) { chartService = new ChartService(); }\n\n\t ChartElement.fn.init.call(this, options);\n\n\t this.chartService = chartService;\n\n\t if (!this.options.visible) {\n\t this.options = deepExtend({}, this.options, {\n\t labels: {\n\t visible: false\n\t },\n\t line: {\n\t visible: false\n\t },\n\t margin: 0,\n\t majorTickSize: 0,\n\t minorTickSize: 0\n\t });\n\t }\n\n\t this.options.minorTicks = deepExtend({}, {\n\t color: this.options.line.color,\n\t width: this.options.line.width,\n\t visible: this.options.minorTickType !== NONE\n\t }, this.options.minorTicks, {\n\t size: this.options.minorTickSize,\n\t align: this.options.minorTickType\n\t });\n\n\t this.options.majorTicks = deepExtend({}, {\n\t color: this.options.line.color,\n\t width: this.options.line.width,\n\t visible: this.options.majorTickType !== NONE\n\t }, this.options.majorTicks, {\n\t size: this.options.majorTickSize,\n\t align: this.options.majorTickType\n\t });\n\n\t this.initFields();\n\n\t if (!this.options._deferLabels) {\n\t this.createLabels();\n\t }\n\n\t this.createTitle();\n\t this.createNotes();\n\t },\n\n\t initFields: function() {\n\t },\n\n\t labelsRange: function() {\n\t return {\n\t min: this.options.labels.skip,\n\t max: this.labelsCount()\n\t };\n\t },\n\n\t createLabels: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var align = options.vertical ? RIGHT : CENTER;\n\t var labelOptions = deepExtend({ }, options.labels, {\n\t align: align,\n\t zIndex: options.zIndex\n\t });\n\t var step = Math.max(1, labelOptions.step);\n\n\t this.clearLabels();\n\n\t if (labelOptions.visible) {\n\t var range = this.labelsRange();\n\t var rotation = labelOptions.rotation;\n\n\t if (isObject(rotation)) {\n\t labelOptions.alignRotation = rotation.align;\n\t labelOptions.rotation = rotation.angle;\n\t }\n\n\t if (labelOptions.rotation === \"auto\") {\n\t labelOptions.rotation = 0;\n\t options.autoRotateLabels = true;\n\t }\n\n\t for (var idx = range.min; idx < range.max; idx += step) {\n\t var label = this$1.createAxisLabel(idx, labelOptions);\n\t if (label) {\n\t this$1.append(label);\n\t this$1.labels.push(label);\n\t }\n\t }\n\t }\n\t },\n\n\t clearLabels: function() {\n\t this.children = grep(this.children, function (child) { return !(child instanceof AxisLabel); });\n\t this.labels = [];\n\t },\n\n\t clearTitle: function() {\n\t var this$1 = this;\n\n\t if (this.title) {\n\t this.children = grep(this.children, function (child) { return child !== this$1.title; });\n\t this.title = undefined;\n\t }\n\t },\n\n\t clear: function() {\n\t this.clearLabels();\n\t this.clearTitle();\n\t },\n\n\t lineBox: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var box = ref.box;\n\t var vertical = options.vertical;\n\t var mirror = options.labels.mirror;\n\t var axisX = mirror ? box.x1 : box.x2;\n\t var axisY = mirror ? box.y2 : box.y1;\n\t var lineWidth = options.line.width || 0;\n\n\t return vertical ?\n\t new Box(axisX, box.y1, axisX, box.y2 - lineWidth) :\n\t new Box(box.x1, axisY, box.x2 - lineWidth, axisY);\n\t },\n\n\t createTitle: function() {\n\t var options = this.options;\n\t var titleOptions = deepExtend({\n\t rotation: options.vertical ? -90 : 0,\n\t text: \"\",\n\t zIndex: 1,\n\t visualSize: true\n\t }, options.title);\n\n\t if (titleOptions.visible && titleOptions.text) {\n\t var title = new TextBox(titleOptions.text, titleOptions);\n\t this.append(title);\n\t this.title = title;\n\t }\n\t },\n\n\t createNotes: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var notes = options.notes;\n\t var items = notes.data || [];\n\n\t this.notes = [];\n\n\t for (var i = 0; i < items.length; i++) {\n\t var item = deepExtend({}, notes, items[i]);\n\t item.value = this$1.parseNoteValue(item.value);\n\n\t var note = new Note({\n\t value: item.value,\n\t text: item.label.text,\n\t dataItem: item\n\t }, item, this$1.chartService);\n\n\t if (note.options.visible) {\n\t if (defined(note.options.position)) {\n\t if (options.vertical && !inArray(note.options.position, [ LEFT, RIGHT ])) {\n\t note.options.position = options.reverse ? LEFT : RIGHT;\n\t } else if (!options.vertical && !inArray(note.options.position, [ TOP, BOTTOM ])) {\n\t note.options.position = options.reverse ? BOTTOM : TOP;\n\t }\n\t } else {\n\t if (options.vertical) {\n\t note.options.position = options.reverse ? LEFT : RIGHT;\n\t } else {\n\t note.options.position = options.reverse ? BOTTOM : TOP;\n\t }\n\t }\n\t this$1.append(note);\n\t this$1.notes.push(note);\n\t }\n\t }\n\t },\n\n\t parseNoteValue: function(value) {\n\t return value;\n\t },\n\n\t renderVisual: function() {\n\t ChartElement.fn.renderVisual.call(this);\n\n\t this.createPlotBands();\n\t },\n\n\t createVisual: function() {\n\t ChartElement.fn.createVisual.call(this);\n\n\t this.createBackground();\n\t this.createLine();\n\t },\n\n\t gridLinesVisual: function() {\n\t var gridLines = this._gridLines;\n\t if (!gridLines) {\n\t gridLines = this._gridLines = new Group({\n\t zIndex: -2\n\t });\n\t this.appendVisual(this._gridLines);\n\t }\n\n\t return gridLines;\n\t },\n\n\t createTicks: function(lineGroup) {\n\t var options = this.options;\n\t var lineBox = this.lineBox();\n\t var mirror = options.labels.mirror;\n\t var majorUnit = options.majorTicks.visible ? options.majorUnit : 0;\n\t var tickLineOptions = {\n\t // TODO\n\t // _alignLines: options._alignLines,\n\t vertical: options.vertical\n\t };\n\n\t function render(tickPositions, tickOptions, skipUnit) {\n\t var count = tickPositions.length;\n\t var step = Math.max(1, tickOptions.step);\n\n\t if (tickOptions.visible) {\n\t for (var i = tickOptions.skip; i < count; i += step) {\n\t if (defined(skipUnit) && (i % skipUnit === 0)) {\n\t continue;\n\t }\n\n\t tickLineOptions.tickX = mirror ? lineBox.x2 : lineBox.x2 - tickOptions.size;\n\t tickLineOptions.tickY = mirror ? lineBox.y1 - tickOptions.size : lineBox.y1;\n\t tickLineOptions.position = tickPositions[i];\n\n\t lineGroup.append(createAxisTick(tickLineOptions, tickOptions));\n\t }\n\t }\n\t }\n\n\t render(this.getMajorTickPositions(), options.majorTicks);\n\t render(this.getMinorTickPositions(), options.minorTicks, majorUnit / options.minorUnit);\n\t },\n\n\t createLine: function() {\n\t var options = this.options;\n\t var line = options.line;\n\t var lineBox = this.lineBox();\n\n\t if (line.width > 0 && line.visible) {\n\t var path = new Path({\n\t stroke: {\n\t width: line.width,\n\t color: line.color,\n\t dashType: line.dashType\n\t }\n\n\t /* TODO\n\t zIndex: line.zIndex,\n\t */\n\t });\n\n\t path.moveTo(lineBox.x1, lineBox.y1)\n\t .lineTo(lineBox.x2, lineBox.y2);\n\n\t if (options._alignLines) {\n\t alignPathToPixel(path);\n\t }\n\n\t var group = this._lineGroup = new Group();\n\t group.append(path);\n\n\t this.visual.append(group);\n\t this.createTicks(group);\n\t }\n\t },\n\n\t getActualTickSize: function() {\n\t var options = this.options;\n\t var tickSize = 0;\n\n\t if (options.majorTicks.visible && options.minorTicks.visible) {\n\t tickSize = Math.max(options.majorTicks.size, options.minorTicks.size);\n\t } else if (options.majorTicks.visible) {\n\t tickSize = options.majorTicks.size;\n\t } else if (options.minorTicks.visible) {\n\t tickSize = options.minorTicks.size;\n\t }\n\n\t return tickSize;\n\t },\n\n\t createBackground: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var box = ref.box;\n\t var background = options.background;\n\n\t if (background) {\n\t this._backgroundPath = Path.fromRect(box.toRect(), {\n\t fill: {\n\t color: background\n\t },\n\t stroke: null\n\t });\n\n\t this.visual.append(this._backgroundPath);\n\t }\n\t },\n\n\t createPlotBands: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var plotBands = options.plotBands || [];\n\t var vertical = options.vertical;\n\t var plotArea = this.plotArea;\n\n\t if (plotBands.length === 0) {\n\t return;\n\t }\n\n\t var group = this._plotbandGroup = new Group({\n\t zIndex: -1\n\t });\n\n\t var altAxis = grep(this.pane.axes, function (axis) { return axis.options.vertical !== this$1.options.vertical; })[0];\n\n\t for (var idx = 0; idx < plotBands.length; idx++) {\n\t var item = plotBands[idx];\n\t var slotX = (void 0), slotY = (void 0);\n\n\t if (vertical) {\n\t slotX = (altAxis || plotArea.axisX).lineBox();\n\t slotY = this$1.getSlot(item.from, item.to, true);\n\t } else {\n\t slotX = this$1.getSlot(item.from, item.to, true);\n\t slotY = (altAxis || plotArea.axisY).lineBox();\n\t }\n\n\t if (slotX.width() !== 0 && slotY.height() !== 0) {\n\t var bandRect = new Rect(\n\t [ slotX.x1, slotY.y1 ],\n\t [ slotX.width(), slotY.height() ]\n\t );\n\n\t var path = Path.fromRect(bandRect, {\n\t fill: {\n\t color: item.color,\n\t opacity: item.opacity\n\t },\n\t stroke: null\n\t });\n\n\t group.append(path);\n\t }\n\t }\n\n\t this.appendVisual(group);\n\t },\n\n\t createGridLines: function(altAxis) {\n\t var options = this.options;\n\t var minorGridLines = options.minorGridLines;\n\t var majorGridLines = options.majorGridLines;\n\t var minorUnit = options.minorUnit;\n\t var vertical = options.vertical;\n\t var axisLineVisible = altAxis.options.line.visible;\n\t var majorUnit = majorGridLines.visible ? options.majorUnit : 0;\n\t var lineBox = altAxis.lineBox();\n\t var linePos = lineBox[vertical ? \"y1\" : \"x1\"];\n\t var lineOptions = {\n\t lineStart: lineBox[vertical ? \"x1\" : \"y1\"],\n\t lineEnd: lineBox[vertical ? \"x2\" : \"y2\"],\n\t vertical: vertical\n\t };\n\t var majorTicks = [];\n\n\t var container = this.gridLinesVisual();\n\n\t function render(tickPositions, gridLine, skipUnit) {\n\t var count = tickPositions.length;\n\t var step = Math.max(1, gridLine.step);\n\n\t if (gridLine.visible) {\n\t for (var i = gridLine.skip; i < count; i += step) {\n\t var pos = round(tickPositions[i]);\n\t if (!inArray(pos, majorTicks)) {\n\t if (i % skipUnit !== 0 && (!axisLineVisible || linePos !== pos)) {\n\t lineOptions.position = pos;\n\t container.append(createAxisGridLine(lineOptions, gridLine));\n\n\t majorTicks.push(pos);\n\t }\n\t }\n\t }\n\t }\n\t }\n\n\t render(this.getMajorTickPositions(), majorGridLines);\n\t render(this.getMinorTickPositions(), minorGridLines, majorUnit / minorUnit);\n\n\t return container.children;\n\t },\n\n\t reflow: function(box) {\n\t var ref = this;\n\t var options = ref.options;\n\t var labels = ref.labels;\n\t var title = ref.title;\n\t var vertical = options.vertical;\n\t var count = labels.length;\n\t var sizeFn = vertical ? WIDTH : HEIGHT;\n\t var titleSize = title ? title.box[sizeFn]() : 0;\n\t var space = this.getActualTickSize() + options.margin + titleSize;\n\t var rootBox = (this.getRoot() || {}).box || box;\n\t var boxSize = rootBox[sizeFn]();\n\t var maxLabelSize = 0;\n\n\t for (var i = 0; i < count; i++) {\n\t var labelSize = labels[i].box[sizeFn]();\n\t if (labelSize + space <= boxSize) {\n\t maxLabelSize = Math.max(maxLabelSize, labelSize);\n\t }\n\t }\n\n\t if (vertical) {\n\t this.box = new Box(\n\t box.x1, box.y1,\n\t box.x1 + maxLabelSize + space, box.y2\n\t );\n\t } else {\n\t this.box = new Box(\n\t box.x1, box.y1,\n\t box.x2, box.y1 + maxLabelSize + space\n\t );\n\t }\n\n\t this.arrangeTitle();\n\t this.arrangeLabels();\n\t this.arrangeNotes();\n\t },\n\n\t getLabelsTickPositions: function() {\n\t return this.getMajorTickPositions();\n\t },\n\n\t labelTickIndex: function(label) {\n\t return label.index;\n\t },\n\n\t arrangeLabels: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var options = ref.options;\n\t var labels = ref.labels;\n\t var labelsBetweenTicks = this.labelsBetweenTicks();\n\t var vertical = options.vertical;\n\t var lineBox = this.lineBox();\n\t var mirror = options.labels.mirror;\n\t var tickPositions = this.getLabelsTickPositions();\n\t var labelOffset = this.getActualTickSize() + options.margin;\n\n\t for (var idx = 0; idx < labels.length; idx++) {\n\t var label = labels[idx];\n\t var tickIx = this$1.labelTickIndex(label);\n\t var labelSize = vertical ? label.box.height() : label.box.width();\n\t var labelPos = tickPositions[tickIx] - (labelSize / 2);\n\t var labelBox = (void 0), firstTickPosition = (void 0), nextTickPosition = (void 0);\n\n\t if (vertical) {\n\t if (labelsBetweenTicks) {\n\t firstTickPosition = tickPositions[tickIx];\n\t nextTickPosition = tickPositions[tickIx + 1];\n\n\t var middle = firstTickPosition + (nextTickPosition - firstTickPosition) / 2;\n\t labelPos = middle - (labelSize / 2);\n\t }\n\n\t var labelX = lineBox.x2;\n\n\t if (mirror) {\n\t labelX += labelOffset;\n\t label.options.rotationOrigin = LEFT;\n\t } else {\n\t labelX -= labelOffset + label.box.width();\n\t label.options.rotationOrigin = RIGHT;\n\t }\n\n\t labelBox = label.box.move(labelX, labelPos);\n\t } else {\n\t if (labelsBetweenTicks) {\n\t firstTickPosition = tickPositions[tickIx];\n\t nextTickPosition = tickPositions[tickIx + 1];\n\t } else {\n\t firstTickPosition = labelPos;\n\t nextTickPosition = labelPos + labelSize;\n\t }\n\n\t var labelY = lineBox.y1;\n\n\t if (mirror) {\n\t labelY -= labelOffset + label.box.height();\n\t label.options.rotationOrigin = BOTTOM;\n\t } else {\n\t labelY += labelOffset;\n\t label.options.rotationOrigin = TOP;\n\t }\n\n\t labelBox = new Box(firstTickPosition, labelY,\n\t nextTickPosition, labelY + label.box.height());\n\t }\n\n\t label.reflow(labelBox);\n\t }\n\t },\n\n\t autoRotateLabels: function() {\n\t if (this.options.autoRotateLabels && !this.options.vertical) {\n\t var tickPositions = this.getMajorTickPositions();\n\t var labels = this.labels;\n\t var angle;\n\n\t for (var idx = 0; idx < labels.length; idx++) {\n\t var width = Math.abs(tickPositions[idx + 1] - tickPositions[idx]);\n\t var labelBox = labels[idx].box;\n\n\t if (labelBox.width() > width) {\n\t if (labelBox.height() > width) {\n\t angle = -90;\n\t break;\n\t }\n\t angle = -45;\n\t }\n\t }\n\n\t if (angle) {\n\t for (var idx$1 = 0; idx$1 < labels.length; idx$1++) {\n\t labels[idx$1].options.rotation = angle;\n\t labels[idx$1].reflow(new Box());\n\t }\n\t return true;\n\t }\n\t }\n\t },\n\n\t arrangeTitle: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var title = ref.title;\n\t var mirror = options.labels.mirror;\n\t var vertical = options.vertical;\n\n\t if (title) {\n\t if (vertical) {\n\t title.options.align = mirror ? RIGHT : LEFT;\n\t title.options.vAlign = title.options.position;\n\t } else {\n\t title.options.align = title.options.position;\n\t title.options.vAlign = mirror ? TOP : BOTTOM;\n\t }\n\n\t title.reflow(this.box);\n\t }\n\t },\n\n\t arrangeNotes: function() {\n\t var this$1 = this;\n\n\t for (var idx = 0; idx < this.notes.length; idx++) {\n\t var item = this$1.notes[idx];\n\t var value = item.options.value;\n\t var slot = (void 0);\n\n\t if (defined(value)) {\n\t if (this$1.shouldRenderNote(value)) {\n\t item.show();\n\t } else {\n\t item.hide();\n\t }\n\n\t slot = this$1.noteSlot(value);\n\t } else {\n\t item.hide();\n\t }\n\n\t item.reflow(slot || this$1.lineBox());\n\t }\n\t },\n\n\t noteSlot: function(value) {\n\t return this.getSlot(value);\n\t },\n\n\t alignTo: function(secondAxis) {\n\t var lineBox = secondAxis.lineBox();\n\t var vertical = this.options.vertical;\n\t var pos = vertical ? Y : X;\n\n\t this.box.snapTo(lineBox, pos);\n\t if (vertical) {\n\t this.box.shrink(0, this.lineBox().height() - lineBox.height());\n\t } else {\n\t this.box.shrink(this.lineBox().width() - lineBox.width(), 0);\n\t }\n\t this.box[pos + 1] -= this.lineBox()[pos + 1] - lineBox[pos + 1];\n\t this.box[pos + 2] -= this.lineBox()[pos + 2] - lineBox[pos + 2];\n\t },\n\n\t axisLabelText: function(value, dataItem, options) {\n\t var tmpl = getTemplate(options);\n\t var text = value;\n\n\t if (tmpl) {\n\t text = tmpl({ value: value, dataItem: dataItem, format: options.format, culture: options.culture });\n\t } else if (options.format) {\n\t text = this.chartService.format.localeAuto(options.format, [ value ], options.culture);\n\t }\n\n\t return text;\n\t },\n\n\t slot: function(from , to, limit) {\n\t var slot = this.getSlot(from, to, limit);\n\t if (slot) {\n\t return slot.toRect();\n\t }\n\t },\n\n\t contentBox: function() {\n\t var box = this.box.clone();\n\t var labels = this.labels;\n\t if (labels.length) {\n\t var axis = this.options.vertical ? Y : X;\n\t if (this.chartService.isPannable(axis)) {\n\t var offset = this.maxLabelOffset();\n\t box[axis + 1] -= offset.start;\n\t box[axis + 2] += offset.end;\n\t } else {\n\t if (labels[0].options.visible) {\n\t box.wrap(labels[0].box);\n\t }\n\t var lastLabel = labels[labels.length - 1];\n\t if (lastLabel.options.visible) {\n\t box.wrap(lastLabel.box);\n\t }\n\t }\n\t }\n\n\t return box;\n\t },\n\n\t maxLabelOffset: function() {\n\t var this$1 = this;\n\n\t var ref = this.options;\n\t var vertical = ref.vertical;\n\t var reverse = ref.reverse;\n\t var labelsBetweenTicks = this.labelsBetweenTicks();\n\t var tickPositions = this.getLabelsTickPositions();\n\t var offsetField = vertical ? Y : X;\n\t var labels = this.labels;\n\t var startPosition = reverse ? 1 : 0;\n\t var endPosition = reverse ? 0 : 1;\n\t var maxStartOffset = 0;\n\t var maxEndOffset = 0;\n\n\t for (var idx = 0; idx < labels.length; idx++) {\n\t var label = labels[idx];\n\t var tickIx = this$1.labelTickIndex(label);\n\t var startTick = (void 0), endTick = (void 0);\n\n\t if (labelsBetweenTicks) {\n\t startTick = tickPositions[tickIx + startPosition];\n\t endTick = tickPositions[tickIx + endPosition];\n\t } else {\n\t startTick = endTick = tickPositions[tickIx];\n\t }\n\n\t maxStartOffset = Math.max(maxStartOffset, startTick - label.box[offsetField + 1]);\n\t maxEndOffset = Math.max(maxEndOffset, label.box[offsetField + 2] - endTick);\n\t }\n\n\t return {\n\t start: maxStartOffset,\n\t end: maxEndOffset\n\t };\n\t },\n\n\t limitRange: function(from, to, min, max, offset) {\n\t var options = this.options;\n\n\t if ((from < min && offset < 0 && (!defined(options.min) || options.min <= min)) || (max < to && offset > 0 && (!defined(options.max) || max <= options.max))) {\n\t return null;\n\t }\n\n\t if ((to < min && offset > 0) || (max < from && offset < 0)) {\n\t return {\n\t min: from,\n\t max: to\n\t };\n\t }\n\n\t var rangeSize = to - from;\n\t var minValue = from;\n\t var maxValue = to;\n\n\t if (from < min && offset < 0) {\n\t minValue = limitValue(from, min, max);\n\t maxValue = limitValue(from + rangeSize, min + rangeSize, max);\n\t } else if (to > max && offset > 0) {\n\t maxValue = limitValue(to, min, max);\n\t minValue = limitValue(to - rangeSize, min, max - rangeSize);\n\t }\n\n\t return {\n\t min: minValue,\n\t max: maxValue\n\t };\n\t },\n\n\t valueRange: function() {\n\t return {\n\t min: this.seriesMin,\n\t max: this.seriesMax\n\t };\n\t },\n\n\t labelsBetweenTicks: function() {\n\t return !this.options.justified;\n\t },\n\n\t prepareUserOptions: function() {\n\t }\n\t});\n\n\tsetDefaultOptions(Axis, {\n\t labels: {\n\t visible: true,\n\t rotation: 0,\n\t mirror: false,\n\t step: 1,\n\t skip: 0\n\t },\n\t line: {\n\t width: 1,\n\t color: BLACK,\n\t visible: true\n\t },\n\t title: {\n\t visible: true,\n\t position: CENTER\n\t },\n\t majorTicks: {\n\t align: OUTSIDE,\n\t size: 4,\n\t skip: 0,\n\t step: 1\n\t },\n\t minorTicks: {\n\t align: OUTSIDE,\n\t size: 3,\n\t skip: 0,\n\t step: 1\n\t },\n\t axisCrossingValue: 0,\n\t majorTickType: OUTSIDE,\n\t minorTickType: NONE,\n\t majorGridLines: {\n\t skip: 0,\n\t step: 1\n\t },\n\t minorGridLines: {\n\t visible: false,\n\t width: 1,\n\t color: BLACK,\n\t skip: 0,\n\t step: 1\n\t },\n\t // TODO: Move to line or labels options\n\t margin: 5,\n\t visible: true,\n\t reverse: false,\n\t justified: true,\n\t notes: {\n\t label: {\n\t text: \"\"\n\t }\n\t },\n\n\t _alignLines: true,\n\t _deferLabels: false\n\t});\n\n\tvar MILLISECONDS = \"milliseconds\";\n\tvar SECONDS = \"seconds\";\n\tvar MINUTES = \"minutes\";\n\tvar HOURS = \"hours\";\n\tvar DAYS = \"days\";\n\tvar WEEKS = \"weeks\";\n\tvar MONTHS = \"months\";\n\tvar YEARS = \"years\";\n\n\tvar TIME_PER_MILLISECOND = 1;\n\tvar TIME_PER_SECOND = 1000;\n\tvar TIME_PER_MINUTE = 60 * TIME_PER_SECOND;\n\tvar TIME_PER_HOUR = 60 * TIME_PER_MINUTE;\n\tvar TIME_PER_DAY = 24 * TIME_PER_HOUR;\n\tvar TIME_PER_WEEK = 7 * TIME_PER_DAY;\n\tvar TIME_PER_MONTH = 31 * TIME_PER_DAY;\n\tvar TIME_PER_YEAR = 365 * TIME_PER_DAY;\n\tvar TIME_PER_UNIT = {\n\t \"years\": TIME_PER_YEAR,\n\t \"months\": TIME_PER_MONTH,\n\t \"weeks\": TIME_PER_WEEK,\n\t \"days\": TIME_PER_DAY,\n\t \"hours\": TIME_PER_HOUR,\n\t \"minutes\": TIME_PER_MINUTE,\n\t \"seconds\": TIME_PER_SECOND,\n\t \"milliseconds\": TIME_PER_MILLISECOND\n\t};\n\n\tfunction absoluteDateDiff(a, b) {\n\t var diff = a.getTime() - b;\n\t var offsetDiff = a.getTimezoneOffset() - b.getTimezoneOffset();\n\n\t return diff - (offsetDiff * TIME_PER_MINUTE);\n\t}\n\n\tfunction addTicks(date, ticks) {\n\t return new Date(date.getTime() + ticks);\n\t}\n\n\tfunction toDate(value) {\n\t var result;\n\n\t if (value instanceof Date) {\n\t result = value;\n\t } else if (value) {\n\t result = new Date(value);\n\t }\n\n\t return result;\n\t}\n\n\tfunction startOfWeek(date, weekStartDay) {\n\t if (weekStartDay === void 0) { weekStartDay = 0; }\n\n\t var daysToSubtract = 0;\n\t var day = date.getDay();\n\n\t if (!isNaN(day)) {\n\t while (day !== weekStartDay) {\n\t if (day === 0) {\n\t day = 6;\n\t } else {\n\t day--;\n\t }\n\n\t daysToSubtract++;\n\t }\n\t }\n\n\t return addTicks(date, -daysToSubtract * TIME_PER_DAY);\n\t}\n\n\tfunction adjustDST(date, hours) {\n\t if (hours === 0 && date.getHours() === 23) {\n\t date.setHours(date.getHours() + 2);\n\t return true;\n\t }\n\n\t return false;\n\t}\n\n\tfunction addHours(date, hours) {\n\t var roundedDate = new Date(date);\n\n\t roundedDate.setMinutes(0, 0, 0);\n\n\t var tzDiff = (date.getTimezoneOffset() - roundedDate.getTimezoneOffset()) * TIME_PER_MINUTE;\n\n\t return addTicks(roundedDate, tzDiff + hours * TIME_PER_HOUR);\n\t}\n\n\tfunction addDuration(dateValue, value, unit, weekStartDay) {\n\t var result = dateValue;\n\n\t if (dateValue) {\n\t var date = toDate(dateValue);\n\t var hours = date.getHours();\n\n\t if (unit === YEARS) {\n\t result = new Date(date.getFullYear() + value, 0, 1);\n\t adjustDST(result, 0);\n\t } else if (unit === MONTHS) {\n\t result = new Date(date.getFullYear(), date.getMonth() + value, 1);\n\t adjustDST(result, hours);\n\t } else if (unit === WEEKS) {\n\t result = addDuration(startOfWeek(date, weekStartDay), value * 7, DAYS);\n\t adjustDST(result, hours);\n\t } else if (unit === DAYS) {\n\t result = new Date(date.getFullYear(), date.getMonth(), date.getDate() + value);\n\t adjustDST(result, hours);\n\t } else if (unit === HOURS) {\n\t result = addHours(date, value);\n\t } else if (unit === MINUTES) {\n\t result = addTicks(date, value * TIME_PER_MINUTE);\n\n\t if (result.getSeconds() > 0) {\n\t result.setSeconds(0);\n\t }\n\t } else if (unit === SECONDS) {\n\t result = addTicks(date, value * TIME_PER_SECOND);\n\t } else if (unit === MILLISECONDS) {\n\t result = addTicks(date, value);\n\t }\n\n\t if (unit !== MILLISECONDS && result.getMilliseconds() > 0) {\n\t result.setMilliseconds(0);\n\t }\n\t }\n\n\t return result;\n\t}\n\n\tfunction floorDate(date, unit, weekStartDay) {\n\t return addDuration(toDate(date), 0, unit, weekStartDay);\n\t}\n\n\tfunction ceilDate(dateValue, unit, weekStartDay) {\n\t var date = toDate(dateValue);\n\n\t if (date && floorDate(date, unit, weekStartDay).getTime() === date.getTime()) {\n\t return date;\n\t }\n\n\t return addDuration(date, 1, unit, weekStartDay);\n\t}\n\n\tfunction dateComparer(a, b) {\n\t if (a && b) {\n\t return a.getTime() - b.getTime();\n\t }\n\n\t return -1;\n\t}\n\n\tfunction dateDiff(a, b) {\n\t return a.getTime() - b;\n\t}\n\n\tfunction toTime(value) {\n\t if (isArray(value)) {\n\t var result = [];\n\t for (var idx = 0; idx < value.length; idx++) {\n\t result.push(toTime(value[idx]));\n\t }\n\n\t return result;\n\t } else if (value) {\n\t return toDate(value).getTime();\n\t }\n\t}\n\n\tfunction dateEquals(a, b) {\n\t if (a && b) {\n\t return toTime(a) === toTime(b);\n\t }\n\n\t return a === b;\n\t}\n\n\tfunction timeIndex(date, start, baseUnit) {\n\t return absoluteDateDiff(date, start) / TIME_PER_UNIT[baseUnit];\n\t}\n\n\tfunction dateIndex(value, start, baseUnit, baseUnitStep) {\n\t var date = toDate(value);\n\t var startDate = toDate(start);\n\t var index;\n\n\t if (baseUnit === MONTHS) {\n\t index = (date.getMonth() - startDate.getMonth() + (date.getFullYear() - startDate.getFullYear()) * 12) +\n\t timeIndex(date, new Date(date.getFullYear(), date.getMonth()), DAYS) / new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();\n\t } else if (baseUnit === YEARS) {\n\t index = date.getFullYear() - startDate.getFullYear() + dateIndex(date, new Date(date.getFullYear(), 0), MONTHS, 1) / 12;\n\t } else if (baseUnit === DAYS || baseUnit === WEEKS) {\n\t index = timeIndex(date, startDate, baseUnit);\n\t } else {\n\t index = dateDiff(date, start) / TIME_PER_UNIT[baseUnit];\n\t }\n\n\t return index / baseUnitStep;\n\t}\n\n\tfunction duration(a, b, unit) {\n\t var diff;\n\n\t if (unit === YEARS) {\n\t diff = b.getFullYear() - a.getFullYear();\n\t } else if (unit === MONTHS) {\n\t diff = duration(a, b, YEARS) * 12 + b.getMonth() - a.getMonth();\n\t } else if (unit === DAYS) {\n\t diff = Math.floor(dateDiff(b, a) / TIME_PER_DAY);\n\t } else {\n\t diff = Math.floor(dateDiff(b, a) / TIME_PER_UNIT[unit]);\n\t }\n\n\t return diff;\n\t}\n\n\tfunction lteDateIndex(date, sortedDates) {\n\t var low = 0;\n\t var high = sortedDates.length - 1;\n\t var index;\n\n\t while (low <= high) {\n\t index = Math.floor((low + high) / 2);\n\t var currentDate = sortedDates[index];\n\n\t if (currentDate < date) {\n\t low = index + 1;\n\t continue;\n\t }\n\n\t if (currentDate > date) {\n\t high = index - 1;\n\t continue;\n\t }\n\n\t while (dateEquals(sortedDates[index - 1], date)) {\n\t index--;\n\t }\n\n\t return index;\n\t }\n\n\t if (sortedDates[index] <= date) {\n\t return index;\n\t }\n\n\t return index - 1;\n\t}\n\n\tfunction parseDate(intlService, date) {\n\t var result;\n\t if (isString(date)) {\n\t result = intlService.parseDate(date) || toDate(date);\n\t } else {\n\t result = toDate(date);\n\t }\n\t return result;\n\t}\n\n\tfunction parseDates(intlService, dates) {\n\t if (isArray(dates)) {\n\t var result = [];\n\t for (var idx = 0; idx < dates.length; idx++) {\n\t result.push(parseDate(intlService, dates[idx]));\n\t }\n\n\t return result;\n\t }\n\n\t return parseDate(intlService, dates);\n\t}\n\n\tvar MIN_CATEGORY_POINTS_RANGE = 0.01;\n\n\tfunction indexOf(value, arr) {\n\t if (value instanceof Date) {\n\t var length = arr.length;\n\t for (var idx = 0; idx < length; idx++) {\n\t if (dateEquals(arr[idx], value)) {\n\t return idx;\n\t }\n\t }\n\n\t return -1;\n\t }\n\n\t return arr.indexOf(value);\n\t}\n\n\tvar CategoryAxis = Axis.extend({\n\t initFields: function() {\n\t this._ticks = {};\n\t },\n\n\t categoriesHash: function() {\n\t return \"\";\n\t },\n\n\t clone: function() {\n\t var copy = new CategoryAxis($.extend({}, this.options, {\n\t categories: this.options.srcCategories\n\t }), this.chartService);\n\t copy.createLabels();\n\n\t return copy;\n\t },\n\n\t initUserOptions: function(options) {\n\t var categories = options.categories || [];\n\t var definedMin = defined(options.min);\n\t var definedMax = defined(options.max);\n\t options.srcCategories = options.categories = categories;\n\n\t if ((definedMin || definedMax) && categories.length) {\n\t var min = definedMin ? Math.floor(options.min) : 0;\n\t var max;\n\n\t if (definedMax) {\n\t max = options.justified ? Math.floor(options.max) + 1 : Math.ceil(options.max);\n\t } else {\n\t max = categories.length;\n\t }\n\n\t options.categories = options.categories.slice(min, max);\n\t }\n\n\t return options;\n\t },\n\n\t rangeIndices: function() {\n\t var options = this.options;\n\t var length = options.categories.length || 1;\n\t var min = isNumber(options.min) ? options.min % 1 : 0;\n\t var max;\n\n\t if (isNumber(options.max) && options.max % 1 !== 0 && options.max < this.totalRange().max) {\n\t max = length - (1 - options.max % 1);\n\t } else {\n\t max = length - (options.justified ? 1 : 0);\n\t }\n\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t },\n\n\t totalRangeIndices: function(limit) {\n\t var options = this.options;\n\t var min = isNumber(options.min) ? options.min : 0;\n\t var max;\n\n\t if (isNumber(options.max)) {\n\t max = options.max;\n\t } else if (isNumber(options.min)) {\n\t max = min + options.categories.length;\n\t } else {\n\t max = this.totalRange().max || 1;\n\t }\n\n\t if (limit) {\n\t var totalRange = this.totalRange();\n\t min = limitValue(min, 0, totalRange.max);\n\t max = limitValue(max, 0, totalRange.max);\n\t }\n\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t },\n\n\t range: function() {\n\t var options = this.options;\n\t var min = isNumber(options.min) ? options.min : 0;\n\t var max = isNumber(options.max) ? options.max : this.totalRange().max;\n\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t },\n\n\t roundedRange: function() {\n\t return this.range();\n\t },\n\n\t totalRange: function() {\n\t var options = this.options;\n\t return { min: 0, max: Math.max(this._seriesMax || 0, options.srcCategories.length) - (options.justified ? 1 : 0) };\n\t },\n\n\t scaleOptions: function() {\n\t var ref = this.rangeIndices();\n\t var min = ref.min;\n\t var max = ref.max;\n\t var lineBox = this.lineBox();\n\t var size = this.options.vertical ? lineBox.height() : lineBox.width();\n\t var scale = size / ((max - min) || 1);\n\n\t return {\n\t scale: scale * (this.options.reverse ? -1 : 1),\n\t box: lineBox,\n\t min: min,\n\t max: max\n\t };\n\t },\n\n\t arrangeLabels: function() {\n\t Axis.fn.arrangeLabels.call(this);\n\t this.hideOutOfRangeLabels();\n\t },\n\n\t hideOutOfRangeLabels: function() {\n\t var ref = this;\n\t var box = ref.box;\n\t var labels = ref.labels;\n\n\t if (labels.length) {\n\t var valueAxis = this.options.vertical ? Y : X;\n\t var start = box[valueAxis + 1];\n\t var end = box[valueAxis + 2];\n\t var firstLabel = labels[0];\n\t var lastLabel = last(labels);\n\n\t if (firstLabel.box[valueAxis + 1] > end || firstLabel.box[valueAxis + 2] < start) {\n\t firstLabel.options.visible = false;\n\t }\n\t if (lastLabel.box[valueAxis + 1] > end || lastLabel.box[valueAxis + 2] < start) {\n\t lastLabel.options.visible = false;\n\t }\n\t }\n\t },\n\n\t getMajorTickPositions: function() {\n\t return this.getTicks().majorTicks;\n\t },\n\n\t getMinorTickPositions: function() {\n\t return this.getTicks().minorTicks;\n\t },\n\n\t getLabelsTickPositions: function() {\n\t return this.getTicks().labelTicks;\n\t },\n\n\t tickIndices: function(stepSize) {\n\t var ref = this.rangeIndices();\n\t var min = ref.min;\n\t var max = ref.max;\n\t var limit = Math.ceil(max);\n\t var current = Math.floor(min);\n\t var indices = [];\n\n\t while (current <= limit) {\n\t indices.push(current);\n\t current += stepSize;\n\t }\n\n\t return indices;\n\t },\n\n\t getTickPositions: function(stepSize) {\n\t var ref = this.options;\n\t var vertical = ref.vertical;\n\t var reverse = ref.reverse;\n\t var ref$1 = this.scaleOptions();\n\t var scale = ref$1.scale;\n\t var box = ref$1.box;\n\t var min = ref$1.min;\n\t var pos = box[(vertical ? Y : X) + (reverse ? 2 : 1)];\n\t var indices = this.tickIndices(stepSize);\n\t var positions = [];\n\n\t for (var idx = 0; idx < indices.length; idx++) {\n\t positions.push(pos + round(scale * (indices[idx] - min), COORD_PRECISION));\n\t }\n\n\t return positions;\n\t },\n\n\t getTicks: function() {\n\t var options = this.options;\n\t var cache = this._ticks;\n\t var range = this.rangeIndices();\n\t var lineBox = this.lineBox();\n\t var hash = lineBox.getHash() + range.min + \",\" + range.max + options.reverse + options.justified;\n\n\t if (cache._hash !== hash) {\n\t var hasMinor = options.minorTicks.visible || options.minorGridLines.visible;\n\t cache._hash = hash;\n\t cache.labelTicks = this.getTickPositions(1);\n\t cache.majorTicks = this.filterOutOfRangePositions(cache.labelTicks, lineBox);\n\t cache.minorTicks = hasMinor ? this.filterOutOfRangePositions(this.getTickPositions(0.5), lineBox) : [];\n\t }\n\n\t return cache;\n\t },\n\n\t filterOutOfRangePositions: function(positions, lineBox) {\n\t if (!positions.length) {\n\t return positions;\n\t }\n\n\t var axis = this.options.vertical ? Y : X;\n\t var inRange = function (position) { return lineBox[axis + 1] <= position && position <= lineBox[axis + 2]; };\n\n\t var end = positions.length - 1;\n\t var startIndex = 0;\n\t while (!inRange(positions[startIndex]) && startIndex <= end) {\n\t startIndex++;\n\t }\n\n\t var endIndex = end;\n\n\t while (!inRange(positions[endIndex]) && endIndex >= 0) {\n\t endIndex--;\n\t }\n\n\t return positions.slice(startIndex, endIndex + 1);\n\t },\n\n\t getSlot: function(from, to, limit) {\n\t var options = this.options;\n\t var reverse = options.reverse;\n\t var justified = options.justified;\n\t var vertical = options.vertical;\n\t var ref = this.scaleOptions();\n\t var scale = ref.scale;\n\t var box = ref.box;\n\t var min = ref.min;\n\t var valueAxis = vertical ? Y : X;\n\t var lineStart = box[valueAxis + (reverse ? 2 : 1)];\n\t var slotBox = box.clone();\n\t var singleSlot = !defined(to);\n\n\t var start = valueOrDefault(from, 0);\n\t var end = valueOrDefault(to, start);\n\t end = Math.max(end - 1, start);\n\n\t // Fixes transient bug caused by iOS 6.0 JIT\n\t // (one can never be too sure)\n\t end = Math.max(start, end);\n\n\t var p1 = lineStart + (start - min) * scale;\n\t var p2 = lineStart + (end + 1 - min) * scale;\n\n\t if (singleSlot && justified) {\n\t p2 = p1;\n\t }\n\n\t if (limit) {\n\t p1 = limitValue(p1, box[valueAxis + 1], box[valueAxis + 2]);\n\t p2 = limitValue(p2, box[valueAxis + 1], box[valueAxis + 2]);\n\t }\n\n\t slotBox[valueAxis + 1] = reverse ? p2 : p1;\n\t slotBox[valueAxis + 2] = reverse ? p1 : p2;\n\n\t return slotBox;\n\t },\n\n\t limitSlot: function(slot) {\n\t var vertical = this.options.vertical;\n\t var valueAxis = vertical ? Y : X;\n\t var lineBox = this.lineBox();\n\t var limittedSlot = slot.clone();\n\n\t limittedSlot[valueAxis + 1] = limitValue(slot[valueAxis + 1], lineBox[valueAxis + 1], lineBox[valueAxis + 2]);\n\t limittedSlot[valueAxis + 2] = limitValue(slot[valueAxis + 2], lineBox[valueAxis + 1], lineBox[valueAxis + 2]);\n\n\t return limittedSlot;\n\t },\n\n\t slot: function(from, to, limit) {\n\t var min = Math.floor(this.options.min || 0);\n\t var start = from;\n\t var end = to;\n\n\t if (typeof start === \"string\") {\n\t start = this.categoryIndex(start);\n\t } else if (isNumber(start)) {\n\t start -= min;\n\t }\n\n\t if (typeof end === \"string\") {\n\t end = this.categoryIndex(end);\n\t } else if (isNumber(end)) {\n\t end -= min;\n\t }\n\n\t return Axis.fn.slot.call(this, start, end, limit);\n\t },\n\n\t pointCategoryIndex: function(point) {\n\t var ref = this.options;\n\t var reverse = ref.reverse;\n\t var justified = ref.justified;\n\t var vertical = ref.vertical;\n\t var valueAxis = vertical ? Y : X;\n\t var ref$1 = this.scaleOptions();\n\t var scale = ref$1.scale;\n\t var box = ref$1.box;\n\t var min = ref$1.min;\n\t var max = ref$1.max;\n\t var startValue = reverse ? max : min;\n\t var lineStart = box[valueAxis + 1];\n\t var lineEnd = box[valueAxis + 2];\n\t var pos = point[valueAxis];\n\n\t if (pos < lineStart || pos > lineEnd) {\n\t return null;\n\t }\n\n\t var value = startValue + (pos - lineStart) / scale;\n\t var diff = value % 1;\n\n\t if (justified) {\n\t value = Math.round(value);\n\t } else if (diff === 0 && value > 0) {\n\t value--;\n\t }\n\n\t return Math.floor(value);\n\t },\n\n\t getCategory: function(point) {\n\t var index = this.pointCategoryIndex(point);\n\n\t if (index === null) {\n\t return null;\n\t }\n\n\t return this.options.categories[index];\n\t },\n\n\t categoryIndex: function(value) {\n\t return this.totalIndex(value) - Math.floor(this.options.min || 0);\n\t },\n\n\t categoryAt: function(index, total) {\n\t var options = this.options;\n\n\t return (total ? options.srcCategories : options.categories)[index];\n\t },\n\n\t categoriesCount: function() {\n\t return (this.options.categories || []).length;\n\t },\n\n\t translateRange: function(delta) {\n\t var options = this.options;\n\t var lineBox = this.lineBox();\n\t var size = options.vertical ? lineBox.height() : lineBox.width();\n\t var range = options.categories.length;\n\t var scale = size / range;\n\t var offset = round(delta / scale, DEFAULT_PRECISION);\n\n\t return {\n\t min: offset,\n\t max: range + offset\n\t };\n\t },\n\n\t zoomRange: function(rate) {\n\t var rangeIndices = this.totalRangeIndices();\n\t var ref = this.totalRange();\n\t var totalMin = ref.min;\n\t var totalMax = ref.max;\n\t var min = limitValue(rangeIndices.min + rate, totalMin, totalMax);\n\t var max = limitValue(rangeIndices.max - rate, totalMin, totalMax);\n\n\t if (max - min > 0) {\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t }\n\t },\n\n\t scaleRange: function(scale) {\n\t var range = this.options.categories.length;\n\t var delta = scale * range;\n\n\t return {\n\t min: -delta,\n\t max: range + delta\n\t };\n\t },\n\n\t labelsCount: function() {\n\t var labelsRange = this.labelsRange();\n\n\t return labelsRange.max - labelsRange.min;\n\t },\n\n\t labelsRange: function() {\n\t var options = this.options;\n\t var justified = options.justified;\n\t var labelOptions = options.labels;\n\t var ref = this.totalRangeIndices(true);\n\t var min = ref.min;\n\t var max = ref.max;\n\t var start = Math.floor(min);\n\n\t if (!justified) {\n\t min = Math.floor(min);\n\t max = Math.ceil(max);\n\t } else {\n\t min = Math.ceil(min);\n\t max = Math.floor(max);\n\t }\n\n\t var skip;\n\n\t if (min > labelOptions.skip) {\n\t skip = labelOptions.skip + labelOptions.step * Math.ceil((min - labelOptions.skip) / labelOptions.step);\n\t } else {\n\t skip = labelOptions.skip;\n\t }\n\n\t return {\n\t min: skip - start,\n\t max: (options.categories.length ? max + (justified ? 1 : 0) : 0) - start\n\t };\n\t },\n\n\t createAxisLabel: function(index, labelOptions) {\n\t var options = this.options;\n\t var dataItem = options.dataItems ? options.dataItems[index] : null;\n\t var category = valueOrDefault(options.categories[index], \"\");\n\t var text = this.axisLabelText(category, dataItem, labelOptions);\n\n\t return new AxisLabel(category, text, index, dataItem, labelOptions);\n\t },\n\n\t shouldRenderNote: function(value) {\n\t var range = this.totalRangeIndices();\n\n\t return Math.floor(range.min) <= value && value <= Math.ceil(range.max);\n\t },\n\n\t noteSlot: function(value) {\n\t var options = this.options;\n\t var index = value - Math.floor(options.min || 0);\n\t return this.getSlot(index);\n\t },\n\n\t arrangeNotes: function() {\n\t Axis.fn.arrangeNotes.call(this);\n\t this.hideOutOfRangeNotes();\n\t },\n\n\t hideOutOfRangeNotes: function() {\n\t var ref = this;\n\t var notes = ref.notes;\n\t var box = ref.box;\n\t if (notes && notes.length) {\n\t var valueAxis = this.options.vertical ? Y : X;\n\t var start = box[valueAxis + 1];\n\t var end = box[valueAxis + 2];\n\n\t for (var idx = 0; idx < notes.length; idx++) {\n\t var note = notes[idx];\n\t if (note.box && (end < note.box[valueAxis + 1] || note.box[valueAxis + 2] < start)) {\n\t note.hide();\n\t }\n\t }\n\t }\n\t },\n\n\t pan: function(delta) {\n\t var range = this.totalRangeIndices(true);\n\t var ref = this.scaleOptions();\n\t var scale = ref.scale;\n\t var offset = round(delta / scale, DEFAULT_PRECISION);\n\t var totalRange = this.totalRange();\n\t var min = range.min + offset;\n\t var max = range.max + offset;\n\n\t return this.limitRange(min, max, 0, totalRange.max, offset);\n\t },\n\n\t pointsRange: function(start, end) {\n\t var ref = this.options;\n\t var reverse = ref.reverse;\n\t var vertical = ref.vertical;\n\t var valueAxis = vertical ? Y : X;\n\t var range = this.totalRangeIndices(true);\n\t var ref$1 = this.scaleOptions();\n\t var scale = ref$1.scale;\n\t var box = ref$1.box;\n\t var lineStart = box[valueAxis + (reverse ? 2 : 1)];\n\n\t var diffStart = start[valueAxis] - lineStart;\n\t var diffEnd = end[valueAxis] - lineStart;\n\n\t var min = range.min + diffStart / scale;\n\t var max = range.min + diffEnd / scale;\n\t var rangeMin = Math.min(min, max);\n\t var rangeMax = Math.max(min, max);\n\n\t if (rangeMax - rangeMin >= MIN_CATEGORY_POINTS_RANGE) {\n\t return {\n\t min: rangeMin,\n\t max: rangeMax\n\t };\n\t }\n\t },\n\n\t valueRange: function() {\n\t return this.range();\n\t },\n\n\t totalIndex: function(value) {\n\t var options = this.options;\n\t var index = this._categoriesMap ?\n\t this._categoriesMap.get(value) : indexOf(value, options.srcCategories);\n\n\t return index;\n\t },\n\n\t currentRangeIndices: function() {\n\t var options = this.options;\n\t var min = 0;\n\n\t if (isNumber(options.min)) {\n\t min = Math.floor(options.min);\n\t }\n\n\t var max;\n\t if (isNumber(options.max)) {\n\t max = options.justified ? Math.floor(options.max) : Math.ceil(options.max) - 1;\n\t } else {\n\t max = this.totalCount() - 1;\n\t }\n\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t },\n\n\t mapCategories: function() {\n\t if (!this._categoriesMap) {\n\t var map$$1 = this._categoriesMap = new HashMap();\n\t var srcCategories = this.options.srcCategories;\n\t for (var idx = 0; idx < srcCategories.length; idx++) {\n\t map$$1.set(srcCategories[idx], idx);\n\t }\n\t }\n\t },\n\n\t totalCount: function() {\n\t return Math.max(this.options.srcCategories.length, this._seriesMax || 0);\n\t }\n\t});\n\n\tsetDefaultOptions(CategoryAxis, {\n\t type: \"category\",\n\t vertical: false,\n\t majorGridLines: {\n\t visible: false,\n\t width: 1,\n\t color: BLACK\n\t },\n\t labels: {\n\t zIndex: 1\n\t },\n\t justified: false,\n\t _deferLabels: true\n\t});\n\n\tvar COORDINATE_LIMIT = 300000;\n\n\tvar DateLabelFormats = {\n\t milliseconds: \"HH:mm:ss.fff\",\n\t seconds: \"HH:mm:ss\",\n\t minutes: \"HH:mm\",\n\t hours: \"HH:mm\",\n\t days: \"M/d\",\n\t weeks: \"M/d\",\n\t months: \"MMM 'yy\",\n\t years: \"yyyy\"\n\t};\n\n\tvar ZERO_THRESHOLD = 0.2;\n\n\tvar AUTO = \"auto\";\n\tvar BASE_UNITS = [\n\t MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS, WEEKS, MONTHS, YEARS\n\t];\n\tvar FIT = \"fit\";\n\n\tfunction categoryRange(categories) {\n\t var range = categories._range;\n\t if (!range) {\n\t range = categories._range = sparseArrayLimits(categories);\n\t range.min = toDate(range.min);\n\t range.max = toDate(range.max);\n\t }\n\n\t return range;\n\t}\n\n\tvar EmptyDateRange = Class.extend({\n\t init: function(options) {\n\t this.options = options;\n\t },\n\n\t displayIndices: function() {\n\t return {\n\t min: 0,\n\t max: 1\n\t };\n\t },\n\n\t displayRange: function() {\n\t return {};\n\t },\n\n\t total: function() {\n\t return {};\n\t },\n\n\t valueRange: function() {\n\t return {};\n\t },\n\n\t valueIndex: function() {\n\t return -1;\n\t },\n\n\t values: function() {\n\t return [];\n\t },\n\n\t totalIndex: function() {\n\t return -1;\n\t },\n\n\t valuesCount: function() {\n\t return 0;\n\t },\n\n\t totalCount: function() {\n\t return 0;\n\t },\n\n\t dateAt: function() {\n\t return null;\n\t }\n\t});\n\n\tvar DateRange = Class.extend({\n\t init: function(start, end, options) {\n\t this.options = options;\n\t options.baseUnitStep = options.baseUnitStep || 1;\n\n\t var roundToBaseUnit = options.roundToBaseUnit;\n\t var justified = options.justified;\n\n\t this.start = addDuration(start, 0, options.baseUnit, options.weekStartDay);\n\t var lowerEnd = this.roundToTotalStep(end);\n\t var expandEnd = !justified && dateEquals(end, lowerEnd) && !options.justifyEnd;\n\n\t this.end = this.roundToTotalStep(end, !justified, expandEnd ? 1 : 0);\n\n\t var min = options.min || start;\n\t this.valueStart = this.roundToTotalStep(min);\n\t this.displayStart = roundToBaseUnit ? this.valueStart : min;\n\n\t var max = options.max;\n\t if (!max) {\n\t this.valueEnd = lowerEnd;\n\t this.displayEnd = roundToBaseUnit || expandEnd ? this.end : end;\n\t } else {\n\t this.valueEnd = this.roundToTotalStep(max, false, !justified && dateEquals(max, this.roundToTotalStep(max)) ? -1 : 0);\n\t this.displayEnd = roundToBaseUnit ? this.roundToTotalStep(max, !justified) : options.max;\n\t }\n\n\t if (this.valueEnd < this.valueStart) {\n\t this.valueEnd = this.valueStart;\n\t }\n\t if (this.displayEnd <= this.displayStart) {\n\t this.displayEnd = this.roundToTotalStep(this.displayStart, false, 1);\n\t }\n\t },\n\n\t displayRange: function() {\n\t return {\n\t min: this.displayStart,\n\t max: this.displayEnd\n\t };\n\t },\n\n\t displayIndices: function() {\n\t if (!this._indices) {\n\t var options = this.options;\n\n\t var baseUnit = options.baseUnit;\n\t var baseUnitStep = options.baseUnitStep;\n\n\t var minIdx = dateIndex(this.displayStart, this.valueStart, baseUnit, baseUnitStep);\n\t var maxIdx = dateIndex(this.displayEnd, this.valueStart, baseUnit, baseUnitStep);\n\n\t this._indices = { min: minIdx, max: maxIdx };\n\t }\n\n\t return this._indices;\n\t },\n\n\t total: function() {\n\t return {\n\t min: this.start,\n\t max: this.end\n\t };\n\t },\n\n\t totalCount: function() {\n\t var last$$1 = this.totalIndex(this.end);\n\n\t return last$$1 + (this.options.justified ? 1 : 0);\n\t },\n\n\t valueRange: function() {\n\t return {\n\t min: this.valueStart,\n\t max: this.valueEnd\n\t };\n\t },\n\n\t valueIndex: function(value) {\n\t var options = this.options;\n\t return Math.floor(dateIndex(value, this.valueStart, options.baseUnit, options.baseUnitStep));\n\t },\n\n\t totalIndex: function(value) {\n\t var options = this.options;\n\t return Math.floor(dateIndex(value, this.start, options.baseUnit, options.baseUnitStep));\n\t },\n\n\t dateIndex: function(value) {\n\t var options = this.options;\n\t return dateIndex(value, this.valueStart, options.baseUnit, options.baseUnitStep);\n\t },\n\n\t valuesCount: function() {\n\t var maxIdx = this.valueIndex(this.valueEnd);\n\n\t return maxIdx + 1;\n\t },\n\n\t values: function() {\n\t var values = this._values;\n\t if (!values) {\n\t var options = this.options;\n\t var range = this.valueRange();\n\t this._values = values = [];\n\n\t for (var date = range.min; date <= range.max;) {\n\t values.push(date);\n\t date = addDuration(date, options.baseUnitStep, options.baseUnit, options.weekStartDay);\n\t }\n\t }\n\n\t return values;\n\t },\n\n\t dateAt: function(index, total) {\n\t var options = this.options;\n\n\t return addDuration(total ? this.start : this.valueStart, options.baseUnitStep * index, options.baseUnit, options.weekStartDay);\n\t },\n\n\t roundToTotalStep: function(value, upper, next) {\n\t var ref = this.options;\n\t var baseUnit = ref.baseUnit;\n\t var baseUnitStep = ref.baseUnitStep;\n\t var weekStartDay = ref.weekStartDay;\n\t var start = this.start;\n\n\t var step = dateIndex(value, start, baseUnit, baseUnitStep);\n\t var roundedStep = upper ? Math.ceil(step) : Math.floor(step);\n\n\t if (next) {\n\t roundedStep += next;\n\t }\n\n\t return addDuration(start, roundedStep * baseUnitStep, baseUnit, weekStartDay);\n\t }\n\t});\n\n\tfunction autoBaseUnit(options, startUnit, startStep) {\n\t var categoryLimits = categoryRange(options.categories);\n\t var span = (options.max || categoryLimits.max) - (options.min || categoryLimits.min);\n\t var autoBaseUnitSteps = options.autoBaseUnitSteps;\n\t var maxDateGroups = options.maxDateGroups;\n\t var autoUnit = options.baseUnit === FIT;\n\t var autoUnitIx = startUnit ? BASE_UNITS.indexOf(startUnit) : 0;\n\t var baseUnit = autoUnit ? BASE_UNITS[autoUnitIx++] : options.baseUnit;\n\t var units = span / TIME_PER_UNIT[baseUnit];\n\t var totalUnits = units;\n\t var unitSteps, step, nextStep;\n\n\t while (!step || units >= maxDateGroups) {\n\t unitSteps = unitSteps || autoBaseUnitSteps[baseUnit].slice(0);\n\n\t do {\n\t nextStep = unitSteps.shift();\n\t } while (nextStep && startUnit === baseUnit && nextStep < startStep);\n\n\t if (nextStep) {\n\t step = nextStep;\n\t units = totalUnits / step;\n\t } else if (baseUnit === last(BASE_UNITS)) {\n\t step = Math.ceil(totalUnits / maxDateGroups);\n\t break;\n\t } else if (autoUnit) {\n\t baseUnit = BASE_UNITS[autoUnitIx++] || last(BASE_UNITS);\n\t totalUnits = span / TIME_PER_UNIT[baseUnit];\n\t unitSteps = null;\n\t } else {\n\t if (units > maxDateGroups) {\n\t step = Math.ceil(totalUnits / maxDateGroups);\n\t }\n\t break;\n\t }\n\t }\n\n\t options.baseUnitStep = step;\n\t options.baseUnit = baseUnit;\n\t}\n\n\tfunction defaultBaseUnit(options) {\n\t var categories = options.categories;\n\t var count = defined(categories) ? categories.length : 0;\n\t var minDiff = MAX_VALUE;\n\t var lastCategory, unit;\n\n\t for (var categoryIx = 0; categoryIx < count; categoryIx++) {\n\t var category = categories[categoryIx];\n\n\t if (category && lastCategory) {\n\t var diff = absoluteDateDiff(category, lastCategory);\n\t if (diff > 0) {\n\t minDiff = Math.min(minDiff, diff);\n\n\t if (minDiff >= TIME_PER_YEAR) {\n\t unit = YEARS;\n\t } else if (minDiff >= TIME_PER_MONTH - TIME_PER_DAY * 3) {\n\t unit = MONTHS;\n\t } else if (minDiff >= TIME_PER_WEEK) {\n\t unit = WEEKS;\n\t } else if (minDiff >= TIME_PER_DAY) {\n\t unit = DAYS;\n\t } else if (minDiff >= TIME_PER_HOUR) {\n\t unit = HOURS;\n\t } else if (minDiff >= TIME_PER_MINUTE) {\n\t unit = MINUTES;\n\t } else {\n\t unit = SECONDS;\n\t }\n\t }\n\t }\n\n\t lastCategory = category;\n\t }\n\n\t options.baseUnit = unit || DAYS;\n\t}\n\n\tfunction initUnit(options) {\n\t var baseUnit = (options.baseUnit || \"\").toLowerCase();\n\t var useDefault = baseUnit !== FIT && !inArray(baseUnit, BASE_UNITS);\n\n\t if (useDefault) {\n\t defaultBaseUnit(options);\n\t }\n\n\t if (baseUnit === FIT || options.baseUnitStep === AUTO) {\n\t autoBaseUnit(options);\n\t }\n\n\t return options;\n\t}\n\n\tvar DateCategoryAxis = CategoryAxis.extend({\n\t clone: function() {\n\t var copy = new DateCategoryAxis($.extend({}, this.options), this.chartService);\n\t copy.createLabels();\n\n\t return copy;\n\t },\n\n\t categoriesHash: function() {\n\t var start = this.dataRange.total().min;\n\t return this.options.baseUnit + this.options.baseUnitStep + start;\n\t },\n\n\t initUserOptions: function(options) {\n\t return options;\n\t },\n\n\t initFields: function() {\n\t CategoryAxis.fn.initFields.call(this);\n\n\t var chartService = this.chartService;\n\t var intlService = chartService.intl;\n\t var options = this.options;\n\n\t var categories = options.categories || [];\n\t if (!categories._parsed) {\n\t categories = parseDates(intlService, categories);\n\t categories._parsed = true;\n\t }\n\n\t options = deepExtend({\n\t roundToBaseUnit: true\n\t }, options, {\n\t categories: categories,\n\t min: parseDate(intlService, options.min),\n\t max: parseDate(intlService, options.max)\n\t });\n\n\t if (chartService.panning && chartService.isPannable(options.vertical ? Y : X)) {\n\t options.roundToBaseUnit = false;\n\t }\n\n\t options.userSetBaseUnit = options.userSetBaseUnit || options.baseUnit;\n\t options.userSetBaseUnitStep = options.userSetBaseUnitStep || options.baseUnitStep;\n\n\t this.options = options;\n\t options.srcCategories = categories;\n\n\t if (categories.length > 0) {\n\t var range = categoryRange(categories);\n\t var maxDivisions = options.maxDivisions;\n\n\t this.dataRange = new DateRange(range.min, range.max, initUnit(options));\n\n\t if (maxDivisions) {\n\t var dataRange = this.dataRange.displayRange();\n\n\t var divisionOptions = $.extend({}, options, {\n\t justified: true,\n\t roundToBaseUnit: false,\n\t baseUnit: 'fit',\n\t min: dataRange.min,\n\t max: dataRange.max,\n\t maxDateGroups: maxDivisions\n\t });\n\n\t var dataRangeOptions = this.dataRange.options;\n\n\t autoBaseUnit(divisionOptions, dataRangeOptions.baseUnit, dataRangeOptions.baseUnitStep);\n\n\t this.divisionRange = new DateRange(range.min, range.max, divisionOptions);\n\t } else {\n\t this.divisionRange = this.dataRange;\n\t }\n\n\t } else {\n\t options.baseUnit = options.baseUnit || DAYS;\n\t this.dataRange = this.divisionRange = new EmptyDateRange(options);\n\t }\n\t },\n\n\t tickIndices: function(stepSize) {\n\t var ref = this;\n\t var dataRange = ref.dataRange;\n\t var divisionRange = ref.divisionRange;\n\t var valuesCount = divisionRange.valuesCount();\n\n\t if (!this.options.maxDivisions || !valuesCount) {\n\t return CategoryAxis.fn.tickIndices.call(this, stepSize);\n\t }\n\n\t var indices = [];\n\t var values = divisionRange.values();\n\t var offset = 0;\n\n\t if (!this.options.justified) {\n\t values = values.concat(divisionRange.dateAt(valuesCount));\n\t offset = 0.5;//align ticks to the center of not justified categories\n\t }\n\n\t for (var idx = 0; idx < values.length; idx++) {\n\t indices.push(dataRange.dateIndex(values[idx]) + offset);\n\t if (stepSize !== 1 && idx >= 1) {\n\t var last$$1 = indices.length - 1;\n\t indices.splice(idx, 0, indices[last$$1 - 1] + (indices[last$$1] - indices[last$$1 - 1]) * stepSize);\n\t }\n\t }\n\n\t return indices;\n\t },\n\n\t shouldRenderNote: function(value) {\n\t var range = this.range();\n\t var categories = this.options.categories || [];\n\n\t return dateComparer(value, range.min) >= 0 && dateComparer(value, range.max) <= 0 && categories.length;\n\t },\n\n\t parseNoteValue: function(value) {\n\t return parseDate(this.chartService.intl, value);\n\t },\n\n\t noteSlot: function(value) {\n\t return this.getSlot(value);\n\t },\n\n\t translateRange: function(delta) {\n\t var options = this.options;\n\t var baseUnit = options.baseUnit;\n\t var weekStartDay = options.weekStartDay;\n\t var vertical = options.vertical;\n\t var lineBox = this.lineBox();\n\t var size = vertical ? lineBox.height() : lineBox.width();\n\t var range = this.range();\n\t var scale = size / (range.max - range.min);\n\t var offset = round(delta / scale, DEFAULT_PRECISION);\n\n\t if (range.min && range.max) {\n\t var from = addTicks(options.min || range.min, offset);\n\t var to = addTicks(options.max || range.max, offset);\n\n\t range = {\n\t min: addDuration(from, 0, baseUnit, weekStartDay),\n\t max: addDuration(to, 0, baseUnit, weekStartDay)\n\t };\n\t }\n\n\t return range;\n\t },\n\n\t scaleRange: function(delta) {\n\t var rounds = Math.abs(delta);\n\t var result = this.range();\n\t var from = result.min;\n\t var to = result.max;\n\n\t if (from && to) {\n\t while (rounds--) {\n\t var range = dateDiff(from, to);\n\t var step = Math.round(range * 0.1);\n\t if (delta < 0) {\n\t from = addTicks(from, step);\n\t to = addTicks(to, -step);\n\t } else {\n\t from = addTicks(from, -step);\n\t to = addTicks(to, step);\n\t }\n\t }\n\n\t result = { min: from, max: to };\n\t }\n\n\t return result;\n\t },\n\n\t labelsRange: function() {\n\t return {\n\t min: this.options.labels.skip,\n\t max: this.divisionRange.valuesCount()\n\t };\n\t },\n\n\t pan: function(delta) {\n\t if (this.isEmpty()) {\n\t return null;\n\t }\n\n\t var options = this.options;\n\t var lineBox = this.lineBox();\n\t var size = options.vertical ? lineBox.height() : lineBox.width();\n\t var ref = this.dataRange.displayRange();\n\t var min = ref.min;\n\t var max = ref.max;\n\t var totalLimits = this.dataRange.total();\n\t var scale = size / (max - min);\n\t var offset = round(delta / scale, DEFAULT_PRECISION) * (options.reverse ? -1 : 1);\n\t var from = addTicks(min, offset);\n\t var to = addTicks(max, offset);\n\n\t var panRange = this.limitRange(toTime(from), toTime(to), toTime(totalLimits.min), toTime(totalLimits.max), offset);\n\n\t if (panRange) {\n\t panRange.min = toDate(panRange.min);\n\t panRange.max = toDate(panRange.max);\n\t panRange.baseUnit = options.baseUnit;\n\t panRange.baseUnitStep = options.baseUnitStep || 1;\n\t panRange.userSetBaseUnit = options.userSetBaseUnit;\n\t panRange.userSetBaseUnitStep = options.userSetBaseUnitStep;\n\n\t return panRange;\n\t }\n\t },\n\n\t pointsRange: function(start, end) {\n\t if (this.isEmpty()) {\n\t return null;\n\t }\n\n\t var pointsRange = CategoryAxis.fn.pointsRange.call(this, start, end);\n\t var datesRange = this.dataRange.displayRange();\n\t var indicesRange = this.dataRange.displayIndices();\n\t var scale = dateDiff(datesRange.max, datesRange.min) / (indicesRange.max - indicesRange.min);\n\t var options = this.options;\n\n\t var min = addTicks(datesRange.min, pointsRange.min * scale);\n\t var max = addTicks(datesRange.min, pointsRange.max * scale);\n\n\t return {\n\t min: min,\n\t max: max,\n\t baseUnit: options.userSetBaseUnit || options.baseUnit,\n\t baseUnitStep: options.userSetBaseUnitStep || options.baseUnitStep\n\t };\n\t },\n\n\t zoomRange: function(delta) {\n\t if (this.isEmpty()) {\n\t return null;\n\t }\n\n\t var options = this.options;\n\t var fit = options.userSetBaseUnit === FIT;\n\t var totalLimits = this.dataRange.total();\n\t var ref = this.dataRange.displayRange();\n\t var rangeMin = ref.min;\n\t var rangeMax = ref.max;\n\t var ref$1 = this.dataRange.options;\n\t var weekStartDay = ref$1.weekStartDay;\n\t var baseUnit = ref$1.baseUnit;\n\t var baseUnitStep = ref$1.baseUnitStep;\n\t var min = addDuration(rangeMin, delta * baseUnitStep, baseUnit, weekStartDay);\n\t var max = addDuration(rangeMax, -delta * baseUnitStep, baseUnit, weekStartDay);\n\n\t if (fit) {\n\t var autoBaseUnitSteps = options.autoBaseUnitSteps;\n\t var maxDateGroups = options.maxDateGroups;\n\n\t var maxDiff = last(autoBaseUnitSteps[baseUnit]) * maxDateGroups * TIME_PER_UNIT[baseUnit];\n\t var rangeDiff = dateDiff(rangeMax, rangeMin);\n\t var diff = dateDiff(max, min);\n\t var baseUnitIndex = BASE_UNITS.indexOf(baseUnit);\n\t var autoBaseUnitStep, ticks;\n\n\t if (diff < TIME_PER_UNIT[baseUnit] && baseUnit !== MILLISECONDS) {\n\t baseUnit = BASE_UNITS[baseUnitIndex - 1];\n\t autoBaseUnitStep = last(autoBaseUnitSteps[baseUnit]);\n\t ticks = (rangeDiff - (maxDateGroups - 1) * autoBaseUnitStep * TIME_PER_UNIT[baseUnit]) / 2;\n\t min = addTicks(rangeMin, ticks);\n\t max = addTicks(rangeMax, -ticks);\n\n\t } else if (diff > maxDiff && baseUnit !== YEARS) {\n\t var stepIndex = 0;\n\n\t do {\n\t baseUnitIndex++;\n\t baseUnit = BASE_UNITS[baseUnitIndex];\n\t stepIndex = 0;\n\t ticks = 2 * TIME_PER_UNIT[baseUnit];\n\t do {\n\t autoBaseUnitStep = autoBaseUnitSteps[baseUnit][stepIndex];\n\t stepIndex++;\n\t } while (stepIndex < autoBaseUnitSteps[baseUnit].length && ticks * autoBaseUnitStep < rangeDiff);\n\t } while (baseUnit !== YEARS && ticks * autoBaseUnitStep < rangeDiff);\n\n\t ticks = (ticks * autoBaseUnitStep - rangeDiff) / 2;\n\t if (ticks > 0) {\n\t min = addTicks(rangeMin, -ticks);\n\t max = addTicks(rangeMax, ticks);\n\t min = addTicks(min, limitValue(max, totalLimits.min, totalLimits.max) - max);\n\t max = addTicks(max, limitValue(min, totalLimits.min, totalLimits.max) - min);\n\t }\n\t }\n\t }\n\n\t if (min < totalLimits.min) {\n\t min = totalLimits.min;\n\t }\n\t if (max > totalLimits.max) {\n\t max = totalLimits.max;\n\t }\n\n\t if (min && max && dateDiff(max, min) > 0) {\n\t return {\n\t min: min,\n\t max: max,\n\t baseUnit: options.userSetBaseUnit || options.baseUnit,\n\t baseUnitStep: options.userSetBaseUnitStep || options.baseUnitStep\n\t };\n\t }\n\t },\n\n\t range: function() {\n\t return this.dataRange.displayRange();\n\t },\n\n\t createAxisLabel: function(index, labelOptions) {\n\t var options = this.options;\n\t var dataItem = options.dataItems && !options.maxDivisions ? options.dataItems[index] : null;\n\t var date = this.divisionRange.dateAt(index);\n\t var unitFormat = labelOptions.dateFormats[this.divisionRange.options.baseUnit];\n\n\t labelOptions.format = labelOptions.format || unitFormat;\n\t var text = this.axisLabelText(date, dataItem, labelOptions);\n\t if (text) {\n\t return new AxisLabel(date, text, index, dataItem, labelOptions);\n\t }\n\t },\n\n\t categoryIndex: function(value) {\n\t return this.dataRange.valueIndex(value);\n\t },\n\n\t slot: function(from, to, limit) {\n\t var dateRange = this.dataRange;\n\t var start = from;\n\t var end = to;\n\n\t if (start instanceof Date) {\n\t start = dateRange.dateIndex(start);\n\t }\n\n\t if (end instanceof Date) {\n\t end = dateRange.dateIndex(end);\n\t }\n\n\t var slot = this.getSlot(start, end, limit);\n\t if (slot) {\n\t return slot.toRect();\n\t }\n\t },\n\n\t getSlot: function(a, b, limit) {\n\t var start = a;\n\t var end = b;\n\n\t if (typeof start === OBJECT) {\n\t start = this.categoryIndex(start);\n\t }\n\n\t if (typeof end === OBJECT) {\n\t end = this.categoryIndex(end);\n\t }\n\n\t return CategoryAxis.fn.getSlot.call(this, start, end, limit);\n\t },\n\n\t valueRange: function() {\n\t var options = this.options;\n\t var range = categoryRange(options.srcCategories);\n\n\t return {\n\t min: toDate(range.min),\n\t max: toDate(range.max)\n\t };\n\t },\n\n\t categoryAt: function(index, total) {\n\t return this.dataRange.dateAt(index, total);\n\t },\n\n\t categoriesCount: function() {\n\t return this.dataRange.valuesCount();\n\t },\n\n\t rangeIndices: function() {\n\t return this.dataRange.displayIndices();\n\t },\n\n\t labelsBetweenTicks: function() {\n\t return !this.divisionRange.options.justified;\n\t },\n\n\t prepareUserOptions: function() {\n\t if (this.isEmpty()) {\n\t return;\n\t }\n\n\t this.options.categories = this.dataRange.values();\n\t },\n\n\t getCategory: function(point) {\n\t var index = this.pointCategoryIndex(point);\n\n\t if (index === null) {\n\t return null;\n\t }\n\n\t return this.dataRange.dateAt(index);\n\t },\n\n\t totalIndex: function(value) {\n\t return this.dataRange.totalIndex(value);\n\t },\n\n\t currentRangeIndices: function() {\n\t var range = this.dataRange.valueRange();\n\t return {\n\t min: this.dataRange.totalIndex(range.min),\n\t max: this.dataRange.totalIndex(range.max)\n\t };\n\t },\n\n\t totalRange: function() {\n\t return this.dataRange.total();\n\t },\n\n\t totalCount: function() {\n\t return this.dataRange.totalCount();\n\t },\n\n\t isEmpty: function() {\n\t return !this.options.srcCategories.length;\n\t },\n\n\t roundedRange: function() {\n\t if (this.options.roundToBaseUnit !== false || this.isEmpty()) {\n\t return this.range();\n\t }\n\n\t var options = this.options;\n\t var datesRange = categoryRange(options.srcCategories);\n\n\t var dateRange = new DateRange(datesRange.min, datesRange.max, $.extend({}, options, {\n\t justified: false,\n\t roundToBaseUnit: true,\n\t justifyEnd: options.justified\n\t }));\n\n\t return dateRange.displayRange();\n\t }\n\t});\n\n\tsetDefaultOptions(DateCategoryAxis, {\n\t type: DATE,\n\t labels: {\n\t dateFormats: DateLabelFormats\n\t },\n\t autoBaseUnitSteps: {\n\t milliseconds: [ 1, 10, 100 ],\n\t seconds: [ 1, 2, 5, 15, 30 ],\n\t minutes: [ 1, 2, 5, 15, 30 ],\n\t hours: [ 1, 2, 3 ],\n\t days: [ 1, 2, 3 ],\n\t weeks: [ 1, 2 ],\n\t months: [ 1, 2, 3, 6 ],\n\t years: [ 1, 2, 3, 5, 10, 25, 50 ]\n\t },\n\t maxDateGroups: 10\n\t});\n\n\tfunction autoAxisMin(min, max, narrow) {\n\t if (!min && !max) {\n\t return 0;\n\t }\n\n\t var axisMin;\n\n\t if (min >= 0 && max >= 0) {\n\t var minValue = min === max ? 0 : min;\n\n\t var diff = (max - minValue) / max;\n\t if (narrow === false || (!narrow && diff > ZERO_THRESHOLD)) {\n\t return 0;\n\t }\n\n\t axisMin = Math.max(0, minValue - ((max - minValue) / 2));\n\t } else {\n\t axisMin = min;\n\t }\n\n\t return axisMin;\n\t}\n\n\tfunction autoAxisMax(min, max, narrow) {\n\t if (!min && !max) {\n\t return 1;\n\t }\n\n\t var axisMax;\n\n\t if (min <= 0 && max <= 0) {\n\t var maxValue = min === max ? 0 : max;\n\n\t var diff = Math.abs((maxValue - min) / maxValue);\n\t if (narrow === false || (!narrow && diff > ZERO_THRESHOLD)) {\n\t return 0;\n\t }\n\n\t axisMax = Math.min(0, maxValue - ((min - maxValue) / 2));\n\t } else {\n\t axisMax = max;\n\t }\n\n\t return axisMax;\n\t}\n\n\tfunction floor(value, step) {\n\t return round(Math.floor(value / step) * step, DEFAULT_PRECISION);\n\t}\n\n\tfunction ceil(value, step) {\n\t return round(Math.ceil(value / step) * step, DEFAULT_PRECISION);\n\t}\n\n\tfunction limitCoordinate(value) {\n\t return Math.max(Math.min(value, COORDINATE_LIMIT), -COORDINATE_LIMIT);\n\t}\n\n\tvar MIN_VALUE_RANGE = Math.pow(10, -DEFAULT_PRECISION + 1);\n\n\tvar NumericAxis = Axis.extend({\n\t init: function(seriesMin, seriesMax, options, chartService) {\n\t Axis.fn.init.call(this, $.extend({}, options, {\n\t seriesMin: seriesMin,\n\t seriesMax: seriesMax\n\t }), chartService);\n\t },\n\n\t initUserOptions: function(options) {\n\t var autoOptions = autoAxisOptions(options.seriesMin, options.seriesMax, options);\n\t this.totalOptions = totalAxisOptions(autoOptions, options);\n\n\t return axisOptions(autoOptions, options);\n\t },\n\n\t initFields: function() {\n\t this.totalMin = this.totalOptions.min;\n\t this.totalMax = this.totalOptions.max;\n\t this.totalMajorUnit = this.totalOptions.majorUnit;\n\t this.seriesMin = this.options.seriesMin;\n\t this.seriesMax = this.options.seriesMax;\n\t },\n\n\t clone: function() {\n\t return new NumericAxis(\n\t this.seriesMin,\n\t this.seriesMax,\n\t $.extend({}, this.options),\n\t this.chartService\n\t );\n\t },\n\n\t startValue: function() {\n\t return 0;\n\t },\n\n\t range: function() {\n\t var options = this.options;\n\t return { min: options.min, max: options.max };\n\t },\n\n\t getDivisions: function(stepValue) {\n\t if (stepValue === 0) {\n\t return 1;\n\t }\n\n\t var options = this.options;\n\t var range = options.max - options.min;\n\n\t return Math.floor(round(range / stepValue, COORD_PRECISION)) + 1;\n\t },\n\n\t getTickPositions: function(unit, skipUnit) {\n\t var options = this.options;\n\t var vertical = options.vertical;\n\t var reverse = options.reverse;\n\t var lineBox = this.lineBox();\n\t var lineSize = vertical ? lineBox.height() : lineBox.width();\n\t var range = options.max - options.min;\n\t var scale = lineSize / range;\n\t var step = unit * scale;\n\t var divisions = this.getDivisions(unit);\n\t var dir = (vertical ? -1 : 1) * (reverse ? -1 : 1);\n\t var startEdge = dir === 1 ? 1 : 2;\n\t var positions = [];\n\t var pos = lineBox[(vertical ? Y : X) + startEdge];\n\t var skipStep = 0;\n\n\t if (skipUnit) {\n\t skipStep = skipUnit / unit;\n\t }\n\n\t for (var idx = 0; idx < divisions; idx++) {\n\t if (idx % skipStep !== 0) {\n\t positions.push(round(pos, COORD_PRECISION));\n\t }\n\n\t pos = pos + step * dir;\n\t }\n\n\t return positions;\n\t },\n\n\t getMajorTickPositions: function() {\n\t return this.getTickPositions(this.options.majorUnit);\n\t },\n\n\t getMinorTickPositions: function() {\n\t return this.getTickPositions(this.options.minorUnit);\n\t },\n\n\t getSlot: function(a, b, limit) {\n\t if (limit === void 0) { limit = false; }\n\n\t var options = this.options;\n\t var vertical = options.vertical;\n\t var reverse = options.reverse;\n\t var valueAxis = vertical ? Y : X;\n\t var lineBox = this.lineBox();\n\t var lineStart = lineBox[valueAxis + (reverse ? 2 : 1)];\n\t var lineSize = vertical ? lineBox.height() : lineBox.width();\n\t var dir = reverse ? -1 : 1;\n\t var step = dir * (lineSize / (options.max - options.min));\n\t var slotBox = new Box(lineBox.x1, lineBox.y1, lineBox.x1, lineBox.y1);\n\n\t var start = a;\n\t var end = b;\n\n\t if (!defined(start)) {\n\t start = end || 0;\n\t }\n\n\t if (!defined(end)) {\n\t end = start || 0;\n\t }\n\n\t if (limit) {\n\t start = Math.max(Math.min(start, options.max), options.min);\n\t end = Math.max(Math.min(end, options.max), options.min);\n\t }\n\n\t var p1, p2;\n\n\t if (vertical) {\n\t p1 = options.max - Math.max(start, end);\n\t p2 = options.max - Math.min(start, end);\n\t } else {\n\t p1 = Math.min(start, end) - options.min;\n\t p2 = Math.max(start, end) - options.min;\n\t }\n\n\t slotBox[valueAxis + 1] = limitCoordinate(lineStart + step * (reverse ? p2 : p1));\n\t slotBox[valueAxis + 2] = limitCoordinate(lineStart + step * (reverse ? p1 : p2));\n\n\t return slotBox;\n\t },\n\n\t getValue: function(point) {\n\t var options = this.options;\n\t var vertical = options.vertical;\n\t var reverse = options.reverse;\n\t var max = Number(options.max);\n\t var min = Number(options.min);\n\t var valueAxis = vertical ? Y : X;\n\t var lineBox = this.lineBox();\n\t var lineStart = lineBox[valueAxis + (reverse ? 2 : 1)];\n\t var lineSize = vertical ? lineBox.height() : lineBox.width();\n\t var dir = reverse ? -1 : 1;\n\t var offset = dir * (point[valueAxis] - lineStart);\n\t var step = (max - min) / lineSize;\n\t var valueOffset = offset * step;\n\n\t if (offset < 0 || offset > lineSize) {\n\t return null;\n\t }\n\n\t var value = vertical ?\n\t max - valueOffset :\n\t min + valueOffset;\n\n\t return round(value, DEFAULT_PRECISION);\n\t },\n\n\t translateRange: function(delta) {\n\t var options = this.options;\n\t var vertical = options.vertical;\n\t var reverse = options.reverse;\n\t var max = options.max;\n\t var min = options.min;\n\t var lineBox = this.lineBox();\n\t var size = vertical ? lineBox.height() : lineBox.width();\n\t var range = max - min;\n\t var scale = size / range;\n\t var offset = round(delta / scale, DEFAULT_PRECISION);\n\n\t if ((vertical || reverse) && !(vertical && reverse )) {\n\t offset = -offset;\n\t }\n\n\t return {\n\t min: min + offset,\n\t max: max + offset,\n\t offset: offset\n\t };\n\t },\n\n\t scaleRange: function(delta) {\n\t var options = this.options;\n\t var offset = -delta * options.majorUnit;\n\n\t return {\n\t min: options.min - offset,\n\t max: options.max + offset\n\t };\n\t },\n\n\t labelsCount: function() {\n\t return this.getDivisions(this.options.majorUnit);\n\t },\n\n\t createAxisLabel: function(index, labelOptions) {\n\t var options = this.options;\n\t var value = round(options.min + (index * options.majorUnit), DEFAULT_PRECISION);\n\t var text = this.axisLabelText(value, null, labelOptions);\n\n\t return new AxisLabel(value, text, index, null, labelOptions);\n\t },\n\n\t shouldRenderNote: function(value) {\n\t var range = this.range();\n\t return range.min <= value && value <= range.max;\n\t },\n\n\t pan: function(delta) {\n\t var range = this.translateRange(delta);\n\t return this.limitRange(range.min, range.max, this.totalMin, this.totalMax, range.offset);\n\t },\n\n\t pointsRange: function(start, end) {\n\t var startValue = this.getValue(start);\n\t var endValue = this.getValue(end);\n\t var min = Math.min(startValue, endValue);\n\t var max = Math.max(startValue, endValue);\n\n\t if (this.isValidRange(min, max)) {\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t }\n\t },\n\n\t zoomRange: function(delta) {\n\t var ref = this;\n\t var totalMin = ref.totalMin;\n\t var totalMax = ref.totalMax;\n\t var newRange = this.scaleRange(delta);\n\t var min = limitValue(newRange.min, totalMin, totalMax);\n\t var max = limitValue(newRange.max, totalMin, totalMax);\n\n\t if (this.isValidRange(min, max)) {\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t }\n\t },\n\n\t isValidRange: function(min, max) {\n\t return max - min > MIN_VALUE_RANGE;\n\t }\n\t});\n\n\tfunction autoAxisOptions(seriesMin, seriesMax, options) {\n\t var narrowRange = options.narrowRange;\n\n\t var autoMin = autoAxisMin(seriesMin, seriesMax, narrowRange);\n\t var autoMax = autoAxisMax(seriesMin, seriesMax, narrowRange);\n\n\t var majorUnit = autoMajorUnit(autoMin, autoMax);\n\t var autoOptions = {\n\t majorUnit: majorUnit\n\t };\n\n\t if (options.roundToMajorUnit !== false) {\n\t if (autoMin < 0 && remainderClose(autoMin, majorUnit, 1 / 3)) {\n\t autoMin -= majorUnit;\n\t }\n\n\t if (autoMax > 0 && remainderClose(autoMax, majorUnit, 1 / 3)) {\n\t autoMax += majorUnit;\n\t }\n\t }\n\n\t autoOptions.min = floor(autoMin, majorUnit);\n\t autoOptions.max = ceil(autoMax, majorUnit);\n\n\t return autoOptions;\n\t}\n\n\tfunction totalAxisOptions(autoOptions, options) {\n\t return {\n\t min: defined(options.min) ? Math.min(autoOptions.min, options.min) : autoOptions.min,\n\t max: defined(options.max) ? Math.max(autoOptions.max, options.max) : autoOptions.max,\n\t majorUnit: autoOptions.majorUnit\n\t };\n\t}\n\n\tfunction clearNullValues(options, fields) {\n\t for (var idx = 0; idx < fields.length; idx++) {\n\t var field = fields[idx];\n\t if (options[field] === null) {\n\t options[field] = undefined;\n\t }\n\t }\n\t}\n\n\tfunction axisOptions(autoOptions, userOptions) {\n\t var options = userOptions;\n\t var userSetMin, userSetMax;\n\n\t if (userOptions) {\n\t clearNullValues(userOptions, [ 'min', 'max' ]);\n\n\t userSetMin = defined(userOptions.min);\n\t userSetMax = defined(userOptions.max);\n\n\t var userSetLimits = userSetMin || userSetMax;\n\n\t if (userSetLimits) {\n\t if (userOptions.min === userOptions.max) {\n\t if (userOptions.min > 0) {\n\t userOptions.min = 0;\n\t } else {\n\t userOptions.max = 1;\n\t }\n\t }\n\t }\n\n\t if (userOptions.majorUnit) {\n\t autoOptions.min = floor(autoOptions.min, userOptions.majorUnit);\n\t autoOptions.max = ceil(autoOptions.max, userOptions.majorUnit);\n\t } else if (userSetLimits) {\n\t options = deepExtend(autoOptions, userOptions);\n\n\t // Determine an auto major unit after min/max have been set\n\t autoOptions.majorUnit = autoMajorUnit(options.min, options.max);\n\t }\n\t }\n\n\t autoOptions.minorUnit = (options.majorUnit || autoOptions.majorUnit) / 5;\n\n\t var result = deepExtend(autoOptions, options);\n\t if (result.min >= result.max) {\n\t if (userSetMin && !userSetMax) {\n\t result.max = result.min + result.majorUnit;\n\t } else if (!userSetMin && userSetMax) {\n\t result.min = result.max - result.majorUnit;\n\t }\n\t }\n\n\t return result;\n\t}\n\n\tfunction remainderClose(value, divisor, ratio) {\n\t var remainder = round(Math.abs(value % divisor), DEFAULT_PRECISION);\n\t var threshold = divisor * (1 - ratio);\n\n\t return remainder === 0 || remainder > threshold;\n\t}\n\n\tsetDefaultOptions(NumericAxis, {\n\t type: \"numeric\",\n\t min: 0,\n\t max: 1,\n\t vertical: true,\n\t majorGridLines: {\n\t visible: true,\n\t width: 1,\n\t color: BLACK\n\t },\n\t labels: {\n\t format: \"#.####################\"\n\t },\n\t zIndex: 1\n\t});\n\n\tvar DateValueAxis = Axis.extend({\n\t init: function(seriesMin, seriesMax, axisOptions, chartService) {\n\t var min = toDate(seriesMin);\n\t var max = toDate(seriesMax);\n\n\t var intlService = chartService.intl;\n\t var options = axisOptions || {};\n\t options = deepExtend(options || {}, {\n\t min: parseDate(intlService, options.min),\n\t max: parseDate(intlService, options.max),\n\t axisCrossingValue: parseDates(intlService, options.axisCrossingValues || options.axisCrossingValue)\n\t });\n\t options = applyDefaults(min, max, options);\n\n\t Axis.fn.init.call(this, options, chartService);\n\n\t this.intlService = intlService;\n\t this.seriesMin = min;\n\t this.seriesMax = max;\n\n\t var weekStartDay = options.weekStartDay || 0;\n\t this.totalMin = toTime(floorDate(toTime(min) - 1, options.baseUnit, weekStartDay));\n\t this.totalMax = toTime(ceilDate(toTime(max) + 1, options.baseUnit, weekStartDay));\n\t },\n\n\t clone: function() {\n\t return new DateValueAxis(this.seriesMin, this.seriesMax, $.extend({}, this.options), this.chartService);\n\t },\n\n\t range: function() {\n\t var options = this.options;\n\t return { min: options.min, max: options.max };\n\t },\n\n\t getDivisions: function(stepValue) {\n\t var options = this.options;\n\n\t return Math.floor(\n\t duration(options.min, options.max, options.baseUnit) / stepValue + 1\n\t );\n\t },\n\n\t getTickPositions: function(step) {\n\t var options = this.options;\n\t var vertical = options.vertical;\n\t var lineBox = this.lineBox();\n\t var dir = (vertical ? -1 : 1) * (options.reverse ? -1 : 1);\n\t var startEdge = dir === 1 ? 1 : 2;\n\t var start = lineBox[(vertical ? Y : X) + startEdge];\n\t var divisions = this.getDivisions(step);\n\t var timeRange = dateDiff(options.max, options.min);\n\t var lineSize = vertical ? lineBox.height() : lineBox.width();\n\t var scale = lineSize / timeRange;\n\t var weekStartDay = options.weekStartDay || 0;\n\n\t var positions = [ start ];\n\t for (var i = 1; i < divisions; i++) {\n\t var date = addDuration(options.min, i * step, options.baseUnit, weekStartDay);\n\t var pos = start + dateDiff(date, options.min) * scale * dir;\n\n\t positions.push(round(pos, COORD_PRECISION));\n\t }\n\n\t return positions;\n\t },\n\n\t getMajorTickPositions: function() {\n\t return this.getTickPositions(this.options.majorUnit);\n\t },\n\n\t getMinorTickPositions: function() {\n\t return this.getTickPositions(this.options.minorUnit);\n\t },\n\n\t getSlot: function(a, b, limit) {\n\t return NumericAxis.prototype.getSlot.call(\n\t this, parseDate(this.intlService, a), parseDate(this.intlService, b), limit\n\t );\n\t },\n\n\t getValue: function(point) {\n\t var value = NumericAxis.prototype.getValue.call(this, point);\n\n\t return value !== null ? toDate(value) : null;\n\t },\n\n\t labelsCount: function() {\n\t return this.getDivisions(this.options.majorUnit);\n\t },\n\n\t createAxisLabel: function(index, labelOptions) {\n\t var options = this.options;\n\t var offset = index * options.majorUnit;\n\t var weekStartDay = options.weekStartDay || 0;\n\t var date = options.min;\n\n\t if (offset > 0) {\n\t date = addDuration(date, offset, options.baseUnit, weekStartDay);\n\t }\n\n\t var unitFormat = labelOptions.dateFormats[options.baseUnit];\n\t labelOptions.format = labelOptions.format || unitFormat;\n\n\t var text = this.axisLabelText(date, null, labelOptions);\n\t return new AxisLabel(date, text, index, null, labelOptions);\n\t },\n\n\t translateRange: function(delta, exact) {\n\t var options = this.options;\n\t var baseUnit = options.baseUnit;\n\t var weekStartDay = options.weekStartDay || 0;\n\t var lineBox = this.lineBox();\n\t var size = options.vertical ? lineBox.height() : lineBox.width();\n\t var range = this.range();\n\t var scale = size / dateDiff(range.max, range.min);\n\t var offset = round(delta / scale, DEFAULT_PRECISION) * (options.reverse ? -1 : 1);\n\t var from = addTicks(options.min, offset);\n\t var to = addTicks(options.max, offset);\n\n\t if (!exact) {\n\t from = addDuration(from, 0, baseUnit, weekStartDay);\n\t to = addDuration(to, 0, baseUnit, weekStartDay);\n\t }\n\n\t return {\n\t min: from,\n\t max: to,\n\t offset: offset\n\t };\n\t },\n\n\t scaleRange: function(delta) {\n\t var ref = this.options;\n\t var from = ref.min;\n\t var to = ref.max;\n\t var rounds = Math.abs(delta);\n\n\t while (rounds--) {\n\t var range = dateDiff(from, to);\n\t var step = Math.round(range * 0.1);\n\t if (delta < 0) {\n\t from = addTicks(from, step);\n\t to = addTicks(to, -step);\n\t } else {\n\t from = addTicks(from, -step);\n\t to = addTicks(to, step);\n\t }\n\t }\n\n\t return { min: from, max: to };\n\t },\n\n\t shouldRenderNote: function(value) {\n\t var range = this.range();\n\n\t return dateComparer(value, range.min) >= 0 && dateComparer(value, range.max) <= 0;\n\t },\n\n\t pan: function(delta) {\n\t var range = this.translateRange(delta, true);\n\t var limittedRange = this.limitRange(toTime(range.min), toTime(range.max), this.totalMin, this.totalMax, range.offset);\n\n\t if (limittedRange) {\n\t return {\n\t min: toDate(limittedRange.min),\n\t max: toDate(limittedRange.max)\n\t };\n\t }\n\t },\n\n\t pointsRange: function(start, end) {\n\t var startValue = this.getValue(start);\n\t var endValue = this.getValue(end);\n\t var min = Math.min(startValue, endValue);\n\t var max = Math.max(startValue, endValue);\n\n\t return {\n\t min: toDate(min),\n\t max: toDate(max)\n\t };\n\t },\n\n\t zoomRange: function(delta) {\n\t var range = this.scaleRange(delta);\n\t var min = toDate(limitValue(toTime(range.min), this.totalMin, this.totalMax));\n\t var max = toDate(limitValue(toTime(range.max), this.totalMin, this.totalMax));\n\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t }\n\t});\n\n\tfunction timeUnits(delta) {\n\t var unit = HOURS;\n\n\t if (delta >= TIME_PER_YEAR) {\n\t unit = YEARS;\n\t } else if (delta >= TIME_PER_MONTH) {\n\t unit = MONTHS;\n\t } else if (delta >= TIME_PER_WEEK) {\n\t unit = WEEKS;\n\t } else if (delta >= TIME_PER_DAY) {\n\t unit = DAYS;\n\t }\n\n\t return unit;\n\t}\n\n\tfunction applyDefaults(seriesMin, seriesMax, options) {\n\t var min = options.min || seriesMin;\n\t var max = options.max || seriesMax;\n\t var baseUnit = options.baseUnit || (max && min ? timeUnits(absoluteDateDiff(max, min)) : HOURS);\n\t var baseUnitTime = TIME_PER_UNIT[baseUnit];\n\t var weekStartDay = options.weekStartDay || 0;\n\t var autoMin = floorDate(toTime(min) - 1, baseUnit, weekStartDay) || toDate(max);\n\t var autoMax = ceilDate(toTime(max) + 1, baseUnit, weekStartDay);\n\t var userMajorUnit = options.majorUnit ? options.majorUnit : undefined;\n\t var majorUnit = userMajorUnit || ceil(\n\t autoMajorUnit(autoMin.getTime(), autoMax.getTime()),\n\t baseUnitTime\n\t ) / baseUnitTime;\n\t var actualUnits = duration(autoMin, autoMax, baseUnit);\n\t var totalUnits = ceil(actualUnits, majorUnit);\n\t var unitsToAdd = totalUnits - actualUnits;\n\t var head = Math.floor(unitsToAdd / 2);\n\t var tail = unitsToAdd - head;\n\n\t if (!options.baseUnit) {\n\t delete options.baseUnit;\n\t }\n\n\t options.baseUnit = options.baseUnit || baseUnit;\n\t options.min = options.min || addDuration(autoMin, -head, baseUnit, weekStartDay);\n\t options.max = options.max || addDuration(autoMax, tail, baseUnit, weekStartDay);\n\t options.minorUnit = options.minorUnit || majorUnit / 5;\n\t options.majorUnit = majorUnit;\n\n\t return options;\n\t}\n\n\tsetDefaultOptions(DateValueAxis, {\n\t type: DATE,\n\t majorGridLines: {\n\t visible: true,\n\t width: 1,\n\t color: BLACK\n\t },\n\t labels: {\n\t dateFormats: DateLabelFormats\n\t }\n\t});\n\n\tvar DEFAULT_MAJOR_UNIT = 10;\n\n\tvar LogarithmicAxis = Axis.extend({\n\t init: function(seriesMin, seriesMax, options, chartService) {\n\n\t var axisOptions = deepExtend({ majorUnit: DEFAULT_MAJOR_UNIT, min: seriesMin, max: seriesMax }, options);\n\t var base = axisOptions.majorUnit;\n\t var autoMax = autoAxisMax$1(seriesMax, base);\n\t var autoMin = autoAxisMin$1(seriesMin, seriesMax, axisOptions);\n\t var range = initRange(autoMin, autoMax, axisOptions, options);\n\n\t axisOptions.max = range.max;\n\t axisOptions.min = range.min;\n\t axisOptions.minorUnit = options.minorUnit || round(base - 1, DEFAULT_PRECISION);\n\n\t Axis.fn.init.call(this, axisOptions, chartService);\n\n\t this.totalMin = defined(options.min) ? Math.min(autoMin, options.min) : autoMin;\n\t this.totalMax = defined(options.max) ? Math.max(autoMax, options.max) : autoMax;\n\t this.logMin = round(log(range.min, base), DEFAULT_PRECISION);\n\t this.logMax = round(log(range.max, base), DEFAULT_PRECISION);\n\t this.seriesMin = seriesMin;\n\t this.seriesMax = seriesMax;\n\n\t this.createLabels();\n\t },\n\n\t clone: function() {\n\t return new LogarithmicAxis(\n\t this.seriesMin,\n\t this.seriesMax,\n\t $.extend({}, this.options),\n\t this.chartService\n\t );\n\t },\n\n\t startValue: function() {\n\t return this.options.min;\n\t },\n\n\t getSlot: function(a, b, limit) {\n\t var ref = this;\n\t var options = ref.options;\n\t var logMin = ref.logMin;\n\t var logMax = ref.logMax;\n\t var reverse = options.reverse;\n\t var vertical = options.vertical;\n\t var base = options.majorUnit;\n\t var valueAxis = vertical ? Y : X;\n\t var lineBox = this.lineBox();\n\t var lineStart = lineBox[valueAxis + (reverse ? 2 : 1)];\n\t var lineSize = vertical ? lineBox.height() : lineBox.width();\n\t var dir = reverse ? -1 : 1;\n\t var step = dir * (lineSize / (logMax - logMin));\n\t var slotBox = new Box(lineBox.x1, lineBox.y1, lineBox.x1, lineBox.y1);\n\t var start = a;\n\t var end = b;\n\n\t if (!defined(start)) {\n\t start = end || 1;\n\t }\n\n\t if (!defined(end)) {\n\t end = start || 1;\n\t }\n\n\t if (start <= 0 || end <= 0) {\n\t return null;\n\t }\n\n\t if (limit) {\n\t start = Math.max(Math.min(start, options.max), options.min);\n\t end = Math.max(Math.min(end, options.max), options.min);\n\t }\n\n\t start = log(start, base);\n\t end = log(end, base);\n\n\t var p1, p2;\n\n\t if (vertical) {\n\t p1 = logMax - Math.max(start, end);\n\t p2 = logMax - Math.min(start, end);\n\t } else {\n\t p1 = Math.min(start, end) - logMin;\n\t p2 = Math.max(start, end) - logMin;\n\t }\n\n\t slotBox[valueAxis + 1] = limitCoordinate(lineStart + step * (reverse ? p2 : p1));\n\t slotBox[valueAxis + 2] = limitCoordinate(lineStart + step * (reverse ? p1 : p2));\n\n\t return slotBox;\n\t },\n\n\t getValue: function(point) {\n\t var ref = this;\n\t var options = ref.options;\n\t var logMin = ref.logMin;\n\t var logMax = ref.logMax;\n\t var reverse = options.reverse;\n\t var vertical = options.vertical;\n\t var base = options.majorUnit;\n\t var lineBox = this.lineBox();\n\t var dir = vertical === reverse ? 1 : -1;\n\t var startEdge = dir === 1 ? 1 : 2;\n\t var lineSize = vertical ? lineBox.height() : lineBox.width();\n\t var step = ((logMax - logMin) / lineSize);\n\t var valueAxis = vertical ? Y : X;\n\t var lineStart = lineBox[valueAxis + startEdge];\n\t var offset = dir * (point[valueAxis] - lineStart);\n\t var valueOffset = offset * step;\n\n\t if (offset < 0 || offset > lineSize) {\n\t return null;\n\t }\n\n\t var value = logMin + valueOffset;\n\n\t return round(Math.pow(base, value), DEFAULT_PRECISION);\n\t },\n\n\t range: function() {\n\t var options = this.options;\n\t return { min: options.min, max: options.max };\n\t },\n\n\t scaleRange: function(delta) {\n\t var base = this.options.majorUnit;\n\t var offset = -delta;\n\n\t return {\n\t min: Math.pow(base, this.logMin - offset),\n\t max: Math.pow(base, this.logMax + offset)\n\t };\n\t },\n\n\t translateRange: function(delta) {\n\t var ref = this;\n\t var options = ref.options;\n\t var logMin = ref.logMin;\n\t var logMax = ref.logMax;\n\t var reverse = options.reverse;\n\t var vertical = options.vertical;\n\t var base = options.majorUnit;\n\t var lineBox = this.lineBox();\n\t var size = vertical ? lineBox.height() : lineBox.width();\n\t var scale = size / (logMax - logMin);\n\t var offset = round(delta / scale, DEFAULT_PRECISION);\n\n\t if ((vertical || reverse) && !(vertical && reverse )) {\n\t offset = -offset;\n\t }\n\n\t return {\n\t min: Math.pow(base, logMin + offset),\n\t max: Math.pow(base, logMax + offset),\n\t offset: offset\n\t };\n\t },\n\n\t labelsCount: function() {\n\t var floorMax = Math.floor(this.logMax);\n\t var count = Math.floor(floorMax - this.logMin) + 1;\n\n\t return count;\n\t },\n\n\t getMajorTickPositions: function() {\n\t var ticks = [];\n\n\t this.traverseMajorTicksPositions(function (position) {\n\t ticks.push(position);\n\t }, { step: 1, skip: 0 });\n\n\t return ticks;\n\t },\n\n\t createTicks: function(lineGroup) {\n\t var options = this.options;\n\t var majorTicks = options.majorTicks;\n\t var minorTicks = options.minorTicks;\n\t var vertical = options.vertical;\n\t var mirror = options.labels.mirror;\n\t var lineBox = this.lineBox();\n\t var ticks = [];\n\t var tickLineOptions = {\n\t // TODO\n\t // _alignLines: options._alignLines,\n\t vertical: vertical\n\t };\n\n\t function render(tickPosition, tickOptions) {\n\t tickLineOptions.tickX = mirror ? lineBox.x2 : lineBox.x2 - tickOptions.size;\n\t tickLineOptions.tickY = mirror ? lineBox.y1 - tickOptions.size : lineBox.y1;\n\t tickLineOptions.position = tickPosition;\n\n\t lineGroup.append(createAxisTick(tickLineOptions, tickOptions));\n\t }\n\n\t if (majorTicks.visible) {\n\t this.traverseMajorTicksPositions(render, majorTicks);\n\t }\n\n\t if (minorTicks.visible) {\n\t this.traverseMinorTicksPositions(render, minorTicks);\n\t }\n\n\t return ticks;\n\t },\n\n\t createGridLines: function(altAxis) {\n\t var options = this.options;\n\t var minorGridLines = options.minorGridLines;\n\t var majorGridLines = options.majorGridLines;\n\t var vertical = options.vertical;\n\t var lineBox = altAxis.lineBox();\n\t var lineOptions = {\n\t lineStart: lineBox[vertical ? \"x1\" : \"y1\"],\n\t lineEnd: lineBox[vertical ? \"x2\" : \"y2\"],\n\t vertical: vertical\n\t };\n\t var majorTicks = [];\n\n\t var container = this.gridLinesVisual();\n\t function render(tickPosition, gridLine) {\n\t if (!inArray(tickPosition, majorTicks)) {\n\t lineOptions.position = tickPosition;\n\t container.append(createAxisGridLine(lineOptions, gridLine));\n\n\t majorTicks.push(tickPosition);\n\t }\n\t }\n\n\t if (majorGridLines.visible) {\n\t this.traverseMajorTicksPositions(render, majorGridLines);\n\t }\n\n\t if (minorGridLines.visible) {\n\t this.traverseMinorTicksPositions(render, minorGridLines);\n\t }\n\n\t return container.children;\n\t },\n\n\t traverseMajorTicksPositions: function(callback, tickOptions) {\n\t var ref = this._lineOptions();\n\t var lineStart = ref.lineStart;\n\t var step = ref.step;\n\t var ref$1 = this;\n\t var logMin = ref$1.logMin;\n\t var logMax = ref$1.logMax;\n\n\t for (var power = Math.ceil(logMin) + tickOptions.skip; power <= logMax; power += tickOptions.step) {\n\t var position = round(lineStart + step * (power - logMin), DEFAULT_PRECISION);\n\t callback(position, tickOptions);\n\t }\n\t },\n\n\t traverseMinorTicksPositions: function(callback, tickOptions) {\n\t var this$1 = this;\n\n\t var ref = this.options;\n\t var min = ref.min;\n\t var max = ref.max;\n\t var minorUnit = ref.minorUnit;\n\t var base = ref.majorUnit;\n\t var ref$1 = this._lineOptions();\n\t var lineStart = ref$1.lineStart;\n\t var step = ref$1.step;\n\t var ref$2 = this;\n\t var logMin = ref$2.logMin;\n\t var logMax = ref$2.logMax;\n\t var start = Math.floor(logMin);\n\n\t for (var power = start; power < logMax; power++) {\n\t var minorOptions = this$1._minorIntervalOptions(power);\n\t for (var idx = tickOptions.skip; idx < minorUnit; idx += tickOptions.step) {\n\t var value = minorOptions.value + idx * minorOptions.minorStep;\n\t if (value > max) {\n\t break;\n\t }\n\t if (value >= min) {\n\t var position = round(lineStart + step * (log(value, base) - logMin), DEFAULT_PRECISION);\n\t callback(position, tickOptions);\n\t }\n\t }\n\t }\n\t },\n\n\t createAxisLabel: function(index, labelOptions) {\n\t var power = Math.ceil(this.logMin + index);\n\t var value = Math.pow(this.options.majorUnit, power);\n\t var text = this.axisLabelText(value, null, labelOptions);\n\n\t return new AxisLabel(value, text, index, null, labelOptions);\n\t },\n\n\t shouldRenderNote: function(value) {\n\t var range = this.range();\n\t return range.min <= value && value <= range.max;\n\t },\n\n\t pan: function(delta) {\n\t var range = this.translateRange(delta);\n\t return this.limitRange(range.min, range.max, this.totalMin, this.totalMax, range.offset);\n\t },\n\n\t pointsRange: function(start, end) {\n\t var startValue = this.getValue(start);\n\t var endValue = this.getValue(end);\n\t var min = Math.min(startValue, endValue);\n\t var max = Math.max(startValue, endValue);\n\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t },\n\n\t zoomRange: function(delta) {\n\t var ref = this;\n\t var options = ref.options;\n\t var totalMin = ref.totalMin;\n\t var totalMax = ref.totalMax;\n\t var newRange = this.scaleRange(delta);\n\t var min = limitValue(newRange.min, totalMin, totalMax);\n\t var max = limitValue(newRange.max, totalMin, totalMax);\n\t var base = options.majorUnit;\n\t var acceptOptionsRange = max > min && options.min && options.max && (round(log(options.max, base) - log(options.min, base), DEFAULT_PRECISION) < 1);\n\t var acceptNewRange = !(options.min === totalMin && options.max === totalMax) && round(log(max, base) - log(min, base), DEFAULT_PRECISION) >= 1;\n\n\t if (acceptOptionsRange || acceptNewRange) {\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t }\n\t },\n\n\t _minorIntervalOptions: function(power) {\n\t var ref = this.options;\n\t var minorUnit = ref.minorUnit;\n\t var base = ref.majorUnit;\n\t var value = Math.pow(base, power);\n\t var nextValue = Math.pow(base, power + 1);\n\t var difference = nextValue - value;\n\t var minorStep = difference / minorUnit;\n\n\t return {\n\t value: value,\n\t minorStep: minorStep\n\t };\n\t },\n\n\t _lineOptions: function() {\n\t var ref = this.options;\n\t var reverse = ref.reverse;\n\t var vertical = ref.vertical;\n\t var valueAxis = vertical ? Y : X;\n\t var lineBox = this.lineBox();\n\t var dir = vertical === reverse ? 1 : -1;\n\t var startEdge = dir === 1 ? 1 : 2;\n\t var lineSize = vertical ? lineBox.height() : lineBox.width();\n\t var step = dir * (lineSize / (this.logMax - this.logMin));\n\t var lineStart = lineBox[valueAxis + startEdge];\n\n\t return {\n\t step: step,\n\t lineStart: lineStart,\n\t lineBox: lineBox\n\t };\n\t }\n\t});\n\n\tfunction initRange(autoMin, autoMax, axisOptions, options) {\n\t var min = axisOptions.min;\n\t var max = axisOptions.max;\n\n\t if (defined(axisOptions.axisCrossingValue) && axisOptions.axisCrossingValue <= 0) {\n\t throwNegativeValuesError();\n\t }\n\n\t if (!defined(options.max)) {\n\t max = autoMax;\n\t } else if (options.max <= 0) {\n\t throwNegativeValuesError();\n\t }\n\n\t if (!defined(options.min)) {\n\t min = autoMin;\n\t } else if (options.min <= 0) {\n\t throwNegativeValuesError();\n\t }\n\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t}\n\n\tfunction autoAxisMin$1(min, max, options) {\n\t var base = options.majorUnit;\n\t var autoMin = min;\n\t if (min <= 0) {\n\t autoMin = max <= 1 ? Math.pow(base, -2) : 1;\n\t } else if (!options.narrowRange) {\n\t autoMin = Math.pow(base, Math.floor(log(min, base)));\n\t }\n\t return autoMin;\n\t}\n\n\tfunction autoAxisMax$1(max, base) {\n\t var logMaxRemainder = round(log(max, base), DEFAULT_PRECISION) % 1;\n\t var autoMax;\n\t if (max <= 0) {\n\t autoMax = base;\n\t } else if (logMaxRemainder !== 0 && (logMaxRemainder < 0.3 || logMaxRemainder > 0.9)) {\n\t autoMax = Math.pow(base, log(max, base) + 0.2);\n\t } else {\n\t autoMax = Math.pow(base, Math.ceil(log(max, base)));\n\t }\n\n\t return autoMax;\n\t}\n\n\tfunction throwNegativeValuesError() {\n\t throw new Error(\"Non positive values cannot be used for a logarithmic axis\");\n\t}\n\n\tfunction log(y, x) {\n\t return Math.log(y) / Math.log(x);\n\t}\n\n\tsetDefaultOptions(LogarithmicAxis, {\n\t type: \"log\",\n\t majorUnit: DEFAULT_MAJOR_UNIT,\n\t minorUnit: 1,\n\t axisCrossingValue: 1,\n\t vertical: true,\n\t majorGridLines: {\n\t visible: true,\n\t width: 1,\n\t color: BLACK\n\t },\n\t zIndex: 1,\n\t _deferLabels: true\n\t});\n\n\tvar GridLinesMixin = {\n\t createGridLines: function(altAxis) {\n\t var options = this.options;\n\t var radius = Math.abs(this.box.center().y - altAxis.lineBox().y1);\n\t var gridLines = [];\n\t var skipMajor = false;\n\t var majorAngles, minorAngles;\n\n\t if (options.majorGridLines.visible) {\n\t majorAngles = this.majorGridLineAngles(altAxis);\n\t skipMajor = true;\n\n\t gridLines = this.renderMajorGridLines(\n\t majorAngles, radius, options.majorGridLines\n\t );\n\t }\n\n\t if (options.minorGridLines.visible) {\n\t minorAngles = this.minorGridLineAngles(altAxis, skipMajor);\n\n\t append(gridLines, this.renderMinorGridLines(\n\t minorAngles, radius, options.minorGridLines, altAxis, skipMajor\n\t ));\n\t }\n\n\t return gridLines;\n\t },\n\n\t renderMajorGridLines: function(angles, radius, options) {\n\t return this.renderGridLines(angles, radius, options);\n\t },\n\n\t renderMinorGridLines: function(angles, radius, options, altAxis, skipMajor) {\n\t var radiusCallback = this.radiusCallback && this.radiusCallback(radius, altAxis, skipMajor);\n\t return this.renderGridLines(angles, radius, options, radiusCallback);\n\t },\n\n\t renderGridLines: function(angles, radius, options, radiusCallback) {\n\t var style = {\n\t stroke: {\n\t width: options.width,\n\t color: options.color,\n\t dashType: options.dashType\n\t }\n\t };\n\n\t var center = this.box.center();\n\t var circle = new Circle([ center.x, center.y ], radius);\n\t var container = this.gridLinesVisual();\n\n\t for (var i = 0; i < angles.length; i++) {\n\t var line = new Path(style);\n\t if (radiusCallback) {\n\t circle.radius = radiusCallback(angles[i]);\n\t }\n\n\t line.moveTo(circle.center)\n\t .lineTo(circle.pointAt(angles[i] + 180));\n\n\t container.append(line);\n\t }\n\n\t return container.children;\n\t },\n\n\t gridLineAngles: function(altAxis, size, skip, step, skipAngles) {\n\t var this$1 = this;\n\n\t var divs = this.intervals(size, skip, step, skipAngles);\n\t var options = altAxis.options;\n\t var altAxisVisible = options.visible && (options.line || {}).visible !== false;\n\n\t return map(divs, function (d) {\n\t var alpha = this$1.intervalAngle(d);\n\n\t if (!altAxisVisible || alpha !== 90) {\n\t return alpha;\n\t }\n\t });\n\t }\n\t};\n\n\tvar RadarCategoryAxis = CategoryAxis.extend({\n\t range: function() {\n\t return { min: 0, max: this.options.categories.length };\n\t },\n\n\t reflow: function(box) {\n\t this.box = box;\n\t this.reflowLabels();\n\t },\n\n\t lineBox: function() {\n\t return this.box;\n\t },\n\n\t reflowLabels: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var labels = ref.labels;\n\t var labelOptions = ref.options.labels;\n\t var skip = labelOptions.skip || 0;\n\t var step = labelOptions.step || 1;\n\t var measureBox = new Box();\n\n\t for (var i = 0; i < labels.length; i++) {\n\t labels[i].reflow(measureBox);\n\t var labelBox = labels[i].box;\n\n\t labels[i].reflow(this$1.getSlot(skip + i * step).adjacentBox(\n\t 0, labelBox.width(), labelBox.height()\n\t ));\n\t }\n\t },\n\n\t intervals: function(size, skipOption, stepOption, skipAngles) {\n\t if (skipAngles === void 0) { skipAngles = false; }\n\n\t var options = this.options;\n\t var categories = options.categories.length;\n\t var divCount = categories / size || 1;\n\t var divAngle = 360 / divCount;\n\t var skip = skipOption || 0;\n\t var step = stepOption || 1;\n\t var divs = [];\n\t var angle = 0;\n\n\t for (var i = skip; i < divCount; i += step) {\n\t if (options.reverse) {\n\t angle = 360 - i * divAngle;\n\t } else {\n\t angle = i * divAngle;\n\t }\n\n\t angle = round(angle, COORD_PRECISION) % 360;\n\n\t if (!(skipAngles && inArray(angle, skipAngles))) {\n\t divs.push(angle);\n\t }\n\t }\n\n\t return divs;\n\t },\n\n\t majorIntervals: function() {\n\t return this.intervals(1);\n\t },\n\n\t minorIntervals: function() {\n\t return this.intervals(0.5);\n\t },\n\n\t intervalAngle: function(interval) {\n\t return (360 + interval + this.options.startAngle) % 360;\n\t },\n\n\t majorAngles: function() {\n\t var this$1 = this;\n\n\t return map(this.majorIntervals(), function (interval) { return this$1.intervalAngle(interval); });\n\t },\n\n\t createLine: function() {\n\t return [];\n\t },\n\n\t majorGridLineAngles: function(altAxis) {\n\t var majorGridLines = this.options.majorGridLines;\n\t return this.gridLineAngles(altAxis, 1, majorGridLines.skip, majorGridLines.step);\n\t },\n\n\t minorGridLineAngles: function(altAxis, skipMajor) {\n\t var ref = this.options;\n\t var minorGridLines = ref.minorGridLines;\n\t var majorGridLines = ref.majorGridLines;\n\t var majorGridLineAngles = skipMajor ? this.intervals(1, majorGridLines.skip, majorGridLines.step) : null;\n\n\t return this.gridLineAngles(altAxis, 0.5, minorGridLines.skip, minorGridLines.step, majorGridLineAngles);\n\t },\n\n\t radiusCallback: function(radius, altAxis, skipMajor) {\n\t if (altAxis.options.type !== ARC) {\n\t var minorAngle = rad(360 / (this.options.categories.length * 2));\n\t var minorRadius = Math.cos(minorAngle) * radius;\n\t var majorAngles = this.majorAngles();\n\n\t var radiusCallback = function(angle) {\n\t if (!skipMajor && inArray(angle, majorAngles)) {\n\t return radius;\n\t }\n\n\t return minorRadius;\n\t };\n\t return radiusCallback;\n\t }\n\t },\n\n\t createPlotBands: function() {\n\t var this$1 = this;\n\n\t var plotBands = this.options.plotBands || [];\n\n\t var group = this._plotbandGroup = new Group({\n\t zIndex: -1\n\t });\n\n\t for (var i = 0; i < plotBands.length; i++) {\n\t var band = plotBands[i];\n\t var slot = this$1.plotBandSlot(band);\n\t var singleSlot = this$1.getSlot(band.from);\n\n\t var head = band.from - Math.floor(band.from);\n\t slot.startAngle += head * singleSlot.angle;\n\n\t var tail = Math.ceil(band.to) - band.to;\n\t slot.angle -= (tail + head) * singleSlot.angle;\n\n\t var ring = ShapeBuilder.current.createRing(slot, {\n\t fill: {\n\t color: band.color,\n\t opacity: band.opacity\n\t },\n\t stroke: {\n\t opacity: band.opacity\n\t }\n\t });\n\t group.append(ring);\n\t }\n\n\t this.appendVisual(group);\n\t },\n\n\t plotBandSlot: function(band) {\n\t return this.getSlot(band.from, band.to - 1);\n\t },\n\n\t getSlot: function(from, to) {\n\t var options = this.options;\n\t var justified = options.justified;\n\t var box = this.box;\n\t var divs = this.majorAngles();\n\t var totalDivs = divs.length;\n\t var slotAngle = 360 / totalDivs;\n\t var fromValue = from;\n\n\t if (options.reverse && !justified) {\n\t fromValue = (fromValue + 1) % totalDivs;\n\t }\n\n\t fromValue = limitValue(Math.floor(fromValue), 0, totalDivs - 1);\n\t var slotStart = divs[fromValue];\n\n\t if (justified) {\n\t slotStart = slotStart - slotAngle / 2;\n\n\t if (slotStart < 0) {\n\t slotStart += 360;\n\t }\n\t }\n\n\t var toValue = limitValue(Math.ceil(to || fromValue), fromValue, totalDivs - 1);\n\t var slots = toValue - fromValue + 1;\n\t var angle = slotAngle * slots;\n\n\t return new Ring(box.center(), 0, box.height() / 2, slotStart, angle);\n\t },\n\n\t slot: function(from, to) {\n\t var slot = this.getSlot(from, to);\n\t var startAngle = slot.startAngle + 180;\n\t var endAngle = startAngle + slot.angle;\n\n\t return new geometry.Arc([ slot.center.x, slot.center.y ], {\n\t startAngle: startAngle,\n\t endAngle: endAngle,\n\t radiusX: slot.radius,\n\t radiusY: slot.radius\n\t });\n\t },\n\n\t pointCategoryIndex: function(point) {\n\t var this$1 = this;\n\n\t var length = this.options.categories.length;\n\t var index = null;\n\n\t for (var i = 0; i < length; i++) {\n\t var slot = this$1.getSlot(i);\n\t if (slot.containsPoint(point)) {\n\t index = i;\n\t break;\n\t }\n\t }\n\n\t return index;\n\t }\n\t});\n\n\tsetDefaultOptions(RadarCategoryAxis, {\n\t startAngle: 90,\n\t labels: {\n\t margin: getSpacing(10)\n\t },\n\t majorGridLines: {\n\t visible: true\n\t },\n\t justified: true\n\t});\n\tdeepExtend(RadarCategoryAxis.prototype, GridLinesMixin);\n\n\tvar PolarAxis = Axis.extend({\n\t init: function(options, chartService) {\n\t Axis.fn.init.call(this, options, chartService);\n\n\t var instanceOptions = this.options;\n\n\t instanceOptions.minorUnit = instanceOptions.minorUnit || instanceOptions.majorUnit / 2;\n\t },\n\n\t getDivisions: function(stepValue) {\n\t return NumericAxis.prototype.getDivisions.call(this, stepValue) - 1;\n\t },\n\n\t reflow: function(box) {\n\t this.box = box;\n\t this.reflowLabels();\n\t },\n\n\t reflowLabels: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var options = ref.options;\n\t var labels = ref.labels;\n\t var labelOptions = ref.options.labels;\n\t var skip = labelOptions.skip || 0;\n\t var step = labelOptions.step || 1;\n\n\t var measureBox = new Box();\n\t var divs = this.intervals(options.majorUnit, skip, step);\n\n\t for (var i = 0; i < labels.length; i++) {\n\t labels[i].reflow(measureBox);\n\t var labelBox = labels[i].box;\n\n\t labels[i].reflow(this$1.getSlot(divs[i]).adjacentBox(0, labelBox.width(), labelBox.height()));\n\t }\n\t },\n\n\t lineBox: function() {\n\t return this.box;\n\t },\n\n\t intervals: function(size, skipOption, stepOption, skipAngles) {\n\t if (skipAngles === void 0) { skipAngles = false; }\n\n\t var min = this.options.min;\n\t var divisions = this.getDivisions(size);\n\t var divs = [];\n\t var skip = skipOption || 0;\n\t var step = stepOption || 1;\n\n\t for (var i = skip; i < divisions; i += step) {\n\t var current = (360 + min + i * size) % 360;\n\t if (!(skipAngles && inArray(current, skipAngles))) {\n\t divs.push(current);\n\t }\n\t }\n\n\t return divs;\n\t },\n\n\t majorIntervals: function() {\n\t return this.intervals(this.options.majorUnit);\n\t },\n\n\t minorIntervals: function() {\n\t return this.intervals(this.options.minorUnit);\n\t },\n\n\t intervalAngle: function(i) {\n\t return (540 - i - this.options.startAngle) % 360;\n\t },\n\n\t createLine: function() {\n\t return [];\n\t },\n\n\t majorGridLineAngles: function(altAxis) {\n\t var majorGridLines = this.options.majorGridLines;\n\t return this.gridLineAngles(altAxis, this.options.majorUnit, majorGridLines.skip, majorGridLines.step);\n\t },\n\n\t minorGridLineAngles: function(altAxis, skipMajor) {\n\t var options = this.options;\n\t var minorGridLines = options.minorGridLines;\n\t var majorGridLines = options.majorGridLines;\n\t var majorGridLineAngles = skipMajor ? this.intervals(options.majorUnit, majorGridLines.skip, majorGridLines.step) : null;\n\n\t return this.gridLineAngles(altAxis, options.minorUnit, minorGridLines.skip, minorGridLines.step, majorGridLineAngles);\n\t },\n\n\t plotBandSlot: function(band) {\n\t return this.getSlot(band.from, band.to);\n\t },\n\n\t getSlot: function(a, b) {\n\t var ref = this;\n\t var options = ref.options;\n\t var box = ref.box;\n\t var startAngle = options.startAngle;\n\t var start = limitValue(a, options.min, options.max);\n\t var end = limitValue(b || start, start, options.max);\n\n\t if (options.reverse) {\n\t start *= -1;\n\t end *= -1;\n\t }\n\n\t start = (540 - start - startAngle) % 360;\n\t end = (540 - end - startAngle) % 360;\n\n\t if (end < start) {\n\t var tmp = start;\n\t start = end;\n\t end = tmp;\n\t }\n\n\t return new Ring(box.center(), 0, box.height() / 2, start, end - start);\n\t },\n\n\t slot: function(from, to) {\n\t if (to === void 0) { to = from; }\n\n\t var options = this.options;\n\t var start = 360 - options.startAngle;\n\t var slot = this.getSlot(from, to);\n\t var min = Math.min(from, to);\n\t var max = Math.max(from, to);\n\t var startAngle, endAngle;\n\n\t if (options.reverse) {\n\t startAngle = min;\n\t endAngle = max;\n\t } else {\n\t startAngle = 360 - max;\n\t endAngle = 360 - min;\n\t }\n\n\t startAngle = (startAngle + start) % 360;\n\t endAngle = (endAngle + start) % 360;\n\n\t return new geometry.Arc([ slot.center.x, slot.center.y ], {\n\t startAngle: startAngle,\n\t endAngle: endAngle,\n\t radiusX: slot.radius,\n\t radiusY: slot.radius\n\t });\n\t },\n\n\t getValue: function(point) {\n\t var options = this.options;\n\t var center = this.box.center();\n\t var dx = point.x - center.x;\n\t var dy = point.y - center.y;\n\t var theta = Math.round(deg(Math.atan2(dy, dx)));\n\t var start = options.startAngle;\n\n\t if (!options.reverse) {\n\t theta *= -1;\n\t start *= -1;\n\t }\n\n\t return (theta + start + 360) % 360;\n\t },\n\n\t valueRange: function() {\n\t return {\n\t min: 0,\n\t max: Math.PI * 2\n\t };\n\t }\n\t});\n\n\tsetDefaultOptions(PolarAxis, {\n\t type: \"polar\",\n\t startAngle: 0,\n\t reverse: false,\n\t majorUnit: 60,\n\t min: 0,\n\t max: 360,\n\t labels: {\n\t margin: getSpacing(10)\n\t },\n\t majorGridLines: {\n\t color: BLACK,\n\t visible: true,\n\t width: 1\n\t },\n\t minorGridLines: {\n\t color: \"#aaa\"\n\t }\n\t});\n\n\tdeepExtend(PolarAxis.prototype, GridLinesMixin, {\n\t createPlotBands: RadarCategoryAxis.prototype.createPlotBands,\n\t majorAngles: RadarCategoryAxis.prototype.majorAngles,\n\t range: NumericAxis.prototype.range,\n\t labelsCount: NumericAxis.prototype.labelsCount,\n\t createAxisLabel: NumericAxis.prototype.createAxisLabel\n\t});\n\n\tvar RadarNumericAxisMixin = {\n\t options: {\n\t majorGridLines: {\n\t visible: true\n\t }\n\t },\n\n\t createPlotBands: function() {\n\t var this$1 = this;\n\n\t var ref = this.options;\n\t var type = ref.majorGridLines.type;\n\t var plotBands = ref.plotBands; if (plotBands === void 0) { plotBands = []; }\n\t var altAxis = this.plotArea.polarAxis;\n\t var majorAngles = altAxis.majorAngles();\n\t var center = altAxis.box.center();\n\t var group = this._plotbandGroup = new Group({\n\t zIndex: -1\n\t });\n\n\t for (var i = 0; i < plotBands.length; i++) {\n\t var band = plotBands[i];\n\t var bandStyle = {\n\t fill: {\n\t color: band.color,\n\t opacity: band.opacity\n\t },\n\t stroke: {\n\t opacity: band.opacity\n\t }\n\t };\n\n\t var slot = this$1.getSlot(band.from, band.to, true);\n\t var ring = new Ring(center, center.y - slot.y2, center.y - slot.y1, 0, 360);\n\n\t var shape = (void 0);\n\t if (type === ARC) {\n\t shape = ShapeBuilder.current.createRing(ring, bandStyle);\n\t } else {\n\t shape = Path.fromPoints(this$1.plotBandPoints(ring, majorAngles), bandStyle).close();\n\t }\n\n\t group.append(shape);\n\t }\n\n\t this.appendVisual(group);\n\t },\n\n\t plotBandPoints: function(ring, angles) {\n\t var innerPoints = [];\n\t var outerPoints = [];\n\t var center = [ ring.center.x, ring.center.y ];\n\t var innerCircle = new Circle(center, ring.innerRadius);\n\t var outerCircle = new Circle(center, ring.radius);\n\n\t for (var i = 0; i < angles.length; i++) {\n\t innerPoints.push(innerCircle.pointAt(angles[i] + 180));\n\t outerPoints.push(outerCircle.pointAt(angles[i] + 180));\n\t }\n\n\t innerPoints.reverse();\n\t innerPoints.push(innerPoints[0]);\n\t outerPoints.push(outerPoints[0]);\n\n\t return outerPoints.concat(innerPoints);\n\t },\n\n\t createGridLines: function(altAxis) {\n\t var options = this.options;\n\t var majorTicks = this.radarMajorGridLinePositions();\n\t var majorAngles = altAxis.majorAngles();\n\t var center = altAxis.box.center();\n\t var gridLines = [];\n\n\t if (options.majorGridLines.visible) {\n\t gridLines = this.renderGridLines(\n\t center, majorTicks, majorAngles, options.majorGridLines\n\t );\n\t }\n\n\t if (options.minorGridLines.visible) {\n\t var minorTicks = this.radarMinorGridLinePositions();\n\t append(gridLines, this.renderGridLines(\n\t center, minorTicks, majorAngles, options.minorGridLines\n\t ));\n\t }\n\n\t return gridLines;\n\t },\n\n\t renderGridLines: function(center, ticks, angles, options) {\n\t var style = {\n\t stroke: {\n\t width: options.width,\n\t color: options.color,\n\t dashType: options.dashType\n\t }\n\t };\n\t var skip = options.skip; if (skip === void 0) { skip = 0; }\n\t var step = options.step; if (step === void 0) { step = 0; }\n\t var container = this.gridLinesVisual();\n\n\t for (var tickIx = skip; tickIx < ticks.length; tickIx += step) {\n\t var tickRadius = center.y - ticks[tickIx];\n\t if (tickRadius > 0) {\n\t var circle = new Circle([ center.x, center.y ], tickRadius);\n\t if (options.type === ARC) {\n\t container.append(new drawing.Circle(circle, style));\n\t } else {\n\t var line = new Path(style);\n\t for (var angleIx = 0; angleIx < angles.length; angleIx++) {\n\t line.lineTo(circle.pointAt(angles[angleIx] + 180));\n\t }\n\n\t line.close();\n\t container.append(line);\n\t }\n\t }\n\t }\n\n\t return container.children;\n\t },\n\n\t getValue: function(point) {\n\t var lineBox = this.lineBox();\n\t var altAxis = this.plotArea.polarAxis;\n\t var majorAngles = altAxis.majorAngles();\n\t var center = altAxis.box.center();\n\t var radius = point.distanceTo(center);\n\t var distance = radius;\n\n\t if (this.options.majorGridLines.type !== ARC && majorAngles.length > 1) {\n\t var dx = point.x - center.x;\n\t var dy = point.y - center.y;\n\t var theta = (deg(Math.atan2(dy, dx)) + 540) % 360;\n\n\t majorAngles.sort(function(a, b) {\n\t return angularDistance(a, theta) - angularDistance(b, theta);\n\t });\n\n\t // Solve triangle (center, point, axis X) using one side (radius) and two angles.\n\t // Angles are derived from triangle (center, point, gridline X)\n\t var midAngle = angularDistance(majorAngles[0], majorAngles[1]) / 2;\n\t var alpha = angularDistance(theta, majorAngles[0]);\n\t var gamma = 90 - midAngle;\n\t var beta = 180 - alpha - gamma;\n\n\t distance = radius * (Math.sin(rad(beta)) / Math.sin(rad(gamma)));\n\t }\n\n\t return this.axisType().prototype.getValue.call(\n\t this, new Point(lineBox.x1, lineBox.y2 - distance)\n\t );\n\t }\n\t};\n\n\tfunction angularDistance(a, b) {\n\t return 180 - Math.abs(Math.abs(a - b) - 180);\n\t}\n\n\tvar RadarNumericAxis = NumericAxis.extend({\n\t radarMajorGridLinePositions: function() {\n\t return this.getTickPositions(this.options.majorUnit);\n\t },\n\n\t radarMinorGridLinePositions: function() {\n\t var options = this.options;\n\t var minorSkipStep = 0;\n\n\t if (options.majorGridLines.visible) {\n\t minorSkipStep = options.majorUnit;\n\t }\n\t return this.getTickPositions(options.minorUnit, minorSkipStep);\n\t },\n\n\t axisType: function() {\n\t return NumericAxis;\n\t }\n\t});\n\n\tdeepExtend(RadarNumericAxis.prototype, RadarNumericAxisMixin);\n\n\tvar RadarLogarithmicAxis = LogarithmicAxis.extend({\n\t radarMajorGridLinePositions: function() {\n\t var positions = [];\n\n\t this.traverseMajorTicksPositions(function(position) {\n\t positions.push(position);\n\t }, this.options.majorGridLines);\n\n\t return positions;\n\t },\n\n\t radarMinorGridLinePositions: function() {\n\t var positions = [];\n\n\t this.traverseMinorTicksPositions(function(position) {\n\t positions.push(position);\n\t }, this.options.minorGridLines);\n\n\t return positions;\n\t },\n\n\t axisType: function() {\n\t return LogarithmicAxis;\n\t }\n\t});\n\n\tdeepExtend(RadarLogarithmicAxis.prototype, RadarNumericAxisMixin);\n\n\tvar WEIGHT = 0.333;\n\tvar EXTREMUM_ALLOWED_DEVIATION = 0.01;\n\n\tvar CurveProcessor = Class.extend({\n\t init: function(closed) {\n\n\t this.closed = closed;\n\t },\n\n\t process: function(dataPoints) {\n\t var this$1 = this;\n\n\t var points = dataPoints.slice(0);\n\t var segments = [];\n\t var closed = this.closed;\n\t var length = points.length;\n\n\t if (length > 2) {\n\t this.removeDuplicates(0, points);\n\t length = points.length;\n\t }\n\n\t if (length < 2 || (length === 2 && points[0].equals(points[1]))) {\n\t return segments;\n\t }\n\n\t var p0 = points[0];\n\t var p1 = points[1];\n\t var p2 = points[2];\n\n\t segments.push(new Segment(p0));\n\n\t while (p0.equals(points[length - 1])) {\n\t closed = true;\n\t points.pop();\n\t length--;\n\t }\n\n\t if (length === 2) {\n\t var tangent = this.tangent(p0,p1, X, Y);\n\n\t last(segments).controlOut(\n\t this.firstControlPoint(tangent, p0, p1, X, Y)\n\t );\n\n\t segments.push(new Segment(\n\t p1,\n\t this.secondControlPoint(tangent, p0, p1, X, Y)\n\t ));\n\n\t return segments;\n\t }\n\n\t var initialControlPoint, lastControlPoint;\n\n\t if (closed) {\n\t p0 = points[length - 1]; p1 = points[0]; p2 = points[1];\n\t var controlPoints = this.controlPoints(p0, p1, p2);\n\t initialControlPoint = controlPoints[1];\n\t lastControlPoint = controlPoints[0];\n\t } else {\n\t var tangent$1 = this.tangent(p0, p1, X,Y);\n\t initialControlPoint = this.firstControlPoint(tangent$1, p0, p1, X, Y);\n\t }\n\n\t var cp0 = initialControlPoint;\n\t for (var idx = 0; idx <= length - 3; idx++) {\n\t this$1.removeDuplicates(idx, points);\n\t length = points.length;\n\t if (idx + 3 <= length) {\n\t p0 = points[idx]; p1 = points[idx + 1]; p2 = points[idx + 2];\n\t var controlPoints$1 = this$1.controlPoints(p0,p1,p2);\n\n\t last(segments).controlOut(cp0);\n\t cp0 = controlPoints$1[1];\n\n\t var cp1 = controlPoints$1[0];\n\t segments.push(new Segment(p1, cp1));\n\t }\n\t }\n\n\t if (closed) {\n\t p0 = points[length - 2]; p1 = points[length - 1]; p2 = points[0];\n\t var controlPoints$2 = this.controlPoints(p0, p1, p2);\n\n\t last(segments).controlOut(cp0);\n\t segments.push(new Segment(\n\t p1,\n\t controlPoints$2[0]\n\t ));\n\n\t last(segments).controlOut(controlPoints$2[1]);\n\t segments.push(new Segment(\n\t p2,\n\t lastControlPoint\n\t ));\n\t } else {\n\t var tangent$2 = this.tangent(p1, p2, X, Y);\n\n\t last(segments).controlOut(cp0);\n\t segments.push(new Segment(\n\t p2,\n\t this.secondControlPoint(tangent$2, p1, p2, X, Y)\n\t ));\n\t }\n\n\t return segments;\n\t },\n\n\t removeDuplicates: function(idx, points) {\n\t while (points[idx + 1] && (points[idx].equals(points[idx + 1]) || points[idx + 1].equals(points[idx + 2]))) {\n\t points.splice(idx + 1, 1);\n\t }\n\t },\n\n\t invertAxis: function(p0, p1, p2) {\n\t var invertAxis = false;\n\n\t if (p0.x === p1.x) {\n\t invertAxis = true;\n\t } else if (p1.x === p2.x) {\n\t if ((p1.y < p2.y && p0.y <= p1.y) || (p2.y < p1.y && p1.y <= p0.y)) {\n\t invertAxis = true;\n\t }\n\t } else {\n\t var fn = this.lineFunction(p0,p1);\n\t var y2 = this.calculateFunction(fn, p2.x);\n\t if (!(p0.y <= p1.y && p2.y <= y2) &&\n\t !(p1.y <= p0.y && p2.y >= y2)) {\n\t invertAxis = true;\n\t }\n\t }\n\n\t return invertAxis;\n\t },\n\n\t isLine: function(p0, p1, p2) {\n\t var fn = this.lineFunction(p0, p1);\n\t var y2 = this.calculateFunction(fn, p2.x);\n\n\t return (p0.x === p1.x && p1.x === p2.x) || round(y2, 1) === round(p2.y, 1);\n\t },\n\n\t lineFunction: function(p1, p2) {\n\t var a = (p2.y - p1.y) / (p2.x - p1.x);\n\t var b = p1.y - a * p1.x;\n\n\t return [ b, a ];\n\t },\n\n\t controlPoints: function(p0, p1, p2) {\n\t var xField = X;\n\t var yField = Y;\n\t var restrict = false;\n\t var switchOrientation = false;\n\t var tangent;\n\n\t if (this.isLine(p0, p1, p2)) {\n\t tangent = this.tangent(p0, p1, X, Y);\n\t } else {\n\t var monotonic = {\n\t x: this.isMonotonicByField(p0, p1, p2, X),\n\t y: this.isMonotonicByField(p0, p1, p2, Y)\n\t };\n\n\t if (monotonic.x && monotonic.y) {\n\t tangent = this.tangent(p0, p2, X, Y);\n\t restrict = true;\n\t } else {\n\t if (this.invertAxis(p0, p1, p2)) {\n\t xField = Y;\n\t yField = X;\n\t }\n\n\t if (monotonic[xField]) {\n\t tangent = 0;\n\t } else {\n\t var sign;\n\t if ((p2[yField] < p0[yField] && p0[yField] <= p1[yField]) ||\n\t (p0[yField] < p2[yField] && p1[yField] <= p0[yField])) {\n\t sign = numberSign((p2[yField] - p0[yField]) * (p1[xField] - p0[xField]));\n\t } else {\n\t sign = -numberSign((p2[xField] - p0[xField]) * (p1[yField] - p0[yField]));\n\t }\n\n\t tangent = EXTREMUM_ALLOWED_DEVIATION * sign;\n\t switchOrientation = true;\n\t }\n\t }\n\t }\n\n\t var secondControlPoint = this.secondControlPoint(tangent, p0, p1, xField, yField);\n\n\t if (switchOrientation) {\n\t var oldXField = xField;\n\t xField = yField;\n\t yField = oldXField;\n\t }\n\n\t var firstControlPoint = this.firstControlPoint(tangent, p1, p2, xField, yField);\n\n\t if (restrict) {\n\t this.restrictControlPoint(p0, p1, secondControlPoint, tangent);\n\t this.restrictControlPoint(p1, p2, firstControlPoint, tangent);\n\t }\n\n\t return [ secondControlPoint, firstControlPoint ];\n\t },\n\n\t restrictControlPoint: function(p1, p2, cp, tangent) {\n\t if (p1.y < p2.y) {\n\t if (p2.y < cp.y) {\n\t cp.x = p1.x + (p2.y - p1.y) / tangent;\n\t cp.y = p2.y;\n\t } else if (cp.y < p1.y) {\n\t cp.x = p2.x - (p2.y - p1.y) / tangent;\n\t cp.y = p1.y;\n\t }\n\t } else {\n\t if (cp.y < p2.y) {\n\t cp.x = p1.x - (p1.y - p2.y) / tangent;\n\t cp.y = p2.y;\n\t } else if (p1.y < cp.y) {\n\t cp.x = p2.x + (p1.y - p2.y) / tangent;\n\t cp.y = p1.y;\n\t }\n\t }\n\t },\n\n\t tangent: function(p0, p1, xField, yField) {\n\t var x = p1[xField] - p0[xField];\n\t var y = p1[yField] - p0[yField];\n\t var tangent;\n\n\t if (x === 0) {\n\t tangent = 0;\n\t } else {\n\t tangent = y / x;\n\t }\n\n\t return tangent;\n\t },\n\n\t isMonotonicByField: function(p0, p1, p2, field) {\n\t return (p2[field] > p1[field] && p1[field] > p0[field]) ||\n\t (p2[field] < p1[field] && p1[field] < p0[field]);\n\t },\n\n\t firstControlPoint: function(tangent, p0, p3, xField, yField) {\n\t var t1 = p0[xField];\n\t var t2 = p3[xField];\n\t var distance = (t2 - t1) * WEIGHT;\n\n\t return this.point(t1 + distance, p0[yField] + distance * tangent, xField, yField);\n\t },\n\n\t secondControlPoint: function(tangent, p0, p3, xField, yField) {\n\t var t1 = p0[xField];\n\t var t2 = p3[xField];\n\t var distance = (t2 - t1) * WEIGHT;\n\n\t return this.point(t2 - distance, p3[yField] - distance * tangent, xField, yField);\n\t },\n\n\t point: function(xValue, yValue, xField, yField) {\n\t var controlPoint = new geometry.Point();\n\t controlPoint[xField] = xValue;\n\t controlPoint[yField] = yValue;\n\n\t return controlPoint;\n\t },\n\n\t calculateFunction: function(fn, x) {\n\t var length = fn.length;\n\t var result = 0;\n\n\t for (var i = 0; i < length; i++) {\n\t result += Math.pow(x,i) * fn[i];\n\t }\n\t return result;\n\t }\n\t});\n\n\tfunction numberSign(value) {\n\t return value <= 0 ? -1 : 1;\n\t}\n\n\tdataviz.Gradients = GRADIENTS;\n\n\tkendo.deepExtend(kendo.dataviz, {\n\t constants: constants,\n\t services: services,\n\t autoMajorUnit: autoMajorUnit,\n\t Point: Point,\n\t Box: Box,\n\t Ring: Ring,\n\t Sector: Sector,\n\t ShapeBuilder: ShapeBuilder,\n\t ShapeElement: ShapeElement,\n\t ChartElement: ChartElement,\n\t BoxElement: BoxElement,\n\t RootElement: RootElement,\n\t FloatElement: FloatElement,\n\t Text: Text,\n\t TextBox: TextBox,\n\t Title: Title,\n\t AxisLabel: AxisLabel,\n\t Axis: Axis,\n\t Note: Note,\n\t CategoryAxis: CategoryAxis,\n\t DateCategoryAxis: DateCategoryAxis,\n\t DateValueAxis: DateValueAxis,\n\t NumericAxis: NumericAxis,\n\t LogarithmicAxis: LogarithmicAxis,\n\t PolarAxis: PolarAxis,\n\t RadarCategoryAxis: RadarCategoryAxis,\n\t RadarNumericAxis: RadarNumericAxis,\n\t RadarLogarithmicAxis: RadarLogarithmicAxis,\n\t CurveProcessor: CurveProcessor,\n\t rectToBox: rectToBox,\n\t addClass: addClass,\n\t removeClass: removeClass,\n\t alignPathToPixel: alignPathToPixel,\n\t clockwise: clockwise,\n\t convertableToNumber: convertableToNumber,\n\t deepExtend: deepExtend,\n\t elementStyles: elementStyles,\n\t getSpacing: getSpacing,\n\t getTemplate: getTemplate,\n\t getter: __common_getter_js,\n\t grep: grep,\n\t hasClasses: hasClasses,\n\t HashMap: HashMap,\n\t inArray: inArray,\n\t interpolateValue: interpolateValue,\n\t InstanceObserver: InstanceObserver,\n\t isArray: isArray,\n\t isFunction: isFunction,\n\t isNumber: isNumber,\n\t isObject: isObject,\n\t isString: isString,\n\t map: map,\n\t mousewheelDelta: mousewheelDelta,\n\t FontLoader: FontLoader,\n\t setDefaultOptions: setDefaultOptions,\n\t sparseArrayLimits: sparseArrayLimits,\n\t styleValue: styleValue,\n\t find: find,\n\t append: append,\n\t bindEvents: bindEvents,\n\t Class: Class,\n\t defined: defined,\n\t deg: deg,\n\t elementOffset: elementOffset,\n\t elementSize: elementSize,\n\t eventElement: eventElement,\n\t eventCoordinates: eventCoordinates,\n\t last: last,\n\t limitValue: limitValue,\n\t logToConsole: kendo.logToConsole,\n\t objectKey: objectKey,\n\t rad: rad,\n\t round: round,\n\t unbindEvents: unbindEvents,\n\t valueOrDefault: valueOrDefault,\n\t absoluteDateDiff: absoluteDateDiff,\n\t addDuration: addDuration,\n\t addTicks: addTicks,\n\t ceilDate: ceilDate,\n\t dateComparer: dateComparer,\n\t dateDiff: dateDiff,\n\t dateEquals: dateEquals,\n\t dateIndex: dateIndex,\n\t duration: duration,\n\t floorDate: floorDate,\n\t lteDateIndex: lteDateIndex,\n\t startOfWeek: startOfWeek,\n\t toDate: toDate,\n\t parseDate: parseDate,\n\t parseDates: parseDates,\n\t toTime: toTime\n\t});\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(868);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 857:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.data\");\n\n/***/ }),\n\n/***/ 858:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 859:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.themes\");\n\n/***/ }),\n\n/***/ 868:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (f, define) {\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(857), __webpack_require__(870), __webpack_require__(871),\n\t __webpack_require__(872),\n\t __webpack_require__(873),\n\t __webpack_require__(869),\n\t __webpack_require__(858),\n\t __webpack_require__(859),\n\t __webpack_require__(874),\n\t __webpack_require__(875),\n\t __webpack_require__(876) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function () {\n\n\t (function ($, undefined) {\n\t // Imports ================================================================\n\t var dataviz = kendo.dataviz,\n\t draw = kendo.drawing,\n\t geom = kendo.geometry,\n\t diagram = dataviz.diagram,\n\t Widget = kendo.ui.Widget,\n\t Class = kendo.Class,\n\t proxy = $.proxy,\n\t deepExtend = kendo.deepExtend,\n\t outerWidth = kendo._outerWidth,\n\t outerHeight = kendo._outerHeight,\n\t extend = $.extend,\n\t HierarchicalDataSource = kendo.data.HierarchicalDataSource,\n\t Canvas = diagram.Canvas,\n\t Group = diagram.Group,\n\t Rectangle = diagram.Rectangle,\n\t Circle = diagram.Circle,\n\t CompositeTransform = diagram.CompositeTransform,\n\t Rect = diagram.Rect,\n\t Path = diagram.Path,\n\t DeleteShapeUnit = diagram.DeleteShapeUnit,\n\t DeleteConnectionUnit = diagram.DeleteConnectionUnit,\n\t TextBlock = diagram.TextBlock,\n\t Image = diagram.Image,\n\t Point = diagram.Point,\n\t Intersect = diagram.Intersect,\n\t ConnectionEditAdorner = diagram.ConnectionEditAdorner,\n\t UndoRedoService = diagram.UndoRedoService,\n\t ToolService = diagram.ToolService,\n\t Selector = diagram.Selector,\n\t ResizingAdorner = diagram.ResizingAdorner,\n\t ConnectorsAdorner = diagram.ConnectorsAdorner,\n\t Cursors = diagram.Cursors,\n\t Utils = diagram.Utils,\n\t Observable = kendo.Observable,\n\t ToBackUnit = diagram.ToBackUnit,\n\t ToFrontUnit = diagram.ToFrontUnit,\n\t PolylineRouter = diagram.PolylineRouter,\n\t CascadingRouter = diagram.CascadingRouter,\n\t isUndefined = Utils.isUndefined,\n\t isDefined = Utils.isDefined,\n\t defined = draw.util.defined,\n\t isArray = $.isArray,\n\t isFunction = kendo.isFunction,\n\t isString = Utils.isString,\n\t isPlainObject = $.isPlainObject,\n\n\t math = Math;\n\n\t // Constants ==============================================================\n\t var NS = \".kendoDiagram\",\n\t CASCADING = \"cascading\",\n\t ITEMBOUNDSCHANGE = \"itemBoundsChange\",\n\t CHANGE = \"change\",\n\t CLICK = \"click\",\n\t DRAG = \"drag\",\n\t DRAG_END = \"dragEnd\",\n\t DRAG_START = \"dragStart\",\n\t MOUSE_ENTER = \"mouseEnter\",\n\t MOUSE_LEAVE = \"mouseLeave\",\n\t ERROR = \"error\",\n\t AUTO = \"Auto\",\n\t TOP = \"Top\",\n\t RIGHT = \"Right\",\n\t LEFT = \"Left\",\n\t BOTTOM = \"Bottom\",\n\t MAXINT = 9007199254740992,\n\t SELECT = \"select\",\n\t ITEMROTATE = \"itemRotate\",\n\t PAN = \"pan\",\n\t ZOOM_START = \"zoomStart\",\n\t ZOOM_END = \"zoomEnd\",\n\t NONE = \"none\",\n\t DEFAULT_CANVAS_WIDTH = 600,\n\t DEFAULT_CANVAS_HEIGHT = 600,\n\t DEFAULT_SHAPE_TYPE = \"rectangle\",\n\t DEFAULT_SHAPE_WIDTH = 100,\n\t DEFAULT_SHAPE_HEIGHT = 100,\n\t DEFAULT_SHAPE_MINWIDTH = 20,\n\t DEFAULT_SHAPE_MINHEIGHT = 20,\n\t DEFAULT_SHAPE_POSITION = 0,\n\t DEFAULT_CONNECTION_BACKGROUND = \"Yellow\",\n\t MAX_VALUE = Number.MAX_VALUE,\n\t MIN_VALUE = -Number.MAX_VALUE,\n\t ABSOLUTE = \"absolute\",\n\t TRANSFORMED = \"transformed\",\n\t ROTATED = \"rotated\",\n\t TRANSPARENT = \"transparent\",\n\t WIDTH = \"width\",\n\t HEIGHT = \"height\",\n\t X = \"x\",\n\t Y = \"y\",\n\t MOUSEWHEEL_NS = \"DOMMouseScroll\" + NS + \" mousewheel\" + NS,\n\t MOBILE_ZOOM_RATE = 0.05,\n\t MOBILE_PAN_DISTANCE = 5,\n\t BUTTON_TEMPLATE = '#=text#',\n\t CONNECTION_CONTENT_OFFSET = 5;\n\n\t diagram.DefaultConnectors = [{\n\t name: TOP\n\t }, {\n\t name: BOTTOM\n\t }, {\n\t name: LEFT\n\t }, {\n\t name: RIGHT\n\t }, {\n\t name: AUTO,\n\t position: function (shape) {\n\t return shape.getPosition(\"center\");\n\t }\n\t }];\n\n\t var defaultButtons = {\n\t cancel: {\n\t text: \"Cancel\",\n\t imageClass: \"k-i-cancel\",\n\t className: \"k-diagram-cancel\",\n\t iconClass: \"k-icon\"\n\t },\n\t update: {\n\t text: \"Update\",\n\t imageClass: \"k-i-checkmark\",\n\t className: \"k-diagram-update\",\n\t iconClass: \"k-icon\"\n\t }\n\t };\n\n\t diagram.shapeDefaults = function(extra) {\n\t var defaults = {\n\t type: DEFAULT_SHAPE_TYPE,\n\t path: \"\",\n\t autoSize: true,\n\t visual: null,\n\t x: DEFAULT_SHAPE_POSITION,\n\t y: DEFAULT_SHAPE_POSITION,\n\t minWidth: DEFAULT_SHAPE_MINWIDTH,\n\t minHeight: DEFAULT_SHAPE_MINHEIGHT,\n\t width: DEFAULT_SHAPE_WIDTH,\n\t height: DEFAULT_SHAPE_HEIGHT,\n\t hover: {},\n\t editable: {\n\t connect: true,\n\t tools: []\n\t },\n\t connectors: diagram.DefaultConnectors,\n\t rotation: {\n\t angle: 0\n\t }\n\t };\n\n\t Utils.simpleExtend(defaults, extra);\n\n\t return defaults;\n\t };\n\n\t function mwDelta(e) {\n\t var origEvent = e.originalEvent,\n\t delta = 0;\n\n\t if (origEvent.wheelDelta) {\n\t delta = -origEvent.wheelDelta / 40;\n\t delta = delta > 0 ? math.ceil(delta) : math.floor(delta);\n\t } else if (origEvent.detail) {\n\t delta = origEvent.detail;\n\t }\n\n\t return delta;\n\t }\n\n\t function isAutoConnector(connector) {\n\t return connector.options.name.toLowerCase() === AUTO.toLowerCase();\n\t }\n\n\t function closestConnector(point, connectors) {\n\t var minimumDistance = MAXINT, resCtr, connector;\n\t for (var i = 0; i < connectors.length; i++) {\n\t connector = connectors[i];\n\t if (!isAutoConnector(connector)) {\n\t var dist = point.distanceTo(connector.position());\n\t if (dist < minimumDistance) {\n\t minimumDistance = dist;\n\t resCtr = connector;\n\t }\n\t }\n\t }\n\t return resCtr;\n\t }\n\n\t function indicesOfItems(group, visuals) {\n\t var i, indices = [], visual;\n\t var children = group.drawingContainer().children;\n\t var length = children.length;\n\t for (i = 0; i < visuals.length; i++) {\n\t visual = visuals[i];\n\t for (var j = 0; j < length; j++) {\n\t if (children[j] == visual.drawingContainer()) {\n\t indices.push(j);\n\t break;\n\t }\n\t }\n\t }\n\t return indices;\n\t }\n\n\t var DiagramElement = Observable.extend({\n\t init: function (options) {\n\t var that = this;\n\t that.dataItem = (options || {}).dataItem;\n\t Observable.fn.init.call(that);\n\t that.options = deepExtend({ id: diagram.randomId() }, that.options, options);\n\t that.isSelected = false;\n\t that.visual = new Group({\n\t id: that.options.id,\n\t autoSize: that.options.autoSize\n\t });\n\t that.id = that.options.id;\n\t that._template();\n\t },\n\n\t options: {\n\t hover: {},\n\t cursor: Cursors.grip,\n\t content: {\n\t align: \"center middle\"\n\t },\n\t selectable: true,\n\t serializable: true,\n\t enable: true\n\t },\n\n\t _getCursor: function (point) {\n\t if (this.adorner) {\n\t return this.adorner._getCursor(point);\n\t }\n\t return this.options.cursor;\n\t },\n\n\t visible: function (value) {\n\t if (isUndefined(value)) {\n\t return this.visual.visible();\n\t } else {\n\t this.visual.visible(value);\n\t }\n\t },\n\n\t bounds: function () {\n\t },\n\n\t refresh: function () {\n\t this.visual.redraw();\n\t },\n\n\t position: function (point) {\n\t this.options.x = point.x;\n\t this.options.y = point.y;\n\t this.visual.position(point);\n\t },\n\n\t toString: function () {\n\t return this.options.id;\n\t },\n\n\t serialize: function () {\n\t // the options json object describes the shape perfectly. So this object can serve as shape serialization.\n\t var json = deepExtend({}, {options: this.options});\n\t if (this.dataItem) {\n\t json.dataItem = this.dataItem.toString();\n\t }\n\t return json;\n\t },\n\n\t _content: function (content) {\n\t if (content !== undefined) {\n\t var options = this.options;\n\n\t if (diagram.Utils.isString(content)) {\n\t options.content.text = content;\n\t } else {\n\t deepExtend(options.content, content);\n\t }\n\n\t var contentOptions = options.content;\n\t var contentVisual = this._contentVisual;\n\n\t if (!contentVisual) {\n\t this._createContentVisual(contentOptions);\n\t } else {\n\t this._updateContentVisual(contentOptions);\n\t }\n\t }\n\n\t return this.options.content.text;\n\t },\n\n\t _createContentVisual: function(options) {\n\t if (options.text) {\n\t this._contentVisual = new TextBlock(options);\n\t this._contentVisual._includeInBBox = false;\n\t this.visual.append(this._contentVisual);\n\t }\n\t },\n\n\t _updateContentVisual: function(options) {\n\t this._contentVisual.redraw(options);\n\t },\n\n\t _hitTest: function (point) {\n\t var bounds = this.bounds();\n\t return this.visible() && bounds.contains(point) && this.options.enable;\n\t },\n\n\t _template: function () {\n\t var that = this;\n\t if (that.options.content.template) {\n\t var data = that.dataItem || {},\n\t elementTemplate = kendo.template(that.options.content.template, {\n\t paramName: \"dataItem\"\n\t });\n\n\t that.options.content.text = elementTemplate(data);\n\t }\n\t },\n\n\t _canSelect: function () {\n\t return this.options.selectable !== false;\n\t },\n\n\t toJSON: function() {\n\t return {\n\t id: this.options.id\n\t };\n\t }\n\t });\n\n\t var Connector = Class.extend({\n\t init: function (shape, options) {\n\t this.options = deepExtend({}, this.options, options);\n\t this.connections = [];\n\t this.shape = shape;\n\t },\n\t options: {\n\t width: 7,\n\t height: 7,\n\t fill: {\n\t color: DEFAULT_CONNECTION_BACKGROUND\n\t },\n\t hover: {}\n\t },\n\t position: function () {\n\t if (this.options.position) {\n\t return this.options.position(this.shape);\n\t } else {\n\t return this.shape.getPosition(this.options.name);\n\t }\n\t },\n\t toJSON: function () {\n\t return {\n\t shapeId: this.shape.toString(),\n\t connector: this.options.name\n\t };\n\t }\n\t });\n\n\t Connector.parse = function (diagram, str) {\n\t var tempStr = str.split(\":\"),\n\t id = tempStr[0],\n\t name = tempStr[1] || AUTO;\n\n\t for (var i = 0; i < diagram.shapes.length; i++) {\n\t var shape = diagram.shapes[i];\n\t if (shape.options.id == id) {\n\t return shape.getConnector(name.trim());\n\t }\n\t }\n\t };\n\n\t var Shape = DiagramElement.extend({\n\t init: function (options, diagram) {\n\t var that = this;\n\t DiagramElement.fn.init.call(that, options);\n\t this.diagram = diagram;\n\t this.updateOptionsFromModel();\n\t options = that.options;\n\t that.connectors = [];\n\t that.type = options.type;\n\t that.createShapeVisual();\n\t that.updateBounds();\n\t that.content(that.content());\n\n\t that._createConnectors();\n\t },\n\n\t options: diagram.shapeDefaults(),\n\n\t _setOptionsFromModel: function(model) {\n\t var modelOptions = filterShapeDataItem(model || this.dataItem);\n\t this.options = deepExtend({}, this.options, modelOptions);\n\n\t this.redrawVisual();\n\t },\n\n\t updateOptionsFromModel: function(model, field) {\n\t if (this.diagram && this.diagram._isEditable) {\n\t var modelOptions = filterShapeDataItem(model || this.dataItem);\n\n\t if (model && field) {\n\t if (!dataviz.inArray(field, [\"x\", \"y\", \"width\", \"height\"])) {\n\t if (this.options.visual) {\n\t this._redrawVisual();\n\t } else if (modelOptions.type) {\n\t this.options = deepExtend({}, this.options, modelOptions);\n\t this._redrawVisual();\n\t }\n\n\t if (this.options.content) {\n\t this._template();\n\t this.content(this.options.content);\n\t }\n\t } else {\n\t var bounds = this.bounds();\n\t bounds[field] = model[field];\n\t this.bounds(bounds);\n\t }\n\t } else {\n\t this.options = deepExtend({}, this.options, modelOptions);\n\t }\n\t }\n\t },\n\n\t _redrawVisual: function() {\n\t this.visual.clear();\n\t this._contentVisual = null;\n\t this.options.dataItem = this.dataItem;\n\t this.createShapeVisual();\n\t this.updateBounds();\n\t },\n\n\t redrawVisual: function() {\n\t this._redrawVisual();\n\t if (this.options.content) {\n\t this._template();\n\t this.content(this.options.content);\n\t }\n\t },\n\n\t updateModel: function(syncChanges) {\n\t var diagram = this.diagram;\n\t if (diagram && diagram._isEditable) {\n\t var bounds = this._bounds;\n\t var model = this.dataItem;\n\n\t if (model) {\n\t diagram._suspendModelRefresh();\n\t if (defined(model.x) && bounds.x !== model.x) {\n\t model.set(\"x\", bounds.x);\n\t }\n\n\t if (defined(model.y) && bounds.y !== model.y) {\n\t model.set(\"y\", bounds.y);\n\t }\n\n\t if (defined(model.width) && bounds.width !== model.width) {\n\t model.set(\"width\", bounds.width);\n\t }\n\n\t if (defined(model.height) && bounds.height !== model.height) {\n\t model.set(\"height\", bounds.height);\n\t }\n\n\t this.dataItem = model;\n\t diagram._resumeModelRefresh();\n\n\t if (syncChanges) {\n\t diagram._syncShapeChanges();\n\t }\n\t }\n\t }\n\t },\n\n\t updateBounds: function() {\n\t var bounds = this.visual._measure(true);\n\t var options = this.options;\n\t this.bounds(new Rect(options.x, options.y, bounds.width, bounds.height));\n\t this._rotate();\n\t this._alignContent();\n\t },\n\n\t content: function(content) {\n\t var result = this._content(content);\n\n\t this._alignContent();\n\n\t return result;\n\t },\n\n\t _alignContent: function() {\n\t var contentOptions = this.options.content || {};\n\t var contentVisual = this._contentVisual;\n\t if (contentVisual && contentOptions.align) {\n\t var containerRect = this.visual._measure();\n\t var aligner = new diagram.RectAlign(containerRect);\n\t var contentBounds = contentVisual.drawingElement.bbox(null);\n\n\t var contentRect = new Rect(0, 0, contentBounds.width(), contentBounds.height());\n\t var alignedBounds = aligner.align(contentRect, contentOptions.align);\n\n\t contentVisual.position(alignedBounds.topLeft());\n\t }\n\t },\n\n\t _createConnectors: function() {\n\t var options = this.options,\n\t length = options.connectors.length,\n\t connectorDefaults = options.connectorDefaults,\n\t connector, i;\n\n\t for (i = 0; i < length; i++) {\n\t connector = new Connector(\n\t this, deepExtend({},\n\t connectorDefaults,\n\t options.connectors[i]\n\t )\n\t );\n\t this.connectors.push(connector);\n\t }\n\t },\n\n\t bounds: function (value) {\n\t var bounds;\n\n\t if (value) {\n\t if (isString(value)) {\n\t switch (value) {\n\t case TRANSFORMED :\n\t bounds = this._transformedBounds();\n\t break;\n\t case ABSOLUTE :\n\t bounds = this._transformedBounds();\n\t var pan = this.diagram._pan;\n\t bounds.x += pan.x;\n\t bounds.y += pan.y;\n\t break;\n\t case ROTATED :\n\t bounds = this._rotatedBounds();\n\t break;\n\t default:\n\t bounds = this._bounds;\n\t }\n\t } else {\n\t this._setBounds(value);\n\t this._triggerBoundsChange();\n\t if (!(this.diagram && this.diagram._layouting)) {\n\t this.refreshConnections();\n\t }\n\t }\n\t } else {\n\t bounds = this._bounds;\n\t }\n\n\t return bounds;\n\t },\n\n\t _setBounds: function(rect) {\n\t var options = this.options;\n\t var topLeft = rect.topLeft();\n\t var x = options.x = topLeft.x;\n\t var y = options.y = topLeft.y;\n\t var width = options.width = math.max(rect.width, options.minWidth);\n\t var height = options.height = math.max(rect.height, options.minHeight);\n\n\t this._bounds = new Rect(x, y, width, height);\n\n\t this.visual.redraw({\n\t x: x,\n\t y: y,\n\t width: width,\n\t height: height\n\t });\n\t },\n\n\t position: function (point) {\n\t if (point) {\n\t this.bounds(new Rect(point.x, point.y, this._bounds.width, this._bounds.height));\n\t } else {\n\t return this._bounds.topLeft();\n\t }\n\t },\n\t /**\n\t * Returns a clone of this shape.\n\t * @returns {Shape}\n\t */\n\t clone: function () {\n\t var json = this.serialize();\n\n\t json.options.id = diagram.randomId();\n\n\t if (this.diagram && this.diagram._isEditable && defined(this.dataItem)) {\n\t json.options.dataItem = cloneDataItem(this.dataItem);\n\t }\n\n\t return new Shape(json.options);\n\t },\n\n\t select: function (value) {\n\t var diagram = this.diagram, selected, deselected;\n\t if (isUndefined(value)) {\n\t value = true;\n\t }\n\n\t if (this._canSelect()) {\n\t if (this.isSelected != value) {\n\t selected = [];\n\t deselected = [];\n\t this.isSelected = value;\n\t if (this.isSelected) {\n\t diagram._selectedItems.push(this);\n\t selected.push(this);\n\t } else {\n\t Utils.remove(diagram._selectedItems, this);\n\t deselected.push(this);\n\t }\n\n\t if (!diagram._internalSelection) {\n\t diagram._selectionChanged(selected, deselected);\n\t }\n\n\t return true;\n\t }\n\t }\n\t },\n\n\t rotate: function (angle, center, undoable) { // we assume the center is always the center of the shape.\n\t var rotate = this.visual.rotate();\n\t if (angle !== undefined) {\n\t if (undoable !== false && this.diagram && this.diagram.undoRedoService && angle !== rotate.angle) {\n\t this.diagram.undoRedoService.add(\n\t new diagram.RotateUnit(this.diagram._resizingAdorner, [this], [rotate.angle]), false);\n\t }\n\n\t var b = this.bounds(),\n\t sc = new Point(b.width / 2, b.height / 2),\n\t deltaAngle,\n\t newPosition;\n\n\t if (center) {\n\t deltaAngle = angle - rotate.angle;\n\t newPosition = b.center().rotate(center, 360 - deltaAngle).minus(sc);\n\t this._rotationOffset = this._rotationOffset.plus(newPosition.minus(b.topLeft()));\n\t this.position(newPosition);\n\t }\n\n\t this.visual.rotate(angle, sc);\n\t this.options.rotation.angle = angle;\n\n\t if (this.diagram && this.diagram._connectorsAdorner) {\n\t this.diagram._connectorsAdorner.refresh();\n\t }\n\n\t this.refreshConnections();\n\n\t if (this.diagram) {\n\t this.diagram.trigger(ITEMROTATE, { item: this });\n\t }\n\t }\n\n\t return rotate;\n\t },\n\n\t connections: function (type) { // in, out, undefined = both\n\t var result = [], i, j, con, cons, ctr;\n\n\t for (i = 0; i < this.connectors.length; i++) {\n\t ctr = this.connectors[i];\n\t cons = ctr.connections;\n\t for (j = 0, cons; j < cons.length; j++) {\n\t con = cons[j];\n\t if (type == \"out\") {\n\t var source = con.source();\n\t if (source.shape && source.shape == this) {\n\t result.push(con);\n\t }\n\t } else if (type == \"in\") {\n\t var target = con.target();\n\t if (target.shape && target.shape == this) {\n\t result.push(con);\n\t }\n\t } else {\n\t result.push(con);\n\t }\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t refreshConnections: function () {\n\t $.each(this.connections(), function () {\n\t this.refresh();\n\t });\n\t },\n\t /**\n\t * Gets a connector of this shape either by the connector's supposed name or\n\t * via a Point in which case the closest connector will be returned.\n\t * @param nameOrPoint The name of a Connector or a Point.\n\t * @returns {Connector}\n\t */\n\t getConnector: function (nameOrPoint) {\n\t var i, ctr;\n\t if (isString(nameOrPoint)) {\n\t nameOrPoint = nameOrPoint.toLocaleLowerCase();\n\t for (i = 0; i < this.connectors.length; i++) {\n\t ctr = this.connectors[i];\n\t if (ctr.options.name.toLocaleLowerCase() == nameOrPoint) {\n\t return ctr;\n\t }\n\t }\n\t } else if (nameOrPoint instanceof Point) {\n\t return closestConnector(nameOrPoint, this.connectors);\n\t } else {\n\t return this.connectors.length ? this.connectors[0] : null;\n\t }\n\t },\n\n\t getPosition: function (side) {\n\t var b = this.bounds(),\n\t fnName = side.charAt(0).toLowerCase() + side.slice(1);\n\n\t if (isFunction(b[fnName])) {\n\t return this._transformPoint(b[fnName]());\n\t }\n\n\t return b.center();\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t var shapeOptions = this.options;\n\t var boundsChange;\n\n\t this.shapeVisual.redraw(this._visualOptions(options));\n\n\t if (this._diffNumericOptions(options, [WIDTH, HEIGHT, X, Y])) {\n\t this.bounds(new Rect(shapeOptions.x, shapeOptions.y, shapeOptions.width, shapeOptions.height));\n\t boundsChange = true;\n\t }\n\n\t if (options.connectors) {\n\t shapeOptions.connectors = options.connectors;\n\t this._updateConnectors();\n\t }\n\n\t shapeOptions = deepExtend(shapeOptions, options);\n\n\t if (options.rotation || boundsChange) {\n\t this._rotate();\n\t }\n\n\t if (shapeOptions.content) {\n\t this.content(shapeOptions.content);\n\t }\n\t }\n\t },\n\n\t _updateConnectors: function() {\n\t var connections = this.connections();\n\t this.connectors = [];\n\t this._createConnectors();\n\t var connection;\n\t var source;\n\t var target;\n\n\t for (var idx = 0; idx < connections.length; idx++) {\n\t connection = connections[idx];\n\t source = connection.source();\n\t target = connection.target();\n\t if (source.shape && source.shape === this) {\n\t connection.source(this.getConnector(source.options.name) || null);\n\t } else if (target.shape && target.shape === this) {\n\t connection.target(this.getConnector(target.options.name) || null);\n\t }\n\t connection.updateModel();\n\t }\n\t },\n\n\t _diffNumericOptions: diagram.diffNumericOptions,\n\n\t _visualOptions: function(options) {\n\t return {\n\t data: options.path,\n\t source: options.source,\n\t hover: options.hover,\n\t fill: options.fill,\n\t stroke: options.stroke\n\t };\n\t },\n\n\t _triggerBoundsChange: function () {\n\t if (this.diagram) {\n\t this.diagram.trigger(ITEMBOUNDSCHANGE, {item: this, bounds: this._bounds.clone()}); // the trigger modifies the arguments internally.\n\t }\n\t },\n\n\t _transformPoint: function (point) {\n\t var rotate = this.rotate(),\n\t bounds = this.bounds(),\n\t tl = bounds.topLeft();\n\n\t if (rotate.angle) {\n\t point.rotate(rotate.center().plus(tl), 360 - rotate.angle);\n\t }\n\n\t return point;\n\t },\n\n\t _transformedBounds: function () {\n\t var bounds = this.bounds(),\n\t tl = bounds.topLeft(),\n\t br = bounds.bottomRight();\n\n\t return Rect.fromPoints(this.diagram.modelToView(tl), this.diagram.modelToView(br));\n\t },\n\n\t _rotatedBounds: function () {\n\t var bounds = this.bounds().rotatedBounds(this.rotate().angle),\n\t tl = bounds.topLeft(),\n\t br = bounds.bottomRight();\n\n\t return Rect.fromPoints(tl, br);\n\t },\n\n\t _rotate: function () {\n\t var rotation = this.options.rotation;\n\n\t if (rotation && rotation.angle) {\n\t this.rotate(rotation.angle);\n\t }\n\n\t this._rotationOffset = new Point();\n\t },\n\n\t _hover: function (value) {\n\t var options = this.options,\n\t hover = options.hover,\n\t stroke = options.stroke,\n\t fill = options.fill;\n\n\t if (value && isDefined(hover.stroke)) {\n\t stroke = deepExtend({}, stroke, hover.stroke);\n\t }\n\n\t if (value && isDefined(hover.fill)) {\n\t fill = hover.fill;\n\t }\n\n\t this.shapeVisual.redraw({\n\t stroke: stroke,\n\t fill: fill\n\t });\n\n\t if (options.editable && options.editable.connect) {\n\t this.diagram._showConnectors(this, value);\n\t }\n\t },\n\n\t _hitTest: function (value) {\n\t if (this.visible()) {\n\t var bounds = this.bounds(), rotatedPoint,\n\t angle = this.rotate().angle;\n\n\t if (value.isEmpty && !value.isEmpty()) { // rect selection\n\t return Intersect.rects(value, bounds, angle ? angle : 0);\n\t } else { // point\n\t rotatedPoint = value.clone().rotate(bounds.center(), angle); // cloning is important because rotate modifies the point inline.\n\t if (bounds.contains(rotatedPoint)) {\n\t return this;\n\t }\n\t }\n\t }\n\t },\n\n\t toJSON: function() {\n\t return {\n\t shapeId: this.options.id\n\t };\n\t },\n\n\t createShapeVisual: function() {\n\t var options = this.options;\n\t var visualOptions = this._visualOptions(options);\n\t var visualTemplate = options.visual;\n\t var type = (options.type + \"\").toLocaleLowerCase();\n\t var shapeVisual;\n\n\t visualOptions.width = options.width;\n\t visualOptions.height = options.height;\n\n\t if (isFunction(visualTemplate)) { // custom template\n\t shapeVisual = visualTemplate.call(this, options);\n\t } else if (visualOptions.data) {\n\t shapeVisual = new Path(visualOptions);\n\t translateToOrigin(shapeVisual);\n\t } else if (type == \"rectangle\"){\n\t shapeVisual = new Rectangle(visualOptions);\n\t } else if (type == \"circle\") {\n\t shapeVisual = new Circle(visualOptions);\n\t } else if (type == \"text\") {\n\t shapeVisual = new TextBlock(visualOptions);\n\t } else if (type == \"image\") {\n\t shapeVisual = new Image(visualOptions);\n\t } else {\n\t shapeVisual = new Path(visualOptions);\n\t }\n\n\t this.shapeVisual = shapeVisual;\n\t this.visual.append(this.shapeVisual);\n\t }\n\t });\n\n\t /**\n\t * The visual link between two Shapes through the intermediate of Connectors.\n\t */\n\t var Connection = DiagramElement.extend({\n\t init: function (from, to, options) {\n\t var that = this;\n\t DiagramElement.fn.init.call(that, options);\n\t this.updateOptionsFromModel();\n\t this._initRouter();\n\t that.path = new diagram.Polyline(that.options);\n\t that.path.fill(TRANSPARENT);\n\t that.visual.append(that.path);\n\t that._sourcePoint = that._targetPoint = new Point();\n\t that._setSource(from);\n\t that._setTarget(to);\n\t that.content(that.options.content);\n\t that.definers = [];\n\t if (defined(options) && options.points) {\n\t that.points(options.points);\n\t }\n\t },\n\n\t options: {\n\t hover: {\n\t stroke: {}\n\t },\n\t startCap: NONE,\n\t endCap: NONE,\n\t points: [],\n\t selectable: true,\n\t fromConnector: AUTO,\n\t toConnector: AUTO\n\t },\n\n\t _setOptionsFromModel: function(model) {\n\t this.updateOptionsFromModel(model || this.dataItem);\n\t },\n\n\t updateOptionsFromModel: function(model) {\n\t if (this.diagram && this.diagram._isEditable) {\n\t var dataMap = this.diagram._dataMap;\n\t var options = filterConnectionDataItem(model || this.dataItem);\n\n\t if (model) {\n\t if (defined(options.from)) {\n\t var from = dataMap[options.from];\n\t if (from && defined(options.fromConnector)) {\n\t from = from.getConnector(options.fromConnector);\n\t }\n\t this.source(from);\n\t } else if (defined(options.fromX) && defined(options.fromY)) {\n\t this.source(new Point(options.fromX, options.fromY));\n\t }\n\n\t if (defined(options.to)) {\n\t var to = dataMap[options.to];\n\t if (to && defined(options.toConnector)) {\n\t to = to.getConnector(options.toConnector);\n\t }\n\t this.target(to);\n\t } else if (defined(options.toX) && defined(options.toY)) {\n\t this.target(new Point(options.toX, options.toY));\n\t }\n\n\t if (defined(options.type) && this.type() !== options.type) {\n\t this.points([]);\n\t this.type(options.type);\n\t }\n\n\t this.dataItem = model;\n\n\t this._template();\n\t this.redraw(this.options);\n\t } else {\n\t this.options = deepExtend({}, options, this.options);\n\t }\n\t }\n\t },\n\n\t updateModel: function(syncChanges) {\n\t if (this.diagram && this.diagram._isEditable) {\n\t if (this.diagram.connectionsDataSource) {\n\t var model = this.diagram.connectionsDataSource.getByUid(this.dataItem.uid);\n\n\t if (model) {\n\t this.diagram._suspendModelRefresh();\n\t if (defined(this.options.fromX) && this.options.fromX !== null) {\n\t clearField(\"from\", model);\n\t clearField(\"fromConnector\", model);\n\t model.set(\"fromX\", this.options.fromX);\n\t model.set(\"fromY\", this.options.fromY);\n\t } else {\n\t model.set(\"from\", this.options.from);\n\t if (defined(model.fromConnector)) {\n\t model.set(\"fromConnector\", this.sourceConnector ? this.sourceConnector.options.name : null);\n\t }\n\t clearField(\"fromX\", model);\n\t clearField(\"fromY\", model);\n\t }\n\n\t if (defined(this.options.toX) && this.options.toX !== null) {\n\t clearField(\"to\", model);\n\t clearField(\"toConnector\", model);\n\t model.set(\"toX\", this.options.toX);\n\t model.set(\"toY\", this.options.toY);\n\t } else {\n\t model.set(\"to\", this.options.to);\n\t if (defined(model.toConnector)) {\n\t model.set(\"toConnector\", this.targetConnector ? this.targetConnector.options.name : null);\n\t }\n\t clearField(\"toX\", model);\n\t clearField(\"toY\", model);\n\t }\n\n\t if (defined(this.options.type) && defined(model.type)) {\n\t model.set(\"type\", this.options.type);\n\t }\n\n\t this.dataItem = model;\n\t this.diagram._resumeModelRefresh();\n\n\t if (syncChanges) {\n\t this.diagram._syncConnectionChanges();\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t /**\n\t * Gets the Point where the source of the connection resides.\n\t * If the endpoint in Auto-connector the location of the resolved connector will be returned.\n\t * If the endpoint is floating the location of the endpoint is returned.\n\t */\n\t sourcePoint: function () {\n\t return this._resolvedSourceConnector ? this._resolvedSourceConnector.position() : this._sourcePoint;\n\t },\n\n\t _setSource: function(source) {\n\t var shapeSource = source instanceof Shape;\n\t var defaultConnector = this.options.fromConnector || AUTO;\n\t var dataItem;\n\t if (shapeSource && !source.getConnector(defaultConnector)) {\n\t return;\n\t }\n\n\t if (source !== undefined) {\n\t this.from = source;\n\t }\n\n\t this._removeFromSourceConnector();\n\n\t if (source === null) { // detach\n\t if (this.sourceConnector) {\n\t this._sourcePoint = (this._resolvedSourceConnector || this.sourceConnector).position();\n\t this._clearSourceConnector();\n\t this._setFromOptions(null, this._sourcePoint);\n\t }\n\t } else if (source instanceof Connector) {\n\t dataItem = source.shape.dataItem;\n\t if (dataItem) {\n\t this._setFromOptions(dataItem.id);\n\t }\n\t this.sourceConnector = source;\n\t this.sourceConnector.connections.push(this);\n\t } else if (source instanceof Point) {\n\t this._setFromOptions(null, source);\n\t this._sourcePoint = source;\n\t if (this.sourceConnector) {\n\t this._clearSourceConnector();\n\t }\n\n\t } else if (shapeSource) {\n\t dataItem = source.dataItem;\n\t if (dataItem) {\n\t this._setFromOptions(dataItem.id);\n\t }\n\n\t this.sourceConnector = source.getConnector(defaultConnector);\n\t this.sourceConnector.connections.push(this);\n\t }\n\t },\n\n\t source: function (source, undoable) {\n\t if (isDefined(source)) {\n\t if (undoable && this.diagram) {\n\t this.diagram.undoRedoService.addCompositeItem(new diagram.ConnectionEditUnit(this, source));\n\t }\n\t this._setSource(source);\n\t this.refresh();\n\t }\n\t return this.sourceConnector ? this.sourceConnector : this._sourcePoint;\n\t },\n\n\t _setFromOptions: function(from, fromPoint) {\n\t this.options.from = from;\n\t if (fromPoint) {\n\t this.options.fromX = fromPoint.x;\n\t this.options.fromY = fromPoint.y;\n\t } else {\n\t this.options.fromX = null;\n\t this.options.fromY = null;\n\t }\n\t },\n\n\t /**\n\t * Gets or sets the PathDefiner of the sourcePoint.\n\t * The left part of this definer is always null since it defines the source tangent.\n\t * @param value\n\t * @returns {*}\n\t */\n\t sourceDefiner: function (value) {\n\t if (value) {\n\t if (value instanceof diagram.PathDefiner) {\n\t value.left = null;\n\t this._sourceDefiner = value;\n\t this.source(value.point); // refresh implicit here\n\t } else {\n\t throw \"The sourceDefiner needs to be a PathDefiner.\";\n\t }\n\t } else {\n\t if (!this._sourceDefiner) {\n\t this._sourceDefiner = new diagram.PathDefiner(this.sourcePoint(), null, null);\n\t }\n\t return this._sourceDefiner;\n\t }\n\t },\n\n\t /**\n\t * Gets the Point where the target of the connection resides.\n\t */\n\t targetPoint: function () {\n\t return this._resolvedTargetConnector ? this._resolvedTargetConnector.position() : this._targetPoint;\n\t },\n\n\t _setTarget: function(target) {\n\t var shapeTarget = target instanceof Shape;\n\t var defaultConnector = this.options.toConnector || AUTO;\n\t var dataItem;\n\n\t if (shapeTarget && !target.getConnector(defaultConnector)) {\n\t return;\n\t }\n\n\t if (target !== undefined) {\n\t this.to = target;\n\t }\n\n\t this._removeFromTargetConnector();\n\n\t if (target === null) { // detach\n\t if (this.targetConnector) {\n\t this._targetPoint = (this._resolvedTargetConnector || this.targetConnector).position();\n\t this._clearTargetConnector();\n\t this._setToOptions(null, this._targetPoint);\n\t }\n\t } else if (target instanceof Connector) {\n\t dataItem = target.shape.dataItem;\n\t if (dataItem) {\n\t this._setToOptions(dataItem.id);\n\t }\n\t this.targetConnector = target;\n\t this.targetConnector.connections.push(this);\n\t } else if (target instanceof Point) {\n\t this._setToOptions(null, target);\n\t this._targetPoint = target;\n\t if (this.targetConnector) {\n\t this._clearTargetConnector();\n\t }\n\t } else if (shapeTarget) {\n\t dataItem = target.dataItem;\n\t if (dataItem) {\n\t this._setToOptions(dataItem.id);\n\t }\n\t this.targetConnector = target.getConnector(defaultConnector);\n\t this.targetConnector.connections.push(this);\n\t }\n\t },\n\n\t target: function (target, undoable) {\n\t if (isDefined(target)) {\n\t if (undoable && this.diagram) {\n\t this.diagram.undoRedoService.addCompositeItem(new diagram.ConnectionEditUnit(this, undefined, target));\n\t }\n\t this._setTarget(target);\n\n\t this.refresh();\n\t }\n\t return this.targetConnector ? this.targetConnector : this._targetPoint;\n\t },\n\n\t _setToOptions: function(to, toPoint) {\n\t this.options.to = to;\n\t if (toPoint) {\n\t this.options.toX = toPoint.x;\n\t this.options.toY = toPoint.y;\n\t } else {\n\t this.options.toX = null;\n\t this.options.toY = null;\n\t }\n\t },\n\n\t /**\n\t * Gets or sets the PathDefiner of the targetPoint.\n\t * The right part of this definer is always null since it defines the target tangent.\n\t * @param value\n\t * @returns {*}\n\t */\n\t targetDefiner: function (value) {\n\t if (value) {\n\t if (value instanceof diagram.PathDefiner) {\n\t value.right = null;\n\t this._targetDefiner = value;\n\t this.target(value.point); // refresh implicit here\n\t } else {\n\t throw \"The sourceDefiner needs to be a PathDefiner.\";\n\t }\n\t } else {\n\t if (!this._targetDefiner) {\n\t this._targetDefiner = new diagram.PathDefiner(this.targetPoint(), null, null);\n\t }\n\t return this._targetDefiner;\n\t }\n\t },\n\n\t _updateConnectors: function() {\n\t this._updateConnector(this.source(), \"source\");\n\t this._updateConnector(this.target(), \"target\");\n\t },\n\n\t _updateConnector: function(instance, name) {\n\t var that = this;\n\t var diagram = that.diagram;\n\t if (instance instanceof Connector && !diagram.getShapeById(instance.shape.id)) {\n\t var dataItem = instance.shape.dataItem;\n\t var connectorName = instance.options.name;\n\t var setNewTarget = function() {\n\t var shape = diagram._dataMap[dataItem.id];\n\t instance = shape.getConnector(connectorName);\n\t that[name](instance, false);\n\t that.updateModel();\n\t };\n\t if (diagram._dataMap[dataItem.id]) {\n\t setNewTarget();\n\t } else {\n\t var inactiveItem = diagram._inactiveShapeItems.getByUid(dataItem.uid);\n\t if (inactiveItem) {\n\t diagram._deferredConnectionUpdates.push(inactiveItem.onActivate(setNewTarget));\n\t }\n\t }\n\t } else {\n\t that[name](instance, false);\n\t }\n\t },\n\n\t content: function(content) {\n\t var result = this._content(content);\n\t if (defined(content)) {\n\t this._alignContent();\n\t }\n\t return result;\n\t },\n\n\t _createContentVisual: function(options) {\n\t var visual;\n\t if (isFunction(options.visual)) {\n\t visual = options.visual.call(this, options);\n\t } else if (options.text) {\n\t visual = new TextBlock(options);\n\t }\n\n\t if (visual) {\n\t this._contentVisual = visual;\n\t visual._includeInBBox = false;\n\t this.visual.append(visual);\n\t }\n\n\t return visual;\n\t },\n\n\t _updateContentVisual: function(options) {\n\t if (isFunction(options.visual)) {\n\t this.visual.remove(this._contentVisual);\n\t this._createContentVisual(options);\n\t } else {\n\t this._contentVisual.redraw(options);\n\t }\n\t },\n\n\t _alignContent: function() {\n\t if (this._contentVisual) {\n\t var offset = CONNECTION_CONTENT_OFFSET;\n\t var points = this.allPoints();\n\t var endIdx = math.floor(points.length / 2);\n\t var startIdx = endIdx - 1;\n\n\t while(startIdx > 0 && points[startIdx].equals(points[endIdx])) {\n\t startIdx--;\n\t endIdx++;\n\t }\n\n\t var endPoint = points[endIdx];\n\t var startPoint = points[startIdx];\n\n\t var boundingBox = this._contentVisual._measure();\n\t var width = boundingBox.width;\n\t var height = boundingBox.height;\n\t var alignToPath = points.length % 2 === 0;\n\t var distance = startPoint.distanceTo(endPoint);\n\n\t if (alignToPath && points.length > 2 && distance > 0 &&\n\t ((startPoint.y === endPoint.y && distance < width) || (startPoint.x === endPoint.x && distance < height))) {\n\t alignToPath = false;\n\t offset = 0;\n\t }\n\n\t var point;\n\n\t if (alignToPath) {\n\t var angle = draw.util.deg(math.atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x));\n\t point = new Point((endPoint.x - startPoint.x) / 2 + startPoint.x, (endPoint.y - startPoint.y) / 2 + startPoint.y);\n\n\t if (math.abs(angle) === 90) {\n\t point.x += offset;\n\t point.y-= height / 2;\n\t } else if (angle % 180 === 0) {\n\t point.x -= width / 2;\n\t point.y -= height + offset;\n\t } else if (angle < -90 || (0 < angle && angle < 90)) {\n\t point.y-= height;\n\t } else if (angle < 0 || angle > 90) {\n\t point.x -= width;\n\t point.y -= height;\n\t }\n\t } else {\n\t var midIdx = math.floor(points.length / 2);\n\t point = points[midIdx].clone();\n\t startPoint = points[midIdx - 1];\n\t endPoint = points[midIdx + 1];\n\n\t var offsetX = startPoint.x <= point.x && endPoint.x <= point.x ? offset : -boundingBox.width - offset;\n\t var offsetY = startPoint.y <= point.y && endPoint.y <= point.y ? offset : -boundingBox.height - offset;\n\n\t point.x += offsetX;\n\t point.y += offsetY;\n\t }\n\n\t this._contentVisual.position(point);\n\t }\n\t },\n\n\t /**\n\t * Selects or unselects this connections.\n\t * @param value True to select, false to unselect.\n\t */\n\t select: function (value) {\n\t var diagram = this.diagram, selected, deselected;\n\t if (this._canSelect()) {\n\t if (this.isSelected !== value) {\n\t this.isSelected = value;\n\t selected = [];\n\t deselected = [];\n\t if (this.isSelected) {\n\t this.adorner = new ConnectionEditAdorner(this, this.options.selection);\n\t diagram._adorn(this.adorner, true);\n\t diagram._selectedItems.push(this);\n\t selected.push(this);\n\t } else {\n\t if (this.adorner) {\n\t diagram._adorn(this.adorner, false);\n\t Utils.remove(diagram._selectedItems, this);\n\t this.adorner = undefined;\n\t deselected.push(this);\n\t }\n\t }\n\n\t if (this.adorner) {\n\t this.adorner.refresh();\n\t }\n\n\t if (!diagram._internalSelection) {\n\t diagram._selectionChanged(selected, deselected);\n\t }\n\t return true;\n\t }\n\t }\n\t },\n\t /**\n\t * Gets or sets the bounds of this connection.\n\t * @param value A Rect object.\n\t * @remark This is automatically set in the refresh().\n\t * @returns {Rect}\n\t */\n\t bounds: function (value) {\n\t if (value && !isString(value)) {\n\t this._bounds = value;\n\t } else {\n\t return this._bounds;\n\t }\n\t },\n\t /**\n\t * Gets or sets the connection type (see ConnectionType enumeration).\n\t * @param value A ConnectionType value.\n\t * @returns {ConnectionType}\n\t */\n\t type: function (value) {\n\t var options = this.options;\n\t if (value) {\n\t if (value !== options.type) {\n\t options.type = value;\n\t this._initRouter();\n\t this.refresh();\n\t }\n\t } else {\n\t return options.type;\n\t }\n\t },\n\n\t _initRouter: function() {\n\t var type = (this.options.type || \"\").toLowerCase();\n\t if (type == CASCADING) {\n\t this._router = new CascadingRouter(this);\n\t } else {\n\t this._router = new PolylineRouter(this);\n\t }\n\t },\n\t /**\n\t * Gets or sets the collection of *intermediate* points.\n\t * The 'allPoints()' property will return all the points.\n\t * The 'definers' property returns the definers of the intermediate points.\n\t * The 'sourceDefiner' and 'targetDefiner' return the definers of the endpoints.\n\t * @param value\n\t */\n\t points: function (value) {\n\t if (value) {\n\t this.definers = [];\n\t for (var i = 0; i < value.length; i++) {\n\t var definition = value[i];\n\t if (definition instanceof diagram.Point) {\n\t this.definers.push(new diagram.PathDefiner(definition));\n\t } else if (definition.hasOwnProperty(\"x\") && definition.hasOwnProperty(\"y\")) { // e.g. Clipboard does not preserve the Point definition and tunred into an Object\n\t this.definers.push(new diagram.PathDefiner(new Point(definition.x, definition.y)));\n\t } else {\n\t throw \"A Connection point needs to be a Point or an object with x and y properties.\";\n\t }\n\t }\n\n\t } else {\n\t var pts = [];\n\t if (isDefined(this.definers)) {\n\t for (var k = 0; k < this.definers.length; k++) {\n\t pts.push(this.definers[k].point);\n\t }\n\t }\n\t return pts;\n\t }\n\t },\n\t /**\n\t * Gets all the points of this connection. This is the combination of the sourcePoint, the points and the targetPoint.\n\t * @returns {Array}\n\t */\n\t allPoints: function () {\n\t var pts = [this.sourcePoint()];\n\t if (this.definers) {\n\t for (var k = 0; k < this.definers.length; k++) {\n\t pts.push(this.definers[k].point);\n\t }\n\t }\n\t pts.push(this.targetPoint());\n\t return pts;\n\t },\n\n\t refresh: function () {\n\t this._resolveConnectors();\n\t this._refreshPath();\n\t this._alignContent();\n\n\t if (this.adorner) {\n\t this.adorner.refresh();\n\t }\n\t },\n\n\t _resolveConnectors: function () {\n\t var connection = this,\n\t sourcePoint, targetPoint,\n\t sourceConnectors, targetConnectors,\n\t source = connection.source(),\n\t target = connection.target();\n\n\t if (source instanceof Point) {\n\t sourcePoint = source;\n\t } else if (source instanceof Connector) {\n\t if (isAutoConnector(source)) {\n\t sourceConnectors = source.shape.connectors;\n\t } else {\n\t sourceConnectors = [source];\n\t }\n\t }\n\n\t if (target instanceof Point) {\n\t targetPoint = target;\n\t } else if (target instanceof Connector) {\n\t if (isAutoConnector(target)) {\n\t targetConnectors = target.shape.connectors;\n\t } else {\n\t targetConnectors = [target];\n\t }\n\t }\n\n\t if (sourcePoint) {\n\t if (targetConnectors) {\n\t connection._resolvedTargetConnector = closestConnector(sourcePoint, targetConnectors);\n\t }\n\t } else if (sourceConnectors) {\n\t if (targetPoint) {\n\t connection._resolvedSourceConnector = closestConnector(targetPoint, sourceConnectors);\n\t } else if (targetConnectors) {\n\t this._resolveAutoConnectors(sourceConnectors, targetConnectors);\n\t }\n\t }\n\t },\n\n\t _resolveAutoConnectors: function(sourceConnectors, targetConnectors) {\n\t var minNonConflict = MAXINT;\n\t var minDist = MAXINT;\n\t var minNonConflictSource, minNonConflictTarget;\n\t var sourcePoint, targetPoint;\n\t var minSource, minTarget;\n\t var sourceConnector, targetConnector;\n\t var sourceIdx, targetIdx;\n\t var dist;\n\n\t for (sourceIdx = 0; sourceIdx < sourceConnectors.length; sourceIdx++) {\n\t sourceConnector = sourceConnectors[sourceIdx];\n\t if (!isAutoConnector(sourceConnector)) {\n\t sourcePoint = sourceConnector.position();\n\n\t for (targetIdx = 0; targetIdx < targetConnectors.length; targetIdx++) {\n\t targetConnector = targetConnectors[targetIdx];\n\t if (!isAutoConnector(targetConnector)) {\n\t targetPoint = targetConnector.position();\n\t dist = math.round(sourcePoint.distanceTo(targetPoint));\n\n\t if (dist < minNonConflict && this.diagram && this._testRoutePoints(sourcePoint, targetPoint, sourceConnector, targetConnector)) {\n\t minNonConflict = dist;\n\t minNonConflictSource = sourceConnector;\n\t minNonConflictTarget = targetConnector;\n\t }\n\n\t if (dist < minDist) {\n\t minSource = sourceConnector;\n\t minTarget = targetConnector;\n\t minDist = dist;\n\t }\n\t }\n\t }\n\t }\n\t }\n\n\t if (minNonConflictSource) {\n\t minSource = minNonConflictSource;\n\t minTarget = minNonConflictTarget;\n\t }\n\n\t this._resolvedSourceConnector = minSource;\n\t this._resolvedTargetConnector = minTarget;\n\t },\n\n\t _testRoutePoints: function(sourcePoint, targetPoint, sourceConnector, targetConnector) {\n\t var router = this._router;\n\t var passRoute = true;\n\t if (router instanceof CascadingRouter) {\n\t var points = router.routePoints(sourcePoint, targetPoint, sourceConnector, targetConnector),\n\t start, end,\n\t rect, exclude;\n\n\t exclude = this._getRouteExclude(sourcePoint, targetPoint, sourceConnector.shape, targetConnector.shape);\n\t points.unshift(sourcePoint);\n\t points.push(targetPoint);\n\n\n\t for (var idx = 1; idx < points.length; idx++) {\n\t start = points[idx - 1];\n\t end = points[idx];\n\t rect = new Rect(math.min(start.x, end.x), math.min(start.y, end.y),\n\t math.abs(start.x - end.x), math.abs(start.y - end.y));\n\t if (rect.width > 0) {\n\t rect.x++;\n\t rect.width-=2;\n\t }\n\t if (rect.height > 0) {\n\t rect.y++;\n\t rect.height-=2;\n\t }\n\n\t if (!rect.isEmpty() && this.diagram._shapesQuadTree.hitTestRect(rect, exclude)) {\n\t passRoute = false;\n\t break;\n\t }\n\t }\n\t }\n\t return passRoute;\n\t },\n\n\t _getRouteExclude: function(sourcePoint, targetPoint, sourceShape, targetShape) {\n\t var exclude = [];\n\t if (this._isPointInsideShape(sourcePoint, sourceShape)){\n\t exclude.push(sourceShape);\n\t }\n\t if (this._isPointInsideShape(targetPoint, targetShape)){\n\t exclude.push(targetShape);\n\t }\n\t return exclude;\n\t },\n\n\t _isPointInsideShape: function (point, shape) {\n\t var bounds = shape.bounds(), rotatedPoint,\n\t angle = shape.rotate().angle,\n\t pointX, pointY,\n\t boundsX = bounds.x,\n\t boundsY = bounds.y;\n\n\t rotatedPoint = point.clone().rotate(bounds.center(), angle);\n\t pointX = rotatedPoint.x;\n\t pointY = rotatedPoint.y;\n\t return pointX > boundsX && pointX < (boundsX + bounds.width) && pointY > boundsY && pointY < (boundsY + bounds.height);\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t this.options = deepExtend({}, this.options, options);\n\n\t var points = this.options.points;\n\n\t if (defined(points) && points.length > 0) {\n\t this.points(points);\n\t this._refreshPath();\n\t }\n\n\t if ((options && options.content) || options.text) {\n\t this.content(options.content);\n\t }\n\n\t this.path.redraw({\n\t fill: options.fill,\n\t stroke: options.stroke,\n\t startCap: options.startCap,\n\t endCap: options.endCap\n\t });\n\t }\n\t },\n\t /**\n\t * Returns a clone of this connection.\n\t * @returns {Connection}\n\t */\n\t clone: function () {\n\t var json = this.serialize();\n\n\t if (this.diagram && this.diagram._isEditable && defined(this.dataItem)) {\n\t json.options.dataItem = cloneDataItem(this.dataItem);\n\t }\n\n\t return new Connection(this.from, this.to, json.options);\n\t },\n\t /**\n\t * Returns a serialized connection in json format. Consist of the options and the dataItem.\n\t * @returns {Connection}\n\t */\n\t serialize: function () {\n\t var from = this.from.toJSON ? this.from.toJSON : this.from.toString(),\n\t to = this.to.toJSON ? this.to.toJSON : this.to.toString();\n\n\t var json = deepExtend({}, {\n\t options: this.options,\n\t from: from,\n\t to: to\n\t });\n\n\t if (defined(this.dataItem)) {\n\t json.dataItem = this.dataItem.toString();\n\t }\n\n\t json.options.points = this.points();\n\t return json;\n\t },\n\n\t /**\n\t * Returns whether the given Point or Rect hits this connection.\n\t * @param value\n\t * @returns {Connection}\n\t * @private\n\t */\n\t _hitTest: function (value) {\n\t if (this.visible()) {\n\t var p = new Point(value.x, value.y), from = this.sourcePoint(), to = this.targetPoint();\n\t if (value.isEmpty && !value.isEmpty() && value.contains(from) && value.contains(to)) {\n\t return this;\n\t }\n\t if (this._router.hitTest(p)) {\n\t return this;\n\t }\n\t }\n\t },\n\n\t _hover: function (value) {\n\t var color = (this.options.stroke || {}).color;\n\n\t if (value && isDefined(this.options.hover.stroke.color)) {\n\t color = this.options.hover.stroke.color;\n\t }\n\n\t this.path.redraw({\n\t stroke: {\n\t color: color\n\t }\n\t });\n\t },\n\n\t _refreshPath: function () {\n\t if (!defined(this.path)) {\n\t return;\n\t }\n\t this._drawPath();\n\t this.bounds(this._router.getBounds());\n\t },\n\n\t _drawPath: function () {\n\t if (this._router) {\n\t this._router.route(); // sets the intermediate points\n\t }\n\t var source = this.sourcePoint();\n\t var target = this.targetPoint();\n\t var points = this.points();\n\n\t this.path.redraw({\n\t points: [source].concat(points, [target])\n\t });\n\t },\n\n\t _clearSourceConnector: function () {\n\t this.sourceConnector = undefined;\n\t this._resolvedSourceConnector = undefined;\n\t },\n\n\t _clearTargetConnector: function () {\n\t this.targetConnector = undefined;\n\t this._resolvedTargetConnector = undefined;\n\t },\n\n\t _removeFromSourceConnector: function() {\n\t if (this.sourceConnector) {\n\t Utils.remove(this.sourceConnector.connections, this);\n\t }\n\t },\n\n\t _removeFromTargetConnector: function() {\n\t if (this.targetConnector) {\n\t Utils.remove(this.targetConnector.connections, this);\n\t }\n\t },\n\n\t toJSON: function() {\n\t var connection = this;\n\t var from, to, point;\n\t if (connection.from && connection.from.toJSON) {\n\t from = connection.from.toJSON();\n\t } else {\n\t point = connection._sourcePoint;\n\t from = {\n\t x: point.x,\n\t y: point.y\n\t };\n\t }\n\n\t if (connection.to && connection.to.toJSON) {\n\t to = connection.to.toJSON();\n\t } else {\n\t point = connection._targetPoint;\n\t to = {\n\t x: point.x,\n\t y: point.y\n\t };\n\t }\n\n\t return {\n\t from : from,\n\t to: to\n\t };\n\t }\n\t });\n\n\t var Diagram = Widget.extend({\n\t init: function (element, userOptions) {\n\t var that = this;\n\n\t kendo.destroy(element);\n\t Widget.fn.init.call(that, element, userOptions);\n\n\t that._initTheme();\n\n\t that._initElements();\n\t that._extendLayoutOptions(that.options);\n\t that._initDefaults(userOptions);\n\t that._interactionDefaults();\n\n\t that._initCanvas();\n\n\t that.mainLayer = new Group({\n\t id: \"main-layer\"\n\t });\n\t that.canvas.append(that.mainLayer);\n\n\t that._shapesQuadTree = new ShapesQuadTree(that);\n\n\t that._pan = new Point();\n\t that._adorners = [];\n\t that.adornerLayer = new Group({\n\t id: \"adorner-layer\"\n\t });\n\t that.canvas.append(that.adornerLayer);\n\n\t that._createHandlers();\n\n\t that._initialize();\n\n\t that._resizingAdorner = new ResizingAdorner(that, { editable: that.options.editable });\n\t that._connectorsAdorner = new ConnectorsAdorner(that);\n\n\t that._adorn(that._resizingAdorner, true);\n\t that._adorn(that._connectorsAdorner, true);\n\n\t that.selector = new Selector(that);\n\t // TODO: We may consider using real Clipboard API once is supported by the standard.\n\t that._clipboard = [];\n\n\t that.pauseMouseHandlers = false;\n\n\t that._fetchFreshData();\n\n\t that._createGlobalToolBar();\n\n\t that._createOptionElements();\n\n\t that.zoom(that.options.zoom);\n\n\t that.canvas.draw();\n\t },\n\n\t options: {\n\t name: \"Diagram\",\n\t theme: \"default\",\n\t layout: \"\",\n\t zoomRate: 0.1,\n\t zoom: 1,\n\t zoomMin: 0,\n\t zoomMax: 2,\n\t dataSource: {},\n\t draggable: true,\n\t template: \"\",\n\t autoBind: true,\n\t editable: {\n\t rotate: {},\n\t resize: {},\n\t text: true,\n\t tools: [],\n\t drag: {\n\t snap: {\n\t size: 10,\n\t angle: 10\n\t }\n\t },\n\t remove: true\n\t },\n\t pannable: {},\n\t selectable: {\n\t key: \"none\"\n\t },\n\t tooltip: { enabled: true, format: \"{0}\" },\n\t copy: {\n\t enabled: true,\n\t offsetX: 20,\n\t offsetY: 20\n\t },\n\t shapeDefaults: diagram.shapeDefaults({ undoable: true }),\n\t connectionDefaults: {\n\t editable: {\n\t tools: []\n\t },\n\t type: CASCADING\n\t },\n\t shapes: [],\n\t connections: []\n\t },\n\n\t events: [\n\t ZOOM_END,\n\t ZOOM_START,\n\t PAN, SELECT,\n\t ITEMROTATE,\n\t ITEMBOUNDSCHANGE,\n\t CHANGE,\n\t CLICK,\n\t MOUSE_ENTER,\n\t MOUSE_LEAVE,\n\t \"toolBarClick\",\n\t \"save\",\n\t \"cancel\",\n\t \"edit\",\n\t \"remove\",\n\t \"add\",\n\t \"dataBound\",\n\t DRAG_START,\n\t DRAG,\n\t DRAG_END\n\t ],\n\n\t items: function() {\n\t return $();\n\t },\n\n\t _createGlobalToolBar: function() {\n\t var editable = this.options.editable;\n\t if (editable) {\n\t var tools = editable.tools;\n\t if (this._isEditable && tools !== false && (!tools || tools.length === 0)) {\n\t tools = [\"createShape\", \"undo\", \"redo\", \"rotateClockwise\", \"rotateAnticlockwise\"];\n\t }\n\n\t if (tools && tools.length) {\n\t this.toolBar = new DiagramToolBar(this, {\n\t tools: tools || {},\n\t click: proxy(this._toolBarClick, this),\n\t modal: false\n\t });\n\n\t this.toolBar.element.css({\n\t textAlign: \"left\"\n\t });\n\n\t this.element.prepend(this.toolBar.element);\n\t this._resize();\n\t }\n\t }\n\t },\n\n\t createShape: function() {\n\t if ((this.editor && this.editor.end()) || !this.editor) {\n\t var dataSource = this.dataSource;\n\t var view = dataSource.view() || [];\n\t var index = view.length;\n\t var model = createModel(dataSource, {});\n\t var shape = this._createShape(model, {});\n\n\t if (!this.trigger(\"add\", { shape: shape })) {\n\t dataSource.insert(index, model);\n\t var inactiveItem = this._inactiveShapeItems.getByUid(model.uid);\n\t inactiveItem.element = shape;\n\t this.edit(shape);\n\t }\n\t }\n\t },\n\n\t _createShape: function(dataItem, options) {\n\t options = deepExtend({}, this.options.shapeDefaults, options);\n\t options.dataItem = dataItem;\n\t var shape = new Shape(options, this);\n\t return shape;\n\t },\n\n\t createConnection: function() {\n\t if (((this.editor && this.editor.end()) || !this.editor)) {\n\t var connectionsDataSource = this.connectionsDataSource;\n\t var view = connectionsDataSource.view() || [];\n\t var index = view.length;\n\t var model = createModel(connectionsDataSource, {});\n\t var connection = this._createConnection(model);\n\t if (!this.trigger(\"add\", { connection: connection })) {\n\t this._connectionsDataMap[model.uid] = connection;\n\t connectionsDataSource.insert(index, model);\n\t this.addConnection(connection, false);\n\t this.edit(connection);\n\t }\n\t }\n\t },\n\n\t _createConnection: function(dataItem, source, target) {\n\t var options = deepExtend({}, this.options.connectionDefaults);\n\t options.dataItem = dataItem;\n\n\t var connection = new Connection(source || new Point(), target || new Point(), options);\n\n\t return connection;\n\t },\n\n\t editModel: function(dataItem, editorType) {\n\t this.cancelEdit();\n\t var editors, template;\n\t var editable = this.options.editable;\n\n\t if (editorType == \"shape\") {\n\t editors = editable.shapeEditors;\n\t template = editable.shapeTemplate;\n\t } else if (editorType == \"connection\") {\n\t var connectionSelectorHandler = proxy(connectionSelector, this);\n\t editors = deepExtend({}, { from: connectionSelectorHandler, to: connectionSelectorHandler }, editable.connectionEditors);\n\t template = editable.connectionTemplate;\n\t } else {\n\t return;\n\t }\n\n\t this.editor = new PopupEditor(this.element, {\n\t update: proxy(this._update, this),\n\t cancel: proxy(this._cancel, this),\n\t model: dataItem,\n\t type: editorType,\n\t target: this,\n\t editors: editors,\n\t template: template\n\t });\n\n\t this.trigger(\"edit\", this._editArgs());\n\t },\n\n\t edit: function(item) {\n\t if (item.dataItem) {\n\t var editorType = item instanceof Shape ? \"shape\" : \"connection\";\n\t this.editModel(item.dataItem, editorType);\n\t }\n\t },\n\n\t cancelEdit: function() {\n\t if (this.editor) {\n\t this._getEditDataSource().cancelChanges(this.editor.model);\n\n\t this._destroyEditor();\n\t }\n\t },\n\n\t saveEdit: function() {\n\t if (this.editor && this.editor.end() &&\n\t !this.trigger(\"save\", this._editArgs())) {\n\t this._getEditDataSource().sync();\n\t }\n\t },\n\n\t _update: function() {\n\t if (this.editor && this.editor.end() &&\n\t !this.trigger(\"save\", this._editArgs())) {\n\t this._getEditDataSource().sync();\n\t this._destroyEditor();\n\t }\n\t },\n\n\t _cancel: function() {\n\t if (this.editor && !this.trigger(\"cancel\", this._editArgs())) {\n\t var model = this.editor.model;\n\t this._getEditDataSource().cancelChanges(model);\n\t var element = this._connectionsDataMap[model.uid] || this._dataMap[model.id];\n\t if (element) {\n\t element._setOptionsFromModel(model);\n\t }\n\t this._destroyEditor();\n\t }\n\t },\n\n\t _getEditDataSource: function() {\n\t return this.editor.options.type === \"shape\" ? this.dataSource : this.connectionsDataSource;\n\t },\n\n\t _editArgs: function() {\n\t var result = { container: this.editor.wrapper };\n\t result[this.editor.options.type] = this.editor.model;\n\t return result;\n\t },\n\n\t _destroyEditor: function() {\n\t if (this.editor) {\n\t this.editor.close();\n\t this.editor = null;\n\t }\n\t },\n\n\t _initElements: function() {\n\t this.wrapper = this.element.empty()\n\t .css(\"position\", \"relative\")\n\t .attr(\"tabindex\", 0)\n\t .addClass(\"k-widget k-diagram\");\n\n\t this.scrollable = $(\"
\").appendTo(this.element);\n\t },\n\n\t _initDefaults: function(userOptions) {\n\t var options = this.options;\n\t var editable = options.editable;\n\t var shapeDefaults = options.shapeDefaults;\n\t var connectionDefaults = options.connectionDefaults;\n\t var userShapeDefaults = (userOptions || {}).shapeDefaults;\n\t if (editable === false) {\n\t shapeDefaults.editable = false;\n\t connectionDefaults.editable = false;\n\t } else {\n\t copyDefaultOptions(editable, shapeDefaults.editable, [\"drag\", \"remove\", \"connect\"]);\n\t copyDefaultOptions(editable, connectionDefaults.editable, [\"drag\", \"remove\"]);\n\t }\n\n\t if (userShapeDefaults && userShapeDefaults.connectors) {\n\t options.shapeDefaults.connectors = userShapeDefaults.connectors;\n\t }\n\t },\n\n\t _interactionDefaults: function() {\n\t var options = this.options;\n\t var selectable = options.selectable;\n\t var pannable = options.pannable;\n\t var mobile = kendo.support.mobileOS;\n\n\t if (selectable && !defined(selectable.multiple)) {\n\t options.selectable = deepExtend({\n\t multiple: mobile ? false : true\n\t }, options.selectable);\n\t }\n\n\t if (pannable && !defined(pannable.key)) {\n\t options.pannable = deepExtend({\n\t key: mobile ? \"none\" : \"ctrl\"\n\t }, options.pannable);\n\t }\n\t },\n\n\t _initCanvas: function() {\n\t var canvasContainer = $(\"
\").appendTo(this.scrollable)[0];\n\t var viewPort = this.viewport();\n\t this.canvas = new Canvas(canvasContainer, {\n\t width: viewPort.width || DEFAULT_CANVAS_WIDTH,\n\t height: viewPort.height || DEFAULT_CANVAS_HEIGHT\n\t });\n\t },\n\n\t _createHandlers: function () {\n\t var that = this;\n\t var element = that.element;\n\n\t element.on(MOUSEWHEEL_NS, proxy(that._wheel, that))\n\t .on(\"keydown\" + NS, proxy(that._keydown, that));\n\n\t that._userEvents = new kendo.UserEvents(this.scrollable, {\n\t multiTouch: true,\n\t fastTap: true,\n\t tap: proxy(that._tap, that),\n\t start: proxy(that._dragStart, that),\n\t move: proxy(that._drag, that),\n\t end: proxy(that._dragEnd, that),\n\t gesturestart: proxy(that._gestureStart, that),\n\t gesturechange: proxy(that._gestureChange, that),\n\t gestureend: proxy(that._gestureEnd, that),\n\t doubleTap: proxy(that._doubleTap, that),\n\t supportDoubleTap: true\n\t });\n\n\t that.toolService = new ToolService(that);\n\n\t this.scrollable\n\t .on(\"mouseover\" + NS, proxy(that._mouseover, that))\n\t .on(\"mouseout\" + NS, proxy(that._mouseout, that))\n\t .on(\"mousemove\" + NS, proxy(that._mouseMove, that))\n\t .on(\"mousedown\" + NS, proxy(that._mouseDown, that))\n\t .on(\"mouseup\" + NS, proxy(that._mouseUp, that));\n\n\t this._syncHandler = proxy(that._syncChanges, that);\n\n\t that._resizeHandler = proxy(that.resize, that, false);\n\t kendo.onResize(that._resizeHandler);\n\n\t this.bind(ZOOM_START, proxy(that._destroyToolBar, that));\n\t this.bind(PAN, proxy(that._destroyToolBar, that));\n\t },\n\n\t _dragStart: function (e) {\n\t this._pauseMouseHandlers = true;\n\t var point = this._eventPositions(e, true);\n\n\t var event = e.event;\n\t if (this.toolService.start(point, this._meta(event))) {\n\t this._destroyToolBar();\n\t event.preventDefault();\n\t }\n\t },\n\n\t _drag: function (e) {\n\t var p = this._eventPositions(e);\n\t var event = e.event;\n\t if (this.toolService.move(p, this._meta(event))) {\n\t event.preventDefault();\n\t }\n\t },\n\n\t _dragEnd: function (e) {\n\t this._pauseMouseHandlers = false;\n\t var p = this._eventPositions(e);\n\t var event = e.event;\n\t if (this.toolService.end(p, this._meta(event))) {\n\t this._createToolBar();\n\t event.preventDefault();\n\t }\n\t },\n\n\t _mouseMove: function (e) {\n\t if (!this._pauseMouseHandlers) {\n\t var p = this._eventPositions(e);\n\t this.toolService._updateHoveredItem(p);\n\t this.toolService._updateCursor(p);\n\t }\n\t },\n\n\t _mouseDown: function () {\n\t this._pauseMouseHandlers = true;\n\t },\n\n\t _mouseUp: function () {\n\t this._pauseMouseHandlers = false;\n\t },\n\n\t _tap: function(e) {\n\t var toolService = this.toolService;\n\t var selectable = this.options.selectable;\n\t var point = this._eventPositions(e);\n\t var focused = this.focus();\n\n\t toolService._updateHoveredItem(point);\n\n\t if (toolService.hoveredItem) {\n\t var item = toolService.hoveredItem;\n\n\t this.trigger(\"click\", {\n\t item: item,\n\t point: point\n\t });\n\n\t if (selectable && item.options.selectable !== false) {\n\t var multiple = selectable.multiple !== false;\n\t var ctrlPressed = kendo.support.mobileOS || this._meta(e.event).ctrlKey;\n\n\t if (item.isSelected) {\n\t if (ctrlPressed) {\n\t this._destroyToolBar();\n\t item.select(false);\n\t } else {\n\t this._createToolBar(focused);\n\t }\n\t } else {\n\t this._destroyToolBar();\n\t this.select(item, {\n\t addToSelection: multiple && ctrlPressed\n\t });\n\t this._createToolBar(focused);\n\t }\n\t }\n\t } else if (selectable) {\n\t this._destroyToolBar();\n\t this.deselect();\n\t }\n\t },\n\n\t _keydown: function (e) {\n\t if (this.toolService.keyDown(e.keyCode, this._meta(e))) {\n\t e.preventDefault();\n\t }\n\t },\n\n\t _wheel: function (e) {\n\t var delta = mwDelta(e),\n\t p = this._eventPositions(e),\n\t meta = deepExtend(this._meta(e), { delta: delta });\n\n\t if (this.toolService.wheel(p, meta)) {\n\t e.preventDefault();\n\t }\n\t },\n\n\t _meta: function (e) {\n\t return { ctrlKey: e.ctrlKey, metaKey: e.metaKey, altKey: e.altKey, shiftKey: e.shiftKey, type: e.type };\n\t },\n\n\t _eventPositions: function (e, start) {\n\t var point;\n\t if (e.touch) {\n\t var field = start ? \"startLocation\" : \"location\";\n\t point = new Point(e.x[field], e.y[field]);\n\t } else {\n\t var event = e.originalEvent;\n\t point = new Point(event.pageX, event.pageY);\n\t }\n\n\t return this.documentToModel(point);\n\t },\n\n\t _gestureStart: function(e) {\n\t this._destroyToolBar();\n\t this.scroller.disable();\n\t var initialCenter = this.documentToModel(new Point(e.center.x, e.center.y));\n\t var eventArgs = {\n\t point: initialCenter,\n\t zoom: this.zoom()\n\t };\n\n\t if (this.trigger(ZOOM_START, eventArgs)) {\n\t return;\n\t }\n\n\t this._gesture = e;\n\t this._initialCenter = initialCenter;\n\t },\n\n\t _gestureChange: function(e) {\n\t var previousGesture = this._gesture;\n\t var initialCenter = this._initialCenter;\n\t var center = this.documentToView(new Point(e.center.x, e.center.y));\n\t var scaleDelta = e.distance / previousGesture.distance;\n\t var zoom = this._zoom;\n\t var updateZoom = false;\n\n\t if (math.abs(scaleDelta - 1) >= MOBILE_ZOOM_RATE) {\n\t this._zoom = zoom = this._getValidZoom(zoom * scaleDelta);\n\t this.options.zoom = zoom;\n\t this._gesture = e;\n\t updateZoom = true;\n\t }\n\n\t var zoomedPoint = initialCenter.times(zoom);\n\t var pan = center.minus(zoomedPoint);\n\t if (updateZoom || this._pan.distanceTo(pan) >= MOBILE_PAN_DISTANCE) {\n\t this._panTransform(pan);\n\t this._updateAdorners();\n\t }\n\n\t e.preventDefault();\n\t },\n\n\t _doubleTap: function(e) {\n\t var diagram = this;\n\t var pointPosition = this._eventPositions(e);\n\t var options = diagram.options;\n\t var zoomRate = options.zoomRate;\n\t var zoom = diagram.zoom() + zoomRate;\n\t var meta = this._meta(e);\n\t var zoomOptions = { point: pointPosition, meta: meta, zoom: zoom };\n\n\n\t if (diagram.trigger(ZOOM_START, zoomOptions)) {\n\t return;\n\t }\n\n\t zoom = kendo.dataviz.round(Math.max(options.zoomMin, Math.min(options.zoomMax, zoom)), 2);\n\t zoomOptions.zoom = zoom;\n\n\t diagram.zoom(zoom, zoomOptions);\n\t diagram.trigger(ZOOM_END, zoomOptions);\n\t },\n\n\t _gestureEnd: function() {\n\t if (this.options.pannable !== false) {\n\t this.scroller.enable();\n\t }\n\t this.trigger(ZOOM_END, {\n\t point: this._initialCenter,\n\t zoom: this.zoom()\n\t });\n\t },\n\n\t _resize: function() {\n\t var viewport = this.viewport();\n\t if (this.canvas) {\n\t this.canvas.size(viewport);\n\t }\n\n\t if (this.scrollable && this.toolBar) {\n\t this.scrollable.height(viewport.height);\n\t }\n\t },\n\n\t _mouseover: function(e) {\n\t var node = e.target._kendoNode;\n\t if (node && node.srcElement._hover) {\n\t node.srcElement._hover(true, node.srcElement);\n\t }\n\t },\n\n\t _mouseout: function(e) {\n\t var node = e.target._kendoNode;\n\t if (node && node.srcElement._hover) {\n\t node.srcElement._hover(false, node.srcElement);\n\t }\n\t },\n\n\t _initTheme: function() {\n\t var that = this;\n\t var themeName = ((that.options || {}).theme || \"\").toLowerCase();\n\t var themes = dataviz.ui.themes || {};\n\t var themeOptions;\n\n\t if(dataviz.SASS_THEMES.indexOf(themeName) != -1) {\n\t themeOptions = dataviz.autoTheme().diagram;\n\t }\n\t else {\n\t themeOptions = (themes[themeName] || {}).diagram;\n\t }\n\n\t that.options = deepExtend({}, themeOptions, that.options);\n\t if (that.options.editable === true) {\n\t deepExtend(that.options, {\n\t editable: (themeOptions || {}).editable\n\t });\n\t }\n\t },\n\n\t _createOptionElements: function() {\n\t var options = this.options;\n\t var shapesLength = options.shapes.length;\n\n\t if (shapesLength) {\n\t this._createShapes();\n\t }\n\n\t if (options.connections.length) {\n\t this._createConnections();\n\t }\n\n\t if (shapesLength && options.layout) {\n\t this.layout(options.layout);\n\t }\n\t },\n\n\t _createShapes: function() {\n\t var that = this,\n\t options = that.options,\n\t shapes = options.shapes,\n\t shape, i;\n\n\t for (i = 0; i < shapes.length; i++) {\n\t shape = shapes[i];\n\t that.addShape(shape);\n\t }\n\t },\n\n\t _createConnections: function() {\n\t var diagram = this,\n\t options = diagram.options,\n\t defaults = options.connectionDefaults,\n\t connections = options.connections,\n\t conn, source, target, i;\n\n\t for(i = 0; i < connections.length; i++) {\n\t conn = connections[i];\n\t source = diagram._findConnectionTarget(conn.from);\n\t target = diagram._findConnectionTarget(conn.to);\n\n\t diagram.connect(source, target, deepExtend({}, defaults, conn));\n\t }\n\t },\n\n\t _findConnectionTarget: function(options) {\n\t options = options || {};\n\t var diagram = this;\n\t var shapeId = isString(options) ? options : options.shapeId || options.id;\n\t var target;\n\t if (shapeId) {\n\t target = diagram.getShapeById(shapeId);\n\t if (options.connector) {\n\t target = target.getConnector(options.connector);\n\t }\n\t } else {\n\t target = new Point(options.x || 0, options.y || 0);\n\t }\n\n\t return target;\n\t },\n\n\t destroy: function () {\n\t var that = this;\n\t Widget.fn.destroy.call(that);\n\n\t if (this._userEvents) {\n\t this._userEvents.destroy();\n\t }\n\n\t kendo.unbindResize(that._resizeHandler);\n\n\t that.clear();\n\t that.element.off(NS);\n\t that.scroller.wrapper.off(NS);\n\t that.canvas.destroy(true);\n\t that.canvas = undefined;\n\n\t that._destroyEditor();\n\t that.destroyScroller();\n\t that._destroyGlobalToolBar();\n\t that._destroyToolBar();\n\t },\n\n\t destroyScroller: function () {\n\t var scroller = this.scroller;\n\n\t if (!scroller) {\n\t return;\n\t }\n\n\t scroller.destroy();\n\t scroller.element.remove();\n\t this.scroller = null;\n\t },\n\n\t save: function () {\n\t var json = {\n\t shapes: [],\n\t connections: []\n\t };\n\t var i, connection, shape;\n\n\t for (i = 0; i < this.shapes.length; i++) {\n\t shape = this.shapes[i];\n\t if (shape.options.serializable) {\n\t json.shapes.push(shape.options);\n\t }\n\t }\n\n\t for (i = 0; i < this.connections.length; i++) {\n\t connection = this.connections[i];\n\n\t json.connections.push(deepExtend({}, connection.options, connection.toJSON()));\n\t }\n\n\t return json;\n\t },\n\n\t focus: function() {\n\t if (!this.element.is(kendo._activeElement())) {\n\t var element = this.element,\n\t scrollContainer = element[0],\n\t containers = [],\n\t offsets = [],\n\t documentElement = document.documentElement,\n\t i;\n\n\t do {\n\t scrollContainer = scrollContainer.parentNode;\n\n\t if (scrollContainer.scrollHeight > scrollContainer.clientHeight) {\n\t containers.push(scrollContainer);\n\t offsets.push(scrollContainer.scrollTop);\n\t }\n\t } while (scrollContainer != documentElement);\n\n\t element.focus();\n\n\t for (i = 0; i < containers.length; i++) {\n\t containers[i].scrollTop = offsets[i];\n\t }\n\t return true;\n\t }\n\t },\n\n\t load: function(options) {\n\t this.clear();\n\n\t this.setOptions(options);\n\t this._createShapes();\n\t this._createConnections();\n\t },\n\n\t setOptions: function(options) {\n\t deepExtend(this.options, options);\n\t },\n\n\t clear: function () {\n\t var that = this;\n\n\t that.select(false);\n\t that.mainLayer.clear();\n\t that._shapesQuadTree.clear();\n\t that._initialize();\n\t },\n\t /**\n\t * Connects two items.\n\t * @param source Shape, Connector, Point.\n\t * @param target Shape, Connector, Point.\n\t * @param options Connection options that will be passed to the newly created connection.\n\t * @returns The newly created connection.\n\t */\n\t connect: function (source, target, options) {\n\t var connection;\n\t if (this.connectionsDataSource && this._isEditable) {\n\t var dataItem = this.connectionsDataSource.add({});\n\t connection = this._connectionsDataMap[dataItem.uid];\n\t connection.source(source);\n\t connection.target(target);\n\t connection.redraw(options);\n\t connection.updateModel();\n\t } else {\n\t connection = new Connection(source, target,\n\t deepExtend({ }, this.options.connectionDefaults, options));\n\n\t this.addConnection(connection);\n\t }\n\n\t return connection;\n\t },\n\t /**\n\t * Determines whether the the two items are connected.\n\t * @param source Shape, Connector, Point.\n\t * @param target Shape, Connector, Point.\n\t * @returns true if the two items are connected.\n\t */\n\t connected: function (source, target) {\n\t for (var i = 0; i < this.connections.length; i++) {\n\t var c = this.connections[i];\n\t if (c.from == source && c.to == target) {\n\t return true;\n\t }\n\t }\n\n\t return false;\n\t },\n\t /**\n\t * Adds connection to the diagram.\n\t * @param connection Connection.\n\t * @param undoable Boolean.\n\t * @returns The newly created connection.\n\t */\n\t addConnection: function (connection, undoable) {\n\t if (undoable !== false) {\n\t this.undoRedoService.add(\n\t new diagram.AddConnectionUnit(connection, this), false);\n\t }\n\n\t connection.diagram = this;\n\t connection._setOptionsFromModel();\n\t connection.refresh();\n\t this.mainLayer.append(connection.visual);\n\t this.connections.push(connection);\n\n\t this.trigger(CHANGE, {\n\t added: [connection],\n\t removed: []\n\t });\n\n\t return connection;\n\t },\n\n\t _addConnection: function (connection, undoable) {\n\t var connectionsDataSource = this.connectionsDataSource;\n\t var dataItem;\n\t if (connectionsDataSource && this._isEditable) {\n\t dataItem = createModel(connectionsDataSource, cloneDataItem(connection.dataItem));\n\t connection.dataItem = dataItem;\n\t connection.updateModel();\n\n\t if (!this.trigger(\"add\", { connection: connection })) {\n\t this._connectionsDataMap[dataItem.uid] = connection;\n\n\t connectionsDataSource.add(dataItem);\n\t this.addConnection(connection, undoable);\n\t connection._updateConnectors();\n\n\t return connection;\n\t }\n\t } else if (!this.trigger(\"add\", { connection: connection })) {\n\t this.addConnection(connection, undoable);\n\t connection._updateConnectors();\n\t return connection;\n\t }\n\t },\n\n\t /**\n\t * Adds shape to the diagram.\n\t * @param item Shape, Point. If point is passed it will be created new Shape and positioned at that point.\n\t * @param options. The options to be passed to the newly created Shape.\n\t * @returns The newly created shape.\n\t */\n\t addShape: function(item, undoable) {\n\t var shape,\n\t shapeDefaults = this.options.shapeDefaults;\n\n\t if (item instanceof Shape) {\n\t shape = item;\n\t } else if (!(item instanceof kendo.Class)) {\n\t shapeDefaults = deepExtend({}, shapeDefaults, item || {});\n\t shape = new Shape(shapeDefaults, this);\n\t } else {\n\t return;\n\t }\n\n\t if (undoable !== false) {\n\t this.undoRedoService.add(new diagram.AddShapeUnit(shape, this), false);\n\t }\n\n\t this.shapes.push(shape);\n\t if (shape.diagram !== this) {\n\t this._shapesQuadTree.insert(shape);\n\t shape.diagram = this;\n\t }\n\t this.mainLayer.append(shape.visual);\n\n\t this.trigger(CHANGE, {\n\t added: [shape],\n\t removed: []\n\t });\n\n\t return shape;\n\t },\n\n\t _addShape: function(shape, undoable) {\n\t var that = this;\n\t var dataSource = that.dataSource;\n\t var dataItem;\n\t if (dataSource && this._isEditable) {\n\t dataItem = createModel(dataSource, cloneDataItem(shape.dataItem));\n\t shape.dataItem = dataItem;\n\t shape.updateModel();\n\n\t if (!this.trigger(\"add\", { shape: shape })) {\n\t this.dataSource.add(dataItem);\n\t var inactiveItem = this._inactiveShapeItems.getByUid(dataItem.uid);\n\t inactiveItem.element = shape;\n\t inactiveItem.undoable = undoable;\n\t return shape;\n\t }\n\t } else if (!this.trigger(\"add\", { shape: shape })) {\n\t return this.addShape(shape, undoable);\n\t }\n\t },\n\t /**\n\t * Removes items (or single item) from the diagram.\n\t * @param items DiagramElement, Array of Items.\n\t * @param undoable.\n\t */\n\n\t remove: function(items, undoable) {\n\t items = isArray(items) ? items.slice(0) : [items];\n\t var elements = splitDiagramElements(items);\n\t var shapes = elements.shapes;\n\t var connections = elements.connections;\n\t var i;\n\n\t if (!defined(undoable)) {\n\t undoable = true;\n\t }\n\n\t if (undoable) {\n\t this.undoRedoService.begin();\n\t }\n\n\t this._suspendModelRefresh();\n\t for (i = shapes.length - 1; i >= 0; i--) {\n\t this._removeItem(shapes[i], undoable, connections);\n\t }\n\n\t for (i = connections.length - 1; i >= 0; i--) {\n\t this._removeItem(connections[i], undoable);\n\t }\n\n\t this._resumeModelRefresh();\n\n\t if (undoable) {\n\t this.undoRedoService.commit(false);\n\t }\n\n\t this.trigger(CHANGE, {\n\t added: [],\n\t removed: items\n\t });\n\t },\n\n\t _removeShapeDataItem: function(item) {\n\t if (this._isEditable) {\n\t this.dataSource.remove(item.dataItem);\n\t delete this._dataMap[item.dataItem.id];\n\t }\n\t },\n\n\t _removeConnectionDataItem: function(item) {\n\t if (this._isEditable) {\n\t this.connectionsDataSource.remove(item.dataItem);\n\t delete this._connectionsDataMap[item.dataItem.uid];\n\t }\n\t },\n\n\t _triggerRemove: function(items){\n\t var toRemove = [];\n\t var item, args, editable;\n\n\t for (var idx = 0; idx < items.length; idx++) {\n\t item = items[idx];\n\t editable = item.options.editable;\n\t if (item instanceof Shape) {\n\t args = { shape: item };\n\t } else {\n\t args = { connection: item };\n\t }\n\t if (editable && editable.remove !== false && !this.trigger(\"remove\", args)) {\n\t toRemove.push(item);\n\t }\n\t }\n\t return toRemove;\n\t },\n\n\t /**\n\t * Executes the next undoable action on top of the undo stack if any.\n\t */\n\t undo: function () {\n\t this.undoRedoService.undo();\n\t },\n\t /**\n\t * Executes the previous undoable action on top of the redo stack if any.\n\t */\n\t redo: function () {\n\t this.undoRedoService.redo();\n\t },\n\t /**\n\t * Selects items on the basis of the given input or returns the current selection if none.\n\t * @param itemsOrRect DiagramElement, Array of elements, \"All\", false or Rect. A value 'false' will deselect everything.\n\t * @param options\n\t * @returns {Array}\n\t */\n\t select: function (item, options) {\n\t if (isDefined(item)) {\n\t options = deepExtend({ addToSelection: false }, options);\n\n\t var addToSelection = options.addToSelection,\n\t items = [],\n\t selected = [],\n\t i, element;\n\n\t if (!addToSelection) {\n\t this.deselect();\n\t }\n\n\t this._internalSelection = true;\n\n\t if (item instanceof Array) {\n\t items = item;\n\t } else if (item instanceof DiagramElement) {\n\t items = [ item ];\n\t }\n\n\t for (i = 0; i < items.length; i++) {\n\t element = items[i];\n\t if (element.select(true)) {\n\t selected.push(element);\n\t }\n\t }\n\n\t this._selectionChanged(selected, []);\n\n\t this._internalSelection = false;\n\t } else {\n\t return this._selectedItems;\n\t }\n\t },\n\n\t selectAll: function() {\n\t this.select(this.shapes.concat(this.connections));\n\t },\n\n\t selectArea: function(rect) {\n\t var i, items, item;\n\t this._internalSelection = true;\n\t var selected = [];\n\t if (rect instanceof Rect) {\n\t items = this.shapes.concat(this.connections);\n\t for (i = 0; i < items.length; i++) {\n\t item = items[i];\n\t if ((!rect || item._hitTest(rect)) && item.options.enable) {\n\t if (item.select(true)) {\n\t selected.push(item);\n\t }\n\t }\n\t }\n\t }\n\n\t this._selectionChanged(selected, []);\n\t this._internalSelection = false;\n\t },\n\n\t deselect: function(item) {\n\t this._internalSelection = true;\n\t var deselected = [],\n\t items = [],\n\t element, i;\n\n\t if (item instanceof Array) {\n\t items = item;\n\t } else if (item instanceof DiagramElement) {\n\t items.push(item);\n\t } else if (!isDefined(item)) {\n\t items = this._selectedItems.slice(0);\n\t }\n\n\t for (i = 0; i < items.length; i++) {\n\t element = items[i];\n\t if (element.select(false)) {\n\t deselected.push(element);\n\t }\n\t }\n\n\t this._selectionChanged([], deselected);\n\t this._internalSelection = false;\n\t },\n\t /**\n\t * Brings to front the passed items.\n\t * @param items DiagramElement, Array of Items.\n\t * @param undoable. By default the action is undoable.\n\t */\n\t toFront: function (items, undoable) {\n\t if (!items) {\n\t items = this._selectedItems.slice();\n\t }\n\n\t var result = this._getDiagramItems(items), indices;\n\t if (!defined(undoable) || undoable) {\n\t indices = indicesOfItems(this.mainLayer, result.visuals);\n\t var unit = new ToFrontUnit(this, items, indices);\n\t this.undoRedoService.add(unit);\n\t } else {\n\t this.mainLayer.toFront(result.visuals);\n\t this._fixOrdering(result, true);\n\t }\n\t },\n\t /**\n\t * Sends to back the passed items.\n\t * @param items DiagramElement, Array of Items.\n\t * @param undoable. By default the action is undoable.\n\t */\n\t toBack: function (items, undoable) {\n\t if (!items) {\n\t items = this._selectedItems.slice();\n\t }\n\n\t var result = this._getDiagramItems(items), indices;\n\t if (!defined(undoable) || undoable) {\n\t indices = indicesOfItems(this.mainLayer, result.visuals);\n\t var unit = new ToBackUnit(this, items, indices);\n\t this.undoRedoService.add(unit);\n\t } else {\n\t this.mainLayer.toBack(result.visuals);\n\t this._fixOrdering(result, false);\n\t }\n\t },\n\t /**\n\t * Bring into view the passed item(s) or rectangle.\n\t * @param items DiagramElement, Array of Items, Rect.\n\t * @param options. align - controls the position of the calculated rectangle relative to the viewport.\n\t * \"Center middle\" will position the items in the center. animate - controls if the pan should be animated.\n\t */\n\t bringIntoView: function (item, options) { // jQuery|Item|Array|Rect\n\t var viewport = this.viewport();\n\t var aligner = new diagram.RectAlign(viewport);\n\t var current, rect, original, newPan;\n\n\t if (viewport.width === 0 || viewport.height === 0) {\n\t return;\n\t }\n\n\t options = deepExtend({animate: false, align: \"center middle\"}, options);\n\t if (options.align == \"none\") {\n\t options.align = \"center middle\";\n\t }\n\n\t if (item instanceof DiagramElement) {\n\t rect = item.bounds(TRANSFORMED);\n\t } else if (isArray(item)) {\n\t rect = this.boundingBox(item);\n\t } else if (item instanceof Rect) {\n\t rect = item.clone();\n\t }\n\n\t original = rect.clone();\n\n\t rect.zoom(this._zoom);\n\n\t if (rect.width > viewport.width || rect.height > viewport.height) {\n\t this._zoom = this._getValidZoom(math.min(viewport.width / original.width, viewport.height / original.height));\n\t rect = original.clone().zoom(this._zoom);\n\t }\n\n\t this._zoomMainLayer();\n\n\t current = rect.clone();\n\t aligner.align(rect, options.align);\n\n\t newPan = rect.topLeft().minus(current.topLeft());\n\t this.pan(newPan.times(-1), options.animate);\n\t },\n\n\t alignShapes: function (direction) {\n\t if (isUndefined(direction)) {\n\t direction = \"Left\";\n\t }\n\t var items = this.select(),\n\t val,\n\t item,\n\t i;\n\n\t if (items.length === 0) {\n\t return;\n\t }\n\n\t switch (direction.toLowerCase()) {\n\t case \"left\":\n\t case \"top\":\n\t val = MAX_VALUE;\n\t break;\n\t case \"right\":\n\t case \"bottom\":\n\t val = MIN_VALUE;\n\t break;\n\t }\n\n\t for (i = 0; i < items.length; i++) {\n\t item = items[i];\n\t if (item instanceof Shape) {\n\t switch (direction.toLowerCase()) {\n\t case \"left\":\n\t val = math.min(val, item.options.x);\n\t break;\n\t case \"top\":\n\t val = math.min(val, item.options.y);\n\t break;\n\t case \"right\":\n\t val = math.max(val, item.options.x);\n\t break;\n\t case \"bottom\":\n\t val = math.max(val, item.options.y);\n\t break;\n\t }\n\t }\n\t }\n\t var undoStates = [];\n\t var shapes = [];\n\t for (i = 0; i < items.length; i++) {\n\t item = items[i];\n\t if (item instanceof Shape) {\n\t shapes.push(item);\n\t undoStates.push(item.bounds());\n\t switch (direction.toLowerCase()) {\n\t case \"left\":\n\t case \"right\":\n\t item.position(new Point(val, item.options.y));\n\t break;\n\t case \"top\":\n\t case \"bottom\":\n\t item.position(new Point(item.options.x, val));\n\t break;\n\t }\n\t }\n\t }\n\t var unit = new diagram.TransformUnit(shapes, undoStates);\n\t this.undoRedoService.add(unit, false);\n\t },\n\n\t zoom: function (zoom, options) {\n\t if (zoom) {\n\t var staticPoint = options ? options.point : new diagram.Point(0, 0);\n\t // var meta = options ? options.meta : 0;\n\t zoom = this._zoom = this._getValidZoom(zoom);\n\n\t if (!isUndefined(staticPoint)) {//Viewpoint vector is constant\n\t staticPoint = new diagram.Point(math.round(staticPoint.x), math.round(staticPoint.y));\n\t var zoomedPoint = staticPoint.times(zoom);\n\t var viewportVector = this.modelToView(staticPoint);\n\t var raw = viewportVector.minus(zoomedPoint);//pan + zoomed point = viewpoint vector\n\t this._storePan(new diagram.Point(math.round(raw.x), math.round(raw.y)));\n\t }\n\n\t if (options) {\n\t options.zoom = zoom;\n\t }\n\n\t this._panTransform();\n\n\t this.canvas.surface.hideTooltip();\n\n\t this._updateAdorners();\n\t }\n\n\t return this._zoom;\n\t },\n\n\t _getPan: function(pan) {\n\t var canvas = this.canvas;\n\t if (!canvas.translate) {\n\t pan = pan.plus(this._pan);\n\t }\n\t return pan;\n\t },\n\n\t pan: function (pan, animate) {\n\t if (pan instanceof Point) {\n\t var that = this;\n\t var scroller = that.scroller;\n\t pan = that._getPan(pan);\n\t pan = pan.times(-1);\n\n\t if (animate) {\n\t scroller.animatedScrollTo(pan.x, pan.y, function() {\n\t that._updateAdorners();\n\t });\n\t } else {\n\t scroller.scrollTo(pan.x, pan.y);\n\t that._updateAdorners();\n\t }\n\t } else {\n\t return this._pan.times(-1);\n\t }\n\t },\n\n\t viewport: function () {\n\t var element = this.element;\n\t var width = element.width();\n\t var height = element.height();\n\n\t if (this.toolBar) {\n\t height -= outerHeight(this.toolBar.element);\n\t }\n\n\t return new Rect(0, 0, width, height);\n\t },\n\t copy: function () {\n\t if (this.options.copy.enabled) {\n\t this._clipboard = [];\n\t this._copyOffset = 1;\n\t for (var i = 0; i < this._selectedItems.length; i++) {\n\t var item = this._selectedItems[i];\n\t this._clipboard.push(item);\n\t }\n\t }\n\t },\n\t cut: function () {\n\t if (this.options.copy.enabled) {\n\t this._clipboard = [];\n\t this._copyOffset = 0;\n\t for (var i = 0; i < this._selectedItems.length; i++) {\n\t var item = this._selectedItems[i];\n\t this._clipboard.push(item);\n\t }\n\t this.remove(this._clipboard, true);\n\t }\n\t },\n\n\t paste: function () {\n\t if (this._clipboard.length > 0) {\n\t var item, copied, i;\n\t var mapping = {};\n\t var elements = splitDiagramElements(this._clipboard);\n\t var connections = elements.connections;\n\t var shapes = elements.shapes;\n\t var offset = {\n\t x: this._copyOffset * this.options.copy.offsetX,\n\t y: this._copyOffset * this.options.copy.offsetY\n\t };\n\t this.deselect();\n\t // first the shapes\n\t for (i = 0; i < shapes.length; i++) {\n\t item = shapes[i];\n\t copied = item.clone();\n\t mapping[item.id] = copied;\n\t copied.position(new Point(item.options.x + offset.x, item.options.y + offset.y));\n\t copied.diagram = this;\n\t copied = this._addShape(copied);\n\t if (copied) {\n\t copied.select();\n\t }\n\t }\n\t // then the connections\n\t for (i = 0; i < connections.length; i++) {\n\t item = connections[i];\n\t copied = this._addConnection(item.clone());\n\t if (copied) {\n\t this._updateCopiedConnection(copied, item, \"source\", mapping, offset);\n\t this._updateCopiedConnection(copied, item, \"target\", mapping, offset);\n\n\t copied.select(true);\n\t copied.updateModel();\n\t }\n\t }\n\n\t this._syncChanges();\n\n\t this._copyOffset += 1;\n\t }\n\t },\n\n\t _updateCopiedConnection: function(connection, sourceConnection, connectorName, mapping, offset) {\n\t var onActivate, inactiveItem, targetShape;\n\t var target = sourceConnection[connectorName]();\n\t var diagram = this;\n\t if (target instanceof Connector && mapping[target.shape.id]) {\n\t targetShape = mapping[target.shape.id];\n\t if (diagram.getShapeById(targetShape.id)) {\n\t connection[connectorName](targetShape.getConnector(target.options.name));\n\t } else {\n\t inactiveItem = diagram._inactiveShapeItems.getByUid(targetShape.dataItem.uid);\n\t if (inactiveItem) {\n\t onActivate = function(item) {\n\t targetShape = diagram._dataMap[item.id];\n\t connection[connectorName](targetShape.getConnector(target.options.name));\n\t connection.updateModel();\n\t };\n\t diagram._deferredConnectionUpdates.push(inactiveItem.onActivate(onActivate));\n\t }\n\t }\n\t } else {\n\t connection[connectorName](new Point(sourceConnection[connectorName + \"Point\"]().x + offset.x, sourceConnection[connectorName + \"Point\"]().y + offset.y));\n\t }\n\t },\n\t /**\n\t * Gets the bounding rectangle of the given items.\n\t * @param items DiagramElement, Array of elements.\n\t * @param origin Boolean. Pass 'true' if you need to get the bounding box of the shapes without their rotation offset.\n\t * @returns {Rect}\n\t */\n\t boundingBox: function (items, origin) {\n\t var rect = Rect.empty(), temp,\n\t di = isDefined(items) ? this._getDiagramItems(items) : {shapes: this.shapes};\n\t if (di.shapes.length > 0) {\n\t var item = di.shapes[0];\n\t rect = item.bounds(ROTATED);\n\t for (var i = 1; i < di.shapes.length; i++) {\n\t item = di.shapes[i];\n\t temp = item.bounds(ROTATED);\n\t if (origin === true) {\n\t temp.x -= item._rotationOffset.x;\n\t temp.y -= item._rotationOffset.y;\n\t }\n\t rect = rect.union(temp);\n\t }\n\t }\n\t return rect;\n\t },\n\n\t _containerOffset: function() {\n\t var containerOffset = this.element.offset();\n\t if (this.toolBar) {\n\t containerOffset.top += outerHeight(this.toolBar.element);\n\t }\n\t return containerOffset;\n\t },\n\n\t documentToView: function(point) {\n\t var containerOffset = this._containerOffset();\n\n\t return new Point(point.x - containerOffset.left, point.y - containerOffset.top);\n\t },\n\t viewToDocument: function(point) {\n\t var containerOffset = this._containerOffset();\n\n\t return new Point(point.x + containerOffset.left, point.y + containerOffset.top);\n\t },\n\t viewToModel: function(point) {\n\t return this._transformWithMatrix(point, this._matrixInvert);\n\t },\n\t modelToView: function(point) {\n\t return this._transformWithMatrix(point, this._matrix);\n\t },\n\t modelToLayer: function(point) {\n\t return this._transformWithMatrix(point, this._layerMatrix);\n\t },\n\t layerToModel: function(point) {\n\t return this._transformWithMatrix(point, this._layerMatrixInvert);\n\t },\n\t documentToModel: function(point) {\n\t var viewPoint = this.documentToView(point);\n\t if (!this.canvas.translate) {\n\t viewPoint.x = viewPoint.x + this.scroller.scrollLeft;\n\t viewPoint.y = viewPoint.y + this.scroller.scrollTop;\n\t }\n\t return this.viewToModel(viewPoint);\n\t },\n\t modelToDocument: function(point) {\n\t return this.viewToDocument(this.modelToView(point));\n\t },\n\t _transformWithMatrix: function(point, matrix) {\n\t var result = point;\n\t if (point instanceof Point) {\n\t if (matrix) {\n\t result = matrix.apply(point);\n\t }\n\t }\n\t else {\n\t var tl = this._transformWithMatrix(point.topLeft(), matrix),\n\t br = this._transformWithMatrix(point.bottomRight(), matrix);\n\t result = Rect.fromPoints(tl, br);\n\t }\n\t return result;\n\t },\n\n\t setDataSource: function(dataSource) {\n\t this.options.dataSource = dataSource;\n\t this._dataSource();\n\t if (this.options.autoBind) {\n\t this.dataSource.fetch();\n\t }\n\t },\n\n\t setConnectionsDataSource: function(dataSource) {\n\t this.options.connectionsDataSource = dataSource;\n\t this._connectionDataSource();\n\t if (this.options.autoBind) {\n\t this.connectionsDataSource.fetch();\n\t }\n\t },\n\n\t /**\n\t * Performs a diagram layout of the given type.\n\t * @param layoutType The layout algorithm to be applied (TreeLayout, LayeredLayout, SpringLayout).\n\t * @param options Layout-specific options.\n\t */\n\t layout: function (options) {\n\t this._layouting = true;\n\t // TODO: raise layout event?\n\t var type;\n\t if(isUndefined(options)) {\n\t options = this.options.layout;\n\t }\n\t if (isUndefined(options) || isUndefined(options.type)) {\n\t type = \"Tree\";\n\t }\n\t else {\n\t type = options.type;\n\t }\n\t var l;\n\t switch (type.toLowerCase()) {\n\t case \"tree\":\n\t l = new diagram.TreeLayout(this);\n\t break;\n\n\t case \"layered\":\n\t l = new diagram.LayeredLayout(this);\n\t break;\n\n\t case \"forcedirected\":\n\t case \"force\":\n\t case \"spring\":\n\t case \"springembedder\":\n\t l = new diagram.SpringLayout(this);\n\t break;\n\t default:\n\t throw \"Layout algorithm '\" + type + \"' is not supported.\";\n\t }\n\t var initialState = new diagram.LayoutState(this);\n\t var finalState = l.layout(options);\n\t if (finalState) {\n\t var unit = new diagram.LayoutUndoUnit(initialState, finalState, options ? options.animate : null);\n\t this.undoRedoService.add(unit);\n\t }\n\t this._layouting = false;\n\t this._redrawConnections();\n\t },\n\t /**\n\t * Gets a shape on the basis of its identifier.\n\t * @param id (string) the identifier of a shape.\n\t * @returns {Shape}\n\t */\n\t getShapeById: function (id) {\n\t var found;\n\t found = Utils.first(this.shapes, function (s) {\n\t return s.visual.id === id;\n\t });\n\t if (found) {\n\t return found;\n\t }\n\t found = Utils.first(this.connections, function (c) {\n\t return c.visual.id === id;\n\t });\n\t return found;\n\t },\n\n\t getShapeByModelId: function (id) {\n\t var shape;\n\t if (this._isEditable) {\n\t shape = this._dataMap[id];\n\t } else {\n\t shape = Utils.first(this.shapes, function(shape) {\n\t return (shape.dataItem || {}).id === id;\n\t });\n\t }\n\t return shape;\n\t },\n\n\t getShapeByModelUid: function(uid) {\n\t var shape;\n\t if (this._isEditable) {\n\t shape = Utils.first(this.shapes, function(shape) {\n\t return (shape.dataItem || {}).uid === uid;\n\t });\n\t } else {\n\t shape = this._dataMap[uid];\n\t }\n\t return shape;\n\t },\n\n\t getConnectionByModelId: function(id) {\n\t var connection;\n\t if (this.connectionsDataSource) {\n\t connection = Utils.first(this.connections, function(connection) {\n\t return (connection.dataItem || {}).id === id;\n\t });\n\t }\n\t return connection;\n\t },\n\n\t getConnectionByModelUid: function(uid) {\n\t var connection;\n\t if (this.connectionsDataSource) {\n\t connection = this._connectionsDataMap[uid];\n\t }\n\t return connection;\n\t },\n\n\t _extendLayoutOptions: function(options) {\n\t if(options.layout) {\n\t options.layout = deepExtend({}, diagram.LayoutBase.fn.defaultOptions || {}, options.layout);\n\t }\n\t },\n\n\t _selectionChanged: function (selected, deselected) {\n\t if (selected.length || deselected.length) {\n\t this.trigger(SELECT, { selected: selected, deselected: deselected });\n\t }\n\t },\n\t _getValidZoom: function (zoom) {\n\t return math.min(math.max(zoom, this.options.zoomMin), this.options.zoomMax);\n\t },\n\t _panTransform: function (pos) {\n\t var diagram = this,\n\t pan = pos || diagram._pan;\n\n\t if (diagram.canvas.translate) {\n\t diagram.scroller.scrollTo(pan.x, pan.y);\n\t diagram._zoomMainLayer();\n\t } else {\n\t diagram._storePan(pan);\n\t diagram._transformMainLayer();\n\t }\n\t },\n\n\t _finishPan: function () {\n\t this.trigger(PAN, {total: this._pan, delta: Number.NaN});\n\t },\n\t _storePan: function (pan) {\n\t this._pan = pan;\n\t this._storeViewMatrix();\n\t },\n\t _zoomMainLayer: function () {\n\t var zoom = this._zoom;\n\n\t var transform = new CompositeTransform(0, 0, zoom, zoom);\n\t transform.render(this.mainLayer);\n\t this._storeLayerMatrix(transform);\n\t this._storeViewMatrix();\n\t },\n\t _transformMainLayer: function () {\n\t var pan = this._pan,\n\t zoom = this._zoom;\n\n\t var transform = new CompositeTransform(pan.x, pan.y, zoom, zoom);\n\t transform.render(this.mainLayer);\n\t this._storeLayerMatrix(transform);\n\t this._storeViewMatrix();\n\t },\n\t _storeLayerMatrix: function(canvasTransform) {\n\t this._layerMatrix = canvasTransform.toMatrix();\n\t this._layerMatrixInvert = canvasTransform.invert().toMatrix();\n\t },\n\t _storeViewMatrix: function() {\n\t var pan = this._pan,\n\t zoom = this._zoom;\n\n\t var transform = new CompositeTransform(pan.x, pan.y, zoom, zoom);\n\t this._matrix = transform.toMatrix();\n\t this._matrixInvert = transform.invert().toMatrix();\n\t },\n\t _toIndex: function (items, indices) {\n\t var result = this._getDiagramItems(items);\n\t this.mainLayer.toIndex(result.visuals, indices);\n\t this._fixOrdering(result, false);\n\t },\n\t _fixOrdering: function (result, toFront) {\n\t var shapePos = toFront ? this.shapes.length - 1 : 0,\n\t conPos = toFront ? this.connections.length - 1 : 0,\n\t i, item;\n\t for (i = 0; i < result.shapes.length; i++) {\n\t item = result.shapes[i];\n\t Utils.remove(this.shapes, item);\n\t Utils.insert(this.shapes, item, shapePos);\n\t }\n\t for (i = 0; i < result.cons.length; i++) {\n\t item = result.cons[i];\n\t Utils.remove(this.connections, item);\n\t Utils.insert(this.connections, item, conPos);\n\t }\n\t },\n\t _getDiagramItems: function (items) {\n\t var i, result = {}, args = items;\n\t result.visuals = [];\n\t result.shapes = [];\n\t result.cons = [];\n\n\t if (!items) {\n\t args = this._selectedItems.slice();\n\t } else if (!isArray(items)) {\n\t args = [items];\n\t }\n\n\t for (i = 0; i < args.length; i++) {\n\t var item = args[i];\n\t if (item instanceof Shape) {\n\t result.shapes.push(item);\n\t result.visuals.push(item.visual);\n\t } else if (item instanceof Connection) {\n\t result.cons.push(item);\n\t result.visuals.push(item.visual);\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t _removeItem: function (item, undoable, removedConnections) {\n\t item.select(false);\n\t if (item instanceof Shape) {\n\t this._removeShapeDataItem(item);\n\t this._removeShape(item, undoable, removedConnections);\n\t } else if (item instanceof Connection) {\n\t this._removeConnectionDataItem(item);\n\t this._removeConnection(item, undoable);\n\t }\n\n\t this.mainLayer.remove(item.visual);\n\t },\n\n\t _removeShape: function (shape, undoable, removedConnections) {\n\t var i, connection, connector,\n\t sources = [], targets = [];\n\t this.toolService._removeHover();\n\n\t if (undoable) {\n\t this.undoRedoService.addCompositeItem(new DeleteShapeUnit(shape));\n\t }\n\t Utils.remove(this.shapes, shape);\n\t this._shapesQuadTree.remove(shape);\n\n\t for (i = 0; i < shape.connectors.length; i++) {\n\t connector = shape.connectors[i];\n\t for (var j = 0; j < connector.connections.length; j++) {\n\t connection = connector.connections[j];\n\t if (!removedConnections || !dataviz.inArray(connection, removedConnections)) {\n\t if (connection.sourceConnector == connector) {\n\t sources.push(connection);\n\t } else if (connection.targetConnector == connector) {\n\t targets.push(connection);\n\t }\n\t }\n\t }\n\t }\n\n\t for (i = 0; i < sources.length; i++) {\n\t sources[i].source(null, undoable);\n\t sources[i].updateModel();\n\t }\n\t for (i = 0; i < targets.length; i++) {\n\t targets[i].target(null, undoable);\n\t targets[i].updateModel();\n\t }\n\t },\n\n\t _removeConnection: function (connection, undoable) {\n\t if (connection.sourceConnector) {\n\t Utils.remove(connection.sourceConnector.connections, connection);\n\t }\n\t if (connection.targetConnector) {\n\t Utils.remove(connection.targetConnector.connections, connection);\n\t }\n\t if (undoable) {\n\t this.undoRedoService.addCompositeItem(new DeleteConnectionUnit(connection));\n\t }\n\n\t Utils.remove(this.connections, connection);\n\t },\n\n\t _removeDataItems: function(items, recursive) {\n\t var item, children, shape, idx;\n\t items = isArray(items) ? items : [items];\n\n\t while (items.length) {\n\t item = items.shift();\n\t shape = this._dataMap[item.uid];\n\t if (shape) {\n\t this._removeShapeConnections(shape);\n\t this._removeItem(shape, false);\n\t delete this._dataMap[item.uid];\n\t if (recursive && item.hasChildren && item.loaded()) {\n\t children = item.children.data();\n\t for (idx = 0; idx < children.length; idx++) {\n\t items.push(children[idx]);\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t _removeShapeConnections: function(shape) {\n\t var connections = shape.connections();\n\t var idx;\n\n\t if (connections) {\n\t for (idx = 0; idx < connections.length; idx++) {\n\t this._removeItem(connections[idx], false);\n\t }\n\t }\n\t },\n\n\t _addDataItem: function(dataItem, undoable) {\n\t if (!defined(dataItem)) {\n\t return;\n\t }\n\n\t var shape = this._dataMap[dataItem.id];\n\t if (shape) {\n\t return shape;\n\t }\n\n\t var options = deepExtend({}, this.options.shapeDefaults);\n\t options.dataItem = dataItem;\n\t shape = new Shape(options, this);\n\t this.addShape(shape, undoable !== false);\n\t this._dataMap[dataItem.id] = shape;\n\t return shape;\n\t },\n\n\t _addDataItemByUid: function(dataItem) {\n\t if (!defined(dataItem)) {\n\t return;\n\t }\n\n\t var shape = this._dataMap[dataItem.uid];\n\t if (shape) {\n\t return shape;\n\t }\n\n\t var options = deepExtend({}, this.options.shapeDefaults);\n\t options.dataItem = dataItem;\n\t shape = new Shape(options, this);\n\t this.addShape(shape);\n\t this._dataMap[dataItem.uid] = shape;\n\t return shape;\n\t },\n\n\t _addDataItems: function(items, parent) {\n\t var item, idx, shape, parentShape, connection;\n\t for (idx = 0; idx < items.length; idx++) {\n\t item = items[idx];\n\t shape = this._addDataItemByUid(item);\n\t parentShape = this._addDataItemByUid(parent);\n\t if (parentShape && !this.connected(parentShape, shape)) { // check if connected to not duplicate connections.\n\t connection = this.connect(parentShape, shape);\n\t }\n\t }\n\t },\n\n\t _refreshSource: function (e) {\n\t var that = this,\n\t node = e.node,\n\t action = e.action,\n\t items = e.items,\n\t options = that.options,\n\t idx,\n\t dataBound;\n\n\t if (e.field) {\n\t for (idx = 0; idx < items.length; idx++) {\n\t if (this._dataMap[items[idx].uid]) {\n\t this._dataMap[items[idx].uid].redrawVisual();\n\t }\n\t }\n\t return;\n\t }\n\n\t if (action == \"remove\") {\n\t this._removeDataItems(e.items, true);\n\t } else {\n\n\t if ((!action || action === \"itemloaded\") && !this._bindingRoots) {\n\t this._bindingRoots = true;\n\t dataBound = true;\n\t }\n\n\t if (!action && !node) {\n\t that.clear();\n\t }\n\n\t this._addDataItems(items, node);\n\n\t for (idx = 0; idx < items.length; idx++) {\n\t items[idx].load();\n\t }\n\t }\n\n\t if (options.layout && (dataBound || action == \"remove\" || action == \"add\")) {\n\t that.layout(options.layout);\n\t }\n\n\t if (dataBound) {\n\t this.trigger(\"dataBound\");\n\t this._bindingRoots = false;\n\t }\n\t },\n\n\t _addItem: function (item) {\n\t if (item instanceof Shape) {\n\t this.addShape(item);\n\t } else if (item instanceof Connection) {\n\t this.addConnection(item);\n\t }\n\t },\n\n\t _createToolBar: function(preventClosing) {\n\t var diagram = this.toolService.diagram;\n\n\t if (!this.singleToolBar && diagram.select().length === 1) {\n\t var element = diagram.select()[0];\n\t if (element && element.options.editable !== false) {\n\t var editable = element.options.editable;\n\t var tools = editable.tools;\n\t if (this._isEditable && tools.length === 0) {\n\t if (element instanceof Shape) {\n\t tools = [\"edit\", \"rotateClockwise\", \"rotateAnticlockwise\"];\n\t } else if (element instanceof Connection) {\n\t tools = [\"edit\"];\n\t }\n\n\t if (editable && editable.remove !== false) {\n\t tools.push(\"delete\");\n\t }\n\t }\n\n\t if (tools && tools.length) {\n\t var padding = 20;\n\t var point;\n\t this.singleToolBar = new DiagramToolBar(diagram, {\n\t tools: tools,\n\t click: proxy(this._toolBarClick, this),\n\t modal: true,\n\t popupZIndex: parseInt(diagram.element.closest(\".k-window\").css(\"zIndex\"), 10) + 10\n\t });\n\t var popupWidth = outerWidth(this.singleToolBar._popup.element);\n\t var popupHeight = outerHeight(this.singleToolBar._popup.element);\n\t if (element instanceof Shape) {\n\t var shapeBounds = this.modelToView(element.bounds(ROTATED));\n\t point = new Point(shapeBounds.x, shapeBounds.y).minus(new Point(\n\t (popupWidth - shapeBounds.width) / 2,\n\t popupHeight + padding));\n\t } else if (element instanceof Connection) {\n\t var connectionBounds = this.modelToView(element.bounds());\n\n\t point = new Point(connectionBounds.x, connectionBounds.y)\n\t .minus(new Point(\n\t (popupWidth - connectionBounds.width - 20) / 2,\n\t popupHeight + padding\n\t ));\n\t }\n\n\t if (point) {\n\t if (!this.canvas.translate) {\n\t point = point.minus(new Point(this.scroller.scrollLeft, this.scroller.scrollTop));\n\t }\n\t point = this.viewToDocument(point);\n\t point = new Point(math.max(point.x, 0), math.max(point.y, 0));\n\t this.singleToolBar.showAt(point);\n\t if (preventClosing) {\n\t this.singleToolBar._popup.one(\"close\", preventDefault);\n\t }\n\t } else {\n\t this._destroyToolBar();\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t _toolBarClick: function(e) {\n\t this.trigger(\"toolBarClick\", e);\n\t this._destroyToolBar();\n\t },\n\n\t _normalizePointZoom: function (point) {\n\t return point.times(1 / this.zoom());\n\t },\n\n\t _initialize: function () {\n\t this.shapes = [];\n\t this._selectedItems = [];\n\t this.connections = [];\n\t this._dataMap = {};\n\t this._connectionsDataMap = {};\n\t this._inactiveShapeItems = new InactiveItemsCollection();\n\t this._deferredConnectionUpdates = [];\n\t this.undoRedoService = new UndoRedoService({\n\t undone: this._syncHandler,\n\t redone: this._syncHandler\n\t });\n\t this.id = diagram.randomId();\n\t },\n\n\t _fetchFreshData: function () {\n\t var that = this;\n\t that._dataSource();\n\n\t if (that._isEditable) {\n\t that._connectionDataSource();\n\t }\n\n\t if (that.options.autoBind) {\n\t if (that._isEditable) {\n\t this._loadingShapes = true;\n\t this._loadingConnections = true;\n\t that.dataSource.fetch();\n\t that.connectionsDataSource.fetch();\n\t } else {\n\t that.dataSource.fetch();\n\t }\n\t }\n\t },\n\n\t _dataSource: function() {\n\t if (defined(this.options.connectionsDataSource)) {\n\t this._isEditable = true;\n\t var dsOptions = this.options.dataSource || {};\n\t var ds = isArray(dsOptions) ? { data: dsOptions } : dsOptions;\n\n\t if (this.dataSource && this._shapesRefreshHandler) {\n\t this.dataSource\n\t .unbind(\"change\", this._shapesRefreshHandler)\n\t .unbind(\"requestStart\", this._shapesRequestStartHandler)\n\t .unbind(\"error\", this._shapesErrorHandler);\n\t } else {\n\t this._shapesRefreshHandler = proxy(this._refreshShapes, this);\n\t this._shapesRequestStartHandler = proxy(this._shapesRequestStart, this);\n\t this._shapesErrorHandler = proxy(this._error, this);\n\t }\n\n\t this.dataSource = kendo.data.DataSource.create(ds)\n\t .bind(\"change\", this._shapesRefreshHandler)\n\t .bind(\"requestStart\", this._shapesRequestStartHandler)\n\t .bind(\"error\", this._shapesErrorHandler);\n\t } else {\n\t this._treeDataSource();\n\t this._isEditable = false;\n\t }\n\t },\n\n\t _connectionDataSource: function() {\n\t var dsOptions = this.options.connectionsDataSource;\n\t if (dsOptions) {\n\t var ds = isArray(dsOptions) ? { data: dsOptions } : dsOptions;\n\n\t if (this.connectionsDataSource && this._connectionsRefreshHandler) {\n\t this.connectionsDataSource\n\t .unbind(\"change\", this._connectionsRefreshHandler)\n\t .unbind(\"requestStart\", this._connectionsRequestStartHandler)\n\t .unbind(\"error\", this._connectionsErrorHandler);\n\t } else {\n\t this._connectionsRefreshHandler = proxy(this._refreshConnections, this);\n\t this._connectionsRequestStartHandler = proxy(this._connectionsRequestStart, this);\n\t this._connectionsErrorHandler = proxy(this._connectionsError, this);\n\t }\n\n\t this.connectionsDataSource = kendo.data.DataSource.create(ds)\n\t .bind(\"change\", this._connectionsRefreshHandler)\n\t .bind(\"requestStart\", this._connectionsRequestStartHandler)\n\t .bind(\"error\", this._connectionsErrorHandler);\n\t }\n\t },\n\n\t _shapesRequestStart: function(e) {\n\t if (e.type == \"read\") {\n\t this._loadingShapes = true;\n\t }\n\t },\n\n\t _connectionsRequestStart: function(e) {\n\t if (e.type == \"read\") {\n\t this._loadingConnections = true;\n\t }\n\t },\n\n\t _error: function () {\n\t this._loadingShapes = false;\n\t },\n\n\t _connectionsError: function() {\n\t this._loadingConnections = false;\n\t },\n\n\t _refreshShapes: function(e) {\n\t if (e.action === \"remove\") {\n\t if (this._shouldRefresh()) {\n\t this._removeShapes(e.items);\n\t }\n\t } else if (e.action === \"itemchange\") {\n\t if (this._shouldRefresh()) {\n\t this._updateShapes(e.items, e.field);\n\t }\n\t } else if (e.action === \"add\") {\n\t this._inactiveShapeItems.add(e.items);\n\t } else if (e.action === \"sync\") {\n\t this._syncShapes(e.items);\n\t } else {\n\t this.refresh();\n\t }\n\t },\n\n\t _shouldRefresh: function() {\n\t return !this._suspended;\n\t },\n\n\t _suspendModelRefresh: function() {\n\t this._suspended = (this._suspended || 0) + 1;\n\t },\n\n\t _resumeModelRefresh: function() {\n\t this._suspended = math.max((this._suspended || 0) - 1, 0);\n\t },\n\n\t refresh: function() {\n\t this._loadingShapes = false;\n\t if (!this._loadingConnections) {\n\t this._rebindShapesAndConnections();\n\t }\n\t },\n\n\t _rebindShapesAndConnections: function() {\n\t this.clear();\n\t this._addShapes(this.dataSource.view());\n\t if (this.connectionsDataSource) {\n\t this._addConnections(this.connectionsDataSource.view(), false);\n\t }\n\n\t if (this.options.layout) {\n\t this.layout(this.options.layout);\n\t } else {\n\t this._redrawConnections();\n\t }\n\t this.trigger(\"dataBound\");\n\t },\n\n\t refreshConnections: function() {\n\t this._loadingConnections = false;\n\t if (!this._loadingShapes) {\n\t this._rebindShapesAndConnections();\n\t }\n\t },\n\n\t _redrawConnections: function() {\n\t var connections = this.connections;\n\t for (var idx = 0; idx < connections.length; idx++) {\n\t connections[idx].refresh();\n\t }\n\t },\n\n\t _removeShapes: function(items) {\n\t var dataMap = this._dataMap;\n\t var item, i;\n\t for (i = 0; i < items.length; i++) {\n\t item = items[i];\n\t if (dataMap[item.id]) {\n\t this.remove(dataMap[item.id], false);\n\t dataMap[item.id] = null;\n\t }\n\t }\n\t },\n\n\t _syncShapes: function() {\n\t var diagram = this;\n\t var inactiveItems = diagram._inactiveShapeItems;\n\t inactiveItems.forEach(function(inactiveItem) {\n\t var dataItem = inactiveItem.dataItem;\n\t var shape = inactiveItem.element;\n\t if (!dataItem.isNew()) {\n\t if (shape) {\n\t shape._setOptionsFromModel();\n\t diagram.addShape(shape, inactiveItem.undoable);\n\t diagram._dataMap[dataItem.id] = shape;\n\t } else {\n\t diagram._addDataItem(dataItem);\n\t }\n\t inactiveItem.activate();\n\t inactiveItems.remove(dataItem);\n\t }\n\t });\n\t },\n\n\t _updateShapes: function(items, field) {\n\t for (var i = 0; i < items.length; i++) {\n\t var dataItem = items[i];\n\n\t var shape = this._dataMap[dataItem.id];\n\t if (shape) {\n\t shape.updateOptionsFromModel(dataItem, field);\n\t }\n\t }\n\t },\n\n\t _addShapes: function(dataItems) {\n\t for (var i = 0; i < dataItems.length; i++) {\n\t this._addDataItem(dataItems[i], false);\n\t }\n\t },\n\n\t _refreshConnections: function(e) {\n\t if (e.action === \"remove\") {\n\t if (this._shouldRefresh()) {\n\t this._removeConnections(e.items);\n\t }\n\t } else if (e.action === \"add\") {\n\t this._addConnections(e.items);\n\t } else if (e.action === \"sync\") {\n\t //TO DO: include logic to update the connections with different values returned from the server.\n\t } else if (e.action === \"itemchange\") {\n\t if (this._shouldRefresh()) {\n\t this._updateConnections(e.items);\n\t }\n\t } else {\n\t this.refreshConnections();\n\t }\n\t },\n\n\t _removeConnections: function(items) {\n\t for (var i = 0; i < items.length; i++) {\n\t this.remove(this._connectionsDataMap[items[i].uid], false);\n\t this._connectionsDataMap[items[i].uid] = null;\n\t }\n\t },\n\n\t _updateConnections: function(items) {\n\t for (var i = 0; i < items.length; i++) {\n\t var dataItem = items[i];\n\n\t var connection = this._connectionsDataMap[dataItem.uid];\n\t connection.updateOptionsFromModel(dataItem);\n\t }\n\t },\n\n\t _addConnections: function(connections, undoable) {\n\t var length = connections.length;\n\n\t for (var i = 0; i < length; i++) {\n\t var dataItem = connections[i];\n\t this._addConnectionDataItem(dataItem, undoable);\n\t }\n\t },\n\n\t _addConnectionDataItem: function(dataItem, undoable) {\n\t if (!this._connectionsDataMap[dataItem.uid]) {\n\t var from = this._validateConnector(dataItem.from);\n\t if (!defined(from) || from === null) {\n\t from = new Point(dataItem.fromX, dataItem.fromY);\n\t }\n\n\t var to = this._validateConnector(dataItem.to);\n\t if (!defined(to) || to === null) {\n\t to = new Point(dataItem.toX, dataItem.toY);\n\t }\n\n\t if (defined(from) && defined(to)) {\n\t var options = deepExtend({}, this.options.connectionDefaults);\n\t options.dataItem = dataItem;\n\t var connection = new Connection(from, to, options);\n\n\t this._connectionsDataMap[dataItem.uid] = connection;\n\t this.addConnection(connection, undoable);\n\t }\n\t }\n\t },\n\n\t _validateConnector: function(value) {\n\t var connector;\n\n\t if (defined(value) && value !== null) {\n\t connector = this._dataMap[value];\n\t }\n\n\t return connector;\n\t },\n\n\t _treeDataSource: function () {\n\t var that = this,\n\t options = that.options,\n\t dataSource = options.dataSource;\n\n\t dataSource = isArray(dataSource) ? { data: dataSource } : dataSource;\n\n\t if (dataSource instanceof kendo.data.DataSource && !(dataSource instanceof kendo.data.HierarchicalDataSource)) {\n\t throw new Error(\"Incorrect DataSource type. If a single dataSource instance is set to the diagram then it should be a HierarchicalDataSource. You should set only the options instead of an instance or a HierarchicalDataSource instance or supply connectionsDataSource as well.\");\n\t }\n\n\t if (!dataSource.fields) {\n\t dataSource.fields = [\n\t { field: \"text\" },\n\t { field: \"url\" },\n\t { field: \"spriteCssClass\" },\n\t { field: \"imageUrl\" }\n\t ];\n\t }\n\t if (that.dataSource && that._refreshHandler) {\n\t that._unbindDataSource();\n\t }\n\n\t that._refreshHandler = proxy(that._refreshSource, that);\n\t that._errorHandler = proxy(that._error, that);\n\n\t that.dataSource = HierarchicalDataSource.create(dataSource)\n\t .bind(CHANGE, that._refreshHandler)\n\t .bind(ERROR, that._errorHandler);\n\t },\n\n\t _unbindDataSource: function () {\n\t var that = this;\n\n\t that.dataSource.unbind(CHANGE, that._refreshHandler).unbind(ERROR, that._errorHandler);\n\t },\n\n\t _adorn: function (adorner, isActive) {\n\t if (isActive !== undefined && adorner) {\n\t if (isActive) {\n\t this._adorners.push(adorner);\n\t this.adornerLayer.append(adorner.visual);\n\t }\n\t else {\n\t Utils.remove(this._adorners, adorner);\n\t this.adornerLayer.remove(adorner.visual);\n\t }\n\t }\n\t },\n\n\t _showConnectors: function (shape, value) {\n\t if (value) {\n\t this._connectorsAdorner.show(shape);\n\t } else {\n\t this._connectorsAdorner.destroy();\n\t }\n\t },\n\n\t _updateAdorners: function() {\n\t var adorners = this._adorners;\n\n\t for(var i = 0; i < adorners.length; i++) {\n\t var adorner = adorners[i];\n\n\t if (adorner.refreshBounds) {\n\t adorner.refreshBounds();\n\t }\n\t adorner.refresh();\n\t }\n\t },\n\n\t _refresh: function () {\n\t for (var i = 0; i < this.connections.length; i++) {\n\t this.connections[i].refresh();\n\t }\n\t },\n\n\t _destroyToolBar: function() {\n\t if (this.singleToolBar) {\n\t this.singleToolBar.hide();\n\t this.singleToolBar.destroy();\n\t this.singleToolBar = null;\n\t }\n\t },\n\n\t _destroyGlobalToolBar: function() {\n\t if (this.toolBar) {\n\t this.toolBar.hide();\n\t this.toolBar.destroy();\n\t this.toolBar = null;\n\t }\n\t },\n\n\t exportDOMVisual: function() {\n\t var viewBox = this.canvas._viewBox;\n\t var scrollOffset = geom.transform()\n\t .translate(-viewBox.x, -viewBox.y);\n\n\t var viewRect = new geom.Rect([0, 0], [viewBox.width, viewBox.height]);\n\t var clipPath = draw.Path.fromRect(viewRect);\n\t var wrap = new draw.Group({ transform: scrollOffset });\n\t var clipWrap = new draw.Group({ clip: clipPath });\n\t var root = this.canvas.drawingElement.children[0];\n\n\t clipWrap.append(wrap);\n\n\t // Don't reparent the root\n\t wrap.children.push(root);\n\n\t return clipWrap;\n\t },\n\n\t exportVisual: function() {\n\t var scale = geom.transform().scale(1 / this._zoom);\n\t var wrap = new draw.Group({\n\t transform: scale\n\t });\n\n\t var root = this.mainLayer.drawingElement;\n\t wrap.children.push(root);\n\n\t return wrap;\n\t },\n\n\t _syncChanges: function() {\n\t this._syncShapeChanges();\n\t this._syncConnectionChanges();\n\t },\n\n\t _syncShapeChanges: function() {\n\t if (this.dataSource && this._isEditable) {\n\t this.dataSource.sync();\n\t }\n\t },\n\n\t _syncConnectionChanges: function() {\n\t var that = this;\n\t if (that.connectionsDataSource && that._isEditable) {\n\t $.when.apply($, that._deferredConnectionUpdates).then(function() {\n\t that.connectionsDataSource.sync();\n\t });\n\t that.deferredConnectionUpdates = [];\n\t }\n\t }\n\t });\n\n\t dataviz.ExportMixin.extend(Diagram.fn, true);\n\n\t if (kendo.PDFMixin) {\n\t kendo.PDFMixin.extend(Diagram.fn);\n\t }\n\n\t function filterShapeDataItem(dataItem) {\n\t var result = {};\n\n\t dataItem = dataItem || {};\n\n\t if (defined(dataItem.text) && dataItem.text !== null) {\n\t result.text = dataItem.text;\n\t }\n\n\t if (defined(dataItem.x) && dataItem.x !== null) {\n\t result.x = dataItem.x;\n\t }\n\n\t if (defined(dataItem.y) && dataItem.y !== null) {\n\t result.y = dataItem.y;\n\t }\n\n\t if (defined(dataItem.width) && dataItem.width !== null) {\n\t result.width = dataItem.width;\n\t }\n\n\t if (defined(dataItem.height) && dataItem.height !== null) {\n\t result.height = dataItem.height;\n\t }\n\n\t if (defined(dataItem.type) && dataItem.type !== null) {\n\t result.type = dataItem.type;\n\t }\n\n\t return result;\n\t }\n\n\t function filterConnectionDataItem(dataItem) {\n\t var result = {};\n\n\t dataItem = dataItem || {};\n\n\t if (defined(dataItem.text) && dataItem.text !== null) {\n\t result.content = dataItem.text;\n\t }\n\n\t if (defined(dataItem.type) && dataItem.type !== null) {\n\t result.type = dataItem.type;\n\t }\n\n\t if (defined(dataItem.from) && dataItem.from !== null) {\n\t result.from = dataItem.from;\n\t }\n\n\t if (defined(dataItem.fromConnector) && dataItem.fromConnector !== null) {\n\t result.fromConnector = dataItem.fromConnector;\n\t }\n\n\t if (defined(dataItem.fromX) && dataItem.fromX !== null) {\n\t result.fromX = dataItem.fromX;\n\t }\n\n\t if (defined(dataItem.fromY) && dataItem.fromY !== null) {\n\t result.fromY = dataItem.fromY;\n\t }\n\n\t if (defined(dataItem.to) && dataItem.to !== null) {\n\t result.to = dataItem.to;\n\t }\n\n\t if (defined(dataItem.toConnector) && dataItem.toConnector !== null) {\n\t result.toConnector = dataItem.toConnector;\n\t }\n\n\t if (defined(dataItem.toX) && dataItem.toX !== null) {\n\t result.toX = dataItem.toX;\n\t }\n\n\t if (defined(dataItem.toY) && dataItem.toY !== null) {\n\t result.toY = dataItem.toY;\n\t }\n\n\t return result;\n\t }\n\n\n\t var DiagramToolBar = kendo.Observable.extend({\n\t init: function(diagram, options) {\n\t kendo.Observable.fn.init.call(this);\n\t this.diagram = diagram;\n\t this.options = deepExtend({}, this.options, options);\n\t this._tools = [];\n\t this.createToolBar();\n\t this.createTools();\n\t this.appendTools();\n\n\t if (this.options.modal) {\n\t this.createPopup();\n\t }\n\n\t this.bind(this.events, options);\n\t },\n\n\t events: [\"click\"],\n\n\t createPopup: function() {\n\t this.container = $(\"
\").append(this.element);\n\t this._popup = this.container.kendoPopup({}).getKendoPopup();\n\t },\n\n\t appendTools: function() {\n\t for (var i = 0; i < this._tools.length; i++) {\n\t var tool = this._tools[i];\n\t if (tool.buttons && tool.buttons.length || !defined(tool.buttons)) {\n\t this._toolBar.add(tool);\n\t }\n\t }\n\t },\n\n\t createToolBar: function() {\n\t this.element = $(\"
\");\n\t this._toolBar = this.element\n\t .kendoToolBar({\n\t click: proxy(this.click, this),\n\t resizable: false\n\t }).getKendoToolBar();\n\n\t this.element.css(\"border\", \"none\");\n\t },\n\n\t createTools: function() {\n\t for (var i = 0; i < this.options.tools.length; i++) {\n\t this.createTool(this.options.tools[i]);\n\t }\n\t },\n\n\t createTool: function(tool) {\n\t if (!isPlainObject(tool)) {\n\t tool = {\n\t name: tool\n\t };\n\t }\n\t var toolName = tool.name + \"Tool\";\n\t if (this[toolName]) {\n\t this[toolName](tool);\n\t } else {\n\t this._tools.push(deepExtend({}, tool, {\n\t attributes: this._setAttributes({action: tool.name})\n\t }));\n\t }\n\t },\n\n\t showAt: function(point) {\n\t var popupZIndex = parseInt(this.options.popupZIndex, 10);\n\n\t if (this._popup) {\n\t this._popup.open(point.x, point.y);\n\n\t if (popupZIndex) {\n\t this._popup.wrapper.css(\"zIndex\", popupZIndex);\n\t }\n\t }\n\t },\n\n\t hide: function() {\n\t if (this._popup) {\n\t this._popup.close();\n\t }\n\t },\n\n\t newGroup: function() {\n\t return {\n\t type: \"buttonGroup\",\n\t buttons: []\n\t };\n\t },\n\n\t editTool: function() {\n\t this._tools.push({\n\t icon: \"edit\",\n\t showText: \"overflow\",\n\t type: \"button\",\n\t text: \"Edit\",\n\t attributes: this._setAttributes({ action: \"edit\" })\n\t });\n\t },\n\n\t deleteTool: function() {\n\t this._tools.push({\n\t icon: \"close\",\n\t showText: \"overflow\",\n\t type: \"button\",\n\t text: \"Delete\",\n\t attributes: this._setAttributes({ action: \"delete\" })\n\t });\n\t },\n\n\t rotateAnticlockwiseTool: function(options) {\n\t this._appendGroup(\"rotate\");\n\t this._rotateGroup.buttons.push({\n\t icon: \"rotate-left\",\n\t showText: \"overflow\",\n\t text: \"RotateAnticlockwise\",\n\t group: \"rotate\",\n\t attributes: this._setAttributes({ action: \"rotateAnticlockwise\", step: options.step })\n\t });\n\t },\n\n\t rotateClockwiseTool: function(options) {\n\t this._appendGroup(\"rotate\");\n\t this._rotateGroup.buttons.push({\n\t icon: \"rotate-right\",\n\t attributes: this._setAttributes({ action: \"rotateClockwise\", step: options.step }),\n\t showText: \"overflow\",\n\t text: \"RotateClockwise\",\n\t group: \"rotate\"\n\t });\n\t },\n\n\t createShapeTool: function() {\n\t this._appendGroup(\"create\");\n\t this._createGroup.buttons.push({\n\t icon: \"shape\",\n\t showText: \"overflow\",\n\t text: \"CreateShape\",\n\t group: \"create\",\n\t attributes: this._setAttributes({ action: \"createShape\" })\n\t });\n\t },\n\n\t createConnectionTool: function() {\n\t this._appendGroup(\"create\");\n\t this._createGroup.buttons.push({\n\t icon: \"connector\",\n\t showText: \"overflow\",\n\t text: \"CreateConnection\",\n\t group: \"create\",\n\t attributes: this._setAttributes({ action: \"createConnection\" })\n\t });\n\t },\n\n\t undoTool: function() {\n\t this._appendGroup(\"history\");\n\t this._historyGroup.buttons.push({\n\t icon: \"undo\",\n\t showText: \"overflow\",\n\t text: \"Undo\",\n\t group: \"history\",\n\t attributes: this._setAttributes({ action: \"undo\" })\n\t });\n\t },\n\n\t redoTool: function() {\n\t this._appendGroup(\"history\");\n\t this._historyGroup.buttons.push({\n\t icon: \"redo\",\n\t showText: \"overflow\",\n\t text: \"Redo\",\n\t group: \"history\",\n\t attributes: this._setAttributes({ action: \"redo\" })\n\t });\n\t },\n\n\t _appendGroup: function(name) {\n\t var prop = \"_\" + name + \"Group\";\n\t if (!this[prop]) {\n\t this[prop] = this.newGroup();\n\t this._tools.push(this[prop]);\n\t }\n\t },\n\n\t _setAttributes: function(attributes) {\n\t var attr = {};\n\n\t if (attributes.action) {\n\t attr[kendo.attr(\"action\")] = attributes.action;\n\t }\n\n\t if (attributes.step) {\n\t attr[kendo.attr(\"step\")] = attributes.step;\n\t }\n\n\t return attr;\n\t },\n\n\t _getAttributes: function(element) {\n\t var attr = {};\n\n\t var action = element.attr(kendo.attr(\"action\"));\n\t if (action) {\n\t attr.action = action;\n\t }\n\n\t var step = element.attr(kendo.attr(\"step\"));\n\t if (step) {\n\t attr.step = step;\n\t }\n\n\t return attr;\n\t },\n\n\t click: function(e) {\n\t var attributes = this._getAttributes($(e.target));\n\t var action = attributes.action;\n\n\t if (action && this[action]) {\n\t this[action](attributes);\n\t }\n\n\t this.trigger(\"click\", this.eventData(action, e.target));\n\t },\n\n\t eventData: function(action, target) {\n\t var elements = this.selectedElements(),\n\t length = elements.length,\n\t shapes = [], connections = [], element;\n\n\t for (var idx = 0; idx < length; idx++) {\n\t element = elements[idx];\n\t if (element instanceof Shape) {\n\t shapes.push(element);\n\t } else {\n\t connections.push(element);\n\t }\n\t }\n\n\t return {\n\t shapes: shapes,\n\t connections: connections,\n\t action: action,\n\t target: target\n\t };\n\t },\n\n\t \"delete\": function() {\n\t var diagram = this.diagram;\n\t var toRemove = diagram._triggerRemove(this.selectedElements());\n\t if (toRemove.length) {\n\t this.diagram.remove(toRemove, true);\n\t this.diagram._syncChanges();\n\t }\n\t },\n\n\t edit: function() {\n\t var selectedElemens = this.selectedElements();\n\t if (selectedElemens.length === 1) {\n\t this.diagram.edit(selectedElemens[0]);\n\t }\n\t },\n\n\t rotateClockwise: function(options) {\n\t var angle = parseFloat(options.step || 90);\n\t this._rotate(angle);\n\t },\n\n\t rotateAnticlockwise: function(options) {\n\t var angle = parseFloat(options.step || 90);\n\t this._rotate(-angle);\n\t },\n\n\t _rotate: function(angle) {\n\t var adorner = this.diagram._resizingAdorner;\n\t adorner.angle(adorner.angle() + angle);\n\t adorner.rotate();\n\t },\n\n\t selectedElements: function() {\n\t return this.diagram.select();\n\t },\n\n\t createShape: function() {\n\t this.diagram.createShape();\n\t },\n\n\t createConnection: function() {\n\t this.diagram.createConnection();\n\t },\n\n\t undo: function() {\n\t this.diagram.undo();\n\t },\n\n\t redo: function() {\n\t this.diagram.redo();\n\t },\n\n\t destroy: function() {\n\t this.diagram = null;\n\t this.element = null;\n\t this.options = null;\n\n\t if (this._toolBar) {\n\t this._toolBar.destroy();\n\t }\n\n\t if (this._popup) {\n\t this._popup.destroy();\n\t }\n\t }\n\t });\n\n\t var Editor = kendo.Observable.extend({\n\t init: function(element, options) {\n\t kendo.Observable.fn.init.call(this);\n\n\t this.options = extend(true, {}, this.options, options);\n\t this.element = element;\n\t this.model = this.options.model;\n\t this.fields = this._getFields();\n\t this._initContainer();\n\t this.createEditable();\n\t },\n\n\t options: {\n\t editors: {}\n\t },\n\n\t _initContainer: function() {\n\t this.wrapper = this.element;\n\t },\n\n\t createEditable: function() {\n\t var options = this.options;\n\n\t this.editable = new kendo.ui.Editable(this.wrapper, {\n\t fields: this.fields,\n\t target: options.target,\n\t clearContainer: false,\n\t model: this.model\n\t });\n\t },\n\n\t _isEditable: function(field) {\n\t return this.model.editable && this.model.editable(field);\n\t },\n\n\t _getFields: function() {\n\t var fields = [];\n\t var modelFields = this.model.fields;\n\n\t for (var field in modelFields) {\n\t var result = {};\n\t if (this._isEditable(field)) {\n\t var editor = this.options.editors[field];\n\t if (editor) {\n\t result.editor = editor;\n\t }\n\t result.field = field;\n\t fields.push(result);\n\t }\n\t }\n\n\t return fields;\n\t },\n\n\t end: function() {\n\t return this.editable.end();\n\t },\n\n\t destroy: function() {\n\t this.editable.destroy();\n\t this.editable.element.find(\"[\" + kendo.attr(\"container-for\") + \"]\").empty();\n\t this.model = this.wrapper = this.element = this.columns = this.editable = null;\n\t }\n\t });\n\n\t var PopupEditor = Editor.extend({\n\t init: function(element, options) {\n\t Editor.fn.init.call(this, element, options);\n\t this.bind(this.events, this.options);\n\n\t this.open();\n\t },\n\n\t events: [ \"update\", \"cancel\" ],\n\n\t options: {\n\t window: {\n\t modal: true,\n\t resizable: false,\n\t draggable: true,\n\t title: \"Edit\",\n\t visible: false\n\t }\n\t },\n\n\t _initContainer: function() {\n\t var that = this;\n\t this.wrapper = $('
')\n\t .attr(kendo.attr(\"uid\"), this.model.uid);\n\n\t var formContent = \"\";\n\n\t if (this.options.template) {\n\t formContent += this._renderTemplate();\n\t this.fields = [];\n\t } else {\n\t formContent += this._renderFields();\n\t }\n\n\t formContent += this._renderButtons();\n\n\t this.wrapper.append(\n\t $('
').append(formContent));\n\n\t this.window = new kendo.ui.Window(this.wrapper.appendTo(this.element), this.options.window);\n\t this.window.bind(\"close\", function(e) {\n\t //The bellow line is required due to: draggable window in IE, change event will be triggered while the window is closing\n\t if (e.userTriggered) {\n\t e.sender.element.focus();\n\t that._cancelClick(e);\n\t }\n\t });\n\n\t this._attachButtonEvents();\n\t },\n\n\t _renderTemplate: function() {\n\t var template = this.options.template;\n\n\t if (typeof template === \"string\") {\n\t template = kendo.unescape(template);\n\t }\n\n\t template = kendo.template(template)(this.model);\n\n\t return template;\n\t },\n\n\t _renderFields: function() {\n\t var form = \"\";\n\t for (var i = 0; i < this.fields.length; i++) {\n\t var field = this.fields[i];\n\n\t form += '
';\n\n\t if (this._isEditable(field.field)) {\n\t form += '
';\n\t }\n\t }\n\n\t return form;\n\t },\n\n\t _renderButtons: function() {\n\t var form = '
';\n\t form += this._createButton(\"update\");\n\t form += this._createButton(\"cancel\");\n\t form += '
';\n\t return form;\n\t },\n\n\t _createButton: function(name) {\n\t return kendo.template(BUTTON_TEMPLATE)(defaultButtons[name]);\n\t },\n\n\t _attachButtonEvents: function() {\n\t this._cancelClickHandler = proxy(this._cancelClick, this);\n\t this.window.element.on(CLICK + NS, \"a.k-diagram-cancel\", this._cancelClickHandler);\n\n\t this._updateClickHandler = proxy(this._updateClick, this);\n\t this.window.element.on(CLICK + NS, \"a.k-diagram-update\", this._updateClickHandler);\n\t },\n\n\t _updateClick: function(e) {\n\t e.preventDefault();\n\t this.trigger(\"update\");\n\t },\n\n\t _cancelClick: function (e) {\n\t e.preventDefault();\n\t this.trigger(\"cancel\");\n\t },\n\n\t open: function() {\n\t this.window.center().open();\n\t },\n\n\t close: function() {\n\t this.window.bind(\"deactivate\", proxy(this.destroy, this)).close();\n\t },\n\n\t destroy: function() {\n\t this.window.close().destroy();\n\t this.window.element.off(CLICK + NS, \"a.k-diagram-cancel\", this._cancelClickHandler);\n\t this.window.element.off(CLICK + NS, \"a.k-diagram-update\", this._updateClickHandler);\n\t this._cancelClickHandler = null;\n\t this._editUpdateClickHandler = null;\n\t this.window = null;\n\t Editor.fn.destroy.call(this);\n\t }\n\t });\n\n\t function connectionSelector(container, options) {\n\t var model = this.dataSource.reader.model;\n\t if (model) {\n\t var textField = model.fn.fields.text ? \"text\": model.idField;\n\t $(\"\")\n\t .appendTo(container).kendoDropDownList({\n\t dataValueField: model.idField,\n\t dataTextField: textField,\n\t dataSource: this.dataSource.data().toJSON(),\n\t optionLabel: \" \",\n\t valuePrimitive: true\n\t });\n\t }\n\t }\n\n\t function InactiveItem(dataItem) {\n\t this.dataItem = dataItem;\n\t this.callbacks = [];\n\t }\n\n\t InactiveItem.fn = InactiveItem.prototype = {\n\t onActivate: function(callback) {\n\t var deffered = $.Deferred();\n\t this.callbacks.push({\n\t callback: callback,\n\t deferred: deffered\n\t });\n\t return deffered;\n\t },\n\n\t activate: function() {\n\t var callbacks = this.callbacks;\n\t var item;\n\t for (var idx = 0; idx < callbacks.length; idx++) {\n\t item = this.callbacks[idx];\n\t item.callback(this.dataItem);\n\t item.deferred.resolve();\n\t }\n\t this.callbacks = [];\n\t }\n\t };\n\n\t function InactiveItemsCollection() {\n\t this.items = {};\n\t }\n\n\t InactiveItemsCollection.fn = InactiveItemsCollection.prototype = {\n\t add: function(items) {\n\t for(var idx = 0; idx < items.length; idx++) {\n\t this.items[items[idx].uid] = new InactiveItem(items[idx]);\n\t }\n\t },\n\n\t forEach: function(callback){\n\t for (var uid in this.items) {\n\t callback(this.items[uid]);\n\t }\n\t },\n\n\t getByUid: function(uid) {\n\t return this.items[uid];\n\t },\n\n\t remove: function(item) {\n\t delete this.items[item.uid];\n\t }\n\t };\n\n\t var QuadRoot = Class.extend({\n\t init: function() {\n\t this.shapes = [];\n\t },\n\n\t _add: function(shape, bounds) {\n\t this.shapes.push({\n\t bounds: bounds,\n\t shape: shape\n\t });\n\t shape._quadNode = this;\n\t },\n\n\t insert: function(shape, bounds) {\n\t this._add(shape, bounds);\n\t },\n\n\t remove: function(shape) {\n\t var shapes = this.shapes;\n\t var length = shapes.length;\n\n\t for (var idx = 0; idx < length; idx++) {\n\t if (shapes[idx].shape === shape) {\n\t shapes.splice(idx, 1);\n\t break;\n\t }\n\t }\n\t },\n\n\t hitTestRect: function(rect, exclude) {\n\t var shapes = this.shapes;\n\t var length = shapes.length;\n\n\t for (var i = 0; i < length; i++) {\n\t if (this._testRect(shapes[i].shape, rect) && !dataviz.inArray(shapes[i].shape, exclude)) {\n\t return true;\n\t }\n\t }\n\t },\n\n\t _testRect: function(shape, rect) {\n\t var angle = shape.rotate().angle;\n\t var bounds = shape.bounds();\n\t var hit;\n\t if (!angle) {\n\t hit = bounds.overlaps(rect);\n\t } else {\n\t hit = Intersect.rects(rect, bounds, -angle);\n\t }\n\t return hit;\n\t }\n\t });\n\n\t var QuadNode = QuadRoot.extend({\n\t init: function(rect) {\n\t QuadRoot.fn.init.call(this);\n\t this.children = [];\n\t this.rect = rect;\n\t },\n\n\t inBounds: function(rect) {\n\t var nodeRect = this.rect;\n\t var nodeBottomRight = nodeRect.bottomRight();\n\t var bottomRight = rect.bottomRight();\n\t var inBounds = nodeRect.x <= rect.x && nodeRect.y <= rect.y && bottomRight.x <= nodeBottomRight.x &&\n\t bottomRight.y <= nodeBottomRight.y;\n\t return inBounds;\n\t },\n\n\t overlapsBounds: function(rect) {\n\t return this.rect.overlaps(rect);\n\t },\n\n\t insert: function (shape, bounds) {\n\t var inserted = false;\n\t var children = this.children;\n\t var length = children.length;\n\t if (this.inBounds(bounds)) {\n\t if (!length && this.shapes.length < 4) {\n\t this._add(shape, bounds);\n\t } else {\n\t if (!length) {\n\t this._initChildren();\n\t }\n\n\t for (var idx = 0; idx < children.length; idx++) {\n\t if (children[idx].insert(shape, bounds)) {\n\t inserted = true;\n\t break;\n\t }\n\t }\n\n\t if (!inserted) {\n\t this._add(shape, bounds);\n\t }\n\t }\n\t inserted = true;\n\t }\n\n\t return inserted;\n\t },\n\n\t _initChildren: function() {\n\t var rect = this.rect,\n\t children = this.children,\n\t shapes = this.shapes,\n\t center = rect.center(),\n\t halfWidth = rect.width / 2,\n\t halfHeight = rect.height / 2,\n\t childIdx, shapeIdx;\n\n\t children.push(\n\t new QuadNode(new Rect(rect.x, rect.y, halfWidth, halfHeight)),\n\t new QuadNode(new Rect(center.x, rect.y, halfWidth, halfHeight)),\n\t new QuadNode(new Rect(rect.x, center.y, halfWidth, halfHeight)),\n\t new QuadNode(new Rect(center.x, center.y, halfWidth, halfHeight))\n\t );\n\t for (shapeIdx = shapes.length - 1; shapeIdx >= 0; shapeIdx--) {\n\t for (childIdx = 0; childIdx < children.length; childIdx++) {\n\t if (children[childIdx].insert(shapes[shapeIdx].shape, shapes[shapeIdx].bounds)) {\n\t shapes.splice(shapeIdx, 1);\n\t break;\n\t }\n\t }\n\t }\n\t },\n\n\t hitTestRect: function(rect, exclude) {\n\t var idx;\n\t var children = this.children;\n\t var length = children.length;\n\t var hit = false;\n\n\t if (this.overlapsBounds(rect)) {\n\t if (QuadRoot.fn.hitTestRect.call(this, rect, exclude)) {\n\t hit = true;\n\t } else {\n\t for (idx = 0; idx < length; idx++) {\n\t if (children[idx].hitTestRect(rect, exclude)) {\n\t hit = true;\n\t break;\n\t }\n\t }\n\t }\n\t }\n\n\t return hit;\n\t }\n\t });\n\n\t var ShapesQuadTree = Class.extend({\n\t ROOT_SIZE: 1000,\n\n\t init: function(diagram) {\n\t var boundsChangeHandler = proxy(this._boundsChange, this);\n\t diagram.bind(ITEMBOUNDSCHANGE, boundsChangeHandler);\n\t diagram.bind(ITEMROTATE, boundsChangeHandler);\n\t this.initRoots();\n\t },\n\n\t initRoots: function() {\n\t this.rootMap = {};\n\t this.root = new QuadRoot();\n\t },\n\n\t clear: function() {\n\t this.initRoots();\n\t },\n\n\t _boundsChange: function(e) {\n\t if (e.item._quadNode) {\n\t e.item._quadNode.remove(e.item);\n\t }\n\t this.insert(e.item);\n\t },\n\n\t insert: function(shape) {\n\t var bounds = shape.bounds(ROTATED);\n\t var rootSize = this.ROOT_SIZE;\n\t var sectors = this.getSectors(bounds);\n\t var x = sectors[0][0];\n\t var y = sectors[1][0];\n\n\t if (this.inRoot(sectors)) {\n\t this.root.insert(shape, bounds);\n\t } else {\n\t if (!this.rootMap[x]) {\n\t this.rootMap[x] = {};\n\t }\n\n\t if (!this.rootMap[x][y]) {\n\t this.rootMap[x][y] = new QuadNode(\n\t new Rect(x * rootSize, y * rootSize, rootSize, rootSize)\n\t );\n\t }\n\n\t this.rootMap[x][y].insert(shape, bounds);\n\t }\n\t },\n\n\t remove: function(shape) {\n\t if (shape._quadNode) {\n\t shape._quadNode.remove(shape);\n\t }\n\t },\n\n\t inRoot: function(sectors) {\n\t return sectors[0].length > 1 || sectors[1].length > 1;\n\t },\n\n\t getSectors: function(rect) {\n\t var rootSize = this.ROOT_SIZE;\n\t var bottomRight = rect.bottomRight();\n\t var bottomX = math.floor(bottomRight.x / rootSize);\n\t var bottomY = math.floor(bottomRight.y / rootSize);\n\t var sectors = [[],[]];\n\t for (var x = math.floor(rect.x / rootSize); x <= bottomX; x++) {\n\t sectors[0].push(x);\n\t }\n\t for (var y = math.floor(rect.y / rootSize); y <= bottomY; y++) {\n\t sectors[1].push(y);\n\t }\n\t return sectors;\n\t },\n\n\t hitTestRect: function(rect, exclude) {\n\t var sectors = this.getSectors(rect);\n\t var xIdx, yIdx, x, y;\n\t var root;\n\n\t if (this.root.hitTestRect(rect, exclude)) {\n\t return true;\n\t }\n\n\t for (xIdx = 0; xIdx < sectors[0].length; xIdx++) {\n\t x = sectors[0][xIdx];\n\t for (yIdx = 0; yIdx < sectors[1].length; yIdx++) {\n\t y = sectors[1][yIdx];\n\t root = (this.rootMap[x] || {})[y];\n\t if (root && root.hitTestRect(rect, exclude)) {\n\t return true;\n\t }\n\t }\n\t }\n\n\t return false;\n\t }\n\t });\n\n\t function cloneDataItem(dataItem) {\n\t var result = dataItem;\n\t if (dataItem instanceof kendo.data.Model) {\n\t result = dataItem.toJSON();\n\t result[dataItem.idField] = dataItem._defaultId;\n\t }\n\t return result;\n\t }\n\n\t function splitDiagramElements(elements) {\n\t var connections = [];\n\t var shapes = [];\n\t var element, idx;\n\t for (idx = 0; idx < elements.length; idx++) {\n\t element = elements[idx];\n\t if (element instanceof Shape) {\n\t shapes.push(element);\n\t } else {\n\t connections.push(element);\n\t }\n\t }\n\t return {\n\t shapes: shapes,\n\t connections: connections\n\t };\n\t }\n\n\t function createModel(dataSource, model) {\n\t if (dataSource.reader.model) {\n\t return new dataSource.reader.model(model);\n\t }\n\n\t return new kendo.data.ObservableObject(model);\n\t }\n\n\t function clearField(field, model) {\n\t if (defined(model[field])) {\n\t model.set(field, null);\n\t }\n\t }\n\n\t function copyDefaultOptions(mainOptions, elementOptions, fields) {\n\t var field;\n\t for (var idx = 0; idx < fields.length; idx++) {\n\t field = fields[idx];\n\t if (elementOptions && !defined(elementOptions[field])) {\n\t elementOptions[field] = mainOptions[field];\n\t }\n\t }\n\t }\n\n\t function translateToOrigin(visual) {\n\t var bbox = visual.drawingContainer().clippedBBox(null);\n\t if (bbox.origin.x !== 0 || bbox.origin.y !== 0) {\n\t visual.position(-bbox.origin.x, -bbox.origin.y);\n\t }\n\t }\n\n\t function preventDefault(e) {\n\t e.preventDefault();\n\t }\n\n\t dataviz.ui.plugin(Diagram);\n\n\t deepExtend(diagram, {\n\t Shape: Shape,\n\t Connection: Connection,\n\t Connector: Connector,\n\t DiagramToolBar: DiagramToolBar,\n\t QuadNode: QuadNode,\n\t QuadRoot: QuadRoot,\n\t ShapesQuadTree: ShapesQuadTree,\n\t PopupEditor: PopupEditor\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 869:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dropdownlist\");\n\n/***/ }),\n\n/***/ 870:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.draganddrop\");\n\n/***/ }),\n\n/***/ 871:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.toolbar\");\n\n/***/ }),\n\n/***/ 872:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.editable\");\n\n/***/ }),\n\n/***/ 873:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.window\");\n\n/***/ }),\n\n/***/ 874:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./svg\");\n\n/***/ }),\n\n/***/ 875:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./services\");\n\n/***/ }),\n\n/***/ 876:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./layout\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(877);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 877:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(878) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t diagram = kendo.dataviz.diagram,\n\t Graph = diagram.Graph,\n\t Node = diagram.Node,\n\t Link = diagram.Link,\n\t deepExtend = kendo.deepExtend,\n\t Size = diagram.Size,\n\t Rect = diagram.Rect,\n\t Dictionary = diagram.Dictionary,\n\t Set = diagram.Set,\n\t HyperTree = diagram.Graph,\n\t Utils = diagram.Utils,\n\t Point = diagram.Point,\n\t EPSILON = 1e-06,\n\t DEG_TO_RAD = Math.PI / 180,\n\t contains = Utils.contains,\n\t grep = $.grep;\n\n\t /**\n\t * Base class for layout algorithms.\n\t * @type {*}\n\t */\n\t var LayoutBase = kendo.Class.extend({\n\t defaultOptions: {\n\t type: \"Tree\",\n\t subtype: \"Down\",\n\t roots: null,\n\t animate: false,\n\t //-------------------------------------------------------------------\n\t /**\n\t * Force-directed option: whether the motion of the nodes should be limited by the boundaries of the diagram surface.\n\t */\n\t limitToView: false,\n\t /**\n\t * Force-directed option: the amount of friction applied to the motion of the nodes.\n\t */\n\t friction: 0.9,\n\t /**\n\t * Force-directed option: the optimal distance between nodes (minimum energy).\n\t */\n\t nodeDistance: 50,\n\t /**\n\t * Force-directed option: the number of time things are being calculated.\n\t */\n\t iterations: 300,\n\t //-------------------------------------------------------------------\n\t /**\n\t * Tree option: the separation in one direction (depends on the subtype what direction this is).\n\t */\n\t horizontalSeparation: 90,\n\t /**\n\t * Tree option: the separation in the complementary direction (depends on the subtype what direction this is).\n\t */\n\t verticalSeparation: 50,\n\n\t //-------------------------------------------------------------------\n\t /**\n\t * Tip-over tree option: children-to-parent vertical distance.\n\t */\n\t underneathVerticalTopOffset: 15,\n\t /**\n\t * Tip-over tree option: children-to-parent horizontal distance.\n\t */\n\t underneathHorizontalOffset: 15,\n\t /**\n\t * Tip-over tree option: leaf-to-next-branch vertical distance.\n\t */\n\t underneathVerticalSeparation: 15,\n\t //-------------------------------------------------------------------\n\t /**\n\t * Settings object to organize the different components of the diagram in a grid layout structure\n\t */\n\t grid: {\n\t /**\n\t * The width of the grid in which components are arranged. Beyond this width a component will be on the next row.\n\t */\n\t width: 1500,\n\t /**\n\t * The left offset of the grid.\n\t */\n\t offsetX: 50,\n\t /**\n\t * The top offset of the grid.\n\t */\n\t offsetY: 50,\n\t /**\n\t * The horizontal padding within a cell of the grid where a single component resides.\n\t */\n\t componentSpacingX: 20,\n\t /**\n\t * The vertical padding within a cell of the grid where a single component resides.\n\t */\n\t componentSpacingY: 20\n\t },\n\n\t //-------------------------------------------------------------------\n\t /**\n\t * Layered option: the separation height/width between the layers.\n\t */\n\t layerSeparation: 50,\n\t /**\n\t * Layered option: how many rounds of shifting and fine-tuning.\n\t */\n\t layeredIterations: 2,\n\t /**\n\t * Tree-radial option: the angle at which the layout starts.\n\t */\n\t startRadialAngle: 0,\n\t /**\n\t * Tree-radial option: the angle at which the layout starts.\n\t */\n\t endRadialAngle: 360,\n\t /**\n\t * Tree-radial option: the separation between levels.\n\t */\n\t radialSeparation: 150,\n\t /**\n\t * Tree-radial option: the separation between the root and the first level.\n\t */\n\t radialFirstLevelSeparation: 200,\n\t /**\n\t * Tree-radial option: whether a virtual roots bing the components in one radial layout.\n\t */\n\t keepComponentsInOneRadialLayout: false,\n\t //-------------------------------------------------------------------\n\n\t // TODO: ensure to change this to false when containers are around\n\t ignoreContainers: true,\n\t layoutContainerChildren: false,\n\t ignoreInvisible: true,\n\t animateTransitions: false\n\t },\n\t init: function () {\n\t },\n\n\t /**\n\t * Organizes the components in a grid.\n\t * Returns the final set of nodes (not the Graph).\n\t * @param components\n\t */\n\t gridLayoutComponents: function (components) {\n\t if (!components) {\n\t throw \"No components supplied.\";\n\t }\n\n\t // calculate and cache the bounds of the components\n\t Utils.forEach(components, function (c) {\n\t c.calcBounds();\n\t });\n\n\t // order by decreasing width\n\t components.sort(function (a, b) {\n\t return b.bounds.width - a.bounds.width;\n\t });\n\n\t var maxWidth = this.options.grid.width,\n\t offsetX = this.options.grid.componentSpacingX,\n\t offsetY = this.options.grid.componentSpacingY,\n\t height = 0,\n\t startX = this.options.grid.offsetX,\n\t startY = this.options.grid.offsetY,\n\t x = startX,\n\t y = startY,\n\t i,\n\t resultLinkSet = [],\n\t resultNodeSet = [];\n\n\t while (components.length > 0) {\n\t if (x >= maxWidth) {\n\t // start a new row\n\t x = startX;\n\t y += height + offsetY;\n\t // reset the row height\n\t height = 0;\n\t }\n\t var component = components.pop();\n\t this.moveToOffset(component, new Point(x, y));\n\t for (i = 0; i < component.nodes.length; i++) {\n\t resultNodeSet.push(component.nodes[i]); // to be returned in the end\n\t }\n\t for (i = 0; i < component.links.length; i++) {\n\t resultLinkSet.push(component.links[i]);\n\t }\n\t var boundingRect = component.bounds;\n\t var currentHeight = boundingRect.height;\n\t if (currentHeight <= 0 || isNaN(currentHeight)) {\n\t currentHeight = 0;\n\t }\n\t var currentWidth = boundingRect.width;\n\t if (currentWidth <= 0 || isNaN(currentWidth)) {\n\t currentWidth = 0;\n\t }\n\n\t if (currentHeight >= height) {\n\t height = currentHeight;\n\t }\n\t x += currentWidth + offsetX;\n\t }\n\n\t return {\n\t nodes: resultNodeSet,\n\t links: resultLinkSet\n\t };\n\t },\n\n\t moveToOffset: function (component, p) {\n\t var i, j,\n\t bounds = component.bounds,\n\t deltax = p.x - bounds.x,\n\t deltay = p.y - bounds.y;\n\n\t for (i = 0; i < component.nodes.length; i++) {\n\t var node = component.nodes[i];\n\t var nodeBounds = node.bounds();\n\t if (nodeBounds.width === 0 && nodeBounds.height === 0 && nodeBounds.x === 0 && nodeBounds.y === 0) {\n\t nodeBounds = new Rect(0, 0, 0, 0);\n\t }\n\t nodeBounds.x += deltax;\n\t nodeBounds.y += deltay;\n\t node.bounds(nodeBounds);\n\t }\n\t for (i = 0; i < component.links.length; i++) {\n\t var link = component.links[i];\n\t if (link.points) {\n\t var newpoints = [];\n\t var points = link.points;\n\t for (j = 0; j < points.length; j++) {\n\t var pt = points[j];\n\t pt.x += deltax;\n\t pt.y += deltay;\n\t newpoints.push(pt);\n\t }\n\t link.points = newpoints;\n\t }\n\t }\n\t this.currentHorizontalOffset += bounds.width + this.options.grid.offsetX;\n\t return new Point(deltax, deltay);\n\t },\n\n\t transferOptions: function (options) {\n\n\t // Size options lead to stackoverflow and need special handling\n\n\t this.options = kendo.deepExtend({}, this.defaultOptions);\n\t if (Utils.isUndefined(options)) {\n\t return;\n\t }\n\n\t this.options = kendo.deepExtend(this.options, options || {});\n\t }\n\t });\n\n\t /**\n\t * The data bucket a hypertree holds in its nodes. *\n\t * @type {*}\n\t */\n\t /* var ContainerGraph = kendo.Class.extend({\n\t init: function (diagram) {\n\t this.diagram = diagram;\n\t this.graph = new Graph(diagram);\n\t this.container = null;\n\t this.containerNode = null;\n\t }\n\n\t });*/\n\n\t /**\n\t * Adapter between the diagram control and the graph representation. It converts shape and connections to nodes and edges taking into the containers and their collapsef state,\n\t * the visibility of items and more. If the layoutContainerChildren is true a hypertree is constructed which holds the hierarchy of containers and many conditions are analyzed\n\t * to investigate how the effective graph structure looks like and how the layout has to be performed.\n\t * @type {*}\n\t */\n\t var DiagramToHyperTreeAdapter = kendo.Class.extend({\n\t init: function (diagram) {\n\n\t /**\n\t * The mapping to/from the original nodes.\n\t * @type {Dictionary}\n\t */\n\t this.nodeMap = new Dictionary();\n\n\t /**\n\t * Gets the mapping of a shape to a container in case the shape sits in a collapsed container.\n\t * @type {Dictionary}\n\t */\n\t this.shapeMap = new Dictionary();\n\n\t /**\n\t * The nodes being mapped.\n\t * @type {Dictionary}\n\t */\n\t this.nodes = [];\n\n\t /**\n\t * The connections being mapped.\n\t * @type {Dictionary}\n\t */\n\t this.edges = [];\n\n\t // the mapping from an edge to all the connections it represents, this can be both because of multiple connections between\n\t // two shapes or because a container holds multiple connections to another shape or container.\n\t this.edgeMap = new Dictionary();\n\n\t /**\n\t * The resulting set of Nodes when the analysis has finished.\n\t * @type {Array}\n\t */\n\t this.finalNodes = [];\n\n\t /**\n\t * The resulting set of Links when the analysis has finished.\n\t * @type {Array}\n\t */\n\t this.finalLinks = [];\n\n\t /**\n\t * The items being omitted because of multigraph edges.\n\t * @type {Array}\n\t */\n\t this.ignoredConnections = [];\n\n\t /**\n\t * The items being omitted because of containers, visibility and other factors.\n\t * @type {Array}\n\t */\n\t this.ignoredShapes = [];\n\n\t /**\n\t * The map from a node to the partition/hypernode in which it sits. This hyperMap is null if 'options.layoutContainerChildren' is false.\n\t * @type {Dictionary}\n\t */\n\t this.hyperMap = new Dictionary();\n\n\t /**\n\t * The hypertree contains the hierarchy defined by the containers.\n\t * It's in essence a Graph of Graphs with a tree structure defined by the hierarchy of containers.\n\t * @type {HyperTree}\n\t */\n\t this.hyperTree = new Graph();\n\n\t /**\n\t * The resulting graph after conversion. Note that this does not supply the information contained in the\n\t * ignored connection and shape collections.\n\t * @type {null}\n\t */\n\t this.finalGraph = null;\n\n\t this.diagram = diagram;\n\t },\n\n\t /**\n\t * The hyperTree is used when the 'options.layoutContainerChildren' is true. It contains the hierarchy of containers whereby each node is a ContainerGraph.\n\t * This type of node has a Container reference to the container which holds the Graph items. There are three possible situations during the conversion process:\n\t * - Ignore the containers: the container are non-existent and only normal shapes are mapped. If a shape has a connection to a container it will be ignored as well\n\t * since there is no node mapped for the container.\n\t * - Do not ignore the containers and leave the content of the containers untouched: the top-level elements are being mapped and the children within a container are not altered.\n\t * - Do not ignore the containers and organize the content of the containers as well: the hypertree is constructed and there is a partitioning of all nodes and connections into the hypertree.\n\t * The only reason a connection or node is not being mapped might be due to the visibility, which includes the visibility change through a collapsed parent container.\n\t * @param options\n\t */\n\t convert: function (options) {\n\n\t if (Utils.isUndefined(this.diagram)) {\n\t throw \"No diagram to convert.\";\n\t }\n\n\t this.options = kendo.deepExtend({\n\t ignoreInvisible: true,\n\t ignoreContainers: true,\n\t layoutContainerChildren: false\n\t },\n\t options || {}\n\t );\n\n\t this.clear();\n\t // create the nodes which participate effectively in the graph analysis\n\t this._renormalizeShapes();\n\n\t // recreate the incoming and outgoing collections of each and every node\n\t this._renormalizeConnections();\n\n\t // export the resulting graph\n\t this.finalNodes = new Dictionary(this.nodes);\n\t this.finalLinks = new Dictionary(this.edges);\n\n\t this.finalGraph = new Graph();\n\t this.finalNodes.forEach(function (n) {\n\t this.finalGraph.addNode(n);\n\t }, this);\n\t this.finalLinks.forEach(function (l) {\n\t this.finalGraph.addExistingLink(l);\n\t }, this);\n\t return this.finalGraph;\n\t },\n\n\t /**\n\t * Maps the specified connection to an edge of the graph deduced from the given diagram.\n\t * @param connection\n\t * @returns {*}\n\t */\n\t mapConnection: function (connection) {\n\t return this.edgeMap.get(connection.id);\n\t },\n\n\t /**\n\t * Maps the specified shape to a node of the graph deduced from the given diagram.\n\t * @param shape\n\t * @returns {*}\n\t */\n\t mapShape: function (shape) {\n\t return this.nodeMap.get(shape.id);\n\t },\n\n\t /**\n\t * Gets the edge, if any, between the given nodes.\n\t * @param a\n\t * @param b\n\t */\n\t getEdge: function (a, b) {\n\t return Utils.first(a.links, function (link) {\n\t return link.getComplement(a) === b;\n\t });\n\t },\n\n\t /**\n\t * Clears all the collections used by the conversion process.\n\t */\n\t clear: function () {\n\t this.finalGraph = null;\n\t this.hyperTree = (!this.options.ignoreContainers && this.options.layoutContainerChildren) ? new HyperTree() : null;\n\t this.hyperMap = (!this.options.ignoreContainers && this.options.layoutContainerChildren) ? new Dictionary() : null;\n\t this.nodeMap = new Dictionary();\n\t this.shapeMap = new Dictionary();\n\t this.nodes = [];\n\t this.edges = [];\n\t this.edgeMap = new Dictionary();\n\t this.ignoredConnections = [];\n\t this.ignoredShapes = [];\n\t this.finalNodes = [];\n\t this.finalLinks = [];\n\t },\n\n\t /**\n\t * The path from a given ContainerGraph to the root (container).\n\t * @param containerGraph\n\t * @returns {Array}\n\t */\n\t listToRoot: function (containerGraph) {\n\t var list = [];\n\t var s = containerGraph.container;\n\t if (!s) {\n\t return list;\n\t }\n\t list.push(s);\n\t while (s.parentContainer) {\n\t s = s.parentContainer;\n\t list.push(s);\n\t }\n\t list.reverse();\n\t return list;\n\t },\n\n\t firstNonIgnorableContainer: function (shape) {\n\n\t if (shape.isContainer && !this._isIgnorableItem(shape)) {\n\t return shape;\n\t }\n\t return !shape.parentContainer ? null : this.firstNonIgnorableContainer(shape.parentContainer);\n\t },\n\t isContainerConnection: function (a, b) {\n\t if (a.isContainer && this.isDescendantOf(a, b)) {\n\t return true;\n\t }\n\t return b.isContainer && this.isDescendantOf(b, a);\n\t },\n\n\t /**\n\t * Returns true if the given shape is a direct child or a nested container child of the given container.\n\t * If the given container and shape are the same this will return false since a shape cannot be its own child.\n\t * @param scope\n\t * @param a\n\t * @returns {boolean}\n\t */\n\t isDescendantOf: function (scope, a) {\n\t if (!scope.isContainer) {\n\t throw \"Expecting a container.\";\n\t }\n\t if (scope === a) {\n\t return false;\n\t }\n\t if (contains(scope.children, a)) {\n\t return true;\n\t }\n\t var containers = [];\n\t for (var i = 0, len = scope.children.length; i < len; i++) {\n\t var c = scope.children[i];\n\t if (c.isContainer && this.isDescendantOf(c, a)) {\n\t containers.push(c);\n\t }\n\t }\n\n\t return containers.length > 0;\n\t },\n\t isIgnorableItem: function (shape) {\n\t if (this.options.ignoreInvisible) {\n\t if (shape.isCollapsed && this._isVisible(shape)) {\n\t return false;\n\t }\n\t if (!shape.isCollapsed && this._isVisible(shape)) {\n\t return false;\n\t }\n\t return true;\n\t }\n\t else {\n\t return shape.isCollapsed && !this._isTop(shape);\n\t }\n\t },\n\n\t /**\n\t * Determines whether the shape is or needs to be mapped to another shape. This occurs essentially when the shape sits in\n\t * a collapsed container hierarchy and an external connection needs a node endpoint. This node then corresponds to the mapped shape and is\n\t * necessarily a container in the parent hierarchy of the shape.\n\t * @param shape\n\t */\n\t isShapeMapped: function (shape) {\n\t return shape.isCollapsed && !this._isVisible(shape) && !this._isTop(shape);\n\t },\n\n\t leastCommonAncestor: function (a, b) {\n\t if (!a) {\n\t throw \"Parameter should not be null.\";\n\t }\n\t if (!b) {\n\t throw \"Parameter should not be null.\";\n\t }\n\n\t if (!this.hyperTree) {\n\t throw \"No hypertree available.\";\n\t }\n\t var al = this.listToRoot(a);\n\t var bl = this.listToRoot(b);\n\t var found = null;\n\t if (Utils.isEmpty(al) || Utils.isEmpty(bl)) {\n\t return this.hyperTree.root.data;\n\t }\n\t var xa = al[0];\n\t var xb = bl[0];\n\t var i = 0;\n\t while (xa === xb) {\n\t found = al[i];\n\t i++;\n\t if (i >= al.length || i >= bl.length) {\n\t break;\n\t }\n\t xa = al[i];\n\t xb = bl[i];\n\t }\n\t if (!found) {\n\t return this.hyperTree.root.data;\n\t }\n\t else {\n\t return grep(this.hyperTree.nodes, function (n) {\n\t return n.data.container === found;\n\t });\n\t }\n\t },\n\t /**\n\t * Determines whether the specified item is a top-level shape or container.\n\t * @param item\n\t * @returns {boolean}\n\t * @private\n\t */\n\t _isTop: function (item) {\n\t return !item.parentContainer;\n\t },\n\n\t /**\n\t * Determines iteratively (by walking up the container stack) whether the specified shape is visible.\n\t * This does NOT tell whether the item is not visible due to an explicit Visibility change or due to a collapse state.\n\t * @param shape\n\t * @returns {*}\n\t * @private\n\t */\n\t _isVisible: function (shape) {\n\n\t if (!shape.visible()) {\n\t return false;\n\t }\n\t return !shape.parentContainer ? shape.visible() : this._isVisible(shape.parentContainer);\n\t },\n\n\t _isCollapsed: function (shape) {\n\n\t if (shape.isContainer && shape.isCollapsed) {\n\t return true;\n\t }\n\t return shape.parentContainer && this._isCollapsed(shape.parentContainer);\n\t },\n\n\t /**\n\t * First part of the graph creation; analyzing the shapes and containers and deciding whether they should be mapped to a Node.\n\t * @private\n\t */\n\t _renormalizeShapes: function () {\n\t // add the nodes, the adjacency structure will be reconstructed later on\n\t if (this.options.ignoreContainers) {\n\t for (var i = 0, len = this.diagram.shapes.length; i < len; i++) {\n\t var shape = this.diagram.shapes[i];\n\n\t // if not visible (and ignoring the invisible ones) or a container we skip\n\t if ((this.options.ignoreInvisible && !this._isVisible(shape)) || shape.isContainer) {\n\t this.ignoredShapes.push(shape);\n\t continue;\n\t }\n\t var node = new Node(shape.id, shape);\n\t node.isVirtual = false;\n\n\t // the mapping will always contain singletons and the hyperTree will be null\n\t this.nodeMap.add(shape.id, node);\n\t this.nodes.push(node);\n\t }\n\t }\n\t else {\n\t throw \"Containers are not supported yet, but stay tuned.\";\n\t }\n\t },\n\n\t /**\n\t * Second part of the graph creation; analyzing the connections and deciding whether they should be mapped to an edge.\n\t * @private\n\t */\n\t _renormalizeConnections: function () {\n\t if (this.diagram.connections.length === 0) {\n\t return;\n\t }\n\t for (var i = 0, len = this.diagram.connections.length; i < len; i++) {\n\t var conn = this.diagram.connections[i];\n\n\t if (this.isIgnorableItem(conn)) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\n\t var source = !conn.sourceConnector ? null : conn.sourceConnector.shape;\n\t var sink = !conn.targetConnector ? null : conn.targetConnector.shape;\n\n\t // no layout for floating connections\n\t if (!source || !sink) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\n\t if (contains(this.ignoredShapes, source) && !this.shapeMap.containsKey(source)) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\t if (contains(this.ignoredShapes, sink) && !this.shapeMap.containsKey(sink)) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\n\t // if the endpoint sits in a collapsed container we need the container rather than the shape itself\n\t if (this.shapeMap.containsKey(source)) {\n\t source = this.shapeMap[source];\n\t }\n\t if (this.shapeMap.containsKey(sink)) {\n\t sink = this.shapeMap[sink];\n\t }\n\n\t var sourceNode = this.mapShape(source);\n\t var sinkNode = this.mapShape(sink);\n\t if ((sourceNode === sinkNode) || this.areConnectedAlready(sourceNode, sinkNode)) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\n\t if (sourceNode === null || sinkNode === null) {\n\t throw \"A shape was not mapped to a node.\";\n\t }\n\t if (this.options.ignoreContainers) {\n\t // much like a floating connection here since at least one end is attached to a container\n\t if (sourceNode.isVirtual || sinkNode.isVirtual) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\t var newEdge = new Link(sourceNode, sinkNode, conn.id, conn);\n\n\t this.edgeMap.add(conn.id, newEdge);\n\t this.edges.push(newEdge);\n\t }\n\t else {\n\t throw \"Containers are not supported yet, but stay tuned.\";\n\t }\n\t }\n\t },\n\n\t areConnectedAlready: function (n, m) {\n\t return Utils.any(this.edges, function (l) {\n\t return l.source === n && l.target === m || l.source === m && l.target === n;\n\t });\n\t }\n\n\t /**\n\t * Depth-first traversal of the given container.\n\t * @param container\n\t * @param action\n\t * @param includeStart\n\t * @private\n\t */\n\t /* _visitContainer: function (container, action, includeStart) {\n\n\t *//*if (container == null) throw new ArgumentNullException(\"container\");\n\t if (action == null) throw new ArgumentNullException(\"action\");\n\t if (includeStart) action(container);\n\t if (container.children.isEmpty()) return;\n\t foreach(\n\t var item\n\t in\n\t container.children.OfType < IShape > ()\n\t )\n\t {\n\t var childContainer = item\n\t as\n\t IContainerShape;\n\t if (childContainer != null) this.VisitContainer(childContainer, action);\n\t else action(item);\n\t }*//*\n\t }*/\n\n\n\t });\n\n\t /**\n\t * The classic spring-embedder (aka force-directed, Fruchterman-Rheingold, barycentric) algorithm.\n\t * http://en.wikipedia.org/wiki/Force-directed_graph_drawing\n\t * - Chapter 12 of Tamassia et al. \"Handbook of graph drawing and visualization\".\n\t * - Kobourov on preprint arXiv; http://arxiv.org/pdf/1201.3011.pdf\n\t * - Fruchterman and Rheingold in SOFTWARE-PRACTICE AND EXPERIENCE, VOL. 21(1 1), 1129-1164 (NOVEMBER 1991)\n\t * @type {*}\n\t */\n\t var SpringLayout = LayoutBase.extend({\n\t init: function (diagram) {\n\t var that = this;\n\t LayoutBase.fn.init.call(that);\n\t if (Utils.isUndefined(diagram)) {\n\t throw \"Diagram is not specified.\";\n\t }\n\t this.diagram = diagram;\n\t },\n\n\t layout: function (options) {\n\n\t this.transferOptions(options);\n\n\t var adapter = new DiagramToHyperTreeAdapter(this.diagram);\n\t var graph = adapter.convert(options);\n\t if (graph.isEmpty()) {\n\t return;\n\t }\n\t // split into connected components\n\t var components = graph.getConnectedComponents();\n\t if (Utils.isEmpty(components)) {\n\t return;\n\t }\n\t for (var i = 0; i < components.length; i++) {\n\t var component = components[i];\n\t this.layoutGraph(component, options);\n\t }\n\t var finalNodeSet = this.gridLayoutComponents(components);\n\t return new diagram.LayoutState(this.diagram, finalNodeSet);\n\t },\n\n\t layoutGraph: function (graph, options) {\n\n\t if (Utils.isDefined(options)) {\n\t this.transferOptions(options);\n\t }\n\t this.graph = graph;\n\n\t var initialTemperature = this.options.nodeDistance * 9;\n\t this.temperature = initialTemperature;\n\n\t var guessBounds = this._expectedBounds();\n\t this.width = guessBounds.width;\n\t this.height = guessBounds.height;\n\n\t for (var step = 0; step < this.options.iterations; step++) {\n\t this.refineStage = step >= this.options.iterations * 5 / 6;\n\t this.tick();\n\t // exponential cooldown\n\t this.temperature = this.refineStage ?\n\t initialTemperature / 30 :\n\t initialTemperature * (1 - step / (2 * this.options.iterations ));\n\t }\n\t },\n\n\t /**\n\t * Single iteration of the simulation.\n\t */\n\t tick: function () {\n\t var i;\n\t // collect the repulsive forces on each node\n\t for (i = 0; i < this.graph.nodes.length; i++) {\n\t this._repulsion(this.graph.nodes[i]);\n\t }\n\n\t // collect the attractive forces on each node\n\t for (i = 0; i < this.graph.links.length; i++) {\n\t this._attraction(this.graph.links[i]);\n\t }\n\t // update the positions\n\t for (i = 0; i < this.graph.nodes.length; i++) {\n\t var node = this.graph.nodes[i];\n\t var offset = Math.sqrt(node.dx * node.dx + node.dy * node.dy);\n\t if (offset === 0) {\n\t return;\n\t }\n\t node.x += Math.min(offset, this.temperature) * node.dx / offset;\n\t node.y += Math.min(offset, this.temperature) * node.dy / offset;\n\t if (this.options.limitToView) {\n\t node.x = Math.min(this.width, Math.max(node.width / 2, node.x));\n\t node.y = Math.min(this.height, Math.max(node.height / 2, node.y));\n\t }\n\t }\n\t },\n\n\t /**\n\t * Shakes the node away from its current position to escape the deadlock.\n\t * @param node A Node.\n\t * @private\n\t */\n\t _shake: function (node) {\n\t // just a simple polar neighborhood\n\t var rho = Math.random() * this.options.nodeDistance / 4;\n\t var alpha = Math.random() * 2 * Math.PI;\n\t node.x += rho * Math.cos(alpha);\n\t node.y -= rho * Math.sin(alpha);\n\t },\n\n\t /**\n\t * The typical Coulomb-Newton force law F=k/r^2\n\t * @remark This only works in dimensions less than three.\n\t * @param d\n\t * @param n A Node.\n\t * @param m Another Node.\n\t * @returns {number}\n\t * @private\n\t */\n\t _InverseSquareForce: function (d, n, m) {\n\t var force;\n\t if (!this.refineStage) {\n\t force = Math.pow(d, 2) / Math.pow(this.options.nodeDistance, 2);\n\t }\n\t else {\n\t var deltax = n.x - m.x;\n\t var deltay = n.y - m.y;\n\n\t var wn = n.width / 2;\n\t var hn = n.height / 2;\n\t var wm = m.width / 2;\n\t var hm = m.height / 2;\n\n\t force = (Math.pow(deltax, 2) / Math.pow(wn + wm + this.options.nodeDistance, 2)) + (Math.pow(deltay, 2) / Math.pow(hn + hm + this.options.nodeDistance, 2));\n\t }\n\t return force * 4 / 3;\n\t },\n\n\t /**\n\t * The typical Hooke force law F=kr^2\n\t * @param d\n\t * @param n\n\t * @param m\n\t * @returns {number}\n\t * @private\n\t */\n\t _SquareForce: function (d, n, m) {\n\t return 1 / this._InverseSquareForce(d, n, m);\n\t },\n\n\t _repulsion: function (n) {\n\t n.dx = 0;\n\t n.dy = 0;\n\t Utils.forEach(this.graph.nodes, function (m) {\n\t if (m === n) {\n\t return;\n\t }\n\t while (n.x === m.x && n.y === m.y) {\n\t this._shake(m);\n\t }\n\t var vx = n.x - m.x;\n\t var vy = n.y - m.y;\n\t var distance = Math.sqrt(vx * vx + vy * vy);\n\t var r = this._SquareForce(distance, n, m) * 2;\n\t n.dx += (vx / distance) * r;\n\t n.dy += (vy / distance) * r;\n\t }, this);\n\t },\n\t _attraction: function (link) {\n\t var t = link.target;\n\t var s = link.source;\n\t if (s === t) {\n\t // loops induce endless shakes\n\t return;\n\t }\n\t while (s.x === t.x && s.y === t.y) {\n\t this._shake(t);\n\t }\n\n\t var vx = s.x - t.x;\n\t var vy = s.y - t.y;\n\t var distance = Math.sqrt(vx * vx + vy * vy);\n\n\t var a = this._InverseSquareForce(distance, s, t) * 5;\n\t var dx = (vx / distance) * a;\n\t var dy = (vy / distance) * a;\n\t t.dx += dx;\n\t t.dy += dy;\n\t s.dx -= dx;\n\t s.dy -= dy;\n\t },\n\n\t /**\n\t * Calculates the expected bounds after layout.\n\t * @returns {*}\n\t * @private\n\t */\n\t _expectedBounds: function () {\n\n\t var size, N = this.graph.nodes.length, /*golden ration optimal?*/ ratio = 1.5, multiplier = 4;\n\t if (N === 0) {\n\t return size;\n\t }\n\t size = Utils.fold(this.graph.nodes, function (s, node) {\n\t var area = node.width * node.height;\n\t if (area > 0) {\n\t s += Math.sqrt(area);\n\t return s;\n\t }\n\t return 0;\n\t }, 0, this);\n\t var av = size / N;\n\t var squareSize = av * Math.ceil(Math.sqrt(N));\n\t var width = squareSize * Math.sqrt(ratio);\n\t var height = squareSize / Math.sqrt(ratio);\n\t return { width: width * multiplier, height: height * multiplier };\n\t }\n\n\t });\n\n\t var TreeLayoutProcessor = kendo.Class.extend({\n\n\t init: function (options) {\n\t this.center = null;\n\t this.options = options;\n\t },\n\t layout: function (treeGraph, root) {\n\t this.graph = treeGraph;\n\t if (!this.graph.nodes || this.graph.nodes.length === 0) {\n\t return;\n\t }\n\n\t if (!contains(this.graph.nodes, root)) {\n\t throw \"The given root is not in the graph.\";\n\t }\n\n\t this.center = root;\n\t this.graph.cacheRelationships();\n\t /* var nonull = this.graph.nodes.where(function (n) {\n\t return n.associatedShape != null;\n\t });*/\n\n\t // transfer the rects\n\t /*nonull.forEach(function (n) {\n\t n.Location = n.associatedShape.Position;\n\t n.NodeSize = n.associatedShape.ActualBounds.ToSize();\n\t }\n\n\t );*/\n\n\t // caching the children\n\t /* nonull.forEach(function (n) {\n\t n.children = n.getChildren();\n\t });*/\n\n\t this.layoutSwitch();\n\n\t // apply the layout to the actual visuals\n\t // nonull.ForEach(n => n.associatedShape.Position = n.Location);\n\t },\n\n\t layoutLeft: function (left) {\n\t this.setChildrenDirection(this.center, \"Left\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t var h = 0, w = 0, y, i, node;\n\t for (i = 0; i < left.length; i++) {\n\t node = left[i];\n\t node.TreeDirection = \"Left\";\n\t var s = this.measure(node, Size.Empty);\n\t w = Math.max(w, s.Width);\n\t h += s.height + this.options.verticalSeparation;\n\t }\n\n\t h -= this.options.verticalSeparation;\n\t var x = this.center.x - this.options.horizontalSeparation;\n\t y = this.center.y + ((this.center.height - h) / 2);\n\t for (i = 0; i < left.length; i++) {\n\t node = left[i];\n\t var p = new Point(x - node.Size.width, y);\n\n\t this.arrange(node, p);\n\t y += node.Size.height + this.options.verticalSeparation;\n\t }\n\t },\n\n\t layoutRight: function (right) {\n\t this.setChildrenDirection(this.center, \"Right\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t var h = 0, w = 0, y, i, node;\n\t for (i = 0; i < right.length; i++) {\n\t node = right[i];\n\t node.TreeDirection = \"Right\";\n\t var s = this.measure(node, Size.Empty);\n\t w = Math.max(w, s.Width);\n\t h += s.height + this.options.verticalSeparation;\n\t }\n\n\t h -= this.options.verticalSeparation;\n\t var x = this.center.x + this.options.horizontalSeparation + this.center.width;\n\t y = this.center.y + ((this.center.height - h) / 2);\n\t for (i = 0; i < right.length; i++) {\n\t node = right[i];\n\t var p = new Point(x, y);\n\t this.arrange(node, p);\n\t y += node.Size.height + this.options.verticalSeparation;\n\t }\n\t },\n\n\t layoutUp: function (up) {\n\t this.setChildrenDirection(this.center, \"Up\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t var w = 0, y, node, i;\n\t for (i = 0; i < up.length; i++) {\n\t node = up[i];\n\t node.TreeDirection = \"Up\";\n\t var s = this.measure(node, Size.Empty);\n\t w += s.width + this.options.horizontalSeparation;\n\t }\n\n\t w -= this.options.horizontalSeparation;\n\t var x = this.center.x + (this.center.width / 2) - (w / 2);\n\n\t // y = this.center.y -verticalSeparation -this.center.height/2 - h;\n\t for (i = 0; i < up.length; i++) {\n\t node = up[i];\n\t y = this.center.y - this.options.verticalSeparation - node.Size.height;\n\t var p = new Point(x, y);\n\t this.arrange(node, p);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\t },\n\n\t layoutDown: function (down) {\n\t var node, i;\n\t this.setChildrenDirection(this.center, \"Down\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t var w = 0, y;\n\t for (i = 0; i < down.length; i++) {\n\t node = down[i];\n\t node.treeDirection = \"Down\";\n\t var s = this.measure(node, Size.Empty);\n\t w += s.width + this.options.horizontalSeparation;\n\t }\n\n\t w -= this.options.horizontalSeparation;\n\t var x = this.center.x + (this.center.width / 2) - (w / 2);\n\t y = this.center.y + this.options.verticalSeparation + this.center.height;\n\t for (i = 0; i < down.length; i++) {\n\t node = down[i];\n\t var p = new Point(x, y);\n\t this.arrange(node, p);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\t },\n\n\t layoutRadialTree: function () {\n\t // var rmax = children.Aggregate(0D, (current, node) => Math.max(node.SectorAngle, current));\n\t this.setChildrenDirection(this.center, \"Radial\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t this.previousRoot = null;\n\t var startAngle = this.options.startRadialAngle * DEG_TO_RAD;\n\t var endAngle = this.options.endRadialAngle * DEG_TO_RAD;\n\t if (endAngle <= startAngle) {\n\t throw \"Final angle should not be less than the start angle.\";\n\t }\n\n\t this.maxDepth = 0;\n\t this.origin = new Point(this.center.x, this.center.y);\n\t this.calculateAngularWidth(this.center, 0);\n\n\t // perform the layout\n\t if (this.maxDepth > 0) {\n\t this.radialLayout(this.center, this.options.radialFirstLevelSeparation, startAngle, endAngle);\n\t }\n\n\t // update properties of the root node\n\t this.center.Angle = endAngle - startAngle;\n\t },\n\n\t tipOverTree: function (down, startFromLevel) {\n\t if (Utils.isUndefined(startFromLevel)) {\n\t startFromLevel = 0;\n\t }\n\n\t this.setChildrenDirection(this.center, \"Down\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t this.setChildrenLayout(this.center, \"Underneath\", false, startFromLevel);\n\t var w = 0, y, node, i;\n\t for (i = 0; i < down.length; i++) {\n\t node = down[i];\n\n\t // if (node.IsSpecial) continue;\n\t node.TreeDirection = \"Down\";\n\t var s = this.measure(node, Size.Empty);\n\t w += s.width + this.options.horizontalSeparation;\n\t }\n\n\t w -= this.options.horizontalSeparation;\n\n\t // putting the root in the center with respect to the whole diagram is not a nice result, let's put it with respect to the first level only\n\t w -= down[down.length - 1].width;\n\t w += down[down.length - 1].associatedShape.bounds().width;\n\n\t var x = this.center.x + (this.center.width / 2) - (w / 2);\n\t y = this.center.y + this.options.verticalSeparation + this.center.height;\n\t for (i = 0; i < down.length; i++) {\n\t node = down[i];\n\t // if (node.IsSpecial) continue;\n\t var p = new Point(x, y);\n\t this.arrange(node, p);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\n\t /*//let's place the special node, assuming there is only one\n\t if (down.Count(n => n.IsSpecial) > 0)\n\t {\n\t var special = (from n in down where n.IsSpecial select n).First();\n\t if (special.Children.Count > 0)\n\t throw new DiagramException(\"The 'special' element should not have children.\");\n\t special.Data.Location = new Point(Center.Data.Location.X + Center.AssociatedShape.BoundingRectangle.Width + this.options.HorizontalSeparation, Center.Data.Location.Y);\n\t }*/\n\t },\n\t calculateAngularWidth: function (n, d) {\n\t if (d > this.maxDepth) {\n\t this.maxDepth = d;\n\t }\n\n\t var aw = 0, w = 1000, h = 1000, diameter = d === 0 ? 0 : Math.sqrt((w * w) + (h * h)) / d;\n\n\t if (n.children.length > 0) {\n\t // eventually with n.IsExpanded\n\t for (var i = 0, len = n.children.length; i < len; i++) {\n\t var child = n.children[i];\n\t aw += this.calculateAngularWidth(child, d + 1);\n\t }\n\t aw = Math.max(diameter, aw);\n\t }\n\t else {\n\t aw = diameter;\n\t }\n\n\t n.sectorAngle = aw;\n\t return aw;\n\t },\n\t sortChildren: function (n) {\n\t var basevalue = 0, i;\n\n\t // update basevalue angle for node ordering\n\t if (n.parents.length > 1) {\n\t throw \"Node is not part of a tree.\";\n\t }\n\t var p = n.parents[0];\n\t if (p) {\n\t var pl = new Point(p.x, p.y);\n\t var nl = new Point(n.x, n.y);\n\t basevalue = this.normalizeAngle(Math.atan2(pl.y - nl.y, pl.x - nl.x));\n\t }\n\n\t var count = n.children.length;\n\t if (count === 0) {\n\t return null;\n\t }\n\n\t var angle = [];\n\t var idx = [];\n\n\t for (i = 0; i < count; ++i) {\n\t var c = n.children[i];\n\t var l = new Point(c.x, c.y);\n\t idx[i] = i;\n\t angle[i] = this.normalizeAngle(-basevalue + Math.atan2(l.y - l.y, l.x - l.x));\n\t }\n\n\t Utils.bisort(angle, idx);\n\t var col = []; // list of nodes\n\t var children = n.children;\n\t for (i = 0; i < count; ++i) {\n\t col.push(children[idx[i]]);\n\t }\n\n\t return col;\n\t },\n\n\t normalizeAngle: function (angle) {\n\t while (angle > Math.PI * 2) {\n\t angle -= 2 * Math.PI;\n\t }\n\t while (angle < 0) {\n\t angle += Math.PI * 2;\n\t }\n\t return angle;\n\t },\n\t radialLayout: function (node, radius, startAngle, endAngle) {\n\t var deltaTheta = endAngle - startAngle;\n\t var deltaThetaHalf = deltaTheta / 2.0;\n\t var parentSector = node.sectorAngle;\n\t var fraction = 0;\n\t var sorted = this.sortChildren(node);\n\t for (var i = 0, len = sorted.length; i < len; i++) {\n\t var childNode = sorted[i];\n\t var cp = childNode;\n\t var childAngleFraction = cp.sectorAngle / parentSector;\n\t if (childNode.children.length > 0) {\n\t this.radialLayout(childNode,\n\t radius + this.options.radialSeparation,\n\t startAngle + (fraction * deltaTheta),\n\t startAngle + ((fraction + childAngleFraction) * deltaTheta));\n\t }\n\n\t this.setPolarLocation(childNode, radius, startAngle + (fraction * deltaTheta) + (childAngleFraction * deltaThetaHalf));\n\t cp.angle = childAngleFraction * deltaTheta;\n\t fraction += childAngleFraction;\n\t }\n\t },\n\t setPolarLocation: function (node, radius, angle) {\n\t node.x = this.origin.x + (radius * Math.cos(angle));\n\t node.y = this.origin.y + (radius * Math.sin(angle));\n\t node.BoundingRectangle = new Rect(node.x, node.y, node.width, node.height);\n\t },\n\n\t /**\n\t * Sets the children direction recursively.\n\t * @param node\n\t * @param direction\n\t * @param includeStart\n\t */\n\t setChildrenDirection: function (node, direction, includeStart) {\n\t var rootDirection = node.treeDirection;\n\t this.graph.depthFirstTraversal(node, function (n) {\n\t n.treeDirection = direction;\n\t });\n\t if (!includeStart) {\n\t node.treeDirection = rootDirection;\n\t }\n\t },\n\n\t /**\n\t * Sets the children layout recursively.\n\t * @param node\n\t * @param layout\n\t * @param includeStart\n\t * @param startFromLevel\n\t */\n\t setChildrenLayout: function (node, layout, includeStart, startFromLevel) {\n\t if (Utils.isUndefined(startFromLevel)) {\n\t startFromLevel = 0;\n\t }\n\t var rootLayout = node.childrenLayout;\n\t if (startFromLevel > 0) {\n\t // assign levels to the Node.Level property\n\t this.graph.assignLevels(node);\n\n\t // assign the layout on the condition that the level is at least the 'startFromLevel'\n\t this.graph.depthFirstTraversal(\n\t node, function (s) {\n\t if (s.level >= startFromLevel + 1) {\n\t s.childrenLayout = layout;\n\t }\n\t }\n\t );\n\t }\n\t else {\n\t this.graph.depthFirstTraversal(node, function (s) {\n\t s.childrenLayout = layout;\n\t });\n\n\t // if the start should not be affected we put the state back\n\t if (!includeStart) {\n\t node.childrenLayout = rootLayout;\n\t }\n\t }\n\t },\n\n\t /**\n\t * Returns the actual size of the node. The given size is the allowed space wherein the node can lay out itself.\n\t * @param node\n\t * @param givenSize\n\t * @returns {Size}\n\t */\n\t measure: function (node, givenSize) {\n\t var w = 0, h = 0, s;\n\t var result = new Size(0, 0);\n\t if (!node) {\n\t throw \"\";\n\t }\n\t var b = node.associatedShape.bounds();\n\t var shapeWidth = b.width;\n\t var shapeHeight = b.height;\n\t if (node.parents.length !== 1) {\n\t throw \"Node not in a spanning tree.\";\n\t }\n\n\t var parent = node.parents[0];\n\t if (node.treeDirection === \"Undefined\") {\n\t node.treeDirection = parent.treeDirection;\n\t }\n\n\t if (Utils.isEmpty(node.children)) {\n\t result = new Size(\n\t Math.abs(shapeWidth) < EPSILON ? 50 : shapeWidth,\n\t Math.abs(shapeHeight) < EPSILON ? 25 : shapeHeight);\n\t }\n\t else if (node.children.length === 1) {\n\t switch (node.treeDirection) {\n\t case \"Radial\":\n\t s = this.measure(node.children[0], givenSize); // child size\n\t w = shapeWidth + (this.options.radialSeparation * Math.cos(node.AngleToParent)) + s.width;\n\t h = shapeHeight + Math.abs(this.options.radialSeparation * Math.sin(node.AngleToParent)) + s.height;\n\t break;\n\t case \"Left\":\n\t case \"Right\":\n\t switch (node.childrenLayout) {\n\n\t case \"TopAlignedWithParent\":\n\t break;\n\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t s = this.measure(node.children[0], givenSize);\n\t w = shapeWidth + s.width + this.options.underneathHorizontalOffset;\n\t h = shapeHeight + this.options.underneathVerticalTopOffset + s.height;\n\t break;\n\n\t case \"Default\":\n\t s = this.measure(node.children[0], givenSize);\n\t w = shapeWidth + this.options.horizontalSeparation + s.width;\n\t h = Math.max(shapeHeight, s.height);\n\t break;\n\n\t default:\n\t throw \"Unhandled TreeDirection in the Radial layout measuring.\";\n\t }\n\t break;\n\t case \"Up\":\n\t case \"Down\":\n\t switch (node.childrenLayout) {\n\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t s = this.measure(node.children[0], givenSize);\n\t w = Math.max(shapeWidth, s.width + this.options.underneathHorizontalOffset);\n\t h = shapeHeight + this.options.underneathVerticalTopOffset + s.height;\n\t break;\n\n\t case \"Default\":\n\t s = this.measure(node.children[0], givenSize);\n\t h = shapeHeight + this.options.verticalSeparation + s.height;\n\t w = Math.max(shapeWidth, s.width);\n\t break;\n\n\t default:\n\t throw \"Unhandled TreeDirection in the Down layout measuring.\";\n\t }\n\t break;\n\t default:\n\t throw \"Unhandled TreeDirection in the layout measuring.\";\n\t }\n\n\t result = new Size(w, h);\n\t }\n\t else {\n\t var i, childNode;\n\t switch (node.treeDirection) {\n\t case \"Left\":\n\t case \"Right\":\n\t switch (node.childrenLayout) {\n\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t w = shapeWidth;\n\t h = shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < node.children.length; i++) {\n\t childNode = node.children[i];\n\t s = this.measure(childNode, givenSize);\n\t w = Math.max(w, s.width + this.options.underneathHorizontalOffset);\n\t h += s.height + this.options.underneathVerticalSeparation;\n\t }\n\n\t h -= this.options.underneathVerticalSeparation;\n\t break;\n\n\t case \"Default\":\n\t w = shapeWidth;\n\t h = 0;\n\t for (i = 0; i < node.children.length; i++) {\n\t childNode = node.children[i];\n\t s = this.measure(childNode, givenSize);\n\t w = Math.max(w, shapeWidth + this.options.horizontalSeparation + s.width);\n\t h += s.height + this.options.verticalSeparation;\n\t }\n\t h -= this.options.verticalSeparation;\n\t break;\n\n\t default:\n\t throw \"Unhandled TreeDirection in the Right layout measuring.\";\n\t }\n\n\t break;\n\t case \"Up\":\n\t case \"Down\":\n\n\t switch (node.childrenLayout) {\n\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t w = shapeWidth;\n\t h = shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < node.children.length; i++) {\n\t childNode = node.children[i];\n\t s = this.measure(childNode, givenSize);\n\t w = Math.max(w, s.width + this.options.underneathHorizontalOffset);\n\t h += s.height + this.options.underneathVerticalSeparation;\n\t }\n\n\t h -= this.options.underneathVerticalSeparation;\n\t break;\n\n\t case \"Default\":\n\t w = 0;\n\t h = 0;\n\t for (i = 0; i < node.children.length; i++) {\n\t childNode = node.children[i];\n\t s = this.measure(childNode, givenSize);\n\t w += s.width + this.options.horizontalSeparation;\n\t h = Math.max(h, s.height + this.options.verticalSeparation + shapeHeight);\n\t }\n\n\t w -= this.options.horizontalSeparation;\n\t break;\n\n\t default:\n\t throw \"Unhandled TreeDirection in the Down layout measuring.\";\n\t }\n\n\t break;\n\t default:\n\t throw \"Unhandled TreeDirection in the layout measuring.\";\n\t }\n\n\t result = new Size(w, h);\n\t }\n\n\t node.SectorAngle = Math.sqrt((w * w / 4) + (h * h / 4));\n\t node.Size = result;\n\t return result;\n\t },\n\t arrange: function (n, p) {\n\t var i, pp, child, node, childrenwidth, b = n.associatedShape.bounds();\n\t var shapeWidth = b.width;\n\t var shapeHeight = b.height;\n\t if (Utils.isEmpty(n.children)) {\n\t n.x = p.x;\n\t n.y = p.y;\n\t n.BoundingRectangle = new Rect(p.x, p.y, shapeWidth, shapeHeight);\n\t }\n\t else {\n\t var x, y;\n\t var selfLocation;\n\t switch (n.treeDirection) {\n\t case \"Left\":\n\t switch (n.childrenLayout) {\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t selfLocation = p;\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t y = p.y + shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < node.children.length; i++) {\n\t node = node.children[i];\n\t x = selfLocation.x - node.associatedShape.width - this.options.underneathHorizontalOffset;\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.underneathVerticalSeparation;\n\t }\n\t break;\n\n\t case \"Default\":\n\t selfLocation = new Point(p.x + n.Size.width - shapeWidth, p.y + ((n.Size.height - shapeHeight) / 2));\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t x = selfLocation.x - this.options.horizontalSeparation; // alignment of children\n\t y = p.y;\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t pp = new Point(x - node.Size.width, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.verticalSeparation;\n\t }\n\t break;\n\n\t default:\n\t throw \"Unsupported TreeDirection\";\n\t }\n\n\t break;\n\t case \"Right\":\n\t switch (n.childrenLayout) {\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t selfLocation = p;\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t x = p.x + shapeWidth + this.options.underneathHorizontalOffset;\n\n\t // alignment of children left-underneath the parent\n\t y = p.y + shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.underneathVerticalSeparation;\n\t }\n\n\t break;\n\n\t case \"Default\":\n\t selfLocation = new Point(p.x, p.y + ((n.Size.height - shapeHeight) / 2));\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t x = p.x + shapeWidth + this.options.horizontalSeparation; // alignment of children\n\t y = p.y;\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.verticalSeparation;\n\t }\n\t break;\n\n\t default:\n\t throw \"Unsupported TreeDirection\";\n\t }\n\n\t break;\n\t case \"Up\":\n\t selfLocation = new Point(p.x + ((n.Size.width - shapeWidth) / 2), p.y + n.Size.height - shapeHeight);\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t if (Math.abs(selfLocation.x - p.x) < EPSILON) {\n\t childrenwidth = 0;\n\t // means there is an aberration due to the oversized Element with respect to the children\n\t for (i = 0; i < n.children.length; i++) {\n\t child = n.children[i];\n\t childrenwidth += child.Size.width + this.options.horizontalSeparation;\n\t }\n\t childrenwidth -= this.options.horizontalSeparation;\n\t x = p.x + ((shapeWidth - childrenwidth) / 2);\n\t }\n\t else {\n\t x = p.x;\n\t }\n\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t y = selfLocation.y - this.options.verticalSeparation - node.Size.height;\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\t break;\n\n\t case \"Down\":\n\n\t switch (n.childrenLayout) {\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\t case \"Underneath\":\n\t selfLocation = p;\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t x = p.x + this.options.underneathHorizontalOffset; // alignment of children left-underneath the parent\n\t y = p.y + shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.underneathVerticalSeparation;\n\t }\n\t break;\n\n\t case \"Default\":\n\t selfLocation = new Point(p.x + ((n.Size.width - shapeWidth) / 2), p.y);\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t if (Math.abs(selfLocation.x - p.x) < EPSILON) {\n\t childrenwidth = 0;\n\t // means there is an aberration due to the oversized Element with respect to the children\n\t for (i = 0; i < n.children.length; i++) {\n\t child = n.children[i];\n\t childrenwidth += child.Size.width + this.options.horizontalSeparation;\n\t }\n\n\t childrenwidth -= this.options.horizontalSeparation;\n\t x = p.x + ((shapeWidth - childrenwidth) / 2);\n\t }\n\t else {\n\t x = p.x;\n\t }\n\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t y = selfLocation.y + this.options.verticalSeparation + shapeHeight;\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\t break;\n\n\t default:\n\t throw \"Unsupported TreeDirection\";\n\t }\n\t break;\n\n\t case \"None\":\n\t break;\n\n\t default:\n\t throw \"Unsupported TreeDirection\";\n\t }\n\t }\n\t },\n\t layoutSwitch: function () {\n\t if (!this.center) {\n\t return;\n\t }\n\n\t if (Utils.isEmpty(this.center.children)) {\n\t return;\n\t }\n\n\t var type = this.options.subtype;\n\t if (Utils.isUndefined(type)) {\n\t type = \"Down\";\n\t }\n\t var single, male, female, leftcount;\n\t var children = this.center.children;\n\t switch (type.toLowerCase()) {\n\t case \"radial\":\n\t case \"radialtree\":\n\t this.layoutRadialTree();\n\t break;\n\n\t case \"mindmaphorizontal\":\n\t case \"mindmap\":\n\t single = this.center.children;\n\n\t if (this.center.children.length === 1) {\n\t this.layoutRight(single);\n\t }\n\t else {\n\t // odd number will give one more at the right\n\t leftcount = children.length / 2;\n\t male = grep(this.center.children, function (n) {\n\t return Utils.indexOf(children, n) < leftcount;\n\t });\n\t female = grep(this.center.children, function (n) {\n\t return Utils.indexOf(children, n) >= leftcount;\n\t });\n\n\t this.layoutLeft(male);\n\t this.layoutRight(female);\n\t }\n\t break;\n\n\t case \"mindmapvertical\":\n\t single = this.center.children;\n\n\t if (this.center.children.length === 1) {\n\t this.layoutDown(single);\n\t }\n\t else {\n\t // odd number will give one more at the right\n\t leftcount = children.length / 2;\n\t male = grep(this.center.children, function (n) {\n\t return Utils.indexOf(children, n) < leftcount;\n\t });\n\t female = grep(this.center.children, function (n) {\n\t return Utils.indexOf(children, n) >= leftcount;\n\t });\n\t this.layoutUp(male);\n\t this.layoutDown(female);\n\t }\n\t break;\n\n\t case \"right\":\n\t this.layoutRight(this.center.children);\n\t break;\n\n\t case \"left\":\n\t this.layoutLeft(this.center.children);\n\t break;\n\n\t case \"up\":\n\t case \"bottom\":\n\t this.layoutUp(this.center.children);\n\t break;\n\n\t case \"down\":\n\t case \"top\":\n\t this.layoutDown(this.center.children);\n\t break;\n\n\t case \"tipover\":\n\t case \"tipovertree\":\n\t if (this.options.tipOverTreeStartLevel < 0) {\n\t throw \"The tip-over level should be a positive integer.\";\n\t }\n\t this.tipOverTree(this.center.children, this.options.tipOverTreeStartLevel);\n\t break;\n\n\t case \"undefined\":\n\t case \"none\":\n\t break;\n\t }\n\t }\n\t });\n\n\t /**\n\t * The various tree layout algorithms.\n\t * @type {*}\n\t */\n\t var TreeLayout = LayoutBase.extend({\n\t init: function (diagram) {\n\t var that = this;\n\t LayoutBase.fn.init.call(that);\n\t if (Utils.isUndefined(diagram)) {\n\t throw \"No diagram specified.\";\n\t }\n\t this.diagram = diagram;\n\t },\n\n\t /**\n\t * Arranges the diagram in a tree-layout with the specified options and tree subtype.\n\t */\n\t layout: function (options) {\n\n\t this.transferOptions(options);\n\n\t // transform the diagram into a Graph\n\t var adapter = new DiagramToHyperTreeAdapter(this.diagram);\n\n\t /**\n\t * The Graph reduction from the given diagram.\n\t * @type {*}\n\t */\n\t this.graph = adapter.convert();\n\n\t var finalNodeSet = this.layoutComponents();\n\n\t // note that the graph contains the original data and\n\t // the components are another instance of nodes referring to the same set of shapes\n\t return new diagram.LayoutState(this.diagram, finalNodeSet);\n\t },\n\n\t layoutComponents: function () {\n\t if (this.graph.isEmpty()) {\n\t return;\n\t }\n\n\t // split into connected components\n\t var components = this.graph.getConnectedComponents();\n\t if (Utils.isEmpty(components)) {\n\t return;\n\t }\n\n\t var layout = new TreeLayoutProcessor(this.options);\n\t var trees = [];\n\t // find a spanning tree for each component\n\t for (var i = 0; i < components.length; i++) {\n\t var component = components[i];\n\n\t var treeGraph = this.getTree(component);\n\t if (!treeGraph) {\n\t throw \"Failed to find a spanning tree for the component.\";\n\t }\n\t var root = treeGraph.root;\n\t var tree = treeGraph.tree;\n\t layout.layout(tree, root);\n\n\t trees.push(tree);\n\t }\n\n\t return this.gridLayoutComponents(trees);\n\n\t },\n\n\t /**\n\t * Gets a spanning tree (and root) for the given graph.\n\t * Ensure that the given graph is connected!\n\t * @param graph\n\t * @returns {*} A literal object consisting of the found root and the spanning tree.\n\t */\n\t getTree: function (graph) {\n\t var root = null;\n\t if (this.options.roots && this.options.roots.length > 0) {\n\t for (var i = 0, len = graph.nodes.length; i < len; i++) {\n\t var node = graph.nodes[i];\n\t for (var j = 0; j < this.options.roots.length; j++) {\n\t var givenRootShape = this.options.roots[j];\n\t if (givenRootShape === node.associatedShape) {\n\t root = node;\n\t break;\n\t }\n\t }\n\t }\n\t }\n\t if (!root) {\n\t // finds the most probable root on the basis of the longest path in the component\n\t root = graph.root();\n\t // should not happen really\n\t if (!root) {\n\t throw \"Unable to find a root for the tree.\";\n\t }\n\t }\n\t return this.getTreeForRoot(graph, root);\n\t },\n\n\t getTreeForRoot: function (graph, root) {\n\n\t var tree = graph.getSpanningTree(root);\n\t if (Utils.isUndefined(tree) || tree.isEmpty()) {\n\t return null;\n\t }\n\t return {\n\t tree: tree,\n\t root: tree.root\n\t };\n\t }\n\n\t });\n\n\t /**\n\t * The Sugiyama aka layered layout algorithm.\n\t * @type {*}\n\t */\n\t var LayeredLayout = LayoutBase.extend({\n\t init: function (diagram) {\n\t var that = this;\n\t LayoutBase.fn.init.call(that);\n\t if (Utils.isUndefined(diagram)) {\n\t throw \"Diagram is not specified.\";\n\t }\n\t this.diagram = diagram;\n\t },\n\n\t layout: function (options) {\n\n\t this.transferOptions(options);\n\n\t var adapter = new DiagramToHyperTreeAdapter(this.diagram);\n\t var graph = adapter.convert(options);\n\t if (graph.isEmpty()) {\n\t return;\n\t }\n\t // split into connected components\n\t var components = graph.getConnectedComponents();\n\t if (Utils.isEmpty(components)) {\n\t return;\n\t }\n\t for (var i = 0; i < components.length; i++) {\n\t var component = components[i];\n\t this.layoutGraph(component, options);\n\t }\n\t var finalNodeSet = this.gridLayoutComponents(components);\n\t return new diagram.LayoutState(this.diagram, finalNodeSet);\n\n\t },\n\n\t /**\n\t * Initializes the runtime data properties of the layout.\n\t * @private\n\t */\n\t _initRuntimeProperties: function () {\n\t for (var k = 0; k < this.graph.nodes.length; k++) {\n\t var node = this.graph.nodes[k];\n\t node.layer = -1;\n\t node.downstreamLinkCount = 0;\n\t node.upstreamLinkCount = 0;\n\n\t node.isVirtual = false;\n\n\t node.uBaryCenter = 0.0;\n\t node.dBaryCenter = 0.0;\n\n\t node.upstreamPriority = 0;\n\t node.downstreamPriority = 0;\n\n\t node.gridPosition = 0;\n\t }\n\t },\n\t _prepare: function (graph) {\n\t var current = [], i, l, link;\n\n\t // defines a mapping of a node to the layer index\n\t var layerMap = new Dictionary();\n\t var layerCount = 0;\n\t var targetLayer, next, target;\n\n\t Utils.forEach(graph.nodes, function (node) {\n\t if (node.incoming.length === 0) {\n\t layerMap.set(node, 0);\n\t current.push(node);\n\t }\n\t });\n\n\t while (current.length > 0) {\n\t next = current.shift();\n\t for (i = 0; i < next.outgoing.length; i++) {\n\t link = next.outgoing[i];\n\t target = link.target;\n\n\t if (layerMap.containsKey(target)) {\n\t targetLayer = Math.max(layerMap.get(next) + 1, layerMap.get(target));\n\t } else {\n\t targetLayer = layerMap.get(next) + 1;\n\t }\n\t layerMap.set(target, targetLayer);\n\t if (targetLayer > layerCount) {\n\t layerCount = targetLayer;\n\t }\n\n\t if (!contains(current, target)) {\n\t current.push(target);\n\t }\n\t }\n\t }\n\n\t var sortedNodes = layerMap.keys();\n\n\t sortedNodes.sort(function (o1, o2) {\n\t var o1layer = layerMap.get(o1);\n\t var o2layer = layerMap.get(o2);\n\t return Utils.sign(o2layer - o1layer);\n\t });\n\n\t for (var n = 0; n < sortedNodes.length; ++n) {\n\t var node = sortedNodes[n];\n\t var minLayer = Number.MAX_VALUE;\n\n\t if (node.outgoing.length === 0) {\n\t continue;\n\t }\n\n\t for (l = 0; l < node.outgoing.length; ++l) {\n\t link = node.outgoing[l];\n\t minLayer = Math.min(minLayer, layerMap.get(link.target));\n\t }\n\n\t if (minLayer > 1) {\n\t layerMap.set(node, minLayer - 1);\n\t }\n\t }\n\n\t this.layers = [];\n\t var layer;\n\t for (i = 0; i < layerCount + 1; i++) {\n\t layer = [];\n\t layer.linksTo = {};\n\t this.layers.push(layer);\n\t }\n\n\t layerMap.forEach(function (node, layer) {\n\t node.layer = layer;\n\t this.layers[layer].push(node);\n\t }, this);\n\n\t // set initial grid positions\n\t for (l = 0; l < this.layers.length; l++) {\n\t layer = this.layers[l];\n\t for (i = 0; i < layer.length; i++) {\n\t layer[i].gridPosition = i;\n\t }\n\t }\n\t },\n\t /**\n\t * Performs the layout of a single component.\n\t */\n\t layoutGraph: function (graph, options) {\n\t if (Utils.isUndefined(graph)) {\n\t throw \"No graph given or graph analysis of the diagram failed.\";\n\t }\n\t if (Utils.isDefined(options)) {\n\t this.transferOptions(options);\n\t }\n\t this.graph = graph;\n\n\t // sets unique indices on the nodes\n\t graph.setItemIndices();\n\n\t // ensures no cycles present for this layout\n\t var reversedEdges = graph.makeAcyclic();\n\n\t // define the runtime props being used by the layout algorithm\n\t this._initRuntimeProperties();\n\n\t this._prepare(graph, options);\n\n\t this._dummify();\n\n\t this._optimizeCrossings();\n\n\t this._swapPairs();\n\n\t this.arrangeNodes();\n\n\t this._moveThingsAround();\n\n\t this._dedummify();\n\n\t // re-reverse the links which were switched earlier\n\t Utils.forEach(reversedEdges, function (e) {\n\t if (e.points) {\n\t e.points.reverse();\n\t }\n\t });\n\t },\n\n\t setMinDist: function (m, n, minDist) {\n\t var l = m.layer;\n\t var i = m.layerIndex;\n\t this.minDistances[l][i] = minDist;\n\t },\n\n\t getMinDist: function (m, n) {\n\t var dist = 0,\n\t i1 = m.layerIndex,\n\t i2 = n.layerIndex,\n\t l = m.layer,\n\t min = Math.min(i1, i2),\n\t max = Math.max(i1, i2);\n\t // use Sum()?\n\t for (var k = min; k < max; ++k) {\n\t dist += this.minDistances[l][k];\n\t }\n\t return dist;\n\t },\n\n\t placeLeftToRight: function (leftClasses) {\n\t var leftPos = new Dictionary(), n, node;\n\t for (var c = 0; c < this.layers.length; ++c) {\n\t var classNodes = leftClasses[c];\n\t if (!classNodes) {\n\t continue;\n\t }\n\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t if (!leftPos.containsKey(node)) {\n\t this.placeLeft(node, leftPos, c);\n\t }\n\t }\n\n\t // adjust class\n\t var d = Number.POSITIVE_INFINITY;\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t var rightSibling = this.rightSibling(node);\n\t if (rightSibling && this.nodeLeftClass.get(rightSibling) !== c) {\n\t d = Math.min(d, leftPos.get(rightSibling) - leftPos.get(node) - this.getMinDist(node, rightSibling));\n\t }\n\t }\n\t if (d === Number.POSITIVE_INFINITY) {\n\t var D = [];\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t var neighbors = [];\n\t Utils.addRange(neighbors, this.upNodes.get(node));\n\t Utils.addRange(neighbors, this.downNodes.get(node));\n\n\t for (var e = 0; e < neighbors.length; e++) {\n\t var neighbor = neighbors[e];\n\t if (this.nodeLeftClass.get(neighbor) < c) {\n\t D.push(leftPos.get(neighbor) - leftPos.get(node));\n\t }\n\t }\n\t }\n\t D.sort();\n\t if (D.length === 0) {\n\t d = 0;\n\t }\n\t else if (D.length % 2 === 1) {\n\t d = D[this.intDiv(D.length, 2)];\n\t }\n\t else {\n\t d = (D[this.intDiv(D.length, 2) - 1] + D[this.intDiv(D.length, 2)]) / 2;\n\t }\n\t }\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t leftPos.set(node, leftPos.get(node) + d);\n\t }\n\t }\n\t return leftPos;\n\t },\n\n\t placeRightToLeft: function (rightClasses) {\n\t var rightPos = new Dictionary(), n, node;\n\t for (var c = 0; c < this.layers.length; ++c) {\n\t var classNodes = rightClasses[c];\n\t if (!classNodes) {\n\t continue;\n\t }\n\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t if (!rightPos.containsKey(node)) {\n\t this.placeRight(node, rightPos, c);\n\t }\n\t }\n\n\t // adjust class\n\t var d = Number.NEGATIVE_INFINITY;\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t var leftSibling = this.leftSibling(node);\n\t if (leftSibling && this.nodeRightClass.get(leftSibling) !== c) {\n\t d = Math.max(d, rightPos.get(leftSibling) - rightPos.get(node) + this.getMinDist(leftSibling, node));\n\t }\n\t }\n\t if (d === Number.NEGATIVE_INFINITY) {\n\t var D = [];\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t var neighbors = [];\n\t Utils.addRange(neighbors, this.upNodes.get(node));\n\t Utils.addRange(neighbors, this.downNodes.get(node));\n\n\t for (var e = 0; e < neighbors.length; e++) {\n\t var neighbor = neighbors[e];\n\t if (this.nodeRightClass.get(neighbor) < c) {\n\t D.push(rightPos.get(node) - rightPos.get(neighbor));\n\t }\n\t }\n\t }\n\t D.sort();\n\t if (D.length === 0) {\n\t d = 0;\n\t }\n\t else if (D.length % 2 === 1) {\n\t d = D[this.intDiv(D.length, 2)];\n\t }\n\t else {\n\t d = (D[this.intDiv(D.length, 2) - 1] + D[this.intDiv(D.length, 2)]) / 2;\n\t }\n\t }\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t rightPos.set(node, rightPos.get(node) + d);\n\t }\n\t }\n\t return rightPos;\n\t },\n\n\t _getLeftWing: function () {\n\t var leftWing = { value: null };\n\t var result = this.computeClasses(leftWing, 1);\n\t this.nodeLeftClass = leftWing.value;\n\t return result;\n\t },\n\n\t _getRightWing: function () {\n\t var rightWing = { value: null };\n\t var result = this.computeClasses(rightWing, -1);\n\t this.nodeRightClass = rightWing.value;\n\t return result;\n\t },\n\n\t computeClasses: function (wingPair, d) {\n\t var currentWing = 0,\n\t wing = wingPair.value = new Dictionary();\n\n\t for (var l = 0; l < this.layers.length; ++l) {\n\t currentWing = l;\n\n\t var layer = this.layers[l];\n\t for (var n = d === 1 ? 0 : layer.length - 1; 0 <= n && n < layer.length; n += d) {\n\t var node = layer[n];\n\t if (!wing.containsKey(node)) {\n\t wing.set(node, currentWing);\n\t if (node.isVirtual) {\n\t var ndsinl = this._nodesInLink(node);\n\t for (var kk = 0; kk < ndsinl.length; kk++) {\n\t var vnode = ndsinl[kk];\n\t wing.set(vnode, currentWing);\n\t }\n\t }\n\t }\n\t else {\n\t currentWing = wing.get(node);\n\t }\n\t }\n\t }\n\n\t var wings = [];\n\t for (var i = 0; i < this.layers.length; i++) {\n\t wings.push(null);\n\t }\n\t wing.forEach(function (node, classIndex) {\n\t if (wings[classIndex] === null) {\n\t wings[classIndex] = [];\n\t }\n\t wings[classIndex].push(node);\n\t });\n\n\t return wings;\n\t },\n\t _isVerticalLayout: function () {\n\t return this.options.subtype.toLowerCase() === \"up\" || this.options.subtype.toLowerCase() === \"down\" || this.options.subtype.toLowerCase() === \"vertical\";\n\t },\n\n\t _isHorizontalLayout: function () {\n\t return this.options.subtype.toLowerCase() === \"right\" || this.options.subtype.toLowerCase() === \"left\" || this.options.subtype.toLowerCase() === \"horizontal\";\n\t },\n\t _isIncreasingLayout: function () {\n\t // meaning that the visiting of the layers goes in the natural order of increasing layer index\n\t return this.options.subtype.toLowerCase() === \"right\" || this.options.subtype.toLowerCase() === \"down\";\n\t },\n\t _moveThingsAround: function () {\n\t var i, l, node, layer, n, w;\n\t // sort the layers by their grid position\n\t for (l = 0; l < this.layers.length; ++l) {\n\t layer = this.layers[l];\n\t layer.sort(this._gridPositionComparer);\n\t }\n\n\t this.minDistances = [];\n\t for (l = 0; l < this.layers.length; ++l) {\n\t layer = this.layers[l];\n\t this.minDistances[l] = [];\n\t for (n = 0; n < layer.length; ++n) {\n\t node = layer[n];\n\t node.layerIndex = n;\n\t this.minDistances[l][n] = this.options.nodeDistance;\n\t if (n < layer.length - 1) {\n\t if (this._isVerticalLayout()) {\n\t this.minDistances[l][n] += (node.width + layer[n + 1].width) / 2;\n\t }\n\t else {\n\t this.minDistances[l][n] += (node.height + layer[n + 1].height) / 2;\n\t }\n\t }\n\t }\n\t }\n\n\t this.downNodes = new Dictionary();\n\t this.upNodes = new Dictionary();\n\t Utils.forEach(this.graph.nodes, function (node) {\n\t this.downNodes.set(node, []);\n\t this.upNodes.set(node, []);\n\t }, this);\n\t Utils.forEach(this.graph.links, function (link) {\n\t var origin = link.source;\n\t var dest = link.target;\n\t var down = null, up = null;\n\t if (origin.layer > dest.layer) {\n\t down = link.source;\n\t up = link.target;\n\t }\n\t else {\n\t up = link.source;\n\t down = link.target;\n\t }\n\t this.downNodes.get(up).push(down);\n\t this.upNodes.get(down).push(up);\n\t }, this);\n\t this.downNodes.forEachValue(function (list) {\n\t list.sort(this._gridPositionComparer);\n\t }, this);\n\t this.upNodes.forEachValue(function (list) {\n\t list.sort(this._gridPositionComparer);\n\t }, this);\n\n\t for (l = 0; l < this.layers.length - 1; ++l) {\n\t layer = this.layers[l];\n\t for (w = 0; w < layer.length - 1; w++) {\n\t var currentNode = layer[w];\n\t if (!currentNode.isVirtual) {\n\t continue;\n\t }\n\n\t var currDown = this.downNodes.get(currentNode)[0];\n\t if (!currDown.isVirtual) {\n\t continue;\n\t }\n\n\t for (n = w + 1; n < layer.length; ++n) {\n\t node = layer[n];\n\t if (!node.isVirtual) {\n\t continue;\n\t }\n\n\t var downNode = this.downNodes.get(node)[0];\n\t if (!downNode.isVirtual) {\n\t continue;\n\t }\n\n\t if (currDown.gridPosition > downNode.gridPosition) {\n\t var pos = currDown.gridPosition;\n\t currDown.gridPosition = downNode.gridPosition;\n\t downNode.gridPosition = pos;\n\t var i1 = currDown.layerIndex;\n\t var i2 = downNode.layerIndex;\n\t this.layers[l + 1][i1] = downNode;\n\t this.layers[l + 1][i2] = currDown;\n\t currDown.layerIndex = i2;\n\t downNode.layerIndex = i1;\n\t }\n\t }\n\t }\n\t }\n\n\n\t var leftClasses = this._getLeftWing();\n\t var rightClasses = this._getRightWing();\n\n\n\t var leftPos = this.placeLeftToRight(leftClasses);\n\t var rightPos = this.placeRightToLeft(rightClasses);\n\t var x = new Dictionary();\n\t Utils.forEach(this.graph.nodes, function (node) {\n\t x.set(node, (leftPos.get(node) + rightPos.get(node)) / 2);\n\t });\n\n\n\t var order = new Dictionary();\n\t var placed = new Dictionary();\n\t for (l = 0; l < this.layers.length; ++l) {\n\t layer = this.layers[l];\n\t var sequenceStart = -1, sequenceEnd = -1;\n\t for (n = 0; n < layer.length; ++n) {\n\t node = layer[n];\n\t order.set(node, 0);\n\t placed.set(node, false);\n\t if (node.isVirtual) {\n\t if (sequenceStart === -1) {\n\t sequenceStart = n;\n\t }\n\t else if (sequenceStart === n - 1) {\n\t sequenceStart = n;\n\t }\n\t else {\n\t sequenceEnd = n;\n\t order.set(layer[sequenceStart], 0);\n\t if (x.get(node) - x.get(layer[sequenceStart]) === this.getMinDist(layer[sequenceStart], node)) {\n\t placed.set(layer[sequenceStart], true);\n\t }\n\t else {\n\t placed.set(layer[sequenceStart], false);\n\t }\n\t sequenceStart = n;\n\t }\n\t }\n\t }\n\t }\n\t var directions = [1, -1];\n\t Utils.forEach(directions, function (d) {\n\t var start = d === 1 ? 0 : this.layers.length - 1;\n\t for (var l = start; 0 <= l && l < this.layers.length; l += d) {\n\t var layer = this.layers[l];\n\t var virtualStartIndex = this._firstVirtualNode(layer);\n\t var virtualStart = null;\n\t var sequence = null;\n\t if (virtualStartIndex !== -1) {\n\t virtualStart = layer[virtualStartIndex];\n\t sequence = [];\n\t for (i = 0; i < virtualStartIndex; i++) {\n\t sequence.push(layer[i]);\n\t }\n\t }\n\t else {\n\t virtualStart = null;\n\t sequence = layer;\n\t }\n\t if (sequence.length > 0) {\n\t this._sequencer(x, null, virtualStart, d, sequence);\n\t for (i = 0; i < sequence.length - 1; ++i) {\n\t this.setMinDist(sequence[i], sequence[i + 1], x.get(sequence[i + 1]) - x.get(sequence[i]));\n\t }\n\t if (virtualStart) {\n\t this.setMinDist(sequence[sequence.length - 1], virtualStart, x.get(virtualStart) - x.get(sequence[sequence.length - 1]));\n\t }\n\t }\n\n\t while (virtualStart) {\n\t var virtualEnd = this.nextVirtualNode(layer, virtualStart);\n\t if (!virtualEnd) {\n\t virtualStartIndex = virtualStart.layerIndex;\n\t sequence = [];\n\t for (i = virtualStartIndex + 1; i < layer.length; i++) {\n\t sequence.push(layer[i]);\n\t }\n\t if (sequence.length > 0) {\n\t this._sequencer(x, virtualStart, null, d, sequence);\n\t for (i = 0; i < sequence.length - 1; ++i) {\n\t this.setMinDist(sequence[i], sequence[i + 1], x.get(sequence[i + 1]) - x.get(sequence[i]));\n\t }\n\t this.setMinDist(virtualStart, sequence[0], x.get(sequence[0]) - x.get(virtualStart));\n\t }\n\t }\n\t else if (order.get(virtualStart) === d) {\n\t virtualStartIndex = virtualStart.layerIndex;\n\t var virtualEndIndex = virtualEnd.layerIndex;\n\t sequence = [];\n\t for (i = virtualStartIndex + 1; i < virtualEndIndex; i++) {\n\t sequence.push(layer[i]);\n\t }\n\t if (sequence.length > 0) {\n\t this._sequencer(x, virtualStart, virtualEnd, d, sequence);\n\t }\n\t placed.set(virtualStart, true);\n\t }\n\t virtualStart = virtualEnd;\n\t }\n\t this.adjustDirections(l, d, order, placed);\n\t }\n\t }, this);\n\n\n\t var fromLayerIndex = this._isIncreasingLayout() ? 0 : this.layers.length - 1;\n\t var reachedFinalLayerIndex = function (k, ctx) {\n\t if (ctx._isIncreasingLayout()) {\n\t return k < ctx.layers.length;\n\t }\n\t else {\n\t return k >= 0;\n\t }\n\t };\n\t var layerIncrement = this._isIncreasingLayout() ? +1 : -1, offset = 0;\n\n\t /**\n\t * Calcs the max height of the given layer.\n\t */\n\t function maximumHeight(layer, ctx) {\n\t var height = Number.MIN_VALUE;\n\t for (var n = 0; n < layer.length; ++n) {\n\t var node = layer[n];\n\t if (ctx._isVerticalLayout()) {\n\t height = Math.max(height, node.height);\n\t }\n\t else {\n\t height = Math.max(height, node.width);\n\t }\n\t }\n\t return height;\n\t }\n\n\t for (i = fromLayerIndex; reachedFinalLayerIndex(i, this); i += layerIncrement) {\n\t layer = this.layers[i];\n\t var height = maximumHeight(layer, this);\n\n\t for (n = 0; n < layer.length; ++n) {\n\t node = layer[n];\n\t if (this._isVerticalLayout()) {\n\t node.x = x.get(node);\n\t node.y = offset + height / 2;\n\t }\n\t else {\n\t node.x = offset + height / 2;\n\t node.y = x.get(node);\n\t }\n\t }\n\n\t offset += this.options.layerSeparation + height;\n\t }\n\t },\n\n\t adjustDirections: function (l, d, order, placed) {\n\t if (l + d < 0 || l + d >= this.layers.length) {\n\t return;\n\t }\n\n\t var prevBridge = null, prevBridgeTarget = null;\n\t var layer = this.layers[l + d];\n\t for (var n = 0; n < layer.length; ++n) {\n\t var nextBridge = layer[n];\n\t if (nextBridge.isVirtual) {\n\t var nextBridgeTarget = this.getNeighborOnLayer(nextBridge, l);\n\t if (nextBridgeTarget.isVirtual) {\n\t if (prevBridge) {\n\t var p = placed.get(prevBridgeTarget);\n\t var clayer = this.layers[l];\n\t var i1 = prevBridgeTarget.layerIndex;\n\t var i2 = nextBridgeTarget.layerIndex;\n\t for (var i = i1 + 1; i < i2; ++i) {\n\t if (clayer[i].isVirtual) {\n\t p = p && placed.get(clayer[i]);\n\t }\n\t }\n\t if (p) {\n\t order.set(prevBridge, d);\n\t var j1 = prevBridge.layerIndex;\n\t var j2 = nextBridge.layerIndex;\n\t for (var j = j1 + 1; j < j2; ++j) {\n\t if (layer[j].isVirtual) {\n\t order.set(layer[j], d);\n\t }\n\t }\n\t }\n\t }\n\t prevBridge = nextBridge;\n\t prevBridgeTarget = nextBridgeTarget;\n\t }\n\t }\n\t }\n\t },\n\n\t getNeighborOnLayer: function (node, l) {\n\t var neighbor = this.upNodes.get(node)[0];\n\t if (neighbor.layer === l) {\n\t return neighbor;\n\t }\n\t neighbor = this.downNodes.get(node)[0];\n\t if (neighbor.layer === l) {\n\t return neighbor;\n\t }\n\t return null;\n\t },\n\n\t _sequencer: function (x, virtualStart, virtualEnd, dir, sequence) {\n\t if (sequence.length === 1) {\n\t this._sequenceSingle(x, virtualStart, virtualEnd, dir, sequence[0]);\n\t }\n\n\t if (sequence.length > 1) {\n\t var r = sequence.length, t = this.intDiv(r, 2);\n\t this._sequencer(x, virtualStart, virtualEnd, dir, sequence.slice(0, t));\n\t this._sequencer(x, virtualStart, virtualEnd, dir, sequence.slice(t));\n\t this.combineSequences(x, virtualStart, virtualEnd, dir, sequence);\n\t }\n\t },\n\n\t _sequenceSingle: function (x, virtualStart, virtualEnd, dir, node) {\n\t var neighbors = dir === -1 ? this.downNodes.get(node) : this.upNodes.get(node);\n\n\t var n = neighbors.length;\n\t if (n !== 0) {\n\t if (n % 2 === 1) {\n\t x.set(node, x.get(neighbors[this.intDiv(n, 2)]));\n\t }\n\t else {\n\t x.set(node, (x.get(neighbors[this.intDiv(n, 2) - 1]) + x.get(neighbors[this.intDiv(n, 2)])) / 2);\n\t }\n\n\t if (virtualStart) {\n\t x.set(node, Math.max(x.get(node), x.get(virtualStart) + this.getMinDist(virtualStart, node)));\n\t }\n\t if (virtualEnd) {\n\t x.set(node, Math.min(x.get(node), x.get(virtualEnd) - this.getMinDist(node, virtualEnd)));\n\t }\n\t }\n\t },\n\n\t combineSequences: function (x, virtualStart, virtualEnd, dir, sequence) {\n\t var r = sequence.length, t = this.intDiv(r, 2);\n\n\t // collect left changes\n\t var leftHeap = [], i, c, n, neighbors, neighbor, pair;\n\t for (i = 0; i < t; ++i) {\n\t c = 0;\n\t neighbors = dir === -1 ? this.downNodes.get(sequence[i]) : this.upNodes.get(sequence[i]);\n\t for (n = 0; n < neighbors.length; ++n) {\n\t neighbor = neighbors[n];\n\t if (x.get(neighbor) >= x.get(sequence[i])) {\n\t c++;\n\t }\n\t else {\n\t c--;\n\t leftHeap.push({ k: x.get(neighbor) + this.getMinDist(sequence[i], sequence[t - 1]), v: 2 });\n\t }\n\t }\n\t leftHeap.push({ k: x.get(sequence[i]) + this.getMinDist(sequence[i], sequence[t - 1]), v: c });\n\t }\n\t if (virtualStart) {\n\t leftHeap.push({ k: x.get(virtualStart) + this.getMinDist(virtualStart, sequence[t - 1]), v: Number.MAX_VALUE });\n\t }\n\t leftHeap.sort(this._positionDescendingComparer);\n\n\t // collect right changes\n\t var rightHeap = [];\n\t for (i = t; i < r; ++i) {\n\t c = 0;\n\t neighbors = dir === -1 ? this.downNodes.get(sequence[i]) : this.upNodes.get(sequence[i]);\n\t for (n = 0; n < neighbors.length; ++n) {\n\t neighbor = neighbors[n];\n\t if (x.get(neighbor) <= x.get(sequence[i])) {\n\t c++;\n\t }\n\t else {\n\t c--;\n\t rightHeap.push({ k: x.get(neighbor) - this.getMinDist(sequence[i], sequence[t]), v: 2 });\n\t }\n\t }\n\t rightHeap.push({ k: x.get(sequence[i]) - this.getMinDist(sequence[i], sequence[t]), v: c });\n\t }\n\t if (virtualEnd) {\n\t rightHeap.push({ k: x.get(virtualEnd) - this.getMinDist(virtualEnd, sequence[t]), v: Number.MAX_VALUE });\n\t }\n\t rightHeap.sort(this._positionAscendingComparer);\n\n\t var leftRes = 0, rightRes = 0;\n\t var m = this.getMinDist(sequence[t - 1], sequence[t]);\n\t while (x.get(sequence[t]) - x.get(sequence[t - 1]) < m) {\n\t if (leftRes < rightRes) {\n\t if (leftHeap.length === 0) {\n\t x.set(sequence[t - 1], x.get(sequence[t]) - m);\n\t break;\n\t }\n\t else {\n\t pair = leftHeap.shift();\n\t leftRes = leftRes + pair.v;\n\t x.set(sequence[t - 1], pair.k);\n\t x.set(sequence[t - 1], Math.max(x.get(sequence[t - 1]), x.get(sequence[t]) - m));\n\t }\n\t }\n\t else {\n\t if (rightHeap.length === 0) {\n\t x.set(sequence[t], x.get(sequence[t - 1]) + m);\n\t break;\n\t }\n\t else {\n\t pair = rightHeap.shift();\n\t rightRes = rightRes + pair.v;\n\t x.set(sequence[t], pair.k);\n\t x.set(sequence[t], Math.min(x.get(sequence[t]), x.get(sequence[t - 1]) + m));\n\t }\n\t }\n\t }\n\t for (i = t - 2; i >= 0; i--) {\n\t x.set(sequence[i], Math.min(x.get(sequence[i]), x.get(sequence[t - 1]) - this.getMinDist(sequence[i], sequence[t - 1])));\n\t }\n\t for (i = t + 1; i < r; i++) {\n\t x.set(sequence[i], Math.max(x.get(sequence[i]), x.get(sequence[t]) + this.getMinDist(sequence[i], sequence[t])));\n\t }\n\t },\n\n\t placeLeft: function (node, leftPos, leftClass) {\n\t var pos = Number.NEGATIVE_INFINITY;\n\t Utils.forEach(this._getComposite(node), function (v) {\n\t var leftSibling = this.leftSibling(v);\n\t if (leftSibling && this.nodeLeftClass.get(leftSibling) === this.nodeLeftClass.get(v)) {\n\t if (!leftPos.containsKey(leftSibling)) {\n\t this.placeLeft(leftSibling, leftPos, leftClass);\n\t }\n\t pos = Math.max(pos, leftPos.get(leftSibling) + this.getMinDist(leftSibling, v));\n\t }\n\t }, this);\n\t if (pos === Number.NEGATIVE_INFINITY) {\n\t pos = 0;\n\t }\n\t Utils.forEach(this._getComposite(node), function (v) {\n\t leftPos.set(v, pos);\n\t });\n\t },\n\n\t placeRight: function (node, rightPos, rightClass) {\n\t var pos = Number.POSITIVE_INFINITY;\n\t Utils.forEach(this._getComposite(node), function (v) {\n\t var rightSibling = this.rightSibling(v);\n\t if (rightSibling && this.nodeRightClass.get(rightSibling) === this.nodeRightClass.get(v)) {\n\t if (!rightPos.containsKey(rightSibling)) {\n\t this.placeRight(rightSibling, rightPos, rightClass);\n\t }\n\t pos = Math.min(pos, rightPos.get(rightSibling) - this.getMinDist(v, rightSibling));\n\t }\n\t }, this);\n\t if (pos === Number.POSITIVE_INFINITY) {\n\t pos = 0;\n\t }\n\t Utils.forEach(this._getComposite(node), function (v) {\n\t rightPos.set(v, pos);\n\t });\n\t },\n\n\t leftSibling: function (node) {\n\t var layer = this.layers[node.layer],\n\t layerIndex = node.layerIndex;\n\t return layerIndex === 0 ? null : layer[layerIndex - 1];\n\t },\n\n\t rightSibling: function (node) {\n\t var layer = this.layers[node.layer];\n\t var layerIndex = node.layerIndex;\n\t return layerIndex === layer.length - 1 ? null : layer[layerIndex + 1];\n\n\t },\n\n\t _getComposite: function (node) {\n\t return node.isVirtual ? this._nodesInLink(node) : [node];\n\t },\n\n\t arrangeNodes: function () {\n\t var i, l, ni, layer, node;\n\t // Initialize node's base priority\n\t for (l = 0; l < this.layers.length; l++) {\n\t layer = this.layers[l];\n\n\t for (ni = 0; ni < layer.length; ni++) {\n\t node = layer[ni];\n\t node.upstreamPriority = node.upstreamLinkCount;\n\t node.downstreamPriority = node.downstreamLinkCount;\n\t }\n\t }\n\n\t // Layout is invoked after MinimizeCrossings\n\t // so we may assume node's barycenters are initially correct\n\n\t var maxLayoutIterations = 2;\n\t for (var it = 0; it < maxLayoutIterations; it++) {\n\t for (i = this.layers.length - 1; i >= 1; i--) {\n\t this.layoutLayer(false, i);\n\t }\n\n\t for (i = 0; i < this.layers.length - 1; i++) {\n\t this.layoutLayer(true, i);\n\t }\n\t }\n\n\t // Offset the whole structure so that there are no gridPositions < 0\n\t var gridPos = Number.MAX_VALUE;\n\t for (l = 0; l < this.layers.length; l++) {\n\t layer = this.layers[l];\n\n\t for (ni = 0; ni < layer.length; ni++) {\n\t node = layer[ni];\n\t gridPos = Math.min(gridPos, node.gridPosition);\n\t }\n\t }\n\n\t if (gridPos < 0) {\n\t for (l = 0; l < this.layers.length; l++) {\n\t layer = this.layers[l];\n\n\t for (ni = 0; ni < layer.length; ni++) {\n\t node = layer[ni];\n\t node.gridPosition = node.gridPosition - gridPos;\n\t }\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Layout of a single layer.\n\t /// \n\t /// The layer to organize.\n\t /// If set to true we move down in the layer stack.\n\t /// \n\t layoutLayer: function (down, layer) {\n\t var iconsidered;\n\t var considered;\n\n\t if (down) {\n\t considered = this.layers[iconsidered = layer + 1];\n\t }\n\t else {\n\t considered = this.layers[iconsidered = layer - 1];\n\t }\n\n\t // list containing the nodes in the considered layer sorted by priority\n\t var sorted = [];\n\t for (var n = 0; n < considered.length; n++) {\n\t sorted.push(considered[n]);\n\t }\n\t sorted.sort(function (n1, n2) {\n\t var n1Priority = (n1.upstreamPriority + n1.downstreamPriority) / 2;\n\t var n2Priority = (n2.upstreamPriority + n2.downstreamPriority) / 2;\n\n\t if (Math.abs(n1Priority - n2Priority) < 0.0001) {\n\t return 0;\n\t }\n\t if (n1Priority < n2Priority) {\n\t return 1;\n\t }\n\t return -1;\n\t });\n\n\t // each node strives for its barycenter; high priority nodes start first\n\t Utils.forEach(sorted, function (node) {\n\t var nodeGridPos = node.gridPosition;\n\t var nodeBaryCenter = this.calcBaryCenter(node);\n\t var nodePriority = (node.upstreamPriority + node.downstreamPriority) / 2;\n\n\t if (Math.abs(nodeGridPos - nodeBaryCenter) < 0.0001) {\n\t // This node is exactly at its barycenter -> perfect\n\t return;\n\t }\n\n\t if (Math.abs(nodeGridPos - nodeBaryCenter) < 0.25 + 0.0001) {\n\t // This node is close enough to the barycenter -> should work\n\t return;\n\t }\n\n\t if (nodeGridPos < nodeBaryCenter) {\n\t // Try to move the node to the right in an\n\t // attempt to reach its barycenter\n\t while (nodeGridPos < nodeBaryCenter) {\n\t if (!this.moveRight(node, considered, nodePriority)) {\n\t break;\n\t }\n\n\t nodeGridPos = node.gridPosition;\n\t }\n\t }\n\t else {\n\t // Try to move the node to the left in an\n\t // attempt to reach its barycenter\n\t while (nodeGridPos > nodeBaryCenter) {\n\t if (!this.moveLeft(node, considered, nodePriority)) {\n\t break;\n\t }\n\n\t nodeGridPos = node.gridPosition;\n\t }\n\t }\n\t }, this);\n\n\t // after the layer has been rearranged we need to recalculate the barycenters\n\t // of the nodes in the surrounding layers\n\t if (iconsidered > 0) {\n\t this.calcDownData(iconsidered - 1);\n\t }\n\t if (iconsidered < this.layers.length - 1) {\n\t this.calcUpData(iconsidered + 1);\n\t }\n\t },\n\n\t /// \n\t /// Moves the node to the right and returns true if this was possible.\n\t /// \n\t /// The node.\n\t /// The layer.\n\t /// Returns true if the shift was possible, otherwise false.\n\t moveRight: function (node, layer, priority) {\n\t var index = Utils.indexOf(layer, node);\n\t if (index === layer.length - 1) {\n\t // this is the last node in the layer, so we can move to the right without troubles\n\t node.gridPosition = node.gridPosition + 0.5;\n\t return true;\n\t }\n\n\t var rightNode = layer[index + 1];\n\t var rightNodePriority = (rightNode.upstreamPriority + rightNode.downstreamPriority) / 2;\n\n\t // check if there is space between the right and the current node\n\t if (rightNode.gridPosition > node.gridPosition + 1) {\n\t node.gridPosition = node.gridPosition + 0.5;\n\t return true;\n\t }\n\n\t // we have reached a node with higher priority; no movement is allowed\n\t if (rightNodePriority > priority ||\n\t Math.abs(rightNodePriority - priority) < 0.0001) {\n\t return false;\n\t }\n\n\t // the right node has lower priority - try to move it\n\t if (this.moveRight(rightNode, layer, priority)) {\n\t node.gridPosition = node.gridPosition + 0.5;\n\t return true;\n\t }\n\n\t return false;\n\t },\n\n\t /// \n\t /// Moves the node to the left and returns true if this was possible.\n\t /// \n\t /// The node.\n\t /// The layer.\n\t /// Returns true if the shift was possible, otherwise false.\n\t moveLeft: function (node, layer, priority) {\n\t var index = Utils.indexOf(layer, node);\n\t if (index === 0) {\n\t // this is the last node in the layer, so we can move to the left without troubles\n\t node.gridPosition = node.gridPosition - 0.5;\n\t return true;\n\t }\n\n\t var leftNode = layer[index - 1];\n\t var leftNodePriority = (leftNode.upstreamPriority + leftNode.downstreamPriority) / 2;\n\n\t // check if there is space between the left and the current node\n\t if (leftNode.gridPosition < node.gridPosition - 1) {\n\t node.gridPosition = node.gridPosition - 0.5;\n\t return true;\n\t }\n\n\t // we have reached a node with higher priority; no movement is allowed\n\t if (leftNodePriority > priority ||\n\t Math.abs(leftNodePriority - priority) < 0.0001) {\n\t return false;\n\t }\n\n\t // The left node has lower priority - try to move it\n\t if (this.moveLeft(leftNode, layer, priority)) {\n\t node.gridPosition = node.gridPosition - 0.5;\n\t return true;\n\t }\n\n\t return false;\n\t },\n\n\t mapVirtualNode: function (node, link) {\n\t this.nodeToLinkMap.set(node, link);\n\t if (!this.linkToNodeMap.containsKey(link)) {\n\t this.linkToNodeMap.set(link, []);\n\t }\n\t this.linkToNodeMap.get(link).push(node);\n\t },\n\n\t _nodesInLink: function (node) {\n\t return this.linkToNodeMap.get(this.nodeToLinkMap.get(node));\n\t },\n\n\t /// \n\t /// Inserts dummy nodes to break long links.\n\t /// \n\t _dummify: function () {\n\t this.linkToNodeMap = new Dictionary();\n\t this.nodeToLinkMap = new Dictionary();\n\n\t var layer, pos, newNode, node, r, newLink, i, l, links = this.graph.links.slice(0);\n\t var layers = this.layers;\n\n\t var addLinkBetweenLayers = function(upLayer, downLayer, link) {\n\t layers[upLayer].linksTo[downLayer] = layers[upLayer].linksTo[downLayer] || [];\n\t layers[upLayer].linksTo[downLayer].push(link);\n\t };\n\n\t for (l = 0; l < links.length; l++) {\n\t var link = links[l];\n\t var o = link.source;\n\t var d = link.target;\n\n\t var oLayer = o.layer;\n\t var dLayer = d.layer;\n\t var oPos = o.gridPosition;\n\t var dPos = d.gridPosition;\n\n\t var step = (dPos - oPos) / Math.abs(dLayer - oLayer);\n\n\t var p = o;\n\t if (oLayer - dLayer > 1) {\n\t for (i = oLayer - 1; i > dLayer; i--) {\n\t newNode = new Node();\n\t newNode.x = o.x;\n\t newNode.y = o.y;\n\t newNode.width = o.width / 100;\n\t newNode.height = o.height / 100;\n\n\t layer = layers[i];\n\t pos = (i - dLayer) * step + oPos;\n\t if (pos > layer.length) {\n\t pos = layer.length;\n\t }\n\n\t // check if origin and dest are both last\n\t if (oPos >= layers[oLayer].length - 1 &&\n\t dPos >= layers[dLayer].length - 1) {\n\t pos = layer.length;\n\t }\n\n\t // check if origin and destination are both first\n\t else if (oPos === 0 && dPos === 0) {\n\t pos = 0;\n\t }\n\n\t newNode.layer = i;\n\t newNode.uBaryCenter = 0.0;\n\t newNode.dBaryCenter = 0.0;\n\t newNode.upstreamLinkCount = 0;\n\t newNode.downstreamLinkCount = 0;\n\t newNode.gridPosition = pos;\n\t newNode.isVirtual = true;\n\n\t Utils.insert(layer, newNode, pos);\n\n\t // translate rightwards nodes' positions\n\t for (r = pos + 1; r < layer.length; r++) {\n\t node = layer[r];\n\t node.gridPosition = node.gridPosition + 1;\n\t }\n\n\t newLink = new Link(p, newNode);\n\t newLink.depthOfDumminess = 0;\n\n\t addLinkBetweenLayers(i - 1, i, newLink);\n\n\t p = newNode;\n\n\t // add the new node and the new link to the graph\n\t this.graph._addNode(newNode);\n\t this.graph.addLink(newLink);\n\n\t newNode.index = this.graph.nodes.length - 1;\n\t this.mapVirtualNode(newNode, link);\n\t }\n\n\t // set the origin of the real arrow to the last dummy\n\t addLinkBetweenLayers(dLayer - 1, dLayer, newLink);\n\t link.changeSource(p);\n\t link.depthOfDumminess = oLayer - dLayer - 1;\n\t } else if (oLayer - dLayer < -1) {\n\t for (i = oLayer + 1; i < dLayer; i++) {\n\t newNode = new Node();\n\t newNode.x = o.x;\n\t newNode.y = o.y;\n\t newNode.width = o.width / 100;\n\t newNode.height = o.height / 100;\n\n\t layer = layers[i];\n\t pos = (i - oLayer) * step + oPos;\n\t if (pos > layer.length) {\n\t pos = layer.length;\n\t }\n\n\t // check if origin and dest are both last\n\t if (oPos >= layers[oLayer].length - 1 &&\n\t dPos >= layers[dLayer].length - 1) {\n\t pos = layer.length;\n\t }\n\n\t // check if origin and destination are both first\n\t else if (oPos === 0 && dPos === 0) {\n\t pos = 0;\n\t }\n\n\t newNode.layer = i;\n\t newNode.uBaryCenter = 0.0;\n\t newNode.dBaryCenter = 0.0;\n\t newNode.upstreamLinkCount = 0;\n\t newNode.downstreamLinkCount = 0;\n\t newNode.gridPosition = pos;\n\t newNode.isVirtual = true;\n\n\t pos &= pos; // truncates to int\n\t Utils.insert(layer, newNode, pos);\n\n\t // translate rightwards nodes' positions\n\t for (r = pos + 1; r < layer.length; r++) {\n\t node = layer[r];\n\t node.gridPosition = node.gridPosition + 1;\n\t }\n\n\t newLink = new Link(p, newNode);\n\t newLink.depthOfDumminess = 0;\n\t addLinkBetweenLayers(i - 1, i, newLink);\n\n\t p = newNode;\n\n\t // add the new node and the new link to the graph\n\t this.graph._addNode(newNode);\n\t this.graph.addLink(newLink);\n\n\t newNode.index = this.graph.nodes.length - 1;\n\t this.mapVirtualNode(newNode, link);\n\t }\n\t addLinkBetweenLayers(dLayer - 1, dLayer, link);\n\n\t // Set the origin of the real arrow to the last dummy\n\t link.changeSource(p);\n\t link.depthOfDumminess = dLayer - oLayer - 1;\n\t } else {\n\t addLinkBetweenLayers(oLayer, dLayer, link);\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Removes the dummy nodes inserted earlier to break long links.\n\t /// \n\t /// The virtual nodes are effectively turned into intermediate connection points.\n\t _dedummify: function () {\n\t var dedum = true;\n\t while (dedum) {\n\t dedum = false;\n\n\t for (var l = 0; l < this.graph.links.length; l++) {\n\t var link = this.graph.links[l];\n\t if (!link.depthOfDumminess) {\n\t continue;\n\t }\n\n\t var points = [];\n\n\t // add points in reverse order\n\t points.unshift({ x: link.target.x, y: link.target.y });\n\t points.unshift({ x: link.source.x, y: link.source.y });\n\n\t // _dedummify the link\n\t var temp = link;\n\t var depthOfDumminess = link.depthOfDumminess;\n\t for (var d = 0; d < depthOfDumminess; d++) {\n\t var node = temp.source;\n\t var prevLink = node.incoming[0];\n\n\t points.unshift({ x: prevLink.source.x, y: prevLink.source.y });\n\n\t temp = prevLink;\n\t }\n\n\t // restore the original link origin\n\t link.changeSource(temp.source);\n\n\t // reset dummification flag\n\t link.depthOfDumminess = 0;\n\n\t // note that we only need the intermediate points, floating links have been dropped in the analysis\n\t if (points.length > 2) {\n\t // first and last are the endpoints\n\t points.splice(0, 1);\n\t points.splice(points.length - 1);\n\t link.points = points;\n\t }\n\t else {\n\t link.points = [];\n\t }\n\n\t // we are not going to delete the dummy elements;\n\t // they won't be needed anymore anyway.\n\n\t dedum = true;\n\t break;\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Optimizes/reduces the crossings between the layers by turning the crossing problem into a (combinatorial) number ordering problem.\n\t /// \n\t _optimizeCrossings: function () {\n\t var moves = -1, i;\n\t var maxIterations = 3;\n\t var iter = 0;\n\n\t while (moves !== 0) {\n\t if (iter++ > maxIterations) {\n\t break;\n\t }\n\n\t moves = 0;\n\n\t for (i = this.layers.length - 1; i >= 1; i--) {\n\t moves += this.optimizeLayerCrossings(false, i);\n\t }\n\n\t for (i = 0; i < this.layers.length - 1; i++) {\n\t moves += this.optimizeLayerCrossings(true, i);\n\t }\n\t }\n\t },\n\n\t calcUpData: function (layer) {\n\t if (layer === 0) {\n\t return;\n\t }\n\n\t var considered = this.layers[layer], i, l, link;\n\t var upLayer = new Set();\n\t var temp = this.layers[layer - 1];\n\t for (i = 0; i < temp.length; i++) {\n\t upLayer.add(temp[i]);\n\t }\n\n\t for (i = 0; i < considered.length; i++) {\n\t var node = considered[i];\n\n\t // calculate barycenter\n\t var sum = 0;\n\t var total = 0;\n\n\t for (l = 0; l < node.incoming.length; l++) {\n\t link = node.incoming[l];\n\t if (upLayer.contains(link.source)) {\n\t total++;\n\t sum += link.source.gridPosition;\n\t }\n\t }\n\n\t for (l = 0; l < node.outgoing.length; l++) {\n\t link = node.outgoing[l];\n\t if (upLayer.contains(link.target)) {\n\t total++;\n\t sum += link.target.gridPosition;\n\t }\n\t }\n\n\t if (total > 0) {\n\t node.uBaryCenter = sum / total;\n\t node.upstreamLinkCount = total;\n\t }\n\t else {\n\t node.uBaryCenter = i;\n\t node.upstreamLinkCount = 0;\n\t }\n\t }\n\t },\n\n\t calcDownData: function (layer) {\n\t if (layer === this.layers.length - 1) {\n\t return;\n\t }\n\n\t var considered = this.layers[layer], i , l, link;\n\t var downLayer = new Set();\n\t var temp = this.layers[layer + 1];\n\t for (i = 0; i < temp.length; i++) {\n\t downLayer.add(temp[i]);\n\t }\n\n\t for (i = 0; i < considered.length; i++) {\n\t var node = considered[i];\n\n\t // calculate barycenter\n\t var sum = 0;\n\t var total = 0;\n\n\t for (l = 0; l < node.incoming.length; l++) {\n\t link = node.incoming[l];\n\t if (downLayer.contains(link.source)) {\n\t total++;\n\t sum += link.source.gridPosition;\n\t }\n\t }\n\n\t for (l = 0; l < node.outgoing.length; l++) {\n\t link = node.outgoing[l];\n\t if (downLayer.contains(link.target)) {\n\t total++;\n\t sum += link.target.gridPosition;\n\t }\n\t }\n\n\t if (total > 0) {\n\t node.dBaryCenter = sum / total;\n\t node.downstreamLinkCount = total;\n\t }\n\t else {\n\t node.dBaryCenter = i;\n\t node.downstreamLinkCount = 0;\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Optimizes the crossings.\n\t /// \n\t /// The big trick here is the usage of weights or values attached to connected nodes which turn a problem of crossing links\n\t /// to an a problem of ordering numbers.\n\t /// The layer index.\n\t /// If set to true we move down in the layer stack.\n\t /// The number of nodes having moved, i.e. the number of crossings reduced.\n\t optimizeLayerCrossings: function (down, layer) {\n\t var iconsidered;\n\t var considered;\n\n\t if (down) {\n\t considered = this.layers[iconsidered = layer + 1];\n\t }\n\t else {\n\t considered = this.layers[iconsidered = layer - 1];\n\t }\n\n\t // remember what it was\n\t var presorted = considered.slice(0);\n\n\t // calculate barycenters for all nodes in the considered layer\n\t if (down) {\n\t this.calcUpData(iconsidered);\n\t }\n\t else {\n\t this.calcDownData(iconsidered);\n\t }\n\n\t var that = this;\n\t // sort nodes within this layer according to the barycenters\n\t considered.sort(function(n1, n2) {\n\t var n1BaryCenter = that.calcBaryCenter(n1),\n\t n2BaryCenter = that.calcBaryCenter(n2);\n\t if (Math.abs(n1BaryCenter - n2BaryCenter) < 0.0001) {\n\t // in case of coinciding barycenters compare by the count of in/out links\n\t if (n1.degree() === n2.degree()) {\n\t return that.compareByIndex(n1, n2);\n\t }\n\t else if (n1.degree() < n2.degree()) {\n\t return 1;\n\t }\n\t return -1;\n\t }\n\t var compareValue = (n2BaryCenter - n1BaryCenter) * 1000;\n\t if (compareValue > 0) {\n\t return -1;\n\t }\n\t else if (compareValue < 0) {\n\t return 1;\n\t }\n\t return that.compareByIndex(n1, n2);\n\t });\n\n\t // count relocations\n\t var i, moves = 0;\n\t for (i = 0; i < considered.length; i++) {\n\t if (considered[i] !== presorted[i]) {\n\t moves++;\n\t }\n\t }\n\n\t if (moves > 0) {\n\t // now that the boxes have been arranged, update their grid positions\n\t var inode = 0;\n\t for (i = 0; i < considered.length; i++) {\n\t var node = considered[i];\n\t node.gridPosition = inode++;\n\t }\n\t }\n\n\t return moves;\n\t },\n\n\t /// \n\t /// Swaps a pair of nodes in a layer.\n\t /// \n\t /// Index of the layer.\n\t /// The Nth node in the layer.\n\t _swapPairs: function () {\n\t var maxIterations = this.options.layeredIterations;\n\t var iter = 0;\n\n\t while (true) {\n\t if (iter++ > maxIterations) {\n\t break;\n\t }\n\n\t var downwards = (iter % 4 <= 1);\n\t var secondPass = (iter % 4 === 1);\n\n\t for (var l = (downwards ? 0 : this.layers.length - 1);\n\t downwards ? l <= this.layers.length - 1 : l >= 0; l += (downwards ? 1 : -1)) {\n\t var layer = this.layers[l];\n\t var hasSwapped = false;\n\n\t // there is no need to recalculate crossings if they were calculated\n\t // on the previous step and nothing has changed\n\t var calcCrossings = true;\n\t var memCrossings = 0;\n\n\t for (var n = 0; n < layer.length - 1; n++) {\n\t // count crossings\n\t var up = 0;\n\t var down = 0;\n\t var crossBefore = 0;\n\n\t if (calcCrossings) {\n\t if (l !== 0) {\n\t up = this.countLinksCrossingBetweenTwoLayers(l - 1, l);\n\t }\n\t if (l !== this.layers.length - 1) {\n\t down = this.countLinksCrossingBetweenTwoLayers(l, l + 1);\n\t }\n\t if (downwards) {\n\t up *= 2;\n\t }\n\t else {\n\t down *= 2;\n\t }\n\n\t crossBefore = up + down;\n\t }\n\t else {\n\t crossBefore = memCrossings;\n\t }\n\n\t if (crossBefore === 0) {\n\t continue;\n\t }\n\n\t // Swap nodes\n\t var node1 = layer[n];\n\t var node2 = layer[n + 1];\n\n\t var node1GridPos = node1.gridPosition;\n\t var node2GridPos = node2.gridPosition;\n\t layer[n] = node2;\n\t layer[n + 1] = node1;\n\t node1.gridPosition = node2GridPos;\n\t node2.gridPosition = node1GridPos;\n\n\t // count crossings again and if worse than before, restore swapping\n\t up = 0;\n\t if (l !== 0) {\n\t up = this.countLinksCrossingBetweenTwoLayers(l - 1, l);\n\t }\n\t down = 0;\n\t if (l !== this.layers.length - 1) {\n\t down = this.countLinksCrossingBetweenTwoLayers(l, l + 1);\n\t }\n\t if (downwards) {\n\t up *= 2;\n\t }\n\t else {\n\t down *= 2;\n\t }\n\t var crossAfter = up + down;\n\n\t var revert = false;\n\t if (secondPass) {\n\t revert = crossAfter >= crossBefore;\n\t }\n\t else {\n\t revert = crossAfter > crossBefore;\n\t }\n\n\t if (revert) {\n\t node1 = layer[n];\n\t node2 = layer[n + 1];\n\n\t node1GridPos = node1.gridPosition;\n\t node2GridPos = node2.gridPosition;\n\t layer[n] = node2;\n\t layer[n + 1] = node1;\n\t node1.gridPosition = node2GridPos;\n\t node2.gridPosition = node1GridPos;\n\n\t // nothing has changed, remember the crossings so that\n\t // they are not calculated again on the next step\n\t memCrossings = crossBefore;\n\t calcCrossings = false;\n\t }\n\t else {\n\t hasSwapped = true;\n\t calcCrossings = true;\n\t }\n\t }\n\n\t if (hasSwapped) {\n\t if (l !== this.layers.length - 1) {\n\t this.calcUpData(l + 1);\n\t }\n\t if (l !== 0) {\n\t this.calcDownData(l - 1);\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Counts the number of links crossing between two layers.\n\t /// \n\t /// The layer index.\n\t /// Another layer index.\n\t /// \n\t countLinksCrossingBetweenTwoLayers: function (ulayer, dlayer) {\n\t var links = this.layers[ulayer].linksTo[dlayer];\n\t var link1, link2, n11, n12, n21, n22, l1, l2;\n\t var crossings = 0;\n\t var length = links.length;\n\n\t for (l1 = 0; l1 < length; l1++) {\n\t link1 = links[l1];\n\t for (l2 = l1 + 1; l2 < length; l2++) {\n\n\t link2 = links[l2];\n\n\t if (link1.target.layer === dlayer) {\n\t n11 = link1.source;\n\t n12 = link1.target;\n\t }\n\t else {\n\t n11 = link1.target;\n\t n12 = link1.source;\n\t }\n\n\t if (link2.target.layer === dlayer) {\n\t n21 = link2.source;\n\t n22 = link2.target;\n\t }\n\t else {\n\t n21 = link2.target;\n\t n22 = link2.source;\n\t }\n\n\t var n11gp = n11.gridPosition;\n\t var n12gp = n12.gridPosition;\n\t var n21gp = n21.gridPosition;\n\t var n22gp = n22.gridPosition;\n\n\t if ((n11gp - n21gp) * (n12gp - n22gp) < 0) {\n\t crossings++;\n\t }\n\t }\n\t }\n\n\t return crossings;\n\t },\n\n\t calcBaryCenter: function (node) {\n\t var upstreamLinkCount = node.upstreamLinkCount;\n\t var downstreamLinkCount = node.downstreamLinkCount;\n\t var uBaryCenter = node.uBaryCenter;\n\t var dBaryCenter = node.dBaryCenter;\n\n\t if (upstreamLinkCount > 0 && downstreamLinkCount > 0) {\n\t return (uBaryCenter + dBaryCenter) / 2;\n\t }\n\t if (upstreamLinkCount > 0) {\n\t return uBaryCenter;\n\t }\n\t if (downstreamLinkCount > 0) {\n\t return dBaryCenter;\n\t }\n\n\t return 0;\n\t },\n\n\t _gridPositionComparer: function (x, y) {\n\t if (x.gridPosition < y.gridPosition) {\n\t return -1;\n\t }\n\t if (x.gridPosition > y.gridPosition) {\n\t return 1;\n\t }\n\t return 0;\n\t },\n\n\t _positionAscendingComparer: function (x, y) {\n\t return x.k < y.k ? -1 : x.k > y.k ? 1 : 0;\n\t },\n\n\t _positionDescendingComparer: function (x, y) {\n\t return x.k < y.k ? 1 : x.k > y.k ? -1 : 0;\n\t },\n\n\t _firstVirtualNode: function (layer) {\n\t for (var c = 0; c < layer.length; c++) {\n\t if (layer[c].isVirtual) {\n\t return c;\n\t }\n\t }\n\t return -1;\n\t },\n\n\t compareByIndex: function (o1, o2) {\n\t var i1 = o1.index;\n\t var i2 = o2.index;\n\n\t if (i1 < i2) {\n\t return 1;\n\t }\n\n\t if (i1 > i2) {\n\t return -1;\n\t }\n\n\t return 0;\n\t },\n\n\t intDiv: function (numerator, denominator) {\n\t return (numerator - numerator % denominator) / denominator;\n\t },\n\n\t nextVirtualNode: function (layer, node) {\n\t var nodeIndex = node.layerIndex;\n\t for (var i = nodeIndex + 1; i < layer.length; ++i) {\n\t if (layer[i].isVirtual) {\n\t return layer[i];\n\t }\n\t }\n\t return null;\n\t }\n\n\t });\n\n\t /**\n\t * Captures the state of a diagram; node positions, link points and so on.\n\t * @type {*}\n\t */\n\t var LayoutState = kendo.Class.extend({\n\t init: function (diagram, graphOrNodes) {\n\t if (Utils.isUndefined(diagram)) {\n\t throw \"No diagram given\";\n\t }\n\t this.diagram = diagram;\n\t this.nodeMap = new Dictionary();\n\t this.linkMap = new Dictionary();\n\t this.capture(graphOrNodes ? graphOrNodes : diagram);\n\t },\n\n\t /**\n\t * Will capture either\n\t * - the state of the shapes and the intermediate points of the connections in the diagram\n\t * - the bounds of the nodes contained in the Graph together with the intermediate points of the links in the Graph\n\t * - the bounds of the nodes in the Array\n\t * - the links points and node bounds in the literal object\n\t * @param diagramOrGraphOrNodes\n\t */\n\t capture: function (diagramOrGraphOrNodes) {\n\t var node,\n\t nodes,\n\t shape,\n\t i,\n\t conn,\n\t link,\n\t links;\n\n\t if (diagramOrGraphOrNodes instanceof diagram.Graph) {\n\n\t for (i = 0; i < diagramOrGraphOrNodes.nodes.length; i++) {\n\t node = diagramOrGraphOrNodes.nodes[i];\n\t shape = node.associatedShape;\n\t //shape.bounds(new Rect(node.x, node.y, node.width, node.height));\n\t this.nodeMap.set(shape.visual.id, new Rect(node.x, node.y, node.width, node.height));\n\t }\n\t for (i = 0; i < diagramOrGraphOrNodes.links.length; i++) {\n\t link = diagramOrGraphOrNodes.links[i];\n\t conn = link.associatedConnection;\n\t this.linkMap.set(conn.visual.id, link.points());\n\t }\n\t }\n\t else if (diagramOrGraphOrNodes instanceof Array) {\n\t nodes = diagramOrGraphOrNodes;\n\t for (i = 0; i < nodes.length; i++) {\n\t node = nodes[i];\n\t shape = node.associatedShape;\n\t if (shape) {\n\t this.nodeMap.set(shape.visual.id, new Rect(node.x, node.y, node.width, node.height));\n\t }\n\t }\n\t }\n\t else if (diagramOrGraphOrNodes.hasOwnProperty(\"links\") && diagramOrGraphOrNodes.hasOwnProperty(\"nodes\")) {\n\t nodes = diagramOrGraphOrNodes.nodes;\n\t links = diagramOrGraphOrNodes.links;\n\t for (i = 0; i < nodes.length; i++) {\n\t node = nodes[i];\n\t shape = node.associatedShape;\n\t if (shape) {\n\t this.nodeMap.set(shape.visual.id, new Rect(node.x, node.y, node.width, node.height));\n\t }\n\t }\n\t for (i = 0; i < links.length; i++) {\n\t link = links[i];\n\t conn = link.associatedConnection;\n\t if (conn) {\n\t this.linkMap.set(conn.visual.id, link.points);\n\t }\n\t }\n\t }\n\t else { // capture the diagram\n\t var shapes = this.diagram.shapes;\n\t var connections = this.diagram.connections;\n\t for (i = 0; i < shapes.length; i++) {\n\t shape = shapes[i];\n\t this.nodeMap.set(shape.visual.id, shape.bounds());\n\t }\n\t for (i = 0; i < connections.length; i++) {\n\t conn = connections[i];\n\t this.linkMap.set(conn.visual.id, conn.points());\n\t }\n\t }\n\t }\n\t });\n\n\t deepExtend(diagram, {\n\t init: function (element) {\n\t kendo.init(element, diagram.ui);\n\t },\n\t SpringLayout: SpringLayout,\n\t TreeLayout: TreeLayout,\n\t GraphAdapter: DiagramToHyperTreeAdapter,\n\t LayeredLayout: LayeredLayout,\n\t LayoutBase: LayoutBase,\n\t LayoutState: LayoutState\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 878:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./math\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(879);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 858:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(880), __webpack_require__(858) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var kendo = window.kendo,\n\t diagram = kendo.dataviz.diagram,\n\t Class = kendo.Class,\n\t deepExtend = kendo.deepExtend,\n\t dataviz = kendo.dataviz,\n\t Utils = diagram.Utils,\n\t Point = dataviz.Point2D,\n\t isFunction = kendo.isFunction,\n\t contains = Utils.contains,\n\t map = $.map;\n\n\t // Constants ==============================================================\n\t var HITTESTAREA = 3,\n\t EPSILON = 1e-06;\n\n\t deepExtend(Point.fn, {\n\t plus: function (p) {\n\t return new Point(this.x + p.x, this.y + p.y);\n\t },\n\t minus: function (p) {\n\t return new Point(this.x - p.x, this.y - p.y);\n\t },\n\t offset: function (value) {\n\t return new Point(this.x - value, this.y - value);\n\t },\n\t times: function (s) {\n\t return new Point(this.x * s, this.y * s);\n\t },\n\t normalize: function () {\n\t if (this.length() === 0) {\n\t return new Point();\n\t }\n\t return this.times(1 / this.length());\n\t },\n\t length: function () {\n\t return Math.sqrt(this.x * this.x + this.y * this.y);\n\t },\n\t toString: function () {\n\t return \"(\" + this.x + \",\" + this.y + \")\";\n\t },\n\t lengthSquared: function () {\n\t return (this.x * this.x + this.y * this.y);\n\t },\n\t middleOf: function MiddleOf(p, q) {\n\t return new Point(q.x - p.x, q.y - p.y).times(0.5).plus(p);\n\t },\n\t toPolar: function (useDegrees) {\n\t var factor = 1;\n\t if (useDegrees) {\n\t factor = 180 / Math.PI;\n\t }\n\t var a = Math.atan2(Math.abs(this.y), Math.abs(this.x));\n\t var halfpi = Math.PI / 2;\n\t var len = this.length();\n\t if (this.x === 0) {\n\t // note that the angle goes down and not the usual mathematical convention\n\n\t if (this.y === 0) {\n\t return new Polar(0, 0);\n\t }\n\t if (this.y > 0) {\n\t return new Polar(len, factor * halfpi);\n\t }\n\t if (this.y < 0) {\n\t return new Polar(len, factor * 3 * halfpi);\n\t }\n\t }\n\t else if (this.x > 0) {\n\t if (this.y === 0) {\n\t return new Polar(len, 0);\n\t }\n\t if (this.y > 0) {\n\t return new Polar(len, factor * a);\n\t }\n\t if (this.y < 0) {\n\t return new Polar(len, factor * (4 * halfpi - a));\n\t }\n\t }\n\t else {\n\t if (this.y === 0) {\n\t return new Polar(len, 2 * halfpi);\n\t }\n\t if (this.y > 0) {\n\t return new Polar(len, factor * (2 * halfpi - a));\n\t }\n\t if (this.y < 0) {\n\t return new Polar(len, factor * (2 * halfpi + a));\n\t }\n\t }\n\t },\n\t isOnLine: function (from, to) {\n\t if (from.x > to.x) { // from must be the leftmost point\n\t var temp = to;\n\t to = from;\n\t from = temp;\n\t }\n\t var r1 = new Rect(from.x, from.y).inflate(HITTESTAREA, HITTESTAREA),\n\t r2 = new Rect(to.x, to.y).inflate(HITTESTAREA, HITTESTAREA), o1, u1;\n\t if (r1.union(r2).contains(this)) {\n\t if (from.x === to.x || from.y === to.y) {\n\t return true;\n\t }\n\t else if (from.y < to.y) {\n\t o1 = r1.x + (((r2.x - r1.x) * (this.y - (r1.y + r1.height))) / ((r2.y + r2.height) - (r1.y + r1.height)));\n\t u1 = (r1.x + r1.width) + ((((r2.x + r2.width) - (r1.x + r1.width)) * (this.y - r1.y)) / (r2.y - r1.y));\n\t }\n\t else {\n\t o1 = r1.x + (((r2.x - r1.x) * (this.y - r1.y)) / (r2.y - r1.y));\n\t u1 = (r1.x + r1.width) + ((((r2.x + r2.width) - (r1.x + r1.width)) * (this.y - (r1.y + r1.height))) / ((r2.y + r2.height) - (r1.y + r1.height)));\n\t }\n\t return (this.x > o1 && this.x < u1);\n\t }\n\t return false;\n\t }\n\t });\n\n\t deepExtend(Point, {\n\t parse: function (str) {\n\t var tempStr = str.slice(1, str.length - 1),\n\t xy = tempStr.split(\",\"),\n\t x = parseInt(xy[0], 10),\n\t y = parseInt(xy[1], 10);\n\t if (!isNaN(x) && !isNaN(y)) {\n\t return new Point(x, y);\n\t }\n\t }\n\t });\n\n\t /**\n\t * Structure combining a Point with two additional points representing the handles or tangents attached to the first point.\n\t * If the additional points are null or equal to the first point the path will be sharp.\n\t * Left and right correspond to the direction of the underlying path.\n\t */\n\t var PathDefiner = Class.extend(\n\t {\n\t init: function (p, left, right) {\n\t this.point = p;\n\t this.left = left;\n\t this.right = right;\n\t }\n\t }\n\t );\n\n\t /**\n\t * Defines a rectangular region.\n\t */\n\t var Rect = Class.extend({\n\t init: function (x, y, width, height) {\n\t this.x = x || 0;\n\t this.y = y || 0;\n\t this.width = width || 0;\n\t this.height = height || 0;\n\t },\n\t contains: function (point) {\n\t return ((point.x >= this.x) && (point.x <= (this.x + this.width)) && (point.y >= this.y) && (point.y <= (this.y + this.height)));\n\t },\n\t inflate: function (dx, dy) {\n\t if (dy === undefined) {\n\t dy = dx;\n\t }\n\n\t this.x -= dx;\n\t this.y -= dy;\n\t this.width += 2 * dx + 1;\n\t this.height += 2 * dy + 1;\n\t return this;\n\t },\n\t offset: function (dx, dy) {\n\t var x = dx, y = dy;\n\t if (dx instanceof Point) {\n\t x = dx.x;\n\t y = dx.y;\n\t }\n\t this.x += x;\n\t this.y += y;\n\t return this;\n\t },\n\t union: function (r) {\n\t var x1 = Math.min(this.x, r.x);\n\t var y1 = Math.min(this.y, r.y);\n\t var x2 = Math.max((this.x + this.width), (r.x + r.width));\n\t var y2 = Math.max((this.y + this.height), (r.y + r.height));\n\t return new Rect(x1, y1, x2 - x1, y2 - y1);\n\t },\n\t center: function () {\n\t return new Point(this.x + this.width / 2, this.y + this.height / 2);\n\t },\n\t top: function () {\n\t return new Point(this.x + this.width / 2, this.y);\n\t },\n\t right: function () {\n\t return new Point(this.x + this.width, this.y + this.height / 2);\n\t },\n\t bottom: function () {\n\t return new Point(this.x + this.width / 2, this.y + this.height);\n\t },\n\t left: function () {\n\t return new Point(this.x, this.y + this.height / 2);\n\t },\n\t topLeft: function () {\n\t return new Point(this.x, this.y);\n\t },\n\t topRight: function () {\n\t return new Point(this.x + this.width, this.y);\n\t },\n\t bottomLeft: function () {\n\t return new Point(this.x, this.y + this.height);\n\t },\n\t bottomRight: function () {\n\t return new Point(this.x + this.width, this.y + this.height);\n\t },\n\t clone: function () {\n\t return new Rect(this.x, this.y, this.width, this.height);\n\t },\n\t isEmpty: function () {\n\t return !this.width && !this.height;\n\t },\n\t equals: function (rect) {\n\t return this.x === rect.x && this.y === rect.y && this.width === rect.width && this.height === rect.height;\n\t },\n\t rotatedBounds: function (angle) {\n\t var rect = this.clone(),\n\t points = this.rotatedPoints(angle),\n\t tl = points[0],\n\t tr = points[1],\n\t br = points[2],\n\t bl = points[3];\n\n\t rect.x = Math.min(br.x, tl.x, tr.x, bl.x);\n\t rect.y = Math.min(br.y, tl.y, tr.y, bl.y);\n\t rect.width = Math.max(br.x, tl.x, tr.x, bl.x) - rect.x;\n\t rect.height = Math.max(br.y, tl.y, tr.y, bl.y) - rect.y;\n\n\t return rect;\n\t },\n\t rotatedPoints: function (angle) {\n\t var rect = this,\n\t c = rect.center(),\n\t br = rect.bottomRight().rotate(c, 360 - angle),\n\t tl = rect.topLeft().rotate(c, 360 - angle),\n\t tr = rect.topRight().rotate(c, 360 - angle),\n\t bl = rect.bottomLeft().rotate(c, 360 - angle);\n\n\t return [tl, tr, br, bl];\n\t },\n\t toString: function (delimiter) {\n\t delimiter = delimiter || \" \";\n\n\t return this.x + delimiter + this.y + delimiter + this.width + delimiter + this.height;\n\t },\n\t scale: function (scaleX, scaleY, staicPoint, adornerCenter, angle) {\n\t var tl = this.topLeft();\n\t var thisCenter = this.center();\n\t tl.rotate(thisCenter, 360 - angle).rotate(adornerCenter, angle);\n\n\t var delta = staicPoint.minus(tl);\n\t var scaled = new Point(delta.x * scaleX, delta.y * scaleY);\n\t var position = delta.minus(scaled);\n\t tl = tl.plus(position);\n\t tl.rotate(adornerCenter, 360 - angle).rotate(thisCenter, angle);\n\n\t this.x = tl.x;\n\t this.y = tl.y;\n\n\t this.width *= scaleX;\n\t this.height *= scaleY;\n\t },\n\n\t zoom: function(zoom) {\n\t this.x *= zoom;\n\t this.y *= zoom;\n\t this.width *= zoom;\n\t this.height *= zoom;\n\t return this;\n\t },\n\n\t overlaps: function(rect) {\n\t var bottomRight = this.bottomRight();\n\t var rectBottomRight = rect.bottomRight();\n\t var overlaps = !(bottomRight.x < rect.x || bottomRight.y < rect.y ||\n\t rectBottomRight.x < this.x || rectBottomRight.y < this.y);\n\t return overlaps;\n\t }\n\t });\n\n\t var Size = Class.extend({\n\t init: function (width, height) {\n\t this.width = width;\n\t this.height = height;\n\t }\n\t });\n\n\t Size.prototype.Empty = new Size(0, 0);\n\n\t Rect.toRect = function (rect) {\n\t if (!(rect instanceof Rect)) {\n\t rect = new Rect(rect.x, rect.y, rect.width, rect.height);\n\t }\n\n\t return rect;\n\t };\n\n\t Rect.empty = function () {\n\t return new Rect(0, 0, 0, 0);\n\t };\n\n\t Rect.fromPoints = function (p, q) {\n\t if (isNaN(p.x) || isNaN(p.y) || isNaN(q.x) || isNaN(q.y)) {\n\t throw \"Some values are NaN.\";\n\t }\n\t return new Rect(Math.min(p.x, q.x), Math.min(p.y, q.y), Math.abs(p.x - q.x), Math.abs(p.y - q.y));\n\t };\n\n\t function isNearZero(num) {\n\t return Math.abs(num) < EPSILON;\n\t }\n\n\t function intersectLine(start1, end1, start2, end2, isSegment) {\n\t var tangensdiff = ((end1.x - start1.x) * (end2.y - start2.y)) - ((end1.y - start1.y) * (end2.x - start2.x));\n\t if (isNearZero(tangensdiff)) {\n\t //parallel lines\n\t return;\n\t }\n\n\t var num1 = ((start1.y - start2.y) * (end2.x - start2.x)) - ((start1.x - start2.x) * (end2.y - start2.y));\n\t var num2 = ((start1.y - start2.y) * (end1.x - start1.x)) - ((start1.x - start2.x) * (end1.y - start1.y));\n\t var r = num1 / tangensdiff;\n\t var s = num2 / tangensdiff;\n\n\t if (isSegment && (r < 0 || r > 1 || s < 0 || s > 1)) {\n\t //r < 0 => line 1 is below line 2\n\t //r > 1 => line 1 is above line 2\n\t //s < 0 => line 2 is below line 1\n\t //s > 1 => line 2 is above line 1\n\t return;\n\t }\n\n\t return new Point(start1.x + (r * (end1.x - start1.x)), start1.y + (r * (end1.y - start1.y)));\n\t }\n\n\t var Intersect = {\n\t lines: function (start1, end1, start2, end2) {\n\t return intersectLine(start1, end1, start2, end2);\n\t },\n\t segments: function (start1, end1, start2, end2) {\n\t return intersectLine(start1, end1, start2, end2, true);\n\t },\n\t rectWithLine: function (rect, start, end) {\n\t return Intersect.segments(start, end, rect.topLeft(), rect.topRight()) ||\n\t Intersect.segments(start, end, rect.topRight(), rect.bottomRight()) ||\n\t Intersect.segments(start, end, rect.bottomLeft(), rect.bottomRight()) ||\n\t Intersect.segments(start, end, rect.topLeft(), rect.bottomLeft());\n\t },\n\t rects: function (rect1, rect2, angle) {\n\t var tl = rect2.topLeft(),\n\t tr = rect2.topRight(),\n\t bl = rect2.bottomLeft(),\n\t br = rect2.bottomRight();\n\t var center = rect2.center();\n\t if (angle) {\n\t tl = tl.rotate(center, angle);\n\t tr = tr.rotate(center, angle);\n\t bl = bl.rotate(center, angle);\n\t br = br.rotate(center, angle);\n\t }\n\n\t var intersect = rect1.contains(tl) ||\n\t rect1.contains(tr) ||\n\t rect1.contains(bl) ||\n\t rect1.contains(br) ||\n\t Intersect.rectWithLine(rect1, tl, tr) ||\n\t Intersect.rectWithLine(rect1, tl, bl) ||\n\t Intersect.rectWithLine(rect1, tr, br) ||\n\t Intersect.rectWithLine(rect1, bl, br);\n\n\t if (!intersect) {//last possible case is rect1 to be completely within rect2\n\t tl = rect1.topLeft();\n\t tr = rect1.topRight();\n\t bl = rect1.bottomLeft();\n\t br = rect1.bottomRight();\n\n\t if (angle) {\n\t var reverseAngle = 360 - angle;\n\t tl = tl.rotate(center, reverseAngle);\n\t tr = tr.rotate(center, reverseAngle);\n\t bl = bl.rotate(center, reverseAngle);\n\t br = br.rotate(center, reverseAngle);\n\t }\n\n\t intersect = rect2.contains(tl) ||\n\t rect2.contains(tr) ||\n\t rect2.contains(bl) ||\n\t rect2.contains(br);\n\t }\n\n\t return intersect;\n\t }\n\t };\n\n\t /**\n\t * Aligns two rectangles, where one is the container and the other is content.\n\t */\n\t var RectAlign = Class.extend({\n\t init: function (container) {\n\t this.container = Rect.toRect(container);\n\t },\n\n\t align: function (content, alignment) {\n\t var alignValues = alignment.toLowerCase().split(\" \");\n\n\t for (var i = 0; i < alignValues.length; i++) {\n\t content = this._singleAlign(content, alignValues[i]);\n\t }\n\n\t return content;\n\t },\n\t _singleAlign: function (content, alignment) {\n\t if (isFunction(this[alignment])) {\n\t return this[alignment](content);\n\t }\n\t else {\n\t return content;\n\t }\n\t },\n\n\t left: function (content) {\n\t return this._align(content, this._left);\n\t },\n\t center: function (content) {\n\t return this._align(content, this._center);\n\t },\n\t right: function (content) {\n\t return this._align(content, this._right);\n\t },\n\t stretch: function (content) {\n\t return this._align(content, this._stretch);\n\t },\n\t top: function (content) {\n\t return this._align(content, this._top);\n\t },\n\t middle: function (content) {\n\t return this._align(content, this._middle);\n\t },\n\t bottom: function (content) {\n\t return this._align(content, this._bottom);\n\t },\n\n\t _left: function (container, content) {\n\t content.x = container.x;\n\t },\n\t _center: function (container, content) {\n\t content.x = ((container.width - content.width) / 2) || 0;\n\t },\n\t _right: function (container, content) {\n\t content.x = container.width - content.width;\n\t },\n\t _top: function (container, content) {\n\t content.y = container.y;\n\t },\n\t _middle: function (container, content) {\n\t content.y = ((container.height - content.height) / 2) || 0;\n\t },\n\t _bottom: function (container, content) {\n\t content.y = container.height - content.height;\n\t },\n\t _stretch: function (container, content) {\n\t content.x = 0;\n\t content.y = 0;\n\t content.height = container.height;\n\t content.width = container.width;\n\t },\n\t _align: function (content, alignCalc) {\n\t content = Rect.toRect(content);\n\t alignCalc(this.container, content);\n\n\t return content;\n\t }\n\t });\n\n\t var Polar = Class.extend({\n\t init: function (r, a) {\n\t this.r = r;\n\t this.angle = a;\n\t }\n\t });\n\n\t /**\n\t * SVG transformation matrix.\n\t */\n\t var Matrix = Class.extend({\n\t init: function (a, b, c, d, e, f) {\n\t this.a = a || 0;\n\t this.b = b || 0;\n\t this.c = c || 0;\n\t this.d = d || 0;\n\t this.e = e || 0;\n\t this.f = f || 0;\n\t },\n\t plus: function (m) {\n\t this.a += m.a;\n\t this.b += m.b;\n\t this.c += m.c;\n\t this.d += m.d;\n\t this.e += m.e;\n\t this.f += m.f;\n\t },\n\t minus: function (m) {\n\t this.a -= m.a;\n\t this.b -= m.b;\n\t this.c -= m.c;\n\t this.d -= m.d;\n\t this.e -= m.e;\n\t this.f -= m.f;\n\t },\n\t times: function (m) {\n\t return new Matrix(\n\t this.a * m.a + this.c * m.b,\n\t this.b * m.a + this.d * m.b,\n\t this.a * m.c + this.c * m.d,\n\t this.b * m.c + this.d * m.d,\n\t this.a * m.e + this.c * m.f + this.e,\n\t this.b * m.e + this.d * m.f + this.f\n\t );\n\t },\n\t apply: function (p) {\n\t return new Point(this.a * p.x + this.c * p.y + this.e, this.b * p.x + this.d * p.y + this.f);\n\t },\n\t applyRect: function (r) {\n\t return Rect.fromPoints(this.apply(r.topLeft()), this.apply(r.bottomRight()));\n\t },\n\t toString: function () {\n\t return \"matrix(\" + this.a + \" \" + this.b + \" \" + this.c + \" \" + this.d + \" \" + this.e + \" \" + this.f + \")\";\n\t }\n\t });\n\n\t deepExtend(Matrix, {\n\t fromSVGMatrix: function (vm) {\n\t var m = new Matrix();\n\t m.a = vm.a;\n\t m.b = vm.b;\n\t m.c = vm.c;\n\t m.d = vm.d;\n\t m.e = vm.e;\n\t m.f = vm.f;\n\t return m;\n\t },\n\t fromMatrixVector: function (v) {\n\t var m = new Matrix();\n\t m.a = v.a;\n\t m.b = v.b;\n\t m.c = v.c;\n\t m.d = v.d;\n\t m.e = v.e;\n\t m.f = v.f;\n\t return m;\n\t },\n\t fromList: function (v) {\n\t if (v.length !== 6) {\n\t throw \"The given list should consist of six elements.\";\n\t }\n\t var m = new Matrix();\n\t m.a = v[0];\n\t m.b = v[1];\n\t m.c = v[2];\n\t m.d = v[3];\n\t m.e = v[4];\n\t m.f = v[5];\n\t return m;\n\t },\n\t translation: function (x, y) {\n\t var m = new Matrix();\n\t m.a = 1;\n\t m.b = 0;\n\t m.c = 0;\n\t m.d = 1;\n\t m.e = x;\n\t m.f = y;\n\t return m;\n\t },\n\t unit: function () {\n\t return new Matrix(1, 0, 0, 1, 0, 0);\n\t },\n\t rotation: function (angle, x, y) {\n\t var m = new Matrix();\n\t m.a = Math.cos(angle * Math.PI / 180);\n\t m.b = Math.sin(angle * Math.PI / 180);\n\t m.c = -m.b;\n\t m.d = m.a;\n\t m.e = (x - x * m.a + y * m.b) || 0;\n\t m.f = (y - y * m.a - x * m.b) || 0;\n\t return m;\n\t },\n\t scaling: function (scaleX, scaleY) {\n\t var m = new Matrix();\n\t m.a = scaleX;\n\t m.b = 0;\n\t m.c = 0;\n\t m.d = scaleY;\n\t m.e = 0;\n\t m.f = 0;\n\t return m;\n\t },\n\t parse: function (v) {\n\t var parts, nums;\n\t if (v) {\n\t v = v.trim();\n\t // of the form \"matrix(...)\"\n\t if (v.slice(0, 6).toLowerCase() === \"matrix\") {\n\t nums = v.slice(7, v.length - 1).trim();\n\t parts = nums.split(\",\");\n\t if (parts.length === 6) {\n\t return Matrix.fromList(map(parts, function (p) {\n\t return parseFloat(p);\n\t }));\n\t }\n\t parts = nums.split(\" \");\n\t if (parts.length === 6) {\n\t return Matrix.fromList(map(parts, function (p) {\n\t return parseFloat(p);\n\t }));\n\t }\n\t }\n\t // of the form \"(...)\"\n\t if (v.slice(0, 1) === \"(\" && v.slice(v.length - 1) === \")\") {\n\t v = v.substr(1, v.length - 1);\n\t }\n\t if (v.indexOf(\",\") > 0) {\n\t parts = v.split(\",\");\n\t if (parts.length === 6) {\n\t return Matrix.fromList(map(parts, function (p) {\n\t return parseFloat(p);\n\t }));\n\t }\n\t }\n\t if (v.indexOf(\" \") > 0) {\n\t parts = v.split(\" \");\n\t if (parts.length === 6) {\n\t return Matrix.fromList(map(parts, function (p) {\n\t return parseFloat(p);\n\t }));\n\t }\n\t }\n\t }\n\t return parts;\n\t }\n\t });\n\n\t /**\n\t * SVG transformation represented as a vector.\n\t */\n\t var MatrixVector = Class.extend({\n\t init: function (a, b, c, d, e, f) {\n\t this.a = a || 0;\n\t this.b = b || 0;\n\t this.c = c || 0;\n\t this.d = d || 0;\n\t this.e = e || 0;\n\t this.f = f || 0;\n\t },\n\t fromMatrix: function FromMatrix(m) {\n\t var v = new MatrixVector();\n\t v.a = m.a;\n\t v.b = m.b;\n\t v.c = m.c;\n\t v.d = m.d;\n\t v.e = m.e;\n\t v.f = m.f;\n\t return v;\n\t }\n\t });\n\n\t /**\n\t * Returns a value with Gaussian (normal) distribution.\n\t * @param mean The mean value of the distribution.\n\t * @param deviation The deviation (spreading at half-height) of the distribution.\n\t * @returns {number}\n\t */\n\t function normalVariable(mean, deviation) {\n\t var x, y, r;\n\t do {\n\t x = Math.random() * 2 - 1;\n\t y = Math.random() * 2 - 1;\n\t r = x * x + y * y;\n\t }\n\t while (!r || r > 1);\n\t return mean + deviation * x * Math.sqrt(-2 * Math.log(r) / r);\n\t }\n\n\t /**\n\t * Returns a random identifier which can be used as an ID of objects, eventually augmented with a prefix.\n\t * @returns {string}\n\t */\n\t function randomId(length) {\n\t if (Utils.isUndefined(length)) {\n\t length = 10;\n\t }\n\t // old version return Math.floor((1 + Math.random()) * 0x1000000).toString(16).substring(1);\n\t var result = '';\n\t var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\t for (var i = length; i > 0; --i) {\n\t result += chars.charAt(Math.round(Math.random() * (chars.length - 1)));\n\t }\n\t return result;\n\t }\n\n\t var Geometry = {\n\n\t /**\n\t * Returns the squared distance to the line defined by the two given Points.\n\t * @param p An arbitrary Point.\n\t * @param a An endpoint of the line or segment.\n\t * @param b The complementary endpoint of the line or segment.\n\t */\n\t _distanceToLineSquared: function (p, a, b) {\n\t function d2(pt1, pt2) {\n\t return (pt1.x - pt2.x) * (pt1.x - pt2.x) + (pt1.y - pt2.y) * (pt1.y - pt2.y);\n\t }\n\n\t if (a === b) { // returns the distance of p to a\n\t return d2(p, a);\n\t }\n\n\t var vx = b.x - a.x,\n\t vy = b.y - a.y,\n\t dot = (p.x - a.x) * vx + (p.y - a.y) * vy;\n\t if (dot < 0) {\n\t return d2(a, p); // sits on side of a\n\t }\n\n\t dot = (b.x - p.x) * vx + (b.y - p.y) * vy;\n\t if (dot < 0) {\n\t return d2(b, p); // sits on side of b\n\t }\n\t // regular case, use crossproduct to get the sine out\n\t dot = (b.x - p.x) * vy - (b.y - p.y) * vx;\n\t return dot * dot / (vx * vx + vy * vy);\n\t },\n\n\t /**\n\t * Returns the distance to the line defined by the two given Points.\n\t * @param p An arbitrary Point.\n\t * @param a An endpoint of the line or segment.\n\t * @param b The complementary endpoint of the line or segment.\n\t */\n\t distanceToLine: function (p, a, b) {\n\t return Math.sqrt(this._distanceToLineSquared(p, a, b));\n\t },\n\n\t /**\n\t * Returns the distance of the given points to the polyline defined by the points.\n\t * @param p An arbitrary point.\n\t * @param points The points defining the polyline.\n\t * @returns {Number}\n\t */\n\t distanceToPolyline: function (p, points) {\n\t var minimum = Number.MAX_VALUE;\n\t if (Utils.isUndefined(points) || points.length === 0) {\n\t return Number.MAX_VALUE;\n\t }\n\t for (var s = 0; s < points.length - 1; s++) {\n\t var p1 = points[s];\n\t var p2 = points[s + 1];\n\n\t var d = this._distanceToLineSquared(p, p1, p2);\n\t if (d < minimum) {\n\t minimum = d;\n\t }\n\t }\n\t return Math.sqrt(minimum);\n\t }\n\t };\n\n\t /*---------------The HashTable structure--------------------------------*/\n\n\t /**\n\t * Represents a collection of key-value pairs that are organized based on the hash code of the key.\n\t * _buckets[hashId] = {key: key, value:...}\n\t * Important: do not use the standard Array access method, use the get/set methods instead.\n\t * See http://en.wikipedia.org/wiki/Hash_table\n\t */\n\t var HashTable = kendo.Class.extend({\n\t init: function () {\n\t this._buckets = [];\n\t this.length = 0;\n\t },\n\n\t /**\n\t * Adds the literal object with the given key (of the form {key: key,....}).\n\t */\n\t add: function (key, value) {\n\n\t var obj = this._createGetBucket(key);\n\t if (Utils.isDefined(value)) {\n\t obj.value = value;\n\t }\n\t return obj;\n\t },\n\n\t /**\n\t * Gets the literal object with the given key.\n\t */\n\t get: function (key) {\n\t if (this._bucketExists(key)) {\n\t return this._createGetBucket(key);\n\t }\n\t return null;\n\t },\n\n\t /**\n\t * Set the key-value pair.\n\t * @param key The key of the entry.\n\t * @param value The value to set. If the key already exists the value will be overwritten.\n\t */\n\t set: function (key, value) {\n\t this.add(key, value);\n\t },\n\n\t /**\n\t * Determines whether the HashTable contains a specific key.\n\t */\n\t containsKey: function (key) {\n\t return this._bucketExists(key);\n\t },\n\n\t /**\n\t * Removes the element with the specified key from the hashtable.\n\t * Returns the removed bucket.\n\t */\n\t remove: function (key) {\n\t if (this._bucketExists(key)) {\n\t var hashId = this._hash(key);\n\t delete this._buckets[hashId];\n\t this.length--;\n\t return key;\n\t }\n\t },\n\n\t /**\n\t * Foreach with an iterator working on the key-value pairs.\n\t * @param func\n\t */\n\t forEach: function (func) {\n\t var hashes = this._hashes();\n\t for (var i = 0, len = hashes.length; i < len; i++) {\n\t var hash = hashes[i];\n\t var bucket = this._buckets[hash];\n\t if (Utils.isUndefined(bucket)) {\n\t continue;\n\t }\n\t func(bucket);\n\t }\n\t },\n\n\t /**\n\t * Returns a (shallow) clone of the current HashTable.\n\t * @returns {HashTable}\n\t */\n\t clone: function () {\n\t var ht = new HashTable();\n\t var hashes = this._hashes();\n\t for (var i = 0, len = hashes.length; i < len; i++) {\n\t var hash = hashes[i];\n\t var bucket = this._buckets[hash];\n\t if (Utils.isUndefined(bucket)) {\n\t continue;\n\t }\n\t ht.add(bucket.key, bucket.value);\n\t }\n\t return ht;\n\t },\n\n\t /**\n\t * Returns the hashes of the buckets.\n\t * @returns {Array}\n\t * @private\n\t */\n\t _hashes: function () {\n\t var hashes = [];\n\t for (var hash in this._buckets) {\n\t if (this._buckets.hasOwnProperty(hash)) {\n\t hashes.push(hash);\n\t }\n\t }\n\t return hashes;\n\t },\n\n\t _bucketExists: function (key) {\n\t var hashId = this._hash(key);\n\t return Utils.isDefined(this._buckets[hashId]);\n\t },\n\n\t /**\n\t * Returns-adds the createGetBucket with the given key. If not present it will\n\t * be created and returned.\n\t * A createGetBucket is a literal object of the form {key: key, ...}.\n\t */\n\t _createGetBucket: function (key) {\n\t var hashId = this._hash(key);\n\t var bucket = this._buckets[hashId];\n\t if (Utils.isUndefined(bucket)) {\n\t bucket = { key: key };\n\t this._buckets[hashId] = bucket;\n\t this.length++;\n\t }\n\t return bucket;\n\t },\n\n\t /**\n\t * Hashing of the given key.\n\t */\n\t _hash: function (key) {\n\t if (Utils.isNumber(key)) {\n\t return key;\n\t }\n\t if (Utils.isString(key)) {\n\t return this._hashString(key);\n\t }\n\t if (Utils.isObject(key)) {\n\t return this._objectHashId(key);\n\t }\n\t throw \"Unsupported key type.\";\n\t },\n\n\t /**\n\t * Hashing of a string.\n\t */\n\t _hashString: function (s) {\n\t // see for example http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery\n\t var result = 0;\n\t if (s.length === 0) {\n\t return result;\n\t }\n\t for (var i = 0; i < s.length; i++) {\n\t var ch = s.charCodeAt(i);\n\t result = ((result * 32) - result) + ch;\n\t }\n\t return result;\n\t },\n\n\t /**\n\t * Returns the unique identifier for an object. This is automatically assigned and add on the object.\n\t */\n\t _objectHashId: function (key) {\n\t var id = key._hashId;\n\t if (Utils.isUndefined(id)) {\n\t id = randomId();\n\t key._hashId = id;\n\t }\n\t return id;\n\t }\n\t });\n\n\t /*---------------The Dictionary structure--------------------------------*/\n\n\t /**\n\t * Represents a collection of key-value pairs.\n\t * Important: do not use the standard Array access method, use the get/Set methods instead.\n\t */\n\t var Dictionary = kendo.Observable.extend({\n\t /**\n\t * Initializes a new instance of the Dictionary class.\n\t * @param dictionary Loads the content of the given dictionary into this new one.\n\t */\n\t init: function (dictionary) {\n\t var that = this;\n\t kendo.Observable.fn.init.call(that);\n\t this._hashTable = new HashTable();\n\t this.length = 0;\n\t if (Utils.isDefined(dictionary)) {\n\t if ($.isArray(dictionary)) {\n\t for (var i = 0; i < dictionary.length; i++) {\n\t this.add(dictionary[i]);\n\t }\n\t } else {\n\t dictionary.forEach(function (k, v) {\n\t this.add(k, v);\n\t }, this);\n\t }\n\t }\n\t },\n\n\t /**\n\t * Adds a key-value to the dictionary.\n\t * If the key already exists this will assign the given value to the existing entry.\n\t */\n\t add: function (key, value) {\n\t var entry = this._hashTable.get(key);\n\t if (!entry) {\n\t entry = this._hashTable.add(key);\n\t this.length++;\n\t this.trigger('changed');\n\t }\n\t entry.value = value;\n\t },\n\n\t /**\n\t * Set the key-value pair.\n\t * @param key The key of the entry.\n\t * @param value The value to set. If the key already exists the value will be overwritten.\n\t */\n\t set: function (key, value) {\n\t this.add(key, value);\n\t },\n\n\t /**\n\t * Gets the value associated with the given key in the dictionary.\n\t */\n\t get: function (key) {\n\t var entry = this._hashTable.get(key);\n\t if (entry) {\n\t return entry.value;\n\t }\n\t throw new Error(\"Cannot find key \" + key);\n\t },\n\n\t /**\n\t * Returns whether the dictionary contains the given key.\n\t */\n\t containsKey: function (key) {\n\t return this._hashTable.containsKey(key);\n\t },\n\n\t /**\n\t * Removes the element with the specified key from the dictionary.\n\t */\n\t remove: function (key) {\n\t if (this.containsKey(key)) {\n\t this.trigger(\"changed\");\n\t this.length--;\n\t return this._hashTable.remove(key);\n\t }\n\t },\n\n\t /**\n\t * The functional gets the key and value as parameters.\n\t */\n\t forEach: function (func, thisRef) {\n\t this._hashTable.forEach(function (entry) {\n\t func.call(thisRef, entry.key, entry.value);\n\t });\n\t },\n\n\t /**\n\t * Same as forEach except that only the value is passed to the functional.\n\t */\n\t forEachValue: function (func, thisRef) {\n\t this._hashTable.forEach(function (entry) {\n\t func.call(thisRef, entry.value);\n\t });\n\t },\n\n\t /**\n\t * Calls a defined callback function for each key in the dictionary.\n\t */\n\t forEachKey: function (func, thisRef) {\n\t this._hashTable.forEach(function (entry) {\n\t func.call(thisRef, entry.key);\n\t });\n\t },\n\n\t /**\n\t * Gets an array with all keys in the dictionary.\n\t */\n\t keys: function () {\n\t var keys = [];\n\t this.forEachKey(function (key) {\n\t keys.push(key);\n\t });\n\t return keys;\n\t }\n\t });\n\n\t /*---------------Queue structure--------------------------------*/\n\n\t var Queue = kendo.Class.extend({\n\n\t init: function () {\n\t this._tail = null;\n\t this._head = null;\n\t this.length = 0;\n\t },\n\n\t /**\n\t * Enqueues an object to the end of the queue.\n\t */\n\t enqueue: function (value) {\n\t var entry = { value: value, next: null };\n\t if (!this._head) {\n\t this._head = entry;\n\t this._tail = this._head;\n\t }\n\t else {\n\t this._tail.next = entry;\n\t this._tail = this._tail.next;\n\t }\n\t this.length++;\n\t },\n\n\t /**\n\t * Removes and returns the object at top of the queue.\n\t */\n\t dequeue: function () {\n\t if (this.length < 1) {\n\t throw new Error(\"The queue is empty.\");\n\t }\n\t var value = this._head.value;\n\t this._head = this._head.next;\n\t this.length--;\n\t return value;\n\t },\n\n\t contains: function (item) {\n\t var current = this._head;\n\t while (current) {\n\t if (current.value === item) {\n\t return true;\n\t }\n\t current = current.next;\n\t }\n\t return false;\n\t }\n\t });\n\n\n\t /**\n\t * While other data structures can have multiple times the same item a Set owns only\n\t * once a particular item.\n\t * @type {*}\n\t */\n\t var Set = kendo.Observable.extend({\n\t init: function (resource) {\n\t var that = this;\n\t kendo.Observable.fn.init.call(that);\n\t this._hashTable = new HashTable();\n\t this.length = 0;\n\t if (Utils.isDefined(resource)) {\n\t if (resource instanceof HashTable) {\n\t resource.forEach(function (d) {\n\t this.add(d);\n\t });\n\t }\n\t else if (resource instanceof Dictionary) {\n\t resource.forEach(function (k, v) {\n\t this.add({key: k, value: v});\n\t }, this);\n\t }\n\t }\n\t },\n\n\t contains: function (item) {\n\t return this._hashTable.containsKey(item);\n\t },\n\n\t add: function (item) {\n\t var entry = this._hashTable.get(item);\n\t if (!entry) {\n\t this._hashTable.add(item, item);\n\t this.length++;\n\t this.trigger('changed');\n\t }\n\t },\n\n\t get: function (item) {\n\t if (this.contains(item)) {\n\t return this._hashTable.get(item).value;\n\t }\n\t else {\n\t return null;\n\t }\n\t },\n\n\t /**\n\t * Returns the hash of the item.\n\t * @param item\n\t * @returns {*}\n\t */\n\t hash: function (item) {\n\t return this._hashTable._hash(item);\n\t },\n\n\t /**\n\t * Removes the given item from the set. No exception is thrown if the item is not in the Set.\n\t * @param item\n\t */\n\t remove: function (item) {\n\t if (this.contains(item)) {\n\t this._hashTable.remove(item);\n\t this.length--;\n\t this.trigger('changed');\n\t }\n\t },\n\t /**\n\t * Foreach with an iterator working on the key-value pairs.\n\t * @param func\n\t */\n\t forEach: function (func, context) {\n\t this._hashTable.forEach(function (kv) {\n\t func(kv.value);\n\t }, context);\n\t },\n\t toArray: function () {\n\t var r = [];\n\t this.forEach(function (d) {\n\t r.push(d);\n\t });\n\t return r;\n\t }\n\t });\n\n\t /*----------------Node-------------------------------*/\n\n\t /**\n\t * Defines the node (vertex) of a Graph.\n\t */\n\t var Node = kendo.Class.extend({\n\n\t init: function (id, shape) {\n\n\t /**\n\t * Holds all the links incident with the current node.\n\t * Do not use this property to manage the incoming links, use the appropriate add/remove methods instead.\n\t */\n\t this.links = [];\n\n\t /**\n\t * Holds the links from the current one to another Node .\n\t * Do not use this property to manage the incoming links, use the appropriate add/remove methods instead.\n\t */\n\t this.outgoing = [];\n\n\t /**\n\t * Holds the links from another Node to the current one.\n\t * Do not use this property to manage the incoming links, use the appropriate add/remove methods instead.\n\t */\n\t this.incoming = [];\n\n\t /**\n\t * Holds the weight of this Node.\n\t */\n\t this.weight = 1;\n\n\t if (Utils.isDefined(id)) {\n\t this.id = id;\n\t }\n\t else {\n\t this.id = randomId();\n\t }\n\t if (Utils.isDefined(shape)) {\n\t this.associatedShape = shape;\n\t // transfer the shape's bounds to the runtime props\n\t var b = shape.bounds();\n\t this.width = b.width;\n\t this.height = b.height;\n\t this.x = b.x;\n\t this.y = b.y;\n\t }\n\t else {\n\t this.associatedShape = null;\n\t }\n\t /**\n\t * The payload of the node.\n\t * @type {null}\n\t */\n\t this.data = null;\n\t this.type = \"Node\";\n\t this.shortForm = \"Node '\" + this.id + \"'\";\n\t /**\n\t * Whether this is an injected node during the analysis or layout process.\n\t * @type {boolean}\n\t */\n\t this.isVirtual = false;\n\t },\n\n\t /**\n\t * Returns whether this node has no links attached.\n\t */\n\t isIsolated: function () {\n\t return Utils.isEmpty(this.links);\n\t },\n\n\t /**\n\t * Gets or sets the bounding rectangle of this node.\n\t * This should be considered as runtime data, the property is not hotlinked to a SVG item.\n\t */\n\t bounds: function (r) {\n\t if (!Utils.isDefined(r)) {\n\t return new diagram.Rect(this.x, this.y, this.width, this.height);\n\t }\n\n\t this.x = r.x;\n\t this.y = r.y;\n\t this.width = r.width;\n\t this.height = r.height;\n\t },\n\n\t /**\n\t * Returns whether there is at least one link with the given (complementary) node. This can be either an\n\t * incoming or outgoing link.\n\t */\n\t isLinkedTo: function (node) {\n\t var that = this;\n\t return Utils.any(that.links, function (link) {\n\t return link.getComplement(that) === node;\n\t });\n\t },\n\n\t /**\n\t * Gets the children of this node, defined as the adjacent nodes with a link from this node to the adjacent one.\n\t * @returns {Array}\n\t */\n\t getChildren: function () {\n\t if (this.outgoing.length === 0) {\n\t return [];\n\t }\n\t var children = [];\n\t for (var i = 0, len = this.outgoing.length; i < len; i++) {\n\t var link = this.outgoing[i];\n\t children.push(link.getComplement(this));\n\t }\n\t return children;\n\t },\n\n\t /**\n\t * Gets the parents of this node, defined as the adjacent nodes with a link from the adjacent node to this one.\n\t * @returns {Array}\n\t */\n\t getParents: function () {\n\t if (this.incoming.length === 0) {\n\t return [];\n\t }\n\t var parents = [];\n\t for (var i = 0, len = this.incoming.length; i < len; i++) {\n\t var link = this.incoming[i];\n\t parents.push(link.getComplement(this));\n\t }\n\t return parents;\n\t },\n\n\t /**\n\t * Returns a clone of the Node. Note that the identifier is not cloned since it's a different Node instance.\n\t * @returns {Node}\n\t */\n\t clone: function () {\n\t var copy = new Node();\n\t if (Utils.isDefined(this.weight)) {\n\t copy.weight = this.weight;\n\t }\n\t if (Utils.isDefined(this.balance)) {\n\t copy.balance = this.balance;\n\t }\n\t if (Utils.isDefined(this.owner)) {\n\t copy.owner = this.owner;\n\t }\n\t copy.associatedShape = this.associatedShape;\n\t copy.x = this.x;\n\t copy.y = this.y;\n\t copy.width = this.width;\n\t copy.height = this.height;\n\t return copy;\n\t },\n\n\t /**\n\t * Returns whether there is a link from the current node to the given node.\n\t */\n\t adjacentTo: function (node) {\n\t return this.isLinkedTo(node) !== null;\n\t },\n\n\t /**\n\t * Removes the given link from the link collection this node owns.\n\t * @param link\n\t */\n\t removeLink: function (link) {\n\t if (link.source === this) {\n\t Utils.remove(this.links, link);\n\t Utils.remove(this.outgoing, link);\n\t link.source = null;\n\t }\n\n\t if (link.target === this) {\n\t Utils.remove(this.links, link);\n\t Utils.remove(this.incoming, link);\n\t link.target = null;\n\t }\n\t },\n\n\t /**\n\t * Returns whether there is a (outgoing) link from the current node to the given one.\n\t */\n\t hasLinkTo: function (node) {\n\t return Utils.any(this.outgoing, function (link) {\n\t return link.target === node;\n\t });\n\t },\n\n\t /**\n\t * Returns the degree of this node, i.e. the sum of incoming and outgoing links.\n\t */\n\t degree: function () {\n\t return this.links.length;\n\t },\n\n\t /**\n\t * Returns whether this node is either the source or the target of the given link.\n\t */\n\t incidentWith: function (link) {\n\t return contains(this.links, link);\n\t },\n\n\t /**\n\t * Returns the links between this node and the given one.\n\t */\n\t getLinksWith: function (node) {\n\t return Utils.all(this.links, function (link) {\n\t return link.getComplement(this) === node;\n\t }, this);\n\t },\n\n\t /**\n\t * Returns the nodes (either parent or child) which are linked to the current one.\n\t */\n\t getNeighbors: function () {\n\t var neighbors = [];\n\t Utils.forEach(this.incoming, function (e) {\n\t neighbors.push(e.getComplement(this));\n\t }, this);\n\t Utils.forEach(this.outgoing, function (e) {\n\t neighbors.push(e.getComplement(this));\n\t }, this);\n\t return neighbors;\n\t }\n\t });\n\n\t /**\n\t * Defines a directed link (edge, connection) of a Graph.\n\t */\n\t var Link = kendo.Class.extend({\n\n\t init: function (source, target, id, connection) {\n\t if (Utils.isUndefined(source)) {\n\t throw \"The source of the new link is not set.\";\n\t }\n\t if (Utils.isUndefined(target)) {\n\t throw \"The target of the new link is not set.\";\n\t }\n\t var sourceFound, targetFound;\n\t if (Utils.isString(source)) {\n\t sourceFound = new Node(source);\n\t }\n\t else {\n\t sourceFound = source;\n\t }\n\t if (Utils.isString(target)) {\n\t targetFound = new Node(target);\n\t }\n\t else {\n\t targetFound = target;\n\t }\n\n\t this.source = sourceFound;\n\t this.target = targetFound;\n\t this.source.links.push(this);\n\t this.target.links.push(this);\n\t this.source.outgoing.push(this);\n\t this.target.incoming.push(this);\n\t if (Utils.isDefined(id)) {\n\t this.id = id;\n\t }\n\t else {\n\t this.id = randomId();\n\t }\n\t if (Utils.isDefined(connection)) {\n\t this.associatedConnection = connection;\n\t }\n\t else {\n\t this.associatedConnection = null;\n\t }\n\t this.type = \"Link\";\n\t this.shortForm = \"Link '\" + this.source.id + \"->\" + this.target.id + \"'\";\n\t },\n\n\t /**\n\t * Returns the complementary node of the given one, if any.\n\t */\n\t getComplement: function (node) {\n\t if (this.source !== node && this.target !== node) {\n\t throw \"The given node is not incident with this link.\";\n\t }\n\t return this.source === node ? this.target : this.source;\n\t },\n\n\t /**\n\t * Returns the overlap of the current link with the given one, if any.\n\t */\n\t getCommonNode: function (link) {\n\t if (this.source === link.source || this.source === link.target) {\n\t return this.source;\n\t }\n\t if (this.target === link.source || this.target === link.target) {\n\t return this.target;\n\t }\n\t return null;\n\t },\n\n\t /**\n\t * Returns whether the current link is bridging the given nodes.\n\t */\n\t isBridging: function (v1, v2) {\n\t return this.source === v1 && this.target === v2 || this.source === v2 && this.target === v1;\n\t },\n\n\t /**\n\t * Returns the source and target of this link as a tuple.\n\t */\n\t getNodes: function () {\n\t return [this.source, this.target];\n\t },\n\n\t /**\n\t * Returns whether the given node is either the source or the target of the current link.\n\t */\n\t incidentWith: function (node) {\n\t return this.source === node || this.target === node;\n\t },\n\n\t /**\n\t * Returns whether the given link is a continuation of the current one. This can be both\n\t * via an incoming or outgoing link.\n\t */\n\t adjacentTo: function (link) {\n\t return contains(this.source.links, link) || contains(this.target.links, link);\n\t },\n\n\t /**\n\t * Changes the source-node of this link.\n\t */\n\t changeSource: function (node) {\n\t Utils.remove(this.source.links, this);\n\t Utils.remove(this.source.outgoing, this);\n\n\t node.links.push(this);\n\t node.outgoing.push(this);\n\n\t this.source = node;\n\t },\n\n\t /**\n\t * Changes the target-node of this link.\n\t * @param node\n\t */\n\t changeTarget: function (node) {\n\t Utils.remove(this.target.links, this);\n\t Utils.remove(this.target.incoming, this);\n\n\t node.links.push(this);\n\t node.incoming.push(this);\n\n\t this.target = node;\n\t },\n\n\t /**\n\t * Changes both the source and the target nodes of this link.\n\t */\n\t changesNodes: function (v, w) {\n\t if (this.source === v) {\n\t this.changeSource(w);\n\t }\n\t else if (this.target === v) {\n\t this.changeTarget(w);\n\t }\n\t },\n\n\t /**\n\t * Reverses the direction of this link.\n\t */\n\t reverse: function () {\n\t var oldSource = this.source;\n\t var oldTarget = this.target;\n\n\t this.source = oldTarget;\n\t Utils.remove(oldSource.outgoing, this);\n\t this.source.outgoing.push(this);\n\n\t this.target = oldSource;\n\t Utils.remove(oldTarget.incoming, this);\n\t this.target.incoming.push(this);\n\t return this;\n\t },\n\n\t /**\n\t * Ensures that the given target defines the endpoint of this link.\n\t */\n\t directTo: function (target) {\n\t if (this.source !== target && this.target !== target) {\n\t throw \"The given node is not incident with this link.\";\n\t }\n\t if (this.target !== target) {\n\t this.reverse();\n\t }\n\t },\n\n\t /**\n\t * Returns a reversed clone of this link.\n\t */\n\t createReverseEdge: function () {\n\t var r = this.clone();\n\t r.reverse();\n\t r.reversed = true;\n\t return r;\n\t },\n\n\t /**\n\t * Returns a clone of this link.\n\t */\n\t clone: function () {\n\t var clone = new Link(this.source, this.target);\n\t return clone;\n\t }\n\t });\n\n\t /*--------------Graph structure---------------------------------*/\n\t /**\n\t * Defines a directed graph structure.\n\t * Note that the incidence structure resides in the nodes through the incoming and outgoing links collection, rahter than\n\t * inside the Graph.\n\t */\n\t var Graph = kendo.Class.extend({\n\t init: function (idOrDiagram) {\n\t /**\n\t * The links or edge collection of this Graph.\n\t * @type {Array}\n\t */\n\t this.links = [];\n\t /**\n\t * The node or vertex collection of this Graph.\n\t * @type {Array}\n\t */\n\t this.nodes = [];\n\n\t this._nodeMap = new Dictionary();\n\t /**\n\t * The optional reference to the Diagram on which this Graph is based.\n\t * @type {null}\n\t */\n\t this.diagram = null;\n\n\t /**\n\t * The root of this Graph. If not set explicitly the first Node with zero incoming links will be taken.\n\t * @type {null}\n\t * @private\n\t */\n\t this._root = null;\n\t if (Utils.isDefined(idOrDiagram)) {\n\t if (Utils.isString(idOrDiagram)) {\n\t this.id = idOrDiagram;\n\t }\n\t else {\n\t this.diagram = idOrDiagram;\n\t this.id = idOrDiagram.id;\n\t }\n\t }\n\t else {\n\t this.id = randomId();\n\t }\n\n\t /**\n\t * The bounds of this graph if the nodes have spatial extension defined.\n\t * @type {Rect}\n\t */\n\t this.bounds = new Rect();\n\t // keeps track whether the children & parents have been created\n\t this._hasCachedRelationships = false;\n\t this.type = \"Graph\";\n\t },\n\t /**\n\t * Caches the relational information of parents and children in the 'parents' and 'children'\n\t * properties.\n\t * @param forceRebuild If set to true the relational info will be rebuild even if already present.\n\t */\n\t cacheRelationships: function (forceRebuild) {\n\t if (Utils.isUndefined(forceRebuild)) {\n\t forceRebuild = false;\n\t }\n\t if (this._hasCachedRelationships && !forceRebuild) {\n\t return;\n\t }\n\t for (var i = 0, len = this.nodes.length; i < len; i++) {\n\t var node = this.nodes[i];\n\t node.children = this.getChildren(node);\n\t node.parents = this.getParents(node);\n\t }\n\t this._hasCachedRelationships = true;\n\t },\n\n\t /**\n\t * Assigns tree-levels to the nodes assuming this is a tree graph.\n\t * If not connected or not a tree the process will succeed but\n\t * will have little meaning.\n\t * @param startNode The node from where the level numbering starts, usually the root of the tree.\n\t * @param visited The collection of visited nodes.\n\t * @param offset The offset or starting counter of the level info.\n\t */\n\t assignLevels: function (startNode, offset, visited) {\n\t if (!startNode) {\n\t throw \"Start node not specified.\";\n\t }\n\t if (Utils.isUndefined(offset)) {\n\t offset = 0;\n\t }\n\t // if not done before, cache the parents and children\n\t this.cacheRelationships();\n\t if (Utils.isUndefined(visited)) {\n\t visited = new Dictionary();\n\t Utils.forEach(this.nodes, function (n) {\n\t visited.add(n, false);\n\t });\n\t }\n\t visited.set(startNode, true);\n\t startNode.level = offset;\n\t var children = startNode.children;\n\t for (var i = 0, len = children.length; i < len; i++) {\n\t var child = children[i];\n\t if (!child || visited.get(child)) {\n\t continue;\n\t }\n\t this.assignLevels(child, offset + 1, visited);\n\t }\n\t },\n\n\t /**\n\t * Gets or set the root of this graph.\n\t * If not set explicitly the first Node with zero incoming links will be taken.\n\t * @param value\n\t * @returns {*}\n\t */\n\t root: function (value) {\n\t if (Utils.isUndefined(value)) {\n\t if (!this._root) {\n\t // TODO: better to use the longest path for the most probable root?\n\t var found = Utils.first(this.nodes, function (n) {\n\t return n.incoming.length === 0;\n\t });\n\t if (found) {\n\t return found;\n\t }\n\t return Utils.first(this.nodes);\n\t }\n\t else {\n\t return this._root;\n\t }\n\t }\n\t else {\n\t this._root = value;\n\t }\n\t },\n\n\t /**\n\t * Returns the connected components of this graph.\n\t * Note that the returned graphs are made up of the nodes and links of this graph, i.e. a pointer to the items of this graph.\n\t * If you alter the items of the components you'll alter the original graph and vice versa.\n\t * @returns {Array}\n\t */\n\t getConnectedComponents: function () {\n\t this.componentIndex = 0;\n\t this.setItemIndices();\n\t var componentId = Utils.initArray(this.nodes.length, -1);\n\n\t for (var v = 0; v < this.nodes.length; v++) {\n\t if (componentId[v] === -1) {\n\t this._collectConnectedNodes(componentId, v);\n\t this.componentIndex++;\n\t }\n\t }\n\n\t var components = [], i;\n\t for (i = 0; i < this.componentIndex; ++i) {\n\t components[i] = new Graph();\n\t }\n\t for (i = 0; i < componentId.length; ++i) {\n\t var graph = components[componentId[i]];\n\t graph.addNodeAndOutgoings(this.nodes[i]);\n\t }\n\t // sorting the components in decreasing order of node count\n\t components.sort(function (a, b) {\n\t return b.nodes.length - a.nodes.length;\n\t });\n\t return components;\n\t },\n\n\t _collectConnectedNodes: function (setIds, nodeIndex) {\n\t setIds[nodeIndex] = this.componentIndex; // part of the current component\n\t var node = this.nodes[nodeIndex];\n\t Utils.forEach(node.links,\n\t function (link) {\n\t var next = link.getComplement(node);\n\t var nextId = next.index;\n\t if (setIds[nextId] === -1) {\n\t this._collectConnectedNodes(setIds, nextId);\n\t }\n\t }, this);\n\t },\n\n\t /**\n\t * Calculates the bounds of this Graph if the Nodes have spatial dimensions defined.\n\t * @returns {Rect}\n\t */\n\t calcBounds: function () {\n\t if (this.isEmpty()) {\n\t this.bounds = new Rect();\n\t return this.bounds;\n\t }\n\t var b = null;\n\t for (var i = 0, len = this.nodes.length; i < len; i++) {\n\t var node = this.nodes[i];\n\t if (!b) {\n\t b = node.bounds();\n\t }\n\t else {\n\t b = b.union(node.bounds());\n\t }\n\t }\n\t this.bounds = b;\n\t return this.bounds;\n\t },\n\n\t /**\n\t * Creates a spanning tree for the current graph.\n\t * Important: this will not return a spanning forest if the graph is disconnected.\n\t * Prim's algorithm finds a minimum-cost spanning tree of an edge-weighted, connected, undirected graph;\n\t * see http://en.wikipedia.org/wiki/Prim%27s_algorithm .\n\t * @param root The root of the spanning tree.\n\t * @returns {Graph}\n\t */\n\t getSpanningTree: function (root) {\n\t var tree = new Graph();\n\t var map = new Dictionary(), source, target;\n\t tree.root = root.clone();\n\t tree.root.level = 0;\n\t tree.root.id = root.id;\n\t map.add(root, tree.root);\n\t root.level = 0;\n\n\t var visited = [];\n\t var remaining = [];\n\t tree._addNode(tree.root);\n\t visited.push(root);\n\t remaining.push(root);\n\n\t var levelCount = 1;\n\t while (remaining.length > 0) {\n\t var next = remaining.pop();\n\t for (var ni = 0; ni < next.links.length; ni++) {\n\t var link = next.links[ni];\n\t var cn = link.getComplement(next);\n\t if (contains(visited, cn)) {\n\t continue;\n\t }\n\n\t cn.level = next.level + 1;\n\t if (levelCount < cn.level + 1) {\n\t levelCount = cn.level + 1;\n\t }\n\t if (!contains(remaining, cn)) {\n\t remaining.push(cn);\n\t }\n\t if (!contains(visited, cn)) {\n\t visited.push(cn);\n\t }\n\t if (map.containsKey(next)) {\n\t source = map.get(next);\n\t }\n\t else {\n\t source = next.clone();\n\t source.level = next.level;\n\t source.id = next.id;\n\t map.add(next, source);\n\t }\n\t if (map.containsKey(cn)) {\n\t target = map.get(cn);\n\t }\n\t else {\n\t target = cn.clone();\n\t target.level = cn.level;\n\t target.id = cn.id;\n\t map.add(cn, target);\n\t }\n\t var newLink = new Link(source, target);\n\t tree.addLink(newLink);\n\t }\n\n\t }\n\n\t var treeLevels = [];\n\t for (var i = 0; i < levelCount; i++) {\n\t treeLevels.push([]);\n\t }\n\n\t Utils.forEach(tree.nodes, function (node) {\n\t treeLevels[node.level].push(node);\n\t });\n\n\t tree.treeLevels = treeLevels;\n\t tree.cacheRelationships();\n\t return tree;\n\t },\n\n\t /**\n\t * Returns a random node in this graph.\n\t * @param excludedNodes The collection of nodes which should not be considered.\n\t * @param incidenceLessThan The maximum degree or incidence the random node should have.\n\t * @returns {*}\n\t */\n\t takeRandomNode: function (excludedNodes, incidenceLessThan) {\n\t if (Utils.isUndefined(excludedNodes)) {\n\t excludedNodes = [];\n\t }\n\t if (Utils.isUndefined(incidenceLessThan)) {\n\t incidenceLessThan = 4;\n\t }\n\t if (this.nodes.length === 0) {\n\t return null;\n\t }\n\t if (this.nodes.length === 1) {\n\t return contains(excludedNodes, this.nodes[0]) ? null : this.nodes[0];\n\t }\n\t var pool = $.grep(this.nodes, function (node) {\n\t return !contains(excludedNodes, node) && node.degree() <= incidenceLessThan;\n\t });\n\t if (Utils.isEmpty(pool)) {\n\t return null;\n\t }\n\t return pool[Utils.randomInteger(0, pool.length)];\n\t },\n\n\t /**\n\t * Returns whether this is an empty graph.\n\t */\n\t isEmpty: function () {\n\t return Utils.isEmpty(this.nodes);\n\t },\n\n\t /**\n\t * Checks whether the endpoints of the links are all in the nodes collection.\n\t */\n\t isHealthy: function () {\n\t return Utils.all(this.links, function (link) {\n\t return contains(this.nodes, link.source) && contains(this.nodes, link.target);\n\t }, this);\n\t },\n\n\t /**\n\t * Gets the parents of this node, defined as the adjacent nodes with a link from the adjacent node to this one.\n\t * @returns {Array}\n\t */\n\t getParents: function (n) {\n\t if (!this.hasNode(n)) {\n\t throw \"The given node is not part of this graph.\";\n\t }\n\t return n.getParents();\n\t },\n\n\t /**\n\t * Gets the children of this node, defined as the adjacent nodes with a link from this node to the adjacent one.\n\t * @returns {Array}\n\t */\n\t getChildren: function (n) {\n\t if (!this.hasNode(n)) {\n\t throw \"The given node is not part of this graph.\";\n\t }\n\t return n.getChildren();\n\t },\n\n\t /**\n\t * Adds a new link to the graph between the given nodes.\n\t */\n\t addLink: function (sourceOrLink, target, owner) {\n\n\t if (Utils.isUndefined(sourceOrLink)) {\n\t throw \"The source of the link is not defined.\";\n\t }\n\t if (Utils.isUndefined(target)) {\n\t // can only be undefined if the first one is a Link\n\t if (Utils.isDefined(sourceOrLink.type) && sourceOrLink.type === \"Link\") {\n\t this.addExistingLink(sourceOrLink);\n\t return;\n\t }\n\t else {\n\t throw \"The target of the link is not defined.\";\n\t }\n\t }\n\n\t var foundSource = this.getNode(sourceOrLink);\n\t if (Utils.isUndefined(foundSource)) {\n\t foundSource = this.addNode(sourceOrLink);\n\t }\n\t var foundTarget = this.getNode(target);\n\t if (Utils.isUndefined(foundTarget)) {\n\t foundTarget = this.addNode(target);\n\t }\n\n\t var newLink = new Link(foundSource, foundTarget);\n\n\t if (Utils.isDefined(owner)) {\n\t newLink.owner = owner;\n\t }\n\n\t /*newLink.source.outgoing.push(newLink);\n\t newLink.source.links.push(newLink);\n\t newLink.target.incoming.push(newLink);\n\t newLink.target.links.push(newLink);*/\n\n\t this.links.push(newLink);\n\n\t return newLink;\n\t },\n\n\t /**\n\t * Removes all the links in this graph.\n\t */\n\t removeAllLinks: function () {\n\t while (this.links.length > 0) {\n\t var link = this.links[0];\n\t this.removeLink(link);\n\t }\n\t },\n\n\t /**\n\t * Adds the given link to the current graph.\n\t */\n\t addExistingLink: function (link) {\n\n\t if (this.hasLink(link)) {\n\t return;\n\t }\n\t this.links.push(link);\n\t if (this.hasNode(link.source.id)) {\n\t // priority to the existing node with the id even if other props are different\n\t var s = this.getNode(link.source.id);\n\t link.changeSource(s);\n\t }\n\t else {\n\t this.addNode(link.source);\n\t }\n\n\t if (this.hasNode(link.target.id)) {\n\t var t = this.getNode(link.target.id);\n\t link.changeTarget(t);\n\t }\n\t else {\n\t this.addNode(link.target);\n\t }\n\n\t /* if (!link.source.outgoing.contains(link)) {\n\t link.source.outgoing.push(link);\n\t }\n\t if (!link.source.links.contains(link)) {\n\t link.source.links.push(link);\n\t }\n\t if (!link.target.incoming.contains(link)) {\n\t link.target.incoming.push(link);\n\t }\n\t if (!link.target.links.contains(link)) {\n\t link.target.links.push(link);\n\t }*/\n\t },\n\n\t /**\n\t * Returns whether the given identifier or Link is part of this graph.\n\t * @param linkOrId An identifier or a Link object.\n\t * @returns {*}\n\t */\n\t hasLink: function (linkOrId) {\n\t if (Utils.isString(linkOrId)) {\n\t return Utils.any(this.links, function (link) {\n\t return link.id === linkOrId;\n\t });\n\t }\n\t if (linkOrId.type === \"Link\") {\n\t return contains(this.links, linkOrId);\n\t }\n\t throw \"The given object is neither an identifier nor a Link.\";\n\t },\n\t /**\n\t * Gets the node with the specified Id or null if not part of this graph.\n\t */\n\t getNode: function (nodeOrId) {\n\t var id = nodeOrId.id || nodeOrId;\n\t if (this._nodeMap.containsKey(id)) {\n\t return this._nodeMap.get(id);\n\t }\n\t },\n\n\t /**\n\t * Returns whether the given node or node Id is part of this graph.\n\t */\n\t hasNode: function (nodeOrId) {\n\t var id = nodeOrId.id || nodeOrId;\n\t return this._nodeMap.containsKey(id);\n\t },\n\n\t _addNode: function(node) {\n\t this.nodes.push(node);\n\t this._nodeMap.add(node.id, node);\n\t },\n\n\t _removeNode: function(node) {\n\t Utils.remove(this.nodes, node);\n\t this._nodeMap.remove(node.id);\n\t },\n\n\t /**\n\t * Removes the given node from this graph.\n\t * The node can be specified as an object or as an identifier (string).\n\t */\n\t removeNode: function (nodeOrId) {\n\t var n = nodeOrId;\n\t if (Utils.isString(nodeOrId)) {\n\t n = this.getNode(nodeOrId);\n\t }\n\n\t if (Utils.isDefined(n)) {\n\t var links = n.links;\n\t n.links = [];\n\t for (var i = 0, len = links.length; i < len; i++) {\n\t var link = links[i];\n\t this.removeLink(link);\n\t }\n\t this._removeNode(n);\n\t }\n\t else {\n\t throw \"The identifier should be a Node or the Id (string) of a node.\";\n\t }\n\t },\n\n\t /**\n\t * Returns whether the given nodes are connected with a least one link independently of the direction.\n\t */\n\t areConnected: function (n1, n2) {\n\t return Utils.any(this.links, function (link) {\n\t return link.source == n1 && link.target == n2 || link.source == n2 && link.target == n1;\n\t });\n\t },\n\n\t /**\n\t * Removes the given link from this graph.\n\t */\n\t removeLink: function (link) {\n\t /* if (!this.links.contains(link)) {\n\t throw \"The given link is not part of the Graph.\";\n\t }\n\t */\n\t Utils.remove(this.links, link);\n\n\t Utils.remove(link.source.outgoing, link);\n\t Utils.remove(link.source.links, link);\n\t Utils.remove(link.target.incoming, link);\n\t Utils.remove(link.target.links, link);\n\t },\n\n\t /**\n\t * Adds a new node to this graph, if not already present.\n\t * The node can be an existing Node or the identifier of a new node.\n\t * No error is thrown if the node is already there and the existing one is returned.\n\t */\n\t addNode: function (nodeOrId, layoutRect, owner) {\n\n\t var newNode = null;\n\n\t if (!Utils.isDefined(nodeOrId)) {\n\t throw \"No Node or identifier for a new Node is given.\";\n\t }\n\n\t if (Utils.isString(nodeOrId)) {\n\t if (this.hasNode(nodeOrId)) {\n\t return this.getNode(nodeOrId);\n\t }\n\t newNode = new Node(nodeOrId);\n\t }\n\t else {\n\t if (this.hasNode(nodeOrId)) {\n\t return this.getNode(nodeOrId);\n\t }\n\t // todo: ensure that the param is a Node?\n\t newNode = nodeOrId;\n\t }\n\n\t if (Utils.isDefined(layoutRect)) {\n\t newNode.bounds(layoutRect);\n\t }\n\n\t if (Utils.isDefined(owner)) {\n\t newNode.owner = owner;\n\t }\n\t this._addNode(newNode);\n\t return newNode;\n\t },\n\n\t /**\n\t * Adds the given Node and its outgoing links.\n\t */\n\t addNodeAndOutgoings: function (node) {\n\t if (!this.hasNode(node)) {\n\t this._addNode(node);\n\t }\n\n\t var newLinks = node.outgoing;\n\t node.outgoing = [];\n\t Utils.forEach(newLinks, function (link) {\n\t this.addExistingLink(link);\n\t }, this);\n\t },\n\n\t /**\n\t * Sets the 'index' property on the links and nodes of this graph.\n\t */\n\t setItemIndices: function () {\n\t var i;\n\t for (i = 0; i < this.nodes.length; ++i) {\n\t this.nodes[i].index = i;\n\t }\n\n\t for (i = 0; i < this.links.length; ++i) {\n\t this.links[i].index = i;\n\t }\n\t },\n\n\t /**\n\t * Returns a clone of this graph.\n\t */\n\t clone: function (saveMapping) {\n\t var copy = new Graph();\n\t var save = Utils.isDefined(saveMapping) && saveMapping === true;\n\t if (save) {\n\t copy.nodeMap = new Dictionary();\n\t copy.linkMap = new Dictionary();\n\t }\n\t // we need a map even if the saveMapping is not set\n\t var map = new Dictionary();\n\t Utils.forEach(this.nodes, function (nOriginal) {\n\t var nCopy = nOriginal.clone();\n\t map.set(nOriginal, nCopy);\n\t copy._addNode(nCopy);\n\n\t if (save) {\n\t copy.nodeMap.set(nCopy, nOriginal);\n\t }\n\t });\n\n\t Utils.forEach(this.links, function (linkOriginal) {\n\t if (map.containsKey(linkOriginal.source) && map.containsKey(linkOriginal.target)) {\n\t var linkCopy = copy.addLink(map.get(linkOriginal.source), map.get(linkOriginal.target));\n\t if (save) {\n\t copy.linkMap.set(linkCopy, linkOriginal);\n\t }\n\t }\n\t });\n\n\t return copy;\n\t },\n\n\t /**\n\t * The parsing allows a quick way to create graphs.\n\t * - [\"n1->n2\", \"n2->n3\"]: creates the three nodes and adds the links\n\t * - [\"n1->n2\", {id: \"QSDF\"}, \"n2->n3\"]: same as previous but also performs a deep extend of the link between n1 and n2 with the given object.\n\t */\n\t linearize: function (addIds) {\n\t return Graph.Utils.linearize(this, addIds);\n\t },\n\n\t /**\n\t * Performs a depth-first traversal starting at the given node.\n\t * @param startNode a node or id of a node in this graph\n\t * @param action\n\t */\n\t depthFirstTraversal: function (startNode, action) {\n\t if (Utils.isUndefined(startNode)) {\n\t throw \"You need to supply a starting node.\";\n\t }\n\t if (Utils.isUndefined(action)) {\n\t throw \"You need to supply an action.\";\n\t }\n\t if (!this.hasNode(startNode)) {\n\t throw \"The given start-node is not part of this graph\";\n\t }\n\t var foundNode = this.getNode(startNode);// case the given one is an Id\n\t var visited = [];\n\t this._dftIterator(foundNode, action, visited);\n\t },\n\n\t _dftIterator: function (node, action, visited) {\n\n\t action(node);\n\t visited.push(node);\n\t var children = node.getChildren();\n\t for (var i = 0, len = children.length; i < len; i++) {\n\t var child = children[i];\n\t if (contains(visited, child)) {\n\t continue;\n\t }\n\t this._dftIterator(child, action, visited);\n\t }\n\t },\n\n\t /**\n\t * Performs a breadth-first traversal starting at the given node.\n\t * @param startNode a node or id of a node in this graph\n\t * @param action\n\t */\n\t breadthFirstTraversal: function (startNode, action) {\n\n\t if (Utils.isUndefined(startNode)) {\n\t throw \"You need to supply a starting node.\";\n\t }\n\t if (Utils.isUndefined(action)) {\n\t throw \"You need to supply an action.\";\n\t }\n\n\t if (!this.hasNode(startNode)) {\n\t throw \"The given start-node is not part of this graph\";\n\t }\n\t var foundNode = this.getNode(startNode);// case the given one is an Id\n\t var queue = new Queue();\n\t var visited = [];\n\t queue.enqueue(foundNode);\n\n\t while (queue.length > 0) {\n\t var node = queue.dequeue();\n\t action(node);\n\t visited.push(node);\n\t var children = node.getChildren();\n\t for (var i = 0, len = children.length; i < len; i++) {\n\t var child = children[i];\n\t if (contains(visited, child) || contains(queue, child)) {\n\t continue;\n\t }\n\t queue.enqueue(child);\n\t }\n\t }\n\t },\n\n\t /**\n\t * This is the classic Tarjan algorithm for strongly connected components.\n\t * See e.g. http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm\n\t * @param excludeSingleItems Whether isolated nodes should be excluded from the analysis.\n\t * @param node The start node from which the analysis starts.\n\t * @param indices Numbers the nodes consecutively in the order in which they are discovered.\n\t * @param lowLinks The smallest index of any node known to be reachable from the node, including the node itself\n\t * @param connected The current component.\n\t * @param stack The bookkeeping stack of things to visit.\n\t * @param index The counter of visited nodes used to assign the indices.\n\t * @private\n\t */\n\t _stronglyConnectedComponents: function (excludeSingleItems, node, indices, lowLinks, connected, stack, index) {\n\t indices.add(node, index);\n\t lowLinks.add(node, index);\n\t index++;\n\n\t stack.push(node);\n\n\t var children = node.getChildren(), next;\n\t for (var i = 0, len = children.length; i < len; i++) {\n\t next = children[i];\n\t if (!indices.containsKey(next)) {\n\t this._stronglyConnectedComponents(excludeSingleItems, next, indices, lowLinks, connected, stack, index);\n\t lowLinks.add(node, Math.min(lowLinks.get(node), lowLinks.get(next)));\n\t }\n\t else if (contains(stack, next)) {\n\t lowLinks.add(node, Math.min(lowLinks.get(node), indices.get(next)));\n\t }\n\t }\n\t // If v is a root node, pop the stack and generate a strong component\n\t if (lowLinks.get(node) === indices.get(node)) {\n\t var component = [];\n\t do {\n\t next = stack.pop();\n\t component.push(next);\n\t }\n\t while (next !== node);\n\t if (!excludeSingleItems || (component.length > 1)) {\n\t connected.push(component);\n\t }\n\t }\n\t },\n\n\t /**\n\t * Returns the cycles found in this graph.\n\t * The returned arrays consist of the nodes which are strongly coupled.\n\t * @param excludeSingleItems Whether isolated nodes should be excluded.\n\t * @returns {Array} The array of cycles found.\n\t */\n\t findCycles: function (excludeSingleItems) {\n\t if (Utils.isUndefined(excludeSingleItems)) {\n\t excludeSingleItems = true;\n\t }\n\t var indices = new Dictionary();\n\t var lowLinks = new Dictionary();\n\t var connected = [];\n\t var stack = [];\n\t for (var i = 0, len = this.nodes.length; i < len; i++) {\n\t var node = this.nodes[i];\n\t if (indices.containsKey(node)) {\n\t continue;\n\t }\n\t this._stronglyConnectedComponents(excludeSingleItems, node, indices, lowLinks, connected, stack, 0);\n\t }\n\t return connected;\n\t },\n\n\t /**\n\t * Returns whether this graph is acyclic.\n\t * @returns {*}\n\t */\n\t isAcyclic: function () {\n\t return Utils.isEmpty(this.findCycles());\n\t },\n\n\t /**\n\t * Returns whether the given graph is a subgraph of this one.\n\t * @param other Another graph instance.\n\t */\n\t isSubGraph: function (other) {\n\t var otherArray = other.linearize();\n\t var thisArray = this.linearize();\n\t return Utils.all(otherArray, function (s) {\n\t return contains(thisArray, s);\n\t });\n\t },\n\n\t /**\n\t * Makes an acyclic graph from the current (connected) one.\n\t * * @returns {Array} The reversed links.\n\t */\n\t makeAcyclic: function () {\n\t // if empty or almost empty\n\t if (this.isEmpty() || this.nodes.length <= 1 || this.links.length <= 1) {\n\t return [];\n\t }\n\t // singular case of just two nodes\n\t if (this.nodes.length == 2) {\n\t var result = [];\n\t if (this.links.length > 1) {\n\t var oneLink = this.links[0];\n\t var oneNode = oneLink.source;\n\t for (var i = 0, len = this.links.length; i < len; i++) {\n\t var link = this.links[i];\n\t if (link.source == oneNode) {\n\t continue;\n\t }\n\t var rev = link.reverse();\n\t result.push(rev);\n\t }\n\t }\n\t return result;\n\t }\n\n\t var copy = this.clone(true); // copy.nodeMap tells you the mapping\n\t var N = this.nodes.length;\n\n\t var intensityCatalog = new Dictionary();\n\n\t /**\n\t * If there are both incoming and outgoing links this will return the flow intensity (out-in).\n\t * Otherwise the node acts as a flow source with N specifying the (equal) intensity.\n\t * @param node\n\t * @returns {number}\n\t */\n\t var flowIntensity = function (node) {\n\t if (node.outgoing.length === 0) {\n\t return (2 - N);\n\t }\n\t else if (node.incoming.length === 0) {\n\t return (N - 2);\n\t }\n\t else {\n\t return node.outgoing.length - node.incoming.length;\n\t }\n\t };\n\n\t /**\n\t * Collects the nodes with the same intensity.\n\t * @param node\n\t * @param intensityCatalog\n\t */\n\t var catalogEqualIntensity = function (node, intensityCatalog) {\n\t var intensity = flowIntensity(node, N);\n\t if (!intensityCatalog.containsKey(intensity)) {\n\t intensityCatalog.set(intensity, []);\n\t }\n\t intensityCatalog.get(intensity).push(node);\n\t };\n\n\t Utils.forEach(copy.nodes, function (v) {\n\t catalogEqualIntensity(v, intensityCatalog);\n\t });\n\n\t var sourceStack = [];\n\t var targetStack = [];\n\n\t while (copy.nodes.length > 0) {\n\t var source, target, intensity;\n\t if (intensityCatalog.containsKey(2 - N)) {\n\t var targets = intensityCatalog.get(2 - N); // nodes without outgoings\n\t while (targets.length > 0) {\n\t target = targets.pop();\n\t for (var li = 0; li < target.links.length; li++) {\n\t var targetLink = target.links[li];\n\t source = targetLink.getComplement(target);\n\t intensity = flowIntensity(source, N);\n\t Utils.remove(intensityCatalog.get(intensity), source);\n\t source.removeLink(targetLink);\n\t catalogEqualIntensity(source, intensityCatalog);\n\t }\n\t copy._removeNode(target);\n\t targetStack.unshift(target);\n\t }\n\t }\n\n\t // move sources to sourceStack\n\t if (intensityCatalog.containsKey(N - 2)) {\n\t var sources = intensityCatalog.get(N - 2); // nodes without incomings\n\t while (sources.length > 0) {\n\t source = sources.pop();\n\t for (var si = 0; si < source.links.length; si++) {\n\t var sourceLink = source.links[si];\n\t target = sourceLink.getComplement(source);\n\t intensity = flowIntensity(target, N);\n\t Utils.remove(intensityCatalog.get(intensity), target);\n\t target.removeLink(sourceLink);\n\t catalogEqualIntensity(target, intensityCatalog);\n\t }\n\t sourceStack.push(source);\n\t copy._removeNode(source);\n\t }\n\t }\n\n\t if (copy.nodes.length > 0) {\n\t for (var k = N - 3; k > 2 - N; k--) {\n\t if (intensityCatalog.containsKey(k) &&\n\t intensityCatalog.get(k).length > 0) {\n\t var maxdiff = intensityCatalog.get(k);\n\t var v = maxdiff.pop();\n\t for (var ri = 0; ri < v.links.length; ri++) {\n\t var ril = v.links[ri];\n\t var u = ril.getComplement(v);\n\t intensity = flowIntensity(u, N);\n\t Utils.remove(intensityCatalog.get(intensity), u);\n\t u.removeLink(ril);\n\t catalogEqualIntensity(u, intensityCatalog);\n\t }\n\t sourceStack.push(v);\n\t copy._removeNode(v);\n\t break;\n\t }\n\t }\n\t }\n\t }\n\n\t sourceStack = sourceStack.concat(targetStack);\n\n\t var vertexOrder = new Dictionary();\n\t for (var kk = 0; kk < this.nodes.length; kk++) {\n\t vertexOrder.set(copy.nodeMap.get(sourceStack[kk]), kk);\n\t }\n\n\t var reversedEdges = [];\n\t Utils.forEach(this.links, function (link) {\n\t if (vertexOrder.get(link.source) > vertexOrder.get(link.target)) {\n\t link.reverse();\n\t reversedEdges.push(link);\n\t }\n\t });\n\t return reversedEdges;\n\t }\n\t });\n\n\t /**\n\t * A collection of predefined graphs for demo and testing purposes.\n\t */\n\t Graph.Predefined = {\n\t /**\n\t * Eight-shapes graph all connected in a cycle.\n\t * @returns {*}\n\t * @constructor\n\t */\n\t EightGraph: function () {\n\t return Graph.Utils.parse([ \"1->2\", \"2->3\", \"3->4\", \"4->1\", \"3->5\", \"5->6\", \"6->7\", \"7->3\"]);\n\t },\n\n\t /**\n\t * Creates a typical mindmap diagram.\n\t * @returns {*}\n\t * @constructor\n\t */\n\t Mindmap: function () {\n\t return Graph.Utils.parse([\"0->1\", \"0->2\", \"0->3\", \"0->4\", \"0->5\", \"1->6\", \"1->7\", \"7->8\", \"2->9\", \"9->10\", \"9->11\", \"3->12\",\n\t \"12->13\", \"13->14\", \"4->15\", \"4->16\", \"15->17\", \"15->18\", \"18->19\", \"18->20\", \"14->21\", \"14->22\", \"5->23\", \"23->24\", \"23->25\", \"6->26\"]);\n\t },\n\n\t /**\n\t * Three nodes connected in a cycle.\n\t * @returns {*}\n\t * @constructor\n\t */\n\t ThreeGraph: function () {\n\t return Graph.Utils.parse([ \"1->2\", \"2->3\", \"3->1\"]);\n\t },\n\n\t /**\n\t * A tree with each node having two children.\n\t * @param levels How many levels the binary tree should have.\n\t * @returns {diagram.Graph}\n\t * @constructor\n\t */\n\t BinaryTree: function (levels) {\n\t if (Utils.isUndefined(levels)) {\n\t levels = 5;\n\t }\n\t return Graph.Utils.createBalancedTree(levels, 2);\n\t },\n\n\t /**\n\t * A linear graph (discrete line segment).\n\t * @param length How many segments (the node count is hence (length+1)).\n\t * @returns {diagram.Graph}\n\t * @constructor\n\t */\n\t Linear: function (length) {\n\t if (Utils.isUndefined(length)) {\n\t length = 10;\n\t }\n\t return Graph.Utils.createBalancedTree(length, 1);\n\t },\n\n\t /**\n\t * A standard tree-graph with the specified levels and children (siblings) count.\n\t * Note that for a balanced tree of level N and sibling count s, counting the root as level zero:\n\t * - NodeCount = (1-s^(N+1))/(1-s)]\n\t * - LinkCount = s.(1-s^N)/(1-s)\n\t * @param levels How many levels the tree should have.\n\t * @param siblingsCount How many siblings each level should have.\n\t * @returns {diagram.Graph}\n\t * @constructor\n\t */\n\t Tree: function (levels, siblingsCount) {\n\t return Graph.Utils.createBalancedTree(levels, siblingsCount);\n\t },\n\n\t /**\n\t * Creates a forest.\n\t * Note that for a balanced forest of level N, sibling count s and tree count t, counting the root as level zero:\n\t * - NodeCount = t.(1-s^(N+1))/(1-s)]\n\t * - LinkCount = t.s.(1-s^N)/(1-s)\n\t * @param levels How many levels the tree should have.\n\t * @param siblingsCount How many siblings each level should have.\n\t * @param trees The amount of trees the forest should have.\n\t * @returns {diagram.Graph}\n\t * @constructor\n\t */\n\t Forest: function (levels, siblingsCount, trees) {\n\t return Graph.Utils.createBalancedForest(levels, siblingsCount, trees);\n\t },\n\n\t /**\n\t * A workflow-like graph with cycles.\n\t * @returns {*}\n\t * @constructor\n\t */\n\t Workflow: function () {\n\t return Graph.Utils.parse(\n\t [\"0->1\", \"1->2\", \"2->3\", \"1->4\", \"4->3\", \"3->5\", \"5->6\", \"6->3\", \"6->7\", \"5->4\"]\n\t );\n\t },\n\n\t /**\n\t * A grid graph with the direction of the links avoiding cycles.\n\t * Node count: (n+1).(m+1)\n\t * Link count: n.(m+1) + m.(n+1)\n\t * @param n Horizontal count of grid cells. If zero this will result in a linear graph.\n\t * @param m Vertical count of grid cells. If zero this will result in a linear graph.\n\t * @constructor\n\t */\n\t Grid: function (n, m) {\n\t var g = new diagram.Graph();\n\t if (n <= 0 && m <= 0) {\n\t return g;\n\t }\n\n\t for (var i = 0; i < n + 1; i++) {\n\t var previous = null;\n\t for (var j = 0; j < m + 1; j++) {\n\t // using x-y coordinates to name the nodes\n\t var node = new Node(i.toString() + \".\" + j.toString());\n\t g.addNode(node);\n\t if (previous) {\n\t g.addLink(previous, node);\n\t }\n\t if (i > 0) {\n\t var left = g.getNode((i - 1).toString() + \".\" + j.toString());\n\t g.addLink(left, node);\n\t }\n\t previous = node;\n\t }\n\t }\n\t return g;\n\t }\n\n\t };\n\n\t /**\n\t * Graph generation and other utilities.\n\t */\n\t Graph.Utils = {\n\t /**\n\t * The parsing allows a quick way to create graphs.\n\t * - [\"n1->n2\", \"n2->n3\"]: creates the three nodes and adds the links\n\t * - [\"n1->n2\", {id: \"id177\"}, \"n2->n3\"]: same as previous but also performs a deep extend of the link between n1 and n2 with the given object.\n\t */\n\t parse: function (graphString) {\n\n\t var previousLink, graph = new diagram.Graph(), parts = graphString.slice();\n\t for (var i = 0, len = parts.length; i < len; i++) {\n\t var part = parts[i];\n\t if (Utils.isString(part)) // link spec\n\t {\n\t if (part.indexOf(\"->\") < 0) {\n\t throw \"The link should be specified as 'a->b'.\";\n\t }\n\t var p = part.split(\"->\");\n\t if (p.length != 2) {\n\t throw \"The link should be specified as 'a->b'.\";\n\t }\n\t previousLink = new Link(p[0], p[1]);\n\t graph.addLink(previousLink);\n\t }\n\t if (Utils.isObject(part)) {\n\t if (!previousLink) {\n\t throw \"Specification found before Link definition.\";\n\t }\n\t kendo.deepExtend(previousLink, part);\n\t }\n\t }\n\t return graph;\n\t },\n\n\t /**\n\t * Returns a linearized representation of the given Graph.\n\t * See also the Graph.Utils.parse method for the inverse operation.\n\t */\n\t linearize: function (graph, addIds) {\n\t if (Utils.isUndefined(graph)) {\n\t throw \"Expected an instance of a Graph object in slot one.\";\n\t }\n\t if (Utils.isUndefined(addIds)) {\n\t addIds = false;\n\t }\n\t var lin = [];\n\t for (var i = 0, len = graph.links.length; i < len; i++) {\n\t var link = graph.links[i];\n\t lin.push(link.source.id + \"->\" + link.target.id);\n\t if (addIds) {\n\t lin.push({id: link.id});\n\t }\n\t }\n\t return lin;\n\t },\n\n\t /**\n\t * The method used by the diagram creation to instantiate a shape.\n\t * @param kendoDiagram The Kendo diagram where the diagram will be created.\n\t * @param p The position at which to place the shape.\n\t * @param shapeDefaults Optional Shape options.\n\t * @param id Optional identifier of the shape.\n\t * @returns {*}\n\t * @private\n\t */\n\t _addShape: function (kendoDiagram, p, id, shapeDefaults) {\n\t if (Utils.isUndefined(p)) {\n\t p = new diagram.Point(0, 0);\n\t }\n\n\t if (Utils.isUndefined(id)) {\n\t id = randomId();\n\t }\n\n\t shapeDefaults = kendo.deepExtend({\n\t width: 20,\n\t height: 20,\n\t id: id,\n\t radius: 10,\n\t fill: \"#778899\",\n\t data: \"circle\",\n\t undoable: false,\n\t x: p.x,\n\t y: p.y\n\t }, shapeDefaults);\n\n\t return kendoDiagram.addShape(shapeDefaults);\n\t },\n\t /**\n\t * The method used by the diagram creation to instantiate a connection.\n\t * @param diagram he Kendo diagram where the diagram will be created.\n\t * @param from The source shape.\n\t * @param to The target shape.\n\t * @param options Optional Connection options.\n\t * @returns {*}\n\t * @private\n\t */\n\t _addConnection: function (diagram, from, to, options) {\n\t return diagram.connect(from, to, options);\n\t },\n\n\t /**\n\t * Creates a diagram from the given Graph.\n\t * @param diagram The Kendo diagram where the diagram will be created.\n\t * @param graph The graph structure defining the diagram.\n\t */\n\t createDiagramFromGraph: function (diagram, graph, doLayout, randomSize) {\n\n\t if (Utils.isUndefined(diagram)) {\n\t throw \"The diagram surface is undefined.\";\n\t }\n\t if (Utils.isUndefined(graph)) {\n\t throw \"No graph specification defined.\";\n\t }\n\t if (Utils.isUndefined(doLayout)) {\n\t doLayout = true;\n\t }\n\t if (Utils.isUndefined(randomSize)) {\n\t randomSize = false;\n\t }\n\n\t var width = diagram.element.clientWidth || 200;\n\t var height = diagram.element.clientHeight || 200;\n\t var map = [], node, shape;\n\t for (var i = 0, len = graph.nodes.length; i < len; i++) {\n\t node = graph.nodes[i];\n\t var p = node.position;\n\t if (Utils.isUndefined(p)) {\n\t if (Utils.isDefined(node.x) && Utils.isDefined(node.y)) {\n\t p = new Point(node.x, node.y);\n\t }\n\t else {\n\t p = new Point(Utils.randomInteger(10, width - 20), Utils.randomInteger(10, height - 20));\n\t }\n\t }\n\t var opt = {};\n\n\t if (node.id === \"0\") {\n\t /* kendo.deepExtend(opt,\n\t {\n\t fill: \"Orange\",\n\t data: 'circle',\n\t width: 100,\n\t height: 100,\n\t center: new Point(50, 50)\n\t });*/\n\t }\n\t else if (randomSize) {\n\t kendo.deepExtend(opt, {\n\t width: Math.random() * 150 + 20,\n\t height: Math.random() * 80 + 50,\n\t data: 'rectangle',\n\t fill: {\n\t color: \"#778899\"\n\t }\n\t });\n\t }\n\n\t shape = this._addShape(diagram, p, node.id, opt);\n\t //shape.content(node.id);\n\n\t var bounds = shape.bounds();\n\t if (Utils.isDefined(bounds)) {\n\t node.x = bounds.x;\n\t node.y = bounds.y;\n\t node.width = bounds.width;\n\t node.height = bounds.height;\n\t }\n\t map[node.id] = shape;\n\t }\n\t for (var gli = 0; gli < graph.links.length; gli++) {\n\t var link = graph.links[gli];\n\t var sourceShape = map[link.source.id];\n\t if (Utils.isUndefined(sourceShape)) {\n\t continue;\n\t }\n\t var targetShape = map[link.target.id];\n\t if (Utils.isUndefined(targetShape)) {\n\t continue;\n\t }\n\t this._addConnection(diagram, sourceShape, targetShape, {id: link.id});\n\n\t }\n\t if (doLayout) {\n\t var l = new diagram.SpringLayout(diagram);\n\t l.layoutGraph(graph, {limitToView: false});\n\t for (var shi = 0; shi < graph.nodes.length; shi++) {\n\t node = graph.nodes[shi];\n\t shape = map[node.id];\n\t shape.bounds(new Rect(node.x, node.y, node.width, node.height));\n\t }\n\t }\n\t },\n\n\t /**\n\t * Creates a balanced tree with the specified number of levels and siblings count.\n\t * Note that for a balanced tree of level N and sibling count s, counting the root as level zero:\n\t * - NodeCount = (1-s^(N+1))/(1-s)]\n\t * - LinkCount = s.(1-s^N)/(1-s)\n\t * @param levels How many levels the tree should have.\n\t * @param siblingsCount How many siblings each level should have.\n\t * @returns {diagram.Graph}\n\t */\n\t createBalancedTree: function (levels, siblingsCount) {\n\t if (Utils.isUndefined(levels)) {\n\t levels = 3;\n\t }\n\t if (Utils.isUndefined(siblingsCount)) {\n\t siblingsCount = 3;\n\t }\n\n\t var g = new diagram.Graph(), counter = -1, lastAdded = [], news;\n\t if (levels <= 0 || siblingsCount <= 0) {\n\t return g;\n\t }\n\t var root = new Node((++counter).toString());\n\t g.addNode(root);\n\t g.root = root;\n\t lastAdded.push(root);\n\t for (var i = 0; i < levels; i++) {\n\t news = [];\n\t for (var j = 0; j < lastAdded.length; j++) {\n\t var parent = lastAdded[j];\n\t for (var k = 0; k < siblingsCount; k++) {\n\t var item = new Node((++counter).toString());\n\t g.addLink(parent, item);\n\t news.push(item);\n\t }\n\t }\n\t lastAdded = news;\n\t }\n\t return g;\n\t },\n\n\t /**\n\t * Creates a balanced tree with the specified number of levels and siblings count.\n\t * Note that for a balanced forest of level N, sibling count s and tree count t, counting the root as level zero:\n\t * - NodeCount = t.(1-s^(N+1))/(1-s)]\n\t * - LinkCount = t.s.(1-s^N)/(1-s)\n\t * @param levels How many levels the tree should have.\n\t * @param siblingsCount How many siblings each level should have.\n\t * @returns {diagram.Graph}\n\t * @param treeCount The number of trees the forest should have.\n\t */\n\t createBalancedForest: function (levels, siblingsCount, treeCount) {\n\t if (Utils.isUndefined(levels)) {\n\t levels = 3;\n\t }\n\t if (Utils.isUndefined(siblingsCount)) {\n\t siblingsCount = 3;\n\t }\n\t if (Utils.isUndefined(treeCount)) {\n\t treeCount = 5;\n\t }\n\t var g = new diagram.Graph(), counter = -1, lastAdded = [], news;\n\t if (levels <= 0 || siblingsCount <= 0 || treeCount <= 0) {\n\t return g;\n\t }\n\n\t for (var t = 0; t < treeCount; t++) {\n\t var root = new Node((++counter).toString());\n\t g.addNode(root);\n\t lastAdded = [root];\n\t for (var i = 0; i < levels; i++) {\n\t news = [];\n\t for (var j = 0; j < lastAdded.length; j++) {\n\t var parent = lastAdded[j];\n\t for (var k = 0; k < siblingsCount; k++) {\n\t var item = new Node((++counter).toString());\n\t g.addLink(parent, item);\n\t news.push(item);\n\t }\n\t }\n\t lastAdded = news;\n\t }\n\t }\n\t return g;\n\t },\n\n\t /**\n\t * Creates a random graph (uniform distribution) with the specified amount of nodes.\n\t * @param nodeCount The amount of nodes the random graph should have.\n\t * @param maxIncidence The maximum allowed degree of the nodes.\n\t * @param isTree Whether the return graph should be a tree (default: false).\n\t * @returns {diagram.Graph}\n\t */\n\t createRandomConnectedGraph: function (nodeCount, maxIncidence, isTree) {\n\n\t /* Swa's Mathematica export of random Bernoulli graphs\n\t gr[n_,p_]:=Module[{g=RandomGraph[BernoulliGraphDistribution[n,p],VertexLabels->\"Name\",DirectedEdges->True]},\n\t While[Not[ConnectedGraphQ[g]],g=RandomGraph[BernoulliGraphDistribution[n,p],VertexLabels->\"Name\",DirectedEdges->True]];g];\n\t project[a_]:=(\"\\\"\"<>ToString[Part[#,1]]<>\"->\"<>ToString[Part[#,2]]<>\"\\\"\")& @ a;\n\t export[g_]:=project/@ EdgeList[g]\n\t g = gr[12,.1]\n\t export [g]\n\t */\n\n\t if (Utils.isUndefined(nodeCount)) {\n\t nodeCount = 40;\n\t }\n\t if (Utils.isUndefined(maxIncidence)) {\n\t maxIncidence = 4;\n\t }\n\t if (Utils.isUndefined(isTree)) {\n\t isTree = false;\n\t }\n\n\t var g = new diagram.Graph(), counter = -1;\n\t if (nodeCount <= 0) {\n\t return g;\n\t }\n\n\t var root = new Node((++counter).toString());\n\t g.addNode(root);\n\t if (nodeCount === 1) {\n\t return g;\n\t }\n\t if (nodeCount > 1) {\n\t // random tree\n\t for (var i = 1; i < nodeCount; i++) {\n\t var poolNode = g.takeRandomNode([], maxIncidence);\n\t if (!poolNode) {\n\t //failed to find one so the graph will have less nodes than specified\n\t break;\n\t }\n\t var newNode = g.addNode(i.toString());\n\t g.addLink(poolNode, newNode);\n\t }\n\t if (!isTree && nodeCount > 1) {\n\t var randomAdditions = Utils.randomInteger(1, nodeCount);\n\t for (var ri = 0; ri < randomAdditions; ri++) {\n\t var n1 = g.takeRandomNode([], maxIncidence);\n\t var n2 = g.takeRandomNode([], maxIncidence);\n\t if (n1 && n2 && !g.areConnected(n1, n2)) {\n\t g.addLink(n1, n2);\n\t }\n\t }\n\t }\n\t return g;\n\t }\n\t },\n\n\t /**\n\t * Generates a random diagram.\n\t * @param diagram The host diagram.\n\t * @param shapeCount The number of shapes the random diagram should contain.\n\t * @param maxIncidence The maximum degree the shapes can have.\n\t * @param isTree Whether the generated diagram should be a tree\n\t * @param layoutType The optional layout type to apply after the diagram is generated.\n\t */\n\t randomDiagram: function (diagram, shapeCount, maxIncidence, isTree, randomSize) {\n\t var g = kendo.dataviz.diagram.Graph.Utils.createRandomConnectedGraph(shapeCount, maxIncidence, isTree);\n\t Graph.Utils.createDiagramFromGraph(diagram, g, false, randomSize);\n\t }\n\t };\n\n\t kendo.deepExtend(diagram, {\n\t init: function (element) {\n\t kendo.init(element, diagram.ui);\n\t },\n\n\t Point: Point,\n\t Intersect: Intersect,\n\t Geometry: Geometry,\n\t Rect: Rect,\n\t Size: Size,\n\t RectAlign: RectAlign,\n\t Matrix: Matrix,\n\t MatrixVector: MatrixVector,\n\t normalVariable: normalVariable,\n\t randomId: randomId,\n\t Dictionary: Dictionary,\n\t HashTable: HashTable,\n\t Queue: Queue,\n\t Set: Set,\n\t Node: Node,\n\t Link: Link,\n\t Graph: Graph,\n\t PathDefiner: PathDefiner\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 880:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./utils\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(881);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 860:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.drawing\");\n\n/***/ }),\n\n/***/ 874:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./svg\");\n\n/***/ }),\n\n/***/ 881:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (f, define) {\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(860), __webpack_require__(874) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function () {\n\n\t (function ($, undefined) {\n\t // Imports ================================================================\n\t var kendo = window.kendo,\n\t dataviz = kendo.dataviz,\n\t diagram = dataviz.diagram,\n\t Class = kendo.Class,\n\t Group = diagram.Group,\n\t Rect = diagram.Rect,\n\t Rectangle = diagram.Rectangle,\n\t Utils = diagram.Utils,\n\t isUndefined = Utils.isUndefined,\n\t Point = diagram.Point,\n\t Circle = diagram.Circle,\n\t Ticker = diagram.Ticker,\n\t deepExtend = kendo.deepExtend,\n\t Movable = kendo.ui.Movable,\n\t browser = kendo.support.browser,\n\t util = kendo.drawing.util,\n\t defined = util.defined,\n\t inArray = $.inArray,\n\t proxy = $.proxy;\n\n\t // Constants ==============================================================\n\t var Cursors = {\n\t arrow: \"default\",\n\t grip: \"pointer\",\n\t cross: \"pointer\",\n\t add: \"pointer\",\n\t move: \"move\",\n\t select: \"pointer\",\n\t south: \"s-resize\",\n\t east: \"e-resize\",\n\t west: \"w-resize\",\n\t north: \"n-resize\",\n\t rowresize: \"row-resize\",\n\t colresize: \"col-resize\"\n\t },\n\t HIT_TEST_DISTANCE = 10,\n\t AUTO = \"Auto\",\n\t TOP = \"Top\",\n\t RIGHT = \"Right\",\n\t LEFT = \"Left\",\n\t BOTTOM = \"Bottom\",\n\t DEFAULT_SNAP_SIZE = 10,\n\t DEFAULT_SNAP_ANGLE = 10,\n\t DRAG_START = \"dragStart\",\n\t DRAG = \"drag\",\n\t DRAG_END = \"dragEnd\",\n\t ITEMROTATE = \"itemRotate\",\n\t ITEMBOUNDSCHANGE = \"itemBoundsChange\",\n\t MIN_SNAP_SIZE = 5,\n\t MIN_SNAP_ANGLE = 5,\n\t MOUSE_ENTER = \"mouseEnter\",\n\t MOUSE_LEAVE = \"mouseLeave\",\n\t ZOOM_START = \"zoomStart\",\n\t ZOOM_END = \"zoomEnd\",\n\t SCROLL_MIN = -20000,\n\t SCROLL_MAX = 20000,\n\t FRICTION = 0.90,\n\t FRICTION_MOBILE = 0.93,\n\t VELOCITY_MULTIPLIER = 5,\n\t TRANSPARENT = \"transparent\",\n\t PAN = \"pan\",\n\t ROTATED = \"rotated\",\n\t SOURCE = \"source\",\n\t TARGET = \"target\",\n\t HANDLE_NAMES = {\n\t \"-1\": SOURCE,\n\t \"1\": TARGET\n\t };\n\n\t diagram.Cursors = Cursors;\n\n\t var PositionAdapter = kendo.Class.extend({\n\t init: function (layoutState) {\n\t this.layoutState = layoutState;\n\t this.diagram = layoutState.diagram;\n\t },\n\t initState: function () {\n\t this.froms = [];\n\t this.tos = [];\n\t this.subjects = [];\n\t function pusher(id, bounds) {\n\t var shape = this.diagram.getShapeById(id);\n\t if (shape) {\n\t this.subjects.push(shape);\n\t this.froms.push(shape.bounds().topLeft());\n\t this.tos.push(bounds.topLeft());\n\t }\n\t }\n\n\t this.layoutState.nodeMap.forEach(pusher, this);\n\t },\n\t update: function (tick) {\n\t if (this.subjects.length <= 0) {\n\t return;\n\t }\n\t for (var i = 0; i < this.subjects.length; i++) {\n\t //todo: define a Lerp function instead\n\t this.subjects[i].position(\n\t new Point(this.froms[i].x + (this.tos[i].x - this.froms[i].x) * tick, this.froms[i].y + (this.tos[i].y - this.froms[i].y) * tick)\n\t );\n\t }\n\t }\n\t });\n\n\t var LayoutUndoUnit = Class.extend({\n\t init: function (initialState, finalState, animate) {\n\t if (isUndefined(animate)) {\n\t this.animate = false;\n\t }\n\t else {\n\t this.animate = animate;\n\t }\n\t this._initialState = initialState;\n\t this._finalState = finalState;\n\t this.title = \"Diagram layout\";\n\t },\n\t undo: function () {\n\t this.setState(this._initialState);\n\t },\n\t redo: function () {\n\t this.setState(this._finalState);\n\t },\n\t setState: function (state) {\n\t var diagram = state.diagram;\n\t if (this.animate) {\n\t state.linkMap.forEach(\n\t function (id, points) {\n\t var conn = diagram.getShapeById(id);\n\t conn.visible(false);\n\t if (conn) {\n\t conn.points(points);\n\t }\n\t }\n\t );\n\t var ticker = new Ticker();\n\t ticker.addAdapter(new PositionAdapter(state));\n\t ticker.onComplete(function () {\n\t state.linkMap.forEach(\n\t function (id) {\n\t var conn = diagram.getShapeById(id);\n\t conn.visible(true);\n\t }\n\t );\n\t });\n\t ticker.play();\n\t }\n\t else {\n\t state.nodeMap.forEach(function (id, bounds) {\n\t var shape = diagram.getShapeById(id);\n\t if (shape) {\n\t shape.position(bounds.topLeft());\n\t }\n\t });\n\t state.linkMap.forEach(\n\t function (id, points) {\n\t var conn = diagram.getShapeById(id);\n\t if (conn) {\n\t conn.points(points);\n\t }\n\t }\n\t );\n\t }\n\t }\n\t });\n\n\t var CompositeUnit = Class.extend({\n\t init: function (unit) {\n\t this.units = [];\n\t this.title = \"Composite unit\";\n\t if (unit !== undefined) {\n\t this.units.push(unit);\n\t }\n\t },\n\t add: function (undoUnit) {\n\t this.units.push(undoUnit);\n\t },\n\t undo: function () {\n\t for (var i = 0; i < this.units.length; i++) {\n\t this.units[i].undo();\n\t }\n\t },\n\t redo: function () {\n\t for (var i = 0; i < this.units.length; i++) {\n\t this.units[i].redo();\n\t }\n\t }\n\t });\n\n\t var ConnectionEditUnit = Class.extend({\n\t init: function (item, redoSource, redoTarget) {\n\t this.item = item;\n\t this._redoSource = redoSource;\n\t this._redoTarget = redoTarget;\n\t if (defined(redoSource)) {\n\t this._undoSource = item.source();\n\t }\n\n\t if (defined(redoTarget)) {\n\t this._undoTarget = item.target();\n\t }\n\t this.title = \"Connection Editing\";\n\t },\n\t undo: function () {\n\t if (this._undoSource !== undefined) {\n\t this.item._updateConnector(this._undoSource, \"source\");\n\t }\n\n\t if (this._undoTarget !== undefined) {\n\t this.item._updateConnector(this._undoTarget, \"target\");\n\t }\n\n\t this.item.updateModel();\n\t },\n\t redo: function () {\n\t if (this._redoSource !== undefined) {\n\t this.item._updateConnector(this._redoSource, \"source\");\n\t }\n\n\t if (this._redoTarget !== undefined) {\n\t this.item._updateConnector(this._redoTarget, \"target\");\n\t }\n\n\t this.item.updateModel();\n\t }\n\t });\n\n\t var ConnectionEditUndoUnit = Class.extend({\n\t init: function (item, undoSource, undoTarget) {\n\t this.item = item;\n\t this._undoSource = undoSource;\n\t this._undoTarget = undoTarget;\n\t this._redoSource = item.source();\n\t this._redoTarget = item.target();\n\t this.title = \"Connection Editing\";\n\t },\n\t undo: function () {\n\t this.item._updateConnector(this._undoSource, \"source\");\n\t this.item._updateConnector(this._undoTarget, \"target\");\n\t this.item.updateModel();\n\t },\n\t redo: function () {\n\t this.item._updateConnector(this._redoSource, \"source\");\n\t this.item._updateConnector(this._redoTarget, \"target\");\n\t this.item.updateModel();\n\t }\n\t });\n\n\t var DeleteConnectionUnit = Class.extend({\n\t init: function (connection) {\n\t this.connection = connection;\n\t this.diagram = connection.diagram;\n\t this.targetConnector = connection.targetConnector;\n\t this.title = \"Delete connection\";\n\t },\n\t undo: function () {\n\t this.diagram._addConnection(this.connection, false);\n\t },\n\t redo: function () {\n\t this.diagram.remove(this.connection, false);\n\t }\n\t });\n\n\t var DeleteShapeUnit = Class.extend({\n\t init: function (shape) {\n\t this.shape = shape;\n\t this.diagram = shape.diagram;\n\t this.title = \"Deletion\";\n\t },\n\t undo: function () {\n\t this.diagram._addShape(this.shape, false);\n\t this.shape.select(false);\n\t },\n\t redo: function () {\n\t this.shape.select(false);\n\t this.diagram.remove(this.shape, false);\n\t }\n\t });\n\t /**\n\t * Holds the undoredo state when performing a rotation, translation or scaling. The adorner is optional.\n\t * @type {*}\n\t */\n\t var TransformUnit = Class.extend({\n\t init: function (shapes, undoStates, adorner) {\n\t this.shapes = shapes;\n\t this.undoStates = undoStates;\n\t this.title = \"Transformation\";\n\t this.redoStates = [];\n\t this.adorner = adorner;\n\t for (var i = 0; i < this.shapes.length; i++) {\n\t var shape = this.shapes[i];\n\t this.redoStates.push(shape.bounds());\n\t }\n\t },\n\t undo: function () {\n\t for (var i = 0; i < this.shapes.length; i++) {\n\t var shape = this.shapes[i];\n\t shape.bounds(this.undoStates[i]);\n\t if (shape.hasOwnProperty(\"layout\")) {\n\t shape.layout(shape, this.redoStates[i], this.undoStates[i]);\n\t }\n\t shape.updateModel();\n\t }\n\t if (this.adorner) {\n\t this.adorner.refreshBounds();\n\t this.adorner.refresh();\n\t }\n\t },\n\t redo: function () {\n\t for (var i = 0; i < this.shapes.length; i++) {\n\t var shape = this.shapes[i];\n\t shape.bounds(this.redoStates[i]);\n\t // the 'layout' property, if implemented, lets the shape itself work out what to do with the new bounds\n\t if (shape.hasOwnProperty(\"layout\")) {\n\t shape.layout(shape, this.undoStates[i], this.redoStates[i]);\n\t }\n\t shape.updateModel();\n\t }\n\n\t if (this.adorner) {\n\t this.adorner.refreshBounds();\n\t this.adorner.refresh();\n\t }\n\t }\n\t });\n\n\t var AddConnectionUnit = Class.extend({\n\t init: function (connection, diagram) {\n\t this.connection = connection;\n\t this.diagram = diagram;\n\t this.title = \"New connection\";\n\t },\n\n\t undo: function () {\n\t this.diagram.remove(this.connection, false);\n\t },\n\n\t redo: function () {\n\t this.diagram._addConnection(this.connection, false);\n\t }\n\t });\n\n\t var AddShapeUnit = Class.extend({\n\t init: function (shape, diagram) {\n\t this.shape = shape;\n\t this.diagram = diagram;\n\t this.title = \"New shape\";\n\t },\n\n\t undo: function () {\n\t this.diagram.deselect();\n\t this.diagram.remove(this.shape, false);\n\t },\n\n\t redo: function () {\n\t this.diagram._addShape(this.shape, false);\n\t }\n\t });\n\n\t var PanUndoUnit = Class.extend({\n\t init: function (initialPosition, finalPosition, diagram) {\n\t this.initial = initialPosition;\n\t this.finalPos = finalPosition;\n\t this.diagram = diagram;\n\t this.title = \"Pan Unit\";\n\t },\n\t undo: function () {\n\t this.diagram.pan(this.initial);\n\t },\n\t redo: function () {\n\t this.diagram.pan(this.finalPos);\n\t }\n\t });\n\n\t var RotateUnit = Class.extend({\n\t init: function (adorner, shapes, undoRotates) {\n\t this.shapes = shapes;\n\t this.undoRotates = undoRotates;\n\t this.title = \"Rotation\";\n\t this.redoRotates = [];\n\t this.redoAngle = adorner._angle;\n\t this.adorner = adorner;\n\t this.center = adorner._innerBounds.center();\n\t for (var i = 0; i < this.shapes.length; i++) {\n\t var shape = this.shapes[i];\n\t this.redoRotates.push(shape.rotate().angle);\n\t }\n\t },\n\t undo: function () {\n\t var i, shape;\n\t for (i = 0; i < this.shapes.length; i++) {\n\t shape = this.shapes[i];\n\t shape.rotate(this.undoRotates[i], this.center, false);\n\t if (shape.hasOwnProperty(\"layout\")) {\n\t shape.layout(shape);\n\t }\n\t shape.updateModel();\n\t }\n\t if (this.adorner) {\n\t this.adorner._initialize();\n\t this.adorner.refresh();\n\t }\n\t },\n\t redo: function () {\n\t var i, shape;\n\t for (i = 0; i < this.shapes.length; i++) {\n\t shape = this.shapes[i];\n\t shape.rotate(this.redoRotates[i], this.center, false);\n\t if (shape.hasOwnProperty(\"layout\")) {\n\t shape.layout(shape);\n\t }\n\t shape.updateModel();\n\t }\n\t if (this.adorner) {\n\t this.adorner._initialize();\n\t this.adorner.refresh();\n\t }\n\t }\n\t });\n\n\t var ToFrontUnit = Class.extend({\n\t init: function (diagram, items, initialIndices) {\n\t this.diagram = diagram;\n\t this.indices = initialIndices;\n\t this.items = items;\n\t this.title = \"Rotate Unit\";\n\t },\n\t undo: function () {\n\t this.diagram._toIndex(this.items, this.indices);\n\t },\n\t redo: function () {\n\t this.diagram.toFront(this.items, false);\n\t }\n\t });\n\n\t var ToBackUnit = Class.extend({\n\t init: function (diagram, items, initialIndices) {\n\t this.diagram = diagram;\n\t this.indices = initialIndices;\n\t this.items = items;\n\t this.title = \"Rotate Unit\";\n\t },\n\t undo: function () {\n\t this.diagram._toIndex(this.items, this.indices);\n\t },\n\t redo: function () {\n\t this.diagram.toBack(this.items, false);\n\t }\n\t });\n\n\t /**\n\t * Undo-redo service.\n\t */\n\t var UndoRedoService = kendo.Observable.extend({\n\t init: function (options) {\n\t kendo.Observable.fn.init.call(this, options);\n\t this.bind(this.events, options);\n\t this.stack = [];\n\t this.index = 0;\n\t this.capacity = 100;\n\t },\n\n\t events: [\"undone\", \"redone\"],\n\n\t /**\n\t * Starts the collection of units. Add those with\n\t * the addCompositeItem method and call commit. Or cancel to forget about it.\n\t */\n\t begin: function () {\n\t this.composite = new CompositeUnit();\n\t },\n\n\t /**\n\t * Cancels the collection process of unit started with 'begin'.\n\t */\n\t cancel: function () {\n\t this.composite = undefined;\n\t },\n\n\t /**\n\t * Commits a batch of units.\n\t */\n\t commit: function (execute) {\n\t if (this.composite.units.length > 0) {\n\t this._restart(this.composite, execute);\n\t }\n\t this.composite = undefined;\n\t },\n\n\t /**\n\t * Adds a unit as part of the begin-commit batch.\n\t * @param undoUnit\n\t */\n\t addCompositeItem: function (undoUnit) {\n\t if (this.composite) {\n\t this.composite.add(undoUnit);\n\t } else {\n\t this.add(undoUnit);\n\t }\n\t },\n\n\t /**\n\t * Standard addition of a unit. See also the batch version; begin-addCompositeUnit-commit methods.\n\t * @param undoUnit The unit to be added.\n\t * @param execute If false, the unit will be added but not executed.\n\t */\n\t add: function (undoUnit, execute) {\n\t this._restart(undoUnit, execute);\n\t },\n\n\t /**\n\t * Returns the number of undoable unit in the stack.\n\t * @returns {Number}\n\t */\n\n\t pop: function() {\n\t if (this.index > 0) {\n\t this.stack.pop();\n\t this.index--;\n\t }\n\t },\n\n\t count: function () {\n\t return this.stack.length;\n\t },\n\n\t /**\n\t * Rollback of the unit on top of the stack.\n\t */\n\t undo: function () {\n\t if (this.index > 0) {\n\t this.index--;\n\t this.stack[this.index].undo();\n\t this.trigger(\"undone\");\n\t }\n\t },\n\n\t /**\n\t * Redo of the last undone action.\n\t */\n\t redo: function () {\n\t if (this.stack.length > 0 && this.index < this.stack.length) {\n\t this.stack[this.index].redo();\n\t this.index++;\n\t this.trigger(\"redone\");\n\t }\n\t },\n\n\t _restart: function (composite, execute) {\n\t // throw away anything beyond this point if this is a new branch\n\t this.stack.splice(this.index, this.stack.length - this.index);\n\t this.stack.push(composite);\n\t if (execute !== false) {\n\t this.redo();\n\t } else {\n\t this.index++;\n\t }\n\t // check the capacity\n\t if (this.stack.length > this.capacity) {\n\t this.stack.splice(0, this.stack.length - this.capacity);\n\t this.index = this.capacity; //points to the end of the stack\n\t }\n\t },\n\n\t /**\n\t * Clears the stack.\n\t */\n\t clear: function () {\n\t this.stack = [];\n\t this.index = 0;\n\t }\n\t });\n\n\t// Tools =========================================\n\n\t var EmptyTool = Class.extend({\n\t init: function (toolService) {\n\t this.toolService = toolService;\n\t },\n\t start: function () {\n\t },\n\t move: function () {\n\t },\n\t end: function () {\n\t },\n\t tryActivate: function () {\n\t return false;\n\t },\n\t getCursor: function () {\n\t return Cursors.arrow;\n\t }\n\t });\n\n\t var ScrollerTool = EmptyTool.extend({\n\t init: function (toolService) {\n\t var tool = this;\n\t var friction = kendo.support.mobileOS ? FRICTION_MOBILE : FRICTION;\n\t EmptyTool.fn.init.call(tool, toolService);\n\n\t var diagram = tool.toolService.diagram,\n\t canvas = diagram.canvas;\n\n\t var scroller = diagram.scroller = tool.scroller = $(diagram.scrollable).kendoMobileScroller({\n\t friction: friction,\n\t velocityMultiplier: VELOCITY_MULTIPLIER,\n\t mousewheelScrolling: false,\n\t zoom: false,\n\t scroll: proxy(tool._move, tool)\n\t }).data(\"kendoMobileScroller\");\n\n\t if (canvas.translate) {\n\t tool.movableCanvas = new Movable(canvas.element);\n\t }\n\n\t var virtualScroll = function (dimension, min, max) {\n\t dimension.makeVirtual();\n\t dimension.virtualSize(min || SCROLL_MIN, max || SCROLL_MAX);\n\t };\n\n\t virtualScroll(scroller.dimensions.x);\n\t virtualScroll(scroller.dimensions.y);\n\t scroller.disable();\n\t },\n\n\t tryActivate: function (p, meta) {\n\t var toolService = this.toolService;\n\t var options = toolService.diagram.options.pannable;\n\t var enabled = meta.ctrlKey;\n\n\t if (defined(options.key)) {\n\t if (!options.key || options.key == \"none\") {\n\t enabled = noMeta(meta) && !defined(toolService.hoveredItem);\n\t } else {\n\t enabled = meta[options.key + \"Key\"];\n\t }\n\t }\n\n\t return options !== false && enabled && !defined(toolService.hoveredAdorner) && !defined(toolService._hoveredConnector);\n\t },\n\n\t start: function () {\n\t this.scroller.enable();\n\t },\n\t move: function () {\n\t },//the tool itself should not handle the scrolling. Let kendo scroller take care of this part. Check _move\n\t _move: function (args) {\n\t var tool = this,\n\t diagram = tool.toolService.diagram,\n\t canvas = diagram.canvas,\n\t scrollPos = new Point(args.scrollLeft, args.scrollTop);\n\n\t if (canvas.translate) {\n\t diagram._storePan(scrollPos.times(-1));\n\t tool.movableCanvas.moveTo(scrollPos);\n\t canvas.translate(scrollPos.x, scrollPos.y);\n\t } else {\n\t scrollPos = scrollPos.plus(diagram._pan.times(-1));\n\t }\n\n\t diagram.trigger(PAN, {pan: scrollPos});\n\t },\n\t end: function () {\n\t this.scroller.disable();\n\t },\n\t getCursor: function () {\n\t return Cursors.move;\n\t }\n\t });\n\n\t /**\n\t * The tool handling the transformations via the adorner.\n\t * @type {*}\n\t */\n\t var PointerTool = Class.extend({\n\t init: function (toolService) {\n\t this.toolService = toolService;\n\t },\n\t tryActivate: function () {\n\t return true; // the pointer tool is last and handles all others requests.\n\t },\n\t start: function (p, meta) {\n\t var toolService = this.toolService,\n\t diagram = toolService.diagram,\n\t hoveredItem = toolService.hoveredItem;\n\n\t if (hoveredItem) {\n\t toolService.selectSingle(hoveredItem, meta);\n\t if (hoveredItem.adorner) { //connection\n\t this.adorner = hoveredItem.adorner;\n\t this.handle = this.adorner._hitTest(p);\n\t }\n\t }\n\n\t if (!this.handle) {\n\t this.handle = diagram._resizingAdorner._hitTest(p);\n\t if (this.handle) {\n\t this.adorner = diagram._resizingAdorner;\n\t }\n\t }\n\n\t if (this.adorner) {\n\t if (!this.adorner.isDragHandle(this.handle) || !diagram.trigger(DRAG_START, { shapes: this.adorner.shapes, connections: [] })) {\n\t this.adorner.start(p);\n\t } else {\n\t toolService.startPoint = p;\n\t toolService.end(p);\n\t }\n\t }\n\t },\n\n\t move: function (p) {\n\t if (this.adorner) {\n\t this.adorner.move(this.handle, p);\n\t if (this.adorner.isDragHandle(this.handle)) {\n\t this.toolService.diagram.trigger(DRAG, { shapes: this.adorner.shapes, connections: [] });\n\t }\n\t }\n\t },\n\n\t end: function () {\n\t var diagram = this.toolService.diagram,\n\t adorner = this.adorner,\n\t unit;\n\n\t if (adorner) {\n\t if (!adorner.isDragHandle(this.handle) || !diagram.trigger(DRAG_END, { shapes: adorner.shapes, connections: [] })) {\n\t unit = adorner.stop();\n\t if (unit) {\n\t diagram.undoRedoService.add(unit, false);\n\t }\n\t } else {\n\t adorner.cancel();\n\t }\n\t }\n\n\t this.adorner = undefined;\n\t this.handle = undefined;\n\t },\n\t getCursor: function (p) {\n\t return this.toolService.hoveredItem ? this.toolService.hoveredItem._getCursor(p) : Cursors.arrow;\n\t }\n\t });\n\n\t var SelectionTool = Class.extend({\n\t init: function (toolService) {\n\t this.toolService = toolService;\n\t },\n\t tryActivate: function (p, meta) {\n\t var toolService = this.toolService;\n\t var selectable = toolService.diagram.options.selectable;\n\t var enabled = selectable && selectable.multiple !== false;\n\n\t if (enabled) {\n\t if (selectable.key && selectable.key != \"none\") {\n\t enabled = meta[selectable.key + \"Key\"];\n\t } else {\n\t enabled = noMeta(meta);\n\t }\n\t }\n\n\t return enabled && !defined(toolService.hoveredItem) && !defined(toolService.hoveredAdorner);\n\t },\n\t start: function (p) {\n\t var diagram = this.toolService.diagram;\n\t diagram.deselect();\n\t diagram.selector.start(p);\n\t },\n\t move: function (p) {\n\t var diagram = this.toolService.diagram;\n\t diagram.selector.move(p);\n\t },\n\t end: function (p, meta) {\n\t var diagram = this.toolService.diagram, hoveredItem = this.toolService.hoveredItem;\n\t var rect = diagram.selector.bounds();\n\t if ((!hoveredItem || !hoveredItem.isSelected) && !meta.ctrlKey) {\n\t diagram.deselect();\n\t }\n\t if (!rect.isEmpty()) {\n\t diagram.selectArea(rect);\n\t }\n\t diagram.selector.end();\n\t },\n\t getCursor: function () {\n\t return Cursors.arrow;\n\t }\n\t });\n\n\t var ConnectionTool = Class.extend({\n\t init: function (toolService) {\n\t this.toolService = toolService;\n\t this.type = \"ConnectionTool\";\n\t },\n\t tryActivate: function() {\n\t return this.toolService._hoveredConnector;\n\t },\n\t start: function (p, meta) {\n\t var toolService = this.toolService,\n\t diagram = toolService.diagram,\n\t connector = toolService._hoveredConnector,\n\t connection = diagram._createConnection({}, connector._c, p);\n\n\t if (canDrag(connection) && !diagram.trigger(DRAG_START, { shapes: [], connections: [connection], connectionHandle: TARGET }) && diagram._addConnection(connection)) {\n\t toolService._connectionManipulation(connection, connector._c.shape, true);\n\t toolService._removeHover();\n\t toolService.selectSingle(toolService.activeConnection, meta);\n\t if (meta.type == \"touchmove\") {\n\t diagram._cachedTouchTarget = connector.visual;\n\t }\n\t } else {\n\t connection.source(null);\n\t toolService.end(p);\n\t }\n\t },\n\n\t move: function (p) {\n\t var toolService = this.toolService;\n\t var connection = toolService.activeConnection;\n\n\t connection.target(p);\n\t toolService.diagram.trigger(DRAG, { shapes: [], connections: [connection], connectionHandle: TARGET });\n\t return true;\n\t },\n\n\t end: function (p) {\n\t var toolService = this.toolService,\n\t d = toolService.diagram,\n\t connection = toolService.activeConnection,\n\t hoveredItem = toolService.hoveredItem,\n\t connector = toolService._hoveredConnector,\n\t target,\n\t cachedTouchTarget = d._cachedTouchTarget;\n\n\t if (!connection) {\n\t return;\n\t }\n\n\t if (connector && connector._c != connection.sourceConnector) {\n\t target = connector._c;\n\t } else if (hoveredItem && hoveredItem instanceof diagram.Shape) {\n\t target = hoveredItem.getConnector(AUTO) || hoveredItem.getConnector(p);\n\t } else {\n\t target = p;\n\t }\n\n\t connection.target(target);\n\n\t if (!d.trigger(DRAG_END, { shapes: [], connections: [connection], connectionHandle: TARGET })) {\n\t connection.updateModel();\n\t d._syncConnectionChanges();\n\t } else {\n\t d.remove(connection, false);\n\t d.undoRedoService.pop();\n\t }\n\t toolService._connectionManipulation();\n\n\t if(cachedTouchTarget) {\n\t d._connectorsAdorner.visual.remove(cachedTouchTarget);\n\t d._cachedTouchTarget = null;\n\t }\n\t },\n\n\t getCursor: function () {\n\t return Cursors.arrow;\n\t }\n\t });\n\n\t var ConnectionEditTool = Class.extend({\n\t init: function (toolService) {\n\t this.toolService = toolService;\n\t this.type = \"ConnectionTool\";\n\t },\n\n\t tryActivate: function (p, meta) {\n\t var toolService = this.toolService,\n\t diagram = toolService.diagram,\n\t selectable = diagram.options.selectable,\n\t item = toolService.hoveredItem,\n\t isActive = selectable !== false &&\n\t item && item.path && !(item.isSelected && meta.ctrlKey);\n\n\t if (isActive) {\n\t this._c = item;\n\t }\n\n\t return isActive;\n\t },\n\n\t start: function (p, meta) {\n\t var toolService = this.toolService;\n\t var connection = this._c;\n\n\t toolService.selectSingle(connection, meta);\n\n\t var adorner = connection.adorner;\n\n\t var handle, name;\n\t if (adorner) {\n\t handle = adorner._hitTest(p);\n\t name = HANDLE_NAMES[handle];\n\t }\n\n\t if (canDrag(connection) && adorner && !toolService.diagram.trigger(DRAG_START, { shapes: [], connections: [connection], connectionHandle: name })) {\n\t this.handle = handle;\n\t this.handleName = name;\n\t adorner.start(p);\n\t } else {\n\t toolService.startPoint = p;\n\t toolService.end(p);\n\t }\n\t },\n\n\t move: function (p) {\n\t var adorner = this._c.adorner;\n\t if (canDrag(this._c) && adorner) {\n\t adorner.move(this.handle, p);\n\t this.toolService.diagram.trigger(DRAG, { shapes: [], connections: [this._c], connectionHandle: this.handleName });\n\n\t return true;\n\t }\n\t },\n\n\t end: function (p) {\n\t var connection = this._c;\n\t var adorner = connection.adorner;\n\t var toolService = this.toolService;\n\t var diagram = toolService.diagram;\n\n\t if (adorner) {\n\t if (canDrag(connection)) {\n\t var unit = adorner.stop(p);\n\t if (!diagram.trigger(DRAG_END, { shapes: [], connections: [connection], connectionHandle: this.handleName })) {\n\t diagram.undoRedoService.add(unit, false);\n\t connection.updateModel();\n\t diagram._syncConnectionChanges();\n\t } else {\n\t unit.undo();\n\t }\n\t }\n\t }\n\t },\n\n\t getCursor: function () {\n\t return Cursors.move;\n\t }\n\t });\n\n\t function testKey(key, str) {\n\t return str.charCodeAt(0) == key || str.toUpperCase().charCodeAt(0) == key;\n\t }\n\n\t /**\n\t * The service managing the tools.\n\t * @type {*}\n\t */\n\t var ToolService = Class.extend({\n\t init: function (diagram) {\n\t this.diagram = diagram;\n\t this.tools = [\n\t new ScrollerTool(this),\n\t new ConnectionEditTool(this),\n\t new ConnectionTool(this),\n\t new SelectionTool(this),\n\t new PointerTool(this)\n\t ]; // the order matters.\n\n\t this.activeTool = undefined;\n\t },\n\n\t start: function (p, meta) {\n\t meta = deepExtend({}, meta);\n\t if (this.activeTool) {\n\t this.activeTool.end(p, meta);\n\t }\n\t this._updateHoveredItem(p);\n\t this._activateTool(p, meta);\n\t this.activeTool.start(p, meta);\n\t this._updateCursor(p);\n\t this.diagram.focus();\n\t this.diagram.canvas.surface.suspendTracking();\n\t this.startPoint = p;\n\t return true;\n\t },\n\n\t move: function (p, meta) {\n\t meta = deepExtend({}, meta);\n\t var updateHovered = true;\n\t if (this.activeTool) {\n\t updateHovered = this.activeTool.move(p, meta);\n\t }\n\t if (updateHovered) {\n\t this._updateHoveredItem(p);\n\t }\n\t this._updateCursor(p);\n\t return true;\n\t },\n\n\t end: function (p, meta) {\n\t meta = deepExtend({}, meta);\n\t if (this.activeTool) {\n\t this.activeTool.end(p, meta);\n\t }\n\t this.diagram.canvas.surface.resumeTracking();\n\t this.activeTool = undefined;\n\t this._updateCursor(p);\n\t return true;\n\t },\n\n\t keyDown: function (key, meta) {\n\t var diagram = this.diagram;\n\t meta = deepExtend({ ctrlKey: false, metaKey: false, altKey: false }, meta);\n\t if ((meta.ctrlKey || meta.metaKey) && !meta.altKey) {// ctrl or option\n\t if (testKey(key, \"a\")) {// A: select all\n\t diagram.selectAll();\n\t diagram._destroyToolBar();\n\t return true;\n\t } else if (testKey(key, \"z\")) {// Z: undo\n\t diagram.undo();\n\t diagram._destroyToolBar();\n\t return true;\n\t } else if (testKey(key, \"y\")) {// y: redo\n\t diagram.redo();\n\t diagram._destroyToolBar();\n\t return true;\n\t } else if (testKey(key, \"c\")) {\n\t diagram.copy();\n\t diagram._destroyToolBar();\n\t } else if (testKey(key, \"x\")) {\n\t diagram.cut();\n\t diagram._destroyToolBar();\n\t } else if (testKey(key, \"v\")) {\n\t diagram.paste();\n\t diagram._destroyToolBar();\n\t } else if (testKey(key, \"l\")) {\n\t diagram.layout();\n\t diagram._destroyToolBar();\n\t } else if (testKey(key, \"d\")) {\n\t diagram._destroyToolBar();\n\t diagram.copy();\n\t diagram.paste();\n\t }\n\t } else if (key === 46 || key === 8) {// del: deletion\n\t var toRemove = this.diagram._triggerRemove(diagram.select());\n\t if (toRemove.length) {\n\t this.diagram.remove(toRemove, true);\n\t this.diagram._syncChanges();\n\t this.diagram._destroyToolBar();\n\t }\n\n\t return true;\n\t } else if (key === 27) {// ESC: stop any action\n\t this._discardNewConnection();\n\t diagram.deselect();\n\t diagram._destroyToolBar();\n\t return true;\n\t }\n\n\t },\n\t wheel: function (p, meta) {\n\t var diagram = this.diagram,\n\t delta = meta.delta,\n\t z = diagram.zoom(),\n\t options = diagram.options,\n\t zoomRate = options.zoomRate,\n\t zoomOptions = { point: p, meta: meta, zoom: z };\n\n\t if (diagram.trigger(ZOOM_START, zoomOptions)) {\n\t return;\n\t }\n\n\t if (delta < 0) {\n\t z += zoomRate;\n\t } else {\n\t z -= zoomRate;\n\t }\n\n\t z = kendo.dataviz.round(Math.max(options.zoomMin, Math.min(options.zoomMax, z)), 2);\n\t zoomOptions.zoom = z;\n\n\t diagram.zoom(z, zoomOptions);\n\t diagram.trigger(ZOOM_END, zoomOptions);\n\n\t return true;\n\t },\n\t setTool: function (tool, index) {\n\t tool.toolService = this;\n\t this.tools[index] = tool;\n\t },\n\n\t selectSingle: function(item, meta) {\n\t var diagram = this.diagram;\n\t var selectable = diagram.options.selectable;\n\t if (selectable && !item.isSelected && item.options.selectable !== false) {\n\t var addToSelection = meta.ctrlKey && selectable.multiple !== false;\n\t diagram.select(item, { addToSelection: addToSelection });\n\t }\n\t },\n\n\t _discardNewConnection: function () {\n\t if (this.newConnection) {\n\t this.diagram.remove(this.newConnection);\n\t this.newConnection = undefined;\n\t }\n\t },\n\t _activateTool: function (p, meta) {\n\t for (var i = 0; i < this.tools.length; i++) {\n\t var tool = this.tools[i];\n\t if (tool.tryActivate(p, meta)) {\n\t this.activeTool = tool;\n\t break; // activating the first available tool in the loop.\n\t }\n\t }\n\t },\n\t _updateCursor: function (p) {\n\t var element = this.diagram.element;\n\t var cursor = this.activeTool ? this.activeTool.getCursor(p) : (this.hoveredAdorner ? this.hoveredAdorner._getCursor(p) : (this.hoveredItem ? this.hoveredItem._getCursor(p) : Cursors.arrow));\n\n\t element.css({cursor: cursor});\n\t // workaround for IE 7 issue in which the elements overflow the container after setting cursor\n\t if (browser.msie && browser.version == 7) {\n\t element[0].style.cssText = element[0].style.cssText;\n\t }\n\t },\n\t _connectionManipulation: function (connection, disabledShape, isNew) {\n\t this.activeConnection = connection;\n\t this.disabledShape = disabledShape;\n\t if (isNew) {\n\t this.newConnection = this.activeConnection;\n\t } else {\n\t this.newConnection = undefined;\n\t }\n\t },\n\t _updateHoveredItem: function (p) {\n\t var hit = this._hitTest(p);\n\t var diagram = this.diagram;\n\n\t if (hit != this.hoveredItem && (!this.disabledShape || hit != this.disabledShape)) {\n\t if (this.hoveredItem) {\n\t diagram.trigger(MOUSE_LEAVE, { item: this.hoveredItem });\n\t this.hoveredItem._hover(false);\n\t }\n\n\t if (hit && hit.options.enable) {\n\t diagram.trigger(MOUSE_ENTER, { item: hit });\n\n\t this.hoveredItem = hit; // Shape, connection or connector\n\t this.hoveredItem._hover(true);\n\t } else {\n\t this.hoveredItem = undefined;\n\t }\n\t }\n\t },\n\t _removeHover: function () {\n\t if (this.hoveredItem) {\n\t this.hoveredItem._hover(false);\n\t this.hoveredItem = undefined;\n\t }\n\t },\n\t _hitTest: function (point) {\n\t var hit, d = this.diagram, item, i;\n\n\t // connectors\n\t if (this._hoveredConnector) {\n\t this._hoveredConnector._hover(false);\n\t this._hoveredConnector = undefined;\n\t }\n\t if (d._connectorsAdorner._visible) {\n\t hit = d._connectorsAdorner._hitTest(point);\n\t if (hit) {\n\t return hit;\n\t }\n\t }\n\n\t hit = this.diagram._resizingAdorner._hitTest(point);\n\t if (hit) {\n\t this.hoveredAdorner = d._resizingAdorner;\n\t if (hit.x !== 0 || hit.y !== 0) { // hit testing for resizers or rotator, otherwise if (0,0) than pass through.\n\t return;\n\t }\n\t hit = undefined;\n\t } else {\n\t this.hoveredAdorner = undefined;\n\t }\n\n\t if (!this.activeTool || this.activeTool.type !== \"ConnectionTool\") {\n\t var selectedConnections = []; // only the connections should have higher presence because the connection edit point is on top of connector.\n\t // TODO: This should be reworked. The connection adorner should be one for all selected connections and should be hit tested prior the connections and shapes itself.\n\t for (i = 0; i < d._selectedItems.length; i++) {\n\t item = d._selectedItems[i];\n\t if (item instanceof diagram.Connection) {\n\t selectedConnections.push(item);\n\t }\n\t }\n\t hit = this._hitTestItems(selectedConnections, point);\n\t }\n\n\t return hit || this._hitTestElements(point);\n\t },\n\n\t _hitTestElements: function(point) {\n\t var diagram = this.diagram;\n\t var shapeHit = this._hitTestItems(diagram.shapes, point);\n\t var connectionHit = this._hitTestItems(diagram.connections, point);\n\t var hit;\n\n\t if ((!this.activeTool || this.activeTool.type != \"ConnectionTool\") && shapeHit && connectionHit && !hitTestShapeConnectors(shapeHit, point)) {\n\t var mainLayer = diagram.mainLayer;\n\t var shapeIdx = inArray(shapeHit.visual, mainLayer.children);\n\t var connectionIdx = inArray(connectionHit.visual, mainLayer.children);\n\t hit = shapeIdx > connectionIdx ? shapeHit : connectionHit;\n\t }\n\t return hit || shapeHit || connectionHit;\n\t },\n\n\t _hitTestItems: function (array, point) {\n\t var i, item, hit;\n\t for (i = array.length - 1; i >= 0; i--) {\n\t item = array[i];\n\t hit = item._hitTest(point);\n\t if (hit) {\n\t return hit;\n\t }\n\t }\n\t }\n\t });\n\n\t// Routing =========================================\n\n\t /**\n\t * Base class for connection routers.\n\t */\n\t var ConnectionRouterBase = kendo.Class.extend({\n\t init: function () {\n\t }\n\t /*route: function (connection) {\n\t },\n\t hitTest: function (p) {\n\n\t },\n\t getBounds: function () {\n\n\t }*/\n\t });\n\n\t /**\n\t * Base class for polyline and cascading routing.\n\t */\n\t var LinearConnectionRouter = ConnectionRouterBase.extend({\n\t init: function (connection) {\n\t var that = this;\n\t ConnectionRouterBase.fn.init.call(that);\n\t this.connection = connection;\n\t },\n\t /**\n\t * Hit testing for polyline paths.\n\t */\n\t hitTest: function (p) {\n\t var rec = this.getBounds().inflate(HIT_TEST_DISTANCE);\n\t if (!rec.contains(p)) {\n\t return false;\n\t }\n\t return diagram.Geometry.distanceToPolyline(p, this.connection.allPoints()) < HIT_TEST_DISTANCE;\n\t },\n\n\t /**\n\t * Bounds of a polyline.\n\t * @returns {kendo.dataviz.diagram.Rect}\n\t */\n\t getBounds: function () {\n\t var points = this.connection.allPoints(),\n\t s = points[0],\n\t e = points[points.length - 1],\n\t right = Math.max(s.x, e.x),\n\t left = Math.min(s.x, e.x),\n\t top = Math.min(s.y, e.y),\n\t bottom = Math.max(s.y, e.y);\n\n\t for (var i = 1; i < points.length - 1; ++i) {\n\t right = Math.max(right, points[i].x);\n\t left = Math.min(left, points[i].x);\n\t top = Math.min(top, points[i].y);\n\t bottom = Math.max(bottom, points[i].y);\n\t }\n\n\t return new Rect(left, top, right - left, bottom - top);\n\t }\n\t });\n\n\t /**\n\t * A simple poly-linear routing which does not alter the intermediate points.\n\t * Does hold the underlying hit, bounds....logic.\n\t * @type {*|Object|void|extend|Zepto.extend|b.extend}\n\t */\n\t var PolylineRouter = LinearConnectionRouter.extend({\n\t init: function (connection) {\n\t var that = this;\n\t LinearConnectionRouter.fn.init.call(that);\n\t this.connection = connection;\n\t },\n\t route: function () {\n\t // just keep the points as is\n\t }\n\t });\n\n\t var CascadingRouter = LinearConnectionRouter.extend({\n\t SAME_SIDE_DISTANCE_RATIO: 5,\n\n\t init: function (connection) {\n\t var that = this;\n\t LinearConnectionRouter.fn.init.call(that);\n\t this.connection = connection;\n\t },\n\n\t routePoints: function(start, end, sourceConnector, targetConnector) {\n\t var result;\n\n\t if (sourceConnector && targetConnector) {\n\t result = this._connectorPoints(start, end, sourceConnector, targetConnector);\n\t } else {\n\t result = this._floatingPoints(start, end, sourceConnector);\n\t }\n\t return result;\n\t },\n\n\t route: function () {\n\t var sourceConnector = this.connection._resolvedSourceConnector;\n\t var targetConnector = this.connection._resolvedTargetConnector;\n\t var start = this.connection.sourcePoint();\n\t var end = this.connection.targetPoint();\n\t var points = this.routePoints(start, end, sourceConnector, targetConnector);\n\t this.connection.points(points);\n\t },\n\n\t _connectorSides: [{\n\t name: \"Top\",\n\t axis: \"y\",\n\t boundsPoint: \"topLeft\",\n\t secondarySign: 1\n\t }, {\n\t name: \"Left\",\n\t axis: \"x\",\n\t boundsPoint: \"topLeft\",\n\t secondarySign: 1\n\t }, {\n\t name: \"Bottom\",\n\t axis: \"y\",\n\t boundsPoint: \"bottomRight\",\n\t secondarySign: -1\n\t }, {\n\t name: \"Right\",\n\t axis: \"x\",\n\t boundsPoint: \"bottomRight\",\n\t secondarySign: -1\n\t }],\n\n\t _connectorSide: function(connector, targetPoint) {\n\t var position = connector.position();\n\t var shapeBounds = connector.shape.bounds(ROTATED);\n\t var bounds = {\n\t topLeft: shapeBounds.topLeft(),\n\t bottomRight: shapeBounds.bottomRight()\n\t };\n\t var sides = this._connectorSides;\n\t var min = util.MAX_NUM;\n\t var sideDistance;\n\t var minSide;\n\t var axis;\n\t var side;\n\t for (var idx = 0; idx < sides.length; idx++) {\n\t side = sides[idx];\n\t axis = side.axis;\n\t sideDistance = Math.round(Math.abs(position[axis] - bounds[side.boundsPoint][axis]));\n\t if (sideDistance < min) {\n\t min = sideDistance;\n\t minSide = side;\n\t } else if (sideDistance === min &&\n\t (position[axis] - targetPoint[axis]) * side.secondarySign > (position[minSide.axis] - targetPoint[minSide.axis]) * minSide.secondarySign) {\n\t minSide = side;\n\t }\n\t }\n\t return minSide.name;\n\t },\n\n\t _sameSideDistance: function(connector) {\n\t var bounds = connector.shape.bounds(ROTATED);\n\t return Math.min(bounds.width, bounds.height) / this.SAME_SIDE_DISTANCE_RATIO;\n\t },\n\n\t _connectorPoints: function(start, end, sourceConnector, targetConnector) {\n\t var sourceConnectorSide = this._connectorSide(sourceConnector, end);\n\t var targetConnectorSide = this._connectorSide(targetConnector, start);\n\t var deltaX = end.x - start.x;\n\t var deltaY = end.y - start.y;\n\t var sameSideDistance = this._sameSideDistance(sourceConnector);\n\t var result = [];\n\t var pointX, pointY;\n\n\t if (sourceConnectorSide === TOP || sourceConnectorSide == BOTTOM) {\n\t if (targetConnectorSide == TOP || targetConnectorSide == BOTTOM) {\n\t if (sourceConnectorSide == targetConnectorSide) {\n\t if (sourceConnectorSide == TOP) {\n\t pointY = Math.min(start.y, end.y) - sameSideDistance;\n\t } else {\n\t pointY = Math.max(start.y, end.y) + sameSideDistance;\n\t }\n\t result = [new Point(start.x, pointY), new Point(end.x, pointY)];\n\t } else {\n\t result = [new Point(start.x, start.y + deltaY / 2), new Point(end.x, start.y + deltaY / 2)];\n\t }\n\t } else {\n\t result = [new Point(start.x, end.y)];\n\t }\n\t } else {\n\t if (targetConnectorSide == LEFT || targetConnectorSide == RIGHT) {\n\t if (sourceConnectorSide == targetConnectorSide) {\n\t if (sourceConnectorSide == LEFT) {\n\t pointX = Math.min(start.x, end.x) - sameSideDistance;\n\t } else {\n\t pointX = Math.max(start.x, end.x) + sameSideDistance;\n\t }\n\t result = [new Point(pointX, start.y), new Point(pointX, end.y)];\n\t } else {\n\t result = [new Point(start.x + deltaX / 2, start.y), new Point(start.x + deltaX / 2, start.y + deltaY)];\n\t }\n\t } else {\n\t result = [new Point(end.x, start.y)];\n\t }\n\t }\n\t return result;\n\t },\n\n\t _floatingPoints: function(start, end, sourceConnector) {\n\t var sourceConnectorSide = sourceConnector ? this._connectorSide(sourceConnector, end) : null;\n\t var cascadeStartHorizontal = this._startHorizontal(start, end, sourceConnectorSide);\n\t var points = [start, start, end, end];\n\t var deltaX = end.x - start.x;\n\t var deltaY = end.y - start.y;\n\t var length = points.length;\n\t var shiftX;\n\t var shiftY;\n\n\t // note that this is more generic than needed for only two intermediate points.\n\t for (var idx = 1; idx < length - 1; ++idx) {\n\t if (cascadeStartHorizontal) {\n\t if (idx % 2 !== 0) {\n\t shiftX = deltaX / (length / 2);\n\t shiftY = 0;\n\t }\n\t else {\n\t shiftX = 0;\n\t shiftY = deltaY / ((length - 1) / 2);\n\t }\n\t }\n\t else {\n\t if (idx % 2 !== 0) {\n\t shiftX = 0;\n\t shiftY = deltaY / (length / 2);\n\t }\n\t else {\n\t shiftX = deltaX / ((length - 1) / 2);\n\t shiftY = 0;\n\t }\n\t }\n\t points[idx] = new Point(points[idx - 1].x + shiftX, points[idx - 1].y + shiftY);\n\t }\n\t // need to fix the wrong 1.5 factor of the last intermediate point\n\t idx--;\n\t if ((cascadeStartHorizontal && (idx % 2 !== 0)) || (!cascadeStartHorizontal && (idx % 2 === 0))) {\n\t points[length - 2] = new Point(points[length - 1].x, points[length - 2].y);\n\t } else {\n\t points[length - 2] = new Point(points[length - 2].x, points[length - 1].y);\n\t }\n\n\t return [points[1], points[2]];\n\t },\n\n\t _startHorizontal: function (start, end, sourceSide) {\n\t var horizontal;\n\t if (sourceSide !== null && (sourceSide === RIGHT || sourceSide === LEFT)) {\n\t horizontal = true;\n\t } else {\n\t horizontal = Math.abs(start.x - end.x) > Math.abs(start.y - end.y);\n\t }\n\n\t return horizontal;\n\t }\n\t });\n\n\t// Adorners =========================================\n\n\t var AdornerBase = Class.extend({\n\t init: function (diagram, options) {\n\t var that = this;\n\t that.diagram = diagram;\n\t that.options = deepExtend({}, that.options, options);\n\t that.visual = new Group();\n\t that.diagram._adorners.push(that);\n\t },\n\t refresh: function () {\n\n\t }\n\t });\n\n\t var ConnectionEditAdorner = AdornerBase.extend({\n\t init: function (connection, options) {\n\t var that = this, diagram;\n\t that.connection = connection;\n\t diagram = that.connection.diagram;\n\t that._ts = diagram.toolService;\n\t AdornerBase.fn.init.call(that, diagram, options);\n\t var sp = that.connection.sourcePoint();\n\t var tp = that.connection.targetPoint();\n\t that.spVisual = new Circle(deepExtend(that.options.handles, { center: sp }));\n\t that.epVisual = new Circle(deepExtend(that.options.handles, { center: tp }));\n\t that.visual.append(that.spVisual);\n\t that.visual.append(that.epVisual);\n\t },\n\n\t options: {\n\t handles: {}\n\t },\n\n\t _getCursor: function () {\n\t return Cursors.move;\n\t },\n\n\t start: function (p) {\n\t this.handle = this._hitTest(p);\n\t this.startPoint = p;\n\t this._initialSource = this.connection.source();\n\t this._initialTarget = this.connection.target();\n\t switch (this.handle) {\n\t case -1:\n\t if (this.connection.targetConnector) {\n\t this._ts._connectionManipulation(this.connection, this.connection.targetConnector.shape);\n\t }\n\t break;\n\t case 1:\n\t if (this.connection.sourceConnector) {\n\t this._ts._connectionManipulation(this.connection, this.connection.sourceConnector.shape);\n\t }\n\t break;\n\t }\n\t },\n\n\t move: function (handle, p) {\n\t switch (handle) {\n\t case -1:\n\t this.connection.source(p);\n\t break;\n\t case 1:\n\t this.connection.target(p);\n\t break;\n\t default:\n\t var delta = p.minus(this.startPoint);\n\t this.startPoint = p;\n\t if (!this.connection.sourceConnector) {\n\t this.connection.source(this.connection.sourcePoint().plus(delta));\n\t }\n\t if (!this.connection.targetConnector) {\n\t this.connection.target(this.connection.targetPoint().plus(delta));\n\t }\n\t break;\n\t }\n\t this.refresh();\n\t return true;\n\t },\n\n\t stop: function (p) {\n\t var ts = this.diagram.toolService, item = ts.hoveredItem, target;\n\t if (ts._hoveredConnector) {\n\t target = ts._hoveredConnector._c;\n\t } else if (item && item instanceof diagram.Shape) {\n\t target = item.getConnector(AUTO) || item.getConnector(p);\n\t } else {\n\t target = p;\n\t }\n\n\t if (this.handle === -1) {\n\t this.connection.source(target);\n\t } else if (this.handle === 1) {\n\t this.connection.target(target);\n\t }\n\n\t this.handle = undefined;\n\t this._ts._connectionManipulation();\n\t return new ConnectionEditUndoUnit(this.connection, this._initialSource, this._initialTarget);\n\t },\n\n\t _hitTest: function (point) {\n\t var sourcePoint = this.connection.sourcePoint();\n\t var targetPoint = this.connection.targetPoint();\n\t var radiusX = this.options.handles.width / 2 + HIT_TEST_DISTANCE;\n\t var radiusY = this.options.handles.height / 2 + HIT_TEST_DISTANCE;\n\t var sourcePointDistance = sourcePoint.distanceTo(point);\n\t var targetPointDistance = targetPoint.distanceTo(point);\n\t var sourceHandle = new Rect(sourcePoint.x, sourcePoint.y).inflate(radiusX, radiusY).contains(point);\n\t var targetHandle = new Rect(targetPoint.x, targetPoint.y).inflate(radiusX, radiusY).contains(point);\n\t var handle = 0;\n\n\t if (sourceHandle && (!targetHandle || sourcePointDistance < targetPointDistance)) {\n\t handle = -1;\n\t } else if (targetHandle && (!sourceHandle || targetPointDistance < sourcePointDistance)) {\n\t handle = 1;\n\t }\n\n\t return handle;\n\t },\n\n\t refresh: function () {\n\t this.spVisual.redraw({ center: this.diagram.modelToLayer(this.connection.sourcePoint()) });\n\t this.epVisual.redraw({ center: this.diagram.modelToLayer(this.connection.targetPoint()) });\n\t }\n\t });\n\n\t var ConnectorsAdorner = AdornerBase.extend({\n\t init: function (diagram, options) {\n\t var that = this;\n\t AdornerBase.fn.init.call(that, diagram, options);\n\t that._refreshHandler = function (e) {\n\t if (e.item == that.shape) {\n\t that.refresh();\n\t }\n\t };\n\t },\n\n\t show: function (shape) {\n\t var that = this, len, i, ctr;\n\t that._visible = true;\n\t that.shape = shape;\n\t that.diagram.bind(ITEMBOUNDSCHANGE, that._refreshHandler);\n\t len = shape.connectors.length;\n\t that.connectors = [];\n\t that._clearVisual();\n\t for (i = 0; i < len; i++) {\n\t ctr = new ConnectorVisual(shape.connectors[i]);\n\t that.connectors.push(ctr);\n\t that.visual.append(ctr.visual);\n\t }\n\t that.visual.visible(true);\n\t that.refresh();\n\t },\n\n\t _clearVisual: function() {\n\t var that = this;\n\t if(that.diagram._cachedTouchTarget) {\n\t that._keepCachedTouchTarget();\n\t } else {\n\t that.visual.clear();\n\t }\n\t },\n\n\t _keepCachedTouchTarget: function () {\n\t var that = this,\n\t visualChildren = that.visual.children;\n\t var childrenCount = visualChildren.length;\n\t var index = inArray(that.diagram._cachedTouchTarget, visualChildren);\n\t for (var i = childrenCount - 1; i >= 0; i--) {\n\t if(i == index) {\n\t continue;\n\t }\n\t that.visual.remove(visualChildren[i]);\n\t }\n\t },\n\n\t destroy: function () {\n\t var that = this;\n\t that.diagram.unbind(ITEMBOUNDSCHANGE, that._refreshHandler);\n\t that.shape = undefined;\n\t that._visible = undefined;\n\t that.visual.visible(false);\n\t },\n\n\t _hitTest: function (p) {\n\t var ctr, i;\n\t for (i = 0; i < this.connectors.length; i++) {\n\t ctr = this.connectors[i];\n\t if (ctr._hitTest(p)) {\n\t ctr._hover(true);\n\t this.diagram.toolService._hoveredConnector = ctr;\n\t break;\n\t }\n\t }\n\t },\n\n\t refresh: function () {\n\t if (this.shape) {\n\t var bounds = this.shape.bounds();\n\t bounds = this.diagram.modelToLayer(bounds);\n\t this.visual.position(bounds.topLeft());\n\t $.each(this.connectors, function () {\n\t this.refresh();\n\t });\n\t }\n\t }\n\t });\n\n\t function hitToOppositeSide(hit, bounds) {\n\t var result;\n\n\t if (hit.x == -1 && hit.y == -1) {\n\t result = bounds.bottomRight();\n\t } else if (hit.x == 1 && hit.y == 1) {\n\t result = bounds.topLeft();\n\t } else if (hit.x == -1 && hit.y == 1) {\n\t result = bounds.topRight();\n\t } else if (hit.x == 1 && hit.y == -1) {\n\t result = bounds.bottomLeft();\n\t } else if (hit.x === 0 && hit.y == -1) {\n\t result = bounds.bottom();\n\t } else if (hit.x === 0 && hit.y == 1) {\n\t result = bounds.top();\n\t } else if (hit.x == 1 && hit.y === 0) {\n\t result = bounds.left();\n\t } else if (hit.x == -1 && hit.y === 0) {\n\t result = bounds.right();\n\t }\n\n\t return result;\n\t }\n\n\t var ResizingAdorner = AdornerBase.extend({\n\t init: function (diagram, options) {\n\t var that = this;\n\t AdornerBase.fn.init.call(that, diagram, options);\n\t that._manipulating = false;\n\t that.map = [];\n\t that.shapes = [];\n\n\t that._initSelection();\n\t that._createHandles();\n\t that.redraw();\n\t that.diagram.bind(\"select\", function (e) {\n\t that._initialize(e.selected);\n\t });\n\n\t that._refreshHandler = function () {\n\t if (!that._internalChange) {\n\t that.refreshBounds();\n\t that.refresh();\n\t }\n\t };\n\n\t that._rotatedHandler = function () {\n\t if (that.shapes.length == 1) {\n\t that._angle = that.shapes[0].rotate().angle;\n\t }\n\t that._refreshHandler();\n\t };\n\n\t that.diagram.bind(ITEMBOUNDSCHANGE, that._refreshHandler).bind(ITEMROTATE, that._rotatedHandler);\n\t that.refreshBounds();\n\t that.refresh();\n\t },\n\n\t options: {\n\t handles: {\n\t fill: {\n\t color: \"#fff\"\n\t },\n\t stroke: {\n\t color: \"#282828\"\n\t },\n\t height: 7,\n\t width: 7,\n\t hover: {\n\t fill: {\n\t color: \"#282828\"\n\t },\n\t stroke: {\n\t color: \"#282828\"\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#778899\",\n\t width: 1,\n\t dashType: \"dash\"\n\t },\n\t fill: {\n\t color: TRANSPARENT\n\t }\n\t },\n\t offset: 10\n\t },\n\n\t _initSelection: function() {\n\t var that = this;\n\t var diagram = that.diagram;\n\t var selectable = diagram.options.selectable;\n\t var options = deepExtend({}, that.options.selectable, selectable);\n\t that.rect = new Rectangle(options);\n\t that.visual.append(that.rect);\n\t },\n\n\t _resizable: function() {\n\t return this.options.editable && this.options.editable.resize !== false;\n\t },\n\n\t _handleOptions: function() {\n\t return (this.options.editable.resize || {}).handles || this.options.handles;\n\t },\n\n\t _createHandles: function() {\n\t var handles, item, y, x;\n\n\t if (this._resizable()) {\n\t handles = this._handleOptions();\n\t for (x = -1; x <= 1; x++) {\n\t for (y = -1; y <= 1; y++) {\n\t if ((x !== 0) || (y !== 0)) { // (0, 0) element, (-1, -1) top-left, (+1, +1) bottom-right\n\t item = new Rectangle(handles);\n\t item.drawingElement._hover = proxy(this._hover, this);\n\t this.map.push({ x: x, y: y, visual: item });\n\t this.visual.append(item);\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t bounds: function (value) {\n\t if (value) {\n\t this._innerBounds = value.clone();\n\t this._bounds = this.diagram.modelToLayer(value).inflate(this.options.offset, this.options.offset);\n\t } else {\n\t return this._bounds;\n\t }\n\t },\n\n\t _hitTest: function (p) {\n\t var tp = this.diagram.modelToLayer(p),\n\t i, hit, handleBounds, handlesCount = this.map.length, handle;\n\n\t if (this._angle) {\n\t tp = tp.clone().rotate(this._bounds.center(), this._angle);\n\t }\n\n\t if (this._resizable()) {\n\t for (i = 0; i < handlesCount; i++) {\n\t handle = this.map[i];\n\t hit = new Point(handle.x, handle.y);\n\t handleBounds = this._getHandleBounds(hit); //local coordinates\n\t handleBounds.offset(this._bounds.x, this._bounds.y);\n\t if (handleBounds.contains(tp)) {\n\t return hit;\n\t }\n\t }\n\t }\n\n\t if (this._bounds.contains(tp)) {\n\t return new Point(0, 0);\n\t }\n\t },\n\n\t _getHandleBounds: function (p) {\n\t if (this._resizable()) {\n\t var handles = this._handleOptions(),\n\t w = handles.width,\n\t h = handles.height,\n\t r = new Rect(0, 0, w, h);\n\n\t if (p.x < 0) {\n\t r.x = - w / 2;\n\t } else if (p.x === 0) {\n\t r.x = Math.floor(this._bounds.width / 2) - w / 2;\n\t } else if (p.x > 0) {\n\t r.x = this._bounds.width + 1.0 - w / 2;\n\t } if (p.y < 0) {\n\t r.y = - h / 2;\n\t } else if (p.y === 0) {\n\t r.y = Math.floor(this._bounds.height / 2) - h / 2;\n\t } else if (p.y > 0) {\n\t r.y = this._bounds.height + 1.0 - h / 2;\n\t }\n\n\t return r;\n\t }\n\t },\n\n\t _getCursor: function (point) {\n\t var hit = this._hitTest(point);\n\t if (hit && (hit.x >= -1) && (hit.x <= 1) && (hit.y >= -1) && (hit.y <= 1) && this._resizable()) {\n\t var angle = this._angle;\n\t if (angle) {\n\t angle = 360 - angle;\n\t hit.rotate(new Point(0, 0), angle);\n\t hit = new Point(Math.round(hit.x), Math.round(hit.y));\n\t }\n\n\t if (hit.x == -1 && hit.y == -1) {\n\t return \"nw-resize\";\n\t }\n\t if (hit.x == 1 && hit.y == 1) {\n\t return \"se-resize\";\n\t }\n\t if (hit.x == -1 && hit.y == 1) {\n\t return \"sw-resize\";\n\t }\n\t if (hit.x == 1 && hit.y == -1) {\n\t return \"ne-resize\";\n\t }\n\t if (hit.x === 0 && hit.y == -1) {\n\t return \"n-resize\";\n\t }\n\t if (hit.x === 0 && hit.y == 1) {\n\t return \"s-resize\";\n\t }\n\t if (hit.x == 1 && hit.y === 0) {\n\t return \"e-resize\";\n\t }\n\t if (hit.x == -1 && hit.y === 0) {\n\t return \"w-resize\";\n\t }\n\t }\n\t return this._manipulating ? Cursors.move : Cursors.select;\n\t },\n\n\t _initialize: function() {\n\t var that = this, i, item,\n\t items = that.diagram.select();\n\n\t that.shapes = [];\n\t for (i = 0; i < items.length; i++) {\n\t item = items[i];\n\t if (item instanceof diagram.Shape) {\n\t that.shapes.push(item);\n\t item._rotationOffset = new Point();\n\t }\n\t }\n\n\t that._angle = that.shapes.length == 1 ? that.shapes[0].rotate().angle : 0;\n\t that._startAngle = that._angle;\n\t that._rotates();\n\t that._positions();\n\t that.refreshBounds();\n\t that.refresh();\n\t that.redraw();\n\t },\n\n\t _rotates: function () {\n\t var that = this, i, shape;\n\t that.initialRotates = [];\n\t for (i = 0; i < that.shapes.length; i++) {\n\t shape = that.shapes[i];\n\t that.initialRotates.push(shape.rotate().angle);\n\t }\n\t },\n\n\t _positions: function () {\n\t var that = this, i, shape;\n\t that.initialStates = [];\n\t for (i = 0; i < that.shapes.length; i++) {\n\t shape = that.shapes[i];\n\t that.initialStates.push(shape.bounds());\n\t }\n\t },\n\n\t _hover: function(value, element) {\n\t if (this._resizable()) {\n\t var handleOptions = this._handleOptions(),\n\t hover = handleOptions.hover,\n\t stroke = handleOptions.stroke,\n\t fill = handleOptions.fill;\n\n\t if (value && Utils.isDefined(hover.stroke)) {\n\t stroke = deepExtend({}, stroke, hover.stroke);\n\t }\n\n\t if (value && Utils.isDefined(hover.fill)) {\n\t fill = hover.fill;\n\t }\n\t element.stroke(stroke.color, stroke.width, stroke.opacity);\n\t element.fill(fill.color, fill.opacity);\n\t }\n\t },\n\n\t start: function (p) {\n\t this._sp = p;\n\t this._cp = p;\n\t this._lp = p;\n\t this._manipulating = true;\n\t this._internalChange = true;\n\t this.shapeStates = [];\n\t for (var i = 0; i < this.shapes.length; i++) {\n\t var shape = this.shapes[i];\n\t this.shapeStates.push(shape.bounds());\n\t }\n\t },\n\n\t redraw: function () {\n\t var i, handle,\n\t visibleHandles = this._resizable();\n\n\t for (i = 0; i < this.map.length; i++) {\n\t handle = this.map[i];\n\t handle.visual.visible(visibleHandles);\n\t }\n\t },\n\n\t angle: function(value) {\n\t if (defined(value)) {\n\t this._angle = value;\n\t }\n\n\t return this._angle;\n\t },\n\n\t rotate: function() {\n\t var center = this._innerBounds.center();\n\t var currentAngle = this.angle();\n\t this._internalChange = true;\n\t for (var i = 0; i < this.shapes.length; i++) {\n\t var shape = this.shapes[i];\n\t currentAngle = (currentAngle + this.initialRotates[i] - this._startAngle) % 360;\n\t shape.rotate(currentAngle, center);\n\t }\n\t this.refresh();\n\t },\n\n\t move: function (handle, p) {\n\t var delta, dragging,\n\t dtl = new Point(),\n\t dbr = new Point(),\n\t bounds, center, shape,\n\t i, angle, newBounds,\n\t changed = 0, staticPoint,\n\t scaleX, scaleY;\n\n\t if (handle.y === -2 && handle.x === -1) {\n\t center = this._innerBounds.center();\n\t this._angle = this._truncateAngle(Utils.findAngle(center, p));\n\t for (i = 0; i < this.shapes.length; i++) {\n\t shape = this.shapes[i];\n\t angle = (this._angle + this.initialRotates[i] - this._startAngle) % 360;\n\t shape.rotate(angle, center);\n\t if (shape.hasOwnProperty(\"layout\")) {\n\t shape.layout(shape);\n\t }\n\t this._rotating = true;\n\t }\n\t this.refresh();\n\t } else {\n\t if (this.shouldSnap()) {\n\t var thr = this._truncateDistance(p.minus(this._lp));\n\t // threshold\n\t if (thr.x === 0 && thr.y === 0) {\n\t this._cp = p;\n\t return;\n\t }\n\t delta = thr;\n\t this._lp = new Point(this._lp.x + thr.x, this._lp.y + thr.y);\n\t } else {\n\t delta = p.minus(this._cp);\n\t }\n\n\t if (this.isDragHandle(handle)) {\n\t dbr = dtl = delta; // dragging\n\t dragging = true;\n\t } else {\n\t if (this._angle) { // adjust the delta so that resizers resize in the correct direction after rotation.\n\t delta.rotate(new Point(0, 0), this._angle);\n\t }\n\t if (handle.x == -1) {\n\t dtl.x = delta.x;\n\t } else if (handle.x == 1) {\n\t dbr.x = delta.x;\n\t }\n\t if (handle.y == -1) {\n\t dtl.y = delta.y;\n\t } else if (handle.y == 1) {\n\t dbr.y = delta.y;\n\t }\n\t }\n\n\t if (!dragging) {\n\t staticPoint = hitToOppositeSide(handle, this._innerBounds);\n\t scaleX = (this._innerBounds.width + delta.x * handle.x) / this._innerBounds.width;\n\t scaleY = (this._innerBounds.height + delta.y * handle.y) / this._innerBounds.height;\n\t }\n\n\t for (i = 0; i < this.shapes.length; i++) {\n\t shape = this.shapes[i];\n\t bounds = shape.bounds();\n\t if (dragging) {\n\t if (!canDrag(shape)) {\n\t continue;\n\t }\n\t newBounds = this._displaceBounds(bounds, dtl, dbr, dragging);\n\t } else {\n\t newBounds = bounds.clone();\n\t newBounds.scale(scaleX, scaleY, staticPoint, this._innerBounds.center(), shape.rotate().angle);\n\t var newCenter = newBounds.center(); // fixes the new rotation center.\n\t newCenter.rotate(bounds.center(), -this._angle);\n\t newBounds = new Rect(newCenter.x - newBounds.width / 2, newCenter.y - newBounds.height / 2, newBounds.width, newBounds.height);\n\t }\n\t if (newBounds.width >= shape.options.minWidth && newBounds.height >= shape.options.minHeight) { // if we up-size very small shape\n\t var oldBounds = bounds;\n\t shape.bounds(newBounds);\n\t if (shape.hasOwnProperty(\"layout\")) {\n\t shape.layout(shape, oldBounds, newBounds);\n\t }\n\t if (oldBounds.width !== newBounds.width || oldBounds.height !== newBounds.height) {\n\t shape.rotate(shape.rotate().angle); // forces the rotation to update it's rotation center\n\t }\n\t changed += 1;\n\t }\n\t }\n\n\t if (changed) {\n\t if (changed == i) {\n\t newBounds = this._displaceBounds(this._innerBounds, dtl, dbr, dragging);\n\t this.bounds(newBounds);\n\t } else {\n\t this.refreshBounds();\n\t }\n\t this.refresh();\n\t }\n\n\t this._positions();\n\t }\n\n\t this._cp = p;\n\t },\n\n\t isDragHandle: function(handle) {\n\t return handle.x === 0 && handle.y === 0;\n\t },\n\n\t cancel: function() {\n\t var shapes = this.shapes;\n\t var states = this.shapeStates;\n\t for (var idx = 0; idx < shapes.length; idx++) {\n\t shapes[idx].bounds(states[idx]);\n\t }\n\t this.refreshBounds();\n\t this.refresh();\n\t this._manipulating = undefined;\n\t this._internalChange = undefined;\n\t this._rotating = undefined;\n\t },\n\n\t _truncatePositionToGuides: function (bounds) {\n\t if (this.diagram.ruler) {\n\t return this.diagram.ruler.truncatePositionToGuides(bounds);\n\t }\n\t return bounds;\n\t },\n\n\t _truncateSizeToGuides: function (bounds) {\n\t if (this.diagram.ruler) {\n\t return this.diagram.ruler.truncateSizeToGuides(bounds);\n\t }\n\t return bounds;\n\t },\n\n\t _truncateAngle: function (a) {\n\t var snap = this.snapOptions();\n\t var snapAngle = Math.max(snap.angle || DEFAULT_SNAP_ANGLE, MIN_SNAP_ANGLE);\n\t return snap ? Math.floor((a % 360) / snapAngle) * snapAngle : (a % 360);\n\t },\n\n\t _truncateDistance: function (d) {\n\t if (d instanceof diagram.Point) {\n\t return new diagram.Point(this._truncateDistance(d.x), this._truncateDistance(d.y));\n\t } else {\n\t var snap = this.snapOptions() || {};\n\t var snapSize = Math.max(snap.size || DEFAULT_SNAP_SIZE, MIN_SNAP_SIZE);\n\t return snap ? Math.floor(d / snapSize) * snapSize : d;\n\t }\n\t },\n\n\t snapOptions: function() {\n\t var editable = this.diagram.options.editable;\n\t var snap = ((editable || {}).drag || {}).snap || {};\n\t return snap;\n\t },\n\n\t shouldSnap: function() {\n\t var editable = this.diagram.options.editable;\n\t var drag = (editable || {}).drag;\n\t var snap = (drag || {}).snap;\n\t return editable !== false && drag !== false && snap !== false;\n\t },\n\n\t _displaceBounds: function (bounds, dtl, dbr, dragging) {\n\t var tl = bounds.topLeft().plus(dtl),\n\t br = bounds.bottomRight().plus(dbr),\n\t newBounds = Rect.fromPoints(tl, br),\n\t newCenter;\n\t if (!dragging) {\n\t newCenter = newBounds.center();\n\t newCenter.rotate(bounds.center(), -this._angle);\n\t newBounds = new Rect(newCenter.x - newBounds.width / 2, newCenter.y - newBounds.height / 2, newBounds.width, newBounds.height);\n\t }\n\t return newBounds;\n\t },\n\n\t stop: function () {\n\t var unit, i, shape;\n\t if (this._cp != this._sp) {\n\t if (this._rotating) {\n\t unit = new RotateUnit(this, this.shapes, this.initialRotates);\n\t this._rotating = false;\n\t } else if (this._diffStates()) {\n\t if (this.diagram.ruler) {\n\t for (i = 0; i < this.shapes.length; i++) {\n\t shape = this.shapes[i];\n\t var bounds = shape.bounds();\n\t bounds = this._truncateSizeToGuides(this._truncatePositionToGuides(bounds));\n\t shape.bounds(bounds);\n\t this.refreshBounds();\n\t this.refresh();\n\t }\n\t }\n\t for (i = 0; i < this.shapes.length; i++) {\n\t shape = this.shapes[i];\n\t shape.updateModel();\n\t }\n\t unit = new TransformUnit(this.shapes, this.shapeStates, this);\n\t this.diagram._syncShapeChanges();\n\t }\n\t }\n\n\t this._manipulating = undefined;\n\t this._internalChange = undefined;\n\t this._rotating = undefined;\n\t return unit;\n\t },\n\n\t _diffStates: function() {\n\t var shapes = this.shapes;\n\t var states = this.shapeStates;\n\t for (var idx = 0; idx < shapes.length; idx++) {\n\t if (!shapes[idx].bounds().equals(states[idx])) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t },\n\n\t refreshBounds: function () {\n\t var bounds = this.shapes.length == 1 ?\n\t this.shapes[0].bounds().clone() :\n\t this.diagram.boundingBox(this.shapes, true);\n\n\t this.bounds(bounds);\n\t },\n\n\t refresh: function () {\n\t var that = this, b, bounds;\n\t if (this.shapes.length > 0) {\n\t bounds = this.bounds();\n\t this.visual.visible(true);\n\t this.visual.position(bounds.topLeft());\n\t $.each(this.map, function () {\n\t b = that._getHandleBounds(new Point(this.x, this.y));\n\t this.visual.position(b.topLeft());\n\t });\n\t this.visual.position(bounds.topLeft());\n\n\t var center = new Point(bounds.width / 2, bounds.height / 2);\n\t this.visual.rotate(this._angle, center);\n\t this.rect.redraw({ width: bounds.width, height: bounds.height });\n\t if (this.rotationThumb) {\n\t var thumb = this.options.editable.rotate.thumb;\n\t this._rotationThumbBounds = new Rect(bounds.center().x, bounds.y + thumb.y, 0, 0).inflate(thumb.width);\n\t this.rotationThumb.redraw({ x: bounds.width / 2 - thumb.width / 2 });\n\t }\n\t } else {\n\t this.visual.visible(false);\n\t }\n\t }\n\t });\n\n\t var Selector = Class.extend({\n\t init: function (diagram) {\n\t var selectable = diagram.options.selectable;\n\t this.options = deepExtend({}, this.options, selectable);\n\n\t this.visual = new Rectangle(this.options);\n\t this.diagram = diagram;\n\t },\n\t options: {\n\t stroke: {\n\t color: \"#778899\",\n\t width: 1,\n\t dashType: \"dash\"\n\t },\n\t fill: {\n\t color: TRANSPARENT\n\t }\n\t },\n\t start: function (p) {\n\t this._sp = this._ep = p;\n\t this.refresh();\n\t this.diagram._adorn(this, true);\n\t },\n\t end: function () {\n\t this._sp = this._ep = undefined;\n\t this.diagram._adorn(this, false);\n\t },\n\t bounds: function (value) {\n\t if (value) {\n\t this._bounds = value;\n\t }\n\t return this._bounds;\n\t },\n\t move: function (p) {\n\t this._ep = p;\n\t this.refresh();\n\t },\n\t refresh: function () {\n\t if (this._sp) {\n\t var visualBounds = Rect.fromPoints(this.diagram.modelToLayer(this._sp), this.diagram.modelToLayer(this._ep));\n\t this.bounds(Rect.fromPoints(this._sp, this._ep));\n\t this.visual.position(visualBounds.topLeft());\n\t this.visual.redraw({ height: visualBounds.height + 1, width: visualBounds.width + 1 });\n\t }\n\t }\n\t });\n\n\t var ConnectorVisual = Class.extend({\n\t init: function (connector) {\n\t this.options = deepExtend({}, connector.options);\n\t this._c = connector;\n\t this.visual = new Circle(this.options);\n\t this.refresh();\n\t },\n\t _hover: function (value) {\n\t var options = this.options,\n\t hover = options.hover,\n\t stroke = options.stroke,\n\t fill = options.fill;\n\n\t if (value && Utils.isDefined(hover.stroke)) {\n\t stroke = deepExtend({}, stroke, hover.stroke);\n\t }\n\n\t if (value && Utils.isDefined(hover.fill)) {\n\t fill = hover.fill;\n\t }\n\n\t this.visual.redraw({\n\t stroke: stroke,\n\t fill: fill\n\t });\n\t },\n\t refresh: function () {\n\t var p = this._c.shape.diagram.modelToView(this._c.position()),\n\t relative = p.minus(this._c.shape.bounds(\"transformed\").topLeft()),\n\t value = new Rect(p.x, p.y, 0, 0);\n\t value.inflate(this.options.width / 2, this.options.height / 2);\n\t this._visualBounds = value;\n\t this.visual.redraw({ center: new Point(relative.x, relative.y) });\n\t },\n\t _hitTest: function (p) {\n\t var tp = this._c.shape.diagram.modelToView(p);\n\t return this._visualBounds.contains(tp);\n\t }\n\t });\n\n\t function canDrag(element) {\n\t var editable = element.options.editable;\n\t return editable && editable.drag !== false;\n\t }\n\n\t function hitTestShapeConnectors(shape, point) {\n\t var connector, position, rect;\n\t for (var idx = 0; idx < shape.connectors.length; idx++) {\n\t connector = shape.connectors[idx];\n\t position = connector.position();\n\t rect = new Rect(position.x, position.y);\n\t rect.inflate(HIT_TEST_DISTANCE, HIT_TEST_DISTANCE);\n\t if (rect.contains(point)) {\n\t return connector;\n\t }\n\t }\n\t }\n\n\t function noMeta(meta) {\n\t return meta.ctrlKey === false && meta.altKey === false && meta.shiftKey === false;\n\t }\n\n\t deepExtend(diagram, {\n\t CompositeUnit: CompositeUnit,\n\t TransformUnit: TransformUnit,\n\t PanUndoUnit: PanUndoUnit,\n\t AddShapeUnit: AddShapeUnit,\n\t AddConnectionUnit: AddConnectionUnit,\n\t DeleteShapeUnit: DeleteShapeUnit,\n\t DeleteConnectionUnit: DeleteConnectionUnit,\n\t ConnectionEditAdorner: ConnectionEditAdorner,\n\t ConnectionTool: ConnectionTool,\n\t ConnectorVisual: ConnectorVisual,\n\t UndoRedoService: UndoRedoService,\n\t ResizingAdorner: ResizingAdorner,\n\t Selector: Selector,\n\t ToolService: ToolService,\n\t ConnectorsAdorner: ConnectorsAdorner,\n\t LayoutUndoUnit: LayoutUndoUnit,\n\t ConnectionEditUnit: ConnectionEditUnit,\n\t ToFrontUnit: ToFrontUnit,\n\t ToBackUnit: ToBackUnit,\n\t ConnectionRouterBase: ConnectionRouterBase,\n\t PolylineRouter: PolylineRouter,\n\t CascadingRouter: CascadingRouter,\n\t SelectionTool: SelectionTool,\n\t ScrollerTool: ScrollerTool,\n\t PointerTool: PointerTool,\n\t ConnectionEditTool: ConnectionEditTool,\n\t RotateUnit: RotateUnit\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(882);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 860:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.drawing\");\n\n/***/ }),\n\n/***/ 878:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./math\");\n\n/***/ }),\n\n/***/ 882:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(860), __webpack_require__(878) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var kendo = window.kendo,\n\t diagram = kendo.dataviz.diagram,\n\t Class = kendo.Class,\n\t deepExtend = kendo.deepExtend,\n\t Point = diagram.Point,\n\t Rect = diagram.Rect,\n\t Matrix = diagram.Matrix,\n\t Utils = diagram.Utils,\n\t isNumber = Utils.isNumber,\n\t isString = Utils.isString,\n\t MatrixVector = diagram.MatrixVector,\n\n\t g = kendo.geometry,\n\t d = kendo.drawing,\n\n\t defined = d.util.defined,\n\n\t inArray = $.inArray;\n\n\t // Constants ==============================================================\n\t var TRANSPARENT = \"transparent\",\n\t Markers = {\n\t none: \"none\",\n\t arrowStart: \"ArrowStart\",\n\t filledCircle: \"FilledCircle\",\n\t arrowEnd: \"ArrowEnd\"\n\t },\n\t FULL_CIRCLE_ANGLE = 360,\n\t START = \"start\",\n\t END = \"end\",\n\t WIDTH = \"width\",\n\t HEIGHT = \"height\",\n\t X = \"x\",\n\t Y = \"y\";\n\n\t diagram.Markers = Markers;\n\n\t function diffNumericOptions(options, fields) {\n\t var elementOptions = this.options;\n\t var hasChanges = false;\n\t var value, field;\n\t for (var i = 0; i < fields.length; i++) {\n\t field = fields[i];\n\t value = options[field];\n\t if (isNumber(value) && elementOptions[field] !== value) {\n\t elementOptions[field] = value;\n\t hasChanges = true;\n\t }\n\t }\n\n\t return hasChanges;\n\t }\n\n\t var Scale = Class.extend({\n\t init: function (x, y) {\n\t this.x = x;\n\t this.y = y;\n\t },\n\t toMatrix: function () {\n\t return Matrix.scaling(this.x, this.y);\n\t },\n\t toString: function () {\n\t return kendo.format(\"scale({0},{1})\", this.x, this.y);\n\t },\n\t invert: function() {\n\t return new Scale(1/this.x, 1/this.y);\n\t }\n\t });\n\n\t var Translation = Class.extend({\n\t init: function (x, y) {\n\t this.x = x;\n\t this.y = y;\n\t },\n\t toMatrixVector: function () {\n\t return new MatrixVector(0, 0, 0, 0, this.x, this.y);\n\t },\n\t toMatrix: function () {\n\t return Matrix.translation(this.x, this.y);\n\t },\n\t toString: function () {\n\t return kendo.format(\"translate({0},{1})\", this.x, this.y);\n\t },\n\t plus: function (delta) {\n\t this.x += delta.x;\n\t this.y += delta.y;\n\t },\n\t times: function (factor) {\n\t this.x *= factor;\n\t this.y *= factor;\n\t },\n\t length: function () {\n\t return Math.sqrt(this.x * this.x + this.y * this.y);\n\t },\n\t normalize: function () {\n\t if (this.Length === 0) {\n\t return;\n\t }\n\t this.times(1 / this.length());\n\t },\n\t invert: function() {\n\t return new Translation(-this.x, -this.y);\n\t }\n\t });\n\n\t var Rotation = Class.extend({\n\t init: function (angle, x, y) {\n\t this.x = x || 0;\n\t this.y = y || 0;\n\t this.angle = angle;\n\t },\n\t toString: function () {\n\t if (this.x && this.y) {\n\t return kendo.format(\"rotate({0},{1},{2})\", this.angle, this.x, this.y);\n\t } else {\n\t return kendo.format(\"rotate({0})\", this.angle);\n\t }\n\t },\n\t toMatrix: function () {\n\t return Matrix.rotation(this.angle, this.x, this.y); // T*R*T^-1\n\t },\n\t center: function () {\n\t return new Point(this.x, this.y);\n\t },\n\t invert: function() {\n\t return new Rotation(FULL_CIRCLE_ANGLE - this.angle, this.x, this.y);\n\t }\n\t });\n\n\t Rotation.ZERO = new Rotation(0);\n\n\t Rotation.create = function (rotation) {\n\t return new Rotation(rotation.angle, rotation.x, rotation.y);\n\t };\n\n\t Rotation.parse = function (str) {\n\t var values = str.slice(1, str.length - 1).split(\",\"),\n\t angle = values[0],\n\t x = values[1],\n\t y = values[2];\n\t var rotation = new Rotation(angle, x, y);\n\t return rotation;\n\t };\n\n\t var CompositeTransform = Class.extend({\n\t init: function (x, y, scaleX, scaleY, angle, center) {\n\t this.translate = new Translation(x, y);\n\t if (scaleX !== undefined && scaleY !== undefined) {\n\t this.scale = new Scale(scaleX, scaleY);\n\t }\n\t if (angle !== undefined) {\n\t this.rotate = center ? new Rotation(angle, center.x, center.y) : new Rotation(angle);\n\t }\n\t },\n\t toString: function () {\n\t var toString = function (transform) {\n\t return transform ? transform.toString() : \"\";\n\t };\n\n\t return toString(this.translate) +\n\t toString(this.rotate) +\n\t toString(this.scale);\n\t },\n\n\t render: function (visual) {\n\t visual._transform = this;\n\t visual._renderTransform();\n\t },\n\n\t toMatrix: function () {\n\t var m = Matrix.unit();\n\n\t if (this.translate) {\n\t m = m.times(this.translate.toMatrix());\n\t }\n\t if (this.rotate) {\n\t m = m.times(this.rotate.toMatrix());\n\t }\n\t if (this.scale) {\n\t m = m.times(this.scale.toMatrix());\n\t }\n\t return m;\n\t },\n\t invert: function() {\n\t var rotate = this.rotate ? this.rotate.invert() : undefined,\n\t rotateMatrix = rotate ? rotate.toMatrix() : Matrix.unit(),\n\t scale = this.scale ? this.scale.invert() : undefined,\n\t scaleMatrix = scale ? scale.toMatrix() : Matrix.unit();\n\n\t var translatePoint = new Point(-this.translate.x, -this.translate.y);\n\t translatePoint = rotateMatrix.times(scaleMatrix).apply(translatePoint);\n\t var translate = new Translation(translatePoint.x, translatePoint.y);\n\n\t var transform = new CompositeTransform();\n\t transform.translate = translate;\n\t transform.rotate = rotate;\n\t transform.scale = scale;\n\n\t return transform;\n\t }\n\t });\n\n\t var AutoSizeableMixin = {\n\t _setScale: function() {\n\t var options = this.options;\n\t var originWidth = this._originWidth;\n\t var originHeight = this._originHeight;\n\t var scaleX = options.width / originWidth;\n\t var scaleY = options.height / originHeight;\n\n\t if (!isNumber(scaleX)) {\n\t scaleX = 1;\n\t }\n\t if (!isNumber(scaleY)) {\n\t scaleY = 1;\n\t }\n\n\t this._transform.scale = new Scale(scaleX, scaleY);\n\t },\n\n\t _setTranslate: function() {\n\t var options = this.options;\n\t var x = options.x || 0;\n\t var y = options.y || 0;\n\t this._transform.translate = new Translation(x, y);\n\t },\n\n\t _initSize: function() {\n\t var options = this.options;\n\t var transform = false;\n\t if (options.autoSize !== false && (defined(options.width) || defined(options.height))) {\n\t this._measure(true);\n\t this._setScale();\n\t transform = true;\n\t }\n\n\t if (defined(options.x) || defined(options.y)) {\n\t this._setTranslate();\n\t transform = true;\n\t }\n\n\t if (transform) {\n\t this._renderTransform();\n\t }\n\t },\n\n\t _updateSize: function(options) {\n\t var update = false;\n\n\t if (this.options.autoSize !== false && this._diffNumericOptions(options, [WIDTH, HEIGHT])) {\n\t update = true;\n\t this._measure(true);\n\t this._setScale();\n\t }\n\n\t if (this._diffNumericOptions(options, [X, Y])) {\n\t update = true;\n\t this._setTranslate();\n\t }\n\n\t if (update) {\n\t this._renderTransform();\n\t }\n\n\t return update;\n\t }\n\t };\n\n\t var Element = Class.extend({\n\t init: function (options) {\n\t var element = this;\n\t element.options = deepExtend({}, element.options, options);\n\t element.id = element.options.id;\n\t element._originSize = Rect.empty();\n\t element._transform = new CompositeTransform();\n\t },\n\n\t visible: function (value) {\n\t return this.drawingContainer().visible(value);\n\t },\n\n\t redraw: function (options) {\n\t if (options && options.id) {\n\t this.id = options.id;\n\t }\n\t },\n\n\t position: function (x, y) {\n\t var options = this.options;\n\t if (!defined(x)) {\n\t return new Point(options.x, options.y);\n\t }\n\n\t if (defined(y)) {\n\t options.x = x;\n\t options.y = y;\n\t } else if (x instanceof Point) {\n\t options.x = x.x;\n\t options.y = x.y;\n\t }\n\n\t this._transform.translate = new Translation(options.x, options.y);\n\t this._renderTransform();\n\t },\n\n\t rotate: function (angle, center) {\n\t if (defined(angle)) {\n\t this._transform.rotate = new Rotation(angle, center.x, center.y);\n\t this._renderTransform();\n\t }\n\t return this._transform.rotate || Rotation.ZERO;\n\t },\n\n\t drawingContainer: function() {\n\t return this.drawingElement;\n\t },\n\n\t _renderTransform: function () {\n\t var matrix = this._transform.toMatrix();\n\t this.drawingContainer().transform(new g.Matrix(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f));\n\t },\n\n\t _hover: function () {},\n\n\t _diffNumericOptions: diffNumericOptions,\n\n\t _measure: function (force) {\n\t var rect;\n\t if (!this._measured || force) {\n\t var box = this._boundingBox() || new g.Rect();\n\t var startPoint = box.topLeft();\n\t rect = new Rect(startPoint.x, startPoint.y, box.width(), box.height());\n\t this._originSize = rect;\n\t this._originWidth = rect.width;\n\t this._originHeight = rect.height;\n\t this._measured = true;\n\t } else {\n\t rect = this._originSize;\n\t }\n\t return rect;\n\t },\n\n\t _boundingBox: function() {\n\t return this.drawingElement.rawBBox();\n\t }\n\t });\n\n\t var VisualBase = Element.extend({\n\t init: function(options) {\n\t Element.fn.init.call(this, options);\n\n\t options = this.options;\n\t options.fill = normalizeDrawingOptions(options.fill);\n\t options.stroke = normalizeDrawingOptions(options.stroke);\n\t },\n\n\t options: {\n\t stroke: {\n\t color: \"gray\",\n\t width: 1\n\t },\n\t fill: {\n\t color: TRANSPARENT\n\t }\n\t },\n\n\t fill: function(color, opacity) {\n\t this._fill({\n\t color: getColor(color),\n\t opacity: opacity\n\t });\n\t },\n\n\t stroke: function(color, width, opacity) {\n\t this._stroke({\n\t color: getColor(color),\n\t width: width,\n\t opacity: opacity\n\t });\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t var stroke = options.stroke;\n\t var fill = options.fill;\n\t if (stroke) {\n\t this._stroke(normalizeDrawingOptions(stroke));\n\t }\n\t if (fill) {\n\t this._fill(normalizeDrawingOptions(fill));\n\t }\n\n\t Element.fn.redraw.call(this, options);\n\t }\n\t },\n\n\t _hover: function (show) {\n\t var drawingElement = this.drawingElement;\n\t var options = this.options;\n\t var hover = options.hover;\n\n\t if (hover && hover.fill) {\n\t var fill = show ? normalizeDrawingOptions(hover.fill) : options.fill;\n\t drawingElement.fill(fill.color, fill.opacity);\n\t }\n\t },\n\n\t _stroke: function(strokeOptions) {\n\t var options = this.options;\n\t deepExtend(options, {\n\t stroke: strokeOptions\n\t });\n\n\t strokeOptions = options.stroke;\n\n\t var stroke = null;\n\t if (strokeOptions.width > 0) {\n\t stroke = {\n\t color: strokeOptions.color,\n\t width: strokeOptions.width,\n\t opacity: strokeOptions.opacity,\n\t dashType: strokeOptions.dashType\n\t };\n\t }\n\n\t this.drawingElement.options.set(\"stroke\", stroke);\n\t },\n\n\t _fill: function(fillOptions) {\n\t var options = this.options;\n\t deepExtend(options, {\n\t fill: fillOptions || {}\n\t });\n\t var fill = options.fill;\n\n\t if (fill.gradient) {\n\t var gradient = fill.gradient;\n\t var GradientClass = (gradient.type === \"radial\" ? d.RadialGradient : d.LinearGradient);\n\t this.drawingElement.fill(new GradientClass(gradient));\n\t } else {\n\t this.drawingElement.fill(fill.color, fill.opacity);\n\t }\n\t }\n\t });\n\n\t var TextBlock = VisualBase.extend({\n\t init: function (options) {\n\t options = this._textColor(options);\n\t VisualBase.fn.init.call(this, options);\n\n\t this._font();\n\t this._initText();\n\t this._initSize();\n\t },\n\n\t options: {\n\t fontSize: 15,\n\t fontFamily: \"sans-serif\",\n\t stroke: {\n\t width: 0\n\t },\n\t fill: {\n\t color: \"black\"\n\t },\n\t autoSize: true\n\t },\n\n\t _initText: function() {\n\t var options = this.options;\n\n\t this.drawingElement = new d.Text(defined(options.text) ? options.text : \"\", new g.Point(), {\n\t font: options.font\n\t });\n\n\t this._fill();\n\t this._stroke();\n\t },\n\n\t _textColor: function(options) {\n\t if (options && options.color) {\n\t options = deepExtend({}, options, {\n\t fill: {\n\t color: options.color\n\t }\n\t });\n\t }\n\t return options;\n\t },\n\n\t _font: function() {\n\t var options = this.options;\n\t if (options.fontFamily && defined(options.fontSize)) {\n\t var fontOptions = [];\n\n\t if (options.fontStyle) {\n\t fontOptions.push(options.fontStyle);\n\t }\n\n\t if (options.fontWeight) {\n\t fontOptions.push(options.fontWeight);\n\t }\n\n\t fontOptions.push(options.fontSize + (isNumber(options.fontSize) ? \"px\" : \"\"));\n\t fontOptions.push(options.fontFamily);\n\n\t options.font = fontOptions.join(\" \");\n\t } else {\n\t delete options.font;\n\t }\n\t },\n\n\t content: function (text) {\n\t return this.drawingElement.content(text);\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t var sizeChanged = false;\n\t var textOptions = this.options;\n\n\t options = this._textColor(options);\n\n\t VisualBase.fn.redraw.call(this, options);\n\n\t if (options.fontFamily || defined(options.fontSize) || options.fontStyle || options.fontWeight) {\n\t deepExtend(textOptions, {\n\t fontFamily: options.fontFamily,\n\t fontSize: options.fontSize,\n\t fontStyle: options.fontStyle,\n\t fontWeight: options.fontWeight\n\t });\n\t this._font();\n\t this.drawingElement.options.set(\"font\", textOptions.font);\n\t sizeChanged = true;\n\t }\n\n\t if (options.text) {\n\t this.content(options.text);\n\t sizeChanged = true;\n\t }\n\n\t if (!this._updateSize(options) && sizeChanged) {\n\t this._initSize();\n\t }\n\t }\n\t }\n\t });\n\n\t deepExtend(TextBlock.fn, AutoSizeableMixin);\n\n\t var Rectangle = VisualBase.extend({\n\t init: function (options) {\n\t VisualBase.fn.init.call(this, options);\n\t this._initPath();\n\t this._setPosition();\n\t },\n\n\t _setPosition: function() {\n\t var options = this.options;\n\t var x = options.x;\n\t var y = options.y;\n\t if (defined(x) || defined(y)) {\n\t this.position(x || 0, y || 0);\n\t }\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t VisualBase.fn.redraw.call(this, options);\n\t if (this._diffNumericOptions(options, [WIDTH, HEIGHT])) {\n\t this._drawPath();\n\t }\n\t if (this._diffNumericOptions(options, [X, Y])) {\n\t this._setPosition();\n\t }\n\t }\n\t },\n\n\t _initPath: function() {\n\t var options = this.options;\n\t this.drawingElement = new d.Path({\n\t stroke: options.stroke,\n\t closed: true\n\t });\n\n\t this._fill();\n\t this._drawPath();\n\t },\n\n\t _drawPath: function() {\n\t var drawingElement = this.drawingElement;\n\t var sizeOptions = sizeOptionsOrDefault(this.options);\n\t var width = sizeOptions.width;\n\t var height = sizeOptions.height;\n\n\t drawingElement.segments.elements([\n\t createSegment(0, 0),\n\t createSegment(width, 0),\n\t createSegment(width, height),\n\t createSegment(0, height)\n\t ]);\n\t }\n\t });\n\n\t var MarkerBase = VisualBase.extend({\n\t init: function(options) {\n\t VisualBase.fn.init.call(this, options);\n\t var anchor = this.options.anchor;\n\t this.anchor = new g.Point(anchor.x, anchor.y);\n\t this.createElement();\n\t },\n\n\t options: {\n\t stroke: {\n\t color: TRANSPARENT,\n\t width: 0\n\t },\n\t fill: {\n\t color: \"black\"\n\t }\n\t },\n\n\t _transformToPath: function(point, path) {\n\t var transform = path.transform();\n\t if (point && transform) {\n\t point = point.transformCopy(transform);\n\t }\n\t return point;\n\t },\n\n\t redraw: function(options) {\n\t if (options) {\n\t if (options.position) {\n\t this.options.position = options.position;\n\t }\n\n\t VisualBase.fn.redraw.call(this, options);\n\t }\n\t }\n\t });\n\n\t var CircleMarker = MarkerBase.extend({\n\t options: {\n\t radius: 4,\n\t anchor: {\n\t x: 0,\n\t y: 0\n\t }\n\t },\n\n\t createElement: function() {\n\t var options = this.options;\n\t this.drawingElement = new d.Circle(new g.Circle(this.anchor, options.radius), {\n\t fill: options.fill,\n\t stroke: options.stroke\n\t });\n\t },\n\n\t positionMarker: function(path) {\n\t var options = this.options;\n\t var position = options.position;\n\t var segments = path.segments;\n\t var targetSegment;\n\t var point;\n\n\t if (position == START) {\n\t targetSegment = segments[0];\n\t } else {\n\t targetSegment = segments[segments.length - 1];\n\t }\n\t if (targetSegment) {\n\t point = this._transformToPath(targetSegment.anchor(), path);\n\t this.drawingElement.transform(g.transform().translate(point.x, point.y));\n\t }\n\t }\n\t });\n\n\t var ArrowMarker = MarkerBase.extend({\n\t options: {\n\t path: \"M 0 0 L 10 5 L 0 10 L 3 5 z\" ,\n\t anchor: {\n\t x: 10,\n\t y: 5\n\t }\n\t },\n\n\t createElement: function() {\n\t var options = this.options;\n\t this.drawingElement = d.Path.parse(options.path, {\n\t fill: options.fill,\n\t stroke: options.stroke\n\t });\n\t },\n\n\t positionMarker: function(path) {\n\t var points = this._linePoints(path);\n\t var start = points.start;\n\t var end = points.end;\n\t var transform = g.transform();\n\t if (start) {\n\t transform.rotate(lineAngle(start, end), end);\n\t }\n\n\t if (end) {\n\t var anchor = this.anchor;\n\t var translate = end.clone().translate(-anchor.x, -anchor.y);\n\t transform.translate(translate.x, translate.y);\n\t }\n\t this.drawingElement.transform(transform);\n\t },\n\n\t _linePoints: function(path) {\n\t var options = this.options;\n\t var segments = path.segments;\n\t var startPoint, endPoint, targetSegment;\n\t if (options.position == START) {\n\t targetSegment = segments[0];\n\t if (targetSegment) {\n\t endPoint = targetSegment.anchor();\n\t startPoint = targetSegment.controlOut();\n\t var nextSegment = segments[1];\n\t if (!startPoint && nextSegment) {\n\t startPoint = nextSegment.anchor();\n\t }\n\t }\n\t } else {\n\t targetSegment = segments[segments.length - 1];\n\t if (targetSegment) {\n\t endPoint = targetSegment.anchor();\n\t startPoint = targetSegment.controlIn();\n\t var prevSegment = segments[segments.length - 2];\n\t if (!startPoint && prevSegment) {\n\t startPoint = prevSegment.anchor();\n\t }\n\t }\n\t }\n\t if (endPoint) {\n\t return {\n\t start: this._transformToPath(startPoint, path),\n\t end: this._transformToPath(endPoint, path)\n\t };\n\t }\n\t }\n\t });\n\n\t var MarkerPathMixin = {\n\t _getPath: function(position) {\n\t var path = this.drawingElement;\n\t if (path instanceof d.MultiPath) {\n\t if (position == START) {\n\t path = path.paths[0];\n\t } else {\n\t path = path.paths[path.paths.length - 1];\n\t }\n\t }\n\t if (path && path.segments.length) {\n\t return path;\n\t }\n\t },\n\n\t _normalizeMarkerOptions: function(options) {\n\t var startCap = options.startCap;\n\t var endCap = options.endCap;\n\n\t if (isString(startCap)) {\n\t options.startCap = {\n\t type: startCap\n\t };\n\t }\n\n\t if (isString(endCap)) {\n\t options.endCap = {\n\t type: endCap\n\t };\n\t }\n\t },\n\n\t _removeMarker: function(position) {\n\t var marker = this._markers[position];\n\t if (marker) {\n\t this.drawingContainer().remove(marker.drawingElement);\n\t delete this._markers[position];\n\t }\n\t },\n\n\t _createMarkers: function() {\n\t var options = this.options;\n\t this._normalizeMarkerOptions(options);\n\n\t this._markers = {};\n\t this._markers[START] = this._createMarker(options.startCap, START);\n\t this._markers[END] = this._createMarker(options.endCap, END);\n\t },\n\n\t _createMarker: function(options, position) {\n\t var type = (options || {}).type;\n\t var path = this._getPath(position);\n\t var markerType, marker;\n\t if (!path) {\n\t this._removeMarker(position);\n\t return;\n\t }\n\n\t if (type == Markers.filledCircle) {\n\t markerType = CircleMarker;\n\t } else if (type == Markers.arrowStart || type == Markers.arrowEnd){\n\t markerType = ArrowMarker;\n\t } else {\n\t this._removeMarker(position);\n\t }\n\t if (markerType) {\n\t marker = new markerType(deepExtend({}, options, {\n\t position: position\n\t }));\n\t marker.positionMarker(path);\n\t this.drawingContainer().append(marker.drawingElement);\n\n\t return marker;\n\t }\n\t },\n\n\t _positionMarker : function(position) {\n\t var marker = this._markers[position];\n\n\t if (marker) {\n\t var path = this._getPath(position);\n\t if (path) {\n\t marker.positionMarker(path);\n\t } else {\n\t this._removeMarker(position);\n\t }\n\t }\n\t },\n\n\t _capMap: {\n\t start: \"startCap\",\n\t end: \"endCap\"\n\t },\n\n\t _redrawMarker: function(pathChange, position, options) {\n\t this._normalizeMarkerOptions(options);\n\n\t var pathOptions = this.options;\n\t var cap = this._capMap[position];\n\t var pathCapType = (pathOptions[cap] || {}).type;\n\t var optionsCap = options[cap];\n\t var created = false;\n\t if (optionsCap) {\n\t pathOptions[cap] = deepExtend({}, pathOptions[cap], optionsCap);\n\t if (optionsCap.type && pathCapType != optionsCap.type) {\n\t this._removeMarker(position);\n\t this._markers[position] = this._createMarker(pathOptions[cap], position);\n\t created = true;\n\t } else if (this._markers[position]) {\n\t this._markers[position].redraw(optionsCap);\n\t }\n\t } else if (pathChange && !this._markers[position] && pathOptions[cap]) {\n\t this._markers[position] = this._createMarker(pathOptions[cap], position);\n\t created = true;\n\t }\n\t return created;\n\t },\n\n\t _redrawMarkers: function (pathChange, options) {\n\t if (!this._redrawMarker(pathChange, START, options) && pathChange) {\n\t this._positionMarker(START);\n\t }\n\t if (!this._redrawMarker(pathChange, END, options) && pathChange) {\n\t this._positionMarker(END);\n\t }\n\t }\n\t };\n\n\t var Path = VisualBase.extend({\n\t init: function (options) {\n\t VisualBase.fn.init.call(this, options);\n\t this.container = new d.Group();\n\t this._createElements();\n\t this._initSize();\n\t },\n\n\t options: {\n\t autoSize: true\n\t },\n\n\t drawingContainer: function() {\n\t return this.container;\n\t },\n\n\t data: function (value) {\n\t var options = this.options;\n\t if (value) {\n\t if (options.data != value) {\n\t options.data = value;\n\t this._setData(value);\n\t this._initSize();\n\t this._redrawMarkers(true, {});\n\t }\n\t } else {\n\t return options.data;\n\t }\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t VisualBase.fn.redraw.call(this, options);\n\n\t var pathOptions = this.options;\n\t var data = options.data;\n\n\t if (defined(data) && pathOptions.data != data) {\n\t pathOptions.data = data;\n\t this._setData(data);\n\t if (!this._updateSize(options)) {\n\t this._initSize();\n\t }\n\t this._redrawMarkers(true, options);\n\t } else {\n\t this._updateSize(options);\n\t this._redrawMarkers(false, options);\n\t }\n\t }\n\t },\n\n\t _createElements: function() {\n\t var options = this.options;\n\n\t this.drawingElement = d.Path.parse(options.data || \"\", {\n\t stroke: options.stroke\n\t });\n\n\t this._fill();\n\t this.container.append(this.drawingElement);\n\t this._createMarkers();\n\t },\n\n\t _setData: function(data) {\n\t var drawingElement = this.drawingElement;\n\t var multipath = d.Path.parse(data || \"\");\n\t var paths = multipath.paths.slice(0);\n\t multipath.paths.elements([]);\n\t drawingElement.paths.elements(paths);\n\t }\n\t });\n\n\t deepExtend(Path.fn, AutoSizeableMixin);\n\t deepExtend(Path.fn, MarkerPathMixin);\n\n\t var Line = VisualBase.extend({\n\t init: function (options) {\n\t VisualBase.fn.init.call(this, options);\n\t this.container = new d.Group();\n\t this._initPath();\n\t this._createMarkers();\n\t },\n\n\t drawingContainer: function() {\n\t return this.container;\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t options = options || {};\n\t var from = options.from;\n\t var to = options.to;\n\t if (from) {\n\t this.options.from = from;\n\t }\n\n\t if (to) {\n\t this.options.to = to;\n\t }\n\n\t if (from || to) {\n\t this._drawPath();\n\t this._redrawMarkers(true, options);\n\t } else {\n\t this._redrawMarkers(false, options);\n\t }\n\n\t VisualBase.fn.redraw.call(this, options);\n\t }\n\t },\n\n\t _initPath: function() {\n\t var options = this.options;\n\t var drawingElement = this.drawingElement = new d.Path({\n\t stroke: options.stroke\n\t });\n\n\t this._fill();\n\t this._drawPath();\n\t this.container.append(drawingElement);\n\t },\n\n\t _drawPath: function() {\n\t var options = this.options;\n\t var drawingElement = this.drawingElement;\n\t var from = options.from || new Point();\n\t var to = options.to || new Point();\n\n\t drawingElement.segments.elements([\n\t createSegment(from.x, from.y),\n\t createSegment(to.x, to.y)\n\t ]);\n\t }\n\t });\n\n\t deepExtend(Line.fn, MarkerPathMixin);\n\n\t var Polyline = VisualBase.extend({\n\t init: function (options) {\n\t VisualBase.fn.init.call(this, options);\n\t this.container = new d.Group();\n\t this._initPath();\n\t this._createMarkers();\n\t },\n\n\t drawingContainer: function() {\n\t return this.container;\n\t },\n\n\t points: function (points) {\n\t var options = this.options;\n\t if (points) {\n\t options.points = points;\n\t this._updatePath();\n\t } else {\n\t return options.points;\n\t }\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t var points = options.points;\n\t VisualBase.fn.redraw.call(this, options);\n\n\t if (points && this._pointsDiffer(points)) {\n\t this.points(points);\n\t this._redrawMarkers(true, options);\n\t } else {\n\t this._redrawMarkers(false, options);\n\t }\n\t }\n\t },\n\n\t _initPath: function() {\n\t var options = this.options;\n\t this.drawingElement = new d.Path({\n\t stroke: options.stroke\n\t });\n\n\t this._fill();\n\t this.container.append(this.drawingElement);\n\n\t if (options.points) {\n\t this._updatePath();\n\t }\n\t },\n\n\t _pointsDiffer: function(points) {\n\t var currentPoints = this.options.points;\n\t var differ = currentPoints.length !== points.length;\n\t if (!differ) {\n\t for (var i = 0; i < points.length; i++) {\n\t if (currentPoints[i].x !== points[i].x || currentPoints[i].y !== points[i].y) {\n\t differ = true;\n\t break;\n\t }\n\t }\n\t }\n\n\t return differ;\n\t },\n\n\t _updatePath: function() {\n\t var drawingElement = this.drawingElement;\n\t var options = this.options;\n\t var points = options.points;\n\t var segments = [];\n\t var point;\n\t for (var i = 0; i < points.length; i++) {\n\t point = points[i];\n\t segments.push(createSegment(point.x, point.y));\n\t }\n\n\t drawingElement.segments.elements(segments);\n\t },\n\n\t options: {\n\t points: []\n\t }\n\t });\n\n\t deepExtend(Polyline.fn, MarkerPathMixin);\n\n\t var Image = Element.extend({\n\t init: function (options) {\n\t Element.fn.init.call(this, options);\n\n\t this._initImage();\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t if (options.source) {\n\t this.drawingElement.src(options.source);\n\t }\n\n\t if (this._diffNumericOptions(options, [WIDTH, HEIGHT, X, Y])) {\n\t this.drawingElement.rect(this._rect());\n\t }\n\n\t Element.fn.redraw.call(this, options);\n\t }\n\t },\n\n\t _initImage: function() {\n\t var options = this.options;\n\t var rect = this._rect();\n\n\t this.drawingElement = new d.Image(options.source, rect, {});\n\t },\n\n\t _rect: function() {\n\t var sizeOptions = sizeOptionsOrDefault(this.options);\n\t var origin = new g.Point(sizeOptions.x, sizeOptions.y);\n\t var size = new g.Size(sizeOptions.width, sizeOptions.height);\n\n\t return new g.Rect(origin, size);\n\t }\n\t });\n\n\t var Group = Element.extend({\n\t init: function (options) {\n\t this.children = [];\n\t Element.fn.init.call(this, options);\n\t this.drawingElement = new d.Group();\n\t this._initSize();\n\t },\n\n\t options: {\n\t autoSize: false\n\t },\n\n\t append: function (visual) {\n\t this.drawingElement.append(visual.drawingContainer());\n\t this.children.push(visual);\n\t this._childrenChange = true;\n\t },\n\n\t remove: function (visual) {\n\t if (this._remove(visual)) {\n\t this._childrenChange = true;\n\t }\n\t },\n\n\t _remove: function(visual) {\n\t var index = inArray(visual, this.children);\n\t if (index >= 0) {\n\t this.drawingElement.removeAt(index);\n\t this.children.splice(index, 1);\n\t return true;\n\t }\n\t },\n\n\t clear: function () {\n\t this.drawingElement.clear();\n\t this.children = [];\n\t this._childrenChange = true;\n\t },\n\n\t toFront: function (visuals) {\n\t var visual;\n\n\t for (var i = 0; i < visuals.length; i++) {\n\t visual = visuals[i];\n\t if (this._remove(visual)) {\n\t this.append(visual);\n\t }\n\t }\n\t },\n\t //TO DO: add drawing group support for moving and inserting children\n\t toBack: function (visuals) {\n\t this._reorderChildren(visuals, 0);\n\t },\n\n\t toIndex: function (visuals, indices) {\n\t this._reorderChildren(visuals, indices);\n\t },\n\n\t _reorderChildren: function(visuals, indices) {\n\t var group = this.drawingElement;\n\t var drawingChildren = group.children.slice(0);\n\t var children = this.children;\n\t var fixedPosition = isNumber(indices);\n\t var i, index, toIndex, drawingElement, visual;\n\n\t for (i = 0; i < visuals.length; i++) {\n\t visual = visuals[i];\n\t drawingElement = visual.drawingContainer();\n\n\t index = inArray(visual, children);\n\t if (index >= 0) {\n\t drawingChildren.splice(index, 1);\n\t children.splice(index, 1);\n\n\t toIndex = fixedPosition ? indices : indices[i];\n\n\t drawingChildren.splice(toIndex, 0, drawingElement);\n\t children.splice(toIndex, 0, visual);\n\t }\n\t }\n\t group.clear();\n\t group.append.apply(group, drawingChildren);\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t if (this._childrenChange) {\n\t this._childrenChange = false;\n\t if (!this._updateSize(options)) {\n\t this._initSize();\n\t }\n\t } else {\n\t this._updateSize(options);\n\t }\n\n\t Element.fn.redraw.call(this, options);\n\t }\n\t },\n\n\t _boundingBox: function() {\n\t var children = this.children;\n\t var boundingBox;\n\t var visual, childBoundingBox;\n\t for (var i = 0; i < children.length; i++) {\n\t visual = children[i];\n\t if (visual.visible() && visual._includeInBBox !== false) {\n\t childBoundingBox = visual.drawingContainer().clippedBBox(null);\n\t if (childBoundingBox) {\n\t if (boundingBox) {\n\t boundingBox = g.Rect.union(boundingBox, childBoundingBox);\n\t } else {\n\t boundingBox = childBoundingBox;\n\t }\n\t }\n\t }\n\t }\n\n\t return boundingBox;\n\t }\n\t });\n\n\t deepExtend(Group.fn, AutoSizeableMixin);\n\n\t var Layout = Group.extend({\n\t init: function (rect, options) {\n\t this.children = [];\n\t Element.fn.init.call(this, options);\n\t this.drawingElement = new d.Layout(toDrawingRect(rect), options);\n\t this._initSize();\n\t },\n\n\t rect: function(rect) {\n\t if (rect) {\n\t this.drawingElement.rect(toDrawingRect(rect));\n\t } else {\n\t var drawingRect = this.drawingElement.rect();\n\t if (drawingRect) {\n\t return new Rect(drawingRect.origin.x, drawingRect.origin.y, drawingRect.size.width, drawingRect.size.height);\n\t }\n\t }\n\t },\n\n\t reflow: function() {\n\t this.drawingElement.reflow();\n\t },\n\n\t redraw: function (options) {\n\t kendo.deepExtend(this.drawingElement.options, options);\n\t Group.fn.redraw.call(this, options);\n\t }\n\t });\n\n\t var Circle = VisualBase.extend({\n\t init: function (options) {\n\t VisualBase.fn.init.call(this, options);\n\t this._initCircle();\n\t this._initSize();\n\t },\n\n\t redraw: function (options) {\n\t if (options) {\n\t var circleOptions = this.options;\n\n\t if (options.center) {\n\t deepExtend(circleOptions, {\n\t center: options.center\n\t });\n\t this._center.move(circleOptions.center.x, circleOptions.center.y);\n\t }\n\n\t if (this._diffNumericOptions(options, [\"radius\"])) {\n\t this._circle.setRadius(circleOptions.radius);\n\t }\n\n\t this._updateSize(options);\n\n\t VisualBase.fn.redraw.call(this, options);\n\t }\n\t },\n\n\t _initCircle: function() {\n\t var options = this.options;\n\t var width = options.width;\n\t var height = options.height;\n\t var radius = options.radius;\n\t if (!defined(radius)) {\n\t if (!defined(width)) {\n\t width = height;\n\t }\n\t if (!defined(height)) {\n\t height = width;\n\t }\n\t options.radius = radius = Math.min(width, height) / 2;\n\t }\n\n\t var center = options.center || {x: radius, y: radius};\n\t this._center = new g.Point(center.x, center.y);\n\t this._circle = new g.Circle(this._center, radius);\n\t this.drawingElement = new d.Circle(this._circle, {\n\t stroke: options.stroke\n\t });\n\n\t this._fill();\n\t }\n\t });\n\t deepExtend(Circle.fn, AutoSizeableMixin);\n\n\t var Canvas = Class.extend({\n\t init: function (element, options) {\n\t options = options || {};\n\t this.element = element;\n\t this.surface = d.Surface.create(element, options);\n\t if (kendo.isFunction(this.surface.translate)) {\n\t this.translate = this._translate;\n\t }\n\n\t this.drawingElement = new d.Group();\n\t this._viewBox = new Rect(0, 0, options.width, options.height);\n\t this.size(this._viewBox);\n\t },\n\n\t bounds: function () {\n\t var box = this.drawingElement.clippedBBox();\n\t return new Rect(0, 0, box.width(), box.height());\n\t },\n\n\t size: function (size) {\n\t var viewBox = this._viewBox;\n\t if (defined(size)) {\n\t viewBox.width = size.width;\n\t viewBox.height = size.height;\n\t this.surface.setSize(size);\n\t }\n\t return {\n\t width: viewBox.width,\n\t height: viewBox.height\n\t };\n\t },\n\n\t _translate: function (x, y) {\n\t var viewBox = this._viewBox;\n\t if (defined(x) && defined(y)) {\n\t viewBox.x = x;\n\t viewBox.y = y;\n\t this.surface.translate({x: x, y: y});\n\t }\n\t return {\n\t x: viewBox.x,\n\t y: viewBox.y\n\t };\n\t },\n\n\t draw: function() {\n\t this.surface.draw(this.drawingElement);\n\t },\n\n\t append: function (visual) {\n\t this.drawingElement.append(visual.drawingContainer());\n\t return this;\n\t },\n\n\t remove: function (visual) {\n\t this.drawingElement.remove(visual.drawingContainer());\n\t },\n\n\t insertBefore: function () {\n\n\t },\n\n\t clear: function () {\n\t this.drawingElement.clear();\n\t },\n\n\t destroy: function(clearHtml) {\n\t this.surface.destroy();\n\t if(clearHtml) {\n\t $(this.element).remove();\n\t }\n\t }\n\t });\n\n\t // Helper functions ===========================================\n\n\t function sizeOptionsOrDefault(options) {\n\t return {\n\t x: options.x || 0,\n\t y: options.y || 0,\n\t width: options.width || 0,\n\t height: options.height || 0\n\t };\n\t }\n\n\t function normalizeDrawingOptions(options) {\n\t if (options) {\n\t var drawingOptions = options;\n\n\t if (isString(drawingOptions)) {\n\t drawingOptions = {\n\t color: drawingOptions\n\t };\n\t }\n\n\t if (drawingOptions.color) {\n\t drawingOptions.color = getColor(drawingOptions.color);\n\t }\n\t return drawingOptions;\n\t }\n\t }\n\n\t function getColor(value) {\n\t var color;\n\t if (value != TRANSPARENT) {\n\t color = new d.Color(value).toHex();\n\t } else {\n\t color = value;\n\t }\n\t return color;\n\t }\n\n\t function lineAngle(p1, p2) {\n\t var xDiff = p2.x - p1.x;\n\t var yDiff = p2.y - p1.y;\n\t var angle = d.util.deg(Math.atan2(yDiff, xDiff));\n\t return angle;\n\t }\n\n\t function createSegment(x, y) {\n\t return new d.Segment(new g.Point(x, y));\n\t }\n\n\t function toDrawingRect(rect) {\n\t if (rect) {\n\t return new g.Rect([rect.x, rect.y], [rect.width, rect.height]);\n\t }\n\t }\n\n\t // Exports ================================================================\n\t kendo.deepExtend(diagram, {\n\t init: function (element) {\n\t kendo.init(element, diagram.ui);\n\t },\n\t diffNumericOptions: diffNumericOptions,\n\t Element: Element,\n\t Scale: Scale,\n\t Translation: Translation,\n\t Rotation: Rotation,\n\t Circle: Circle,\n\t Group: Group,\n\t Rectangle: Rectangle,\n\t Canvas: Canvas,\n\t Path: Path,\n\t Layout: Layout,\n\t Line: Line,\n\t MarkerBase: MarkerBase,\n\t ArrowMarker: ArrowMarker,\n\t CircleMarker: CircleMarker,\n\t Polyline: Polyline,\n\t CompositeTransform: CompositeTransform,\n\t TextBlock: TextBlock,\n\t Image: Image,\n\t VisualBase: VisualBase\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(883);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 863:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.core\");\n\n/***/ }),\n\n/***/ 883:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(863) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t diagram = kendo.dataviz.diagram = {},\n\t deepExtend = kendo.deepExtend,\n\t isArray = $.isArray,\n\t EPSILON = 1e-06;\n\n\t /*-------------------Diverse utilities----------------------------*/\n\t var Utils = {\n\t };\n\n\t deepExtend(Utils, {\n\t isNearZero: function (num) {\n\t return Math.abs(num) < EPSILON;\n\t },\n\t isDefined: function (obj) {\n\t return typeof obj !== 'undefined';\n\t },\n\n\t isUndefined: function (obj) {\n\t return (typeof obj === 'undefined') || obj === null;\n\t },\n\t /**\n\t * Returns whether the given object is an object or a value.\n\t */\n\t isObject: function (obj) {\n\t return obj === Object(obj);\n\t },\n\t /**\n\t * Returns whether the object has a property with the given name.\n\t */\n\t has: function (obj, key) {\n\t return Object.hasOwnProperty.call(obj, key);\n\t },\n\t /**\n\t * Returns whether the given object is a string.\n\t */\n\t isString: function (obj) {\n\t return Object.prototype.toString.call(obj) == '[object String]';\n\t },\n\t isBoolean: function (obj) {\n\t return Object.prototype.toString.call(obj) == '[object Boolean]';\n\t },\n\t isType: function (obj, type) {\n\t return Object.prototype.toString.call(obj) == '[object ' + type + ']';\n\t },\n\t /**\n\t * Returns whether the given object is a number.\n\t */\n\t isNumber: function (obj) {\n\t return !isNaN(parseFloat(obj)) && isFinite(obj);\n\t },\n\t /**\n\t * Return whether the given object (array or dictionary).\n\t */\n\t isEmpty: function (obj) {\n\t if (obj === null) {\n\t return true;\n\t }\n\t if (isArray(obj) || Utils.isString(obj)) {\n\t return obj.length === 0;\n\t }\n\t for (var key in obj) {\n\t if (Utils.has(obj, key)) {\n\t return false;\n\t }\n\t }\n\t return true;\n\t },\n\t simpleExtend: function(destination, source) {\n\t if(!Utils.isObject(source)) {\n\t return;\n\t }\n\n\t for(var name in source) {\n\t destination[name] = source[name];\n\t }\n\t },\n\t /**\n\t * Returns an array of the specified size and with each entry set to the given value.\n\t * @param size\n\t * @param value\n\t * @returns {Array}\n\t */\n\t initArray: function createIdArray(size, value) {\n\t var array = [];\n\t for (var i = 0; i < size; ++i) {\n\t array[i] = value;\n\t }\n\t return array;\n\t },\n\t serializePoints: function (points) {\n\t var res = [];\n\t for (var i = 0; i < points.length; i++) {\n\t var p = points[i];\n\t res.push(p.x + \";\" + p.y);\n\t }\n\t return res.join(\";\");\n\t },\n\t deserializePoints: function (s) {\n\t var v = s.split(\";\"), points = [];\n\t if (v.length % 2 !== 0) {\n\t throw \"Not an array of points.\";\n\t }\n\t for (var i = 0; i < v.length; i += 2) {\n\t points.push(new diagram.Point(\n\t parseInt(v[i], 10),\n\t parseInt(v[i + 1], 10)\n\t ));\n\t }\n\t return points;\n\t },\n\t /**\n\t * Returns an integer within the given bounds.\n\t * @param lower The inclusive lower bound.\n\t * @param upper The exclusive upper bound.\n\t * @returns {number}\n\t */\n\t randomInteger: function (lower, upper) {\n\t return parseInt(Math.floor(Math.random() * upper) + lower, 10);\n\t } ,\n\t /*\n\t Depth-first traversal of the given node.\n\t */\n\t DFT: function (el, func) {\n\t func(el);\n\t if (el.childNodes) {\n\t for (var i = 0; i < el.childNodes.length; i++) {\n\t var item = el.childNodes[i];\n\t this.DFT(item, func);\n\t }\n\t }\n\t },\n\t /*\n\t Returns the angle in degrees for the given matrix\n\t */\n\t getMatrixAngle: function (m) {\n\t if (m === null || m.d === 0) {\n\t return 0;\n\t }\n\t return Math.atan2(m.b, m.d) * 180 / Math.PI;\n\t },\n\n\t /*\n\t Returns the scaling factors for the given matrix.\n\t */\n\t getMatrixScaling: function (m) {\n\t var sX = Math.sqrt(m.a * m.a + m.c * m.c);\n\t var sY = Math.sqrt(m.b * m.b + m.d * m.d);\n\t return [sX, sY];\n\t }\n\n\t });\n\n\t /**\n\t * The Range defines an array of equally separated numbers.\n\t * @param start The start-value of the Range.\n\t * @param stop The end-value of the Range.\n\t * @param step The separation between the values (default:1).\n\t * @returns {Array}\n\t */\n\t function Range(start, stop, step) {\n\t if (typeof start == 'undefined' || typeof stop == 'undefined') {\n\t return [];\n\t }\n\t if (step && Utils.sign(stop - start) != Utils.sign(step)) {\n\t throw \"The sign of the increment should allow to reach the stop-value.\";\n\t }\n\t step = step || 1;\n\t start = start || 0;\n\t stop = stop || start;\n\t if ((stop - start) / step === Infinity) {\n\t throw \"Infinite range defined.\";\n\t }\n\t var range = [], i = -1, j;\n\n\t function rangeIntegerScale(x) {\n\t var k = 1;\n\t while (x * k % 1) {\n\t k *= 10;\n\t }\n\t return k;\n\t }\n\n\t var k = rangeIntegerScale(Math.abs(step));\n\t start *= k;\n\t stop *= k;\n\t step *= k;\n\t if (start > stop && step > 0) {\n\t step = -step;\n\t }\n\t if (step < 0) {\n\t while ((j = start + step * ++i) >= stop) {\n\t range.push(j / k);\n\t }\n\t }\n\t else {\n\t while ((j = start + step * ++i) <= stop) {\n\t range.push(j / k);\n\t }\n\t }\n\t return range;\n\t }\n\n\t /*-------------------Diverse math functions----------------------------*/\n\n\t function findRadian(start, end) {\n\t if (start == end) {\n\t return 0;\n\t }\n\t var sngXComp = end.x - start.x,\n\t sngYComp = start.y - end.y,\n\t atan = Math.atan(sngXComp / sngYComp);\n\t if (sngYComp >= 0) {\n\t return sngXComp < 0 ? atan + (2 * Math.PI) : atan;\n\t }\n\t return atan + Math.PI;\n\t }\n\n\t Utils.sign = function(number) {\n\t return number ? number < 0 ? -1 : 1 : 0;\n\t };\n\n\t Utils.findAngle = function(center, end) {\n\t return findRadian(center, end) * 180 / Math.PI;\n\t };\n\n\t /*-------------------Array Helpers ----------------------------*/\n\n\t Utils.forEach = function(arr, iterator, thisRef) {\n\t for (var i = 0; i < arr.length; i++) {\n\t iterator.call(thisRef, arr[i], i, arr);\n\t }\n\t };\n\n\t Utils.any = function(arr, predicate) {\n\t for (var i = 0; i < arr.length; ++i) {\n\t if (predicate(arr[i])) {\n\t return arr[i];\n\t }\n\t }\n\t return null;\n\t };\n\n\t Utils.remove = function (arr, what) {\n\t var ax;\n\t while ((ax = Utils.indexOf(arr, what)) !== -1) {\n\t arr.splice(ax, 1);\n\t }\n\t return arr;\n\t };\n\n\t Utils.contains = function (arr, obj) {\n\t return Utils.indexOf(arr, obj) !== -1;\n\t };\n\n\t Utils.indexOf = function(arr, what) {\n\t return $.inArray(what, arr);\n\t };\n\n\t Utils.fold = function (list, iterator, acc, context) {\n\t var initial = arguments.length > 2;\n\n\t for (var i = 0; i < list.length; i++) {\n\t var value = list[i];\n\t if (!initial) {\n\t acc = value;\n\t initial = true;\n\t }\n\t else {\n\t acc = iterator.call(context, acc, value, i, list);\n\t }\n\t }\n\n\t if (!initial) {\n\t throw 'Reduce of empty array with no initial value';\n\t }\n\n\t return acc;\n\t };\n\n\t Utils.find = function (arr, iterator, context) {\n\t var result;\n\t Utils.any(arr, function (value, index, list) {\n\t if (iterator.call(context, value, index, list)) {\n\t result = value;\n\t return true;\n\t }\n\t return false;\n\t });\n\t return result;\n\t };\n\n\t Utils.first = function (arr, constraint, context) {\n\t if (arr.length === 0) {\n\t return null;\n\t }\n\t if (Utils.isUndefined(constraint)) {\n\t return arr[0];\n\t }\n\n\t return Utils.find(arr, constraint, context);\n\t };\n\n\t /**\n\t * Inserts the given element at the specified position and returns the result.\n\t */\n\t Utils.insert = function (arr, element, position) {\n\t arr.splice(position, 0, element);\n\t return arr;\n\t };\n\n\t Utils.all = function (arr, iterator, context) {\n\t var result = true;\n\t var value;\n\n\t for (var i = 0; i < arr.length; i++) {\n\t value = arr[i];\n\t result = result && iterator.call(context, value, i, arr);\n\n\t if (!result) {\n\t break;\n\t }\n\t }\n\n\t return result;\n\t };\n\n\t Utils.clear = function (arr) {\n\t arr.splice(0, arr.length);\n\t };\n\n\t /**\n\t * Sort the arrays on the basis of the first one (considered as keys and the other array as values).\n\t * @param a\n\t * @param b\n\t * @param sortfunc (optiona) sorting function for the values in the first array\n\t */\n\t Utils.bisort = function (a, b, sortfunc) {\n\t if (Utils.isUndefined(a)) {\n\t throw \"First array is not specified.\";\n\t }\n\t if (Utils.isUndefined(b)) {\n\t throw \"Second array is not specified.\";\n\t }\n\t if (a.length != b.length) {\n\t throw \"The two arrays should have equal length\";\n\t }\n\n\t var all = [], i;\n\n\t for (i = 0; i < a.length; i++) {\n\t all.push({ 'x': a[i], 'y': b[i] });\n\t }\n\t if (Utils.isUndefined(sortfunc)) {\n\t all.sort(function (m, n) {\n\t return m.x - n.x;\n\t });\n\t }\n\t else {\n\t all.sort(function (m, n) {\n\t return sortfunc(m.x, n.x);\n\t });\n\t }\n\n\t Utils.clear(a);\n\t Utils.clear(b);\n\n\t for (i = 0; i < all.length; i++) {\n\t a.push(all[i].x);\n\t b.push(all[i].y);\n\t }\n\t };\n\n\t Utils.addRange = function (arr, range) {\n\t arr.push.apply(arr, range);\n\t };\n\n\t var Easing = {\n\t easeInOut: function (pos) {\n\t return ((-Math.cos(pos * Math.PI) / 2) + 0.5);\n\t }\n\t };\n\n\t /**\n\t * An animation ticker driving an adapter which sets a particular\n\t * property in function of the tick.\n\t * @type {*}\n\t */\n\t var Ticker = kendo.Class.extend({\n\t init: function () {\n\t this.adapters = [];\n\t this.target = 0;\n\t this.tick = 0;\n\t this.interval = 20;\n\t this.duration = 800;\n\t this.lastTime = null;\n\t this.handlers = [];\n\t var _this = this;\n\t this.transition = Easing.easeInOut;\n\t this.timerDelegate = function () {\n\t _this.onTimerEvent();\n\t };\n\t },\n\t addAdapter: function (a) {\n\t this.adapters.push(a);\n\t },\n\t onComplete: function (handler) {\n\t this.handlers.push(handler);\n\t },\n\t removeHandler: function (handler) {\n\t this.handlers = $.grep(this.handlers, function (h) {\n\t return h !== handler;\n\t });\n\t },\n\t trigger: function () {\n\t var _this = this;\n\t if (this.handlers) {\n\t Utils.forEach(this.handlers, function (h) {\n\t return h.call(_this.caller !== null ? _this.caller : _this);\n\t });\n\t }\n\t },\n\t onStep: function () {\n\t },\n\t seekTo: function (to) {\n\t this.seekFromTo(this.tick, to);\n\t },\n\t seekFromTo: function (from, to) {\n\t this.target = Math.max(0, Math.min(1, to));\n\t this.tick = Math.max(0, Math.min(1, from));\n\t this.lastTime = new Date().getTime();\n\t if (!this.intervalId) {\n\t this.intervalId = window.setInterval(this.timerDelegate, this.interval);\n\t }\n\t },\n\t stop: function () {\n\t if (this.intervalId) {\n\t window.clearInterval(this.intervalId);\n\t this.intervalId = null;\n\n\t //this.trigger.call(this);\n\t this.trigger();\n\t // this.next();\n\t }\n\t },\n\t play: function (origin) {\n\t if (this.adapters.length === 0) {\n\t return;\n\t }\n\t if (origin !== null) {\n\t this.caller = origin;\n\t }\n\t this.initState();\n\t this.seekFromTo(0, 1);\n\t },\n\t reverse: function () {\n\t this.seekFromTo(1, 0);\n\t },\n\t initState: function () {\n\t if (this.adapters.length === 0) {\n\t return;\n\t }\n\t for (var i = 0; i < this.adapters.length; i++) {\n\t this.adapters[i].initState();\n\t }\n\t },\n\t propagate: function () {\n\t var value = this.transition(this.tick);\n\n\t for (var i = 0; i < this.adapters.length; i++) {\n\t this.adapters[i].update(value);\n\t }\n\t },\n\t onTimerEvent: function () {\n\t var now = new Date().getTime();\n\t var timePassed = now - this.lastTime;\n\t this.lastTime = now;\n\t var movement = (timePassed / this.duration) * (this.tick < this.target ? 1 : -1);\n\t if (Math.abs(movement) >= Math.abs(this.tick - this.target)) {\n\t this.tick = this.target;\n\t } else {\n\t this.tick += movement;\n\t }\n\n\t try {\n\t this.propagate();\n\t } finally {\n\t this.onStep.call(this);\n\t if (this.target == this.tick) {\n\t this.stop();\n\t }\n\t }\n\t }\n\t });\n\n\t kendo.deepExtend(diagram, {\n\t init: function (element) {\n\t kendo.init(element, diagram.ui);\n\t },\n\n\t Utils: Utils,\n\t Range: Range,\n\t Ticker: Ticker\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(884);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 858:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 860:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.drawing\");\n\n/***/ }),\n\n/***/ 863:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.core\");\n\n/***/ }),\n\n/***/ 864:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.color\");\n\n/***/ }),\n\n/***/ 884:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/***********************************************************************\n\t * WARNING: this file is auto-generated. If you change it directly,\n\t * your modifications will eventually be lost. The source code is in\n\t * `kendo-charts` repository, you should make your changes there and\n\t * run `src-modules/sync.sh` in this repository.\n\t */\n\t(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(863),\n\t __webpack_require__(864),\n\t __webpack_require__(860),\n\t __webpack_require__(858)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\twindow.kendo.dataviz = window.kendo.dataviz || {};\n\tvar dataviz = kendo.dataviz;\n\tvar getSpacing = dataviz.getSpacing;\n\tvar defined = dataviz.defined;\n\tvar constants = dataviz.constants;\n\tvar BLACK = constants.BLACK;\n\tvar COORD_PRECISION = constants.COORD_PRECISION;\n\tvar services = dataviz.services;\n\tvar deepExtend = dataviz.deepExtend;\n\tvar isArray = dataviz.isArray;\n\tvar setDefaultOptions = dataviz.setDefaultOptions;\n\tvar NumericAxis = dataviz.NumericAxis;\n\tvar limitValue = dataviz.limitValue;\n\tvar Box = dataviz.Box;\n\tvar interpolateValue = dataviz.interpolateValue;\n\tvar round = dataviz.round;\n\tvar drawing = kendo.drawing;\n\tvar DrawingGroup = drawing.Group;\n\tvar DrawingPath = drawing.Path;\n\tvar Animation = drawing.Animation;\n\tvar AnimationFactory = drawing.AnimationFactory;\n\tvar geometry = kendo.geometry;\n\tvar Rect = geometry.Rect;\n\tvar GeometryPoint = geometry.Point;\n\tvar transform = geometry.transform;\n\n\tvar ANGULAR_SPEED = 150;\n\tvar LINEAR_SPEED = 250;\n\tvar ARROW = \"arrow\";\n\tvar ARROW_POINTER = \"arrowPointer\";\n\tvar BAR_POINTER = \"barPointer\";\n\tvar DEFAULT_HEIGHT = 200;\n\tvar DEFAULT_LINE_WIDTH = 0.5;\n\tvar DEFAULT_WIDTH = 200;\n\tvar DEGREE = Math.PI / 180;\n\tvar INSIDE = \"inside\";\n\tvar LINEAR = \"linear\";\n\tvar OUTSIDE = \"outside\";\n\tvar RADIAL_POINTER = \"radialPointer\";\n\tvar RADIAL_RANGE_POINTER = \"radialRangePointer\";\n\n\tfunction pad(bbox, value) {\n\t var origin = bbox.getOrigin();\n\t var size = bbox.getSize();\n\t var spacing = getSpacing(value);\n\n\t bbox.setOrigin([ origin.x - spacing.left, origin.y - spacing.top ]);\n\t bbox.setSize([ size.width + (spacing.left + spacing.right), size.height + (spacing.top + spacing.bottom) ]);\n\n\t return bbox;\n\t}\n\n\tvar Group = DrawingGroup;\n\tvar Path$1 = DrawingPath;\n\tvar Text = drawing.Text;\n\n\tfunction buildLabelElement(label, options) {\n\t var labelBox = label.box;\n\t var textBox = label.children[0].box;\n\t var border = options.border || {};\n\t var background = options.background || \"\";\n\n\t var wrapper = Path$1.fromRect(new Rect([ labelBox.x1, labelBox.y1 ], [ labelBox.width(), labelBox.height() ]), {\n\t stroke: {}\n\t });\n\n\t var text = new Text(label.text, new GeometryPoint(textBox.x1, textBox.y1), {\n\t font: options.font,\n\t fill: { color: options.color }\n\t });\n\n\t var styleGeometry = pad(text.bbox().clone(), options.padding);\n\n\t var styleBox = Path$1.fromRect(styleGeometry, {\n\t stroke: {\n\t color: border.width ? border.color : \"\",\n\t width: border.width,\n\t opacity: border.opacity,\n\t dashType: border.dashType,\n\t lineJoin: \"round\",\n\t lineCap: \"round\"\n\t },\n\t fill: {\n\t color: background\n\t }\n\t });\n\n\t var elements = new Group();\n\t elements.append(wrapper);\n\t elements.append(styleBox);\n\t elements.append(text);\n\n\t return elements;\n\t}\n\n\tfunction getRange(range, min, max) {\n\t var from = defined(range.from) ? range.from : constants.MIN_VALUE;\n\t var to = defined(range.to) ? range.to : constants.MAX_VALUE;\n\n\t range.from = Math.max(Math.min(to, from), min);\n\t range.to = Math.min(Math.max(to, from), max);\n\n\t return range;\n\t}\n\n\tfunction unpad(bbox, value) {\n\t var spacing = getSpacing(value);\n\n\t spacing.left = -spacing.left; spacing.top = -spacing.top;\n\t spacing.right = -spacing.right; spacing.bottom = -spacing.bottom;\n\n\t return pad(bbox, spacing);\n\t}\n\n\tvar DEFAULT_MARGIN = 5;\n\tvar Path = DrawingPath;\n\tvar Surface = drawing.Surface;\n\n\tvar Gauge = dataviz.Class.extend({\n\t init: function(element, userOptions, theme, context) {\n\t if (context === void 0) { context = {}; }\n\n\t this.element = element;\n\t this.theme = theme;\n\t this.contextService = new services.ChartService(this, context);\n\t this._originalOptions = deepExtend({}, this.options, userOptions);\n\t this.options = deepExtend({}, this._originalOptions);\n\t this._initTheme(theme);\n\n\t this.redraw();\n\t },\n\n\t destroy: function() {\n\t if (this.surface) {\n\t this.surface.destroy();\n\t this.surface = null;\n\t }\n\n\t delete this.element;\n\t delete this.surfaceElement;\n\t },\n\n\t value: function(pointerValue) {\n\t var pointer = this.pointers[0];\n\n\t if (arguments.length === 0) {\n\t return pointer.value();\n\t }\n\n\t pointer.value(pointerValue);\n\t this._setValueOptions(pointerValue);\n\t },\n\n\t _draw: function() {\n\t var surface = this.surface;\n\n\t surface.clear();\n\t surface.draw(this._visuals);\n\t },\n\n\t exportVisual: function() {\n\t return this._visuals;\n\t },\n\n\t allValues: function(values) {\n\t var pointers = this.pointers;\n\t var allValues = [];\n\n\t if (arguments.length === 0) {\n\t for (var i = 0; i < pointers.length; i++) {\n\t allValues.push(pointers[i].value());\n\t }\n\n\t return allValues;\n\t }\n\n\t if (isArray(values)) {\n\t for (var i$1 = 0; i$1 < values.length; i$1++) {\n\t if (dataviz.isNumber(values[i$1])) {\n\t pointers[i$1].value(values[i$1]);\n\t }\n\t }\n\t }\n\n\t this._setValueOptions(values);\n\t },\n\n\t _setValueOptions: function(values) {\n\t var pointers = [].concat(this.options.pointer);\n\t var arrayValues = [].concat(values);\n\n\t for (var i = 0; i < arrayValues.length; i++) {\n\t pointers[i].value = arrayValues[i];\n\t }\n\t },\n\n\t resize: function() {\n\t this.noTransitionsRedraw();\n\t },\n\n\t noTransitionsRedraw: function() {\n\t var transitions = this.options.transitions;\n\n\t this._toggleTransitions(false);\n\n\t this.redraw();\n\n\t this._toggleTransitions(transitions);\n\t },\n\n\t redraw: function() {\n\t var size = this._surfaceSize();\n\t var wrapper = new Rect([ 0, 0 ], [ size.width, size.height ]);\n\n\t this._initSurface();\n\n\t this.gaugeArea = this._createGaugeArea();\n\n\t this._createModel();\n\n\t var bbox = unpad(wrapper.bbox(), this._gaugeAreaMargin);\n\t this.reflow(bbox);\n\t },\n\n\t setOptions: function(options, theme) {\n\t this._originalOptions = deepExtend(this._originalOptions, options);\n\t this.options = deepExtend({}, this._originalOptions);\n\n\t this._initTheme(theme);\n\n\t this.redraw();\n\t },\n\n\t setDirection: function(rtl) {\n\t this.contextService.rtl = Boolean(rtl);\n\t if (this.surface && this.surface.type === 'svg') {\n\t this.surface.destroy();\n\t this.surface = null;\n\t }\n\t },\n\n\t setIntlService: function(intl) {\n\t this.contextService.intl = intl;\n\t },\n\n\t _initTheme: function(theme) {\n\t var currentTheme = theme || this.theme || {};\n\t this.theme = currentTheme;\n\n\t this.options = deepExtend({}, currentTheme, this.options);\n\t var options = this.options;\n\t var pointer = options.pointer;\n\n\t if (isArray(pointer)) {\n\t var pointers = [];\n\t for (var i = 0; i < pointer.length; i++) {\n\t pointers.push(deepExtend({}, currentTheme.pointer, pointer[i]));\n\t }\n\t options.pointer = pointers;\n\t }\n\t },\n\n\t _createGaugeArea: function() {\n\t var options = this.options.gaugeArea;\n\t var size = this.surface.size();\n\t var border = options.border || {};\n\t var areaGeometry = new Rect([ 0, 0 ], [ size.width, size.height ]);\n\n\t this._gaugeAreaMargin = options.margin || DEFAULT_MARGIN;\n\n\t if (border.width > 0) {\n\t areaGeometry = unpad(areaGeometry, border.width);\n\t }\n\n\t var gaugeArea = Path.fromRect(areaGeometry, {\n\t stroke: {\n\t color: border.width ? border.color : \"\",\n\t width: border.width,\n\t dashType: border.dashType,\n\t lineJoin: \"round\",\n\t lineCap: \"round\"\n\t },\n\t fill: {\n\t color: options.background\n\t }\n\t });\n\n\t return gaugeArea;\n\t },\n\n\t _initSurface: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var surface = ref.surface;\n\t var element = this._surfaceElement();\n\t var size = this._surfaceSize();\n\n\t dataviz.elementSize(element, size);\n\n\t if (!surface || surface.options.type !== options.renderAs) {\n\t if (surface) {\n\t surface.destroy();\n\t }\n\n\t this.surface = Surface.create(element, {\n\t type: options.renderAs\n\t });\n\t } else {\n\t this.surface.clear();\n\t this.surface.resize();\n\t }\n\t },\n\n\t _surfaceSize: function() {\n\t var options = this.options;\n\t var size = this._getSize();\n\n\t if (options.gaugeArea) {\n\t deepExtend(size, options.gaugeArea);\n\t }\n\n\t return size;\n\t },\n\n\t _surfaceElement: function() {\n\t if (!this.surfaceElement) {\n\t this.surfaceElement = document.createElement('div');\n\t this.element.appendChild(this.surfaceElement);\n\t }\n\n\t return this.surfaceElement;\n\t },\n\n\t getSize: function() {\n\t return this._getSize();\n\t },\n\n\t _getSize: function() {\n\t var element = this.element;\n\t var defaultSize = this._defaultSize();\n\t var width = element.offsetWidth;\n\t var height = element.offsetHeight;\n\n\t if (!width) {\n\t width = defaultSize.width;\n\t }\n\n\t if (!height) {\n\t height = defaultSize.height;\n\t }\n\n\t return { width: width, height: height };\n\t },\n\n\t _defaultSize: function() {\n\t return {\n\t width: DEFAULT_WIDTH,\n\t height: DEFAULT_HEIGHT\n\t };\n\t },\n\n\t _toggleTransitions: function(value) {\n\t var this$1 = this;\n\n\t this.options.transitions = value;\n\t for (var i = 0; i < this.pointers.length; i++) {\n\t this$1.pointers[i].options.animation.transitions = value;\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(Gauge, {\n\t plotArea: {},\n\t theme: \"default\",\n\t renderAs: \"\",\n\t pointer: {},\n\t scale: {},\n\t gaugeArea: {}\n\t});\n\n\tvar Path$2 = DrawingPath;\n\tvar Group$2 = DrawingGroup;\n\tvar Point = GeometryPoint;\n\n\tfunction renderAxisTick(tickRenderOptions, tickOptions) {\n\t var position = tickRenderOptions.position;\n\t var tickX = tickRenderOptions.tickX;\n\t var tickY = tickRenderOptions.tickY;\n\t var start, end;\n\n\t if (tickRenderOptions.vertical) {\n\t start = new Point(tickX, position);\n\t end = new Point(tickX + tickOptions.size, position);\n\t } else {\n\t start = new Point(position, tickY);\n\t end = new Point(position, tickY + tickOptions.size);\n\t }\n\n\t var tickPath = new Path$2({\n\t stroke: {\n\t color: tickOptions.color,\n\t width: tickOptions.width\n\t }\n\t }).moveTo(start).lineTo(end);\n\n\t return tickPath;\n\t}\n\n\tfunction renderTicks(tickGroup, tickPositions, tickRenderOptions, tickOptions) {\n\t var count = tickPositions.length;\n\n\t if (tickOptions.visible) {\n\t var mirror = tickRenderOptions.mirror;\n\t var lineBox = tickRenderOptions.lineBox;\n\t for (var i = tickOptions.skip; i < count; i += tickOptions.step) {\n\t if (i % tickOptions.skipUnit === 0) {\n\t continue;\n\t }\n\n\t tickRenderOptions.tickX = mirror ? lineBox.x2 : lineBox.x2 - tickOptions.size;\n\t tickRenderOptions.tickY = mirror ? lineBox.y1 - tickOptions.size : lineBox.y1;\n\t tickRenderOptions.position = tickPositions[i];\n\n\t tickGroup.append(renderAxisTick(tickRenderOptions, tickOptions));\n\t }\n\t }\n\t}\n\n\tvar LinearScale = NumericAxis.extend({\n\t init: function(options, service) {\n\t var scaleOptions = options || {};\n\t if (!defined(scaleOptions.reverse) && scaleOptions.vertical === false && (service || {}).rtl) {\n\t scaleOptions = $.extend({}, scaleOptions, {\n\t reverse: true\n\t });\n\t }\n\n\t NumericAxis.fn.init.call(this, 0, 1, scaleOptions, service);\n\n\t this.options.minorUnit = this.options.minorUnit || this.options.majorUnit / 10;\n\t },\n\n\t initUserOptions: function(options) {\n\t var scaleOptions = deepExtend({}, this.options, options);\n\t scaleOptions = deepExtend({}, scaleOptions , { labels: { mirror: scaleOptions.mirror } });\n\t scaleOptions.majorUnit = scaleOptions.majorUnit || dataviz.autoMajorUnit(scaleOptions.min, scaleOptions.max);\n\n\t return scaleOptions;\n\t },\n\n\t initFields: function() {\n\t },\n\n\t render: function() {\n\t var elements = this.elements = new Group$2();\n\t var labels = this.renderLabels();\n\t var scaleLine = this.renderLine();\n\t var scaleTicks = this.renderTicks();\n\t var ranges = this.renderRanges();\n\n\t elements.append(scaleLine, labels, scaleTicks, ranges);\n\n\t return elements;\n\t },\n\n\t renderRanges: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var min = options.min;\n\t var max = options.max;\n\t var vertical = options.vertical;\n\t var mirror = options.labels.mirror;\n\t var ranges = options.ranges || [];\n\t var elements = new Group$2();\n\t var count = ranges.length;\n\t var rangeSize = options.rangeSize || options.minorTicks.size / 2;\n\n\t for (var i = 0; i < count; i++) {\n\t var range = getRange(ranges[i], min, max);\n\t var slot = this$1.getSlot(range.from, range.to);\n\t var slotX = vertical ? this$1.lineBox() : slot;\n\t var slotY = vertical ? slot : this$1.lineBox();\n\t if (vertical) {\n\t slotX.x1 -= rangeSize * (mirror ? -1 : 1);\n\t } else {\n\t slotY.y2 += rangeSize * (mirror ? -1 : 1);\n\t }\n\n\t elements.append(Path$2.fromRect(new Rect([ slotX.x1, slotY.y1 ], [ slotX.x2 - slotX.x1, slotY.y2 - slotY.y1 ]), {\n\t fill: { color: range.color, opacity: range.opacity },\n\t stroke: { }\n\t }));\n\t }\n\n\t return elements;\n\t },\n\n\t renderLabels: function() {\n\t var ref = this;\n\t var labels = ref.labels;\n\t var options = ref.options;\n\t var elements = new Group$2();\n\n\t for (var i = 0; i < labels.length; i++) {\n\t elements.append(buildLabelElement(labels[i], options.labels));\n\t }\n\n\t return elements;\n\t },\n\n\t renderLine: function() {\n\t var line = this.options.line;\n\t var lineBox = this.lineBox();\n\t var elements = new Group$2();\n\n\t if (line.width > 0 && line.visible) {\n\t var linePath = new Path$2({\n\t stroke: {\n\t color: line.color,\n\t dashType: line.dashType,\n\t width: line.width\n\t }\n\t });\n\n\t linePath.moveTo(lineBox.x1, lineBox.y1).lineTo(lineBox.x2, lineBox.y2);\n\t elements.append(linePath);\n\t }\n\n\t return elements;\n\t },\n\n\t renderTicks: function() {\n\t var ticks = new Group$2();\n\t var options = this.options;\n\t var majorUnit = options.majorTicks.visible ? options.majorUnit : 0;\n\t var tickRenderOptions = {\n\t vertical: options.vertical,\n\t mirror: options.labels.mirror,\n\t lineBox: this.lineBox()\n\t };\n\n\t renderTicks(ticks, this.getMajorTickPositions(), tickRenderOptions, options.majorTicks);\n\t renderTicks(ticks, this.getMinorTickPositions(), tickRenderOptions, deepExtend({}, {\n\t skipUnit: majorUnit / options.minorUnit\n\t }, options.minorTicks));\n\n\t return ticks;\n\t }\n\t});\n\n\tsetDefaultOptions(LinearScale, {\n\t min: 0,\n\t max: 50,\n\n\t majorTicks: {\n\t size: 15,\n\t align: INSIDE,\n\t color: BLACK,\n\t width: DEFAULT_LINE_WIDTH,\n\t visible: true\n\t },\n\n\t minorTicks: {\n\t size: 10,\n\t align: INSIDE,\n\t color: BLACK,\n\t width: DEFAULT_LINE_WIDTH,\n\t visible: true\n\t },\n\n\t line: {\n\t width: DEFAULT_LINE_WIDTH\n\t },\n\n\t labels: {\n\t position: INSIDE,\n\t padding: 2\n\t },\n\t mirror: false,\n\t _alignLines: false\n\t});\n\n\tvar Pointer = dataviz.Class.extend({\n\t init: function(scale, userOptions) {\n\n\t var ref = scale.options;\n\t var min = ref.min;\n\t var max = ref.max;\n\t var options = this.options = deepExtend({}, this.options, userOptions);\n\n\t options.fill = options.color;\n\n\t this.scale = scale;\n\n\t if (defined(options.value)) {\n\t options.value = limitValue(options.value, min, max);\n\t } else {\n\t options.value = min;\n\t }\n\t },\n\n\t value: function(newValue) {\n\t var options = this.options;\n\t var value = options.value;\n\n\t if (arguments.length === 0) {\n\t return value;\n\t }\n\n\t var ref = this.scale.options;\n\t var min = ref.min;\n\t var max = ref.max;\n\n\t options._oldValue = defined(options._oldValue) ? options.value : min;\n\t options.value = limitValue(newValue, min, max);\n\n\t if (this.elements) {\n\t this.repaint();\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(Pointer, {\n\t color: BLACK\n\t});\n\n\tvar LinearPointer = Pointer.extend({\n\t init: function(scale, options) {\n\t Pointer.fn.init.call(this, scale, options);\n\n\t this.options = deepExtend({\n\t track: {\n\t visible: defined(options.track)\n\t }\n\t }, this.options);\n\t },\n\n\t reflow: function() {\n\t var ref = this;\n\t var options = ref.options;\n\t var scale = ref.scale;\n\t var ref$1 = scale.options;\n\t var mirror = ref$1.mirror;\n\t var vertical = ref$1.vertical;\n\t var scaleLine = scale.lineBox();\n\t var trackSize = options.track.size || options.size;\n\t var pointerHalfSize = options.size / 2;\n\t var margin = getSpacing(options.margin);\n\t var space = vertical ?\n\t margin[mirror ? \"left\" : \"right\"] :\n\t margin[mirror ? \"bottom\" : \"top\"];\n\t var pointerBox, pointerRangeBox, trackBox;\n\n\t space = mirror ? -space : space;\n\n\t if (vertical) {\n\t trackBox = new Box(\n\t scaleLine.x1 + space, scaleLine.y1,\n\t scaleLine.x1 + space, scaleLine.y2);\n\n\t if (mirror) {\n\t trackBox.x1 -= trackSize;\n\t } else {\n\t trackBox.x2 += trackSize;\n\t }\n\n\t if (options.shape !== BAR_POINTER) {\n\t pointerRangeBox = new Box(\n\t scaleLine.x2 + space, scaleLine.y1 - pointerHalfSize,\n\t scaleLine.x2 + space, scaleLine.y2 + pointerHalfSize\n\t );\n\t pointerBox = pointerRangeBox;\n\t }\n\t } else {\n\t trackBox = new Box(\n\t scaleLine.x1, scaleLine.y1 - space,\n\t scaleLine.x2, scaleLine.y1 - space);\n\n\t if (mirror) {\n\t trackBox.y2 += trackSize;\n\t } else {\n\t trackBox.y1 -= trackSize;\n\t }\n\n\t if (options.shape !== BAR_POINTER) {\n\t pointerRangeBox = new Box(\n\t scaleLine.x1 - pointerHalfSize, scaleLine.y1 - space,\n\t scaleLine.x2 + pointerHalfSize, scaleLine.y1 - space\n\t );\n\t pointerBox = pointerRangeBox;\n\t }\n\t }\n\n\t this.trackBox = trackBox;\n\t this.pointerRangeBox = pointerRangeBox;\n\t this.box = pointerBox || trackBox.clone().pad(options.border.width);\n\t },\n\n\t getElementOptions: function() {\n\t var options = this.options;\n\n\t return {\n\t fill: {\n\t color: options.color,\n\t opacity: options.opacity\n\t },\n\t stroke: defined(options.border) ? {\n\t color: options.border.width ? options.border.color || options.color : \"\",\n\t width: options.border.width,\n\t dashType: options.border.dashType,\n\t opacity: options.opacity\n\t } : null\n\t };\n\t },\n\n\t _margin: function() {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var options = ref.options;\n\t var ref$1 = scale.options;\n\t var mirror = ref$1.mirror;\n\t var vertical = ref$1.vertical;\n\t var margin = getSpacing(options.margin);\n\n\t var space = vertical ?\n\t margin[mirror ? \"left\" : \"right\"] :\n\t margin[mirror ? \"bottom\" : \"top\"];\n\n\t return space;\n\t }\n\t});\n\n\tsetDefaultOptions(LinearPointer, {\n\t shape: BAR_POINTER,\n\n\t track: {\n\t border: {\n\t width: 1\n\t }\n\t },\n\n\t color: BLACK,\n\t border: {\n\t width: 1\n\t },\n\t opacity: 1,\n\n\t margin: getSpacing(3),\n\t animation: {\n\t type: BAR_POINTER\n\t },\n\t visible: true\n\t});\n\n\tvar ArrowLinearPointerAnimation = Animation.extend({\n\t setup: function() {\n\t var options = this.options;\n\t var margin = options.margin;\n\t var from = options.from;\n\t var to = options.to;\n\t var vertical = options.vertical;\n\t var axis = vertical ? \"x1\" : \"y1\";\n\n\t if (options.mirror === vertical) {\n\t from[axis] -= margin; to[axis] -= margin;\n\t } else {\n\t from[axis] += margin; to[axis] += margin;\n\t }\n\n\t var fromScale = this.fromScale = new GeometryPoint(from.x1, from.y1);\n\t var toScale = this.toScale = new GeometryPoint(to.x1, to.y1);\n\n\t if (options.duration !== 0) {\n\t options.duration = Math.max((fromScale.distanceTo(toScale) / options.duration) * 1000, 1);\n\t }\n\t },\n\n\t step: function(pos) {\n\t var translateX = interpolateValue(this.fromScale.x, this.toScale.x, pos);\n\t var translateY = interpolateValue(this.fromScale.y, this.toScale.y, pos);\n\n\t this.element.transform(transform().translate(translateX, translateY));\n\t }\n\t});\n\n\tsetDefaultOptions(ArrowLinearPointerAnimation, {\n\t easing: LINEAR,\n\t duration: LINEAR_SPEED\n\t});\n\n\tAnimationFactory.current.register(ARROW_POINTER, ArrowLinearPointerAnimation);\n\n\tvar Point$1 = GeometryPoint;\n\tvar Path$3 = DrawingPath;\n\n\tvar ArrowLinearPointer = LinearPointer.extend({\n\t init: function(scale, options) {\n\t LinearPointer.fn.init.call(this, scale, options);\n\n\t if (!defined(this.options.size)) {\n\t this.options.size = this.scale.options.majorTicks.size * 0.6;\n\t }\n\t },\n\n\t pointerShape: function() {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var size = ref.options.size;\n\t var halfSize = size / 2;\n\t var sign = (scale.options.mirror ? -1 : 1);\n\t var shape;\n\n\t if (scale.options.vertical) {\n\t shape = [\n\t new Point$1(0, 0 - halfSize), new Point$1(0 - sign * size, 0), new Point$1(0, 0 + halfSize)\n\t ];\n\t } else {\n\t shape = [\n\t new Point$1(0 - halfSize, 0), new Point$1(0, 0 + sign * size), new Point$1(0 + halfSize, 0)\n\t ];\n\t }\n\n\t return shape;\n\t },\n\n\t repaint: function() {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var options = ref.options;\n\t var animation = new ArrowLinearPointerAnimation(this.elements, deepExtend(options.animation, {\n\t vertical: scale.options.vertical,\n\t mirror: scale.options.mirror,\n\t margin: this._margin(options.margin),\n\t from: scale.getSlot(options._oldValue),\n\t to: scale.getSlot(options.value)\n\t }));\n\n\t if (options.animation.transitions === false) {\n\t animation.options.duration = 0;\n\t }\n\n\t animation.setup();\n\t animation.play();\n\t },\n\n\t render: function() {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var options = ref.options;\n\t var elementOptions = this.getElementOptions();\n\t var shape = this.pointerShape(options.value);\n\n\t options.animation.type = ARROW_POINTER;\n\n\t var elements = new Path$3({\n\t stroke: elementOptions.stroke,\n\t fill: elementOptions.fill\n\t }).moveTo(shape[0]).lineTo(shape[1]).lineTo(shape[2]).close();\n\n\t var slot = scale.getSlot(options.value);\n\t elements.transform(transform().translate(slot.x1, slot.y1));\n\n\t this.elements = elements;\n\n\t return elements;\n\t }\n\t});\n\n\tvar BarLinearPointerAnimation = Animation.extend({\n\t setup: function() {\n\t var options = this.options;\n\t var axis = this.axis = options.vertical ? constants.Y : constants.X;\n\t var to = this.to = options.newPoints[0][axis];\n\t var from = this.from = options.oldPoints[0][axis];\n\n\t if (options.duration !== 0) {\n\t options.duration = Math.max((Math.abs(to - from) / options.speed) * 1000, 1);\n\t }\n\n\t this._set(from);\n\t },\n\n\t step: function(pos) {\n\t var value = interpolateValue(this.from, this.to, pos);\n\t this._set(value);\n\t },\n\n\t _set: function(value) {\n\t var setter = \"set\" + this.axis.toUpperCase();\n\t var points = this.options.newPoints;\n\n\t points[0][setter](value);\n\t points[1][setter](value);\n\t }\n\t});\n\n\tsetDefaultOptions(BarLinearPointerAnimation, {\n\t easing: LINEAR,\n\t speed: LINEAR_SPEED\n\t});\n\n\tAnimationFactory.current.register(BAR_POINTER, BarLinearPointerAnimation);\n\n\tvar Group$3 = DrawingGroup;\n\tvar Path$4 = DrawingPath;\n\n\tvar BarLinearPointer = LinearPointer.extend({\n\t init: function(scale, options) {\n\t LinearPointer.fn.init.call(this, scale, options);\n\n\t if (!defined(this.options.size)) {\n\t this.options.size = this.scale.options.majorTicks.size * 0.3;\n\t }\n\t },\n\n\t pointerShape: function(value) {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var options = ref.options;\n\t var ref$1 = scale.options;\n\t var mirror = ref$1.mirror;\n\t var vertical = ref$1.vertical;\n\t var dir = mirror === vertical ? -1 : 1;\n\t var size = options.size * dir;\n\t var minSlot = scale.getSlot(scale.options.min);\n\t var slot = scale.getSlot(value);\n\t var axis = vertical ? constants.Y : constants.X;\n\t var sizeAxis = vertical ? constants.X : constants.Y;\n\t var margin = this._margin() * dir;\n\n\t var p1 = new GeometryPoint();\n\t p1[axis] = minSlot[axis + \"1\"];\n\t p1[sizeAxis] = minSlot[sizeAxis + \"1\"];\n\n\t var p2 = new GeometryPoint();\n\t p2[axis] = slot[axis + \"1\"];\n\t p2[sizeAxis] = slot[sizeAxis + \"1\"];\n\n\t if (vertical) {\n\t p1.translate(margin, 0);\n\t p2.translate(margin, 0);\n\t } else {\n\t p1.translate(0, margin);\n\t p2.translate(0, margin);\n\t }\n\n\t var p3 = p2.clone();\n\t var p4 = p1.clone();\n\n\t if (vertical) {\n\t p3.translate(size, 0);\n\t p4.translate(size, 0);\n\t } else {\n\t p3.translate(0, size);\n\t p4.translate(0, size);\n\t }\n\n\t return [ p1, p2, p3, p4 ];\n\t },\n\n\t repaint: function() {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var options = ref.options;\n\t var shape = this.pointerShape(options.value);\n\t var pointerPath = this.pointerPath;\n\t var oldShape = this.pointerShape(options._oldValue);\n\n\t pointerPath.moveTo(shape[0]).lineTo(shape[1]).lineTo(shape[2]).lineTo(shape[3]).close();\n\n\t var animation = new BarLinearPointerAnimation(pointerPath, deepExtend(options.animation, {\n\t reverse: scale.options.reverse,\n\t vertical: scale.options.vertical,\n\t oldPoints: [ oldShape[1], oldShape[2] ],\n\t newPoints: [ shape[1], shape[2] ]\n\t }));\n\n\t if (options.animation.transitions === false) {\n\t animation.options.duration = 0;\n\t }\n\n\t animation.setup();\n\t animation.play();\n\t },\n\n\t render: function() {\n\t var group = new Group$3();\n\t var elementOptions = this.getElementOptions();\n\n\t if (this.options.track.visible) {\n\t group.append(this.renderTrack());\n\t }\n\n\t var pointer = this.pointerPath = new Path$4({\n\t stroke: elementOptions.stroke,\n\t fill: elementOptions.fill\n\t });\n\n\t group.append(pointer);\n\n\t this.elements = group;\n\n\t return group;\n\t },\n\n\t renderTrack: function() {\n\t var trackOptions = this.options.track;\n\t var border = trackOptions.border || {};\n\t var trackBox = this.trackBox.clone().pad(border.width || 0);\n\n\t return new Path$4.fromRect(trackBox.toRect(), {\n\t fill: {\n\t color: trackOptions.color,\n\t opacity: trackOptions.opacity\n\t },\n\t stroke: {\n\t color: border.width ? border.color || trackOptions.color : \"\",\n\t width: border.width,\n\t dashType: border.dashType\n\t }\n\t });\n\t }\n\t});\n\n\tvar DEFAULT_MIN_WIDTH = 60;\n\tvar DEFAULT_MIN_HEIGHT = 60;\n\n\tvar Group$1 = DrawingGroup;\n\n\tvar LinearGauge = Gauge.extend({\n\t reflow: function(bbox) {\n\t var pointers = this.pointers;\n\t var bboxX = bbox.origin.x;\n\t var bboxY = bbox.origin.y;\n\n\t var box = new Box(bboxX, bboxY, bboxX + bbox.width(), bboxY + bbox.height());\n\n\t this.scale.reflow(box);\n\t this._shrinkScaleWidth(box);\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t pointers[i].reflow();\n\t }\n\n\t this.bbox = this._getBox(box);\n\t this._alignElements();\n\t this._shrinkElements();\n\t this._buildVisual();\n\t this._draw();\n\t },\n\n\t _buildVisual: function() {\n\t var visuals = new Group$1();\n\t var scaleElements = this.scale.render();\n\t var pointers = this.pointers;\n\n\t visuals.append(this.gaugeArea);\n\t visuals.append(scaleElements);\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t var current = pointers[i];\n\t visuals.append(current.render());\n\t current.value(current.options.value);\n\t }\n\n\t this._visuals = visuals;\n\t },\n\n\t _createModel: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var scale = this.scale = new LinearScale(options.scale, this.contextService);\n\n\t this.pointers = [];\n\n\t var pointers = options.pointer;\n\t pointers = isArray(pointers) ? pointers : [ pointers ];\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t var currentOptions = deepExtend({}, pointers[i], {\n\t animation: {\n\t transitions: options.transitions\n\t }\n\t });\n\t var pointerType = currentOptions.shape === ARROW ? ArrowLinearPointer : BarLinearPointer;\n\n\t this$1.pointers.push(new pointerType(scale, currentOptions));\n\t }\n\t },\n\n\t _defaultSize: function() {\n\t var vertical = this.options.scale.vertical;\n\n\t return {\n\t width: vertical ? DEFAULT_MIN_WIDTH : DEFAULT_WIDTH,\n\t height: vertical ? DEFAULT_HEIGHT : DEFAULT_MIN_HEIGHT\n\t };\n\t },\n\n\t _getBox: function(box) {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var pointers = ref.pointers;\n\t var boxCenter = box.center();\n\t var plotAreaBox = pointers[0].box.clone().wrap(scale.box);\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t plotAreaBox.wrap(pointers[i].box.clone());\n\t }\n\n\t var size;\n\t if (scale.options.vertical) {\n\t size = plotAreaBox.width() / 2;\n\t plotAreaBox = new Box(\n\t boxCenter.x - size, box.y1,\n\t boxCenter.x + size, box.y2\n\t );\n\t } else {\n\t size = plotAreaBox.height() / 2;\n\t plotAreaBox = new Box(\n\t box.x1, boxCenter.y - size,\n\t box.x2, boxCenter.y + size\n\t );\n\t }\n\n\t return plotAreaBox;\n\t },\n\n\t _alignElements: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var scale = ref.scale;\n\t var pointers = ref.pointers;\n\t var scaleBox = scale.box;\n\t var box = pointers[0].box.clone().wrap(scale.box);\n\t var plotAreaBox = this.bbox;\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t box.wrap(pointers[i].box.clone());\n\t }\n\n\t var diff;\n\t if (scale.options.vertical) {\n\t diff = plotAreaBox.center().x - box.center().x;\n\t scale.reflow(new Box(\n\t scaleBox.x1 + diff, plotAreaBox.y1,\n\t scaleBox.x2 + diff, plotAreaBox.y2\n\t ));\n\t } else {\n\t diff = plotAreaBox.center().y - box.center().y;\n\t scale.reflow(new Box(\n\t scaleBox.x1, scaleBox.y1 + diff,\n\t scaleBox.x2, scaleBox.y2 + diff\n\t ));\n\t }\n\n\t for (var i$1 = 0; i$1 < pointers.length; i$1++) {\n\t pointers[i$1].reflow(this$1.bbox);\n\t }\n\t },\n\n\t _shrinkScaleWidth: function(bbox) {\n\t var ref = this;\n\t var scale = ref.scale;\n\t if (!scale.options.vertical) {\n\t var overflow = scale.contentBox().width() - bbox.width();\n\t if (overflow > 0) {\n\t scale.box.shrink(overflow, 0);\n\t scale.box.alignTo(bbox, 'center');\n\t scale.reflow(scale.box);\n\t }\n\t }\n\t },\n\n\t _shrinkElements: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var scale = ref.scale;\n\t var pointers = ref.pointers;\n\t var scaleBox = scale.box.clone();\n\t var pos = scale.options.vertical ? \"y\" : \"x\";\n\t var pointerBox = pointers[0].box;\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t pointerBox.wrap(pointers[i].box.clone());\n\t }\n\n\t scaleBox[pos + 1] += Math.max(scaleBox[pos + 1] - pointerBox[pos + 1], 0);\n\t scaleBox[pos + 2] -= Math.max(pointerBox[pos + 2] - scaleBox[pos + 2], 0);\n\n\t scale.reflow(scaleBox);\n\n\t for (var i$1 = 0; i$1 < pointers.length; i$1++) {\n\t pointers[i$1].reflow(this$1.bbox);\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(LinearGauge, {\n\t transitions: true,\n\t gaugeArea: {\n\t background: \"\"\n\t },\n\t scale: {\n\t vertical: true\n\t }\n\t});\n\n\tvar GEO_ARC_ADJUST_ANGLE = 180;\n\n\tvar Arc = drawing.Arc;\n\tvar Path$5 = DrawingPath;\n\tvar Group$5 = DrawingGroup;\n\n\tfunction drawTicks(arc, tickAngles, unit, tickOptions) {\n\t var ticks = new Group$5();\n\t var center = arc.center;\n\t var radius = arc.getRadiusX();\n\n\t if (tickOptions.visible) {\n\t for (var i = 0; i < tickAngles.length; i++) {\n\t var tickStart = arc.pointAt(tickAngles[i]);\n\t var tickEnd = new GeometryPoint(center.x + radius - tickOptions.size, center.y).rotate(tickAngles[i], center);\n\n\t ticks.append(new Path$5({\n\t stroke: {\n\t color: tickOptions.color,\n\t width: tickOptions.width\n\t }\n\t }).moveTo(tickStart).lineTo(tickEnd));\n\t }\n\t }\n\n\t return ticks;\n\t}\n\n\tfunction rangeSegment(from, to, color, opacity) {\n\t return { from: from, to: to, color: color, opacity: opacity };\n\t}\n\n\tvar RadialScale = NumericAxis.extend({\n\t init: function(options, service) {\n\t NumericAxis.fn.init.call(this, 0, 1, options, service);\n\t },\n\n\t initUserOptions: function(options) {\n\t var scaleOptions = deepExtend({}, this.options, options);\n\t scaleOptions.majorUnit = scaleOptions.majorUnit || dataviz.autoMajorUnit(scaleOptions.min, scaleOptions.max);\n\t scaleOptions.minorUnit = scaleOptions.minorUnit || scaleOptions.majorUnit / 10;\n\n\t return scaleOptions;\n\t },\n\n\t initFields: function() {\n\t },\n\n\t render: function(center, radius) {\n\t var arc = this.renderArc(center, radius);\n\n\t this.bbox = arc.bbox();\n\t this.labelElements = this.renderLabels();\n\t this.ticks = this.renderTicks();\n\t this.ranges = this.renderRanges();\n\t },\n\n\t reflow: function(bbox) {\n\t var center = bbox.center();\n\t var radius = Math.min(bbox.height(), bbox.width()) / 2;\n\n\t if (defined(this.bbox)) {\n\t this.bbox = this.arc.bbox();\n\t this.radius(this.arc.getRadiusX());\n\t this.repositionRanges();\n\t this.renderLabels();\n\t } else {\n\t return this.render(center, radius);\n\t }\n\t },\n\n\t slotAngle: function(value) {\n\t var ref = this.options;\n\t var min = ref.min;\n\t var max = ref.max;\n\t var reverse = ref.reverse;\n\t var startAngle = ref.startAngle;\n\t var endAngle = ref.endAngle;\n\t var angle = endAngle - startAngle;\n\t var result;\n\n\t if (reverse) {\n\t result = endAngle - (value - min) / (max - min) * angle;\n\t } else {\n\t result = ((value - min) / (max - min) * angle) + startAngle;\n\t }\n\n\t return result + GEO_ARC_ADJUST_ANGLE;\n\t },\n\n\t hasRanges: function() {\n\t var ranges = this.options.ranges;\n\n\t return ranges && ranges.length;\n\t },\n\n\t ticksSize: function() {\n\t var ref = this.options;\n\t var majorTicks = ref.majorTicks;\n\t var minorTicks = ref.minorTicks;\n\t var size = 0;\n\t if (majorTicks.visible) {\n\t size = majorTicks.size;\n\t }\n\n\t if (minorTicks.visible) {\n\t size = Math.max(minorTicks.size, size);\n\t }\n\n\t return size;\n\t },\n\n\t renderLabels: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var arc = this.arc.clone();\n\t var radius = arc.getRadiusX();\n\t var tickAngles = this.tickAngles(arc, options.majorUnit);\n\t var rangeSize = options.rangeSize = options.rangeSize || radius * 0.1;\n\t var labelsGroup = new Group$5();\n\n\t var rangeDistance = radius * 0.05;\n\t if (defined(options.rangeDistance)) {\n\t rangeDistance = options.rangeDistance;\n\t } else {\n\t options.rangeDistance = rangeDistance;\n\t }\n\n\t var labelsOptions = options.labels;\n\t var isInside = labelsOptions.position === INSIDE;\n\t var hasLabelElements = defined(this.labelElements);\n\n\t if (isInside) {\n\t radius -= this.ticksSize();\n\n\t if (this.hasRanges() && !hasLabelElements) {\n\t radius -= rangeSize + rangeDistance;\n\t }\n\t arc.setRadiusX(radius).setRadiusY(radius);\n\t }\n\n\t var labels = this.labels;\n\t var count = labels.length;\n\t var padding = labelsOptions.padding;\n\n\t for (var i = 0; i < count; i++) {\n\t var label = labels[i];\n\t var halfWidth = label.box.width() / 2;\n\t var halfHeight = label.box.height() / 2;\n\t var angle = tickAngles[i];\n\t var labelAngle = (angle - GEO_ARC_ADJUST_ANGLE) * DEGREE;\n\n\t var lp = arc.pointAt(angle);\n\t var cx = lp.x + (Math.cos(labelAngle) * (halfWidth + padding) * (isInside ? 1 : -1));\n\t var cy = lp.y + (Math.sin(labelAngle) * (halfHeight + padding) * (isInside ? 1 : -1));\n\n\t label.reflow(new Box(cx - halfWidth, cy - halfHeight, cx + halfWidth, cy + halfHeight));\n\t var labelPos = new GeometryPoint(label.box.x1, label.box.y1);\n\n\t var labelElement = (void 0);\n\t if (!hasLabelElements) {\n\t labelElement = buildLabelElement(label, options.labels);\n\t labelsGroup.append(labelElement);\n\t } else {\n\t labelElement = this$1.labelElements.children[i];\n\t var prevLabelPos = labelElement.bbox().origin;\n\n\t var labelTransform = labelElement.transform() || transform();\n\t labelTransform.translate(labelPos.x - prevLabelPos.x, labelPos.y - prevLabelPos.y);\n\t labelElement.transform(labelTransform);\n\t }\n\n\t this$1.bbox = Rect.union(this$1.bbox, labelElement.bbox());\n\t }\n\n\t return labelsGroup;\n\t },\n\n\t repositionRanges: function() {\n\t var ranges = this.ranges.children;\n\n\t if (ranges.length > 0) {\n\t var ref = this.options;\n\t var rangeDistance = ref.rangeDistance;\n\t var rangeSize = ref.rangeSize;\n\t var rangeRadius = this.getRangeRadius();\n\n\t if (this.options.labels.position === INSIDE) {\n\t rangeRadius += rangeSize + rangeDistance;\n\t }\n\n\t var newRadius = rangeRadius + (rangeSize / 2);\n\n\t for (var i = 0; i < ranges.length; i++) {\n\t ranges[i]._geometry.setRadiusX(newRadius).setRadiusY(newRadius);\n\t }\n\n\t this.bbox = Rect.union(this.bbox, this.ranges.bbox());\n\t }\n\t },\n\n\t renderRanges: function() {\n\t var this$1 = this;\n\n\t var segments = this.rangeSegments();\n\t var segmentsCount = segments.length;\n\t var result = new Group$5();\n\n\t if (segmentsCount) {\n\t var ref = this.options;\n\t var rangeSize = ref.rangeSize;\n\t var reverse = ref.reverse;\n\t var rangeDistance = ref.rangeDistance;\n\t var rangeRadius = this.getRangeRadius();\n\n\t // move the ticks with a range distance and a range size\n\t this.radius(this.radius() - rangeSize - rangeDistance);\n\n\t for (var i = 0; i < segmentsCount; i++) {\n\t var segment = segments[i];\n\t var from = this$1.slotAngle(segment[reverse ? \"to\" : \"from\"]);\n\t var to = this$1.slotAngle(segment[!reverse ? \"to\" : \"from\"]);\n\n\t if (to - from !== 0) {\n\t result.append(this$1.createRange(from, to, rangeRadius, segment));\n\t }\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t createRange: function(startAngle, endAngle, rangeRadius, options) {\n\t var rangeSize = this.options.rangeSize;\n\t var rangeGeom = new geometry.Arc(this.arc.center, {\n\t radiusX: rangeRadius + (rangeSize / 2),\n\t radiusY: rangeRadius + (rangeSize / 2),\n\t startAngle: startAngle,\n\t endAngle: endAngle\n\t });\n\n\t return new Arc(rangeGeom, {\n\t stroke: {\n\t width: rangeSize,\n\t color: options.color,\n\t opacity: options.opacity,\n\t lineCap: options.lineCap\n\t }\n\t });\n\t },\n\n\t rangeSegments: function() {\n\t var options = this.options;\n\t var ranges = options.ranges || [];\n\t var count = ranges.length;\n\t var segments = [];\n\n\t if (count) {\n\t var min = options.min;\n\t var max = options.max;\n\t var defaultColor = options.rangePlaceholderColor;\n\t segments.push(rangeSegment(min, max, defaultColor));\n\n\t for (var i = 0; i < count; i++) {\n\t var range = getRange(ranges[i], min, max);\n\t var segmentsCount = segments.length;\n\n\t for (var j = 0; j < segmentsCount; j++) {\n\t var segment = segments[j];\n\n\t if (segment.from <= range.from && range.from <= segment.to) {\n\t segments.push(rangeSegment(range.from, range.to, range.color, range.opacity));\n\n\t if (segment.from <= range.to && range.to <= segment.to) {\n\t segments.push(rangeSegment(range.to, segment.to, defaultColor, range.opacity));\n\t }\n\n\t segment.to = range.from;\n\n\t break;\n\t }\n\t }\n\t }\n\t }\n\n\t return segments;\n\t },\n\n\t getRangeRadius: function() {\n\t var ref = this;\n\t var arc = ref.arc;\n\t var options = ref.options;\n\t var rangeSize = options.rangeSize;\n\t var rangeDistance = options.rangeDistance;\n\t var majorTickSize = options.majorTicks.size;\n\t var radius;\n\n\t if (options.labels.position === OUTSIDE) {\n\t radius = arc.getRadiusX() - majorTickSize - rangeDistance - rangeSize;\n\t } else {\n\t radius = arc.getRadiusX() - rangeSize;\n\t }\n\n\t return radius;\n\t },\n\n\t renderArc: function(center, radius) {\n\t var options = this.options;\n\n\t var arc = this.arc = new geometry.Arc(center, {\n\t radiusX: radius,\n\t radiusY: radius,\n\t startAngle: options.startAngle + GEO_ARC_ADJUST_ANGLE,\n\t endAngle: options.endAngle + GEO_ARC_ADJUST_ANGLE\n\t });\n\n\t return arc;\n\t },\n\n\t renderTicks: function() {\n\t var ref = this;\n\t var arc = ref.arc;\n\t var options = ref.options;\n\t var tickArc = arc.clone();\n\n\t this.majorTickAngles = this.tickAngles(arc, options.majorUnit);\n\t this.majorTicks = drawTicks(tickArc, this.majorTickAngles, options.majorUnit, options.majorTicks);\n\n\t var allTicks = new Group$5();\n\t allTicks.append(this.majorTicks);\n\n\t var majorTickSize = options.majorTicks.size;\n\t var minorTickSize = options.minorTicks.size;\n\n\t this._tickDifference = majorTickSize - minorTickSize;\n\n\t if (options.labels.position === OUTSIDE) {\n\t var radius = tickArc.getRadiusX();\n\t tickArc.setRadiusX(radius - majorTickSize + minorTickSize)\n\t .setRadiusY(radius - majorTickSize + minorTickSize);\n\t }\n\n\t this.minorTickAngles = this.normalizeTickAngles(this.tickAngles(arc, options.minorUnit));\n\t this.minorTicks = drawTicks(tickArc, this.minorTickAngles, options.minorUnit, options.minorTicks);\n\t allTicks.append(this.minorTicks);\n\n\t return allTicks;\n\t },\n\n\t normalizeTickAngles: function(angles) {\n\t var options = this.options;\n\t var skip = options.majorUnit / options.minorUnit;\n\n\t for (var i = angles.length - 1; i >= 0; i--) {\n\t if (i % skip === 0) {\n\t angles.splice(i, 1);\n\t }\n\t }\n\n\t return angles;\n\t },\n\n\t tickAngles: function(ring, stepValue) {\n\t var options = this.options;\n\t var reverse = options.reverse;\n\t var range = options.max - options.min;\n\t var angle = ring.endAngle - ring.startAngle;\n\t var tickCount = range / stepValue;\n\t var pos = ring.startAngle;\n\t var step = angle / tickCount;\n\n\t if (reverse) {\n\t pos += angle;\n\t step = -step;\n\t }\n\n\t var positions = [];\n\t for (var i = 0; i < tickCount; i++) {\n\t positions.push(round(pos, COORD_PRECISION));\n\t pos += step;\n\t }\n\n\t if (round(pos) <= ring.endAngle) {\n\t positions.push(pos);\n\t }\n\n\t return positions;\n\t },\n\n\t radius: function(value) {\n\t if (value) {\n\t this.arc.setRadiusX(value).setRadiusY(value);\n\t this.repositionTicks(this.majorTicks.children, this.majorTickAngles);\n\t this.repositionTicks(this.minorTicks.children, this.minorTickAngles, true);\n\t } else {\n\t return this.arc.getRadiusX();\n\t }\n\t },\n\n\t repositionTicks: function(ticks, tickAngles, minor) {\n\t var diff = minor ? (this._tickDifference || 0) : 0;\n\t var tickArc = this.arc;\n\t var radius = tickArc.getRadiusX();\n\n\t if (minor && this.options.labels.position === OUTSIDE && diff !== 0) {\n\t tickArc = this.arc.clone();\n\t tickArc.setRadiusX(radius - diff).setRadiusY(radius - diff);\n\t }\n\n\t for (var i = 0; i < ticks.length; i++) {\n\t var newPoint = tickArc.pointAt(tickAngles[i]);\n\t var segments = ticks[i].segments;\n\t var xDiff = newPoint.x - segments[0].anchor().x;\n\t var yDiff = newPoint.y - segments[0].anchor().y;\n\n\t ticks[i].transform(new transform().translate(xDiff, yDiff));\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(RadialScale, {\n\t min: 0,\n\t max: 100,\n\n\t majorTicks: {\n\t size: 15,\n\t align: INSIDE,\n\t color: BLACK,\n\t width: DEFAULT_LINE_WIDTH,\n\t visible: true\n\t },\n\n\t minorTicks: {\n\t size: 10,\n\t align: INSIDE,\n\t color: BLACK,\n\t width: DEFAULT_LINE_WIDTH,\n\t visible: true\n\t },\n\n\t startAngle: -30,\n\t endAngle: 210,\n\n\t labels: {\n\t position: INSIDE,\n\t padding: 2\n\t }\n\t});\n\n\tvar RadialPointerAnimation = Animation.extend({\n\t init: function(element, options) {\n\t Animation.fn.init.call(this, element, options);\n\n\t var animationOptions = this.options;\n\n\t animationOptions.duration = Math.max((Math.abs(animationOptions.newAngle - animationOptions.oldAngle) / animationOptions.duration) * 1000, 1);\n\t },\n\n\t step: function(pos) {\n\t var options = this.options;\n\t var angle = interpolateValue(options.oldAngle, options.newAngle, pos);\n\n\t this.element.transform(transform().rotate(angle, options.center));\n\t }\n\t});\n\n\tsetDefaultOptions(RadialPointerAnimation, {\n\t easing: LINEAR,\n\t duration: ANGULAR_SPEED\n\t});\n\n\tAnimationFactory.current.register(RADIAL_POINTER, RadialPointerAnimation);\n\n\tvar CAP_SIZE = 0.05;\n\tvar Circle = drawing.Circle;\n\tvar Group$6 = DrawingGroup;\n\tvar Path$6 = DrawingPath;\n\n\tvar RadialPointer = Pointer.extend({\n\t setAngle: function(angle) {\n\t this.elements.transform(transform().rotate(angle, this.center));\n\t },\n\n\t repaint: function() {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var options = ref.options;\n\t var oldAngle = scale.slotAngle(options._oldValue);\n\t var newAngle = scale.slotAngle(options.value);\n\n\t if (options.animation.transitions === false) {\n\t this.setAngle(newAngle);\n\t } else {\n\t new RadialPointerAnimation(this.elements, deepExtend(options.animation, {\n\t oldAngle: oldAngle,\n\t newAngle: newAngle\n\t })).play();\n\t }\n\t },\n\n\t render: function() {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var options = ref.options;\n\t var elements = new Group$6();\n\n\t if (options.animation !== false) {\n\t deepExtend(options.animation, {\n\t startAngle: 0,\n\t center: scale.arc.center,\n\t reverse: scale.options.reverse\n\t });\n\t }\n\n\t elements.append(this._renderNeedle(), this._renderCap());\n\n\t this.elements = elements;\n\t this.setAngle(DEGREE);\n\n\t return elements;\n\t },\n\n\t reflow: function(arc) {\n\t var center = this.center = arc.center;\n\t var length = limitValue(this.options.length || 1, 0.1, 1.5);\n\t var radius = this.radius = arc.getRadiusX() * length;\n\t var capSize = this.capSize = Math.round(radius * this.options.cap.size);\n\n\t this.bbox = Rect.fromPoints(new GeometryPoint(center.x - capSize, center.y - capSize),\n\t new GeometryPoint(center.x + capSize, center.y + capSize));\n\t },\n\n\t _renderNeedle: function() {\n\t var minorTickSize = this.scale.options.minorTicks.size;\n\t var center = this.center;\n\t var needleColor = this.options.color;\n\n\t var needlePath = new Path$6({\n\t fill: { color: needleColor },\n\t stroke: { color: needleColor, width: DEFAULT_LINE_WIDTH }\n\t });\n\n\t needlePath.moveTo(center.x + this.radius - minorTickSize, center.y)\n\t .lineTo(center.x, center.y - (this.capSize / 2))\n\t .lineTo(center.x, center.y + (this.capSize / 2))\n\t .close();\n\n\t return needlePath;\n\t },\n\n\t _renderCap: function() {\n\t var options = this.options;\n\t var capColor = options.cap.color || options.color;\n\t var circle = new geometry.Circle(this.center, this.capSize);\n\n\t var cap = new Circle(circle, {\n\t fill: { color: capColor },\n\t stroke: { color: capColor }\n\t });\n\n\t return cap;\n\t }\n\t});\n\n\tsetDefaultOptions(RadialPointer, {\n\t cap: {\n\t size: CAP_SIZE\n\t },\n\t arrow: {\n\t width: 16,\n\t height: 14\n\t },\n\t animation: {\n\t type: RADIAL_POINTER,\n\t duration: ANGULAR_SPEED\n\t }\n\t});\n\n\tvar Group$4 = DrawingGroup;\n\n\tvar RadialGauge = Gauge.extend({\n\t reflow: function(bbox) {\n\t var this$1 = this;\n\n\t var pointers = this.pointers;\n\t this.scale.reflow(bbox);\n\t this._initialPlotArea = this.scale.bbox;\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t pointers[i].reflow(this$1.scale.arc);\n\t this$1._initialPlotArea = Rect.union(this$1._initialPlotArea, pointers[i].bbox);\n\t }\n\n\t this.fitScale(bbox);\n\t this.alignScale(bbox);\n\t this._buildVisual(this.gaugeArea, pointers, this.scale);\n\t this._draw();\n\t },\n\n\t _buildVisual: function(gaugeArea, pointers, scale) {\n\t var visuals = this._visuals = new Group$4();\n\n\t visuals.append(gaugeArea);\n\t visuals.append(scale.ticks);\n\t visuals.append(scale.ranges);\n\t this._buildPointers(pointers);\n\t visuals.append(scale.labelElements);\n\t },\n\n\t _buildPointers: function(pointers) {\n\t var this$1 = this;\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t var current = pointers[i];\n\t current.render();\n\t this$1._visuals.append(current.elements);\n\n\t current.value(current.options.value);\n\t }\n\t },\n\n\t fitScale: function(bbox) {\n\t var this$1 = this;\n\n\t var arc = this.scale.arc;\n\t var plotAreaBox = this._initialPlotArea;\n\t var step = Math.abs(this.getDiff(plotAreaBox, bbox));\n\t var min = round(step, COORD_PRECISION);\n\t var max = round(-step, COORD_PRECISION);\n\t var minDiff, midDiff, maxDiff, mid, oldDiff;\n\t var staleFlag = 0;\n\t var i = 0;\n\n\t while (i++ < 100) {\n\t staleFlag = (oldDiff === maxDiff) ? (staleFlag + 1) : 0;\n\n\t if (staleFlag > 5) {\n\t break;\n\t }\n\n\t if (min !== mid) {\n\t minDiff = this$1.getPlotBox(min, bbox, arc);\n\t if (0 <= minDiff && minDiff <= 2) {\n\t break;\n\t }\n\t }\n\n\t if (max !== mid) {\n\t maxDiff = this$1.getPlotBox(max, bbox, arc);\n\t if (0 <= maxDiff && maxDiff <= 2) {\n\t break;\n\t }\n\t }\n\n\t if (minDiff > 0 && maxDiff > 0) {\n\t mid = min * 2;\n\t } else if (minDiff < 0 && maxDiff < 0) {\n\t mid = max * 2;\n\t } else {\n\t mid = round(((min + max) / 2) || 1, COORD_PRECISION);\n\t }\n\n\t midDiff = this$1.getPlotBox(mid, bbox, arc);\n\t if (0 <= midDiff && midDiff <= 2) {\n\t break;\n\t }\n\n\t oldDiff = maxDiff;\n\n\t if (midDiff > 0) {\n\t max = mid;\n\t maxDiff = midDiff;\n\t } else {\n\t min = mid;\n\t minDiff = midDiff;\n\t }\n\t }\n\t },\n\n\t getPlotBox: function(step, bbox, arc) {\n\t var this$1 = this;\n\n\t var scale = this.scale;\n\t var pointers = this.pointers;\n\t var radius = arc.getRadiusX();\n\t var scaleArc = arc.clone();\n\n\t scaleArc.setRadiusX(radius + step).setRadiusY(radius + step);\n\n\t scale.arc = scaleArc;\n\t scale.reflow(bbox);\n\t this.plotBbox = scale.bbox;\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t pointers[i].reflow(scaleArc);\n\t this$1.plotBbox = Rect.union(this$1.plotBbox, pointers[i].bbox);\n\t }\n\n\t return this.getDiff(this.plotBbox, bbox);\n\t },\n\n\t getDiff: function(plotBox, box) {\n\t return Math.min(box.width() - plotBox.width(), box.height() - plotBox.height());\n\t },\n\n\t alignScale: function(bbox) {\n\t var this$1 = this;\n\n\t var plotBoxCenter = this.plotBbox.center();\n\t var boxCenter = bbox.center();\n\t var paddingX = plotBoxCenter.x - boxCenter.x;\n\t var paddingY = plotBoxCenter.y - boxCenter.y;\n\t var ref = this;\n\t var scale = ref.scale;\n\t var pointers = ref.pointers;\n\n\t scale.arc.center.x -= paddingX;\n\t scale.arc.center.y -= paddingY;\n\n\t scale.reflow(bbox);\n\n\t for (var i = 0; i < pointers.length; i++) {\n\t pointers[i].reflow(scale.arc);\n\t this$1.plotBbox = Rect.union(scale.bbox, pointers[i].bbox);\n\t }\n\t },\n\n\t _createModel: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var pointers = options.pointer;\n\t var scale = this.scale = new RadialScale(options.scale, this.contextService);\n\n\t this.pointers = [];\n\n\t var pointersArr = isArray(pointers) ? pointers : [ pointers ];\n\t for (var i = 0; i < pointersArr.length; i++) {\n\t var current = new RadialPointer(scale, deepExtend({}, pointersArr[i], {\n\t animation: {\n\t transitions: options.transitions\n\t }\n\t }));\n\n\t this$1.pointers.push(current);\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(RadialGauge, {\n\t transitions: true,\n\t gaugeArea: {\n\t background: \"\"\n\t }\n\t});\n\n\tvar ArcScale = RadialScale.extend({\n\t rangeSegments: function() {\n\t var ref = this.options;\n\t var min = ref.min;\n\t var max = ref.max;\n\t var rangePlaceholderColor = ref.rangePlaceholderColor;\n\t var rangeLineCap = ref.rangeLineCap;\n\n\t return [ { from: min, to: max, color: rangePlaceholderColor, lineCap: rangeLineCap } ];\n\t },\n\n\t hasRanges: function() {\n\t return true;\n\t },\n\n\t placeholderRangeAngle: function(angle) {\n\t var geometry$$1 = this.ranges.children[0].geometry();\n\n\t if (this.options.reverse) {\n\t geometry$$1.setEndAngle(angle);\n\t } else {\n\t geometry$$1.setStartAngle(angle);\n\t }\n\t },\n\n\t addRange: function(from, to, options) {\n\t var reverse = this.options.reverse;\n\n\t var startAngle = this.slotAngle(reverse ? to : from);\n\t var endAngle = this.slotAngle(reverse ? from : to);\n\n\t var range = this.createRange(startAngle, endAngle, this.getRangeRadius(), options);\n\n\t this.ranges.append(range);\n\n\t return range;\n\t }\n\t});\n\n\tsetDefaultOptions(ArcScale, {\n\t min: 0,\n\t max: 100,\n\n\t majorTicks: {\n\t visible: false\n\t },\n\n\t minorTicks: {\n\t visible: false\n\t },\n\n\t labels: {\n\t visible: false\n\t },\n\n\t startAngle: 0,\n\t endAngle: 180,\n\t rangeLineCap: 'round'\n\t});\n\n\tvar MAX_DURATION = 800;\n\n\tvar RangePointerAnimation = Animation.extend({\n\t init: function(element, options) {\n\t Animation.fn.init.call(this, element, options);\n\n\t var animationOptions = this.options;\n\t var duration = (Math.abs(animationOptions.newAngle - animationOptions.oldAngle) / animationOptions.duration) * 1000;\n\t animationOptions.duration = limitValue(duration, ANGULAR_SPEED, MAX_DURATION);\n\n\t var startColor = element.elements.options.get(\"stroke.color\");\n\t var color = element.currentColor();\n\t if (startColor !== color) {\n\t this.startColor = new kendo.Color(startColor);\n\t this.color = new kendo.Color(color);\n\t }\n\t },\n\n\t step: function(pos) {\n\t var ref = this;\n\t var options = ref.options;\n\t var startColor = ref.startColor;\n\t var color = ref.color;\n\t var angle = interpolateValue(options.oldAngle, options.newAngle, pos);\n\t this.element.angle(angle);\n\n\t if (color) {\n\t var r = round(interpolateValue(startColor.r, color.r, pos));\n\t var g = round(interpolateValue(startColor.g, color.g, pos));\n\t var b = round(interpolateValue(startColor.b, color.b, pos));\n\n\t this.element.stroke(new kendo.Color(r, g, b).toHex());\n\t }\n\t }\n\t});\n\n\tsetDefaultOptions(RangePointerAnimation, {\n\t easing: LINEAR,\n\t duration: ANGULAR_SPEED\n\t});\n\n\tAnimationFactory.current.register(RADIAL_RANGE_POINTER, RangePointerAnimation);\n\n\tvar RangePointer = Pointer.extend({\n\t repaint: function() {\n\t var ref = this;\n\t var scale = ref.scale;\n\t var options = ref.options;\n\t var oldAngle = scale.slotAngle(options._oldValue);\n\t var newAngle = scale.slotAngle(options.value);\n\n\t if (this.animation) {\n\t this.animation.abort();\n\t }\n\n\t if (options.animation.transitions === false) {\n\t this.angle(newAngle);\n\t this.stroke(this.currentColor());\n\t } else {\n\t this.animation = new RangePointerAnimation(this, deepExtend(options.animation, {\n\t oldAngle: oldAngle,\n\t newAngle: newAngle\n\t }));\n\n\t this.animation.play();\n\t }\n\t },\n\n\t angle: function(value) {\n\t var geometry$$1 = this.elements.geometry();\n\t if (this.scale.options.reverse) {\n\t geometry$$1.setStartAngle(value);\n\t } else {\n\t geometry$$1.setEndAngle(value);\n\t }\n\t this.scale.placeholderRangeAngle(value);\n\t },\n\n\t stroke: function(value) {\n\t this.elements.stroke(value);\n\t },\n\n\t render: function() {\n\t if (this.elements) {\n\t return;\n\t }\n\n\t var ref = this;\n\t var scale = ref.scale;\n\t var options = ref.options;\n\n\t if (options.animation !== false) {\n\t deepExtend(options.animation, {\n\t startAngle: 0,\n\t center: scale.arc.center,\n\t reverse: scale.options.reverse\n\t });\n\t }\n\n\t this.elements = scale.addRange(scale.options.min, this.options.value, {\n\t color: this.currentColor(),\n\t opacity: options.opacity,\n\t lineCap: scale.options.rangeLineCap\n\t });\n\t },\n\n\t currentColor: function() {\n\t var ref = this.scale.options;\n\t var min = ref.min;\n\t var max = ref.max;\n\t var ref$1 = this.options;\n\t var colors = ref$1.colors;\n\t var color = ref$1.color;\n\t var value = ref$1.value;\n\t var currentValue = dataviz.isNumber(value) ? value : min;\n\n\t if (colors) {\n\t for (var idx = 0; idx < colors.length; idx++) {\n\t var ref$2 = colors[idx];\n\t var rangeColor = ref$2.color;\n\t var from = ref$2.from; if (from === void 0) { from = min; }\n\t var to = ref$2.to; if (to === void 0) { to = max; }\n\n\t if (from <= currentValue && currentValue <= to) {\n\t return rangeColor;\n\t }\n\t }\n\t }\n\n\t return color;\n\t },\n\n\t reflow: function() {\n\t this.render();\n\n\t this.bbox = this.elements.bbox();\n\t }\n\t});\n\n\tsetDefaultOptions(RangePointer, {\n\t animation: {\n\t type: RADIAL_RANGE_POINTER,\n\t duration: ANGULAR_SPEED\n\t }\n\t});\n\n\tvar ArcGauge = RadialGauge.extend({\n\t _initTheme: function(theme) {\n\t RadialGauge.fn._initTheme.call(this, theme);\n\n\t this.options.color = this.options.color || (this.theme.pointer || {}).color;\n\t },\n\n\t _createModel: function() {\n\t var options = this.options;\n\t var scale = this.scale = new ArcScale(options.scale, this.contextService);\n\n\t var pointer = new RangePointer(scale, deepExtend({}, {\n\t colors: options.colors,\n\t color: options.color,\n\t value: options.value,\n\t opacity: options.opacity,\n\t animation: {\n\t transitions: options.transitions\n\t }\n\t }));\n\n\t this.pointers = [ pointer ];\n\t },\n\n\t _buildPointers: function(pointers) {\n\t for (var i = 0; i < pointers.length; i++) {\n\t var current = pointers[i];\n\t current.render();\n\n\t current.value(current.options.value);\n\t }\n\t },\n\n\t _setValueOptions: function(value) {\n\t this.options.value = value;\n\t },\n\n\t currentColor: function() {\n\t var pointer = this.pointers[0];\n\t if (pointer) {\n\t return pointer.currentColor();\n\t }\n\t },\n\n\t centerLabelPosition: function(width, height) {\n\t var size = this.getSize();\n\t var center = this.scale.arc.center;\n\n\t var left = center.x - width / 2;\n\t var top = center.y - height / 2;\n\n\t if (width < size.width) {\n\t var right = left + width;\n\n\t left = Math.max(left, 0);\n\n\t if (right > size.width) {\n\t left -= right - size.width;\n\t }\n\t }\n\n\t if (height < size.height) {\n\t var bbox = this.scale.bbox;\n\t var yLimit = bbox.bottomRight().y;\n\t var bottom = top + height;\n\n\t top = Math.max(top, bbox.origin.y);\n\n\t if (bottom > yLimit) {\n\t top -= bottom - yLimit;\n\t }\n\t }\n\n\t return {\n\t left: left,\n\t top: top\n\t };\n\t }\n\t});\n\n\tkendo.deepExtend(kendo.dataviz, {\n\t Gauge: Gauge,\n\t LinearGauge: LinearGauge,\n\t LinearPointer: LinearPointer,\n\t ArrowLinearPointer: ArrowLinearPointer,\n\t BarLinearPointer: BarLinearPointer,\n\t LinearScale: LinearScale,\n\t RadialGauge: RadialGauge,\n\t RadialPointer: RadialPointer,\n\t RadialScale: RadialScale,\n\t ArcGauge: ArcGauge,\n\t RangePointer: RangePointer,\n\t ArcScale: ArcScale\n\t});\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(885);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 885:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(886)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\t var kendo = window.kendo;\n\t var Widget = kendo.ui.Widget;\n\t var dataviz = kendo.dataviz;\n\t var LinearGauge = dataviz.LinearGauge;\n\t var RadialGauge = dataviz.RadialGauge;\n\t var ArcGauge = dataviz.ArcGauge;\n\t var draw = kendo.drawing;\n\n\t function themeOptions(options) {\n\t var themes = dataviz.ui.themes || {};\n\t var themeName = options.theme || \"\";\n\t var lowerName = themeName.toLowerCase();\n\n\t if(dataviz.SASS_THEMES.indexOf(lowerName) != -1) {\n\t return dataviz.autoTheme().gauge;\n\t }\n\n\t return (themes[themeName] || themes[lowerName] || {}).gauge;\n\t }\n\n\t var Gauge = Widget.extend({\n\t init: function(element, userOptions) {\n\t kendo.destroy(element);\n\t $(element).empty();\n\n\t Widget.fn.init.call(this, element);\n\n\t this.options = kendo.deepExtend(this.options, userOptions);\n\n\t this.wrapper = this.element;\n\t this._createInstance();\n\n\t this.element.addClass('k-gauge');\n\n\t kendo.notify(this, dataviz.ui);\n\t },\n\n\t options: {\n\t theme: \"default\",\n\t renderAs: \"\",\n\t pointer: {},\n\t scale: {},\n\t gaugeArea: {\n\t background: \"\"\n\t },\n\t transitions: true\n\t },\n\n\t setOptions: function(options) {\n\t this._instance.setOptions(options, themeOptions(options));\n\n\t this._copyFields();\n\t },\n\n\t redraw: function() {\n\t this._instance.redraw();\n\t this._copyFields();\n\t },\n\n\t destroy: function() {\n\t Widget.fn.destroy.call(this);\n\t this._instance.destroy();\n\t },\n\n\t _createInstance: function() {\n\t var gaugeType = this._gaugeType();\n\t this._instance = new gaugeType(this.element[0], this.options, themeOptions(this.options));\n\t this._copyFields();\n\t },\n\n\t _copyFields: function() {\n\t this._originalOptions = this._instance._originalOptions;\n\t this.options = this._instance.options;\n\t this.surface = this._instance.surface;\n\t this.bbox = this._instance.bbox;\n\t this.gaugeArea = this._instance.gaugeArea;\n\t this.pointers = this._instance.pointers;\n\t this.scale = this._instance.scale;\n\t },\n\n\t _resize: function() {\n\t this._instance.resize();\n\t }\n\t });\n\n\t var proxyMembers = [\"getSize\", \"value\", \"allValues\", \"exportVisual\"];\n\n\t function createProxyMember(name) {\n\t Gauge.fn[name] = function() {\n\t return this._instance[name].apply(this._instance, arguments);\n\t };\n\t }\n\n\t for (var idx = 0; idx < proxyMembers.length; idx++) {\n\t createProxyMember(proxyMembers[idx]);\n\t }\n\n\t dataviz.ExportMixin.extend(Gauge.fn);\n\n\t var RadialGaugeWidget = Gauge.extend({\n\n\t options: {\n\t name: \"RadialGauge\"\n\t },\n\n\t _gaugeType: function() {\n\t return RadialGauge;\n\t }\n\t });\n\n\t var LinearGaugeWidget = Gauge.extend({\n\n\t options: {\n\t name: \"LinearGauge\",\n\t scale: {\n\t vertical: true\n\t }\n\t },\n\n\t _gaugeType: function() {\n\t return LinearGauge;\n\t }\n\t });\n\n\t var ArcGaugeWidget = Gauge.extend({\n\t init: function(element, userOptions) {\n\t Gauge.fn.init.call(this, element, userOptions);\n\n\t this.element.css('position', 'relative');\n\t this.element.addClass('k-arcgauge');\n\n\t this._centerTemplate();\n\t },\n\n\t options: {\n\t name: \"ArcGauge\"\n\t },\n\n\t setOptions: function(options) {\n\t Gauge.fn.setOptions.call(this, options);\n\t this._centerTemplate();\n\t },\n\n\t redraw: function() {\n\t Gauge.fn.redraw.call(this);\n\t this._centerTemplate();\n\t },\n\n\t value: function(value) {\n\t var instance = this._instance;\n\t if (arguments.length === 0) {\n\t return instance.value();\n\t }\n\n\t instance.value(value);\n\n\t this._centerTemplate();\n\t },\n\n\t destroy: function() {\n\t Gauge.fn.destroy.call(this);\n\t delete this._centerElement;\n\t },\n\n\t exportVisual: function() {\n\t if (this._centerElement) {\n\t return false;\n\t }\n\n\t return Gauge.fn.exportVisual.call(this);\n\t },\n\n\t _resize: function() {\n\t this._instance.resize();\n\n\t this._centerTemplate();\n\t },\n\n\t _centerTemplate: function() {\n\t if (this.options.centerTemplate) {\n\t var template = kendo.template(this.options.centerTemplate);\n\n\t var instance = this._instance;\n\t var centerElement = this._getCenterElement();\n\n\t centerElement.html(template({ color: instance.currentColor(), value: instance.value() }));\n\n\t var position = instance.centerLabelPosition(centerElement.width(), centerElement.height());\n\n\t centerElement.css(position);\n\t } else if (this._centerElement) {\n\t this._centerElement.remove();\n\t this._centerElement = null;\n\t }\n\t },\n\n\t _getCenterElement: function() {\n\t var centerElement = this._centerElement;\n\t if (!centerElement) {\n\t centerElement = this._centerElement = $('
').addClass('k-arcgauge-label');\n\t this.element.append(centerElement);\n\t }\n\n\t return centerElement;\n\t },\n\n\t _gaugeType: function() {\n\t return ArcGauge;\n\t }\n\t });\n\n\t function createExportMethod(name) {\n\t ArcGaugeWidget.fn[name] = function(options) {\n\t var gauge = this;\n\t var method = draw[name];\n\n\t if (!gauge._centerElement) {\n\t return method(gauge.exportVisual(), options);\n\t }\n\n\t return draw.drawDOM(gauge.element).then(function(visual) {\n\t return method(visual, options);\n\t });\n\t };\n\t }\n\n\t var exportMethods = ['exportSVG', 'exportImage', 'exportPDF'];\n\n\t for (idx = 0; idx < exportMethods.length; idx++) {\n\t createExportMethod(exportMethods[idx]);\n\t }\n\n\t dataviz.ui.plugin(LinearGaugeWidget);\n\t dataviz.ui.plugin(RadialGaugeWidget);\n\t dataviz.ui.plugin(ArcGaugeWidget);\n\n\t kendo.deepExtend(dataviz, {\n\t Gauge: Gauge,\n\t LinearGauge: LinearGaugeWidget,\n\t RadialGauge: RadialGaugeWidget,\n\t ArcGauge: ArcGaugeWidget\n\t });\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 886:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo-gauges\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(887);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 860:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.drawing\");\n\n/***/ }),\n\n/***/ 887:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(860) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function() {\n\t var kendo = window.kendo,\n\t Widget = kendo.ui.Widget,\n\t template = kendo.template,\n\n\t util = kendo.drawing.util,\n\t valueOrDefault = util.valueOrDefault,\n\t defined = util.defined;\n\n\t var Attribution = Widget.extend({\n\t init: function(element, options) {\n\t Widget.fn.init.call(this, element, options);\n\t this._initOptions(options);\n\t this.items = [];\n\t this.element.addClass(\"k-widget k-attribution\");\n\t },\n\n\t options: {\n\t name: \"Attribution\",\n\t separator: \" | \",\n\t itemTemplate: \"#= text #\"\n\t },\n\n\t filter: function(extent, zoom) {\n\t this._extent = extent;\n\t this._zoom = zoom;\n\t this._render();\n\t },\n\n\t add: function(item) {\n\t if (defined(item)) {\n\t if (typeof item === \"string\") {\n\t item = { text: item };\n\t }\n\n\t this.items.push(item);\n\t this._render();\n\t }\n\t },\n\n\t remove: function(text) {\n\t var result = [];\n\t for (var i = 0; i < this.items.length; i++) {\n\t var item = this.items[i];\n\t if (item.text !== text) {\n\t result.push(item);\n\t }\n\t }\n\n\t this.items = result;\n\n\t this._render();\n\t },\n\n\t clear: function() {\n\t this.items = [];\n\t this.element.empty();\n\t },\n\n\t _render: function() {\n\t var result = [];\n\t var itemTemplate = template(this.options.itemTemplate);\n\n\t for (var i = 0; i < this.items.length; i++) {\n\t var item = this.items[i];\n\t var text = this._itemText(item);\n\t if (text !== \"\") {\n\t result.push(itemTemplate({\n\t text: text\n\t }));\n\t }\n\t }\n\n\t if (result.length > 0) {\n\t this.element.empty()\n\t .append(result.join(this.options.separator))\n\t .show();\n\t } else {\n\t this.element.hide();\n\t }\n\t },\n\n\t _itemText: function(item) {\n\t var text = \"\";\n\t var inZoomLevel = this._inZoomLevel(item.minZoom, item.maxZoom);\n\t var inArea = this._inArea(item.extent);\n\n\t if (inZoomLevel && inArea) {\n\t text += item.text;\n\t }\n\n\t return text;\n\t },\n\n\t _inZoomLevel: function(min, max) {\n\t var result = true;\n\t min = valueOrDefault(min, -Number.MAX_VALUE);\n\t max = valueOrDefault(max, Number.MAX_VALUE);\n\n\t result = this._zoom > min && this._zoom < max;\n\n\t return result;\n\t },\n\n\t _inArea: function(area) {\n\t var result = true;\n\n\t if (area) {\n\t result = area.contains(this._extent);\n\t }\n\n\t return result;\n\t }\n\t });\n\n\t kendo.dataviz.ui.plugin(Attribution);\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(888);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 860:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.drawing\");\n\n/***/ }),\n\n/***/ 888:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(889), __webpack_require__(860) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var math = Math,\n\t atan = math.atan,\n\t exp = math.exp,\n\t pow = math.pow,\n\t sin = math.sin,\n\t log = math.log,\n\t tan = math.tan,\n\n\t kendo = window.kendo,\n\t Class = kendo.Class,\n\n\t dataviz = kendo.dataviz,\n\t deepExtend = kendo.deepExtend,\n\n\t g = kendo.geometry,\n\t Point = g.Point,\n\n\t map = dataviz.map,\n\t Location = map.Location,\n\n\t util = kendo.drawing.util,\n\t rad = util.rad,\n\t deg = util.deg,\n\t limit = util.limitValue;\n\n\t // Constants ==============================================================\n\t var PI = math.PI,\n\t PI_DIV_2 = PI / 2,\n\t PI_DIV_4 = PI / 4,\n\t DEG_TO_RAD = PI / 180;\n\n\t // Coordinate reference systems ===========================================\n\t var WGS84 = {\n\t a: 6378137, // Semi-major radius\n\t b: 6356752.314245179, // Semi-minor radius\n\t f: 0.0033528106647474805, // Flattening\n\t e: 0.08181919084262149 // Eccentricity\n\t };\n\n\t // WGS 84 / World Mercator\n\t var Mercator = Class.extend({\n\t init: function(options) {\n\t this._initOptions(options);\n\t },\n\n\t MAX_LNG: 180,\n\t MAX_LAT: 85.0840590501,\n\t INVERSE_ITERATIONS: 15,\n\t INVERSE_CONVERGENCE: 1e-12,\n\n\t options: {\n\t centralMeridian: 0,\n\t datum: WGS84\n\t },\n\n\t forward: function(loc, clamp) {\n\t var proj = this,\n\t options = proj.options,\n\t datum = options.datum,\n\t r = datum.a,\n\t lng0 = options.centralMeridian,\n\t lat = limit(loc.lat, -proj.MAX_LAT, proj.MAX_LAT),\n\t lng = clamp ? limit(loc.lng, -proj.MAX_LNG, proj.MAX_LNG) : loc.lng,\n\t x = rad(lng - lng0) * r,\n\t y = proj._projectLat(lat);\n\n\t return new Point(x, y);\n\t },\n\n\t _projectLat: function(lat) {\n\t var datum = this.options.datum,\n\t ecc = datum.e,\n\t r = datum.a,\n\t y = rad(lat),\n\t ts = tan(PI_DIV_4 + y / 2),\n\t con = ecc * sin(y),\n\t p = pow((1 - con) / (1 + con), ecc / 2);\n\n\t // See:\n\t // http://en.wikipedia.org/wiki/Mercator_projection#Generalization_to_the_ellipsoid\n\t return r * log(ts * p);\n\t },\n\n\t inverse: function(point, clamp) {\n\t var proj = this,\n\t options = proj.options,\n\t datum = options.datum,\n\t r = datum.a,\n\t lng0 = options.centralMeridian,\n\t lng = point.x / (DEG_TO_RAD * r) + lng0,\n\t lat = limit(proj._inverseY(point.y), -proj.MAX_LAT, proj.MAX_LAT);\n\n\t if (clamp) {\n\t lng = limit(lng, -proj.MAX_LNG, proj.MAX_LNG);\n\t }\n\n\t return new Location(lat, lng);\n\t },\n\n\t _inverseY: function(y) {\n\t var proj = this,\n\t datum = proj.options.datum,\n\t r = datum.a,\n\t ecc = datum.e,\n\t ecch = ecc / 2,\n\t ts = exp(-y / r),\n\t phi = PI_DIV_2 - 2 * atan(ts),\n\t i;\n\n\t for (i = 0; i <= proj.INVERSE_ITERATIONS; i++) {\n\t var con = ecc * sin(phi),\n\t p = pow((1 - con) / (1 + con), ecch),\n\t dphi = PI_DIV_2 - 2 * atan(ts * p) - phi;\n\n\t phi += dphi;\n\n\t if (math.abs(dphi) <= proj.INVERSE_CONVERGENCE) {\n\t break;\n\t }\n\t }\n\n\t return deg(phi);\n\t }\n\t });\n\n\t // WGS 84 / Pseudo-Mercator\n\t // Used by Google Maps, Bing, OSM, etc.\n\t // Spherical projection of ellipsoidal coordinates.\n\t var SphericalMercator = Mercator.extend({\n\t MAX_LAT: 85.0511287798,\n\n\t _projectLat: function(lat) {\n\t var r = this.options.datum.a,\n\t y = rad(lat),\n\t ts = tan(PI_DIV_4 + y / 2);\n\n\t return r * log(ts);\n\t },\n\n\t _inverseY: function(y) {\n\t var r = this.options.datum.a,\n\t ts = exp(-y / r);\n\n\t return deg(PI_DIV_2 - (2 * atan(ts)));\n\t }\n\t });\n\n\t var Equirectangular = Class.extend({\n\t forward: function(loc) {\n\t return new Point(loc.lng, loc.lat);\n\t },\n\n\t inverse: function(point) {\n\t return new Location(point.y, point.x);\n\t }\n\t });\n\n\t // TODO: Better (less cryptic name) for this class(es)\n\t var EPSG3857 = Class.extend({\n\t init: function() {\n\t var crs = this,\n\t proj = crs._proj = new SphericalMercator();\n\n\t var c = this.c = 2 * PI * proj.options.datum.a;\n\n\t // Scale circumference to 1, mirror Y and shift origin to top left\n\t this._tm = g.transform().translate(0.5, 0.5).scale(1/c, -1/c);\n\n\t // Inverse transform matrix\n\t this._itm = g.transform().scale(c, -c).translate(-0.5, -0.5);\n\t },\n\n\t // Location <-> Point (screen coordinates for a given scale)\n\t toPoint: function(loc, scale, clamp) {\n\t var point = this._proj.forward(loc, clamp);\n\n\t return point\n\t .transform(this._tm)\n\t .scale(scale || 1);\n\t },\n\n\t toLocation: function(point, scale, clamp) {\n\t point = point\n\t .clone()\n\t .scale(1 / (scale || 1))\n\t .transform(this._itm);\n\n\t return this._proj.inverse(point, clamp);\n\t }\n\t });\n\n\t var EPSG3395 = Class.extend({\n\t init: function() {\n\t this._proj = new Mercator();\n\t },\n\n\t toPoint: function(loc) {\n\t return this._proj.forward(loc);\n\t },\n\n\t toLocation: function(point) {\n\t return this._proj.inverse(point);\n\t }\n\t });\n\n\t // WGS 84\n\t var EPSG4326 = Class.extend({\n\t init: function() {\n\t this._proj = new Equirectangular();\n\t },\n\n\t toPoint: function(loc) {\n\t return this._proj.forward(loc);\n\t },\n\n\t toLocation: function(point) {\n\t return this._proj.inverse(point);\n\t }\n\t });\n\n\t // Exports ================================================================\n\t deepExtend(dataviz, {\n\t map: {\n\t crs: {\n\t EPSG3395: EPSG3395,\n\t EPSG3857: EPSG3857,\n\t EPSG4326: EPSG4326\n\t },\n\t datums: {\n\t WGS84: WGS84\n\t },\n\t projections: {\n\t Equirectangular: Equirectangular,\n\t Mercator: Mercator,\n\t SphericalMercator: SphericalMercator\n\t }\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 889:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./location\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(890);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 890:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(891), __webpack_require__(892) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var proxy = $.proxy,\n\n\t kendo = window.kendo,\n\t Class = kendo.Class,\n\n\t dataviz = kendo.dataviz,\n\t deepExtend = kendo.deepExtend,\n\n\t Extent = dataviz.map.Extent,\n\n\t util = kendo.drawing.util,\n\t defined = util.defined;\n\n\t // Implementation =========================================================\n\t var Layer = Class.extend({\n\t init: function(map, options) {\n\t this._initOptions(options);\n\t this.map = map;\n\n\t this.element = $(\"
\")\n\t .css({\n\t \"zIndex\": this.options.zIndex,\n\t \"opacity\": this.options.opacity\n\t })\n\t .appendTo(map.scrollElement);\n\n\t this._beforeReset = proxy(this._beforeReset, this);\n\t this._reset = proxy(this._reset, this);\n\t this._resize = proxy(this._resize, this);\n\t this._panEnd = proxy(this._panEnd, this);\n\t this._activate();\n\n\t this._updateAttribution();\n\t },\n\n\t destroy: function() {\n\t this._deactivate();\n\t },\n\n\t show: function() {\n\t this.reset();\n\t this._activate();\n\t this._applyExtent(true);\n\t },\n\n\t hide: function() {\n\t this._deactivate();\n\t this._setVisibility(false);\n\t },\n\n\t reset: function() {\n\t this._beforeReset();\n\t this._reset();\n\t },\n\n\t _reset: function() {\n\t this._applyExtent();\n\t },\n\n\t _beforeReset: $.noop,\n\n\t _resize: $.noop,\n\n\t _panEnd: function() {\n\t this._applyExtent();\n\t },\n\n\t _applyExtent: function() {\n\t var options = this.options;\n\n\t var zoom = this.map.zoom();\n\t var matchMinZoom = !defined(options.minZoom) || zoom >= options.minZoom;\n\t var matchMaxZoom = !defined(options.maxZoom) || zoom <= options.maxZoom;\n\n\t var extent = Extent.create(options.extent);\n\t var inside = !extent || extent.overlaps(this.map.extent());\n\n\t this._setVisibility(matchMinZoom && matchMaxZoom && inside);\n\t },\n\n\t _setVisibility: function(visible) {\n\t this.element.css(\"display\", visible ? \"\" : \"none\");\n\t },\n\n\t _activate: function() {\n\t var map = this.map;\n\t this._deactivate();\n\t map.bind(\"beforeReset\", this._beforeReset);\n\t map.bind(\"reset\", this._reset);\n\t map.bind(\"resize\", this._resize);\n\t map.bind(\"panEnd\", this._panEnd);\n\t },\n\n\t _deactivate: function() {\n\t var map = this.map;\n\t map.unbind(\"beforeReset\", this._beforeReset);\n\t map.unbind(\"reset\", this._reset);\n\t map.unbind(\"resize\", this._resize);\n\t map.unbind(\"panEnd\", this._panEnd);\n\t },\n\n\t _updateAttribution: function() {\n\t var attr = this.map.attribution;\n\n\t if (attr) {\n\t attr.add(this.options.attribution);\n\t }\n\t }\n\t });\n\n\t // Exports ================================================================\n\t deepExtend(dataviz, {\n\t map: {\n\t layers: {\n\t Layer: Layer\n\t }\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 891:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../../kendo.core\");\n\n/***/ }),\n\n/***/ 892:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../location\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(893);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 893:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define) {\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(894) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function() {\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var kendo = window.kendo,\n\n\t dataviz = kendo.dataviz,\n\t deepExtend = kendo.deepExtend,\n\t defined = kendo.drawing.util.defined,\n\n\t Extent = dataviz.map.Extent,\n\t Location = dataviz.map.Location,\n\t TileLayer = dataviz.map.layers.TileLayer,\n\t TileView = dataviz.map.layers.TileView;\n\n\t // Bing tile layer =============================================================\n\t var BingLayer = TileLayer.extend({\n\t init: function(map, options) {\n\t this.options.baseUrl =\n\t this._scheme() +\n\t \"://dev.virtualearth.net/REST/v1/Imagery/Metadata/\";\n\n\t TileLayer.fn.init.call(this, map, options);\n\n\t this._onMetadata = $.proxy(this._onMetadata, this);\n\t this._fetchMetadata();\n\t },\n\n\t options: {\n\t imagerySet: \"road\"\n\t },\n\n\t _fetchMetadata: function() {\n\t var options = this.options;\n\n\t if (!options.key) {\n\t throw new Error(\"Bing tile layer: API key is required\");\n\t }\n\n\t $.ajax({\n\t url: options.baseUrl + options.imagerySet,\n\t data: {\n\t output: \"json\",\n\t include: \"ImageryProviders\",\n\t key: options.key,\n\t uriScheme: this._scheme()\n\t },\n\t type: \"get\",\n\t dataType: \"jsonp\",\n\t jsonp: \"jsonp\",\n\t success: this._onMetadata\n\t });\n\t },\n\n\t _scheme: function(proto) {\n\t proto = proto || window.location.protocol;\n\t return proto.replace(\":\", \"\") === \"https\" ? \"https\" : \"http\";\n\t },\n\n\t _onMetadata: function(data) {\n\t if (data && data.resourceSets.length) {\n\t var resource = this.resource = data.resourceSets[0].resources[0];\n\n\t deepExtend(this._view.options, {\n\t urlTemplate: resource.imageUrl\n\t .replace(\"{subdomain}\", \"#= subdomain #\")\n\t .replace(\"{quadkey}\", \"#= quadkey #\")\n\t .replace(\"{culture}\", \"#= culture #\"),\n\t subdomains: resource.imageUrlSubdomains\n\t });\n\n\t var options = this.options;\n\t if (!defined(options.minZoom)) {\n\t options.minZoom = resource.zoomMin;\n\t }\n\t if (!defined(options.maxZoom)) {\n\t options.maxZoom = resource.zoomMax;\n\t }\n\n\t this._addAttribution();\n\n\t if (this.element.css(\"display\") !== \"none\") {\n\t this._reset();\n\t }\n\t }\n\t },\n\n\t _viewType: function() {\n\t return BingView;\n\t },\n\n\t _addAttribution: function() {\n\t var attr = this.map.attribution;\n\t if (attr) {\n\t var items = this.resource.imageryProviders;\n\t if (items) {\n\t for (var i = 0; i < items.length; i++) {\n\t var item = items[i];\n\t for (var y = 0; y < item.coverageAreas.length; y++) {\n\t var area = item.coverageAreas[y];\n\t attr.add({\n\t text: item.attribution,\n\t minZoom: area.zoomMin,\n\t maxZoom: area.zoomMax,\n\t extent: new Extent(\n\t new Location(area.bbox[2], area.bbox[1]),\n\t new Location(area.bbox[0], area.bbox[3])\n\t )\n\t });\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t imagerySet: function(value) {\n\t if (value) {\n\t this.options.imagerySet = value;\n\t this.map.attribution.clear();\n\t this._fetchMetadata();\n\t } else {\n\t return this.options.imagerySet;\n\t }\n\t }\n\t });\n\n\t var BingView = TileView.extend({\n\t options: {\n\t culture: \"en-US\"\n\t },\n\n\t tileOptions: function(currentIndex) {\n\t var options = TileView.fn.tileOptions.call(this, currentIndex);\n\n\t options.culture = this.options.culture;\n\t options.quadkey = this.tileQuadKey(this.wrapIndex(currentIndex));\n\n\t return options;\n\t },\n\n\t tileQuadKey: function(index) {\n\t var quadKey = \"\",\n\t digit, mask, i;\n\n\t for (i = this._zoom; i > 0; i--) {\n\t digit = 0;\n\t mask = 1 << (i - 1);\n\n\t if ((index.x & mask) !== 0) {\n\t digit++;\n\t }\n\n\t if ((index.y & mask) !== 0) {\n\t digit += 2;\n\t }\n\n\t quadKey += digit;\n\t }\n\n\t return quadKey;\n\t }\n\t });\n\n\t // Exports ================================================================\n\t deepExtend(dataviz, {\n\t map: {\n\t layers: {\n\t bing: BingLayer,\n\t BingLayer: BingLayer,\n\t BingView: BingView\n\t }\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 894:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./tile\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(895);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 895:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(896) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var kendo = window.kendo,\n\t getter = kendo.getter,\n\n\t dataviz = kendo.dataviz,\n\t deepExtend = kendo.deepExtend,\n\n\t g = kendo.geometry,\n\t d = kendo.drawing,\n\n\t util = d.util,\n\t defined = util.defined,\n\n\t map = dataviz.map,\n\t Location = map.Location,\n\t ShapeLayer = map.layers.ShapeLayer;\n\n\t // Implementation =========================================================\n\t var BubbleLayer = ShapeLayer.extend({\n\t options: {\n\t autoBind: true,\n\t locationField: \"location\",\n\t valueField: \"value\",\n\t minSize: 0,\n\t maxSize: 100,\n\t scale: \"sqrt\",\n\t symbol: \"circle\"\n\t },\n\n\t _load: function(data) {\n\t this.surface.clear();\n\n\t if (data.length === 0) {\n\t return;\n\t }\n\n\t var opt = this.options;\n\t var getValue = getter(opt.valueField);\n\n\t data = data.slice(0);\n\t data.sort(function(a, b) {\n\t return getValue(b) - getValue(a);\n\t });\n\n\t var scaleType = this._scaleType();\n\t var scale;\n\t for (var i = 0; i < data.length; i++) {\n\t var dataItem = data[i];\n\t var location = getter(opt.locationField)(dataItem);\n\t var value = getter(opt.valueField)(dataItem);\n\n\t if (defined(location) && defined(value)) {\n\t if (!scale) {\n\t scale = new scaleType([0, value], [opt.minSize, opt.maxSize]);\n\t }\n\n\t location = Location.create(location);\n\t var center = this.map.locationToView(location);\n\t var size = scale.map(value);\n\n\t var symbol = this._createSymbol({\n\t center: center,\n\t size: size,\n\t style: opt.style,\n\t dataItem: dataItem,\n\t location: location\n\t });\n\n\t symbol.dataItem = dataItem;\n\t symbol.location = location;\n\t symbol.value = value;\n\n\t this._drawSymbol(symbol);\n\t }\n\t }\n\t },\n\n\t _scaleType: function() {\n\t var scale = this.options.scale;\n\n\t if (kendo.isFunction(scale)) {\n\t return scale;\n\t }\n\n\t return dataviz.map.scales[scale];\n\t },\n\n\t _createSymbol: function(args) {\n\t var symbol = this.options.symbol;\n\t if (!kendo.isFunction(symbol)) {\n\t symbol = dataviz.map.symbols[symbol];\n\t }\n\n\t return symbol(args);\n\t },\n\n\t _drawSymbol: function(shape) {\n\t var args = { layer: this, shape: shape };\n\t var cancelled = this.map.trigger(\"shapeCreated\", args);\n\t if (!cancelled) {\n\t this.surface.draw(shape);\n\t }\n\t }\n\t });\n\n\t var SqrtScale = kendo.Class.extend({\n\t init: function(domain, range) {\n\t this._domain = domain;\n\t this._range = range;\n\n\t var domainRange = Math.sqrt(domain[1]) - Math.sqrt(domain[0]);\n\t var outputRange = range[1] - range[0];\n\t this._ratio = outputRange / domainRange;\n\t },\n\n\t map: function(value) {\n\t var rel = (Math.sqrt(value) - Math.sqrt(this._domain[0])) * this._ratio;\n\t return this._range[0] + rel;\n\t }\n\t });\n\n\t var Symbols = {\n\t circle: function (args) {\n\t var geo = new g.Circle(args.center, args.size / 2);\n\t return new d.Circle(geo, args.style);\n\t },\n\n\t square: function(args) {\n\t var path = new d.Path(args.style);\n\t var halfSize = args.size / 2;\n\t var center = args.center;\n\n\t path.moveTo(center.x - halfSize, center.y - halfSize)\n\t .lineTo(center.x + halfSize, center.y - halfSize)\n\t .lineTo(center.x + halfSize, center.y + halfSize)\n\t .lineTo(center.x - halfSize, center.y + halfSize)\n\t .close();\n\n\t return path;\n\t }\n\t };\n\n\t // Exports ================================================================\n\t deepExtend(dataviz, {\n\t map: {\n\t layers: {\n\t bubble: BubbleLayer,\n\t BubbleLayer: BubbleLayer\n\t },\n\t scales: {\n\t sqrt: SqrtScale\n\t },\n\t symbols: Symbols\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 896:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./shape\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(897);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 892:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../location\");\n\n/***/ }),\n\n/***/ 897:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(898), __webpack_require__(892),\n\t __webpack_require__(899), __webpack_require__(900) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var doc = document,\n\t math = Math,\n\t indexOf = $.inArray,\n\t proxy = $.proxy,\n\n\t kendo = window.kendo,\n\t Class = kendo.Class,\n\t DataSource = kendo.data.DataSource,\n\t Tooltip = kendo.ui.Tooltip,\n\n\t dataviz = kendo.dataviz,\n\t deepExtend = kendo.deepExtend,\n\n\t map = dataviz.map,\n\t Location = map.Location,\n\t Layer = map.layers.Layer;\n\n\t // Implementation =========================================================\n\t var MarkerLayer = Layer.extend({\n\t init: function(map, options) {\n\t Layer.fn.init.call(this, map, options);\n\n\t this._markerClick = proxy(this._markerClick, this);\n\t this.element.on(\"click\", \".k-marker\", this._markerClick);\n\n\t this.items = [];\n\t this._initDataSource();\n\t },\n\n\t destroy: function() {\n\t Layer.fn.destroy.call(this);\n\n\t this.element.off(\"click\", \".k-marker\", this._markerClick);\n\n\t this.dataSource.unbind(\"change\", this._dataChange);\n\t this.clear();\n\t },\n\n\t options: {\n\t zIndex: 1000,\n\t autoBind: true,\n\t dataSource: {},\n\t locationField: \"location\",\n\t titleField: \"title\"\n\t },\n\n\t add: function(arg) {\n\t if ($.isArray(arg)) {\n\t for (var i = 0; i < arg.length; i++) {\n\t this._addOne(arg[i]);\n\t }\n\t } else {\n\t return this._addOne(arg);\n\t }\n\t },\n\n\t remove: function(marker) {\n\t marker.destroy();\n\n\t var index = indexOf(marker, this.items);\n\t if (index > -1) {\n\t this.items.splice(index, 1);\n\t }\n\t },\n\n\t clear: function() {\n\t for (var i = 0; i < this.items.length; i++) {\n\t this.items[i].destroy();\n\t }\n\n\t this.items = [];\n\t },\n\n\t update: function(marker) {\n\t var loc = marker.location();\n\t if (loc) {\n\t marker.showAt(this.map.locationToView(loc));\n\n\t var args = { marker: marker, layer: this };\n\t this.map.trigger(\"markerActivate\", args);\n\t }\n\t },\n\n\t _reset: function() {\n\t Layer.fn._reset.call(this);\n\t var items = this.items;\n\t for (var i = 0; i < items.length; i++) {\n\t this.update(items[i]);\n\t }\n\t },\n\n\t bind: function (options, dataItem) {\n\t var marker = map.Marker.create(options, this.options);\n\t marker.dataItem = dataItem;\n\n\t var args = { marker: marker, layer: this };\n\t var cancelled = this.map.trigger(\"markerCreated\", args);\n\t if (!cancelled) {\n\t this.add(marker);\n\t return marker;\n\t }\n\t },\n\n\t setDataSource: function(dataSource) {\n\t if (this.dataSource) {\n\t this.dataSource.unbind(\"change\", this._dataChange);\n\t }\n\n\t this.dataSource = kendo.data.DataSource.create(dataSource);\n\t this.dataSource.bind(\"change\", this._dataChange);\n\n\t if (this.options.autoBind) {\n\t this.dataSource.fetch();\n\t }\n\t },\n\n\t _addOne: function(arg) {\n\t var marker = Marker.create(arg, this.options);\n\t marker.addTo(this);\n\n\t return marker;\n\t },\n\n\t _initDataSource: function() {\n\t var dsOptions = this.options.dataSource;\n\t this._dataChange = proxy(this._dataChange, this);\n\t this.dataSource = DataSource\n\t .create(dsOptions)\n\t .bind(\"change\", this._dataChange);\n\n\t if (dsOptions && this.options.autoBind) {\n\t this.dataSource.fetch();\n\t }\n\t },\n\n\t _dataChange: function(e) {\n\t this._load(e.sender.view());\n\t },\n\n\t _load: function(data) {\n\t this._data = data;\n\t this.clear();\n\n\t var getLocation = kendo.getter(this.options.locationField);\n\t var getTitle = kendo.getter(this.options.titleField);\n\t for (var i = 0; i < data.length; i++) {\n\t var dataItem = data[i];\n\t this.bind({\n\t location: getLocation(dataItem),\n\t title: getTitle(dataItem)\n\t }, dataItem);\n\t }\n\t },\n\n\t _markerClick: function(e) {\n\t var args = { marker: $(e.target).data(\"kendoMarker\"), layer: this };\n\t this.map.trigger(\"markerClick\", args);\n\t }\n\t });\n\n\t var Marker = Class.extend({\n\t init: function(options) {\n\t this.options = options || {};\n\t },\n\n\t addTo: function(parent) {\n\t this.layer = parent.markers || parent;\n\t this.layer.items.push(this);\n\t this.layer.update(this);\n\t },\n\n\t location: function(value) {\n\t if (value) {\n\t this.options.location = Location.create(value).toArray();\n\n\t if (this.layer) {\n\t this.layer.update(this);\n\t }\n\n\t return this;\n\t } else {\n\t return Location.create(this.options.location);\n\t }\n\t },\n\n\t showAt: function(point) {\n\t this.render();\n\t this.element.css({\n\t left: math.round(point.x),\n\t top: math.round(point.y)\n\t });\n\n\t if (this.tooltip && this.tooltip.popup) {\n\t // TODO: Expose popup/tooltip updatePosition? method\n\t this.tooltip.popup._position();\n\t }\n\t },\n\n\t hide: function() {\n\t if (this.element) {\n\t this.element.remove();\n\t this.element = null;\n\t }\n\n\t if (this.tooltip) {\n\t this.tooltip.destroy();\n\t this.tooltip = null;\n\t }\n\t },\n\n\t destroy: function() {\n\t this.layer = null;\n\t this.hide();\n\t },\n\n\t render: function() {\n\t if (!this.element) {\n\t var options = this.options;\n\t var layer = this.layer;\n\n\t this.element = $(doc.createElement(\"span\"))\n\t .addClass(\"k-marker k-icon k-i-marker-\" + kendo.toHyphens(options.shape || \"pin\"))\n\t .attr(\"title\", options.title)\n\t .attr(options.attributes || {})\n\t .data(\"kendoMarker\", this)\n\t .css(\"zIndex\", options.zIndex);\n\n\t if (layer) {\n\t layer.element.append(this.element);\n\t }\n\n\t this.renderTooltip();\n\t }\n\t },\n\n\t renderTooltip: function() {\n\t var marker = this;\n\t var title = marker.options.title;\n\t var options = marker.options.tooltip || {};\n\n\t if (options && Tooltip) {\n\t var template = options.template;\n\t if (template) {\n\t var contentTemplate = kendo.template(template);\n\t options.content = function(e) {\n\t e.location = marker.location();\n\t e.marker = marker;\n\t return contentTemplate(e);\n\t };\n\t }\n\n\t if (title || options.content || options.contentUrl) {\n\t this.tooltip = new Tooltip(this.element, options);\n\t this.tooltip.marker = this;\n\t }\n\t }\n\t }\n\t });\n\n\t Marker.create = function(arg, defaults) {\n\t if (arg instanceof Marker) {\n\t return arg;\n\t }\n\n\t return new Marker(deepExtend({}, defaults, arg));\n\t };\n\n\t // Exports ================================================================\n\t deepExtend(dataviz, {\n\t map: {\n\t layers: {\n\t marker: MarkerLayer,\n\t MarkerLayer: MarkerLayer\n\t },\n\t Marker: Marker\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 898:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./base\");\n\n/***/ }),\n\n/***/ 899:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../../kendo.data\");\n\n/***/ }),\n\n/***/ 900:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../../kendo.tooltip\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(901);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 892:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../location\");\n\n/***/ }),\n\n/***/ 898:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./base\");\n\n/***/ }),\n\n/***/ 901:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(898), __webpack_require__(892)], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var proxy = $.proxy,\n\n\t kendo = window.kendo,\n\t Class = kendo.Class,\n\t DataSource = kendo.data.DataSource,\n\n\t dataviz = kendo.dataviz,\n\t deepExtend = kendo.deepExtend,\n\n\t g = kendo.geometry,\n\n\t d = kendo.drawing,\n\t Group = d.Group,\n\n\t last = d.util.last,\n\t defined = d.util.defined,\n\n\t map = dataviz.map,\n\t Location = map.Location,\n\t Layer = map.layers.Layer;\n\n\t // Implementation =========================================================\n\t var ShapeLayer = Layer.extend({\n\t init: function(map, options) {\n\n\t this._pan = proxy(this._pan, this);\n\n\t Layer.fn.init.call(this, map, options);\n\n\t this.surface = d.Surface.create(this.element, {\n\t width: map.scrollElement.width(),\n\t height: map.scrollElement.height()\n\t });\n\n\t this._initRoot();\n\n\t this.movable = new kendo.ui.Movable(this.surface.element);\n\t this._markers = [];\n\n\t this._click = this._handler(\"shapeClick\");\n\t this.surface.bind(\"click\", this._click);\n\n\t this._mouseenter = this._handler(\"shapeMouseEnter\");\n\t this.surface.bind(\"mouseenter\", this._mouseenter);\n\n\t this._mouseleave = this._handler(\"shapeMouseLeave\");\n\t this.surface.bind(\"mouseleave\", this._mouseleave);\n\n\t this._initDataSource();\n\t },\n\n\t options: {\n\t autoBind: true\n\t },\n\n\t destroy: function() {\n\t Layer.fn.destroy.call(this);\n\n\t this.surface.destroy();\n\t this.dataSource.unbind(\"change\", this._dataChange);\n\t },\n\n\t setDataSource: function(dataSource) {\n\t if (this.dataSource) {\n\t this.dataSource.unbind(\"change\", this._dataChange);\n\t }\n\n\t this.dataSource = kendo.data.DataSource.create(dataSource);\n\t this.dataSource.bind(\"change\", this._dataChange);\n\n\t if (this.options.autoBind) {\n\t this.dataSource.fetch();\n\t }\n\t },\n\n\t _reset: function() {\n\t Layer.fn._reset.call(this);\n\t this._translateSurface();\n\n\t if (this._data) {\n\t this._load(this._data);\n\t }\n\t },\n\n\t _initRoot: function() {\n\t this._root = new Group();\n\t this.surface.draw(this._root);\n\t },\n\n\t _beforeReset: function() {\n\t this.surface.clear();\n\t this._initRoot();\n\t },\n\n\t _resize: function() {\n\t this.surface.size(this.map.size());\n\t },\n\n\t _initDataSource: function() {\n\t var dsOptions = this.options.dataSource;\n\t this._dataChange = proxy(this._dataChange, this);\n\t this.dataSource = DataSource\n\t .create(dsOptions)\n\t .bind(\"change\", this._dataChange);\n\n\t if (dsOptions && this.options.autoBind) {\n\t this.dataSource.fetch();\n\t }\n\t },\n\n\t _dataChange: function(e) {\n\t this._data = e.sender.view();\n\t this._load(this._data);\n\t },\n\n\t _load: function(data) {\n\t this._clearMarkers();\n\n\t if (!this._loader) {\n\t this._loader = new GeoJSONLoader(this.map, this.options.style, this);\n\t }\n\n\t var container = new Group();\n\t for (var i = 0; i < data.length; i++) {\n\t var shape = this._loader.parse(data[i]);\n\t if (shape) {\n\t container.append(shape);\n\t }\n\t }\n\n\t this._root.clear();\n\t this._root.append(container);\n\t },\n\n\t shapeCreated: function(shape) {\n\t var cancelled = false;\n\t if (shape instanceof d.Circle) {\n\t cancelled = defined(this._createMarker(shape));\n\t }\n\n\t if (!cancelled) {\n\t var args = { layer: this, shape: shape };\n\t cancelled = this.map.trigger(\"shapeCreated\", args);\n\t }\n\n\t return cancelled;\n\t },\n\n\t featureCreated: function(e) {\n\t e.layer = this;\n\t this.map.trigger(\"shapeFeatureCreated\", e);\n\t },\n\n\t _createMarker: function(shape) {\n\t var marker = this.map.markers.bind({\n\t location: shape.location\n\t }, shape.dataItem);\n\n\t if (marker) {\n\t this._markers.push(marker);\n\t }\n\n\t return marker;\n\t },\n\n\t _clearMarkers: function() {\n\t for (var i = 0; i < this._markers.length; i++) {\n\t this.map.markers.remove(this._markers[i]);\n\t }\n\t this._markers = [];\n\t },\n\n\t _pan: function() {\n\t if (!this._panning) {\n\t this._panning = true;\n\t this.surface.suspendTracking();\n\t }\n\t },\n\n\t _panEnd: function(e) {\n\t Layer.fn._panEnd.call(this, e);\n\t this._translateSurface();\n\t this.surface.resumeTracking();\n\t this._panning = false;\n\t },\n\n\t _translateSurface: function() {\n\t var map = this.map;\n\t var nw = map.locationToView(map.extent().nw);\n\n\t if (this.surface.translate) {\n\t this.surface.translate(nw);\n\t this.movable.moveTo({ x: nw.x, y: nw.y });\n\t }\n\t },\n\n\t _handler: function(event) {\n\t var layer = this;\n\t return function(e) {\n\t if (e.element) {\n\t var args = {\n\t layer: layer,\n\t shape: e.element,\n\t originalEvent: e.originalEvent\n\t };\n\n\t layer.map.trigger(event, args);\n\t }\n\t };\n\t },\n\n\t _activate: function() {\n\t Layer.fn._activate.call(this);\n\n\t this.map.bind(\"pan\", this._pan);\n\t },\n\n\t _deactivate: function() {\n\t Layer.fn._deactivate.call(this);\n\n\t this.map.unbind(\"pan\", this._pan);\n\t }\n\t });\n\n\t var GeoJSONLoader = Class.extend({\n\t init: function(locator, defaultStyle, observer) {\n\t this.observer = observer;\n\t this.locator = locator;\n\t this.style = defaultStyle;\n\t },\n\n\t parse: function(item) {\n\t var root = new Group();\n\t var unwrap = true;\n\n\t if (item.type === \"Feature\") {\n\t unwrap = false;\n\t this._loadGeometryTo(root, item.geometry, item);\n\t this._featureCreated(root, item);\n\t } else {\n\t this._loadGeometryTo(root, item, item);\n\t }\n\n\t if (unwrap && root.children.length < 2) {\n\t root = root.children[0];\n\t }\n\n\t return root;\n\t },\n\n\t _shapeCreated: function(shape) {\n\t var cancelled = false;\n\n\t if (this.observer && this.observer.shapeCreated) {\n\t cancelled = this.observer.shapeCreated(shape);\n\t }\n\n\t return cancelled;\n\t },\n\n\t _featureCreated: function(group, dataItem) {\n\t if (this.observer && this.observer.featureCreated) {\n\t this.observer.featureCreated({\n\t group: group,\n\t dataItem: dataItem,\n\t properties: dataItem.properties\n\t });\n\t }\n\t },\n\n\t _loadGeometryTo: function(container, geometry, dataItem) {\n\t var coords = geometry.coordinates;\n\t var i;\n\t var path;\n\n\t switch(geometry.type) {\n\t case \"LineString\":\n\t path = this._loadPolygon(container, [coords], dataItem);\n\t this._setLineFill(path);\n\t break;\n\n\t case \"MultiLineString\":\n\t for (i = 0; i < coords.length; i++) {\n\t path = this._loadPolygon(container, [coords[i]], dataItem);\n\t this._setLineFill(path);\n\t }\n\t break;\n\n\t case \"Polygon\":\n\t this._loadPolygon(container, coords, dataItem);\n\t break;\n\n\t case \"MultiPolygon\":\n\t for (i = 0; i < coords.length; i++) {\n\t this._loadPolygon(container, coords[i], dataItem);\n\t }\n\t break;\n\n\t case \"Point\":\n\t this._loadPoint(container, coords, dataItem);\n\t break;\n\n\t case \"MultiPoint\":\n\t for (i = 0; i < coords.length; i++) {\n\t this._loadPoint(container, coords[i], dataItem);\n\t }\n\t break;\n\t }\n\t },\n\n\t _setLineFill: function(path) {\n\t var segments = path.segments;\n\t if (segments.length < 4 || !segments[0].anchor().equals(last(segments).anchor())) {\n\t path.options.fill = null;\n\t }\n\t },\n\n\t _loadShape: function(container, shape) {\n\t if (!this._shapeCreated(shape)) {\n\t container.append(shape);\n\t }\n\n\t return shape;\n\t },\n\n\t _loadPolygon: function(container, rings, dataItem) {\n\t var shape = this._buildPolygon(rings);\n\t shape.dataItem = dataItem;\n\n\t return this._loadShape(container, shape);\n\t },\n\n\t _buildPolygon: function(rings) {\n\t var type = rings.length > 1 ? d.MultiPath : d.Path;\n\t var path = new type(this.style);\n\n\t for (var i = 0; i < rings.length; i++) {\n\t for (var j = 0; j < rings[i].length; j++) {\n\t var point = this.locator.locationToView(\n\t Location.fromLngLat(rings[i][j])\n\t );\n\n\t if (j === 0) {\n\t path.moveTo(point.x, point.y);\n\t } else {\n\t path.lineTo(point.x, point.y);\n\t }\n\t }\n\t }\n\n\t return path;\n\t },\n\n\t _loadPoint: function(container, coords, dataItem) {\n\t var location = Location.fromLngLat(coords);\n\t var point = this.locator.locationToView(location);\n\n\t var circle = new g.Circle(point, 10);\n\t var shape = new d.Circle(circle, this.style);\n\t shape.dataItem = dataItem;\n\t shape.location = location;\n\n\t return this._loadShape(container, shape);\n\t }\n\t });\n\n\t // Exports ================================================================\n\t deepExtend(kendo.data, {\n\t schemas: {\n\t geojson: {\n\t type: \"json\",\n\t data: function(data) {\n\t if (data.type === \"FeatureCollection\") {\n\t return data.features;\n\t }\n\n\t if (data.type === \"GeometryCollection\") {\n\t return data.geometries;\n\t }\n\n\t return data;\n\t }\n\t }\n\t },\n\t transports: {\n\t geojson: {\n\t read: {\n\t dataType: \"json\"\n\t }\n\t }\n\t }\n\t });\n\n\t deepExtend(dataviz, {\n\t map: {\n\t layers: {\n\t shape: ShapeLayer,\n\t ShapeLayer: ShapeLayer\n\t },\n\t GeoJSONLoader: GeoJSONLoader\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(902);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 892:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../location\");\n\n/***/ }),\n\n/***/ 898:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./base\");\n\n/***/ }),\n\n/***/ 902:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define) {\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(898), __webpack_require__(892) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function() {\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var math = Math,\n\n\t proxy = $.proxy,\n\n\t kendo = window.kendo,\n\t Class = kendo.Class,\n\t template = kendo.template,\n\n\t dataviz = kendo.dataviz,\n\t deepExtend = kendo.deepExtend,\n\n\t g = kendo.geometry,\n\t Point = g.Point,\n\n\t Layer = dataviz.map.layers.Layer,\n\n\t util = kendo.util,\n\t renderSize = util.renderSize,\n\n\t drawingUtil = kendo.drawing.util,\n\t round = drawingUtil.round,\n\t limit = drawingUtil.limitValue;\n\n\t // Image tile layer =============================================================\n\t var TileLayer = Layer.extend({\n\t init: function(map, options) {\n\t Layer.fn.init.call(this, map, options);\n\n\t if (typeof this.options.subdomains === \"string\") {\n\t this.options.subdomains = this.options.subdomains.split(\"\");\n\t }\n\n\t var viewType = this._viewType();\n\t this._view = new viewType(this.element, this.options);\n\t },\n\n\t destroy: function() {\n\t Layer.fn.destroy.call(this);\n\n\t this._view.destroy();\n\t this._view = null;\n\t },\n\n\t _beforeReset: function() {\n\t var map = this.map;\n\t var origin = map.locationToLayer(map.extent().nw).round();\n\t this._view.viewOrigin(origin);\n\t },\n\n\t _reset: function() {\n\t Layer.fn._reset.call(this);\n\t this._updateView();\n\t this._view.reset();\n\t },\n\n\t _viewType: function() {\n\t return TileView;\n\t },\n\n\t _activate: function() {\n\t Layer.fn._activate.call(this);\n\n\t if (!kendo.support.mobileOS) {\n\t if (!this._pan) {\n\t this._pan = kendo.throttle(\n\t proxy(this._render, this),\n\t 100\n\t );\n\t }\n\n\t this.map.bind(\"pan\", this._pan);\n\t }\n\t },\n\n\t _deactivate: function() {\n\t Layer.fn._deactivate.call(this);\n\n\t if (this._pan) {\n\t this.map.unbind(\"pan\", this._pan);\n\t }\n\t },\n\n\t _updateView: function() {\n\t var view = this._view,\n\t map = this.map,\n\t extent = map.extent(),\n\t extentToPoint = {\n\t nw: map.locationToLayer(extent.nw).round(),\n\t se: map.locationToLayer(extent.se).round()\n\t };\n\n\t view.center(map.locationToLayer(map.center()));\n\t view.extent(extentToPoint);\n\t view.zoom(map.zoom());\n\t },\n\n\t _resize: function() {\n\t this._render();\n\t },\n\n\t _panEnd: function(e) {\n\t Layer.fn._panEnd.call(this, e);\n\t this._render();\n\t },\n\n\t _render: function() {\n\t this._updateView();\n\t this._view.render();\n\t }\n\t });\n\n\t var TileView = Class.extend({\n\t init: function(element, options) {\n\t this.element = element;\n\t this._initOptions(options);\n\n\t this.pool = new TilePool();\n\t },\n\n\t options: {\n\t tileSize: 256,\n\t subdomains: [\"a\", \"b\", \"c\"],\n\t urlTemplate: \"\"\n\t },\n\n\t center: function(center) {\n\t this._center = center;\n\t },\n\n\t extent: function(extent) {\n\t this._extent = extent;\n\t },\n\n\t viewOrigin: function(origin) {\n\t this._viewOrigin = origin;\n\t },\n\n\t zoom: function(zoom) {\n\t this._zoom = zoom;\n\t },\n\n\t pointToTileIndex: function(point) {\n\t return new Point(\n\t math.floor(point.x / this.options.tileSize),\n\t math.floor(point.y / this.options.tileSize)\n\t );\n\t },\n\n\t tileCount: function() {\n\t var size = this.size(),\n\t firstTileIndex = this.pointToTileIndex(this._extent.nw),\n\t nw = this._extent.nw,\n\t point = this.indexToPoint(firstTileIndex).translate(-nw.x, -nw.y);\n\n\t return {\n\t x: math.ceil((math.abs(point.x) + size.width) / this.options.tileSize),\n\t y: math.ceil((math.abs(point.y) + size.height) / this.options.tileSize)\n\t };\n\t },\n\n\t size: function() {\n\t var nw = this._extent.nw,\n\t se = this._extent.se,\n\t diff = se.clone().translate(-nw.x, -nw.y);\n\n\t return {\n\t width: diff.x,\n\t height: diff.y\n\t };\n\t },\n\n\t indexToPoint: function(index) {\n\t var x = index.x, y = index.y;\n\n\t return new Point(\n\t x * this.options.tileSize,\n\t y * this.options.tileSize\n\t );\n\t },\n\n\t subdomainText: function() {\n\t var subdomains = this.options.subdomains;\n\n\t return subdomains[this.subdomainIndex++ % subdomains.length];\n\t },\n\n\t destroy: function() {\n\t this.element.empty();\n\t this.pool.empty();\n\t },\n\n\t reset: function() {\n\t this.pool.reset();\n\t this.subdomainIndex = 0;\n\t this.render();\n\t },\n\n\t render: function() {\n\t var size = this.tileCount(),\n\t firstTileIndex = this.pointToTileIndex(this._extent.nw),\n\t tile, x, y;\n\n\t for (x = 0; x < size.x; x++) {\n\t for (y = 0; y < size.y; y++) {\n\t tile = this.createTile({\n\t x: firstTileIndex.x + x,\n\t y: firstTileIndex.y + y\n\t });\n\n\t if (!tile.visible) {\n\t tile.show();\n\t }\n\t }\n\t }\n\t },\n\n\t createTile: function(currentIndex) {\n\t var options = this.tileOptions(currentIndex);\n\t var tile = this.pool.get(this._center, options);\n\t if (tile.element.parent().length === 0) {\n\t this.element.append(tile.element);\n\t }\n\n\t return tile;\n\t },\n\n\t tileOptions: function(currentIndex) {\n\t var index = this.wrapIndex(currentIndex),\n\t point = this.indexToPoint(currentIndex),\n\t origin = this._viewOrigin,\n\t offset = point.clone().translate(-origin.x, -origin.y);\n\n\t return {\n\t index: index,\n\t currentIndex: currentIndex,\n\t point: point,\n\t offset: roundPoint(offset),\n\t zoom: this._zoom,\n\t size: this.options.tileSize,\n\t subdomain: this.subdomainText(),\n\t urlTemplate: this.options.urlTemplate,\n\t errorUrlTemplate: this.options.errorUrlTemplate\n\t };\n\t },\n\n\t wrapIndex: function(index) {\n\t var boundary = math.pow(2, this._zoom);\n\t return {\n\t x: this.wrapValue(index.x, boundary),\n\t y: limit(index.y, 0, boundary - 1)\n\t };\n\t },\n\n\t wrapValue: function(value, boundary) {\n\t var remainder = (math.abs(value) % boundary);\n\t if (value >= 0) {\n\t value = remainder;\n\t } else {\n\t value = boundary - (remainder === 0 ? boundary : remainder);\n\t }\n\n\t return value;\n\t }\n\t });\n\n\t var ImageTile = Class.extend({\n\t init: function(id, options) {\n\t this.id = id;\n\t this.visible = true;\n\n\t this._initOptions(options);\n\t this.createElement();\n\t this.show();\n\t },\n\n\t options: {\n\t urlTemplate: \"\",\n\t errorUrlTemplate: \"\"\n\t },\n\n\t createElement: function() {\n\t this.element = $(\"\")\n\t .css({ width: this.options.size, height: this.options.size })\n\t .on(\"error\", proxy(function(e) {\n\t if (this.errorUrl()) {\n\t e.target.setAttribute(\"src\", this.errorUrl());\n\t } else {\n\t e.target.removeAttribute(\"src\");\n\t }\n\t }, this));\n\t },\n\n\t show: function() {\n\t var element = this.element[0];\n\t element.style.top = renderSize(this.options.offset.y);\n\t element.style.left = renderSize(this.options.offset.x);\n\n\t var url = this.url();\n\t if (url) {\n\t element.setAttribute(\"src\", url);\n\t }\n\n\t element.style.visibility = \"visible\";\n\t this.visible = true;\n\t },\n\n\t hide: function() {\n\t this.element[0].style.visibility = \"hidden\";\n\t this.visible = false;\n\t },\n\n\t url: function() {\n\t var urlResult = template(this.options.urlTemplate);\n\n\t return urlResult(this.urlOptions());\n\t },\n\n\t errorUrl: function() {\n\t var urlResult = template(this.options.errorUrlTemplate);\n\n\t return urlResult(this.urlOptions());\n\t },\n\n\t urlOptions: function() {\n\t var options = this.options;\n\t return {\n\t zoom: options.zoom,\n\t subdomain: options.subdomain,\n\t z: options.zoom,\n\t x: options.index.x,\n\t y: options.index.y,\n\t s: options.subdomain,\n\t quadkey: options.quadkey,\n\t q: options.quadkey,\n\t culture: options.culture,\n\t c: options.culture\n\t };\n\t },\n\n\t destroy: function() {\n\t if (this.element) {\n\t this.element.remove();\n\t this.element = null;\n\t }\n\t }\n\t });\n\n\t var TilePool = Class.extend({\n\t init: function() {\n\t this._items = [];\n\t },\n\n\t options: {\n\t maxSize: 100\n\t },\n\n\t get: function(center, options) {\n\t if (this._items.length >= this.options.maxSize) {\n\t this._remove(center);\n\t }\n\n\t return this._create(options);\n\t },\n\n\t empty: function() {\n\t var items = this._items;\n\t for (var i = 0; i < items.length; i++) {\n\t items[i].destroy();\n\t }\n\n\t this._items = [];\n\t },\n\n\t reset: function() {\n\t var items = this._items;\n\t for (var i = 0; i < items.length; i++) {\n\t items[i].hide();\n\t }\n\t },\n\n\t _create: function(options) {\n\t var items = this._items;\n\t var tile;\n\n\t // Build an unique token for the image\n\t // This normally would be the URL, but we don't care about subdomains\n\t var id = util.hashKey(\n\t options.point.toString() +\n\t options.offset.toString() +\n\t options.zoom +\n\t options.urlTemplate\n\t );\n\n\t for (var i = 0; i < items.length; i++) {\n\t if (items[i].id === id) {\n\t tile = items[i];\n\t break;\n\t }\n\t }\n\n\t if (tile) {\n\t tile.show();\n\t } else {\n\t tile = new ImageTile(id, options);\n\t this._items.push(tile);\n\t }\n\n\t return tile;\n\t },\n\n\t _remove: function(center) {\n\t var items = this._items;\n\t var maxDist = -1;\n\t var index = -1;\n\n\t for (var i = 0; i < items.length; i++) {\n\t var dist = items[i].options.point.distanceTo(center);\n\t if (dist > maxDist && !items[i].visible) {\n\t index = i;\n\t maxDist = dist;\n\t }\n\t }\n\n\t if (index !== -1) {\n\t items[index].destroy();\n\t items.splice(index, 1);\n\t }\n\t }\n\t });\n\n\t // Methods ================================================================\n\t function roundPoint(point) {\n\t return new Point(round(point.x), round(point.y));\n\t }\n\n\t // Exports ================================================================\n\t deepExtend(dataviz, {\n\t map: {\n\t layers: {\n\t tile: TileLayer,\n\t TileLayer: TileLayer,\n\n\t ImageTile: ImageTile,\n\t TilePool: TilePool,\n\t TileView: TileView\n\t }\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(903);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 860:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.drawing\");\n\n/***/ }),\n\n/***/ 903:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(860), __webpack_require__(904) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var math = Math,\n\t abs = math.abs,\n\t atan = math.atan,\n\t atan2 = math.atan2,\n\t cos = math.cos,\n\t max = math.max,\n\t min = math.min,\n\t sin = math.sin,\n\t tan = math.tan,\n\n\t kendo = window.kendo,\n\t Class = kendo.Class,\n\n\t dataviz = kendo.dataviz,\n\t deepExtend = kendo.deepExtend,\n\n\t util = kendo.drawing.util,\n\t defined = util.defined,\n\t deg = util.deg,\n\t rad = util.rad,\n\t round = util.round,\n\t valueOrDefault = util.valueOrDefault,\n\n\t sqr = kendo.util.sqr;\n\n\t // Implementation =========================================================\n\t var Location = Class.extend({\n\t init: function(lat, lng) {\n\t if (arguments.length === 1) {\n\t this.lat = lat[0];\n\t this.lng = lat[1];\n\t } else {\n\t this.lat = lat;\n\t this.lng = lng;\n\t }\n\t },\n\n\t DISTANCE_ITERATIONS: 100,\n\t DISTANCE_CONVERGENCE: 1e-12,\n\t DISTANCE_PRECISION: 2,\n\t FORMAT: \"{0:N6},{1:N6}\",\n\n\t toArray: function() {\n\t return [this.lat, this.lng];\n\t },\n\n\t equals: function(loc) {\n\t return loc && loc.lat === this.lat && loc.lng === this.lng;\n\t },\n\n\t clone: function() {\n\t return new Location(this.lat, this.lng);\n\t },\n\n\t round: function(precision) {\n\t this.lng = round(this.lng, precision);\n\t this.lat = round(this.lat, precision);\n\t return this;\n\t },\n\n\t wrap: function() {\n\t this.lng = this.lng % 180;\n\t this.lat = this.lat % 90;\n\t return this;\n\t },\n\n\t distanceTo: function(dest, datum) {\n\t return this.greatCircleTo(dest, datum).distance;\n\t },\n\n\t destination: function(distance, bearing, datum) {\n\t bearing = rad(bearing);\n\t datum = datum || dataviz.map.datums.WGS84;\n\n\t var fromLat = rad(this.lat);\n\t var fromLng = rad(this.lng);\n\t var dToR = distance / kendo.dataviz.map.datums.WGS84.a;\n\n\t var lat = math.asin(sin(fromLat) * cos(dToR) +\n\t cos(fromLat) * sin(dToR) * cos(bearing));\n\n\t var lng = fromLng + atan2(sin(bearing) * sin(dToR) * cos(fromLat),\n\t cos(dToR) - sin(fromLat) * sin(lat));\n\n\t return new Location(deg(lat), deg(lng));\n\t },\n\n\t greatCircleTo: function(dest, datum) {\n\t dest = Location.create(dest);\n\t datum = datum || dataviz.map.datums.WGS84;\n\n\t if (!dest || this.clone().round(8).equals(dest.clone().round(8))) {\n\t return {\n\t distance: 0,\n\t azimuthFrom: 0,\n\t azimuthTo: 0\n\t };\n\t }\n\n\t // See http://en.wikipedia.org/wiki/Vincenty's_formulae#Notation\n\t // o == sigma\n\t // A == alpha\n\t var a = datum.a;\n\t var b = datum.b;\n\t var f = datum.f;\n\n\t var L = rad(dest.lng - this.lng);\n\n\t var U1 = atan((1 - f) * tan(rad(this.lat)));\n\t var sinU1 = sin(U1);\n\t var cosU1 = cos(U1);\n\n\t var U2 = atan((1 - f) * tan(rad(dest.lat)));\n\t var sinU2 = sin(U2);\n\t var cosU2 = cos(U2);\n\n\t var lambda = L;\n\t var prevLambda;\n\n\t var i = this.DISTANCE_ITERATIONS;\n\t var converged = false;\n\n\t var sinLambda;\n\t var cosLambda;\n\t var sino;\n\t var cosA2;\n\t var coso;\n\t var cos2om;\n\t var sigma;\n\n\t while (!converged && i-- > 0) {\n\t sinLambda = sin(lambda);\n\t cosLambda = cos(lambda);\n\t sino = math.sqrt(\n\t sqr(cosU2 * sinLambda) + sqr(cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)\n\t );\n\n\t coso = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;\n\t sigma = atan2(sino, coso);\n\n\t var sinA = cosU1 * cosU2 * sinLambda / sino;\n\t cosA2 = 1 - sqr(sinA);\n\t cos2om = 0;\n\t if (cosA2 !== 0) {\n\t cos2om = coso - 2 * sinU1 * sinU2 / cosA2;\n\t }\n\n\t prevLambda = lambda;\n\t var C = f / 16 * cosA2 * (4 + f * (4 - 3 * cosA2));\n\t lambda = L + (1 - C) * f * sinA * (\n\t sigma + C * sino * (cos2om + C * coso * (-1 + 2 * sqr(cos2om)))\n\t );\n\n\t converged = abs(lambda - prevLambda) <= this.DISTANCE_CONVERGENCE;\n\t }\n\n\t var u2 = cosA2 * (sqr(a) - sqr(b)) / sqr(b);\n\t var A = 1 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 - 175 * u2)));\n\t var B = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 - 47 * u2)));\n\t var deltao = B * sino * (cos2om + B / 4 * (\n\t coso * (-1 + 2 * sqr(cos2om)) - B / 6 * cos2om * (-3 + 4 * sqr(sino)) * (-3 + 4 * sqr(cos2om))\n\t ));\n\n\t var azimuthFrom = atan2(cosU2 * sinLambda, cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);\n\t var azimuthTo = atan2(cosU1 * sinLambda, -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda);\n\n\t return {\n\t distance: round(b * A * (sigma - deltao), this.DISTANCE_PRECISION),\n\t azimuthFrom: deg(azimuthFrom),\n\t azimuthTo: deg(azimuthTo)\n\t };\n\t }\n\t });\n\n\t // IE < 9 doesn't allow to override toString on definition\n\t Location.fn.toString = function() {\n\t return kendo.format(this.FORMAT, this.lat, this.lng);\n\t };\n\n\t Location.fromLngLat = function(ll) {\n\t return new Location(ll[1], ll[0]);\n\t };\n\n\t Location.fromLatLng = function(ll) {\n\t return new Location(ll[0], ll[1]);\n\t };\n\n\t Location.create = function(a, b) {\n\t if (defined(a)) {\n\t if (a instanceof Location) {\n\t return a.clone();\n\t } else if (arguments.length === 1 && a.length === 2) {\n\t return Location.fromLatLng(a);\n\t } else {\n\t return new Location(a, b);\n\t }\n\t }\n\t };\n\n\t var Extent = Class.extend({\n\t init: function(nw, se) {\n\t nw = Location.create(nw);\n\t se = Location.create(se);\n\n\t if (nw.lng + 180 > se.lng + 180 &&\n\t nw.lat + 90 < se.lat + 90) {\n\t this.se = nw;\n\t this.nw = se;\n\t } else {\n\t this.se = se;\n\t this.nw = nw;\n\t }\n\t },\n\n\t contains: function(loc) {\n\t var nw = this.nw,\n\t se = this.se,\n\t lng = valueOrDefault(loc.lng, loc[1]),\n\t lat = valueOrDefault(loc.lat, loc[0]);\n\n\t return loc &&\n\t lng + 180 >= nw.lng + 180 &&\n\t lng + 180 <= se.lng + 180 &&\n\t lat + 90 >= se.lat + 90 &&\n\t lat + 90 <= nw.lat + 90;\n\t },\n\n\t center: function() {\n\t var nw = this.nw;\n\t var se = this.se;\n\n\t var lng = nw.lng + (se.lng - nw.lng) / 2;\n\t var lat = nw.lat + (se.lat - nw.lat) / 2;\n\t return new Location(lat, lng);\n\t },\n\n\t containsAny: function(locs) {\n\t var result = false;\n\t for (var i = 0; i < locs.length; i++) {\n\t result = result || this.contains(locs[i]);\n\t }\n\n\t return result;\n\t },\n\n\t include: function(loc) {\n\t var nw = this.nw,\n\t se = this.se,\n\t lng = valueOrDefault(loc.lng, loc[1]),\n\t lat = valueOrDefault(loc.lat, loc[0]);\n\n\t nw.lng = min(nw.lng, lng);\n\t nw.lat = max(nw.lat, lat);\n\n\t se.lng = max(se.lng, lng);\n\t se.lat = min(se.lat, lat);\n\t },\n\n\t includeAll: function(locs) {\n\t for (var i = 0; i < locs.length; i++) {\n\t this.include(locs[i]);\n\t }\n\t },\n\n\t edges: function() {\n\t var nw = this.nw,\n\t se = this.se;\n\n\t return {nw: this.nw, ne: new Location(nw.lat, se.lng),\n\t se: this.se, sw: new Location(se.lat, nw.lng)};\n\t },\n\n\t toArray: function() {\n\t var nw = this.nw,\n\t se = this.se;\n\n\t return [nw, new Location(nw.lat, se.lng),\n\t se, new Location(se.lat, nw.lng)];\n\t },\n\n\t overlaps: function(extent) {\n\t return this.containsAny(extent.toArray()) ||\n\t extent.containsAny(this.toArray());\n\t }\n\t });\n\n\t Extent.World = new Extent([90, -180], [-90, 180]);\n\n\t Extent.create = function(a, b) {\n\t if (a instanceof Extent) {\n\t return a;\n\t } else if (a && b) {\n\t return new Extent(a, b);\n\t } else if (a && a.length === 4 && !b) {\n\t return new Extent([a[0], a[1]], [a[2], a[3]]);\n\t }\n\t };\n\n\t // Exports ================================================================\n\t deepExtend(dataviz, {\n\t map: {\n\t Extent: Extent,\n\t Location: Location\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 904:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../util/main\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(905);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 889:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./location\");\n\n/***/ }),\n\n/***/ 905:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(906), __webpack_require__(889)], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t // Imports ================================================================\n\t var doc = document,\n\t math = Math,\n\t min = math.min,\n\t pow = math.pow,\n\n\t proxy = $.proxy,\n\n\t kendo = window.kendo,\n\t Widget = kendo.ui.Widget,\n\t deepExtend = kendo.deepExtend,\n\n\t dataviz = kendo.dataviz,\n\t ui = dataviz.ui,\n\n\t g = kendo.geometry,\n\t Point = g.Point,\n\n\t map = dataviz.map,\n\t Extent = map.Extent,\n\t Location = map.Location,\n\t EPSG3857 = map.crs.EPSG3857,\n\n\t util = kendo.util,\n\t renderPos = util.renderPos,\n\n\t drawingUtil = kendo.drawing.util,\n\n\t defined = drawingUtil.defined,\n\t limit = drawingUtil.limitValue,\n\t valueOrDefault = drawingUtil.valueOrDefault;\n\n\t // Constants ==============================================================\n\t var CSS_PREFIX = \"k-\",\n\t FRICTION = 0.90,\n\t FRICTION_MOBILE = 0.93,\n\t MOUSEWHEEL = \"DOMMouseScroll mousewheel\",\n\t VELOCITY_MULTIPLIER = 5,\n\t DEFAULT_ZOOM_RATE = 1;\n\n\t // Map widget =============================================================\n\t var Map = Widget.extend({\n\t init: function(element, options) {\n\t kendo.destroy(element);\n\t Widget.fn.init.call(this, element);\n\n\t this._initOptions(options);\n\t this.bind(this.events, options);\n\n\t this.crs = new EPSG3857();\n\n\t this.element\n\t .addClass(CSS_PREFIX + this.options.name.toLowerCase())\n\t .css(\"position\", \"relative\")\n\t .empty()\n\t .append(doc.createElement(\"div\"));\n\n\t this._viewOrigin = this._getOrigin();\n\t this._initScroller();\n\t this._initMarkers();\n\t this._initControls();\n\t this._initLayers();\n\t this._reset();\n\n\t this._mousewheel = proxy(this._mousewheel, this);\n\t this.element.bind(MOUSEWHEEL, this._mousewheel);\n\t },\n\n\t options: {\n\t name: \"Map\",\n\t controls: {\n\t attribution: true,\n\t navigator: {\n\t panStep: 100\n\t },\n\t zoom: true\n\t },\n\t layers: [],\n\t layerDefaults: {\n\t shape: {\n\t style: {\n\t fill: {\n\t color: \"#fff\"\n\t },\n\t stroke: {\n\t color: \"#aaa\",\n\t width: 0.5\n\t }\n\t }\n\t },\n\t bubble: {\n\t style: {\n\t fill: {\n\t color: \"#fff\",\n\t opacity: 0.5\n\t },\n\t stroke: {\n\t color: \"#aaa\",\n\t width: 0.5\n\t }\n\t }\n\t },\n\t marker: {\n\t shape: \"pinTarget\",\n\t tooltip: {\n\t position: \"top\"\n\t }\n\t }\n\t },\n\t center: [0, 0],\n\t zoom: 3,\n\t minSize: 256,\n\t minZoom: 1,\n\t maxZoom: 19,\n\t markers: [],\n\t markerDefaults: {\n\t shape: \"pinTarget\",\n\t tooltip: {\n\t position: \"top\"\n\t }\n\t },\n\t wraparound: true\n\t },\n\n\t events:[\n\t \"beforeReset\",\n\t \"click\",\n\t \"markerActivate\",\n\t \"markerClick\",\n\t \"markerCreated\",\n\t \"pan\",\n\t \"panEnd\",\n\t \"reset\",\n\t \"shapeClick\",\n\t \"shapeCreated\",\n\t \"shapeFeatureCreated\",\n\t \"shapeMouseEnter\",\n\t \"shapeMouseLeave\",\n\t \"zoomEnd\",\n\t \"zoomStart\"\n\t ],\n\n\t destroy: function() {\n\t this.scroller.destroy();\n\n\t if (this.navigator) {\n\t this.navigator.destroy();\n\t }\n\n\t if (this.attribution) {\n\t this.attribution.destroy();\n\t }\n\n\t if (this.zoomControl) {\n\t this.zoomControl.destroy();\n\t }\n\n\t this.markers.destroy();\n\n\t for (var i = 0; i < this.layers.length; i++) {\n\t this.layers[i].destroy();\n\t }\n\n\t Widget.fn.destroy.call(this);\n\t },\n\n\t zoom: function(level) {\n\t var options = this.options;\n\n\t if (defined(level)) {\n\t level = math.round(limit(level, options.minZoom, options.maxZoom));\n\t if (options.zoom !== level) {\n\t options.zoom = level;\n\t this._reset();\n\t }\n\n\t return this;\n\t } else {\n\t return options.zoom;\n\t }\n\t },\n\n\t center: function(center) {\n\t if (center) {\n\t this.options.center = Location.create(center).toArray();\n\t this._reset();\n\n\t return this;\n\t } else {\n\t return Location.create(this.options.center);\n\t }\n\t },\n\n\t extent: function(extent) {\n\t if (extent) {\n\t this._setExtent(extent);\n\t return this;\n\t } else {\n\t return this._getExtent();\n\t }\n\t },\n\n\t setOptions: function(options) {\n\t Widget.fn.setOptions.call(this, options);\n\t this._reset();\n\t },\n\n\t locationToLayer: function(location, zoom) {\n\t var clamp = !this.options.wraparound;\n\t location = Location.create(location);\n\t return this.crs.toPoint(location, this._layerSize(zoom), clamp);\n\t },\n\n\t layerToLocation: function(point, zoom) {\n\t var clamp = !this.options.wraparound;\n\t point = Point.create(point);\n\t return this.crs.toLocation(point, this._layerSize(zoom), clamp);\n\t },\n\n\t locationToView: function(location) {\n\t location = Location.create(location);\n\t var origin = this.locationToLayer(this._viewOrigin);\n\t var point = this.locationToLayer(location);\n\n\t return point.translateWith(origin.scale(-1));\n\t },\n\n\t viewToLocation: function(point, zoom) {\n\t var origin = this.locationToLayer(this._getOrigin(), zoom);\n\t point = Point.create(point);\n\t point = point.clone().translateWith(origin);\n\t return this.layerToLocation(point, zoom);\n\t },\n\n\t eventOffset: function(e) {\n\t var point;\n\t var x;\n\t var y;\n\t var offset = this.element.offset();\n\n\t if (e.x || e.y) {\n\t var field = \"location\";\n\t x = e.x[field] - offset.left;\n\t y = e.y[field] - offset.top;\n\t point = new g.Point(x, y);\n\t } else {\n\t var event = e.originalEvent || e;\n\t x = valueOrDefault(event.pageX, event.clientX) - offset.left;\n\t y = valueOrDefault(event.pageY, event.clientY) - offset.top;\n\t point = new g.Point(x, y);\n\t }\n\n\t return point;\n\t },\n\n\t eventToView: function(e) {\n\t var cursor = this.eventOffset(e);\n\t return this.locationToView(this.viewToLocation(cursor));\n\t },\n\n\t eventToLayer: function(e) {\n\t return this.locationToLayer(this.eventToLocation(e));\n\t },\n\n\t eventToLocation: function(e) {\n\t var cursor = this.eventOffset(e);\n\t return this.viewToLocation(cursor);\n\t },\n\n\t viewSize: function() {\n\t var element = this.element;\n\t var scale = this._layerSize();\n\t var width = element.width();\n\n\t if (!this.options.wraparound) {\n\t width = min(scale, width);\n\t }\n\t return {\n\t width: width,\n\t height: min(scale, element.height())\n\t };\n\t },\n\n\t exportVisual: function() {\n\t this._reset();\n\t return false;\n\t },\n\n\t _setOrigin: function(origin, zoom) {\n\t var size = this.viewSize(),\n\t topLeft;\n\n\t origin = this._origin = Location.create(origin);\n\t topLeft = this.locationToLayer(origin, zoom);\n\t topLeft.x += size.width / 2;\n\t topLeft.y += size.height / 2;\n\n\t this.options.center = this.layerToLocation(topLeft, zoom).toArray();\n\n\t return this;\n\t },\n\n\t _getOrigin: function(invalidate) {\n\t var size = this.viewSize(),\n\t topLeft;\n\n\t if (invalidate || !this._origin) {\n\t topLeft = this.locationToLayer(this.center());\n\t topLeft.x -= size.width / 2;\n\t topLeft.y -= size.height / 2;\n\n\t this._origin = this.layerToLocation(topLeft);\n\t }\n\n\t return this._origin;\n\t },\n\n\t _setExtent: function(extent) {\n\t var raw = Extent.create(extent);\n\t var se = raw.se.clone();\n\t if (this.options.wraparound && se.lng < 0 && extent.nw.lng > 0) {\n\t se.lng = 180 + (180 + se.lng);\n\t }\n\n\t extent = new Extent(raw.nw, se);\n\t this.center(extent.center());\n\n\t var width = this.element.width();\n\t var height = this.element.height();\n\t for (var zoom = this.options.maxZoom; zoom >= this.options.minZoom; zoom--) {\n\t var topLeft = this.locationToLayer(extent.nw, zoom);\n\t var bottomRight = this.locationToLayer(extent.se, zoom);\n\n\t var layerWidth = math.abs(bottomRight.x - topLeft.x);\n\t var layerHeight = math.abs(bottomRight.y - topLeft.y);\n\n\t if (layerWidth <= width && layerHeight <= height) {\n\t break;\n\t }\n\t }\n\n\t this.zoom(zoom);\n\t },\n\n\t _getExtent: function() {\n\t var nw = this._getOrigin();\n\t var bottomRight = this.locationToLayer(nw);\n\t var size = this.viewSize();\n\n\t bottomRight.x += size.width;\n\t bottomRight.y += size.height;\n\n\t var se = this.layerToLocation(bottomRight);\n\t return new Extent(nw, se);\n\t },\n\n\t _zoomAround: function(pivot, level) {\n\t this._setOrigin(this.layerToLocation(pivot, level), level);\n\t this.zoom(level);\n\t },\n\n\t _initControls: function() {\n\t var controls = this.options.controls;\n\n\t if (ui.Attribution && controls.attribution) {\n\t this._createAttribution(controls.attribution);\n\t }\n\n\t if (!kendo.support.mobileOS) {\n\t if (ui.Navigator && controls.navigator) {\n\t this._createNavigator(controls.navigator);\n\t }\n\n\t if (ui.ZoomControl && controls.zoom) {\n\t this._createZoomControl(controls.zoom);\n\t }\n\t }\n\t },\n\n\t _createControlElement: function(options, defaultPos) {\n\t var pos = options.position || defaultPos;\n\t var posSelector = \".\" + renderPos(pos).replace(\" \", \".\");\n\t var wrap = $(\".k-map-controls\" + posSelector, this.element);\n\t if (wrap.length === 0) {\n\t wrap = $(\"
\")\n\t .addClass(\"k-map-controls \" + renderPos(pos))\n\t .appendTo(this.element);\n\t }\n\n\t return $(\"
\").appendTo(wrap);\n\t },\n\n\t _createAttribution: function(options) {\n\t var element = this._createControlElement(options, \"bottomRight\");\n\t this.attribution = new ui.Attribution(element, options);\n\t },\n\n\t _createNavigator: function(options) {\n\t var element = this._createControlElement(options, \"topLeft\");\n\t var navigator = this.navigator = new ui.Navigator(element, options);\n\n\t this._navigatorPan = proxy(this._navigatorPan, this);\n\t navigator.bind(\"pan\", this._navigatorPan);\n\n\t this._navigatorCenter = proxy(this._navigatorCenter, this);\n\t navigator.bind(\"center\", this._navigatorCenter);\n\t },\n\n\t _navigatorPan: function(e) {\n\t var map = this;\n\t var scroller = map.scroller;\n\n\t var x = scroller.scrollLeft + e.x;\n\t var y = scroller.scrollTop - e.y;\n\n\t var bounds = this._virtualSize;\n\t var height = this.element.height();\n\t var width = this.element.width();\n\n\t // TODO: Move limits in scroller\n\t x = limit(x, bounds.x.min, bounds.x.max - width);\n\t y = limit(y, bounds.y.min, bounds.y.max - height);\n\n\t map.scroller.one(\"scroll\", function(e) { map._scrollEnd(e); });\n\t map.scroller.scrollTo(-x, -y);\n\t },\n\n\t _navigatorCenter: function() {\n\t this.center(this.options.center);\n\t },\n\n\t _createZoomControl: function(options) {\n\t var element = this._createControlElement(options, \"topLeft\");\n\t var zoomControl = this.zoomControl = new ui.ZoomControl(element, options);\n\n\t this._zoomControlChange = proxy(this._zoomControlChange, this);\n\t zoomControl.bind(\"change\", this._zoomControlChange);\n\t },\n\n\t _zoomControlChange: function(e) {\n\t if (!this.trigger(\"zoomStart\", { originalEvent: e })) {\n\t this.zoom(this.zoom() + e.delta);\n\t this.trigger(\"zoomEnd\", { originalEvent: e });\n\t }\n\t },\n\n\t _initScroller: function() {\n\t var friction = kendo.support.mobileOS ? FRICTION_MOBILE : FRICTION;\n\t var zoomable = this.options.zoomable !== false;\n\t var scroller = this.scroller = new kendo.mobile.ui.Scroller(\n\t this.element.children(0), {\n\t friction: friction,\n\t velocityMultiplier: VELOCITY_MULTIPLIER,\n\t zoom: zoomable,\n\t mousewheelScrolling: false,\n\t supportDoubleTap: true\n\t });\n\n\t scroller.bind(\"scroll\", proxy(this._scroll, this));\n\t scroller.bind(\"scrollEnd\", proxy(this._scrollEnd, this));\n\t scroller.userEvents.bind(\"gesturestart\", proxy(this._scaleStart, this));\n\t scroller.userEvents.bind(\"gestureend\", proxy(this._scale, this));\n\t scroller.userEvents.bind(\"doubleTap\", proxy(this._doubleTap, this));\n\t scroller.userEvents.bind(\"tap\", proxy(this._tap, this));\n\n\t this.scrollElement = scroller.scrollElement;\n\t },\n\n\t _initLayers: function() {\n\t var defs = this.options.layers,\n\t layers = this.layers = [];\n\n\t for (var i = 0; i < defs.length; i++) {\n\t var options = defs[i];\n\t var type = options.type || \"shape\";\n\t var defaults = this.options.layerDefaults[type];\n\t var impl = dataviz.map.layers[type];\n\n\t layers.push(new impl(this, deepExtend({}, defaults, options)));\n\t }\n\t },\n\n\t _initMarkers: function() {\n\t this.markers = new map.layers.MarkerLayer(this, this.options.markerDefaults);\n\t this.markers.add(this.options.markers);\n\t },\n\n\t _scroll: function(e) {\n\t var origin = this.locationToLayer(this._viewOrigin).round();\n\t var movable = e.sender.movable;\n\n\t var offset = new g.Point(movable.x, movable.y).scale(-1).scale(1/movable.scale);\n\t origin.x += offset.x;\n\t origin.y += offset.y;\n\n\t this._scrollOffset = offset;\n\n\t this._setOrigin(this.layerToLocation(origin));\n\t this.trigger(\"pan\", {\n\t originalEvent: e,\n\t origin: this._getOrigin(),\n\t center: this.center()\n\t });\n\t },\n\n\t _scrollEnd: function(e) {\n\t if (!this._scrollOffset || !this._panComplete()) {\n\t return;\n\t }\n\n\t this._scrollOffset = null;\n\t this._panEndTS = new Date();\n\n\t this.trigger(\"panEnd\", {\n\t originalEvent: e,\n\t origin: this._getOrigin(),\n\t center: this.center()\n\t });\n\t },\n\n\t _panComplete: function() {\n\t return new Date() - (this._panEndTS || 0) > 50;\n\t },\n\n\t _scaleStart: function(e) {\n\t if (this.trigger(\"zoomStart\", { originalEvent: e })) {\n\t var touch = e.touches[1];\n\t if (touch) {\n\t touch.cancel();\n\t }\n\t }\n\t },\n\n\t _scale: function(e) {\n\t var scale = this.scroller.movable.scale;\n\t var zoom = this._scaleToZoom(scale);\n\t var gestureCenter = new g.Point(e.center.x, e.center.y);\n\t var centerLocation = this.viewToLocation(gestureCenter, zoom);\n\t var centerPoint = this.locationToLayer(centerLocation, zoom);\n\t var originPoint = centerPoint.translate(-gestureCenter.x, -gestureCenter.y);\n\n\t this._zoomAround(originPoint, zoom);\n\t this.trigger(\"zoomEnd\", { originalEvent: e });\n\t },\n\n\t _scaleToZoom: function(scaleDelta) {\n\t var scale = this._layerSize() * scaleDelta;\n\t var tiles = scale / this.options.minSize;\n\t var zoom = math.log(tiles) / math.log(2);\n\n\t return math.round(zoom);\n\t },\n\n\t _reset: function() {\n\t if (this.attribution) {\n\t this.attribution.filter(this.center(), this.zoom());\n\t }\n\n\t this._viewOrigin = this._getOrigin(true);\n\t this._resetScroller();\n\t this.trigger(\"beforeReset\");\n\t this.trigger(\"reset\");\n\t },\n\n\t _resetScroller: function() {\n\t var scroller = this.scroller;\n\t var x = scroller.dimensions.x;\n\t var y = scroller.dimensions.y;\n\t var scale = this._layerSize();\n\t var nw = this.extent().nw;\n\t var topLeft = this.locationToLayer(nw).round();\n\n\t scroller.movable.round = true;\n\t scroller.reset();\n\t scroller.userEvents.cancel();\n\n\t var zoom = this.zoom();\n\t scroller.dimensions.forcedMinScale = pow(2, this.options.minZoom - zoom);\n\t scroller.dimensions.maxScale = pow(2, this.options.maxZoom - zoom);\n\n\t var xBounds = { min: -topLeft.x, max: scale - topLeft.x };\n\t var yBounds = { min: -topLeft.y, max: scale - topLeft.y };\n\n\t if (this.options.wraparound) {\n\t xBounds.max = 20 * scale;\n\t xBounds.min = -xBounds.max;\n\t }\n\n\t if (this.options.pannable === false) {\n\t var viewSize = this.viewSize();\n\t xBounds.min = yBounds.min = 0;\n\t xBounds.max = viewSize.width;\n\t yBounds.max = viewSize.height;\n\t }\n\n\t x.makeVirtual();\n\t y.makeVirtual();\n\t x.virtualSize(xBounds.min, xBounds.max);\n\t y.virtualSize(yBounds.min, yBounds.max);\n\n\t this._virtualSize = { x: xBounds, y: yBounds };\n\t },\n\n\t _renderLayers: function() {\n\t var defs = this.options.layers,\n\t layers = this.layers = [],\n\t scrollWrap = this.scrollWrap;\n\n\t scrollWrap.empty();\n\n\t for (var i = 0; i < defs.length; i++) {\n\t var options = defs[i];\n\t var type = options.type || \"shape\";\n\t var defaults = this.options.layerDefaults[type];\n\t var impl = dataviz.map.layers[type];\n\n\t layers.push(new impl(this, deepExtend({}, defaults, options)));\n\t }\n\t },\n\n\t _layerSize: function(zoom) {\n\t zoom = valueOrDefault(zoom, this.options.zoom);\n\t return this.options.minSize * pow(2, zoom);\n\t },\n\n\t _tap: function(e) {\n\t if (!this._panComplete()) {\n\t return;\n\t }\n\n\t var cursor = this.eventOffset(e);\n\t this.trigger(\"click\", {\n\t originalEvent: e,\n\t location: this.viewToLocation(cursor)\n\t });\n\t },\n\n\t _doubleTap: function(e) {\n\t var options = this.options;\n\t if (options.zoomable !== false) {\n\t if (!this.trigger(\"zoomStart\", { originalEvent: e })) {\n\t var toZoom = this.zoom() + DEFAULT_ZOOM_RATE;\n\t var cursor = this.eventOffset(e);\n\t var location = this.viewToLocation(cursor);\n\t var postZoom = this.locationToLayer(location, toZoom);\n\t var origin = postZoom.translate(-cursor.x, -cursor.y);\n\t this._zoomAround(origin, toZoom);\n\t this.trigger(\"zoomEnd\", { originalEvent: e });\n\t }\n\t }\n\t },\n\n\t _mousewheel: function(e) {\n\t e.preventDefault();\n\t var delta = dataviz.mwDelta(e) > 0 ? -1 : 1;\n\t var options = this.options;\n\t var fromZoom = this.zoom();\n\t var toZoom = limit(fromZoom + delta, options.minZoom, options.maxZoom);\n\n\t if (options.zoomable !== false && toZoom !== fromZoom) {\n\t if (!this.trigger(\"zoomStart\", { originalEvent: e })) {\n\t var cursor = this.eventOffset(e);\n\t var location = this.viewToLocation(cursor);\n\t var postZoom = this.locationToLayer(location, toZoom);\n\t var origin = postZoom.translate(-cursor.x, -cursor.y);\n\t this._zoomAround(origin, toZoom);\n\n\t this.trigger(\"zoomEnd\", { originalEvent: e });\n\t }\n\t }\n\t }\n\t });\n\n\t // Exports ================================================================\n\t dataviz.ui.plugin(Map);\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 906:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./crs\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(907);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 863:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.core\");\n\n/***/ }),\n\n/***/ 907:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(863) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\t var kendo = window.kendo;\n\t var Widget = kendo.ui.Widget;\n\t var keys = kendo.keys;\n\t var proxy = $.proxy;\n\n\t var NS = \".kendoNavigator\";\n\n\t // Helper functions =======================================================\n\t function button(dir) {\n\t return kendo.format(\n\t '', dir);\n\t }\n\n\t var BUTTONS = button(\"up\") + button(\"right\") + button(\"down\") + button(\"left\");\n\n\t var Navigator = Widget.extend({\n\t init: function(element, options) {\n\t Widget.fn.init.call(this, element, options);\n\t this._initOptions(options);\n\n\t this.element.addClass(\"k-widget k-navigator\")\n\t .append(BUTTONS)\n\t .on(\"click\" + NS, \".k-button\", proxy(this, \"_click\"));\n\n\t var parentElement = this.element.parent().closest(\"[\" + kendo.attr(\"role\") + \"]\");\n\t this._keyroot = parentElement.length > 0 ? parentElement : this.element;\n\t this._tabindex(this._keyroot);\n\n\t this._keydown = proxy(this._keydown, this);\n\t this._keyroot.on(\"keydown\", this._keydown);\n\t },\n\n\t options: {\n\t name: \"Navigator\",\n\t panStep: 1\n\t },\n\n\t events: [\n\t \"pan\"\n\t ],\n\n\t dispose: function() {\n\t this._keyroot.off(\"keydown\", this._keydown);\n\t },\n\n\t _pan: function(x, y) {\n\t var panStep = this.options.panStep;\n\t this.trigger(\"pan\", {\n\t x: x * panStep,\n\t y: y * panStep\n\t });\n\t },\n\n\t _click: function(e) {\n\t var x = 0;\n\t var y = 0;\n\t var button = $(e.currentTarget);\n\n\t if (button.is(\".k-navigator-up\")) {\n\t y = 1;\n\t } else if (button.is(\".k-navigator-down\")) {\n\t y = -1;\n\t } else if (button.is(\".k-navigator-right\")) {\n\t x = 1;\n\t } else if (button.is(\".k-navigator-left\")) {\n\t x = -1;\n\t }\n\n\t this._pan(x, y);\n\t e.preventDefault();\n\t },\n\n\t _keydown: function(e) {\n\t switch (e.which) {\n\t case keys.UP:\n\t this._pan(0, 1);\n\t e.preventDefault();\n\t break;\n\n\t case keys.DOWN:\n\t this._pan(0, -1);\n\t e.preventDefault();\n\t break;\n\n\t case keys.RIGHT:\n\t this._pan(1, 0);\n\t e.preventDefault();\n\t break;\n\n\t case keys.LEFT:\n\t this._pan(-1, 0);\n\t e.preventDefault();\n\t break;\n\t }\n\t }\n\t });\n\n\t // Exports ================================================================\n\t kendo.dataviz.ui.plugin(Navigator);\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(908);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 863:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.core\");\n\n/***/ }),\n\n/***/ 908:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(863) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\t var kendo = window.kendo;\n\t var Widget = kendo.ui.Widget;\n\t var keys = kendo.keys;\n\t var proxy = $.proxy;\n\n\t // Helper functions =======================================================\n\t function button(dir, iconClass) {\n\t return kendo.format(\n\t '',\n\t dir, iconClass);\n\t }\n\n\t var NS = \".kendoZoomControl\";\n\t var BUTTONS = button(\"in\", \"k-i-plus\") + button(\"out\", \"k-i-minus\");\n\n\t var PLUS = 187;\n\t var MINUS = 189;\n\t var FF_PLUS = 61;\n\t var FF_MINUS = 173;\n\n\n\t var ZoomControl = Widget.extend({\n\t init: function(element, options) {\n\t Widget.fn.init.call(this, element, options);\n\t this._initOptions(options);\n\n\t this.element.addClass(\"k-widget k-zoom-control k-button-group k-group-horizontal\")\n\t .append(BUTTONS)\n\t .on(\"click\" + NS, \".k-button\", proxy(this, \"_click\"));\n\n\t var parentElement = this.element.parent().closest(\"[\" + kendo.attr(\"role\") + \"]\");\n\t this._keyroot = parentElement.length > 0 ? parentElement : this.element;\n\n\t this._tabindex(this._keyroot);\n\n\t this._keydown = proxy(this._keydown, this);\n\t this._keyroot.on(\"keydown\", this._keydown);\n\t },\n\n\t options: {\n\t name: \"ZoomControl\",\n\t zoomStep: 1\n\t },\n\n\t events: [\n\t \"change\"\n\t ],\n\n\t _change: function(dir) {\n\t var zoomStep = this.options.zoomStep;\n\t this.trigger(\"change\", {\n\t delta: dir * zoomStep\n\t });\n\t },\n\n\t _click: function(e) {\n\t var button = $(e.currentTarget);\n\t var dir = 1;\n\n\t if (button.is(\".k-zoom-out\")) {\n\t dir = -1;\n\t }\n\n\t this._change(dir);\n\t e.preventDefault();\n\t },\n\n\t _keydown: function(e) {\n\t switch (e.which) {\n\t case keys.NUMPAD_PLUS:\n\t case PLUS:\n\t case FF_PLUS:\n\t this._change(1);\n\t break;\n\n\t case keys.NUMPAD_MINUS:\n\t case MINUS:\n\t case FF_MINUS:\n\t this._change(-1);\n\t break;\n\t }\n\t }\n\t });\n\n\n\t // Exports ================================================================\n\t kendo.dataviz.ui.plugin(ZoomControl);\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(909);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 909:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/***********************************************************************\n\t * WARNING: this file is auto-generated. If you change it directly,\n\t * your modifications will eventually be lost. The source code is in\n\t * `kendo-charts` repository, you should make your changes there and\n\t * run `src-modules/sync.sh` in this repository.\n\t */\n\t(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(910)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function () {\n\n\twindow.kendo.dataviz = window.kendo.dataviz || {};\n\tvar dataviz = kendo.dataviz;\n\tvar constants = dataviz.constants;\n\tvar Chart = dataviz.Chart;\n\tvar elementSize = dataviz.elementSize;\n\tvar deepExtend = dataviz.deepExtend;\n\n\tvar TOP_OFFSET = -2;\n\n\tvar SharedTooltip$1 = dataviz.SharedTooltip.extend({\n\t _slotAnchor: function(coords, slot) {\n\t var axis = this.plotArea.categoryAxis;\n\t var vertical = axis.options.vertical;\n\t var align = vertical ? {\n\t horizontal: \"left\",\n\t vertical: \"center\"\n\t } : {\n\t horizontal: \"center\",\n\t vertical: \"bottom\"\n\t };\n\n\t var point;\n\n\t if (vertical) {\n\t point = new dataviz.Point(this.plotArea.box.x2, slot.center().y);\n\t } else {\n\t point = new dataviz.Point(slot.center().x, TOP_OFFSET);\n\t }\n\n\t return {\n\t point: point,\n\t align: align\n\t };\n\t },\n\n\t _defaultAnchor: function(point, slot) {\n\t return this._slotAnchor({}, slot);\n\t }\n\t});\n\n\tvar DEAULT_BAR_WIDTH = 150;\n\tvar DEAULT_BULLET_WIDTH = 150;\n\tvar NO_CROSSHAIR = [ constants.BAR, constants.BULLET ];\n\n\tfunction hide(children) {\n\t var state = [];\n\t for (var idx = 0; idx < children.length; idx++) {\n\t var child = children[idx];\n\t state[idx] = child.style.display;\n\t child.style.display = \"none\";\n\t }\n\n\t return state;\n\t}\n\n\tfunction show(children, state) {\n\t for (var idx = 0; idx < children.length; idx++) {\n\t children[idx].style.display = state[idx];\n\t }\n\t}\n\n\tfunction wrapNumber(value) {\n\t return dataviz.isNumber(value) ? [ value ] : value;\n\t}\n\n\tvar Sparkline = Chart.extend({\n\t _setElementClass: function(element) {\n\t dataviz.addClass(element, 'k-sparkline');\n\t },\n\n\t _initElement: function(element) {\n\t Chart.fn._initElement.call(this, element);\n\n\t this._initialWidth = Math.floor(elementSize(element).width);\n\t },\n\n\t _resize: function() {\n\t var element = this.element;\n\t var state = hide(element.childNodes);\n\n\t this._initialWidth = Math.floor(elementSize(element).width);\n\n\t show(element.childNodes, state);\n\n\t Chart.fn._resize.call(this);\n\t },\n\n\t _modelOptions: function() {\n\t var chartOptions = this.options;\n\t var stage = this._surfaceWrap();\n\t var displayState = hide(stage.childNodes);\n\n\t var space = document.createElement('span');\n\t space.innerHTML = ' ';\n\n\t stage.appendChild(space);\n\n\t var options = deepExtend({\n\t width: this._autoWidth,\n\t height: elementSize(stage).height,\n\t transitions: chartOptions.transitions\n\t }, chartOptions.chartArea, {\n\t inline: true,\n\t align: false\n\t });\n\n\t elementSize(stage, {\n\t width: options.width,\n\t height: options.height\n\t });\n\n\t stage.removeChild(space);\n\n\t show(stage.childNodes, displayState);\n\n\t if (this.surface) {\n\t this.surface.resize();\n\t }\n\n\t return options;\n\t },\n\n\t _surfaceWrap: function() {\n\t if (!this.stage) {\n\t var stage = this.stage = document.createElement('span');\n\t this.element.appendChild(stage);\n\t }\n\t return this.stage;\n\t },\n\n\t _createPlotArea: function(skipSeries) {\n\t var plotArea = Chart.fn._createPlotArea.call(this, skipSeries);\n\t this._autoWidth = this._initialWidth || this._calculateWidth(plotArea);\n\n\t return plotArea;\n\t },\n\n\t _calculateWidth: function(plotArea) {\n\t var options = this.options;\n\t var margin = dataviz.getSpacing(options.chartArea.margin);\n\t var charts = plotArea.charts;\n\t var stage = this._surfaceWrap();\n\t var total = 0;\n\n\t for (var i = 0; i < charts.length; i++) {\n\t var currentChart = charts[i];\n\t var firstSeries = (currentChart.options.series || [])[0];\n\t if (!firstSeries) {\n\t continue;\n\t }\n\n\t if (firstSeries.type === constants.BAR) {\n\t return DEAULT_BAR_WIDTH;\n\t }\n\n\t if (firstSeries.type === constants.BULLET) {\n\t return DEAULT_BULLET_WIDTH;\n\t }\n\n\t if (firstSeries.type === constants.PIE) {\n\t return elementSize(stage).height;\n\t }\n\n\t var categoryAxis = currentChart.categoryAxis;\n\t if (categoryAxis) {\n\t var pointsCount = categoryAxis.categoriesCount() *\n\t (!currentChart.options.isStacked && dataviz.inArray(firstSeries.type, [ constants.COLUMN, constants.VERTICAL_BULLET ]) ? currentChart.seriesOptions.length : 1);\n\n\t total = Math.max(total, pointsCount);\n\t }\n\t }\n\n\t var size = total * options.pointWidth;\n\t if (size > 0) {\n\t size += margin.left + margin.right;\n\t }\n\n\t return size;\n\t },\n\n\t _createSharedTooltip: function(options) {\n\t return new SharedTooltip$1(this._plotArea, options);\n\t }\n\t});\n\n\tSparkline.normalizeOptions = function(userOptions) {\n\t var options = wrapNumber(userOptions);\n\n\t if (dataviz.isArray(options)) {\n\t options = { seriesDefaults: { data: options } };\n\t } else {\n\t options = deepExtend({}, options);\n\t }\n\n\t if (!options.series) {\n\t options.series = [ { data: wrapNumber(options.data) } ];\n\t }\n\n\t deepExtend(options, {\n\t seriesDefaults: {\n\t type: options.type\n\t }\n\t });\n\n\t if (dataviz.inArray(options.series[0].type, NO_CROSSHAIR) ||\n\t dataviz.inArray(options.seriesDefaults.type, NO_CROSSHAIR)) {\n\t options = deepExtend({}, {\n\t categoryAxis: {\n\t crosshair: {\n\t visible: false\n\t }\n\t }\n\t }, options);\n\t }\n\n\t return options;\n\t};\n\n\tdataviz.setDefaultOptions(Sparkline, {\n\t chartArea: {\n\t margin: 2\n\t },\n\t axisDefaults: {\n\t visible: false,\n\t majorGridLines: {\n\t visible: false\n\t },\n\t valueAxis: {\n\t narrowRange: true\n\t }\n\t },\n\t seriesDefaults: {\n\t type: \"line\",\n\t area: {\n\t line: {\n\t width: 0.5\n\t }\n\t },\n\t bar: {\n\t stack: true\n\t },\n\t padding: 2,\n\t width: 0.5,\n\t overlay: {\n\t gradient: null\n\t },\n\t highlight: {\n\t visible: false\n\t },\n\t border: {\n\t width: 0\n\t },\n\t markers: {\n\t size: 2,\n\t visible: false\n\t }\n\t },\n\t tooltip: {\n\t visible: true,\n\t shared: true\n\t },\n\t categoryAxis: {\n\t crosshair: {\n\t visible: true,\n\t tooltip: {\n\t visible: false\n\t }\n\t }\n\t },\n\t legend: {\n\t visible: false\n\t },\n\t transitions: false,\n\n\t pointWidth: 5,\n\n\t panes: [ { clip: false } ]\n\t});\n\n\tkendo.deepExtend(kendo.dataviz, {\n\t Sparkline: Sparkline\n\t});\n\n\t})();\n\n\t}, __webpack_require__(3));\n\n/***/ }),\n\n/***/ 910:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.chart\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(911);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 911:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(912)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\tvar dataviz = kendo.dataviz;\n\tvar Chart = dataviz.ui.Chart;\n\tvar KendoSparkline = dataviz.Sparkline;\n\tvar ChartInstanceObserver = dataviz.ChartInstanceObserver;\n\n\tvar extend = $.extend;\n\n\tvar Sparkline = Chart.extend({\n\n\t init: function(element, userOptions) {\n\t var options = userOptions;\n\t if (options instanceof kendo.data.ObservableArray) {\n\t options = { seriesDefaults: { data: options } };\n\t }\n\n\t Chart.fn.init.call(this, element, KendoSparkline.normalizeOptions(options));\n\t },\n\n\t _createChart: function(options, themeOptions) {\n\t this._instance = new KendoSparkline(this.element[0], options, themeOptions, {\n\t observer: new ChartInstanceObserver(this),\n\t sender: this,\n\t rtl: this._isRtl()\n\t });\n\t },\n\n\t _createTooltip: function() {\n\t return new SparklineTooltip(this.element, extend({}, this.options.tooltip, {\n\t rtl: this._isRtl()\n\t }));\n\t },\n\n\t options: {\n\t name: \"Sparkline\",\n\t chartArea: {\n\t margin: 2\n\t },\n\t axisDefaults: {\n\t visible: false,\n\t majorGridLines: {\n\t visible: false\n\t },\n\t valueAxis: {\n\t narrowRange: true\n\t }\n\t },\n\t seriesDefaults: {\n\t type: \"line\",\n\t area: {\n\t line: {\n\t width: 0.5\n\t }\n\t },\n\t bar: {\n\t stack: true\n\t },\n\t padding: 2,\n\t width: 0.5,\n\t overlay: {\n\t gradient: null\n\t },\n\t highlight: {\n\t visible: false\n\t },\n\t border: {\n\t width: 0\n\t },\n\t markers: {\n\t size: 2,\n\t visible: false\n\t }\n\t },\n\t tooltip: {\n\t visible: true,\n\t shared: true\n\t },\n\t categoryAxis: {\n\t crosshair: {\n\t visible: true,\n\t tooltip: {\n\t visible: false\n\t }\n\t }\n\t },\n\t legend: {\n\t visible: false\n\t },\n\t transitions: false,\n\n\t pointWidth: 5,\n\n\t panes: [{\n\t clip: false\n\t }]\n\t }\n\t});\n\n\tdataviz.ui.plugin(Sparkline);\n\n\tvar SparklineTooltip = dataviz.Tooltip.extend({\n\t options: {\n\t animation: {\n\t duration: 0\n\t }\n\t },\n\n\t _hideElement: function() {\n\t if (this.element) {\n\t this.element.hide().remove();\n\t }\n\t }\n\t});\n\n\tdataviz.SparklineTooltip = SparklineTooltip;\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 912:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo-sparkline\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(913);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 910:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.chart\");\n\n/***/ }),\n\n/***/ 913:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/***********************************************************************\n\t * WARNING: this file is auto-generated. If you change it directly,\n\t * your modifications will eventually be lost. The source code is in\n\t * `kendo-charts` repository, you should make your changes there and\n\t * run `src-modules/sync.sh` in this repository.\n\t */\n\t(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(910)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function () {\n\n\twindow.kendo.dataviz = window.kendo.dataviz || {};\n\tvar dataviz = kendo.dataviz;\n\tvar elementStyles = dataviz.elementStyles;\n\tvar deepExtend = dataviz.deepExtend;\n\tvar toTime = dataviz.toTime;\n\tvar datavizConstants = dataviz.constants;\n\tvar Chart = dataviz.Chart;\n\tvar drawing = kendo.drawing;\n\n\tvar FadeOutAnimation = drawing.Animation.extend({\n\t setup: function() {\n\t this._initialOpacity = parseFloat(elementStyles(this.element, 'opacity').opacity);\n\t },\n\n\t step: function(pos) {\n\t elementStyles(this.element, {\n\t opacity: String(dataviz.interpolateValue(this._initialOpacity, 0, pos))\n\t });\n\t },\n\n\t abort: function() {\n\t drawing.Animation.fn.abort.call(this);\n\t elementStyles(this.element, {\n\t display: 'none',\n\t opacity: String(this._initialOpacity)\n\t });\n\t },\n\n\t cancel: function() {\n\t drawing.Animation.fn.abort.call(this);\n\t elementStyles(this.element, {\n\t opacity: String(this._initialOpacity)\n\t });\n\t }\n\t});\n\n\tfunction createDiv(className, style) {\n\t var div = document.createElement(\"div\");\n\t div.className = className;\n\t if (style) {\n\t div.style.cssText = style;\n\t }\n\n\t return div;\n\t}\n\n\tvar NavigatorHint = dataviz.Class.extend({\n\t init: function(container, chartService, options) {\n\n\t this.options = deepExtend({}, this.options, options);\n\t this.container = container;\n\t this.chartService = chartService;\n\n\t var padding = elementStyles(container, [ \"paddingLeft\", \"paddingTop\" ]);\n\t this.chartPadding = {\n\t top: padding.paddingTop,\n\t left: padding.paddingLeft\n\t };\n\n\t this.createElements();\n\t container.appendChild(this.element);\n\t },\n\n\t createElements: function() {\n\t var element = this.element = createDiv('k-navigator-hint', 'display: none; position: absolute; top: 1px; left: 1px;');\n\t var tooltip = this.tooltip = createDiv('k-tooltip k-chart-tooltip');\n\t var scroll = this.scroll = createDiv('k-scroll');\n\n\t tooltip.innerHTML = ' ';\n\n\t element.appendChild(tooltip);\n\t element.appendChild(scroll);\n\t },\n\n\t show: function(from, to, bbox) {\n\t var ref = this;\n\t var element = ref.element;\n\t var options = ref.options;\n\t var scroll = ref.scroll;\n\t var tooltip = ref.tooltip;\n\t var middle = dataviz.toDate(toTime(from) + toTime(to - from) / 2);\n\t var scrollWidth = bbox.width() * 0.4;\n\t var minPos = bbox.center().x - scrollWidth;\n\t var maxPos = bbox.center().x;\n\t var posRange = maxPos - minPos;\n\t var range = options.max - options.min;\n\t var scale = posRange / range;\n\t var offset = middle - options.min;\n\t var text = this.chartService.intl.format(options.format, from, to);\n\t var template = dataviz.getTemplate(options);\n\n\t this.clearHideTimeout();\n\n\t if (!this._visible) {\n\t elementStyles(element, {\n\t visibility: 'hidden',\n\t display: 'block'\n\t });\n\t this._visible = true;\n\t }\n\n\t if (template) {\n\t text = template({\n\t from: from,\n\t to: to\n\t });\n\t }\n\n\t tooltip.innerHTML = text;\n\t elementStyles(tooltip, {\n\t left: bbox.center().x - tooltip.offsetWidth / 2,\n\t top: bbox.y1\n\t });\n\n\t var tooltipStyle = elementStyles(tooltip, [ 'marginTop', 'borderTopWidth', 'height' ]);\n\n\t elementStyles(scroll, {\n\t width: scrollWidth,\n\t left: minPos + offset * scale,\n\t top: bbox.y1 + tooltipStyle.marginTop + tooltipStyle.borderTopWidth + tooltipStyle.height / 2\n\t });\n\n\t elementStyles(element, {\n\t visibility: 'visible'\n\t });\n\t },\n\n\t clearHideTimeout: function() {\n\t if (this._hideTimeout) {\n\t clearTimeout(this._hideTimeout);\n\t }\n\n\t if (this._hideAnimation) {\n\t this._hideAnimation.cancel();\n\t }\n\t },\n\n\t hide: function() {\n\t var this$1 = this;\n\n\t this.clearHideTimeout();\n\n\t this._hideTimeout = setTimeout(function () {\n\t this$1._visible = false;\n\t this$1._hideAnimation = new FadeOutAnimation(this$1.element);\n\t this$1._hideAnimation.setup();\n\t this$1._hideAnimation.play();\n\t }, this.options.hideDelay);\n\t },\n\n\t destroy: function() {\n\t this.clearHideTimeout();\n\t if (this.container) {\n\t this.container.removeChild(this.element);\n\t }\n\t delete this.container;\n\t delete this.chartService;\n\t delete this.element;\n\t delete this.tooltip;\n\t delete this.scroll;\n\t }\n\t});\n\n\tdataviz.setDefaultOptions(NavigatorHint, {\n\t format: \"{0:d} - {1:d}\",\n\t hideDelay: 500\n\t});\n\n\tvar NAVIGATOR_PANE = \"_navigator\";\n\tvar NAVIGATOR_AXIS = NAVIGATOR_PANE;\n\n\tvar constants = {\n\t\tNAVIGATOR_AXIS: NAVIGATOR_AXIS,\n\t\tNAVIGATOR_PANE: NAVIGATOR_PANE\n\t};\n\n\tvar ZOOM_ACCELERATION = 3;\n\n\tvar Navigator = dataviz.Class.extend({\n\t init: function(chart) {\n\n\t this.chart = chart;\n\t var options = this.options = deepExtend({}, this.options, chart.options.navigator);\n\t var select = options.select;\n\t if (select) {\n\t select.from = this.parseDate(select.from);\n\t select.to = this.parseDate(select.to);\n\t }\n\n\t if (!dataviz.defined(options.hint.visible)) {\n\t options.hint.visible = options.visible;\n\t }\n\n\t var obj;\n\t this.chartObserver = new dataviz.InstanceObserver(this, ( obj = {}, obj[datavizConstants.DRAG] = '_drag', obj[datavizConstants.DRAG_END] = '_dragEnd', obj[datavizConstants.ZOOM] = '_zoom', obj[datavizConstants.ZOOM_END] = '_zoomEnd', obj ));\n\t chart.addObserver(this.chartObserver);\n\t },\n\n\t parseDate: function(value) {\n\t return dataviz.parseDate(this.chart.chartService.intl, value);\n\t },\n\n\t clean: function() {\n\t if (this.selection) {\n\t this.selection.destroy();\n\t this.selection = null;\n\t }\n\n\t if (this.hint) {\n\t this.hint.destroy();\n\t this.hint = null;\n\t }\n\t },\n\n\t destroy: function() {\n\t if (this.chart) {\n\t this.chart.removeObserver(this.chartObserver);\n\t delete this.chart;\n\t }\n\n\t this.clean();\n\t },\n\n\t redraw: function() {\n\t this._redrawSelf();\n\t this.initSelection();\n\t },\n\n\t initSelection: function() {\n\t var ref = this;\n\t var chart = ref.chart;\n\t var options = ref.options;\n\t var axis = this.mainAxis();\n\t var ref$1 = axis.roundedRange();\n\t var min = ref$1.min;\n\t var max = ref$1.max;\n\t var ref$2 = options.select;\n\t var from = ref$2.from;\n\t var to = ref$2.to;\n\t var mousewheel = ref$2.mousewheel;\n\t var axisClone = clone(axis);\n\n\t if (axis.categoriesCount() === 0) {\n\t return;\n\t }\n\n\t this.clean();\n\n\t // \"Freeze\" the selection axis position until the next redraw\n\t axisClone.box = axis.box;\n\n\t this.selection = new dataviz.Selection(chart, axisClone, {\n\t min: min,\n\t max: max,\n\t from: from || min,\n\t to: to || max,\n\t mousewheel: dataviz.valueOrDefault(mousewheel, { zoom: \"left\" }),\n\t visible: options.visible\n\t }, new dataviz.InstanceObserver(this, {\n\t selectStart: '_selectStart',\n\t select: '_select',\n\t selectEnd: '_selectEnd'\n\t }));\n\n\t if (options.hint.visible) {\n\t this.hint = new NavigatorHint(chart.element, chart.chartService, {\n\t min: min,\n\t max: max,\n\t template: dataviz.getTemplate(options.hint),\n\t format: options.hint.format\n\t });\n\t }\n\t },\n\n\t setRange: function() {\n\t var plotArea = this.chart._createPlotArea(true);\n\t var axis = plotArea.namedCategoryAxes[NAVIGATOR_AXIS];\n\n\t var ref = axis.roundedRange();\n\t var min = ref.min;\n\t var max = ref.max;\n\n\t var select = this.options.select || {};\n\t var from = select.from || min;\n\t if (from < min) {\n\t from = min;\n\t }\n\n\t var to = select.to || max;\n\t if (to > max) {\n\t to = max;\n\t }\n\n\t this.options.select = deepExtend({}, select, {\n\t from: from,\n\t to: to\n\t });\n\n\t this.filterAxes();\n\t },\n\n\t _redrawSelf: function(silent) {\n\t var plotArea = this.chart._plotArea;\n\n\t if (plotArea) {\n\t plotArea.redraw(dataviz.last(plotArea.panes), silent);\n\t }\n\t },\n\n\t redrawSlaves: function() {\n\t var chart = this.chart;\n\t var plotArea = chart._plotArea;\n\t var slavePanes = plotArea.panes.slice(0, -1);\n\n\t // Update the original series and categoryAxis before partial refresh.\n\t plotArea.srcSeries = chart.options.series;\n\t plotArea.options.categoryAxis = chart.options.categoryAxis;\n\t plotArea.clearSeriesPointsCache();\n\n\t plotArea.redraw(slavePanes);\n\t },\n\n\t _drag: function(e) {\n\t var ref = this;\n\t var chart = ref.chart;\n\t var selection = ref.selection;\n\t var coords = chart._eventCoordinates(e.originalEvent);\n\t var navigatorAxis = this.mainAxis();\n\t var naviRange = navigatorAxis.roundedRange();\n\t var inNavigator = navigatorAxis.pane.box.containsPoint(coords);\n\t var axis = chart._plotArea.categoryAxis;\n\t var range = e.axisRanges[axis.options.name];\n\t var select = this.options.select;\n\t var duration;\n\n\t if (!range || inNavigator || !selection) {\n\t return;\n\t }\n\n\t if (select.from && select.to) {\n\t duration = toTime(select.to) - toTime(select.from);\n\t } else {\n\t duration = toTime(selection.options.to) - toTime(selection.options.from);\n\t }\n\n\t var from = dataviz.toDate(dataviz.limitValue(\n\t toTime(range.min),\n\t naviRange.min, toTime(naviRange.max) - duration\n\t ));\n\n\t var to = dataviz.toDate(dataviz.limitValue(\n\t toTime(from) + duration,\n\t toTime(naviRange.min) + duration, naviRange.max\n\t ));\n\n\t this.options.select = { from: from, to: to };\n\n\t if (this.options.liveDrag) {\n\t this.filterAxes();\n\t this.redrawSlaves();\n\t }\n\n\t selection.set(from, to);\n\n\t this.showHint(from, to);\n\t },\n\n\t _dragEnd: function() {\n\t this.filterAxes();\n\t this.filter();\n\t this.redrawSlaves();\n\n\t if (this.hint) {\n\t this.hint.hide();\n\t }\n\t },\n\n\t readSelection: function() {\n\t var ref = this;\n\t var ref_selection_options = ref.selection.options;\n\t var from = ref_selection_options.from;\n\t var to = ref_selection_options.to;\n\t var select = ref.options.select;\n\n\t select.from = from;\n\t select.to = to;\n\t },\n\n\t filterAxes: function() {\n\t var ref = this;\n\t var select = ref.options.select; if (select === void 0) { select = { }; }\n\t var chart = ref.chart;\n\t var allAxes = chart.options.categoryAxis;\n\t var from = select.from;\n\t var to = select.to;\n\n\t for (var idx = 0; idx < allAxes.length; idx++) {\n\t var axis = allAxes[idx];\n\t if (axis.pane !== NAVIGATOR_PANE) {\n\t axis.min = from;\n\t axis.max = to;\n\t }\n\t }\n\t },\n\n\t filter: function() {\n\t var ref = this;\n\t var chart = ref.chart;\n\t var select = ref.options.select;\n\n\t if (!chart.requiresHandlers([ \"navigatorFilter\" ])) {\n\t return;\n\t }\n\n\t var mainAxis = this.mainAxis();\n\t var args = {\n\t from: select.from,\n\t to: select.to\n\t };\n\n\t if (mainAxis.options.type !== 'category') {\n\t var axisOptions = new dataviz.DateCategoryAxis(deepExtend({\n\t baseUnit: \"fit\"\n\t }, chart.options.categoryAxis[0], {\n\t categories: [ select.from, select.to ]\n\t }), chart.chartService).options;\n\n\t args.from = dataviz.addDuration(axisOptions.min, -axisOptions.baseUnitStep, axisOptions.baseUnit);\n\t args.to = dataviz.addDuration(axisOptions.max, axisOptions.baseUnitStep, axisOptions.baseUnit);\n\t }\n\n\t this.chart.trigger(\"navigatorFilter\", args);\n\t },\n\n\t _zoom: function(e) {\n\t var ref = this;\n\t var axis = ref.chart._plotArea.categoryAxis;\n\t var selection = ref.selection;\n\t var ref_options = ref.options;\n\t var select = ref_options.select;\n\t var liveDrag = ref_options.liveDrag;\n\t var mainAxis = this.mainAxis();\n\t var delta = e.delta;\n\n\t if (!selection) {\n\t return;\n\t }\n\n\t var fromIx = mainAxis.categoryIndex(selection.options.from);\n\t var toIx = mainAxis.categoryIndex(selection.options.to);\n\n\t e.originalEvent.preventDefault();\n\n\t if (Math.abs(delta) > 1) {\n\t delta *= ZOOM_ACCELERATION;\n\t }\n\n\t if (toIx - fromIx > 1) {\n\t selection.expand(delta);\n\t this.readSelection();\n\t } else {\n\t axis.options.min = select.from;\n\t select.from = axis.scaleRange(-e.delta).min;\n\t }\n\n\t if (liveDrag) {\n\t this.filterAxes();\n\t this.redrawSlaves();\n\t }\n\n\t selection.set(select.from, select.to);\n\n\t this.showHint(this.options.select.from, this.options.select.to);\n\t },\n\n\t _zoomEnd: function(e) {\n\t this._dragEnd(e);\n\t },\n\n\t showHint: function(from, to) {\n\t var plotArea = this.chart._plotArea;\n\n\t if (this.hint) {\n\t this.hint.show(from, to, plotArea.backgroundBox());\n\t }\n\t },\n\n\t _selectStart: function(e) {\n\t return this.chart._selectStart(e);\n\t },\n\n\t _select: function(e) {\n\t this.showHint(e.from, e.to);\n\n\t return this.chart._select(e);\n\t },\n\n\t _selectEnd: function(e) {\n\t if (this.hint) {\n\t this.hint.hide();\n\t }\n\n\t this.readSelection();\n\t this.filterAxes();\n\t this.filter();\n\t this.redrawSlaves();\n\n\t return this.chart._selectEnd(e);\n\t },\n\n\t mainAxis: function() {\n\t var plotArea = this.chart._plotArea;\n\n\t if (plotArea) {\n\t return plotArea.namedCategoryAxes[NAVIGATOR_AXIS];\n\t }\n\t },\n\n\t select: function(from, to) {\n\t var select = this.options.select;\n\n\t if (from && to) {\n\t select.from = this.parseDate(from);\n\t select.to = this.parseDate(to);\n\n\t this.filterAxes();\n\t this.filter();\n\t this.redrawSlaves();\n\n\t this.selection.set(from, to);\n\t }\n\n\t return {\n\t from: select.from,\n\t to: select.to\n\t };\n\t }\n\t});\n\n\tNavigator.setup = function(options, themeOptions) {\n\t if (options === void 0) { options = {}; }\n\t if (themeOptions === void 0) { themeOptions = {}; }\n\n\t if (options.__navi) {\n\t return;\n\t }\n\t options.__navi = true;\n\n\t var naviOptions = deepExtend({}, themeOptions.navigator, options.navigator);\n\t var panes = options.panes = [].concat(options.panes);\n\t var paneOptions = deepExtend({}, naviOptions.pane, { name: NAVIGATOR_PANE });\n\n\t if (!naviOptions.visible) {\n\t paneOptions.visible = false;\n\t paneOptions.height = 0.1;\n\t }\n\n\t panes.push(paneOptions);\n\n\t Navigator.attachAxes(options, naviOptions);\n\t Navigator.attachSeries(options, naviOptions, themeOptions);\n\t};\n\n\tNavigator.attachAxes = function(options, naviOptions) {\n\t var series = naviOptions.series || [];\n\t var categoryAxes = options.categoryAxis = [].concat(options.categoryAxis);\n\t var valueAxes = options.valueAxis = [].concat(options.valueAxis);\n\n\t var equallySpacedSeries = dataviz.filterSeriesByType(series, datavizConstants.EQUALLY_SPACED_SERIES);\n\t var justifyAxis = equallySpacedSeries.length === 0;\n\n\t var base = deepExtend({\n\t type: \"date\",\n\t pane: NAVIGATOR_PANE,\n\t roundToBaseUnit: !justifyAxis,\n\t justified: justifyAxis,\n\t _collapse: false,\n\t majorTicks: { visible: true },\n\t tooltip: { visible: false },\n\t labels: { step: 1 },\n\t autoBind: naviOptions.autoBindElements,\n\t autoBaseUnitSteps: {\n\t minutes: [ 1 ],\n\t hours: [ 1, 2 ],\n\t days: [ 1, 2 ],\n\t weeks: [],\n\t months: [ 1 ],\n\t years: [ 1 ]\n\t }\n\t });\n\t var user = naviOptions.categoryAxis;\n\n\t categoryAxes.push(\n\t deepExtend({}, base, {\n\t maxDateGroups: 200\n\t }, user, {\n\t name: NAVIGATOR_AXIS,\n\t title: null,\n\t baseUnit: \"fit\",\n\t baseUnitStep: \"auto\",\n\t labels: { visible: false },\n\t majorTicks: { visible: false }\n\t }), deepExtend({}, base, user, {\n\t name: NAVIGATOR_AXIS + \"_labels\",\n\t maxDateGroups: 20,\n\t baseUnitStep: \"auto\",\n\t labels: { position: \"\" },\n\t plotBands: [],\n\t autoBaseUnitSteps: {\n\t minutes: []\n\t },\n\t _overlap: true\n\t }), deepExtend({}, base, user, {\n\t name: NAVIGATOR_AXIS + \"_ticks\",\n\t maxDateGroups: 200,\n\t majorTicks: {\n\t width: 0.5\n\t },\n\t plotBands: [],\n\t title: null,\n\t labels: { visible: false, mirror: true },\n\t _overlap: true\n\t })\n\t );\n\n\t valueAxes.push(deepExtend({\n\t name: NAVIGATOR_AXIS,\n\t pane: NAVIGATOR_PANE,\n\t majorGridLines: {\n\t visible: false\n\t },\n\t visible: false\n\t }, naviOptions.valueAxis));\n\t};\n\n\tNavigator.attachSeries = function(options, naviOptions, themeOptions) {\n\t var series = options.series = options.series || [];\n\t var navigatorSeries = [].concat(naviOptions.series || []);\n\t var seriesColors = themeOptions.seriesColors;\n\t var defaults = naviOptions.seriesDefaults;\n\n\t for (var idx = 0; idx < navigatorSeries.length; idx++) {\n\t series.push(\n\t deepExtend({\n\t color: seriesColors[idx % seriesColors.length],\n\t categoryField: naviOptions.dateField,\n\t visibleInLegend: false,\n\t tooltip: {\n\t visible: false\n\t }\n\t }, defaults, navigatorSeries[idx], {\n\t axis: NAVIGATOR_AXIS,\n\t categoryAxis: NAVIGATOR_AXIS,\n\t autoBind: naviOptions.autoBindElements\n\t })\n\t );\n\t }\n\t};\n\n\tfunction ClonedObject() { }\n\tfunction clone(obj) {\n\t ClonedObject.prototype = obj;\n\t return new ClonedObject();\n\t}\n\n\tvar AUTO_CATEGORY_WIDTH = 28;\n\n\tvar StockChart = Chart.extend({\n\t applyDefaults: function(options, themeOptions) {\n\t var width = dataviz.elementSize(this.element).width || datavizConstants.DEFAULT_WIDTH;\n\t var theme = themeOptions;\n\n\t var stockDefaults = {\n\t seriesDefaults: {\n\t categoryField: options.dateField\n\t },\n\t axisDefaults: {\n\t categoryAxis: {\n\t name: \"default\",\n\t majorGridLines: {\n\t visible: false\n\t },\n\t labels: {\n\t step: 2\n\t },\n\t majorTicks: {\n\t visible: false\n\t },\n\t maxDateGroups: Math.floor(width / AUTO_CATEGORY_WIDTH)\n\t }\n\t }\n\t };\n\n\t if (theme) {\n\t theme = deepExtend({}, theme, stockDefaults);\n\t }\n\n\t Navigator.setup(options, theme);\n\n\t Chart.fn.applyDefaults.call(this, options, theme);\n\t },\n\n\t _setElementClass: function(element) {\n\t dataviz.addClass(element, 'k-chart k-stockchart');\n\t },\n\n\t setOptions: function(options) {\n\t this.destroyNavigator();\n\t Chart.fn.setOptions.call(this, options);\n\t },\n\n\t noTransitionsRedraw: function() {\n\t var transitions = this.options.transitions;\n\n\t this.options.transitions = false;\n\t this._fullRedraw();\n\t this.options.transitions = transitions;\n\t },\n\n\t _resize: function() {\n\t this.noTransitionsRedraw();\n\t },\n\n\t _redraw: function() {\n\t var navigator = this.navigator;\n\n\t if (!this._dirty() && navigator && navigator.options.partialRedraw) {\n\t navigator.redrawSlaves();\n\t } else {\n\t this._fullRedraw();\n\t }\n\t },\n\n\t _dirty: function() {\n\t var options = this.options;\n\t var series = [].concat(options.series, options.navigator.series);\n\t var seriesCount = dataviz.grep(series, function(s) { return s && s.visible; }).length;\n\t var dirty = this._seriesCount !== seriesCount;\n\t this._seriesCount = seriesCount;\n\n\t return dirty;\n\t },\n\n\t _fullRedraw: function() {\n\t var navigator = this.navigator;\n\n\t if (!navigator) {\n\t navigator = this.navigator = new Navigator(this);\n\t this.trigger(\"navigatorCreated\", { navigator: navigator });\n\t }\n\n\t navigator.clean();\n\t navigator.setRange();\n\n\t Chart.fn._redraw.call(this);\n\n\t navigator.initSelection();\n\t },\n\n\t _trackSharedTooltip: function(coords) {\n\t var plotArea = this._plotArea;\n\t var pane = plotArea.paneByPoint(coords);\n\n\t if (pane && pane.options.name === NAVIGATOR_PANE) {\n\t this._unsetActivePoint();\n\t } else {\n\t Chart.fn._trackSharedTooltip.call(this, coords);\n\t }\n\t },\n\n\t bindCategories: function() {\n\t Chart.fn.bindCategories.call(this);\n\t this.copyNavigatorCategories();\n\t },\n\n\t copyNavigatorCategories: function() {\n\t var definitions = [].concat(this.options.categoryAxis);\n\t var categories;\n\n\t for (var axisIx = 0; axisIx < definitions.length; axisIx++) {\n\t var axis = definitions[axisIx];\n\t if (axis.name === NAVIGATOR_AXIS) {\n\t categories = axis.categories;\n\t } else if (categories && axis.pane === NAVIGATOR_PANE) {\n\t axis.categories = categories;\n\t }\n\t }\n\t },\n\n\t destroyNavigator: function() {\n\t if (this.navigator) {\n\t this.navigator.destroy();\n\t this.navigator = null;\n\t }\n\t },\n\n\t destroy: function() {\n\t this.destroyNavigator();\n\t Chart.fn.destroy.call(this);\n\t },\n\n\t _stopChartHandlers: function(e) {\n\t var coords = this._eventCoordinates(e);\n\t var pane = this._plotArea.paneByPoint(coords);\n\n\t return Chart.fn._stopChartHandlers.call(this, e) || (pane && pane.options.name === NAVIGATOR_PANE);\n\t },\n\n\t _toggleDragZoomEvents: function() {\n\t if (!this._dragZoomEnabled) {\n\t this.element.style.touchAction = \"none\";\n\n\t this._dragZoomEnabled = true;\n\t }\n\t }\n\t});\n\n\tdataviz.setDefaultOptions(StockChart, {\n\t dateField: \"date\",\n\t axisDefaults: {\n\t categoryAxis: {\n\t type: \"date\",\n\t baseUnit: \"fit\",\n\t justified: true\n\t },\n\t valueAxis: {\n\t narrowRange: true,\n\t labels: {\n\t format: \"C\"\n\t }\n\t }\n\t },\n\t navigator: {\n\t select: {},\n\t seriesDefaults: {\n\t markers: {\n\t visible: false\n\t },\n\t tooltip: {\n\t visible: true\n\t },\n\t line: {\n\t width: 2\n\t }\n\t },\n\t hint: {},\n\t visible: true\n\t },\n\t tooltip: {\n\t visible: true\n\t },\n\t legend: {\n\t visible: false\n\t }\n\t});\n\n\tkendo.deepExtend(kendo.dataviz, {\n\t constants: constants,\n\t Navigator: Navigator,\n\t NavigatorHint: NavigatorHint,\n\t StockChart: StockChart\n\t});\n\n\t})();\n\n\t}, __webpack_require__(3));\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(914);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 914:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(915)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\t var kendo = window.kendo;\n\t var dataviz = kendo.dataviz;\n\t var ChartInstanceObserver = dataviz.ChartInstanceObserver;\n\t var Chart = dataviz.ui.Chart;\n\t var KendoStockChart = dataviz.StockChart;\n\t var constants = dataviz.constants;\n\t var NAVIGATOR_AXIS = constants.NAVIGATOR_AXIS;\n\t var NAVIGATOR_PANE = constants.NAVIGATOR_PANE;\n\t var deepExtend = kendo.deepExtend;\n\t var defined = dataviz.defined;\n\t var proxy = $.proxy;\n\n\t var CHANGE = \"change\";\n\n\t var StockInstanceObserver = ChartInstanceObserver.extend({\n\t handlerMap: {\n\t navigatorFilter: '_onNavigatorFilter',\n\t navigatorCreated: '_onNavigatorCreated'\n\t }\n\t });\n\n\t var StockChart = Chart.extend({\n\n\t options: {\n\t name: \"StockChart\",\n\t dateField: \"date\",\n\t axisDefaults: {\n\t categoryAxis: {\n\t type: \"date\",\n\t baseUnit: \"fit\",\n\t justified: true\n\t },\n\t valueAxis: {\n\t narrowRange: true,\n\t labels: {\n\t format: \"C\"\n\t }\n\t }\n\t },\n\t navigator: {\n\t select: {},\n\t seriesDefaults: {\n\t markers: {\n\t visible: false\n\t },\n\t tooltip: {\n\t visible: true,\n\t template: \"#= kendo.toString(category, 'd') #\"\n\t },\n\t line: {\n\t width: 2\n\t }\n\t },\n\t hint: {},\n\t visible: true\n\t },\n\t tooltip: {\n\t visible: true\n\t },\n\t legend: {\n\t visible: false\n\t },\n\t persistSeriesVisibility: true\n\t },\n\n\t _createChart: function(options, themeOptions) {\n\t this._initNavigatorOptions(options);\n\t this._instance = new KendoStockChart(this.element[0], options, themeOptions, {\n\t observer: new StockInstanceObserver(this),\n\t sender: this,\n\t rtl: this._isRtl()\n\t });\n\t },\n\n\t _initNavigatorOptions: function(options) {\n\t var navigatorOptions = options.navigator || {};\n\t var support = kendo.support;\n\t var isTouch = support.touch;\n\t var isFirefox = support.browser.mozilla;\n\n\t deepExtend(navigatorOptions, {\n\t autoBindElements: !navigatorOptions.dataSource,\n\t partialRedraw: navigatorOptions.dataSource,\n\t liveDrag: !isTouch && !isFirefox\n\t });\n\t },\n\n\t _initDataSource: function(userOptions) {\n\t var options = userOptions || {},\n\t dataSource = options.dataSource,\n\t hasServerFiltering = dataSource && dataSource.serverFiltering,\n\t mainAxis = [].concat(options.categoryAxis)[0],\n\t naviOptions = options.navigator || {},\n\t select = naviOptions.select,\n\t hasSelect = select && select.from && select.to;\n\n\t if (hasServerFiltering && hasSelect) {\n\t var filter = [].concat(dataSource.filter || []);\n\n\t var from = kendo.parseDate(select.from);\n\t var to = kendo.parseDate(select.to);\n\t var dummyAxis = new dataviz.DateCategoryAxis(deepExtend({\n\t baseUnit: \"fit\"\n\t }, mainAxis, {\n\t categories: [from, to]\n\t }), kendo);\n\n\t dataSource.filter = buildFilter(dummyAxis.range().min, to).concat(filter);\n\t }\n\n\t Chart.fn._initDataSource.call(this, userOptions);\n\t },\n\n\t _onNavigatorCreated: function(e) {\n\t this._instance = e.sender;\n\t this.options = e.sender.options;\n\t this._navigator = this.navigator = e.navigator;\n\t this._initNavigatorDataSource();\n\t },\n\n\t _initNavigatorDataSource: function() {\n\t var navigatorOptions = this.options.navigator;\n\t var autoBind = navigatorOptions.autoBind;\n\t var dsOptions = navigatorOptions.dataSource;\n\n\t if (dsOptions) {\n\t this._navigatorDataChangedHandler = this._navigatorDataChangedHandler || proxy(this._onNavigatorDataChanged, this);\n\t this._navigatorDataSource = kendo.data.DataSource\n\t .create(dsOptions)\n\t .bind(CHANGE, this._navigatorDataChangedHandler);\n\n\t if (!defined(autoBind)) {\n\t autoBind = this.options.autoBind;\n\t }\n\n\t if (autoBind) {\n\t this._navigatorDataSource.fetch();\n\t }\n\t }\n\t },\n\n\t _bindNavigatorSeries: function(series, data) {\n\t var seriesIx, currentSeries,\n\t seriesLength = series.length;\n\n\t for (seriesIx = 0; seriesIx < seriesLength; seriesIx++) {\n\t currentSeries = series[seriesIx];\n\n\t if (currentSeries.axis == NAVIGATOR_AXIS && this._isBindable(currentSeries)) {\n\t currentSeries.data = data;\n\t }\n\t }\n\t },\n\n\t _onNavigatorDataChanged: function() {\n\t var chart = this,\n\t instance = chart._instance,\n\t categoryAxes = chart.options.categoryAxis,\n\t axisIx,\n\t axesLength = categoryAxes.length,\n\t data = chart._navigatorDataSource.view(),\n\t currentAxis,\n\t naviCategories;\n\n\t this._bindNavigatorSeries(chart.options.series, data);\n\t if (chart._sourceSeries) {\n\t this._bindNavigatorSeries(chart._sourceSeries, data);\n\t }\n\n\t for (axisIx = 0; axisIx < axesLength; axisIx++) {\n\t currentAxis = categoryAxes[axisIx];\n\n\t if (currentAxis.pane == NAVIGATOR_PANE) {\n\t if (currentAxis.name == NAVIGATOR_AXIS) {\n\t chart._bindCategoryAxis(currentAxis, data, axisIx);\n\t naviCategories = currentAxis.categories;\n\t } else {\n\t currentAxis.categories = naviCategories;\n\t }\n\t }\n\t }\n\n\t if (instance._model) {\n\t var navigator = this.navigator;\n\t navigator.redraw();\n\t navigator.setRange();\n\n\t if (!chart.options.dataSource || (chart.options.dataSource && chart._dataBound)) {\n\t navigator.redrawSlaves();\n\t }\n\t }\n\t },\n\n\t _bindCategories: function() {\n\t Chart.fn._bindCategories.call(this);\n\t if (this._instance) {\n\t this._instance.copyNavigatorCategories();\n\t }\n\t },\n\n\t _onDataChanged: function() {\n\t Chart.fn._onDataChanged.call(this);\n\n\t this._dataBound = true;\n\t },\n\n\t setOptions: function(options) {\n\t this._removeNavigatorDataSource();\n\t this._initNavigatorOptions(options);\n\t this._instance.destroyNavigator();\n\t Chart.fn.setOptions.call(this, options);\n\t },\n\n\t _onNavigatorFilter: function(e) {\n\t this.dataSource.filter(buildFilter(e.from, e.to));\n\t },\n\n\t requiresHandlers: function(names) {\n\t if (dataviz.inArray('navigatorFilter', names)) {\n\t var dataSource = this.dataSource;\n\t var hasServerFiltering = dataSource && dataSource.options.serverFiltering;\n\t return hasServerFiltering && this.options.navigator.dataSource;\n\t }\n\n\t return Chart.fn.requiresHandlers.call(this, names);\n\t },\n\n\t _removeNavigatorDataSource: function() {\n\t var navigatorDataSource = this._navigatorDataSource;\n\t if (navigatorDataSource) {\n\t navigatorDataSource.unbind(CHANGE, this._navigatorDataChangedHandler);\n\t delete this._navigatorDataSource;\n\t }\n\t },\n\n\t destroy: function() {\n\t Chart.fn.destroy.call(this);\n\t this._removeNavigatorDataSource();\n\t }\n\t });\n\n\t dataviz.ui.plugin(StockChart);\n\n\t function buildFilter(from, to) {\n\t return [{\n\t field: \"Date\", operator: \"gte\", value: from\n\t }, {\n\t field: \"Date\", operator: \"lt\", value: to\n\t }];\n\t }\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ }),\n\n/***/ 915:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo-stock-chart\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(916);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 858:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 916:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(858) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function($) {\n\t var cache;\n\n\t function autoTheme(force) {\n\t if (!force && cache) {\n\t return cache;\n\t }\n\n\t var theme = { chart: kendo.dataviz.chartBaseTheme() };\n\t var hook = $(\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
' +\n\t '
').appendTo(document.body);\n\n\t function mapColor(key, varName) {\n\t set(key, queryStyle(varName, \"backgroundColor\"));\n\t }\n\n\t function queryStyle(varName, prop) {\n\t return hook.find(\".k-var--\" + varName).css(prop);\n\t }\n\n\t function set(path, value) {\n\t var store = theme;\n\t var parts = path.split('.');\n\t var key = parts.shift();\n\n\t while (parts.length > 0) {\n\t store = store[key] = store[key] || {};\n\t key = parts.shift();\n\t }\n\n\t store[key] = value;\n\t }\n\n\t (function setColors() {\n\t mapColor(\"chart.axisDefaults.crosshair.color\", \"chart-crosshair-background\");\n\t mapColor(\"chart.axisDefaults.labels.color\", \"normal-text-color\");\n\t mapColor(\"chart.axisDefaults.line.color\", \"chart-major-lines\");\n\t mapColor(\"chart.axisDefaults.majorGridLines.color\", \"chart-major-lines\");\n\t mapColor(\"chart.axisDefaults.minorGridLines.color\", \"chart-minor-lines\");\n\t mapColor(\"chart.axisDefaults.notes.icon.background\", \"chart-notes-background\");\n\t mapColor(\"chart.axisDefaults.notes.icon.border.color\", \"chart-notes-border\");\n\t mapColor(\"chart.axisDefaults.notes.line.color\", \"chart-notes-lines\");\n\t mapColor(\"chart.axisDefaults.title.color\", \"normal-text-color\");\n\t mapColor('chart.chartArea.background', 'background');\n\t mapColor(\"chart.legend.inactiveItems.labels.color\", \"chart-inactive\");\n\t mapColor(\"chart.legend.inactiveItems.markers.color\", \"chart-inactive\");\n\t mapColor(\"chart.legend.labels.color\", \"normal-text-color\");\n\t mapColor(\"chart.seriesDefaults.boxPlot.downColor\", \"chart-major-lines\");\n\t mapColor(\"chart.seriesDefaults.boxPlot.mean.color\", \"base\");\n\t mapColor(\"chart.seriesDefaults.boxPlot.median.color\", \"base\");\n\t mapColor(\"chart.seriesDefaults.boxPlot.whiskers.color\", \"accent\");\n\t mapColor(\"chart.seriesDefaults.bullet.target.color\", \"accent\");\n\t mapColor(\"chart.seriesDefaults.candlestick.downColor\", \"normal-text-color\");\n\t mapColor(\"chart.seriesDefaults.candlestick.line.color\", \"normal-text-color\");\n\t mapColor(\"chart.seriesDefaults.errorBars.color\", \"chart-error-bars-background\");\n\t mapColor(\"chart.seriesDefaults.horizontalWaterfall.line.color\", \"chart-major-lines\");\n\t mapColor(\"chart.seriesDefaults.icon.border.color\", \"chart-major-lines\");\n\t mapColor(\"chart.seriesDefaults.labels.background\", \"background\");\n\t mapColor(\"chart.seriesDefaults.labels.color\", \"normal-text-color\");\n\t mapColor(\"chart.seriesDefaults.notes.icon.background\", \"chart-notes-background\");\n\t mapColor(\"chart.seriesDefaults.notes.icon.border.color\", \"chart-notes-border\");\n\t mapColor(\"chart.seriesDefaults.notes.line.color\", \"chart-notes-lines\");\n\t mapColor(\"chart.seriesDefaults.verticalBoxPlot.downColor\", \"chart-major-lines\");\n\t mapColor(\"chart.seriesDefaults.verticalBoxPlot.mean.color\", \"base\");\n\t mapColor(\"chart.seriesDefaults.verticalBoxPlot.median.color\", \"base\");\n\t mapColor(\"chart.seriesDefaults.verticalBoxPlot.whiskers.color\", \"accent\");\n\t mapColor(\"chart.seriesDefaults.verticalBullet.target.color\", \"accent\");\n\t mapColor(\"chart.seriesDefaults.waterfall.line.color\", \"chart-major-lines\");\n\t mapColor(\"chart.title.color\", \"normal-text-color\");\n\n\t set(\"chart.seriesDefaults.labels.opacity\", queryStyle(\"chart-area-opacity\", \"opacity\"));\n\n\t mapColor(\"diagram.shapeDefaults.fill.color\", \"accent\");\n\t mapColor(\"diagram.shapeDefaults.content.color\", \"accent-contrast\");\n\t mapColor(\"diagram.shapeDefaults.connectorDefaults.fill.color\", \"normal-text-color\");\n\t mapColor(\"diagram.shapeDefaults.connectorDefaults.stroke.color\", \"accent-contrast\");\n\t mapColor(\"diagram.shapeDefaults.connectorDefaults.hover.fill.color\", \"accent-contrast\");\n\t mapColor(\"diagram.shapeDefaults.connectorDefaults.hover.stroke.color\", \"normal-text-color\");\n\t mapColor(\"diagram.editable.resize.handles.stroke.color\", \"normal-text-color\");\n\t mapColor(\"diagram.editable.resize.handles.fill.color\", \"normal-background\");\n\t mapColor(\"diagram.editable.resize.handles.hover.stroke.color\", \"normal-text-color\");\n\t mapColor(\"diagram.editable.resize.handles.hover.fill.color\", \"normal-text-color\");\n\t mapColor(\"diagram.selectable.stroke.color\", \"normal-text-color\");\n\t mapColor(\"diagram.connectionDefaults.stroke.color\", \"normal-text-color\");\n\t mapColor(\"diagram.connectionDefaults.content.color\", \"normal-text-color\");\n\t mapColor(\"diagram.connectionDefaults.selection.handles.fill.color\", \"accent-contrast\");\n\t mapColor(\"diagram.connectionDefaults.selection.handles.stroke.color\", \"normal-text-color\");\n\t mapColor(\"diagram.connectionDefaults.selection.stroke.color\", \"normal-text-color\");\n\n\t mapColor(\"gauge.pointer.color\", \"gauge-pointer\");\n\t mapColor(\"gauge.scale.labels.color\", \"normal-text-color\");\n\t mapColor(\"gauge.scale.minorTicks.color\", \"normal-text-color\");\n\t mapColor(\"gauge.scale.majorTicks.color\", \"normal-text-color\");\n\t mapColor(\"gauge.scale.line.color\", \"normal-text-color\");\n\t mapColor(\"gauge.scale.rangePlaceholderColor\", \"gauge-track\");\n\t })();\n\n\t (function setFonts() {\n\t function font(varName) {\n\t return queryStyle(varName, \"fontSize\") + \" \" +\n\t queryStyle(varName, \"fontFamily\");\n\t }\n\n\t var defaultFont = font(\"chart-font\");\n\t var titleFont = font(\"chart-title-font\");\n\t var labelFont = font(\"chart-label-font\");\n\n\t set(\"chart.axisDefaults.labels.font\", labelFont);\n\t set(\"chart.axisDefaults.notes.label.font\", defaultFont);\n\t set(\"chart.axisDefaults.title.font\", defaultFont);\n\t set(\"chart.legend.labels.font\", defaultFont);\n\t set(\"chart.seriesDefaults.labels.font\", labelFont);\n\t set(\"chart.seriesDefaults.notes.label.font\", defaultFont);\n\t set(\"chart.title.font\", titleFont);\n\t })();\n\n\t (function setSeriesColors() {\n\t function letterPos(letter) {\n\t return letter.toLowerCase().charCodeAt(0) - \"a\".charCodeAt(0);\n\t }\n\n\t function seriesPos(name) {\n\t return letterPos(name.match(/series-([a-z])$/)[1]);\n\t }\n\n\t var series = $(\".k-var--series div\").toArray();\n\t var seriesColors = series.reduce(\n\t function(arr, el) {\n\t var pos = seriesPos(el.className);\n\t arr[pos] = $(el).css(\"backgroundColor\");\n\n\t return arr;\n\t },\n\t [] // Will populate the series colors in this array\n\t );\n\n\t set(\"chart.seriesColors\", seriesColors);\n\t })();\n\n\t hook.remove();\n\n\t cache = theme;\n\n\t return theme;\n\t }\n\n\t kendo.dataviz.autoTheme = autoTheme;\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(917);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 858:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../../kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 917:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/***********************************************************************\n\t * WARNING: this file is auto-generated. If you change it directly,\n\t * your modifications will eventually be lost. The source code is in\n\t * `kendo-charts` repository, you should make your changes there and\n\t * run `src-modules/sync.sh` in this repository.\n\t */\n\t(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(858) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function () {\n\n\twindow.kendo.dataviz = window.kendo.dataviz || {};\n\n\tvar BAR_GAP = 1.5;\n\tvar BAR_SPACING = 0.4;\n\tvar BLACK = '#000';\n\tvar SANS = 'Arial, Helvetica, sans-serif';\n\tvar SANS11 = \"11px \" + SANS;\n\tvar SANS12 = '12px ' + SANS;\n\tvar SANS16 = '16px ' + SANS;\n\tvar TRANSPARENT = 'transparent';\n\tvar WHITE = '#fff';\n\n\tvar notes = function () { return ({\n\t icon: {\n\t border: {\n\t width: 1\n\t }\n\t },\n\t label: {\n\t font: SANS12,\n\t padding: 3\n\t },\n\t line: {\n\t length: 10,\n\t width: 2\n\t },\n\t visible: true\n\t}); };\n\n\tvar axisDefaults = function () { return ({\n\t labels: {\n\t font: SANS12\n\t },\n\t notes: notes(),\n\t title: {\n\t font: SANS16,\n\t margin: 5\n\t }\n\t}); };\n\n\tvar areaSeries = function () { return ({\n\t highlight: {\n\t markers: {\n\t border: {}\n\t }\n\t },\n\t line: {\n\t opacity: 1,\n\t width: 0\n\t },\n\t markers: {\n\t size: 6,\n\t visible: false\n\t },\n\t opacity: 0.4\n\t}); };\n\n\tvar rangeAreaSeries = function () { return ({\n\t highlight: {\n\t markers: {\n\t border: {}\n\t }\n\t },\n\t line: {\n\t opacity: 1,\n\t width: 0\n\t },\n\t markers: {\n\t size: 6,\n\t visible: false\n\t },\n\t opacity: 0.4\n\t}); };\n\n\tvar barSeries = function () { return ({\n\t gap: BAR_GAP,\n\t spacing: BAR_SPACING\n\t}); };\n\n\tvar boxPlotSeries = function () { return ({\n\t outliersField: \"\",\n\t meanField: \"\",\n\t border: {\n\t _brightness: 0.8,\n\t width: 1\n\t },\n\t downColor: WHITE,\n\t gap: 1,\n\t highlight: {\n\t border: {\n\t opacity: 1,\n\t width: 2\n\t },\n\t whiskers: {\n\t width: 3\n\t },\n\t mean: {\n\t width: 2\n\t },\n\t median: {\n\t width: 2\n\t }\n\t },\n\t mean: {\n\t width: 2\n\t },\n\t median: {\n\t width: 2\n\t },\n\t spacing: 0.3,\n\t whiskers: {\n\t width: 2\n\t }\n\t}); };\n\n\tvar bubbleSeries = function () { return ({\n\t border: {\n\t width: 0\n\t },\n\t labels: {\n\t background: TRANSPARENT\n\t },\n\t opacity: 0.6\n\t}); };\n\n\tvar bulletSeries = function () { return ({\n\t gap: BAR_GAP,\n\t spacing: BAR_SPACING,\n\t target: {\n\t color: \"#ff0000\"\n\t }\n\t}); };\n\n\tvar candlestickSeries = function () { return ({\n\t border: {\n\t _brightness: 0.8,\n\t width: 1\n\t },\n\t downColor: WHITE,\n\t gap: 1,\n\t highlight: {\n\t border: {\n\t opacity: 1,\n\t width: 2\n\t },\n\t line: {\n\t width: 2\n\t }\n\t },\n\t line: {\n\t color: BLACK,\n\t width: 1\n\t },\n\t spacing: 0.3\n\t}); };\n\n\tvar columnSeries = function () { return ({\n\t gap: BAR_GAP,\n\t spacing: BAR_SPACING\n\t}); };\n\n\tvar donutSeries = function () { return ({\n\t margin: 1\n\t}); };\n\n\tvar lineSeries = function () { return ({\n\t width: 2\n\t}); };\n\n\tvar ohlcSeries = function () { return ({\n\t gap: 1,\n\t highlight: {\n\t line: {\n\t opacity: 1,\n\t width: 3\n\t }\n\t },\n\t line: {\n\t width: 1\n\t },\n\t spacing: 0.3\n\t}); };\n\n\tvar radarAreaSeries = function () { return ({\n\t line: {\n\t opacity: 1,\n\t width: 0\n\t },\n\t markers: {\n\t size: 6,\n\t visible: false\n\t },\n\t opacity: 0.5\n\t}); };\n\n\tvar radarLineSeries = function () { return ({\n\t markers: {\n\t visible: false\n\t },\n\t width: 2\n\t}); };\n\n\tvar rangeBarSeries = function () { return ({\n\t gap: BAR_GAP,\n\t spacing: BAR_SPACING\n\t}); };\n\n\tvar rangeColumnSeries = function () { return ({\n\t gap: BAR_GAP,\n\t spacing: BAR_SPACING\n\t}); };\n\n\tvar scatterLineSeries = function () { return ({\n\t width: 1\n\t}); };\n\n\tvar waterfallSeries = function () { return ({\n\t gap: 0.5,\n\t line: {\n\t color: BLACK,\n\t width: 1\n\t },\n\t spacing: BAR_SPACING\n\t}); };\n\n\tvar pieSeries = function () { return ({\n\t labels: {\n\t background: '',\n\t color: '',\n\t padding: {\n\t top: 5,\n\t bottom: 5,\n\t left: 7,\n\t right: 7\n\t }\n\t }\n\t}); };\n\n\tvar funnelSeries = function () { return ({\n\t labels: {\n\t background: '',\n\t color: '',\n\t padding: {\n\t top: 5,\n\t bottom: 5,\n\t left: 7,\n\t right: 7\n\t }\n\t }\n\t}); };\n\n\tvar seriesDefaults = function (options) { return ({\n\t visible: true,\n\t labels: {\n\t font: SANS11\n\t },\n\t overlay: options.gradients ? {} : {\n\t gradient: \"none\"\n\t },\n\t area: areaSeries(),\n\t rangeArea: rangeAreaSeries(),\n\t verticalRangeArea: rangeAreaSeries(),\n\t bar: barSeries(),\n\t boxPlot: boxPlotSeries(),\n\t bubble: bubbleSeries(),\n\t bullet: bulletSeries(),\n\t candlestick: candlestickSeries(),\n\t column: columnSeries(),\n\t pie: pieSeries(),\n\t donut: donutSeries(),\n\t funnel: funnelSeries(),\n\t horizontalWaterfall: waterfallSeries(),\n\t line: lineSeries(),\n\t notes: notes(),\n\t ohlc: ohlcSeries(),\n\t radarArea: radarAreaSeries(),\n\t radarLine: radarLineSeries(),\n\t polarArea: radarAreaSeries(),\n\t polarLine: radarLineSeries(),\n\t rangeBar: rangeBarSeries(),\n\t rangeColumn: rangeColumnSeries(),\n\t scatterLine: scatterLineSeries(),\n\t verticalArea: areaSeries(),\n\t verticalBoxPlot: boxPlotSeries(),\n\t verticalBullet: bulletSeries(),\n\t verticalLine: lineSeries(),\n\t waterfall: waterfallSeries()\n\t}); };\n\n\tvar title = function () { return ({\n\t font: SANS16\n\t}); };\n\n\tvar legend = function () { return ({\n\t labels: {\n\t font: SANS12\n\t }\n\t}); };\n\n\tvar baseTheme = function (options) {\n\t if (options === void 0) { options = {}; }\n\n\t return ({\n\t axisDefaults: axisDefaults(),\n\t categoryAxis: {\n\t majorGridLines: {\n\t visible: true\n\t }\n\t },\n\t navigator: {\n\t pane: {\n\t height: 90,\n\t margin: {\n\t top: 10\n\t }\n\t }\n\t },\n\t seriesDefaults: seriesDefaults(options),\n\t title: title(),\n\t legend: legend()\n\t});\n\t};\n\n\tkendo.deepExtend(kendo.dataviz, {\n\t chartBaseTheme: baseTheme\n\t});\n\n\t})();\n\n\t}, __webpack_require__(3));\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(918);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 918:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(919) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\t // Imports ================================================================\n\t var kendo = window.kendo,\n\t ui = kendo.dataviz.ui,\n\t deepExtend = kendo.deepExtend;\n\n\t // Constants ==============================================================\n\t var BLACK = \"#000\",\n\t SANS = \"Arial,Helvetica,sans-serif\",\n\t SANS12 = \"12px \" + SANS,\n\t WHITE = \"#fff\";\n\n\t var chartBaseTheme = kendo.dataviz.chartBaseTheme({\n\t gradients: true\n\t });\n\n\t var gaugeBaseTheme = {\n\t scale: {\n\t labels: {\n\t font: SANS12\n\t }\n\t }\n\t };\n\n\t var diagramBaseTheme = {\n\t shapeDefaults: {\n\t hover: {\n\t opacity: 0.2\n\t },\n\t stroke: {\n\t width: 0\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t width: 7,\n\t height: 7\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t width: 1,\n\t dashType: \"dot\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t width: 2\n\t },\n\t selection: {\n\t handles: {\n\t width: 8,\n\t height: 8\n\t }\n\t },\n\t editable: {\n\t tools: [\"edit\", \"delete\"]\n\t }\n\t }\n\t };\n\n\t var themes = ui.themes,\n\t registerTheme = ui.registerTheme = function(themeName, options) {\n\t var result = {};\n\t // Apply base theme\n\t result.chart = deepExtend({}, chartBaseTheme, options.chart);\n\t result.gauge = deepExtend({}, gaugeBaseTheme, options.gauge);\n\t result.diagram = deepExtend({}, diagramBaseTheme, options.diagram);\n\t result.treeMap = deepExtend({}, options.treeMap);\n\n\t // Copy the line/area chart settings for their vertical counterparts\n\t var defaults = result.chart.seriesDefaults;\n\t defaults.verticalLine = deepExtend({}, defaults.line);\n\t defaults.verticalArea = deepExtend({}, defaults.area);\n\t defaults.rangeArea = deepExtend({}, defaults.area);\n\t defaults.verticalRangeArea = deepExtend({}, defaults.rangeArea);\n\t defaults.verticalBoxPlot = deepExtend({}, defaults.boxPlot);\n\t defaults.polarArea = deepExtend({}, defaults.radarArea);\n\t defaults.polarLine = deepExtend({}, defaults.radarLine);\n\n\t themes[themeName] = result;\n\t };\n\n\t registerTheme(\"black\", {\n\t chart: {\n\t title: {\n\t color: WHITE\n\t },\n\t legend: {\n\t labels: {\n\t color: WHITE\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#919191\"\n\t },\n\t markers: {\n\t color: \"#919191\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: WHITE\n\t },\n\t errorBars: {\n\t color: WHITE\n\t },\n\t notes: {\n\t icon: {\n\t background: \"#3b3b3b\",\n\t border: {\n\t color: \"#8e8e8e\"\n\t }\n\t },\n\t label: {\n\t color: WHITE\n\t },\n\t line: {\n\t color: \"#8e8e8e\"\n\t }\n\t },\n\t pie: {\n\t overlay: {\n\t gradient: \"sharpBevel\"\n\t }\n\t },\n\t donut: {\n\t overlay: {\n\t gradient: \"sharpGlass\"\n\t }\n\t },\n\t line: {\n\t markers: {\n\t background: \"#3d3d3d\"\n\t }\n\t },\n\t scatter: {\n\t markers: {\n\t background: \"#3d3d3d\"\n\t }\n\t },\n\t scatterLine: {\n\t markers: {\n\t background: \"#3d3d3d\"\n\t }\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#8e8e8e\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#8e8e8e\"\n\t }\n\t },\n\t candlestick: {\n\t downColor: \"#555\",\n\t line: {\n\t color: WHITE\n\t },\n\t border: {\n\t _brightness: 1.5,\n\t opacity: 1\n\t },\n\t highlight: {\n\t border: {\n\t color: WHITE,\n\t opacity: 0.2\n\t }\n\t }\n\t },\n\t ohlc: {\n\t line: {\n\t color: WHITE\n\t }\n\t }\n\t },\n\t chartArea: {\n\t background: \"#3d3d3d\"\n\t },\n\t seriesColors: [\"#0081da\", \"#3aafff\", \"#99c900\", \"#ffeb3d\", \"#b20753\", \"#ff4195\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#8e8e8e\"\n\t },\n\t labels: {\n\t color: WHITE\n\t },\n\t majorGridLines: {\n\t color: \"#545454\"\n\t },\n\t minorGridLines: {\n\t color: \"#454545\"\n\t },\n\t title: {\n\t color: WHITE\n\t },\n\t crosshair: {\n\t color: \"#8e8e8e\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"#3b3b3b\",\n\t border: {\n\t color: \"#8e8e8e\"\n\t }\n\t },\n\t label: {\n\t color: WHITE\n\t },\n\t line: {\n\t color: \"#8e8e8e\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#0070e4\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#1d1d1d\",\n\t labels: {\n\t color: WHITE\n\t },\n\t minorTicks: {\n\t color: WHITE\n\t },\n\t majorTicks: {\n\t color: WHITE\n\t },\n\t line: {\n\t color: WHITE\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#0066cc\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#384049\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#3d3d3d\"\n\t },\n\t stroke: {\n\t color: \"#efefef\"\n\t }\n\t }\n\t },\n\t content: {\n\t color: WHITE\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: \"#3d3d3d\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: WHITE\n\t },\n\t fill: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: WHITE\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: WHITE\n\t },\n\t content: {\n\t color: WHITE\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: \"#3d3d3d\"\n\t },\n\t stroke: {\n\t color: \"#efefef\"\n\t }\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#0081da\", \"#314b5c\"],\n\t [\"#3aafff\", \"#3c5464\"],\n\t [\"#99c900\", \"#4f5931\"],\n\t [\"#ffeb3d\", \"#64603d\"],\n\t [\"#b20753\", \"#543241\"],\n\t [\"#ff4195\", \"#643e4f\"]]\n\t }\n\t });\n\n\t registerTheme(\"blueopal\", {\n\t chart: {\n\t title: {\n\t color: \"#293135\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#293135\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#27A5BA\"\n\t },\n\t markers: {\n\t color: \"#27A5BA\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: BLACK,\n\t background: WHITE,\n\t opacity: 0.5\n\t },\n\t errorBars: {\n\t color: \"#293135\"\n\t },\n\t candlestick: {\n\t downColor: \"#c4d0d5\",\n\t line: {\n\t color: \"#9aabb2\"\n\t }\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#9aabb2\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#9aabb2\"\n\t }\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#9aabb2\"\n\t }\n\t },\n\t label: {\n\t color: \"#293135\"\n\t },\n\t line: {\n\t color: \"#9aabb2\"\n\t }\n\t }\n\t },\n\t seriesColors: [\"#0069a5\", \"#0098ee\", \"#7bd2f6\", \"#ffb800\", \"#ff8517\", \"#e34a00\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#9aabb2\"\n\t },\n\t labels: {\n\t color: \"#293135\"\n\t },\n\t majorGridLines: {\n\t color: \"#c4d0d5\"\n\t },\n\t minorGridLines: {\n\t color: \"#edf1f2\"\n\t },\n\t title: {\n\t color: \"#293135\"\n\t },\n\t crosshair: {\n\t color: \"#9aabb2\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#9aabb2\"\n\t }\n\t },\n\t label: {\n\t color: \"#293135\"\n\t },\n\t line: {\n\t color: \"#9aabb2\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#005c83\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#daecf4\",\n\n\t labels: {\n\t color: \"#293135\"\n\t },\n\t minorTicks: {\n\t color: \"#293135\"\n\t },\n\t majorTicks: {\n\t color: \"#293135\"\n\t },\n\t line: {\n\t color: \"#293135\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#7ec6e3\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: \"#003f59\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#003f59\"\n\t }\n\t }\n\t },\n\t content: {\n\t color: \"#293135\"\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#003f59\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#003f59\"\n\t },\n\t stroke: {\n\t color: \"#003f59\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: \"#003f59\"\n\t },\n\t fill: {\n\t color: \"#003f59\"\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#003f59\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: \"#003f59\"\n\t },\n\t content: {\n\t color: \"#293135\"\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: \"#3d3d3d\"\n\t },\n\t stroke: {\n\t color: \"#efefef\"\n\t }\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#0069a5\", \"#bad7e7\"],\n\t [\"#0098ee\", \"#b9e0f5\"],\n\t [\"#7bd2f6\", \"#ceeaf6\"],\n\t [\"#ffb800\", \"#e6e3c4\"],\n\t [\"#ff8517\", \"#e4d8c8\"],\n\t [\"#e34a00\", \"#ddccc2\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"highcontrast\", {\n\t chart: {\n\t title: {\n\t color: \"#ffffff\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#66465B\"\n\t },\n\t markers: {\n\t color: \"#66465B\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t errorBars: {\n\t color: \"#ffffff\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#ffffff\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: \"#ffffff\"\n\t }\n\t },\n\t pie: {\n\t overlay: {\n\t gradient: \"sharpGlass\"\n\t }\n\t },\n\t donut: {\n\t overlay: {\n\t gradient: \"sharpGlass\"\n\t }\n\t },\n\t line: {\n\t markers: {\n\t background: \"#2c232b\"\n\t }\n\t },\n\t scatter: {\n\t markers: {\n\t background: \"#2c232b\"\n\t }\n\t },\n\t scatterLine: {\n\t markers: {\n\t background: \"#2c232b\"\n\t }\n\t },\n\t area: {\n\t opacity: 0.5\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#ffffff\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#ffffff\"\n\t }\n\t },\n\t candlestick: {\n\t downColor: \"#664e62\",\n\t line: {\n\t color: \"#ffffff\"\n\t },\n\t border: {\n\t _brightness: 1.5,\n\t opacity: 1\n\t },\n\t highlight: {\n\t border: {\n\t color: \"#ffffff\",\n\t opacity: 1\n\t }\n\t }\n\t },\n\t ohlc: {\n\t line: {\n\t color: \"#ffffff\"\n\t }\n\t }\n\t },\n\t chartArea: {\n\t background: \"#2c232b\"\n\t },\n\t seriesColors: [\"#a7008f\", \"#ffb800\", \"#3aafff\", \"#99c900\", \"#b20753\", \"#ff4195\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#ffffff\"\n\t },\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t majorGridLines: {\n\t color: \"#664e62\"\n\t },\n\t minorGridLines: {\n\t color: \"#4f394b\"\n\t },\n\t title: {\n\t color: \"#ffffff\"\n\t },\n\t crosshair: {\n\t color: \"#ffffff\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#ffffff\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: \"#ffffff\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#a7008f\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#2c232b\",\n\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t minorTicks: {\n\t color: \"#2c232b\"\n\t },\n\t majorTicks: {\n\t color: \"#664e62\"\n\t },\n\t line: {\n\t color: \"#ffffff\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#a7018f\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#2c232b\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#2c232b\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t }\n\t }\n\t },\n\t content: {\n\t color: WHITE\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: \"#2c232b\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: WHITE\n\t },\n\t fill: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: WHITE\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: WHITE\n\t },\n\t content: {\n\t color: WHITE\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: \"#2c232b\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#a7008f\", \"#451c3f\"],\n\t [\"#ffb800\", \"#564122\"],\n\t [\"#3aafff\", \"#2f3f55\"],\n\t [\"#99c900\", \"#424422\"],\n\t [\"#b20753\", \"#471d33\"],\n\t [\"#ff4195\", \"#562940\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"default\", {\n\t chart: {\n\t title: {\n\t color: \"#8e8e8e\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#232323\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#919191\"\n\t },\n\t markers: {\n\t color: \"#919191\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: BLACK,\n\t background: WHITE,\n\t opacity: 0.5\n\t },\n\t errorBars: {\n\t color: \"#232323\"\n\t },\n\t candlestick: {\n\t downColor: \"#dedede\",\n\t line: {\n\t color: \"#8d8d8d\"\n\t }\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#8e8e8e\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#8e8e8e\"\n\t }\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#8e8e8e\"\n\t }\n\t },\n\t label: {\n\t color: \"#232323\"\n\t },\n\t line: {\n\t color: \"#8e8e8e\"\n\t }\n\t }\n\t },\n\t seriesColors: [\"#ff6800\", \"#a0a700\", \"#ff8d00\", \"#678900\", \"#ffb53c\", \"#396000\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#8e8e8e\"\n\t },\n\t labels: {\n\t color: \"#232323\"\n\t },\n\t minorGridLines: {\n\t color: \"#f0f0f0\"\n\t },\n\t majorGridLines: {\n\t color: \"#dfdfdf\"\n\t },\n\t title: {\n\t color: \"#232323\"\n\t },\n\t crosshair: {\n\t color: \"#8e8e8e\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#8e8e8e\"\n\t }\n\t },\n\t label: {\n\t color: \"#232323\"\n\t },\n\t line: {\n\t color: \"#8e8e8e\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#ea7001\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#dedede\",\n\n\t labels: {\n\t color: \"#2e2e2e\"\n\t },\n\t minorTicks: {\n\t color: \"#2e2e2e\"\n\t },\n\t majorTicks: {\n\t color: \"#2e2e2e\"\n\t },\n\t line: {\n\t color: \"#2e2e2e\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#e15613\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: \"#282828\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#282828\"\n\t }\n\t }\n\t },\n\t content: {\n\t color: \"#2e2e2e\"\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#282828\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#282828\"\n\t },\n\t stroke: {\n\t color: \"#282828\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: \"#282828\"\n\t },\n\t fill: {\n\t color: \"#282828\"\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#a7018f\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: \"#282828\"\n\t },\n\t content: {\n\t color: \"#2e2e2e\"\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#282828\"\n\t }\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#ff6800\", \"#edcfba\"],\n\t [\"#a0a700\", \"#dadcba\"],\n\t [\"#ff8d00\", \"#edd7ba\"],\n\t [\"#678900\", \"#cfd6ba\"],\n\t [\"#ffb53c\", \"#eddfc6\"],\n\t [\"#396000\", \"#c6ceba\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"silver\", {\n\t chart: {\n\t title: {\n\t color: \"#4e5968\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#4e5968\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#B1BCC8\"\n\t },\n\t markers: {\n\t color: \"#B1BCC8\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: \"#293135\",\n\t background: \"#eaeaec\",\n\t opacity: 0.5\n\t },\n\t errorBars: {\n\t color: \"#4e5968\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#4e5968\"\n\t }\n\t },\n\t label: {\n\t color: \"#4e5968\"\n\t },\n\t line: {\n\t color: \"#4e5968\"\n\t }\n\t },\n\t line: {\n\t markers: {\n\t background: \"#eaeaec\"\n\t }\n\t },\n\t scatter: {\n\t markers: {\n\t background: \"#eaeaec\"\n\t }\n\t },\n\t scatterLine: {\n\t markers: {\n\t background: \"#eaeaec\"\n\t }\n\t },\n\t pie: {\n\t connectors: {\n\t color: \"#A6B1C0\"\n\t }\n\t },\n\t donut: {\n\t connectors: {\n\t color: \"#A6B1C0\"\n\t }\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#a6b1c0\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#a6b1c0\"\n\t }\n\t },\n\t candlestick: {\n\t downColor: \"#a6afbe\"\n\t }\n\t },\n\t chartArea: {\n\t background: \"#eaeaec\"\n\t },\n\t seriesColors: [\"#007bc3\", \"#76b800\", \"#ffae00\", \"#ef4c00\", \"#a419b7\", \"#430B62\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#a6b1c0\"\n\t },\n\t labels: {\n\t color: \"#4e5968\"\n\t },\n\t majorGridLines: {\n\t color: \"#dcdcdf\"\n\t },\n\t minorGridLines: {\n\t color: \"#eeeeef\"\n\t },\n\t title: {\n\t color: \"#4e5968\"\n\t },\n\t crosshair: {\n\t color: \"#a6b1c0\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#4e5968\"\n\t }\n\t },\n\t label: {\n\t color: \"#4e5968\"\n\t },\n\t line: {\n\t color: \"#4e5968\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#0879c0\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#f3f3f4\",\n\n\t labels: {\n\t color: \"#515967\"\n\t },\n\t minorTicks: {\n\t color: \"#515967\"\n\t },\n\t majorTicks: {\n\t color: \"#515967\"\n\t },\n\t line: {\n\t color: \"#515967\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#1c82c2\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: \"#515967\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#282828\"\n\t }\n\t }\n\t },\n\t content: {\n\t color: \"#515967\"\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#515967\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#515967\"\n\t },\n\t stroke: {\n\t color: \"#515967\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: \"#515967\"\n\t },\n\t fill: {\n\t color: \"#515967\"\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#515967\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: \"#515967\"\n\t },\n\t content: {\n\t color: \"#515967\"\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#515967\"\n\t }\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#007bc3\", \"#c2dbea\"],\n\t [\"#76b800\", \"#dae7c3\"],\n\t [\"#ffae00\", \"#f5e5c3\"],\n\t [\"#ef4c00\", \"#f2d2c3\"],\n\t [\"#a419b7\", \"#e3c7e8\"],\n\t [\"#430b62\", \"#d0c5d7\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"metro\", {\n\t chart: {\n\t title: {\n\t color: \"#777777\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#777777\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#CBCBCB\"\n\t },\n\t markers: {\n\t color: \"#CBCBCB\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: BLACK\n\t },\n\t errorBars: {\n\t color: \"#777777\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#777777\"\n\t }\n\t },\n\t label: {\n\t color: \"#777777\"\n\t },\n\t line: {\n\t color: \"#777777\"\n\t }\n\t },\n\t candlestick: {\n\t downColor: \"#c7c7c7\",\n\t line: {\n\t color: \"#787878\"\n\t }\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#c7c7c7\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#c7c7c7\"\n\t }\n\t },\n\t overlay: {\n\t gradient: \"none\"\n\t },\n\t border: {\n\t _brightness: 1\n\t }\n\t },\n\t seriesColors: [\"#8ebc00\", \"#309b46\", \"#25a0da\", \"#ff6900\", \"#e61e26\", \"#d8e404\", \"#16aba9\", \"#7e51a1\", \"#313131\", \"#ed1691\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#c7c7c7\"\n\t },\n\t labels: {\n\t color: \"#777777\"\n\t },\n\t minorGridLines: {\n\t color: \"#c7c7c7\"\n\t },\n\t majorGridLines: {\n\t color: \"#c7c7c7\"\n\t },\n\t title: {\n\t color: \"#777777\"\n\t },\n\t crosshair: {\n\t color: \"#c7c7c7\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#777777\"\n\t }\n\t },\n\t label: {\n\t color: \"#777777\"\n\t },\n\t line: {\n\t color: \"#777777\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#8ebc00\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#e6e6e6\",\n\n\t labels: {\n\t color: \"#777\"\n\t },\n\t minorTicks: {\n\t color: \"#777\"\n\t },\n\t majorTicks: {\n\t color: \"#777\"\n\t },\n\t line: {\n\t color: \"#777\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#8ebc00\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: BLACK\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: BLACK\n\t }\n\t }\n\t },\n\t content: {\n\t color: \"#777\"\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#787878\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#787878\"\n\t },\n\t stroke: {\n\t color: \"#787878\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: \"#787878\"\n\t },\n\t fill: {\n\t color: \"#787878\"\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#515967\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: \"#787878\"\n\t },\n\t content: {\n\t color: \"#777\"\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#787878\"\n\t }\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#8ebc00\", \"#e8f2cc\"],\n\t [\"#309b46\", \"#d6ebda\"],\n\t [\"#25a0da\", \"#d3ecf8\"],\n\t [\"#ff6900\", \"#ffe1cc\"],\n\t [\"#e61e26\", \"#fad2d4\"],\n\t [\"#d8e404\", \"#f7facd\"],\n\t [\"#16aba9\", \"#d0eeee\"],\n\t [\"#7e51a1\", \"#e5dcec\"],\n\t [\"#313131\", \"#d6d6d6\"],\n\t [\"#ed1691\", \"#fbd0e9\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"metroblack\", {\n\t chart: {\n\t title: {\n\t color: \"#ffffff\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#797979\"\n\t },\n\t markers: {\n\t color: \"#797979\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t border: {\n\t _brightness: 1\n\t },\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t errorBars: {\n\t color: \"#ffffff\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#cecece\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: \"#cecece\"\n\t }\n\t },\n\t line: {\n\t markers: {\n\t background: \"#0e0e0e\"\n\t }\n\t },\n\t bubble: {\n\t opacity: 0.6\n\t },\n\t scatter: {\n\t markers: {\n\t background: \"#0e0e0e\"\n\t }\n\t },\n\t scatterLine: {\n\t markers: {\n\t background: \"#0e0e0e\"\n\t }\n\t },\n\t candlestick: {\n\t downColor: \"#828282\",\n\t line: {\n\t color: \"#ffffff\"\n\t }\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#cecece\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#cecece\"\n\t }\n\t },\n\t overlay: {\n\t gradient: \"none\"\n\t }\n\t },\n\t chartArea: {\n\t background: \"#0e0e0e\"\n\t },\n\t seriesColors: [\"#00aba9\", \"#309b46\", \"#8ebc00\", \"#ff6900\", \"#e61e26\", \"#d8e404\", \"#25a0da\", \"#7e51a1\", \"#313131\", \"#ed1691\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#cecece\"\n\t },\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t minorGridLines: {\n\t color: \"#2d2d2d\"\n\t },\n\t majorGridLines: {\n\t color: \"#333333\"\n\t },\n\t title: {\n\t color: \"#ffffff\"\n\t },\n\t crosshair: {\n\t color: \"#cecece\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#cecece\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: \"#cecece\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#00aba9\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#2d2d2d\",\n\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t minorTicks: {\n\t color: \"#333333\"\n\t },\n\t majorTicks: {\n\t color: \"#cecece\"\n\t },\n\t line: {\n\t color: \"#cecece\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#00aba9\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#0e0e0e\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#0e0e0e\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t }\n\t }\n\t },\n\t content: {\n\t color: WHITE\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: \"#0e0e0e\"\n\t },\n\t stroke: {\n\t color: \"#787878\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#787878\"\n\t },\n\t stroke: {\n\t color: \"#787878\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: WHITE\n\t },\n\t fill: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#787878\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: WHITE\n\t },\n\t content: {\n\t color: WHITE\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: \"#0e0e0e\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#00aba9\", \"#0b2d2d\"],\n\t [\"#309b46\", \"#152a19\"],\n\t [\"#8ebc00\", \"#28310b\"],\n\t [\"#ff6900\", \"#3e200b\"],\n\t [\"#e61e26\", \"#391113\"],\n\t [\"#d8e404\", \"#36390c\"],\n\t [\"#25a0da\", \"#132b37\"],\n\t [\"#7e51a1\", \"#241b2b\"],\n\t [\"#313131\", \"#151515\"],\n\t [\"#ed1691\", \"#3b1028\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"moonlight\", {\n\t chart: {\n\t title: {\n\t color: \"#ffffff\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#A1A7AB\"\n\t },\n\t markers: {\n\t color: \"#A1A7AB\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t errorBars: {\n\t color: \"#ffffff\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#8c909e\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: \"#8c909e\"\n\t }\n\t },\n\t pie: {\n\t overlay: {\n\t gradient: \"sharpBevel\"\n\t }\n\t },\n\t donut: {\n\t overlay: {\n\t gradient: \"sharpGlass\"\n\t }\n\t },\n\t line: {\n\t markers: {\n\t background: \"#212a33\"\n\t }\n\t },\n\t bubble: {\n\t opacity: 0.6\n\t },\n\t scatter: {\n\t markers: {\n\t background: \"#212a33\"\n\t }\n\t },\n\t scatterLine: {\n\t markers: {\n\t background: \"#212a33\"\n\t }\n\t },\n\t area: {\n\t opacity: 0.3\n\t },\n\t candlestick: {\n\t downColor: \"#757d87\",\n\t line: {\n\t color: \"#ea9d06\"\n\t },\n\t border: {\n\t _brightness: 1.5,\n\t opacity: 1\n\t },\n\t highlight: {\n\t border: {\n\t color: WHITE,\n\t opacity: 0.2\n\t }\n\t }\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#8c909e\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#8c909e\"\n\t }\n\t },\n\t ohlc: {\n\t line: {\n\t color: \"#ea9d06\"\n\t }\n\t }\n\t },\n\t chartArea: {\n\t background: \"#212a33\"\n\t },\n\t seriesColors: [\"#ffca08\", \"#ff710f\", \"#ed2e24\", \"#ff9f03\", \"#e13c02\", \"#a00201\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#8c909e\"\n\t },\n\t minorTicks: {\n\t color: \"#8c909e\"\n\t },\n\t majorTicks: {\n\t color: \"#8c909e\"\n\t },\n\t labels: {\n\t color: \"#ffffff\"\n\t },\n\t majorGridLines: {\n\t color: \"#3e424d\"\n\t },\n\t minorGridLines: {\n\t color: \"#2f3640\"\n\t },\n\t title: {\n\t color: \"#ffffff\"\n\t },\n\t crosshair: {\n\t color: \"#8c909e\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#8c909e\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: \"#8c909e\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#f4af03\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#2f3640\",\n\n\t labels: {\n\t color: WHITE\n\t },\n\t minorTicks: {\n\t color: \"#8c909e\"\n\t },\n\t majorTicks: {\n\t color: \"#8c909e\"\n\t },\n\t line: {\n\t color: \"#8c909e\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#f3ae03\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#414550\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#414550\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t }\n\t }\n\t },\n\t content: {\n\t color: WHITE\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: \"#414550\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: WHITE\n\t },\n\t fill: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: WHITE\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: WHITE\n\t },\n\t content: {\n\t color: WHITE\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: \"#414550\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t }\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#ffca08\", \"#4e4b2b\"],\n\t [\"#ff710f\", \"#4e392d\"],\n\t [\"#ed2e24\", \"#4b2c31\"],\n\t [\"#ff9f03\", \"#4e422a\"],\n\t [\"#e13c02\", \"#482e2a\"],\n\t [\"#a00201\", \"#3b232a\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"uniform\", {\n\t chart: {\n\t title: {\n\t color: \"#686868\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#686868\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#B6B6B6\"\n\t },\n\t markers: {\n\t color: \"#B6B6B6\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: \"#686868\"\n\t },\n\t errorBars: {\n\t color: \"#686868\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#9e9e9e\"\n\t }\n\t },\n\t label: {\n\t color: \"#686868\"\n\t },\n\t line: {\n\t color: \"#9e9e9e\"\n\t }\n\t },\n\t pie: {\n\t overlay: {\n\t gradient: \"sharpBevel\"\n\t }\n\t },\n\t donut: {\n\t overlay: {\n\t gradient: \"sharpGlass\"\n\t }\n\t },\n\t line: {\n\t markers: {\n\t background: \"#ffffff\"\n\t }\n\t },\n\t bubble: {\n\t opacity: 0.6\n\t },\n\t scatter: {\n\t markers: {\n\t background: \"#ffffff\"\n\t }\n\t },\n\t scatterLine: {\n\t markers: {\n\t background: \"#ffffff\"\n\t }\n\t },\n\t area: {\n\t opacity: 0.3\n\t },\n\t candlestick: {\n\t downColor: \"#cccccc\",\n\t line: {\n\t color: \"#cccccc\"\n\t },\n\t border: {\n\t _brightness: 1.5,\n\t opacity: 1\n\t },\n\t highlight: {\n\t border: {\n\t color: \"#cccccc\",\n\t opacity: 0.2\n\t }\n\t }\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#9e9e9e\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#9e9e9e\"\n\t }\n\t },\n\t ohlc: {\n\t line: {\n\t color: \"#cccccc\"\n\t }\n\t }\n\t },\n\t chartArea: {\n\t background: \"#ffffff\"\n\t },\n\t seriesColors: [\"#527aa3\", \"#6f91b3\", \"#8ca7c2\", \"#a8bdd1\", \"#c5d3e0\", \"#e2e9f0\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#9e9e9e\"\n\t },\n\t minorTicks: {\n\t color: \"#aaaaaa\"\n\t },\n\t majorTicks: {\n\t color: \"#888888\"\n\t },\n\t labels: {\n\t color: \"#686868\"\n\t },\n\t majorGridLines: {\n\t color: \"#dadada\"\n\t },\n\t minorGridLines: {\n\t color: \"#e7e7e7\"\n\t },\n\t title: {\n\t color: \"#686868\"\n\t },\n\t crosshair: {\n\t color: \"#9e9e9e\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#9e9e9e\"\n\t }\n\t },\n\t label: {\n\t color: \"#686868\"\n\t },\n\t line: {\n\t color: \"#9e9e9e\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#527aa3\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#e7e7e7\",\n\n\t labels: {\n\t color: \"#686868\"\n\t },\n\t minorTicks: {\n\t color: \"#aaaaaa\"\n\t },\n\t majorTicks: {\n\t color: \"#888888\"\n\t },\n\t line: {\n\t color: \"#9e9e9e\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#d1d1d1\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: \"#686868\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#686868\"\n\t }\n\t }\n\t },\n\t content: {\n\t color: \"#686868\"\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#686868\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#686868\"\n\t },\n\t stroke: {\n\t color: \"#686868\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: \"#686868\"\n\t },\n\t fill: {\n\t color: \"#686868\"\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#686868\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: \"#686868\"\n\t },\n\t content: {\n\t color: \"#686868\"\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#686868\"\n\t }\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#527aa3\", \"#d0d8e1\"],\n\t [\"#6f91b3\", \"#d6dde4\"],\n\t [\"#8ca7c2\", \"#dce1e7\"],\n\t [\"#a8bdd1\", \"#e2e6ea\"],\n\t [\"#c5d3e0\", \"#e7eaed\"],\n\t [\"#e2e9f0\", \"#edeff0\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"bootstrap\", {\n\t chart: {\n\t title: {\n\t color: \"#333333\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#333333\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#999999\"\n\t },\n\t markers: {\n\t color: \"#9A9A9A\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: \"#333333\"\n\t },\n\t overlay: {\n\t gradient: \"none\"\n\t },\n\t errorBars: {\n\t color: \"#343434\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"#000000\",\n\t border: {\n\t color: \"#000000\"\n\t }\n\t },\n\t label: {\n\t color: \"#333333\"\n\t },\n\t line: {\n\t color: \"#000000\"\n\t }\n\t },\n\t pie: {\n\t overlay: {\n\t gradient: \"none\"\n\t }\n\t },\n\t donut: {\n\t overlay: {\n\t gradient: \"none\"\n\t }\n\t },\n\t line: {\n\t markers: {\n\t background: \"#ffffff\"\n\t }\n\t },\n\t bubble: {\n\t opacity: 0.6\n\t },\n\t scatter: {\n\t markers: {\n\t background: \"#ffffff\"\n\t }\n\t },\n\t scatterLine: {\n\t markers: {\n\t background: \"#ffffff\"\n\t }\n\t },\n\t area: {\n\t opacity: 0.8\n\t },\n\t candlestick: {\n\t downColor: \"#d0d0d0\",\n\t line: {\n\t color: \"#333333\"\n\t },\n\t border: {\n\t _brightness: 1.5,\n\t opacity: 1\n\t },\n\t highlight: {\n\t border: {\n\t color: \"#b8b8b8\",\n\t opacity: 0.2\n\t }\n\t }\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#cccccc\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#cccccc\"\n\t }\n\t },\n\t ohlc: {\n\t line: {\n\t color: \"#333333\"\n\t }\n\t }\n\t },\n\t chartArea: {\n\t background: \"#ffffff\"\n\t },\n\t seriesColors: [\"#428bca\", \"#5bc0de\", \"#5cb85c\", \"#f2b661\", \"#e67d4a\", \"#da3b36\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#cccccc\"\n\t },\n\t minorTicks: {\n\t color: \"#ebebeb\"\n\t },\n\t majorTicks: {\n\t color: \"#cccccc\"\n\t },\n\t labels: {\n\t color: \"#333333\"\n\t },\n\t majorGridLines: {\n\t color: \"#cccccc\"\n\t },\n\t minorGridLines: {\n\t color: \"#ebebeb\"\n\t },\n\t title: {\n\t color: \"#333333\"\n\t },\n\t crosshair: {\n\t color: \"#000000\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"#000000\",\n\t border: {\n\t color: \"#000000\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: \"#000000\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#428bca\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#cccccc\",\n\t labels: {\n\t color: \"#333333\"\n\t },\n\t minorTicks: {\n\t color: \"#ebebeb\"\n\t },\n\t majorTicks: {\n\t color: \"#cccccc\"\n\t },\n\t line: {\n\t color: \"#cccccc\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#428bca\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: \"#333333\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#333333\"\n\t }\n\t }\n\t },\n\t content: {\n\t color: \"#333333\"\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#333333\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#333333\"\n\t },\n\t stroke: {\n\t color: \"#333333\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: \"#333333\"\n\t },\n\t fill: {\n\t color: \"#333333\"\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#333333\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: \"#c4c4c4\"\n\t },\n\t content: {\n\t color: \"#333333\"\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#333333\"\n\t }\n\t },\n\t stroke: {\n\t color: \"#333333\"\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#428bca\", \"#d1e0ec\"],\n\t [\"#5bc0de\", \"#d6eaf0\"],\n\t [\"#5cb85c\", \"#d6e9d6\"],\n\t [\"#5cb85c\", \"#f4e8d7\"],\n\t [\"#e67d4a\", \"#f2ddd3\"],\n\t [\"#da3b36\", \"#f0d0cf\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"flat\", {\n\t chart: {\n\t title: {\n\t color: \"#4c5356\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#4c5356\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#CBCBCB\"\n\t },\n\t markers: {\n\t color: \"#CBCBCB\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: \"#4c5356\"\n\t },\n\t errorBars: {\n\t color: \"#4c5356\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#cdcdcd\"\n\t }\n\t },\n\t label: {\n\t color: \"#4c5356\"\n\t },\n\t line: {\n\t color: \"#cdcdcd\"\n\t }\n\t },\n\t candlestick: {\n\t downColor: \"#c7c7c7\",\n\t line: {\n\t color: \"#787878\"\n\t }\n\t },\n\t area: {\n\t opacity: 0.9\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#cdcdcd\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#cdcdcd\"\n\t }\n\t },\n\t overlay: {\n\t gradient: \"none\"\n\t },\n\t border: {\n\t _brightness: 1\n\t }\n\t },\n\t seriesColors: [\"#10c4b2\", \"#ff7663\", \"#ffb74f\", \"#a2df53\", \"#1c9ec4\", \"#ff63a5\", \"#1cc47b\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#cdcdcd\"\n\t },\n\t labels: {\n\t color: \"#4c5356\"\n\t },\n\t minorGridLines: {\n\t color: \"#cdcdcd\"\n\t },\n\t majorGridLines: {\n\t color: \"#cdcdcd\"\n\t },\n\t title: {\n\t color: \"#4c5356\"\n\t },\n\t crosshair: {\n\t color: \"#cdcdcd\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#cdcdcd\"\n\t }\n\t },\n\t label: {\n\t color: \"#4c5356\"\n\t },\n\t line: {\n\t color: \"#cdcdcd\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#10c4b2\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#cdcdcd\",\n\n\t labels: {\n\t color: \"#4c5356\"\n\t },\n\t minorTicks: {\n\t color: \"#4c5356\"\n\t },\n\t majorTicks: {\n\t color: \"#4c5356\"\n\t },\n\t line: {\n\t color: \"#4c5356\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#10c4b2\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: \"#363940\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#363940\"\n\t }\n\t }\n\t },\n\t content: {\n\t color: \"#4c5356\"\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#363940\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#363940\"\n\t },\n\t stroke: {\n\t color: \"#363940\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: \"#363940\"\n\t },\n\t fill: {\n\t color: \"#363940\"\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#363940\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: \"#cdcdcd\"\n\t },\n\t content: {\n\t color: \"#4c5356\"\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#363940\"\n\t }\n\t },\n\t stroke: {\n\t color: \"#363940\"\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#10c4b2\", \"#cff3f0\"],\n\t [\"#ff7663\", \"#ffe4e0\"],\n\t [\"#ffb74f\", \"#fff1dc\"],\n\t [\"#a2df53\", \"#ecf9dd\"],\n\t [\"#1c9ec4\", \"#d2ecf3\"],\n\t [\"#ff63a5\", \"#ffe0ed\"],\n\t [\"#1cc47b\", \"#d2f3e5\"]\n\t ]\n\t }\n\t });\n\n\n\t registerTheme(\"material\", {\n\t chart: {\n\t title: {\n\t color: \"#444444\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#444444\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#CBCBCB\"\n\t },\n\t markers: {\n\t color: \"#CBCBCB\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: \"#444444\"\n\t },\n\t errorBars: {\n\t color: \"#444444\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#e5e5e5\"\n\t }\n\t },\n\t label: {\n\t color: \"#444444\"\n\t },\n\t line: {\n\t color: \"#e5e5e5\"\n\t }\n\t },\n\t candlestick: {\n\t downColor: \"#c7c7c7\",\n\t line: {\n\t color: \"#787878\"\n\t }\n\t },\n\t area: {\n\t opacity: 0.9\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#e5e5e5\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#e5e5e5\"\n\t }\n\t },\n\t overlay: {\n\t gradient: \"none\"\n\t },\n\t border: {\n\t _brightness: 1\n\t }\n\t },\n\t seriesColors: [\"#3f51b5\", \"#03a9f4\", \"#4caf50\", \"#f9ce1d\", \"#ff9800\", \"#ff5722\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#e5e5e5\"\n\t },\n\t labels: {\n\t color: \"#444444\"\n\t },\n\t minorGridLines: {\n\t color: \"#e5e5e5\"\n\t },\n\t majorGridLines: {\n\t color: \"#e5e5e5\"\n\t },\n\t title: {\n\t color: \"#444444\"\n\t },\n\t crosshair: {\n\t color: \"#7f7f7f\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#e5e5e5\"\n\t }\n\t },\n\t label: {\n\t color: \"#444444\"\n\t },\n\t line: {\n\t color: \"#e5e5e5\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#3f51b5\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#e5e5e5\",\n\n\t labels: {\n\t color: \"#444444\"\n\t },\n\t minorTicks: {\n\t color: \"#444444\"\n\t },\n\t majorTicks: {\n\t color: \"#444444\"\n\t },\n\t line: {\n\t color: \"#444444\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#3f51b5\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: \"#7f7f7f\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#7f7f7f\"\n\t }\n\t }\n\t },\n\t content: {\n\t color: \"#444444\"\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#444444\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#444444\"\n\t },\n\t stroke: {\n\t color: \"#444444\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: \"#444444\"\n\t },\n\t fill: {\n\t color: \"#444444\"\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#444444\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: \"#7f7f7f\"\n\t },\n\t content: {\n\t color: \"#444444\"\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#444444\"\n\t }\n\t },\n\t stroke: {\n\t color: \"#444444\"\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#3f51b5\", \"#cff3f0\"],\n\t [\"#03a9f4\", \"#e5f6fe\"],\n\t [\"#4caf50\", \"#edf7ed\"],\n\t [\"#f9ce1d\", \"#fefae8\"],\n\t [\"#ff9800\", \"#fff4e5\"],\n\t [\"#ff5722\", \"#ffeee8\"]\n\t ]\n\t }\n\t });\n\n\t registerTheme(\"materialblack\", {\n\t chart: {\n\t title: {\n\t color: \"#fff\"\n\t },\n\t legend: {\n\t labels: {\n\t color: \"#fff\"\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: \"#CBCBCB\"\n\t },\n\t markers: {\n\t color: \"#CBCBCB\"\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: \"#fff\"\n\t },\n\t errorBars: {\n\t color: \"#fff\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#e5e5e5\"\n\t }\n\t },\n\t label: {\n\t color: \"#fff\"\n\t },\n\t line: {\n\t color: \"#e5e5e5\"\n\t }\n\t },\n\t candlestick: {\n\t downColor: \"#c7c7c7\",\n\t line: {\n\t color: \"#787878\"\n\t }\n\t },\n\t area: {\n\t opacity: 0.9\n\t },\n\t waterfall: {\n\t line: {\n\t color: \"#4d4d4d\"\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: \"#4d4d4d\"\n\t }\n\t },\n\t overlay: {\n\t gradient: \"none\"\n\t },\n\t border: {\n\t _brightness: 1\n\t }\n\t },\n\t chartArea: {\n\t background: \"#1c1c1c\"\n\t },\n\t seriesColors: [\"#3f51b5\", \"#03a9f4\", \"#4caf50\", \"#f9ce1d\", \"#ff9800\", \"#ff5722\"],\n\t axisDefaults: {\n\t line: {\n\t color: \"#4d4d4d\"\n\t },\n\t labels: {\n\t color: \"#fff\"\n\t },\n\t minorGridLines: {\n\t color: \"#4d4d4d\"\n\t },\n\t majorGridLines: {\n\t color: \"#4d4d4d\"\n\t },\n\t title: {\n\t color: \"#fff\"\n\t },\n\t crosshair: {\n\t color: \"#7f7f7f\"\n\t },\n\t notes: {\n\t icon: {\n\t background: \"transparent\",\n\t border: {\n\t color: \"#4d4d4d\"\n\t }\n\t },\n\t label: {\n\t color: \"#fff\"\n\t },\n\t line: {\n\t color: \"#4d4d4d\"\n\t }\n\t }\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: \"#3f51b5\"\n\t },\n\t scale: {\n\t rangePlaceholderColor: \"#4d4d4d\",\n\n\t labels: {\n\t color: \"#fff\"\n\t },\n\t minorTicks: {\n\t color: \"#fff\"\n\t },\n\t majorTicks: {\n\t color: \"#fff\"\n\t },\n\t line: {\n\t color: \"#fff\"\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: \"#3f51b5\"\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: \"#7f7f7f\"\n\t },\n\t stroke: {\n\t color: WHITE\n\t },\n\t hover: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#7f7f7f\"\n\t }\n\t }\n\t },\n\t content: {\n\t color: \"#fff\"\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#fff\"\n\t },\n\t hover: {\n\t fill: {\n\t color: \"#fff\"\n\t },\n\t stroke: {\n\t color: \"#fff\"\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: \"#fff\"\n\t },\n\t fill: {\n\t color: \"#fff\"\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: \"#fff\"\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: \"#7f7f7f\"\n\t },\n\t content: {\n\t color: \"#fff\"\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: WHITE\n\t },\n\t stroke: {\n\t color: \"#fff\"\n\t }\n\t },\n\t stroke: {\n\t color: \"#fff\"\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: [\n\t [\"#3f51b5\", \"#cff3f0\"],\n\t [\"#03a9f4\", \"#e5f6fe\"],\n\t [\"#4caf50\", \"#edf7ed\"],\n\t [\"#f9ce1d\", \"#fefae8\"],\n\t [\"#ff9800\", \"#fff4e5\"],\n\t [\"#ff5722\", \"#ffeee8\"]\n\t ]\n\t }\n\t });\n\n\t (function () {\n\t var TEXT = \"#333333\";\n\t var INACTIVE = \"#7f7f7f\";\n\t var INACTIVE_SHAPE = \"#bdbdbd\";\n\t var AXIS = \"#c8c8c8\";\n\t var AXIS_MINOR = \"#dddddd\";\n\t var SERIES = [\"#008fd3\", \"#99d101\", \"#f39b02\", \"#f05662\", \"#c03c53\", \"#acacac\"];\n\t var SERIES_LIGHT = [\"#cbe8f5\", \"#eaf5cb\", \"#fceacc\", \"#fbdcdf\", \"#f2d7dc\", \"#eeeeee\"];\n\t var PRIMARY = SERIES[0];\n\t var DIAGRAM_HOVER = WHITE;\n\n\t function noteStyle() {\n\t return {\n\t icon: {\n\t background: \"#007cc0\",\n\t border: {\n\t color: \"#007cc0\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: AXIS\n\t }\n\t };\n\t }\n\n\t registerTheme(\"fiori\", {\n\t chart: {\n\t title: {\n\t color: TEXT\n\t },\n\t legend: {\n\t labels: {\n\t color: TEXT\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: INACTIVE\n\t },\n\t markers: {\n\t color: INACTIVE\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: TEXT\n\t },\n\t errorBars: {\n\t color: TEXT\n\t },\n\t notes: noteStyle(),\n\t candlestick: {\n\t downColor: AXIS,\n\t line: {\n\t color: INACTIVE_SHAPE\n\t }\n\t },\n\t area: {\n\t opacity: 0.8\n\t },\n\t waterfall: {\n\t line: {\n\t color: AXIS\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: AXIS\n\t }\n\t },\n\t overlay: {\n\t gradient: \"none\"\n\t },\n\t border: {\n\t _brightness: 1\n\t }\n\t },\n\t seriesColors: SERIES,\n\t axisDefaults: {\n\t line: {\n\t color: AXIS\n\t },\n\t labels: {\n\t color: TEXT\n\t },\n\t minorGridLines: {\n\t color: AXIS_MINOR\n\t },\n\t majorGridLines: {\n\t color: AXIS\n\t },\n\t title: {\n\t color: TEXT\n\t },\n\t crosshair: {\n\t color: INACTIVE\n\t },\n\t notes: noteStyle()\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: PRIMARY\n\t },\n\t scale: {\n\t rangePlaceholderColor: AXIS,\n\t labels: {\n\t color: TEXT\n\t },\n\t minorTicks: {\n\t color: TEXT\n\t },\n\t majorTicks: {\n\t color: TEXT\n\t },\n\t line: {\n\t color: TEXT\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: PRIMARY\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: TEXT\n\t },\n\t stroke: {\n\t color: DIAGRAM_HOVER\n\t },\n\t hover: {\n\t fill: {\n\t color: DIAGRAM_HOVER\n\t },\n\t stroke: {\n\t color: TEXT\n\t }\n\t }\n\t },\n\t content: {\n\t color: TEXT\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: DIAGRAM_HOVER\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t },\n\t hover: {\n\t fill: {\n\t color: INACTIVE_SHAPE\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t },\n\t fill: {\n\t color: INACTIVE_SHAPE\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t },\n\t content: {\n\t color: INACTIVE_SHAPE\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: DIAGRAM_HOVER\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: fuse(SERIES, SERIES_LIGHT)\n\t }\n\t });\n\t })();\n\n\t (function() {\n\t var TEXT = \"#4e4e4e\";\n\t var INACTIVE = \"#7f7f7f\";\n\t var INACTIVE_SHAPE = \"#bdbdbd\";\n\t var AXIS = \"#c8c8c8\";\n\t var AXIS_MINOR = \"#e5e5e5\";\n\t var SERIES = [\"#0072c6\", \"#5db2ff\", \"#008a17\", \"#82ba00\", \"#ff8f32\", \"#ac193d\"];\n\t var SERIES_LIGHT = [\"#cbe2f3\", \"#deeffe\", \"#cbe7d0\", \"#e5f0cb\", \"#fee8d5\", \"#eed0d7\"];\n\t var PRIMARY = SERIES[0];\n\t var DIAGRAM_HOVER = WHITE;\n\n\t function noteStyle() {\n\t return {\n\t icon: {\n\t background: \"#00b0ff\",\n\t border: {\n\t color: \"#00b0ff\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: AXIS\n\t }\n\t };\n\t }\n\n\t registerTheme(\"office365\", {\n\t chart: {\n\t title: {\n\t color: TEXT\n\t },\n\t legend: {\n\t labels: {\n\t color: TEXT\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: INACTIVE\n\t },\n\t markers: {\n\t color: INACTIVE\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: TEXT\n\t },\n\t errorBars: {\n\t color: TEXT\n\t },\n\t notes: noteStyle(),\n\t candlestick: {\n\t downColor: AXIS,\n\t line: {\n\t color: INACTIVE_SHAPE\n\t }\n\t },\n\t area: {\n\t opacity: 0.8\n\t },\n\t waterfall: {\n\t line: {\n\t color: AXIS\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: AXIS\n\t }\n\t },\n\t overlay: {\n\t gradient: \"none\"\n\t },\n\t border: {\n\t _brightness: 1\n\t }\n\t },\n\t seriesColors: SERIES,\n\t axisDefaults: {\n\t line: {\n\t color: AXIS\n\t },\n\t labels: {\n\t color: TEXT\n\t },\n\t minorGridLines: {\n\t color: AXIS_MINOR\n\t },\n\t majorGridLines: {\n\t color: AXIS\n\t },\n\t title: {\n\t color: TEXT\n\t },\n\t crosshair: {\n\t color: INACTIVE\n\t },\n\t notes: noteStyle()\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: PRIMARY\n\t },\n\t scale: {\n\t rangePlaceholderColor: AXIS,\n\t labels: {\n\t color: TEXT\n\t },\n\t minorTicks: {\n\t color: TEXT\n\t },\n\t majorTicks: {\n\t color: TEXT\n\t },\n\t line: {\n\t color: TEXT\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: PRIMARY\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: TEXT\n\t },\n\t stroke: {\n\t color: DIAGRAM_HOVER\n\t },\n\t hover: {\n\t fill: {\n\t color: DIAGRAM_HOVER\n\t },\n\t stroke: {\n\t color: TEXT\n\t }\n\t }\n\t },\n\t content: {\n\t color: TEXT\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: DIAGRAM_HOVER\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t },\n\t hover: {\n\t fill: {\n\t color: INACTIVE_SHAPE\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t },\n\t fill: {\n\t color: INACTIVE_SHAPE\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t },\n\t content: {\n\t color: INACTIVE_SHAPE\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: DIAGRAM_HOVER\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: fuse(SERIES, SERIES_LIGHT)\n\t }\n\t });\n\t })();\n\n\t (function () {\n\t var TEXT = \"#32364c\";\n\t var INACTIVE = \"#7f7f7f\";\n\t var INACTIVE_SHAPE = \"#bdbdbd\";\n\t var AXIS = \"#dfe0e1\";\n\t var AXIS_MINOR = \"#dfe0e1\";\n\t var SERIES = [\"#ff4350\", \"#ff9ea5\", \"#00acc1\", \"#80deea\", \"#ffbf46\", \"#ffd78c\"];\n\t var SERIES_LIGHT = [\"#ffd9dc\", \"#ffeced\", \"#cceef3\", \"#e6f8fb\", \"#fff2da\", \"#fff7e8\"];\n\t var PRIMARY = SERIES[0];\n\t var DIAGRAM_HOVER = WHITE;\n\n\t function noteStyle() {\n\t return {\n\t icon: {\n\t background: \"#007cc0\",\n\t border: {\n\t color: \"#007cc0\"\n\t }\n\t },\n\t label: {\n\t color: \"#ffffff\"\n\t },\n\t line: {\n\t color: AXIS\n\t }\n\t };\n\t }\n\n\t registerTheme(\"nova\", {\n\t chart: {\n\t title: {\n\t color: TEXT\n\t },\n\t legend: {\n\t labels: {\n\t color: TEXT\n\t },\n\t inactiveItems: {\n\t labels: {\n\t color: INACTIVE\n\t },\n\t markers: {\n\t color: INACTIVE\n\t }\n\t }\n\t },\n\t seriesDefaults: {\n\t labels: {\n\t color: TEXT\n\t },\n\t errorBars: {\n\t color: TEXT\n\t },\n\t notes: noteStyle(),\n\t candlestick: {\n\t downColor: AXIS,\n\t line: {\n\t color: INACTIVE_SHAPE\n\t }\n\t },\n\t area: {\n\t opacity: 0.8\n\t },\n\t waterfall: {\n\t line: {\n\t color: AXIS\n\t }\n\t },\n\t horizontalWaterfall: {\n\t line: {\n\t color: AXIS\n\t }\n\t },\n\t overlay: {\n\t gradient: \"none\"\n\t },\n\t border: {\n\t _brightness: 1\n\t }\n\t },\n\t seriesColors: SERIES,\n\t axisDefaults: {\n\t line: {\n\t color: AXIS\n\t },\n\t labels: {\n\t color: TEXT\n\t },\n\t minorGridLines: {\n\t color: AXIS_MINOR\n\t },\n\t majorGridLines: {\n\t color: AXIS\n\t },\n\t title: {\n\t color: TEXT\n\t },\n\t crosshair: {\n\t color: TEXT\n\t },\n\t notes: noteStyle()\n\t }\n\t },\n\t gauge: {\n\t pointer: {\n\t color: PRIMARY\n\t },\n\t scale: {\n\t rangePlaceholderColor: AXIS,\n\t labels: {\n\t color: TEXT\n\t },\n\t minorTicks: {\n\t color: TEXT\n\t },\n\t majorTicks: {\n\t color: TEXT\n\t },\n\t line: {\n\t color: TEXT\n\t }\n\t }\n\t },\n\t diagram: {\n\t shapeDefaults: {\n\t fill: {\n\t color: PRIMARY\n\t },\n\t connectorDefaults: {\n\t fill: {\n\t color: TEXT\n\t },\n\t stroke: {\n\t color: DIAGRAM_HOVER\n\t },\n\t hover: {\n\t fill: {\n\t color: DIAGRAM_HOVER\n\t },\n\t stroke: {\n\t color: TEXT\n\t }\n\t }\n\t },\n\t content: {\n\t color: TEXT\n\t }\n\t },\n\t editable: {\n\t resize: {\n\t handles: {\n\t fill: {\n\t color: DIAGRAM_HOVER\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t },\n\t hover: {\n\t fill: {\n\t color: INACTIVE_SHAPE\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t }\n\t }\n\t },\n\t rotate: {\n\t thumb: {\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t },\n\t fill: {\n\t color: INACTIVE_SHAPE\n\t }\n\t }\n\t }\n\t },\n\t selectable: {\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t },\n\t connectionDefaults: {\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t },\n\t content: {\n\t color: INACTIVE_SHAPE\n\t },\n\t selection: {\n\t handles: {\n\t fill: {\n\t color: DIAGRAM_HOVER\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t },\n\t stroke: {\n\t color: INACTIVE_SHAPE\n\t }\n\t }\n\t }\n\t },\n\t treeMap: {\n\t colors: fuse(SERIES, SERIES_LIGHT)\n\t }\n\t });\n\t })();\n\n\t (function () {\n\t var SERIES = [\"#ff6358\", \"#ffd246\", \"#78d237\", \"#28b4c8\", \"#2d73f5\", \"#aa46be\"];\n\t var SERIES_LIGHT = [\"#ffd9dc\", \"#ffeced\", \"#cceef3\", \"#e6f8fb\", \"#fff2da\", \"#fff7e8\"];\n\n\t registerTheme(\"default-v2\", {\n\t chart: { /* read from DOM */ },\n\t gauge: { /* read from DOM */ },\n\t diagram: { /* read from DOM */ },\n\t treeMap: {\n\t colors: fuse(SERIES, SERIES_LIGHT)\n\t }\n\t });\n\n\t themes.sass = themes[\"default-v2\"];\n\t })();\n\n\n\n\t (function () {\n\t var TEXT = \"#292b2c\";\n\t var AXIS = \"rgba(0, 0, 0, .04)\";\n\t var SERIES = [\"#0275d8\", \"#5bc0de\", \"#5cb85c\", \"#f0ad4e\", \"#e67d4a\", \"#d9534f\"];\n\t var SERIES_LIGHT = [\"#ffd9dc\", \"#ffeced\", \"#cceef3\", \"#e6f8fb\", \"#fff2da\", \"#fff7e8\"];\n\t var PRIMARY = SERIES[0];\n\n\t registerTheme(\"bootstrap-v4\", {\n\t chart: { /* read from DOM */ },\n\t gauge: {\n\t pointer: {\n\t color: PRIMARY\n\t },\n\t scale: {\n\t rangePlaceholderColor: AXIS,\n\t labels: {\n\t color: TEXT\n\t },\n\t minorTicks: {\n\t color: TEXT\n\t },\n\t majorTicks: {\n\t color: TEXT\n\t },\n\t line: {\n\t color: TEXT\n\t }\n\t }\n\t },\n\t diagram: { /* read from DOM */ },\n\t treeMap: {\n\t colors: fuse(SERIES, SERIES_LIGHT)\n\t }\n\t });\n\t })();\n\n\t function fuse(arr1, arr2) {\n\t return $.map(arr1, function(item, index) {\n\t return [\n\t [item, arr2[index]]\n\t ];\n\t });\n\t }\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 919:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./chart-base-theme\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(920);\n\tmodule.exports = __webpack_require__(920);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 920:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(921) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\t \n\t var kendo = window.kendo;\n\t var drawing = kendo.drawing;\n\t var drawDOM = drawing.drawDOM;\n\n\t drawing.drawDOM = function(element, options) {\n\t return drawDOM($(element)[0], options);\n\t };\n\n\t drawing.drawDOM.drawText = drawDOM.drawText;\n\t drawing.drawDOM.getFontFaces = drawDOM.getFontFaces;\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 921:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo-drawing\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(922);\n\tmodule.exports = __webpack_require__(922);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 922:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/***********************************************************************\n\t * WARNING: this file is auto-generated. If you change it directly,\n\t * your modifications will eventually be lost. The source code is in\n\t * `kendo-drawing` repository, you should make your changes there and\n\t * run `src-modules/sync.sh` in this repository.\n\t */\n\t(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(923), __webpack_require__(924), __webpack_require__(925) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\t/* jshint eqnull:true */\n\t/* jshint -W069 */\n\t/* jshint latedef: nofunc */\n\n\twindow.kendo = window.kendo || {};\n\tvar kendoDrawing = kendo.drawing;\n\tvar kendoDrawingUtil = kendoDrawing.util;\n\tvar Class = kendo.Class;\n\tvar kendoUtil = kendo.util;\n\tvar support = kendo.support;\n\tvar supportBrowser = support.browser;\n\n\tvar createPromise = kendoDrawingUtil.createPromise;\n\tvar promiseAll = kendoDrawingUtil.promiseAll;\n\n\tvar ObserversMixin = {\n\t extend: function(proto) {\n\t var this$1 = this;\n\n\t for (var method in this) {\n\t if (method !== \"extend\") {\n\t proto[method] = this$1[method];\n\t }\n\t }\n\t },\n\n\t observers: function() {\n\t this._observers = this._observers || [];\n\t return this._observers;\n\t },\n\n\t addObserver: function(element) {\n\t if (!this._observers) {\n\t this._observers = [ element ];\n\t } else {\n\t this._observers.push(element);\n\t }\n\t return this;\n\t },\n\n\t removeObserver: function(element) {\n\t var observers = this.observers();\n\t var index = observers.indexOf(element);\n\t if (index !== -1) {\n\t observers.splice(index, 1);\n\t }\n\t return this;\n\t },\n\n\t trigger: function(methodName, event) {\n\t var observers = this._observers;\n\n\t if (observers && !this._suspended) {\n\t for (var idx = 0; idx < observers.length; idx++) {\n\t var observer = observers[idx];\n\t if (observer[methodName]) {\n\t observer[methodName](event);\n\t }\n\t }\n\t }\n\t return this;\n\t },\n\n\t optionsChange: function(e) {\n\t if (e === void 0) { e = {}; }\n\n\t e.element = this;\n\t this.trigger(\"optionsChange\", e);\n\t },\n\n\t geometryChange: function() {\n\t this.trigger(\"geometryChange\", {\n\t element: this\n\t });\n\t },\n\n\t suspend: function() {\n\t this._suspended = (this._suspended || 0) + 1;\n\t return this;\n\t },\n\n\t resume: function() {\n\t this._suspended = Math.max((this._suspended || 0) - 1, 0);\n\t return this;\n\t },\n\n\t _observerField: function(field, value) {\n\t if (this[field]) {\n\t this[field].removeObserver(this);\n\t }\n\t this[field] = value;\n\t value.addObserver(this);\n\t }\n\t};\n\n\tfunction append(first, second) {\n\t first.push.apply(first, second);\n\t return first;\n\t}\n\n\t/* eslint-disable key-spacing,no-multi-spaces,no-param-reassign */\n\n\tvar literals = {\n\t 1 : \"i\", 10 : \"x\", 100 : \"c\",\n\t 2 : \"ii\", 20 : \"xx\", 200 : \"cc\",\n\t 3 : \"iii\", 30 : \"xxx\", 300 : \"ccc\",\n\t 4 : \"iv\", 40 : \"xl\", 400 : \"cd\",\n\t 5 : \"v\", 50 : \"l\", 500 : \"d\",\n\t 6 : \"vi\", 60 : \"lx\", 600 : \"dc\",\n\t 7 : \"vii\", 70 : \"lxx\", 700 : \"dcc\",\n\t 8 : \"viii\", 80 : \"lxxx\", 800 : \"dccc\",\n\t 9 : \"ix\", 90 : \"xc\", 900 : \"cm\",\n\t 1000 : \"m\"\n\t};\n\n\tfunction arabicToRoman(n) {\n\t var values = [ 1000,\n\t 900 , 800, 700, 600, 500, 400, 300, 200, 100,\n\t 90 , 80 , 70 , 60 , 50 , 40 , 30 , 20 , 10 ,\n\t 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ];\n\n\t var roman = \"\";\n\t while (n > 0) {\n\t if (n < values[0]) {\n\t values.shift();\n\t } else {\n\t roman += literals[values[0]];\n\t n -= values[0];\n\t }\n\t }\n\t return roman;\n\t}\n\n\tvar UNDEFINED = \"undefined\";\n\n\tfunction defined(value) {\n\t return typeof value !== UNDEFINED;\n\t}\n\n\tvar defId = 1;\n\n\tfunction definitionId() {\n\t return \"kdef\" + defId++;\n\t}\n\n\tvar DEG_TO_RAD = Math.PI / 180;\n\tvar MAX_NUM = Number.MAX_VALUE;\n\tvar MIN_NUM = -Number.MAX_VALUE;\n\n\tfunction deg(radians) {\n\t return radians / DEG_TO_RAD;\n\t}\n\n\tvar KEY_STR = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n\tvar fromCharCode = String.fromCharCode;\n\n\tfunction encodeUTF8(input) {\n\t var output = \"\";\n\n\t for (var i = 0; i < input.length; i++) {\n\t var c = input.charCodeAt(i);\n\n\t if (c < 0x80) {\n\t // One byte\n\t output += fromCharCode(c);\n\t } else if (c < 0x800) {\n\t // Two bytes\n\t output += fromCharCode(0xC0 | (c >>> 6));\n\t output += fromCharCode(0x80 | (c & 0x3f));\n\t } else if (c < 0x10000) {\n\t // Three bytes\n\t output += fromCharCode(0xE0 | (c >>> 12));\n\t output += fromCharCode(0x80 | (c >>> 6 & 0x3f));\n\t output += fromCharCode(0x80 | (c & 0x3f));\n\t }\n\t }\n\n\t return output;\n\t}\n\n\tfunction encodeBase64(input) {\n\t var output = \"\";\n\t var i = 0;\n\n\t var utfInput = encodeUTF8(input);\n\n\t while (i < utfInput.length) {\n\t var chr1 = utfInput.charCodeAt(i++);\n\t var chr2 = utfInput.charCodeAt(i++);\n\t var chr3 = utfInput.charCodeAt(i++);\n\n\t var enc1 = chr1 >> 2;\n\t var enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n\t var enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n\t var enc4 = chr3 & 63;\n\n\t if (isNaN(chr2)) {\n\t enc3 = enc4 = 64;\n\t } else if (isNaN(chr3)) {\n\t enc4 = 64;\n\t }\n\n\t output = output +\n\t KEY_STR.charAt(enc1) + KEY_STR.charAt(enc2) +\n\t KEY_STR.charAt(enc3) + KEY_STR.charAt(enc4);\n\t }\n\n\t return output;\n\t}\n\n\tfunction eventCoordinates(e) {\n\t if (defined((e.x || {}).location)) {\n\t return {\n\t x: e.x.location,\n\t y: e.y.location\n\t };\n\t }\n\n\t return {\n\t x: e.pageX || e.clientX || 0,\n\t y: e.pageY || e.clientY || 0\n\t };\n\t}\n\n\tfunction eventElement(e) {\n\t if (e === void 0) { e = {}; }\n\n\t return e.touch ? e.touch.initialTouch : e.target;\n\t}\n\n\tfunction isTransparent(color) {\n\t return color === \"\" || color === null || color === \"none\" || color === \"transparent\" || !defined(color);\n\t}\n\n\tfunction last(array) {\n\t if (array) {\n\t return array[array.length - 1];\n\t }\n\t}\n\n\tfunction limitValue(value, min, max) {\n\t return Math.max(Math.min(value, max), min);\n\t}\n\n\t/* eslint-disable no-multi-spaces, key-spacing, indent, camelcase, space-before-blocks, eqeqeq, brace-style */\n\t/* eslint-disable space-infix-ops, space-before-function-paren, array-bracket-spacing, object-curly-spacing */\n\t/* eslint-disable no-nested-ternary, max-params, default-case, no-else-return, no-empty */\n\t/* eslint-disable no-param-reassign, no-var, block-scoped-var */\n\n\t// mergeSort is stable.\n\tfunction mergeSort(a, cmp) {\n\t if (a.length < 2) {\n\t return a.slice();\n\t }\n\t function merge(a, b) {\n\t var r = [], ai = 0, bi = 0, i = 0;\n\t while (ai < a.length && bi < b.length) {\n\t if (cmp(a[ai], b[bi]) <= 0) {\n\t r[i++] = a[ai++];\n\t } else {\n\t r[i++] = b[bi++];\n\t }\n\t }\n\t if (ai < a.length) {\n\t r.push.apply(r, a.slice(ai));\n\t }\n\t if (bi < b.length) {\n\t r.push.apply(r, b.slice(bi));\n\t }\n\t return r;\n\t }\n\t return (function sort(a) {\n\t if (a.length <= 1) {\n\t return a;\n\t }\n\t var m = Math.floor(a.length / 2);\n\t var left = a.slice(0, m);\n\t var right = a.slice(m);\n\t left = sort(left);\n\t right = sort(right);\n\t return merge(left, right);\n\t })(a);\n\t}\n\n\tfunction rad(degrees) {\n\t return degrees * DEG_TO_RAD;\n\t}\n\n\tfunction pow(p) {\n\t if (p) {\n\t return Math.pow(10, p);\n\t }\n\n\t return 1;\n\t}\n\n\tfunction round(value, precision) {\n\t var power = pow(precision);\n\t return Math.round(value * power) / power;\n\t}\n\n\tfunction valueOrDefault(value, defaultValue) {\n\t return defined(value) ? value : defaultValue;\n\t}\n\n\tfunction bindEvents(element, events) {\n\t for (var eventName in events) {\n\t var eventNames = eventName.trim().split(\" \");\n\t for (var idx = 0; idx < eventNames.length; idx++) {\n\t element.addEventListener(eventNames[idx], events[eventName], false);\n\t }\n\t }\n\t}\n\n\tfunction elementOffset(element) {\n\t var box = element.getBoundingClientRect();\n\n\t var documentElement = document.documentElement;\n\n\t return {\n\t top: box.top + (window.pageYOffset || documentElement.scrollTop) - (documentElement.clientTop || 0),\n\t left: box.left + (window.pageXOffset || documentElement.scrollLeft) - (documentElement.clientLeft || 0)\n\t };\n\t}\n\n\tfunction elementStyles(element, styles) {\n\t var result = {};\n\t var style = window.getComputedStyle(element) || {};\n\t var stylesArray = Array.isArray(styles) ? styles : [ styles ];\n\n\t for (var idx = 0; idx < stylesArray.length; idx++) {\n\t var field = stylesArray[idx];\n\t result[field] = style[field];\n\t }\n\n\t return result;\n\t}\n\n\tfunction getPixels(value) {\n\t if (isNaN(value)) {\n\t return value;\n\t }\n\t return value + \"px\";\n\t}\n\n\tfunction elementSize(element, size) {\n\t if (size) {\n\t var width = size.width;\n\t var height = size.height;\n\n\t if (defined(width)) {\n\t element.style.width = getPixels(width);\n\t }\n\n\t if (defined(height)) {\n\t element.style.height = getPixels(height);\n\t }\n\n\t } else {\n\t var size$1 = elementStyles(element, [ 'width', 'height' ]);\n\n\t return {\n\t width: parseInt(size$1.width, 10),\n\t height: parseInt(size$1.height, 10)\n\t };\n\t }\n\t}\n\n\tfunction unbindEvents(element, events) {\n\t if (events === void 0) { events = {}; }\n\n\t for (var name in events) {\n\t var eventNames = name.trim().split(\" \");\n\t for (var idx = 0; idx < eventNames.length; idx++) {\n\t element.removeEventListener(eventNames[idx], events[name], false);\n\t }\n\t }\n\t}\n\n\tvar util = {\n\t\tappend: append,\n\t\tarabicToRoman: arabicToRoman,\n\t\tcreatePromise: createPromise,\n\t\tdefined: defined,\n\t\tdefinitionId: definitionId,\n\t\tdeg: deg,\n\t\tencodeBase64: encodeBase64,\n\t\teventCoordinates: eventCoordinates,\n\t\teventElement: eventElement,\n\t\tisTransparent: isTransparent,\n\t\tlast: last,\n\t\tlimitValue: limitValue,\n\t\tmergeSort: mergeSort,\n\t\tpromiseAll: promiseAll,\n\t\trad: rad,\n\t\tround: round,\n\t\tvalueOrDefault: valueOrDefault,\n\t\tbindEvents: bindEvents,\n\t\telementOffset: elementOffset,\n\t\telementSize: elementSize,\n\t\telementStyles: elementStyles,\n\t\tunbindEvents: unbindEvents,\n\t\tDEG_TO_RAD: DEG_TO_RAD,\n\t\tMAX_NUM: MAX_NUM,\n\t\tMIN_NUM: MIN_NUM\n\t};\n\n\tvar toString = {}.toString;\n\n\tvar OptionsStore = Class.extend({\n\t init: function(options, prefix) {\n\t var this$1 = this;\n\t if (prefix === void 0) { prefix = \"\"; }\n\n\t this.prefix = prefix;\n\n\t for (var field in options) {\n\t var member = options[field];\n\t member = this$1._wrap(member, field);\n\t this$1[field] = member;\n\t }\n\t },\n\n\t get: function(field) {\n\t var parts = field.split(\".\");\n\t var result = this;\n\n\t while (parts.length && result) {\n\t var part = parts.shift();\n\t result = result[part];\n\t }\n\n\t return result;\n\t },\n\n\t set: function(field, value) {\n\t var current = this.get(field);\n\n\t if (current !== value) {\n\t this._set(field, this._wrap(value, field));\n\t this.optionsChange({\n\t field: this.prefix + field,\n\t value: value\n\t });\n\t }\n\t },\n\n\t _set: function(field, value) {\n\t var this$1 = this;\n\n\t var composite = field.indexOf(\".\") >= 0;\n\t var parentObj = this;\n\t var fieldName = field;\n\n\t if (composite) {\n\t var parts = fieldName.split(\".\");\n\t var prefix = this.prefix;\n\n\t while (parts.length > 1) {\n\t fieldName = parts.shift();\n\t prefix += fieldName + \".\";\n\n\t var obj = parentObj[fieldName];\n\n\t if (!obj) {\n\t obj = new OptionsStore({}, prefix);\n\t obj.addObserver(this$1);\n\t parentObj[fieldName] = obj;\n\t }\n\t parentObj = obj;\n\t }\n\t fieldName = parts[0];\n\t }\n\n\t parentObj._clear(fieldName);\n\t parentObj[fieldName] = value;\n\t },\n\n\t _clear: function(field) {\n\t var current = this[field];\n\t if (current && current.removeObserver) {\n\t current.removeObserver(this);\n\t }\n\t },\n\n\t _wrap: function(object, field) {\n\t var type = toString.call(object);\n\t var wrapped = object;\n\n\t if (wrapped !== null && defined(wrapped) && type === \"[object Object]\") {\n\t if (!(object instanceof OptionsStore) && !(object instanceof Class)) {\n\t wrapped = new OptionsStore(wrapped, this.prefix + field + \".\");\n\t }\n\n\t wrapped.addObserver(this);\n\t }\n\n\t return wrapped;\n\t }\n\t});\n\n\tObserversMixin.extend(OptionsStore.prototype);\n\n\tfunction setAccessor(field) {\n\t return function(value) {\n\t if (this[field] !== value) {\n\t this[field] = value;\n\t this.geometryChange();\n\t }\n\n\t return this;\n\t };\n\t}\n\n\tfunction getAccessor(field) {\n\t return function() {\n\t return this[field];\n\t };\n\t}\n\n\tfunction defineAccessors(fn, fields) {\n\t for (var i = 0; i < fields.length; i++) {\n\t var name = fields[i];\n\t var capitalized = name.charAt(0).toUpperCase() +\n\t name.substring(1, name.length);\n\n\t fn[\"set\" + capitalized] = setAccessor(name);\n\t fn[\"get\" + capitalized] = getAccessor(name);\n\t }\n\t}\n\n\tvar Matrix = Class.extend({\n\t init: function(a, b, c, d, e, f) {\n\t if (a === void 0) { a = 0; }\n\t if (b === void 0) { b = 0; }\n\t if (c === void 0) { c = 0; }\n\t if (d === void 0) { d = 0; }\n\t if (e === void 0) { e = 0; }\n\t if (f === void 0) { f = 0; }\n\n\t this.a = a;\n\t this.b = b;\n\t this.c = c;\n\t this.d = d;\n\t this.e = e;\n\t this.f = f;\n\t },\n\n\t multiplyCopy: function(matrix) {\n\t return new Matrix(\n\t this.a * matrix.a + this.c * matrix.b,\n\t this.b * matrix.a + this.d * matrix.b,\n\t this.a * matrix.c + this.c * matrix.d,\n\t this.b * matrix.c + this.d * matrix.d,\n\t this.a * matrix.e + this.c * matrix.f + this.e,\n\t this.b * matrix.e + this.d * matrix.f + this.f\n\t );\n\t },\n\n\t invert: function() {\n\t var ref = this;\n\t var a = ref.a;\n\t var b = ref.b;\n\t var d = ref.c;\n\t var e = ref.d;\n\t var g = ref.e;\n\t var h = ref.f;\n\t var det = a * e - b * d;\n\n\t if (det === 0) {\n\t return null;\n\t }\n\n\t return new Matrix(e / det, -b / det, -d / det, a / det,\n\t (d * h - e * g) / det, (b * g - a * h) / det);\n\t },\n\n\t clone: function() {\n\t return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);\n\t },\n\n\t equals: function(other) {\n\t if (!other) {\n\t return false;\n\t }\n\n\t return this.a === other.a && this.b === other.b &&\n\t this.c === other.c && this.d === other.d &&\n\t this.e === other.e && this.f === other.f;\n\t },\n\n\t round: function(precision) {\n\t this.a = round(this.a, precision);\n\t this.b = round(this.b, precision);\n\t this.c = round(this.c, precision);\n\t this.d = round(this.d, precision);\n\t this.e = round(this.e, precision);\n\t this.f = round(this.f, precision);\n\n\t return this;\n\t },\n\n\t toArray: function(precision) {\n\t var result = [ this.a, this.b, this.c, this.d, this.e, this.f ];\n\n\t if (defined(precision)) {\n\t for (var i = 0; i < result.length; i++) {\n\t result[i] = round(result[i], precision);\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t toString: function(precision, separator) {\n\t if (separator === void 0) { separator = \",\"; }\n\n\t return this.toArray(precision).join(separator);\n\t }\n\t});\n\n\tMatrix.translate = function(x, y) {\n\t return new Matrix(1, 0, 0, 1, x, y);\n\t};\n\n\tMatrix.unit = function() {\n\t return new Matrix(1, 0, 0, 1, 0, 0);\n\t};\n\n\tMatrix.rotate = function(angle, x, y) {\n\t var matrix = new Matrix();\n\t matrix.a = Math.cos(rad(angle));\n\t matrix.b = Math.sin(rad(angle));\n\t matrix.c = -matrix.b;\n\t matrix.d = matrix.a;\n\t matrix.e = (x - x * matrix.a + y * matrix.b) || 0;\n\t matrix.f = (y - y * matrix.a - x * matrix.b) || 0;\n\n\t return matrix;\n\t};\n\n\tMatrix.scale = function(scaleX, scaleY) {\n\t return new Matrix(scaleX, 0, 0, scaleY, 0, 0);\n\t};\n\n\tMatrix.IDENTITY = Matrix.unit();\n\n\tfunction toMatrix(transformation) {\n\t if (transformation && typeof transformation.matrix === \"function\") {\n\t return transformation.matrix();\n\t }\n\n\t return transformation;\n\t}\n\n\tvar Point = Class.extend({\n\t init: function(x, y) {\n\n\t this.x = x || 0;\n\t this.y = y || 0;\n\t },\n\n\t equals: function(other) {\n\t return other && other.x === this.x && other.y === this.y;\n\t },\n\n\t clone: function() {\n\t return new Point(this.x, this.y);\n\t },\n\n\t rotate: function(angle, origin) {\n\t var originPoint = Point.create(origin) || Point.ZERO;\n\n\t return this.transform(Matrix.rotate(angle, originPoint.x, originPoint.y));\n\t },\n\n\t translate: function(x, y) {\n\t this.x += x;\n\t this.y += y;\n\n\t this.geometryChange();\n\n\t return this;\n\t },\n\n\t translateWith: function(point) {\n\t return this.translate(point.x, point.y);\n\t },\n\n\t move: function(x, y) {\n\t this.x = this.y = 0;\n\t return this.translate(x, y);\n\t },\n\n\t scale: function(scaleX, scaleY) {\n\t if (scaleY === void 0) { scaleY = scaleX; }\n\n\t this.x *= scaleX;\n\t this.y *= scaleY;\n\n\t this.geometryChange();\n\n\t return this;\n\t },\n\n\t scaleCopy: function(scaleX, scaleY) {\n\t return this.clone().scale(scaleX, scaleY);\n\t },\n\n\t transform: function(transformation) {\n\t var matrix = toMatrix(transformation);\n\t var ref = this;\n\t var x = ref.x;\n\t var y = ref.y;\n\n\t this.x = matrix.a * x + matrix.c * y + matrix.e;\n\t this.y = matrix.b * x + matrix.d * y + matrix.f;\n\n\t this.geometryChange();\n\n\t return this;\n\t },\n\n\t transformCopy: function(transformation) {\n\t var point = this.clone();\n\n\t if (transformation) {\n\t point.transform(transformation);\n\t }\n\n\t return point;\n\t },\n\n\t distanceTo: function(point) {\n\t var dx = this.x - point.x;\n\t var dy = this.y - point.y;\n\n\t return Math.sqrt(dx * dx + dy * dy);\n\t },\n\n\t round: function(digits) {\n\t this.x = round(this.x, digits);\n\t this.y = round(this.y, digits);\n\n\t this.geometryChange();\n\n\t return this;\n\t },\n\n\t toArray: function(digits) {\n\t var doRound = defined(digits);\n\t var x = doRound ? round(this.x, digits) : this.x;\n\t var y = doRound ? round(this.y, digits) : this.y;\n\n\t return [ x, y ];\n\t },\n\n\t toString: function(digits, separator) {\n\t if (separator === void 0) { separator = \" \"; }\n\n\t var ref = this;\n\t var x = ref.x;\n\t var y = ref.y;\n\n\t if (defined(digits)) {\n\t x = round(x, digits);\n\t y = round(y, digits);\n\t }\n\n\t return x + separator + y;\n\t }\n\t});\n\n\tPoint.create = function(arg0, arg1) {\n\t if (defined(arg0)) {\n\t if (arg0 instanceof Point) {\n\t return arg0;\n\t } else if (arguments.length === 1 && arg0.length === 2) {\n\t return new Point(arg0[0], arg0[1]);\n\t }\n\n\t return new Point(arg0, arg1);\n\t }\n\t};\n\n\tPoint.min = function() {\n\t var arguments$1 = arguments;\n\n\t var minX = MAX_NUM;\n\t var minY = MAX_NUM;\n\n\t for (var i = 0; i < arguments.length; i++) {\n\t var point = arguments$1[i];\n\t minX = Math.min(point.x, minX);\n\t minY = Math.min(point.y, minY);\n\t }\n\n\t return new Point(minX, minY);\n\t};\n\n\tPoint.max = function() {\n\t var arguments$1 = arguments;\n\n\t var maxX = MIN_NUM;\n\t var maxY = MIN_NUM;\n\n\t for (var i = 0; i < arguments.length; i++) {\n\t var point = arguments$1[i];\n\t maxX = Math.max(point.x, maxX);\n\t maxY = Math.max(point.y, maxY);\n\t }\n\n\t return new Point(maxX, maxY);\n\t};\n\n\tPoint.minPoint = function() {\n\t return new Point(MIN_NUM, MIN_NUM);\n\t};\n\n\tPoint.maxPoint = function() {\n\t return new Point(MAX_NUM, MAX_NUM);\n\t};\n\n\tif (Object.defineProperties) {\n\t Object.defineProperties(Point, {\n\t ZERO: {\n\t get: function() {\n\t return new Point(0, 0);\n\t }\n\t }\n\t });\n\t}\n\n\tdefineAccessors(Point.prototype, [ \"x\", \"y\" ]);\n\tObserversMixin.extend(Point.prototype);\n\n\tvar Size = Class.extend({\n\t init: function(width, height) {\n\n\t this.width = width || 0;\n\t this.height = height || 0;\n\t },\n\n\t equals: function(other) {\n\t return other && other.width === this.width && other.height === this.height;\n\t },\n\n\t clone: function() {\n\t return new Size(this.width, this.height);\n\t },\n\n\t toArray: function(digits) {\n\t var doRound = defined(digits);\n\t var width = doRound ? round(this.width, digits) : this.width;\n\t var height = doRound ? round(this.height, digits) : this.height;\n\n\t return [ width, height ];\n\t }\n\t});\n\n\tSize.create = function(arg0, arg1) {\n\t if (defined(arg0)) {\n\t if (arg0 instanceof Size) {\n\t return arg0;\n\t } else if (arguments.length === 1 && arg0.length === 2) {\n\t return new Size(arg0[0], arg0[1]);\n\t }\n\n\t return new Size(arg0, arg1);\n\t }\n\t};\n\n\tif (Object.defineProperties) {\n\t Object.defineProperties(Size, {\n\t ZERO: {\n\t get: function() {\n\t return new Size(0, 0);\n\t }\n\t }\n\t });\n\t}\n\n\tdefineAccessors(Size.prototype, [ \"width\", \"height\" ]);\n\tObserversMixin.extend(Size.prototype);\n\n\tvar Rect = Class.extend({\n\t init: function(origin, size) {\n\t if (origin === void 0) { origin = new Point(); }\n\t if (size === void 0) { size = new Size(); }\n\n\t this.setOrigin(origin);\n\t this.setSize(size);\n\t },\n\n\t clone: function() {\n\t return new Rect(\n\t this.origin.clone(),\n\t this.size.clone()\n\t );\n\t },\n\n\t equals: function(other) {\n\t return other &&\n\t other.origin.equals(this.origin) &&\n\t other.size.equals(this.size);\n\t },\n\n\t setOrigin: function(value) {\n\t this._observerField(\"origin\", Point.create(value));\n\t this.geometryChange();\n\t return this;\n\t },\n\n\t getOrigin: function() {\n\t return this.origin;\n\t },\n\n\t setSize: function(value) {\n\t this._observerField(\"size\", Size.create(value));\n\t this.geometryChange();\n\t return this;\n\t },\n\n\t getSize: function() {\n\t return this.size;\n\t },\n\n\t width: function() {\n\t return this.size.width;\n\t },\n\n\t height: function() {\n\t return this.size.height;\n\t },\n\n\t topLeft: function() {\n\t return this.origin.clone();\n\t },\n\n\t bottomRight: function() {\n\t return this.origin.clone().translate(this.width(), this.height());\n\t },\n\n\t topRight: function() {\n\t return this.origin.clone().translate(this.width(), 0);\n\t },\n\n\t bottomLeft: function() {\n\t return this.origin.clone().translate(0, this.height());\n\t },\n\n\t center: function() {\n\t return this.origin.clone().translate(this.width() / 2, this.height() / 2);\n\t },\n\n\t bbox: function(matrix) {\n\t var tl = this.topLeft().transformCopy(matrix);\n\t var tr = this.topRight().transformCopy(matrix);\n\t var br = this.bottomRight().transformCopy(matrix);\n\t var bl = this.bottomLeft().transformCopy(matrix);\n\n\t return Rect.fromPoints(tl, tr, br, bl);\n\t },\n\n\t transformCopy: function(m) {\n\t return Rect.fromPoints(\n\t this.topLeft().transform(m),\n\t this.bottomRight().transform(m)\n\t );\n\t },\n\n\t expand: function(x, y) {\n\t if (y === void 0) { y = x; }\n\n\t this.size.width += 2 * x;\n\t this.size.height += 2 * y;\n\n\t this.origin.translate(-x, -y);\n\n\t return this;\n\t },\n\n\t expandCopy: function(x, y) {\n\t return this.clone().expand(x, y);\n\t },\n\n\t containsPoint: function(point) {\n\t var origin = this.origin;\n\t var bottomRight = this.bottomRight();\n\t return !(point.x < origin.x || point.y < origin.y || bottomRight.x < point.x || bottomRight.y < point.y);\n\t },\n\n\t _isOnPath: function(point, width) {\n\t var rectOuter = this.expandCopy(width, width);\n\t var rectInner = this.expandCopy(-width, -width);\n\n\t return rectOuter.containsPoint(point) && !rectInner.containsPoint(point);\n\t }\n\t});\n\n\tRect.fromPoints = function() {\n\t var topLeft = Point.min.apply(null, arguments);\n\t var bottomRight = Point.max.apply(null, arguments);\n\t var size = new Size(\n\t bottomRight.x - topLeft.x,\n\t bottomRight.y - topLeft.y\n\t );\n\n\t return new Rect(topLeft, size);\n\t};\n\n\tRect.union = function(a, b) {\n\t return Rect.fromPoints(\n\t Point.min(a.topLeft(), b.topLeft()),\n\t Point.max(a.bottomRight(), b.bottomRight())\n\t );\n\t};\n\n\tRect.intersect = function(a, b) {\n\t var rect1 = {\n\t left: a.topLeft().x,\n\t top: a.topLeft().y,\n\t right: a.bottomRight().x,\n\t bottom: a.bottomRight().y\n\t };\n\n\t var rect2 = {\n\t left: b.topLeft().x,\n\t top: b.topLeft().y,\n\t right: b.bottomRight().x,\n\t bottom: b.bottomRight().y\n\t };\n\n\t if (rect1.left <= rect2.right &&\n\t rect2.left <= rect1.right &&\n\t rect1.top <= rect2.bottom &&\n\t rect2.top <= rect1.bottom) {\n\t return Rect.fromPoints(\n\t new Point(Math.max(rect1.left, rect2.left), Math.max(rect1.top, rect2.top)),\n\t new Point(Math.min(rect1.right, rect2.right), Math.min(rect1.bottom, rect2.bottom))\n\t );\n\t }\n\t};\n\n\tObserversMixin.extend(Rect.prototype);\n\n\tvar Transformation = Class.extend({\n\t init: function(matrix) {\n\t if (matrix === void 0) { matrix = Matrix.unit(); }\n\n\t this._matrix = matrix;\n\t },\n\n\t clone: function() {\n\t return new Transformation(\n\t this._matrix.clone()\n\t );\n\t },\n\n\t equals: function(other) {\n\t return other &&\n\t other._matrix.equals(this._matrix);\n\t },\n\n\t translate: function(x, y) {\n\t this._matrix = this._matrix.multiplyCopy(Matrix.translate(x, y));\n\n\t this._optionsChange();\n\t return this;\n\t },\n\n\t scale: function(scaleX, scaleY, origin) {\n\t if (scaleY === void 0) { scaleY = scaleX; }\n\t if (origin === void 0) { origin = null; }\n\n\t var originPoint = origin;\n\n\t if (originPoint) {\n\t originPoint = Point.create(originPoint);\n\t this._matrix = this._matrix.multiplyCopy(Matrix.translate(originPoint.x, originPoint.y));\n\t }\n\n\t this._matrix = this._matrix.multiplyCopy(Matrix.scale(scaleX, scaleY));\n\n\t if (originPoint) {\n\t this._matrix = this._matrix.multiplyCopy(Matrix.translate(-originPoint.x, -originPoint.y));\n\t }\n\n\t this._optionsChange();\n\t return this;\n\t },\n\n\t rotate: function(angle, origin) {\n\t var originPoint = Point.create(origin) || Point.ZERO;\n\n\t this._matrix = this._matrix.multiplyCopy(Matrix.rotate(angle, originPoint.x, originPoint.y));\n\n\t this._optionsChange();\n\t return this;\n\t },\n\n\t multiply: function(transformation) {\n\t var matrix = toMatrix(transformation);\n\n\t this._matrix = this._matrix.multiplyCopy(matrix);\n\n\t this._optionsChange();\n\t return this;\n\t },\n\n\t matrix: function(value) {\n\t if (value) {\n\t this._matrix = value;\n\t this._optionsChange();\n\t return this;\n\t }\n\n\t return this._matrix;\n\t },\n\n\t _optionsChange: function() {\n\t this.optionsChange({\n\t field: \"transform\",\n\t value: this\n\t });\n\t }\n\t});\n\n\tObserversMixin.extend(Transformation.prototype);\n\n\tfunction transform(matrix) {\n\t if (matrix === null) {\n\t return null;\n\t }\n\n\t if (matrix instanceof Transformation) {\n\t return matrix;\n\t }\n\n\t return new Transformation(matrix);\n\t}\n\n\tvar Element$1 = Class.extend({\n\t init: function(options) {\n\n\t this._initOptions(options);\n\t },\n\n\t _initOptions: function(options) {\n\t if (options === void 0) { options = {}; }\n\n\t var clip = options.clip;\n\t var transform$$1 = options.transform;\n\n\t if (transform$$1) {\n\t options.transform = transform(transform$$1);\n\t }\n\n\t if (clip && !clip.id) {\n\t clip.id = definitionId();\n\t }\n\n\t this.options = new OptionsStore(options);\n\t this.options.addObserver(this);\n\t },\n\n\t transform: function(value) {\n\t if (defined(value)) {\n\t this.options.set(\"transform\", transform(value));\n\t } else {\n\t return this.options.get(\"transform\");\n\t }\n\t },\n\n\t parentTransform: function() {\n\t var element = this;\n\t var parentMatrix;\n\n\t while (element.parent) {\n\t element = element.parent;\n\t var transformation = element.transform();\n\t if (transformation) {\n\t parentMatrix = transformation.matrix().multiplyCopy(parentMatrix || Matrix.unit());\n\t }\n\t }\n\n\t if (parentMatrix) {\n\t return transform(parentMatrix);\n\t }\n\t },\n\n\t currentTransform: function(parentTransform) {\n\t if (parentTransform === void 0) { parentTransform = this.parentTransform(); }\n\n\t var elementTransform = this.transform();\n\t var elementMatrix = toMatrix(elementTransform);\n\n\t var parentMatrix = toMatrix(parentTransform);\n\t var combinedMatrix;\n\n\t if (elementMatrix && parentMatrix) {\n\t combinedMatrix = parentMatrix.multiplyCopy(elementMatrix);\n\t } else {\n\t combinedMatrix = elementMatrix || parentMatrix;\n\t }\n\n\t if (combinedMatrix) {\n\t return transform(combinedMatrix);\n\t }\n\t },\n\n\t visible: function(value) {\n\t if (defined(value)) {\n\t this.options.set(\"visible\", value);\n\t return this;\n\t }\n\n\t return this.options.get(\"visible\") !== false;\n\t },\n\n\t clip: function(value) {\n\t var options = this.options;\n\t if (defined(value)) {\n\t if (value && !value.id) {\n\t value.id = definitionId();\n\t }\n\t options.set(\"clip\", value);\n\t return this;\n\t }\n\n\t return options.get(\"clip\");\n\t },\n\n\t opacity: function(value) {\n\t if (defined(value)) {\n\t this.options.set(\"opacity\", value);\n\t return this;\n\t }\n\n\t return valueOrDefault(this.options.get(\"opacity\"), 1);\n\t },\n\n\t clippedBBox: function(transformation) {\n\t var bbox = this._clippedBBox(transformation);\n\t if (bbox) {\n\t var clip = this.clip();\n\t return clip ? Rect.intersect(bbox, clip.bbox(transformation)) : bbox;\n\t }\n\t },\n\n\t containsPoint: function(point, parentTransform) {\n\t if (this.visible()) {\n\t var transform$$1 = this.currentTransform(parentTransform);\n\t var transformedPoint = point;\n\t if (transform$$1) {\n\t transformedPoint = point.transformCopy(transform$$1.matrix().invert());\n\t }\n\t return (this._hasFill() && this._containsPoint(transformedPoint)) || (this._isOnPath && this._hasStroke() && this._isOnPath(transformedPoint));\n\t }\n\t return false;\n\t },\n\n\t _hasFill: function() {\n\t var fill = this.options.fill;\n\t return fill && !isTransparent(fill.color);\n\t },\n\n\t _hasStroke: function() {\n\t var stroke = this.options.stroke;\n\t return stroke && stroke.width > 0 && !isTransparent(stroke.color);\n\t },\n\n\t _clippedBBox: function(transformation) {\n\t return this.bbox(transformation);\n\t }\n\t});\n\n\tElement$1.prototype.nodeType = \"Element\";\n\n\tObserversMixin.extend(Element$1.prototype);\n\n\tfunction ellipseExtremeAngles(center, rx, ry, matrix) {\n\t var extremeX = 0;\n\t var extremeY = 0;\n\n\t if (matrix) {\n\t extremeX = Math.atan2(matrix.c * ry, matrix.a * rx);\n\t if (matrix.b !== 0) {\n\t extremeY = Math.atan2(matrix.d * ry, matrix.b * rx);\n\t }\n\t }\n\n\t return {\n\t x: extremeX,\n\t y: extremeY\n\t };\n\t}\n\n\tvar PI_DIV_2 = Math.PI / 2;\n\n\tvar Circle$2 = Class.extend({\n\t init: function(center, radius) {\n\t if (center === void 0) { center = new Point(); }\n\t if (radius === void 0) { radius = 0; }\n\n\t this.setCenter(center);\n\t this.setRadius(radius);\n\t },\n\n\t setCenter: function(value) {\n\t this._observerField(\"center\", Point.create(value));\n\t this.geometryChange();\n\t return this;\n\t },\n\n\t getCenter: function() {\n\t return this.center;\n\t },\n\n\t equals: function(other) {\n\t return other &&\n\t other.center.equals(this.center) &&\n\t other.radius === this.radius;\n\t },\n\n\t clone: function() {\n\t return new Circle$2(this.center.clone(), this.radius);\n\t },\n\n\t pointAt: function(angle) {\n\t return this._pointAt(rad(angle));\n\t },\n\n\t bbox: function(matrix) {\n\t var this$1 = this;\n\n\t var extremeAngles = ellipseExtremeAngles(this.center, this.radius, this.radius, matrix);\n\t var minPoint = Point.maxPoint();\n\t var maxPoint = Point.minPoint();\n\n\t for (var i = 0; i < 4; i++) {\n\t var currentPointX = this$1._pointAt(extremeAngles.x + i * PI_DIV_2).transformCopy(matrix);\n\t var currentPointY = this$1._pointAt(extremeAngles.y + i * PI_DIV_2).transformCopy(matrix);\n\t var currentPoint = new Point(currentPointX.x, currentPointY.y);\n\n\t minPoint = Point.min(minPoint, currentPoint);\n\t maxPoint = Point.max(maxPoint, currentPoint);\n\t }\n\n\t return Rect.fromPoints(minPoint, maxPoint);\n\t },\n\n\t _pointAt: function(angle) {\n\t var ref = this;\n\t var center = ref.center;\n\t var radius = ref.radius;\n\n\t return new Point(\n\t center.x + radius * Math.cos(angle),\n\t center.y + radius * Math.sin(angle)\n\t );\n\t },\n\n\t containsPoint: function(point) {\n\t var ref = this;\n\t var center = ref.center;\n\t var radius = ref.radius;\n\t var inCircle = Math.pow(point.x - center.x, 2) +\n\t Math.pow(point.y - center.y, 2) <= Math.pow(radius, 2);\n\t return inCircle;\n\t },\n\n\t _isOnPath: function(point, width) {\n\t var ref = this;\n\t var center = ref.center;\n\t var radius = ref.radius;\n\t var pointDistance = center.distanceTo(point);\n\n\t return radius - width <= pointDistance && pointDistance <= radius + width;\n\t }\n\t});\n\n\tdefineAccessors(Circle$2.prototype, [ \"radius\" ]);\n\tObserversMixin.extend(Circle$2.prototype);\n\n\tvar GRADIENT = \"Gradient\";\n\n\tvar Paintable = {\n\t extend: function(proto) {\n\t proto.fill = this.fill;\n\t proto.stroke = this.stroke;\n\t },\n\n\t fill: function(color, opacity) {\n\t var options = this.options;\n\n\t if (defined(color)) {\n\t if (color && color.nodeType !== GRADIENT) {\n\t var newFill = {\n\t color: color\n\t };\n\t if (defined(opacity)) {\n\t newFill.opacity = opacity;\n\t }\n\t options.set(\"fill\", newFill);\n\t } else {\n\t options.set(\"fill\", color);\n\t }\n\n\t return this;\n\t }\n\n\t return options.get(\"fill\");\n\t },\n\n\t stroke: function(color, width, opacity) {\n\t if (defined(color)) {\n\t this.options.set(\"stroke.color\", color);\n\n\t if (defined(width)) {\n\t this.options.set(\"stroke.width\", width);\n\t }\n\n\t if (defined(opacity)) {\n\t this.options.set(\"stroke.opacity\", opacity);\n\t }\n\n\t return this;\n\t }\n\n\t return this.options.get(\"stroke\");\n\t }\n\t};\n\n\tvar IDENTITY_MATRIX_HASH = Matrix.IDENTITY.toString();\n\n\tvar Measurable = {\n\t extend: function(proto) {\n\t proto.bbox = this.bbox;\n\t proto.geometryChange = this.geometryChange;\n\t },\n\n\t bbox: function(transformation) {\n\t var combinedMatrix = toMatrix(this.currentTransform(transformation));\n\t var matrixHash = combinedMatrix ? combinedMatrix.toString() : IDENTITY_MATRIX_HASH;\n\t var bbox;\n\n\t if (this._bboxCache && this._matrixHash === matrixHash) {\n\t bbox = this._bboxCache.clone();\n\t } else {\n\t bbox = this._bbox(combinedMatrix);\n\t this._bboxCache = bbox ? bbox.clone() : null;\n\t this._matrixHash = matrixHash;\n\t }\n\n\t var strokeWidth = this.options.get(\"stroke.width\");\n\t if (strokeWidth && bbox) {\n\t bbox.expand(strokeWidth / 2);\n\t }\n\n\t return bbox;\n\t },\n\n\t geometryChange: function() {\n\t delete this._bboxCache;\n\t this.trigger(\"geometryChange\", {\n\t element: this\n\t });\n\t }\n\t};\n\n\tfunction geometryAccessor(name) {\n\t var fieldName = \"_\" + name;\n\t return function(value) {\n\t if (defined(value)) {\n\t this._observerField(fieldName, value);\n\t this.geometryChange();\n\t return this;\n\t }\n\n\t return this[fieldName];\n\t };\n\t}\n\n\tfunction defineGeometryAccessors(fn, names) {\n\t for (var i = 0; i < names.length; i++) {\n\t fn[names[i]] = geometryAccessor(names[i]);\n\t }\n\t}\n\n\tvar DEFAULT_STROKE = \"#000\";\n\n\tvar Circle = Element$1.extend({\n\t init: function(geometry, options) {\n\t if (geometry === void 0) { geometry = new Circle$2(); }\n\t if (options === void 0) { options = {}; }\n\n\t Element$1.fn.init.call(this, options);\n\t this.geometry(geometry);\n\n\t if (!defined(this.options.stroke)) {\n\t this.stroke(DEFAULT_STROKE);\n\t }\n\t },\n\n\t rawBBox: function() {\n\t return this._geometry.bbox();\n\t },\n\n\t _bbox: function(matrix) {\n\t return this._geometry.bbox(matrix);\n\t },\n\n\t _containsPoint: function(point) {\n\t return this.geometry().containsPoint(point);\n\t },\n\n\t _isOnPath: function(point) {\n\t return this.geometry()._isOnPath(point, this.options.stroke.width / 2);\n\t }\n\t});\n\n\tCircle.prototype.nodeType = \"Circle\";\n\n\tPaintable.extend(Circle.prototype);\n\tMeasurable.extend(Circle.prototype);\n\tdefineGeometryAccessors(Circle.prototype, [ \"geometry\" ]);\n\n\tvar PRECISION = 10;\n\n\tfunction close(a, b, tolerance) {\n\t if (tolerance === void 0) { tolerance = PRECISION; }\n\n\t return round(Math.abs(a - b), tolerance) === 0;\n\t}\n\n\tfunction closeOrLess(a, b, tolerance) {\n\t return a < b || close(a, b, tolerance);\n\t}\n\n\tfunction lineIntersection(p0, p1, p2, p3) {\n\t var s1x = p1.x - p0.x;\n\t var s2x = p3.x - p2.x;\n\t var s1y = p1.y - p0.y;\n\t var s2y = p3.y - p2.y;\n\t var nx = p0.x - p2.x;\n\t var ny = p0.y - p2.y;\n\t var d = s1x * s2y - s2x * s1y;\n\t var s = (s1x * ny - s1y * nx) / d;\n\t var t = (s2x * ny - s2y * nx) / d;\n\n\t if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {\n\t return new Point(p0.x + t * s1x, p0.y + t * s1y);\n\t }\n\t}\n\n\tvar MAX_INTERVAL = 45;\n\tvar pow$1 = Math.pow;\n\n\tvar Arc$2 = Class.extend({\n\t init: function(center, options) {\n\t if (center === void 0) { center = new Point(); }\n\t if (options === void 0) { options = {}; }\n\n\t this.setCenter(center);\n\n\t this.radiusX = options.radiusX;\n\t this.radiusY = options.radiusY || options.radiusX;\n\t this.startAngle = options.startAngle;\n\t this.endAngle = options.endAngle;\n\t this.anticlockwise = options.anticlockwise || false;\n\t this.xRotation = options.xRotation;\n\t },\n\n\t clone: function() {\n\t return new Arc$2(this.center, {\n\t radiusX: this.radiusX,\n\t radiusY: this.radiusY,\n\t startAngle: this.startAngle,\n\t endAngle: this.endAngle,\n\t anticlockwise: this.anticlockwise\n\t });\n\t },\n\n\t setCenter: function(value) {\n\t this._observerField(\"center\", Point.create(value));\n\t this.geometryChange();\n\t return this;\n\t },\n\n\t getCenter: function() {\n\t return this.center;\n\t },\n\n\t pointAt: function(angle) {\n\t var center = this.center;\n\t var radian = rad(angle);\n\n\t return new Point(\n\t center.x + this.radiusX * Math.cos(radian),\n\t center.y + this.radiusY * Math.sin(radian)\n\t );\n\t },\n\n\t curvePoints: function() {\n\t var this$1 = this;\n\n\t var startAngle = this.startAngle;\n\t var dir = this.anticlockwise ? -1 : 1;\n\t var curvePoints = [ this.pointAt(startAngle) ];\n\t var interval = this._arcInterval();\n\t var intervalAngle = interval.endAngle - interval.startAngle;\n\t var subIntervalsCount = Math.ceil(intervalAngle / MAX_INTERVAL);\n\t var subIntervalAngle = intervalAngle / subIntervalsCount;\n\t var currentAngle = startAngle;\n\t var transformation;\n\t if (this.xRotation) {\n\t transformation = transform().rotate(this.xRotation, this.center);\n\t }\n\n\t for (var i = 1; i <= subIntervalsCount; i++) {\n\t var nextAngle = currentAngle + dir * subIntervalAngle;\n\t var points = this$1._intervalCurvePoints(currentAngle, nextAngle, transformation);\n\n\t curvePoints.push(points.cp1, points.cp2, points.p2);\n\t currentAngle = nextAngle;\n\t }\n\n\t return curvePoints;\n\t },\n\n\t bbox: function(matrix) {\n\t var this$1 = this;\n\n\t var interval = this._arcInterval();\n\t var startAngle = interval.startAngle;\n\t var endAngle = interval.endAngle;\n\t var extremeAngles = ellipseExtremeAngles(this.center, this.radiusX, this.radiusY, matrix);\n\t var extremeX = deg(extremeAngles.x);\n\t var extremeY = deg(extremeAngles.y);\n\t var endPoint = this.pointAt(endAngle).transformCopy(matrix);\n\t var currentAngleX = bboxStartAngle(extremeX, startAngle);\n\t var currentAngleY = bboxStartAngle(extremeY, startAngle);\n\t var currentPoint = this.pointAt(startAngle).transformCopy(matrix);\n\t var minPoint = Point.min(currentPoint, endPoint);\n\t var maxPoint = Point.max(currentPoint, endPoint);\n\n\t while (currentAngleX < endAngle || currentAngleY < endAngle) {\n\t var currentPointX = (void 0);\n\t if (currentAngleX < endAngle) {\n\t currentPointX = this$1.pointAt(currentAngleX).transformCopy(matrix);\n\t currentAngleX += 90;\n\t }\n\n\t var currentPointY = (void 0);\n\t if (currentAngleY < endAngle) {\n\t currentPointY = this$1.pointAt(currentAngleY).transformCopy(matrix);\n\t currentAngleY += 90;\n\t }\n\n\t currentPoint = new Point(currentPointX.x, currentPointY.y);\n\t minPoint = Point.min(minPoint, currentPoint);\n\t maxPoint = Point.max(maxPoint, currentPoint);\n\t }\n\n\t return Rect.fromPoints(minPoint, maxPoint);\n\t },\n\n\t _arcInterval: function() {\n\t var ref = this;\n\t var startAngle = ref.startAngle;\n\t var endAngle = ref.endAngle;\n\t var anticlockwise = ref.anticlockwise;\n\n\t if (anticlockwise) {\n\t var oldStart = startAngle;\n\t startAngle = endAngle;\n\t endAngle = oldStart;\n\t }\n\n\t if (startAngle > endAngle || (anticlockwise && startAngle === endAngle)) {\n\t endAngle += 360;\n\t }\n\n\t return {\n\t startAngle: startAngle,\n\t endAngle: endAngle\n\t };\n\t },\n\n\t _intervalCurvePoints: function(startAngle, endAngle, transformation) {\n\t var p1 = this.pointAt(startAngle);\n\t var p2 = this.pointAt(endAngle);\n\t var p1Derivative = this._derivativeAt(startAngle);\n\t var p2Derivative = this._derivativeAt(endAngle);\n\t var t = (rad(endAngle) - rad(startAngle)) / 3;\n\t var cp1 = new Point(p1.x + t * p1Derivative.x, p1.y + t * p1Derivative.y);\n\t var cp2 = new Point(p2.x - t * p2Derivative.x, p2.y - t * p2Derivative.y);\n\t if (transformation) {\n\t p1.transform(transformation);\n\t p2.transform(transformation);\n\t cp1.transform(transformation);\n\t cp2.transform(transformation);\n\t }\n\n\t return {\n\t p1: p1,\n\t cp1: cp1,\n\t cp2: cp2,\n\t p2: p2\n\t };\n\t },\n\n\t _derivativeAt: function(angle) {\n\t var radian = rad(angle);\n\n\t return new Point(-this.radiusX * Math.sin(radian), this.radiusY * Math.cos(radian));\n\t },\n\n\t containsPoint: function(point) {\n\t var interval = this._arcInterval();\n\t var intervalAngle = interval.endAngle - interval.startAngle;\n\t var ref = this;\n\t var center = ref.center;\n\t var radiusX = ref.radiusX;\n\t var radiusY = ref.radiusY;\n\t var distance = center.distanceTo(point);\n\t var angleRad = Math.atan2(point.y - center.y, point.x - center.x);\n\t var pointRadius = (radiusX * radiusY) /\n\t Math.sqrt(pow$1(radiusX, 2) * pow$1(Math.sin(angleRad), 2) + pow$1(radiusY, 2) * pow$1(Math.cos(angleRad), 2));\n\t var startPoint = this.pointAt(this.startAngle).round(PRECISION);\n\t var endPoint = this.pointAt(this.endAngle).round(PRECISION);\n\t var intersection = lineIntersection(center, point.round(PRECISION), startPoint, endPoint);\n\t var containsPoint;\n\n\t if (intervalAngle < 180) {\n\t containsPoint = intersection && closeOrLess(center.distanceTo(intersection), distance) && closeOrLess(distance, pointRadius);\n\t } else {\n\t var angle = calculateAngle(center.x, center.y, radiusX, radiusY, point.x, point.y);\n\t if (angle !== 360) {\n\t angle = (360 + angle) % 360;\n\t }\n\n\t var inAngleRange = interval.startAngle <= angle && angle <= interval.endAngle;\n\t containsPoint = (inAngleRange && closeOrLess(distance, pointRadius)) || (!inAngleRange && (!intersection || intersection.equals(point)));\n\t }\n\t return containsPoint;\n\t },\n\n\t _isOnPath: function(point, width) {\n\t var interval = this._arcInterval();\n\t var center = this.center;\n\t var angle = calculateAngle(center.x, center.y, this.radiusX, this.radiusY, point.x, point.y);\n\t if (angle !== 360) {\n\t angle = (360 + angle) % 360;\n\t }\n\n\t var inAngleRange = interval.startAngle <= angle && angle <= interval.endAngle;\n\n\t return inAngleRange && this.pointAt(angle).distanceTo(point) <= width;\n\t }\n\t});\n\n\tArc$2.fromPoints = function(start, end, rx, ry, largeArc, swipe, rotation) {// eslint-disable-line max-params\n\t var arcParameters = normalizeArcParameters({\n\t x1: start.x,\n\t y1: start.y,\n\t x2: end.x,\n\t y2: end.y,\n\t rx: rx,\n\t ry: ry,\n\t largeArc: largeArc,\n\t swipe: swipe,\n\t rotation: rotation\n\t });\n\n\t return new Arc$2(arcParameters.center, {\n\t startAngle: arcParameters.startAngle,\n\t endAngle: arcParameters.endAngle,\n\t radiusX: arcParameters.radiusX,\n\t radiusY: arcParameters.radiusY,\n\t xRotation: arcParameters.xRotation,\n\t anticlockwise: swipe === 0\n\t });\n\t};\n\n\tdefineAccessors(Arc$2.prototype, [ \"radiusX\", \"radiusY\", \"startAngle\", \"endAngle\", \"anticlockwise\" ]);\n\tObserversMixin.extend(Arc$2.prototype);\n\n\tfunction calculateAngle(cx, cy, rx, ry, x, y) {\n\t var cos = round((x - cx) / rx, 3);\n\t var sin = round((y - cy) / ry, 3);\n\n\t return round(deg(Math.atan2(sin, cos)));\n\t}\n\n\tfunction normalizeArcParameters(parameters) {\n\t var x1 = parameters.x1;\n\t var y1 = parameters.y1;\n\t var x2 = parameters.x2;\n\t var y2 = parameters.y2;\n\t var rx = parameters.rx;\n\t var ry = parameters.ry;\n\t var largeArc = parameters.largeArc;\n\t var swipe = parameters.swipe;\n\t var rotation = parameters.rotation; if (rotation === void 0) { rotation = 0; }\n\n\t var radians = rad(rotation);\n\t var cosine = Math.cos(radians);\n\t var sine = Math.sin(radians);\n\n\t var xT = cosine * (x1 - x2) / 2 + sine * (y1 - y2) / 2;\n\t var yT = -sine * (x1 - x2) / 2 + cosine * (y1 - y2) / 2;\n\n\t var sign = largeArc !== swipe ? 1 : -1;\n\n\t var xt2 = Math.pow(xT, 2);\n\t var yt2 = Math.pow(yT, 2);\n\t var rx2 = Math.pow(rx, 2);\n\t var ry2 = Math.pow(ry, 2);\n\n\t var delta = xt2 / rx2 + yt2 / ry2;\n\n\t if (delta > 1) {\n\t delta = Math.sqrt(xt2 / rx2 + yt2 / ry2);\n\t rx = delta * rx;\n\t rx2 = Math.pow(rx, 2);\n\n\t ry = delta * ry;\n\t ry2 = Math.pow(ry, 2);\n\t }\n\n\t var constT = sign * Math.sqrt((rx2 * ry2 - rx2 * yt2 - ry2 * xt2) / (rx2 * yt2 + ry2 * xt2));\n\t // due to rounding errors the value could become NaN even after radii correction\n\t if (isNaN(constT)) {\n\t constT = 0;\n\t }\n\n\t var cxT = constT * (rx * yT) / ry;\n\t var cyT = - constT * (ry * xT) / rx;\n\n\t var cx = cosine * cxT - sine * cyT + (x1 + x2) / 2;\n\t var cy = sine * cxT + cosine * cyT + (y1 + y2) / 2;\n\n\t var uX = (xT - cxT) / rx;\n\t var uY = (yT - cyT) / ry;\n\t var vX = -(xT + cxT) / rx;\n\t var vY = -(yT + cyT) / ry;\n\n\t var startAngle = (uY >= 0 ? 1 : -1) * deg(Math.acos(uX / Math.sqrt(uX * uX + uY * uY)));\n\n\t var angleCosine = round((uX * vX + uY * vY) / (Math.sqrt(uX * uX + uY * uY) * Math.sqrt(vX * vX + vY * vY)), 10);\n\t var angle = (uX * vY - uY * vX >= 0 ? 1 : -1) * deg(Math.acos(angleCosine));\n\n\t if (!swipe && angle > 0) {\n\t angle -= 360;\n\t }\n\n\t if (swipe && angle < 0) {\n\t angle += 360;\n\t }\n\t var endAngle = startAngle + angle;\n\t var signEndAngle = endAngle >= 0 ? 1 : -1;\n\t endAngle = (Math.abs(endAngle) % 360) * signEndAngle;\n\n\t return {\n\t center: new Point(cx, cy),\n\t startAngle: startAngle,\n\t endAngle: endAngle,\n\t radiusX: rx,\n\t radiusY: ry,\n\t xRotation: rotation\n\t };\n\t}\n\n\tfunction bboxStartAngle(angle, start) {\n\t var startAngle = angle;\n\n\t while (startAngle < start) {\n\t startAngle += 90;\n\t }\n\n\t return startAngle;\n\t}\n\n\tvar push = [].push;\n\tvar pop = [].pop;\n\tvar splice = [].splice;\n\tvar shift = [].shift;\n\tvar slice = [].slice;\n\tvar unshift = [].unshift;\n\n\tvar ElementsArray = Class.extend({\n\t init: function(array) {\n\t if (array === void 0) { array = []; }\n\n\t this.length = 0;\n\t this._splice(0, array.length, array);\n\t },\n\n\t elements: function(value) {\n\t if (value) {\n\t this._splice(0, this.length, value);\n\n\t this._change();\n\t return this;\n\t }\n\n\t return this.slice(0);\n\t },\n\n\t push: function() {\n\t var elements = arguments;\n\t var result = push.apply(this, elements);\n\n\t this._add(elements);\n\n\t return result;\n\t },\n\n\t slice: function() {\n\t return slice.call(this);\n\t },\n\n\t pop: function() {\n\t var length = this.length;\n\t var result = pop.apply(this);\n\n\t if (length) {\n\t this._remove([ result ]);\n\t }\n\n\t return result;\n\t },\n\n\t splice: function(index, howMany) {\n\t var elements = slice.call(arguments, 2);\n\t var result = this._splice(index, howMany, elements);\n\n\t this._change();\n\n\t return result;\n\t },\n\n\t shift: function() {\n\t var length = this.length;\n\t var result = shift.apply(this);\n\n\t if (length) {\n\t this._remove([ result ]);\n\t }\n\n\t return result;\n\t },\n\n\t unshift: function() {\n\t var elements = arguments;\n\t var result = unshift.apply(this, elements);\n\n\t this._add(elements);\n\n\t return result;\n\t },\n\n\t indexOf: function(element) {\n\t var this$1 = this;\n\n\t var length = this.length;\n\n\t for (var idx = 0; idx < length; idx++) {\n\t if (this$1[idx] === element) {\n\t return idx;\n\t }\n\t }\n\t return -1;\n\t },\n\n\t _splice: function(index, howMany, elements) {\n\t var result = splice.apply(this, [ index, howMany ].concat(elements));\n\n\t this._clearObserver(result);\n\t this._setObserver(elements);\n\n\t return result;\n\t },\n\n\t _add: function(elements) {\n\t this._setObserver(elements);\n\t this._change();\n\t },\n\n\t _remove: function(elements) {\n\t this._clearObserver(elements);\n\t this._change();\n\t },\n\n\t _setObserver: function(elements) {\n\t var this$1 = this;\n\n\t for (var idx = 0; idx < elements.length; idx++) {\n\t elements[idx].addObserver(this$1);\n\t }\n\t },\n\n\t _clearObserver: function(elements) {\n\t var this$1 = this;\n\n\t for (var idx = 0; idx < elements.length; idx++) {\n\t elements[idx].removeObserver(this$1);\n\t }\n\t },\n\n\t _change: function() {}\n\t});\n\n\tObserversMixin.extend(ElementsArray.prototype);\n\n\tvar GeometryElementsArray = ElementsArray.extend({\n\t _change: function() {\n\t this.geometryChange();\n\t }\n\t});\n\n\tfunction pointAccessor(name) {\n\t var fieldName = \"_\" + name;\n\t return function(value) {\n\t if (defined(value)) {\n\t this._observerField(fieldName, Point.create(value));\n\t this.geometryChange();\n\t return this;\n\t }\n\n\t return this[fieldName];\n\t };\n\t}\n\n\tfunction definePointAccessors(fn, names) {\n\t for (var i = 0; i < names.length; i++) {\n\t fn[names[i]] = pointAccessor(names[i]);\n\t }\n\t}\n\n\tfunction isOutOfEndPoint(endPoint, controlPoint, point) {\n\t var angle = deg(Math.atan2(controlPoint.y - endPoint.y, controlPoint.x - endPoint.x));\n\t var rotatedPoint = point.transformCopy(transform().rotate(-angle, endPoint));\n\n\t return rotatedPoint.x < endPoint.x;\n\t}\n\n\tfunction calculateCurveAt(t, field, points) {\n\t var t1 = 1 - t;\n\t return Math.pow(t1, 3) * points[0][field] +\n\t 3 * Math.pow(t1, 2) * t * points[1][field] +\n\t 3 * Math.pow(t, 2) * t1 * points[2][field] +\n\t Math.pow(t, 3) * points[3][field];\n\t}\n\n\tfunction toCubicPolynomial(points, field) {\n\t return [ -points[0][field] + 3 * points[1][field] - 3 * points[2][field] + points[3][field],\n\t 3 * (points[0][field] - 2 * points[1][field] + points[2][field]),\n\t 3 * (-points[0][field] + points[1][field]),\n\t points[0][field]\n\t ];\n\t}\n\n\tvar ComplexNumber = Class.extend({\n\t init: function(real, img) {\n\t if (real === void 0) { real = 0; }\n\t if (img === void 0) { img = 0; }\n\n\t this.real = real;\n\t this.img = img;\n\t },\n\n\t add: function(cNumber) {\n\t return new ComplexNumber(round(this.real + cNumber.real, PRECISION), round(this.img + cNumber.img, PRECISION));\n\t },\n\n\t addConstant: function(value) {\n\t return new ComplexNumber(this.real + value, this.img);\n\t },\n\n\t negate: function() {\n\t return new ComplexNumber(-this.real, -this.img);\n\t },\n\n\t multiply: function(cNumber) {\n\t return new ComplexNumber(this.real * cNumber.real - this.img * cNumber.img,\n\t this.real * cNumber.img + this.img * cNumber.real);\n\t },\n\n\t multiplyConstant: function(value) {\n\t return new ComplexNumber(this.real * value, this.img * value);\n\t },\n\n\t nthRoot: function(n) {\n\t var rad$$1 = Math.atan2(this.img, this.real);\n\t var r = Math.sqrt(Math.pow(this.img, 2) + Math.pow(this.real, 2));\n\t var nthR = Math.pow(r, 1 / n);\n\n\t return new ComplexNumber(nthR * Math.cos(rad$$1 / n), nthR * Math.sin(rad$$1 / n)); //Moivre's formula\n\t },\n\n\t equals: function(cNumber) {\n\t return this.real === cNumber.real && this.img === cNumber.img;\n\t },\n\n\t isReal: function() {\n\t return this.img === 0;\n\t }\n\t});\n\n\tfunction numberSign(x) {\n\t return x < 0 ? -1 : 1;\n\t}\n\n\tfunction solveQuadraticEquation(a, b, c) {\n\t var squareRoot = Math.sqrt(Math.pow(b, 2) - 4 * a * c);\n\t return [\n\t (-b + squareRoot) / (2 * a),\n\t (-b - squareRoot) / (2 * a)\n\t ];\n\t}\n\n\t//Cardano's formula\n\tfunction solveCubicEquation(a, b, c, d) {\n\t if (a === 0) {\n\t return solveQuadraticEquation(b, c, d);\n\t }\n\n\t var p = (3 * a * c - Math.pow(b, 2)) / (3 * Math.pow(a, 2));\n\t var q = (2 * Math.pow(b, 3) - 9 * a * b * c + 27 * Math.pow(a, 2) * d) / (27 * Math.pow(a, 3));\n\t var Q = Math.pow(p / 3, 3) + Math.pow(q / 2, 2);\n\t var i = new ComplexNumber(0,1);\n\t var b3a = -b / (3 * a);\n\t var x1, x2, y1, y2, y3, z1, z2;\n\n\t if (Q < 0) {\n\t x1 = new ComplexNumber(-q / 2, Math.sqrt(-Q)).nthRoot(3);\n\t x2 = new ComplexNumber(-q / 2, - Math.sqrt(-Q)).nthRoot(3);\n\t } else {\n\t x1 = -q / 2 + Math.sqrt(Q);\n\t x1 = new ComplexNumber(numberSign(x1) * Math.pow(Math.abs(x1), 1 / 3));\n\t x2 = -q / 2 - Math.sqrt(Q);\n\t x2 = new ComplexNumber(numberSign(x2) * Math.pow(Math.abs(x2), 1 / 3));\n\t }\n\n\t y1 = x1.add(x2);\n\n\t z1 = x1.add(x2).multiplyConstant(-1 / 2);\n\t z2 = x1.add(x2.negate()).multiplyConstant(Math.sqrt(3) / 2);\n\n\t y2 = z1.add(i.multiply(z2));\n\t y3 = z1.add(i.negate().multiply(z2));\n\n\t var result = [];\n\n\t if (y1.isReal()) {\n\t result.push(round(y1.real + b3a, PRECISION));\n\t }\n\t if (y2.isReal()) {\n\t result.push(round(y2.real + b3a, PRECISION));\n\t }\n\t if (y3.isReal()) {\n\t result.push(round(y3.real + b3a, PRECISION));\n\t }\n\n\t return result;\n\t}\n\n\tfunction hasRootsInRange(points, point, field, rootField, range) {\n\t var polynomial = toCubicPolynomial(points, rootField);\n\t var roots = solveCubicEquation(polynomial[0], polynomial[1], polynomial[2], polynomial[3] - point[rootField]);\n\t var intersection;\n\n\t for (var idx = 0; idx < roots.length; idx++) {\n\t if (0 <= roots[idx] && roots[idx] <= 1) {\n\t intersection = calculateCurveAt(roots[idx], field, points);\n\t if (Math.abs(intersection - point[field]) <= range) {\n\t return true;\n\t }\n\t }\n\t }\n\t}\n\n\tfunction curveIntersectionsCount(points, point, bbox) {\n\t var polynomial = toCubicPolynomial(points, \"x\");\n\t var roots = solveCubicEquation(polynomial[0], polynomial[1], polynomial[2], polynomial[3] - point.x);\n\t var rayIntersection, intersectsRay;\n\t var count = 0;\n\t for (var i = 0; i < roots.length; i++) {\n\t rayIntersection = calculateCurveAt(roots[i], \"y\", points);\n\t intersectsRay = close(rayIntersection, point.y) || rayIntersection > point.y;\n\t if (intersectsRay && (((roots[i] === 0 || roots[i] === 1) && bbox.bottomRight().x > point.x) || (0 < roots[i] && roots[i] < 1))) {\n\t count++;\n\t }\n\t }\n\n\t return count;\n\t}\n\n\tfunction lineIntersectionsCount(a, b, point) {\n\t var intersects;\n\t if (a.x !== b.x) {\n\t var minX = Math.min(a.x, b.x);\n\t var maxX = Math.max(a.x, b.x);\n\t var minY = Math.min(a.y, b.y);\n\t var maxY = Math.max(a.y, b.y);\n\t var inRange = minX <= point.x && point.x < maxX;\n\n\t if (minY === maxY) {\n\t intersects = point.y <= minY && inRange;\n\t } else {\n\t intersects = inRange && (((maxY - minY) * ((a.x - b.x) * (a.y - b.y) > 0 ? point.x - minX : maxX - point.x)) / (maxX - minX) + minY - point.y) >= 0;\n\t }\n\t }\n\n\t return intersects ? 1 : 0;\n\t}\n\n\tvar Segment = Class.extend({\n\t init: function(anchor, controlIn, controlOut) {\n\n\t this.anchor(anchor || new Point());\n\t this.controlIn(controlIn);\n\t this.controlOut(controlOut);\n\t },\n\n\t bboxTo: function(toSegment, matrix) {\n\t var segmentAnchor = this.anchor().transformCopy(matrix);\n\t var toSegmentAnchor = toSegment.anchor().transformCopy(matrix);\n\t var rect;\n\n\t if (this.controlOut() && toSegment.controlIn()) {\n\t rect = this._curveBoundingBox(\n\t segmentAnchor, this.controlOut().transformCopy(matrix),\n\t toSegment.controlIn().transformCopy(matrix), toSegmentAnchor\n\t );\n\t } else {\n\t rect = this._lineBoundingBox(segmentAnchor, toSegmentAnchor);\n\t }\n\n\t return rect;\n\t },\n\n\t _lineBoundingBox: function(p1, p2) {\n\t return Rect.fromPoints(p1, p2);\n\t },\n\n\t _curveBoundingBox: function(p1, cp1, cp2, p2) {\n\t var points = [ p1, cp1, cp2, p2 ];\n\t var extremesX = this._curveExtremesFor(points, \"x\");\n\t var extremesY = this._curveExtremesFor(points, \"y\");\n\t var xLimits = arrayLimits([ extremesX.min, extremesX.max, p1.x, p2.x ]);\n\t var yLimits = arrayLimits([ extremesY.min, extremesY.max, p1.y, p2.y ]);\n\n\t return Rect.fromPoints(new Point(xLimits.min, yLimits.min), new Point(xLimits.max, yLimits.max));\n\t },\n\n\t _curveExtremesFor: function(points, field) {\n\t var extremes = this._curveExtremes(\n\t points[0][field], points[1][field],\n\t points[2][field], points[3][field]\n\t );\n\n\t return {\n\t min: calculateCurveAt(extremes.min, field, points),\n\t max: calculateCurveAt(extremes.max, field, points)\n\t };\n\t },\n\n\t _curveExtremes: function(x1, x2, x3, x4) {\n\t var a = x1 - 3 * x2 + 3 * x3 - x4;\n\t var b = - 2 * (x1 - 2 * x2 + x3);\n\t var c = x1 - x2;\n\t var sqrt = Math.sqrt(b * b - 4 * a * c);\n\t var t1 = 0;\n\t var t2 = 1;\n\n\t if (a === 0) {\n\t if (b !== 0) {\n\t t1 = t2 = -c / b;\n\t }\n\t } else if (!isNaN(sqrt)) {\n\t t1 = (- b + sqrt) / (2 * a);\n\t t2 = (- b - sqrt) / (2 * a);\n\t }\n\n\t var min = Math.max(Math.min(t1, t2), 0);\n\t if (min < 0 || min > 1) {\n\t min = 0;\n\t }\n\n\t var max = Math.min(Math.max(t1, t2), 1);\n\t if (max > 1 || max < 0) {\n\t max = 1;\n\t }\n\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t },\n\n\t _intersectionsTo: function(segment, point) {\n\t var intersectionsCount;\n\t if (this.controlOut() && segment.controlIn()) {\n\t intersectionsCount = curveIntersectionsCount([ this.anchor(), this.controlOut(), segment.controlIn(), segment.anchor() ], point, this.bboxTo(segment));\n\t } else {\n\t intersectionsCount = lineIntersectionsCount(this.anchor(), segment.anchor(), point);\n\t }\n\t return intersectionsCount;\n\t },\n\n\t _isOnCurveTo: function(segment, point, width, endSegment) {\n\t var bbox = this.bboxTo(segment).expand(width, width);\n\t if (bbox.containsPoint(point)) {\n\t var p1 = this.anchor();\n\t var p2 = this.controlOut();\n\t var p3 = segment.controlIn();\n\t var p4 = segment.anchor();\n\n\t if (endSegment === \"start\" && p1.distanceTo(point) <= width) {\n\t return !isOutOfEndPoint(p1, p2, point);\n\t } else if (endSegment === \"end\" && p4.distanceTo(point) <= width) {\n\t return !isOutOfEndPoint(p4, p3, point);\n\t }\n\n\t //the approach is not entirely correct but is close and the alternatives are solving a 6th degree polynomial or testing the segment points\n\t var points = [ p1, p2, p3, p4 ];\n\t if (hasRootsInRange(points, point, \"x\", \"y\", width) || hasRootsInRange(points, point, \"y\", \"x\", width)) {\n\t return true;\n\t }\n\t var rotation = transform().rotate(45, point);\n\t var rotatedPoints = [ p1.transformCopy(rotation), p2.transformCopy(rotation), p3.transformCopy(rotation), p4.transformCopy(rotation) ];\n\t return hasRootsInRange(rotatedPoints, point, \"x\", \"y\", width) || hasRootsInRange(rotatedPoints, point, \"y\", \"x\", width);\n\t }\n\t },\n\n\t _isOnLineTo: function(segment, point, width) {\n\t var p1 = this.anchor();\n\t var p2 = segment.anchor();\n\t var angle = deg(Math.atan2(p2.y - p1.y, p2.x - p1.x));\n\t var rect = new Rect([ p1.x, p1.y - width / 2 ], [ p1.distanceTo(p2), width ]);\n\t return rect.containsPoint(point.transformCopy(transform().rotate(-angle, p1)));\n\t },\n\n\t _isOnPathTo: function(segment, point, width, endSegment) {\n\t var isOnPath;\n\t if (this.controlOut() && segment.controlIn()) {\n\t isOnPath = this._isOnCurveTo(segment, point, width / 2, endSegment);\n\t } else {\n\t isOnPath = this._isOnLineTo(segment, point, width);\n\t }\n\t return isOnPath;\n\t }\n\t});\n\n\tdefinePointAccessors(Segment.prototype, [ \"anchor\", \"controlIn\", \"controlOut\" ]);\n\tObserversMixin.extend(Segment.prototype);\n\n\tfunction arrayLimits(arr) {\n\t var length = arr.length;\n\t var min = MAX_NUM;\n\t var max = MIN_NUM;\n\n\t for (var i = 0; i < length; i ++) {\n\t max = Math.max(max, arr[i]);\n\t min = Math.min(min, arr[i]);\n\t }\n\n\t return {\n\t min: min,\n\t max: max\n\t };\n\t}\n\n\tfunction elementsBoundingBox(elements, applyTransform, transformation) {\n\t var boundingBox;\n\n\t for (var i = 0; i < elements.length; i++) {\n\t var element = elements[i];\n\t if (element.visible()) {\n\t var elementBoundingBox = applyTransform ? element.bbox(transformation) : element.rawBBox();\n\t if (elementBoundingBox) {\n\t if (boundingBox) {\n\t boundingBox = Rect.union(boundingBox, elementBoundingBox);\n\t } else {\n\t boundingBox = elementBoundingBox;\n\t }\n\t }\n\t }\n\t }\n\n\t return boundingBox;\n\t}\n\n\tfunction elementsClippedBoundingBox(elements, transformation) {\n\t var boundingBox;\n\n\t for (var i = 0; i < elements.length; i++) {\n\t var element = elements[i];\n\t if (element.visible()) {\n\t var elementBoundingBox = element.clippedBBox(transformation);\n\t if (elementBoundingBox) {\n\t if (boundingBox) {\n\t boundingBox = Rect.union(boundingBox, elementBoundingBox);\n\t } else {\n\t boundingBox = elementBoundingBox;\n\t }\n\t }\n\t }\n\t }\n\n\t return boundingBox;\n\t}\n\n\tvar MultiPath = Element$1.extend({\n\t init: function(options) {\n\t Element$1.fn.init.call(this, options);\n\t this.paths = new GeometryElementsArray();\n\t this.paths.addObserver(this);\n\n\t if (!defined(this.options.stroke)) {\n\t this.stroke(\"#000\");\n\t }\n\t },\n\n\t moveTo: function(x, y) {\n\t var path = new Path();\n\t path.moveTo(x, y);\n\n\t this.paths.push(path);\n\n\t return this;\n\t },\n\n\t lineTo: function(x, y) {\n\t if (this.paths.length > 0) {\n\t last(this.paths).lineTo(x, y);\n\t }\n\n\t return this;\n\t },\n\n\t curveTo: function(controlOut, controlIn, point) {\n\t if (this.paths.length > 0) {\n\t last(this.paths).curveTo(controlOut, controlIn, point);\n\t }\n\n\t return this;\n\t },\n\n\t arc: function(startAngle, endAngle, radiusX, radiusY, anticlockwise) {\n\t if (this.paths.length > 0) {\n\t last(this.paths).arc(startAngle, endAngle, radiusX, radiusY, anticlockwise);\n\t }\n\n\t return this;\n\t },\n\n\t arcTo: function(end, rx, ry, largeArc, swipe, rotation) {\n\t if (this.paths.length > 0) {\n\t last(this.paths).arcTo(end, rx, ry, largeArc, swipe, rotation);\n\t }\n\n\t return this;\n\t },\n\n\t close: function() {\n\t if (this.paths.length > 0) {\n\t last(this.paths).close();\n\t }\n\n\t return this;\n\t },\n\n\t _bbox: function(matrix) {\n\t return elementsBoundingBox(this.paths, true, matrix);\n\t },\n\n\t rawBBox: function() {\n\t return elementsBoundingBox(this.paths, false);\n\t },\n\n\t _containsPoint: function(point) {\n\t var paths = this.paths;\n\n\t for (var idx = 0; idx < paths.length; idx++) {\n\t if (paths[idx]._containsPoint(point)) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t },\n\n\t _isOnPath: function(point) {\n\t var paths = this.paths;\n\t var width = this.options.stroke.width;\n\n\t for (var idx = 0; idx < paths.length; idx++) {\n\t if (paths[idx]._isOnPath(point, width)) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t },\n\n\t _clippedBBox: function(transformation) {\n\t return elementsClippedBoundingBox(this.paths, this.currentTransform(transformation));\n\t }\n\t});\n\n\tMultiPath.prototype.nodeType = \"MultiPath\";\n\n\tPaintable.extend(MultiPath.prototype);\n\tMeasurable.extend(MultiPath.prototype);\n\n\tvar ShapeMap = {\n\t l: function(path, options) {\n\t var parameters = options.parameters;\n\t var position = options.position;\n\n\t for (var i = 0; i < parameters.length; i += 2) {\n\t var point = new Point(parameters[i], parameters[i + 1]);\n\n\t if (options.isRelative) {\n\t point.translateWith(position);\n\t }\n\n\t path.lineTo(point.x, point.y);\n\n\t position.x = point.x;\n\t position.y = point.y;\n\t }\n\t },\n\n\t c: function(path, options) {\n\t var parameters = options.parameters;\n\t var position = options.position;\n\n\t for (var i = 0; i < parameters.length; i += 6) {\n\t var controlOut = new Point(parameters[i], parameters[i + 1]);\n\t var controlIn = new Point(parameters[i + 2], parameters[i + 3]);\n\t var point = new Point(parameters[i + 4], parameters[i + 5]);\n\t if (options.isRelative) {\n\t controlIn.translateWith(position);\n\t controlOut.translateWith(position);\n\t point.translateWith(position);\n\t }\n\n\t path.curveTo(controlOut, controlIn, point);\n\n\t position.x = point.x;\n\t position.y = point.y;\n\t }\n\t },\n\n\t v: function(path, options) {\n\t var value = options.isRelative ? 0 : options.position.x;\n\n\t toLineParamaters(options.parameters, true, value);\n\t this.l(path, options);\n\t },\n\n\t h: function(path, options) {\n\t var value = options.isRelative ? 0 : options.position.y;\n\n\t toLineParamaters(options.parameters, false, value);\n\t this.l(path, options);\n\t },\n\n\t a: function(path, options) {\n\t var parameters = options.parameters;\n\t var position = options.position;\n\n\t for (var i = 0; i < parameters.length; i += 7) {\n\t var radiusX = parameters[i];\n\t var radiusY = parameters[i + 1];\n\t var rotation = parameters[i + 2];\n\t var largeArc = parameters[i + 3];\n\t var swipe = parameters[i + 4];\n\t var endPoint = new Point(parameters[i + 5], parameters[i + 6]);\n\n\t if (options.isRelative) {\n\t endPoint.translateWith(position);\n\t }\n\t if (position.x !== endPoint.x || position.y !== endPoint.y) {\n\t path.arcTo(endPoint, radiusX, radiusY, largeArc, swipe, rotation);\n\n\t position.x = endPoint.x;\n\t position.y = endPoint.y;\n\t }\n\t }\n\t },\n\n\t s: function(path, options) {\n\t var parameters = options.parameters;\n\t var position = options.position;\n\t var previousCommand = options.previousCommand;\n\t var lastControlIn;\n\n\t if (previousCommand === \"s\" || previousCommand === \"c\") {\n\t lastControlIn = last(last(path.paths).segments).controlIn();\n\t }\n\n\t for (var i = 0; i < parameters.length; i += 4) {\n\t var controlIn = new Point(parameters[i], parameters[i + 1]);\n\t var endPoint = new Point(parameters[i + 2], parameters[i + 3]);\n\t var controlOut = (void 0);\n\n\t if (options.isRelative) {\n\t controlIn.translateWith(position);\n\t endPoint.translateWith(position);\n\t }\n\n\t if (lastControlIn) {\n\t controlOut = reflectionPoint(lastControlIn, position);\n\t } else {\n\t controlOut = position.clone();\n\t }\n\n\t lastControlIn = controlIn;\n\n\t path.curveTo(controlOut, controlIn, endPoint);\n\n\t position.x = endPoint.x;\n\t position.y = endPoint.y;\n\t }\n\t },\n\n\t q: function(path, options) {\n\t var parameters = options.parameters;\n\t var position = options.position;\n\n\t for (var i = 0; i < parameters.length; i += 4) {\n\t var controlPoint = new Point(parameters[i], parameters[i + 1]);\n\t var endPoint = new Point(parameters[i + 2], parameters[i + 3]);\n\n\t if (options.isRelative) {\n\t controlPoint.translateWith(position);\n\t endPoint.translateWith(position);\n\t }\n\n\t var cubicControlPoints = quadraticToCubicControlPoints(position, controlPoint, endPoint);\n\n\t path.curveTo(cubicControlPoints.controlOut, cubicControlPoints.controlIn, endPoint);\n\n\t position.x = endPoint.x;\n\t position.y = endPoint.y;\n\t }\n\t },\n\n\t t: function(path, options) {\n\t var parameters = options.parameters;\n\t var position = options.position;\n\t var previousCommand = options.previousCommand;\n\t var controlPoint;\n\n\t if (previousCommand === \"q\" || previousCommand === \"t\") {\n\t var lastSegment = last(last(path.paths).segments);\n\t controlPoint = lastSegment.controlIn().clone()\n\t .translateWith(position.scaleCopy(-1 / 3))\n\t .scale(3 / 2);\n\t }\n\n\t for (var i = 0; i < parameters.length; i += 2) {\n\t var endPoint = new Point(parameters[i], parameters[i + 1]);\n\t if (options.isRelative) {\n\t endPoint.translateWith(position);\n\t }\n\n\t if (controlPoint) {\n\t controlPoint = reflectionPoint(controlPoint, position);\n\t } else {\n\t controlPoint = position.clone();\n\t }\n\n\t var cubicControlPoints = quadraticToCubicControlPoints(position, controlPoint, endPoint);\n\n\t path.curveTo(cubicControlPoints.controlOut, cubicControlPoints.controlIn, endPoint);\n\n\t position.x = endPoint.x;\n\t position.y = endPoint.y;\n\t }\n\t }\n\t};\n\n\tfunction toLineParamaters(parameters, isVertical, value) {\n\t var insertPosition = isVertical ? 0 : 1;\n\n\t for (var i = 0; i < parameters.length; i += 2) {\n\t parameters.splice(i + insertPosition, 0, value);\n\t }\n\t}\n\n\tfunction reflectionPoint(point, center) {\n\t if (point && center) {\n\t return center.scaleCopy(2).translate(-point.x, -point.y);\n\t }\n\t}\n\n\tvar third = 1 / 3;\n\n\tfunction quadraticToCubicControlPoints(position, controlPoint, endPoint) {\n\t var scaledPoint = controlPoint.clone().scale(2 / 3);\n\t return {\n\t controlOut: scaledPoint.clone().translateWith(position.scaleCopy(third)),\n\t controlIn: scaledPoint.translateWith(endPoint.scaleCopy(third))\n\t };\n\t}\n\n\tvar SEGMENT_REGEX = /([a-df-z]{1})([^a-df-z]*)(z)?/gi;\n\tvar SPLIT_REGEX = /[,\\s]?([+\\-]?(?:\\d*\\.\\d+|\\d+)(?:[eE][+\\-]?\\d+)?)/g;\n\tvar MOVE = \"m\";\n\tvar CLOSE = \"z\";\n\n\tfunction parseParameters(str) {\n\t var parameters = [];\n\t str.replace(SPLIT_REGEX, function(match, number) {\n\t parameters.push(parseFloat(number));\n\t });\n\t return parameters;\n\t}\n\n\tvar PathParser = Class.extend({\n\t parse: function(str, options) {\n\t var multiPath = new MultiPath(options);\n\t var position = new Point();\n\t var previousCommand;\n\n\t str.replace(SEGMENT_REGEX, function (match, element, params, closePath) {\n\t var command = element.toLowerCase();\n\t var isRelative = command === element;\n\t var parameters = parseParameters(params.trim());\n\n\t if (command === MOVE) {\n\t if (isRelative) {\n\t position.x += parameters[0];\n\t position.y += parameters[1];\n\t } else {\n\t position.x = parameters[0];\n\t position.y = parameters[1];\n\t }\n\n\t multiPath.moveTo(position.x, position.y);\n\n\t if (parameters.length > 2) {\n\t command = \"l\";\n\t parameters.splice(0, 2);\n\t }\n\t }\n\n\t if (ShapeMap[command]) {\n\t ShapeMap[command](\n\t multiPath, {\n\t parameters: parameters,\n\t position: position,\n\t isRelative: isRelative,\n\t previousCommand: previousCommand\n\t }\n\t );\n\n\t if (closePath && closePath.toLowerCase() === CLOSE) {\n\t multiPath.close();\n\t }\n\t } else if (command !== MOVE) {\n\t throw new Error(\"Error while parsing SVG path. Unsupported command: \" + command);\n\t }\n\n\t previousCommand = command;\n\t });\n\n\t return multiPath;\n\t }\n\t});\n\n\tPathParser.current = new PathParser();\n\n\tvar Path = Element$1.extend({\n\t init: function(options) {\n\t Element$1.fn.init.call(this, options);\n\t this.segments = new GeometryElementsArray();\n\t this.segments.addObserver(this);\n\n\t if (!defined(this.options.stroke)) {\n\t this.stroke(\"#000\");\n\n\t if (!defined(this.options.stroke.lineJoin)) {\n\t this.options.set(\"stroke.lineJoin\", \"miter\");\n\t }\n\t }\n\t },\n\n\t moveTo: function(x, y) {\n\t this.suspend();\n\t this.segments.elements([]);\n\t this.resume();\n\n\t this.lineTo(x, y);\n\n\t return this;\n\t },\n\n\t lineTo: function(x, y) {\n\t var point = defined(y) ? new Point(x, y) : x;\n\t var segment = new Segment(point);\n\n\t this.segments.push(segment);\n\n\t return this;\n\t },\n\n\t curveTo: function(controlOut, controlIn, point) {\n\t if (this.segments.length > 0) {\n\t var lastSegment = last(this.segments);\n\t var segment = new Segment(point, controlIn);\n\t this.suspend();\n\t lastSegment.controlOut(controlOut);\n\t this.resume();\n\n\t this.segments.push(segment);\n\t }\n\n\t return this;\n\t },\n\n\t arc: function(startAngle, endAngle, radiusX, radiusY, anticlockwise) {\n\t if (this.segments.length > 0) {\n\t var lastSegment = last(this.segments);\n\t var anchor = lastSegment.anchor();\n\t var start = rad(startAngle);\n\t var center = new Point(anchor.x - radiusX * Math.cos(start),\n\t anchor.y - radiusY * Math.sin(start));\n\t var arc = new Arc$2(center, {\n\t startAngle: startAngle,\n\t endAngle: endAngle,\n\t radiusX: radiusX,\n\t radiusY: radiusY,\n\t anticlockwise: anticlockwise\n\t });\n\n\t this._addArcSegments(arc);\n\t }\n\n\t return this;\n\t },\n\n\t arcTo: function(end, rx, ry, largeArc, swipe, rotation) {\n\t if (this.segments.length > 0) {\n\t var lastSegment = last(this.segments);\n\t var anchor = lastSegment.anchor();\n\t var arc = Arc$2.fromPoints(anchor, end, rx, ry, largeArc, swipe, rotation);\n\n\t this._addArcSegments(arc);\n\t }\n\t return this;\n\t },\n\n\t _addArcSegments: function(arc) {\n\t var this$1 = this;\n\n\t this.suspend();\n\n\t var curvePoints = arc.curvePoints();\n\n\t for (var i = 1; i < curvePoints.length; i += 3) {\n\t this$1.curveTo(curvePoints[i], curvePoints[i + 1], curvePoints[i + 2]);\n\t }\n\n\t this.resume();\n\t this.geometryChange();\n\t },\n\n\t close: function() {\n\t this.options.closed = true;\n\t this.geometryChange();\n\n\t return this;\n\t },\n\n\t rawBBox: function() {\n\t return this._bbox();\n\t },\n\n\t _containsPoint: function(point) {\n\t var segments = this.segments;\n\t var length = segments.length;\n\t var intersectionsCount = 0;\n\t var previous, current;\n\n\t for (var idx = 1; idx < length; idx++) {\n\t previous = segments[idx - 1];\n\t current = segments[idx];\n\t intersectionsCount += previous._intersectionsTo(current, point);\n\t }\n\n\t if (this.options.closed || !segments[0].anchor().equals(segments[length - 1].anchor())) {\n\t intersectionsCount += lineIntersectionsCount(segments[0].anchor(), segments[length - 1].anchor(), point);\n\t }\n\n\t return intersectionsCount % 2 !== 0;\n\t },\n\n\t _isOnPath: function(point, width) {\n\t var segments = this.segments;\n\t var length = segments.length;\n\t var pathWidth = width || this.options.stroke.width;\n\n\t if (length > 1) {\n\t if (segments[0]._isOnPathTo(segments[1], point, pathWidth, \"start\")) {\n\t return true;\n\t }\n\n\t for (var idx = 2; idx <= length - 2; idx++) {\n\t if (segments[idx - 1]._isOnPathTo(segments[idx], point, pathWidth)) {\n\t return true;\n\t }\n\t }\n\n\t if (segments[length - 2]._isOnPathTo(segments[length - 1], point, pathWidth, \"end\")) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t },\n\n\t _bbox: function(matrix) {\n\t var segments = this.segments;\n\t var length = segments.length;\n\t var boundingBox;\n\n\t if (length === 1) {\n\t var anchor = segments[0].anchor().transformCopy(matrix);\n\t boundingBox = new Rect(anchor, Size.ZERO);\n\t } else if (length > 0) {\n\t for (var i = 1; i < length; i++) {\n\t var segmentBox = segments[i - 1].bboxTo(segments[i], matrix);\n\t if (boundingBox) {\n\t boundingBox = Rect.union(boundingBox, segmentBox);\n\t } else {\n\t boundingBox = segmentBox;\n\t }\n\t }\n\t }\n\n\t return boundingBox;\n\t }\n\t});\n\n\tPath.fromRect = function(rect, options) {\n\t return new Path(options)\n\t .moveTo(rect.topLeft())\n\t .lineTo(rect.topRight())\n\t .lineTo(rect.bottomRight())\n\t .lineTo(rect.bottomLeft())\n\t .close();\n\t};\n\n\tPath.fromPoints = function(points, options) {\n\t if (points) {\n\t var path = new Path(options);\n\n\t for (var i = 0; i < points.length; i++) {\n\t var point = Point.create(points[i]);\n\t if (point) {\n\t if (i === 0) {\n\t path.moveTo(point);\n\t } else {\n\t path.lineTo(point);\n\t }\n\t }\n\t }\n\n\t return path;\n\t }\n\t};\n\n\tPath.fromArc = function(arc, options) {\n\t var path = new Path(options);\n\t var startAngle = arc.startAngle;\n\t var start = arc.pointAt(startAngle);\n\t path.moveTo(start.x, start.y);\n\t path.arc(startAngle, arc.endAngle, arc.radiusX, arc.radiusY, arc.anticlockwise);\n\t return path;\n\t};\n\n\tPath.prototype.nodeType = \"Path\";\n\n\tPaintable.extend(Path.prototype);\n\tMeasurable.extend(Path.prototype);\n\n\tPath.parse = function(str, options) {\n\t return PathParser.current.parse(str, options);\n\t};\n\n\tvar DEFAULT_STROKE$1 = \"#000\";\n\n\tvar Arc = Element$1.extend({\n\t init: function(geometry, options) {\n\t if (geometry === void 0) { geometry = new Arc$2(); }\n\t if (options === void 0) { options = {}; }\n\n\t Element$1.fn.init.call(this, options);\n\n\t this.geometry(geometry);\n\n\t if (!defined(this.options.stroke)) {\n\t this.stroke(DEFAULT_STROKE$1);\n\t }\n\t },\n\n\t _bbox: function(matrix) {\n\t return this._geometry.bbox(matrix);\n\t },\n\n\t rawBBox: function() {\n\t return this.geometry().bbox();\n\t },\n\n\t toPath: function() {\n\t var path = new Path();\n\t var curvePoints = this.geometry().curvePoints();\n\n\t if (curvePoints.length > 0) {\n\t path.moveTo(curvePoints[0].x, curvePoints[0].y);\n\n\t for (var i = 1; i < curvePoints.length; i += 3) {\n\t path.curveTo(curvePoints[i], curvePoints[i + 1], curvePoints[i + 2]);\n\t }\n\t }\n\n\t return path;\n\t },\n\n\t _containsPoint: function(point) {\n\t return this.geometry().containsPoint(point);\n\t },\n\n\t _isOnPath: function(point) {\n\t return this.geometry()._isOnPath(point, this.options.stroke.width / 2);\n\t }\n\t});\n\n\tArc.prototype.nodeType = \"Arc\";\n\n\tPaintable.extend(Arc.prototype);\n\tMeasurable.extend(Arc.prototype);\n\tdefineGeometryAccessors(Arc.prototype, [ \"geometry\" ]);\n\n\tvar DEFAULT_FONT = \"12px sans-serif\";\n\tvar DEFAULT_FILL = \"#000\";\n\n\tvar Text = Element$1.extend({\n\t init: function(content, position, options) {\n\t if (position === void 0) { position = new Point(); }\n\t if (options === void 0) { options = {}; }\n\n\t Element$1.fn.init.call(this, options);\n\n\t this.content(content);\n\t this.position(position);\n\n\t if (!this.options.font) {\n\t this.options.font = DEFAULT_FONT;\n\t }\n\n\t if (!defined(this.options.fill)) {\n\t this.fill(DEFAULT_FILL);\n\t }\n\t },\n\n\t content: function(value) {\n\t if (defined(value)) {\n\t this.options.set(\"content\", value);\n\t return this;\n\t }\n\n\t return this.options.get(\"content\");\n\t },\n\n\t measure: function() {\n\t var metrics = kendoUtil.measureText(this.content(), {\n\t font: this.options.get(\"font\")\n\t });\n\n\t return metrics;\n\t },\n\n\t rect: function() {\n\t var size = this.measure();\n\t var pos = this.position().clone();\n\t return new Rect(pos, [ size.width, size.height ]);\n\t },\n\n\t bbox: function(transformation) {\n\t var combinedMatrix = toMatrix(this.currentTransform(transformation));\n\t return this.rect().bbox(combinedMatrix);\n\t },\n\n\t rawBBox: function() {\n\t return this.rect().bbox();\n\t },\n\n\t _containsPoint: function(point) {\n\t return this.rect().containsPoint(point);\n\t }\n\t});\n\n\tText.prototype.nodeType = \"Text\";\n\n\tPaintable.extend(Text.prototype);\n\n\tdefinePointAccessors(Text.prototype, [ \"position\" ]);\n\n\tvar Image$1 = Element$1.extend({\n\t init: function(src, rect, options) {\n\t if (rect === void 0) { rect = new Rect(); }\n\t if (options === void 0) { options = {}; }\n\n\t Element$1.fn.init.call(this, options);\n\n\t this.src(src);\n\t this.rect(rect);\n\t },\n\n\t src: function(value) {\n\t if (defined(value)) {\n\t this.options.set(\"src\", value);\n\t return this;\n\t }\n\n\t return this.options.get(\"src\");\n\t },\n\n\t bbox: function(transformation) {\n\t var combinedMatrix = toMatrix(this.currentTransform(transformation));\n\t return this._rect.bbox(combinedMatrix);\n\t },\n\n\t rawBBox: function() {\n\t return this._rect.bbox();\n\t },\n\n\t _containsPoint: function(point) {\n\t return this._rect.containsPoint(point);\n\t },\n\n\t _hasFill: function() {\n\t return this.src();\n\t }\n\t});\n\n\tImage$1.prototype.nodeType = \"Image\";\n\n\tdefineGeometryAccessors(Image$1.prototype, [ \"rect\" ]);\n\n\tvar Traversable = {\n\t extend: function(proto, childrenField) {\n\t proto.traverse = function(callback) {\n\t var children = this[childrenField];\n\n\t for (var i = 0; i < children.length; i++) {\n\t var child = children[i];\n\n\t if (child.traverse) {\n\t child.traverse(callback);\n\t } else {\n\t callback(child);\n\t }\n\t }\n\n\t return this;\n\t };\n\t }\n\t};\n\n\tvar Group = Element$1.extend({\n\t init: function(options) {\n\t Element$1.fn.init.call(this, options);\n\t this.children = [];\n\t },\n\n\t childrenChange: function(action, items, index) {\n\t this.trigger(\"childrenChange\",{\n\t action: action,\n\t items: items,\n\t index: index\n\t });\n\t },\n\n\t append: function() {\n\t append(this.children, arguments);\n\t this._reparent(arguments, this);\n\n\t this.childrenChange(\"add\", arguments);\n\n\t return this;\n\t },\n\n\t insert: function(index, element) {\n\t this.children.splice(index, 0, element);\n\t element.parent = this;\n\n\t this.childrenChange(\"add\", [ element ], index);\n\n\t return this;\n\t },\n\n\t insertAt: function(element, index) {\n\t return this.insert(index, element);\n\t },\n\n\t remove: function(element) {\n\t var index = this.children.indexOf(element);\n\t if (index >= 0) {\n\t this.children.splice(index, 1);\n\t element.parent = null;\n\t this.childrenChange(\"remove\", [ element ], index);\n\t }\n\n\t return this;\n\t },\n\n\t removeAt: function(index) {\n\t if (0 <= index && index < this.children.length) {\n\t var element = this.children[index];\n\t this.children.splice(index, 1);\n\t element.parent = null;\n\t this.childrenChange(\"remove\", [ element ], index);\n\t }\n\n\t return this;\n\t },\n\n\t clear: function() {\n\t var items = this.children;\n\t this.children = [];\n\t this._reparent(items, null);\n\n\t this.childrenChange(\"remove\", items, 0);\n\n\t return this;\n\t },\n\n\t bbox: function(transformation) {\n\t return elementsBoundingBox(this.children, true, this.currentTransform(transformation));\n\t },\n\n\t rawBBox: function() {\n\t return elementsBoundingBox(this.children, false);\n\t },\n\n\t _clippedBBox: function(transformation) {\n\t return elementsClippedBoundingBox(this.children, this.currentTransform(transformation));\n\t },\n\n\t currentTransform: function(transformation) {\n\t return Element$1.prototype.currentTransform.call(this, transformation) || null;\n\t },\n\n\t containsPoint: function(point, parentTransform) {\n\t if (this.visible()) {\n\t var children = this.children;\n\t var transform = this.currentTransform(parentTransform);\n\t for (var idx = 0; idx < children.length; idx++) {\n\t if (children[idx].containsPoint(point, transform)) {\n\t return true;\n\t }\n\t }\n\t }\n\t return false;\n\t },\n\n\t _reparent: function(elements, newParent) {\n\t var this$1 = this;\n\n\t for (var i = 0; i < elements.length; i++) {\n\t var child = elements[i];\n\t var parent = child.parent;\n\t if (parent && parent !== this$1 && parent.remove) {\n\t parent.remove(child);\n\t }\n\n\t child.parent = newParent;\n\t }\n\t }\n\t});\n\n\tGroup.prototype.nodeType = \"Group\";\n\n\tTraversable.extend(Group.prototype, \"children\");\n\n\tfunction translateToPoint(point, bbox, element) {\n\t var transofrm = element.transform() || transform();\n\t var matrix = transofrm.matrix();\n\t matrix.e += point.x - bbox.origin.x;\n\t matrix.f += point.y - bbox.origin.y;\n\n\t transofrm.matrix(matrix);\n\t element.transform(transofrm);\n\t}\n\n\tfunction alignStart(size, rect, align, axis, sizeField) {\n\t var start;\n\t if (align === \"start\") {\n\t start = rect.origin[axis];\n\t } else if (align === \"end\") {\n\t start = rect.origin[axis] + rect.size[sizeField] - size;\n\t } else {\n\t start = rect.origin[axis] + (rect.size[sizeField] - size) / 2;\n\t }\n\n\t return start;\n\t}\n\n\tfunction alignStartReverse(size, rect, align, axis, sizeField) {\n\t var start;\n\t if (align === \"start\") {\n\t start = rect.origin[axis] + rect.size[sizeField] - size;\n\t } else if (align === \"end\") {\n\t start = rect.origin[axis];\n\t } else {\n\t start = rect.origin[axis] + (rect.size[sizeField] - size) / 2;\n\t }\n\n\t return start;\n\t}\n\n\tvar DEFAULT_OPTIONS = {\n\t alignContent: \"start\",\n\t justifyContent: \"start\",\n\t alignItems: \"start\",\n\t spacing: 0,\n\t orientation: \"horizontal\",\n\t lineSpacing: 0,\n\t wrap: true,\n\t revers: false\n\t};\n\n\tvar forEach = function (elements, callback) {\n\t elements.forEach(callback);\n\t};\n\n\tvar forEachReverse = function (elements, callback) {\n\t var length = elements.length;\n\n\t for (var idx = length - 1; idx >= 0; idx--) {\n\t callback(elements[idx], idx);\n\t }\n\t};\n\n\tvar Layout = Group.extend({\n\t init: function(rect, options) {\n\t Group.fn.init.call(this, $.extend({}, DEFAULT_OPTIONS, options));\n\t this._rect = rect;\n\t this._fieldMap = {};\n\t },\n\n\t rect: function(value) {\n\t if (value) {\n\t this._rect = value;\n\t return this;\n\t }\n\n\t return this._rect;\n\t },\n\n\t _initMap: function() {\n\t var options = this.options;\n\t var fieldMap = this._fieldMap;\n\t if (options.orientation === \"horizontal\") {\n\t fieldMap.sizeField = \"width\";\n\t fieldMap.groupsSizeField = \"height\";\n\t fieldMap.groupAxis = \"x\";\n\t fieldMap.groupsAxis = \"y\";\n\t } else {\n\t fieldMap.sizeField = \"height\";\n\t fieldMap.groupsSizeField = \"width\";\n\t fieldMap.groupAxis = \"y\";\n\t fieldMap.groupsAxis = \"x\";\n\t }\n\n\t if (options.reverse) {\n\t this.forEach = forEachReverse;\n\t this.justifyAlign = alignStartReverse;\n\t } else {\n\t this.forEach = forEach;\n\t this.justifyAlign = alignStart;\n\t }\n\t },\n\n\t reflow: function() {\n\t var this$1 = this;\n\n\t if (!this._rect || this.children.length === 0) {\n\t return;\n\t }\n\t this._initMap();\n\n\t if (this.options.transform) {\n\t this.transform(null);\n\t }\n\n\t var options = this.options;\n\t var rect = this._rect;\n\t var ref = this._initGroups();\n\t var groups = ref.groups;\n\t var groupsSize = ref.groupsSize;\n\t var ref$1 = this._fieldMap;\n\t var sizeField = ref$1.sizeField;\n\t var groupsSizeField = ref$1.groupsSizeField;\n\t var groupAxis = ref$1.groupAxis;\n\t var groupsAxis = ref$1.groupsAxis;\n\t var groupOrigin = new Point();\n\t var elementOrigin = new Point();\n\t var size = new Size();\n\t var groupStart = alignStart(groupsSize, rect, options.alignContent, groupsAxis, groupsSizeField);\n\t var elementStart, group, groupBox;\n\n\t var arrangeElements = function (bbox, idx) {\n\t var element = group.elements[idx];\n\n\t elementOrigin[groupAxis] = elementStart;\n\t elementOrigin[groupsAxis] = alignStart(bbox.size[groupsSizeField], groupBox, options.alignItems, groupsAxis, groupsSizeField);\n\t translateToPoint(elementOrigin, bbox, element);\n\t elementStart += bbox.size[sizeField] + options.spacing;\n\t };\n\n\t for (var groupIdx = 0; groupIdx < groups.length; groupIdx++) {\n\t group = groups[groupIdx];\n\t groupOrigin[groupAxis] = elementStart = this$1.justifyAlign(group.size, rect, options.justifyContent, groupAxis, sizeField);\n\t groupOrigin[groupsAxis] = groupStart;\n\t size[sizeField] = group.size;\n\t size[groupsSizeField] = group.lineSize;\n\t groupBox = new Rect(groupOrigin, size);\n\t this$1.forEach(group.bboxes, arrangeElements);\n\n\t groupStart += group.lineSize + options.lineSpacing;\n\t }\n\n\t if (!options.wrap && group.size > rect.size[sizeField]) {\n\t var scale = rect.size[sizeField] / groupBox.size[sizeField];\n\t var scaledStart = groupBox.topLeft().scale(scale, scale);\n\t var scaledSize = groupBox.size[groupsSizeField] * scale;\n\t var newStart = alignStart(scaledSize, rect, options.alignContent, groupsAxis, groupsSizeField);\n\t var transform$$1 = transform();\n\t if (groupAxis === \"x\") {\n\t transform$$1.translate(rect.origin.x - scaledStart.x, newStart - scaledStart.y);\n\t } else {\n\t transform$$1.translate(newStart - scaledStart.x, rect.origin.y - scaledStart.y);\n\t }\n\t transform$$1.scale(scale, scale);\n\n\t this.transform(transform$$1);\n\t }\n\t },\n\n\t _initGroups: function() {\n\t var this$1 = this;\n\n\t var ref = this;\n\t var options = ref.options;\n\t var children = ref.children;\n\t var lineSpacing = options.lineSpacing;\n\t var wrap = options.wrap;\n\t var spacing = options.spacing;\n\t var sizeField = this._fieldMap.sizeField;\n\t var group = this._newGroup();\n\t var groups = [];\n\t var addGroup = function() {\n\t groups.push(group);\n\t groupsSize += group.lineSize + lineSpacing;\n\t };\n\t var groupsSize = -lineSpacing;\n\n\t for (var idx = 0; idx < children.length; idx++) {\n\t var element = children[idx];\n\t var bbox = children[idx].clippedBBox();\n\t if (element.visible() && bbox) {\n\t if (wrap && group.size + bbox.size[sizeField] + spacing > this$1._rect.size[sizeField]) {\n\t if (group.bboxes.length === 0) {\n\t this$1._addToGroup(group, bbox, element);\n\t addGroup();\n\t group = this$1._newGroup();\n\t } else {\n\t addGroup();\n\t group = this$1._newGroup();\n\t this$1._addToGroup(group, bbox, element);\n\t }\n\t } else {\n\t this$1._addToGroup(group, bbox, element);\n\t }\n\t }\n\t }\n\n\t if (group.bboxes.length) {\n\t addGroup();\n\t }\n\n\t return {\n\t groups: groups,\n\t groupsSize: groupsSize\n\t };\n\t },\n\n\t _addToGroup: function(group, bbox, element) {\n\t group.size += bbox.size[this._fieldMap.sizeField] + this.options.spacing;\n\t group.lineSize = Math.max(bbox.size[this._fieldMap.groupsSizeField], group.lineSize);\n\t group.bboxes.push(bbox);\n\t group.elements.push(element);\n\t },\n\n\t _newGroup: function() {\n\t return {\n\t lineSize: 0,\n\t size: -this.options.spacing,\n\t bboxes: [],\n\t elements: []\n\t };\n\t }\n\t});\n\n\tvar Rect$2 = Element$1.extend({\n\t init: function(geometry, options) {\n\t if (geometry === void 0) { geometry = new Rect(); }\n\t if (options === void 0) { options = {}; }\n\n\t Element$1.fn.init.call(this, options);\n\t this.geometry(geometry);\n\n\t if (!defined(this.options.stroke)) {\n\t this.stroke(\"#000\");\n\t }\n\t },\n\n\t _bbox: function(matrix) {\n\t return this._geometry.bbox(matrix);\n\t },\n\n\t rawBBox: function() {\n\t return this._geometry.bbox();\n\t },\n\n\t _containsPoint: function(point) {\n\t return this._geometry.containsPoint(point);\n\t },\n\n\t _isOnPath: function(point) {\n\t return this.geometry()._isOnPath(point, this.options.stroke.width / 2);\n\t }\n\t});\n\n\tRect$2.prototype.nodeType = \"Rect\";\n\n\tPaintable.extend(Rect$2.prototype);\n\tMeasurable.extend(Rect$2.prototype);\n\tdefineGeometryAccessors(Rect$2.prototype, [ \"geometry\" ]);\n\n\tfunction alignElements(elements, rect, alignment, axis, sizeField) {\n\t for (var idx = 0; idx < elements.length; idx++) {\n\t var bbox = elements[idx].clippedBBox();\n\t if (bbox) {\n\t var point = bbox.origin.clone();\n\t point[axis] = alignStart(bbox.size[sizeField], rect, alignment || \"start\", axis, sizeField);\n\t translateToPoint(point, bbox, elements[idx]);\n\t }\n\t }\n\t}\n\n\tfunction align(elements, rect, alignment) {\n\t alignElements(elements, rect, alignment, \"x\", \"width\");\n\t}\n\n\tfunction vAlign(elements, rect, alignment) {\n\t alignElements(elements, rect, alignment, \"y\", \"height\");\n\t}\n\n\tfunction stackElements(elements, stackAxis, otherAxis, sizeField) {\n\t if (elements.length > 1) {\n\t var origin = new Point();\n\t var previousBBox = elements[0].bbox;\n\n\t for (var idx = 1; idx < elements.length; idx++) {\n\t var element = elements[idx].element;\n\t var bbox = elements[idx].bbox;\n\t origin[stackAxis] = previousBBox.origin[stackAxis] + previousBBox.size[sizeField];\n\t origin[otherAxis] = bbox.origin[otherAxis];\n\t translateToPoint(origin, bbox, element);\n\t bbox.origin[stackAxis] = origin[stackAxis];\n\t previousBBox = bbox;\n\t }\n\t }\n\t}\n\n\tfunction createStackElements(elements) {\n\t var stackElements = [];\n\n\t for (var idx = 0; idx < elements.length; idx++) {\n\t var element = elements[idx];\n\t var bbox = element.clippedBBox();\n\t if (bbox) {\n\t stackElements.push({\n\t element: element,\n\t bbox: bbox\n\t });\n\t }\n\t }\n\n\t return stackElements;\n\t}\n\n\tfunction stack(elements) {\n\t stackElements(createStackElements(elements), \"x\", \"y\", \"width\");\n\t}\n\n\tfunction vStack(elements) {\n\t stackElements(createStackElements(elements), \"y\", \"x\", \"height\");\n\t}\n\n\tfunction getStacks(elements, rect, sizeField) {\n\t var maxSize = rect.size[sizeField];\n\t var stacks = [];\n\t var stack = [];\n\t var stackSize = 0;\n\t var element, bbox;\n\n\t var addElementToStack = function() {\n\t stack.push({\n\t element: element,\n\t bbox: bbox\n\t });\n\t };\n\n\t for (var idx = 0; idx < elements.length; idx++) {\n\t element = elements[idx];\n\n\t bbox = element.clippedBBox();\n\t if (bbox) {\n\t var size = bbox.size[sizeField];\n\t if (stackSize + size > maxSize) {\n\t if (stack.length) {\n\t stacks.push(stack);\n\t stack = [];\n\t addElementToStack();\n\t stackSize = size;\n\t } else {\n\t addElementToStack();\n\t stacks.push(stack);\n\t stack = [];\n\t stackSize = 0;\n\t }\n\t } else {\n\t addElementToStack();\n\t stackSize += size;\n\t }\n\t }\n\t }\n\n\t if (stack.length) {\n\t stacks.push(stack);\n\t }\n\n\t return stacks;\n\t}\n\n\tfunction wrapElements(elements, rect, axis, otherAxis, sizeField) {\n\t var stacks = getStacks(elements, rect, sizeField);\n\t var origin = rect.origin.clone();\n\t var result = [];\n\n\t for (var idx = 0; idx < stacks.length; idx++) {\n\t var stack = stacks[idx];\n\t var startElement = stack[0];\n\t origin[otherAxis] = startElement.bbox.origin[otherAxis];\n\t translateToPoint(origin, startElement.bbox, startElement.element);\n\t startElement.bbox.origin[axis] = origin[axis];\n\t stackElements(stack, axis, otherAxis, sizeField);\n\t result.push([]);\n\t for (var elementIdx = 0; elementIdx < stack.length; elementIdx++) {\n\t result[idx].push(stack[elementIdx].element);\n\t }\n\t }\n\t return result;\n\t}\n\n\tfunction wrap(elements, rect) {\n\t return wrapElements(elements, rect, \"x\", \"y\", \"width\");\n\t}\n\n\tfunction vWrap(elements, rect) {\n\t return wrapElements(elements, rect, \"y\", \"x\", \"height\");\n\t}\n\n\tfunction fit(element, rect) {\n\t var bbox = element.clippedBBox();\n\t if (bbox) {\n\t var elementSize = bbox.size;\n\t var rectSize = rect.size;\n\t if (rectSize.width < elementSize.width || rectSize.height < elementSize.height) {\n\t var scale = Math.min(rectSize.width / elementSize.width, rectSize.height / elementSize.height);\n\t var transform$$1 = element.transform() || transform();\n\t transform$$1.scale(scale, scale);\n\t element.transform(transform$$1);\n\t }\n\t }\n\t}\n\n\tvar StopsArray = ElementsArray.extend({\n\t _change: function() {\n\t this.optionsChange({\n\t field: \"stops\"\n\t });\n\t }\n\t});\n\n\tfunction optionsAccessor(name) {\n\t return function(value) {\n\t if (defined(value)) {\n\t this.options.set(name, value);\n\t return this;\n\t }\n\n\t return this.options.get(name);\n\t };\n\t}\n\n\tfunction defineOptionsAccessors(fn, names) {\n\t for (var i = 0; i < names.length; i++) {\n\t fn[names[i]] = optionsAccessor(names[i]);\n\t }\n\t}\n\n\tvar GradientStop = Class.extend({\n\t init: function(offset, color, opacity) {\n\n\t this.options = new OptionsStore({\n\t offset: offset,\n\t color: color,\n\t opacity: defined(opacity) ? opacity : 1\n\t });\n\t this.options.addObserver(this);\n\t }\n\t});\n\n\tGradientStop.create = function(arg) {\n\t if (defined(arg)) {\n\t var stop;\n\t if (arg instanceof GradientStop) {\n\t stop = arg;\n\t } else if (arg.length > 1) {\n\t stop = new GradientStop(arg[0], arg[1], arg[2]);\n\t } else {\n\t stop = new GradientStop(arg.offset, arg.color, arg.opacity);\n\t }\n\n\t return stop;\n\t }\n\t};\n\n\tdefineOptionsAccessors(GradientStop.prototype, [ \"offset\", \"color\", \"opacity\" ]);\n\tObserversMixin.extend(GradientStop.prototype);\n\n\tvar Gradient = Class.extend({\n\t init: function(options) {\n\t if (options === void 0) { options = {}; }\n\n\t this.stops = new StopsArray(this._createStops(options.stops));\n\t this.stops.addObserver(this);\n\t this._userSpace = options.userSpace;\n\t this.id = definitionId();\n\t },\n\n\t userSpace: function(value) {\n\t if (defined(value)) {\n\t this._userSpace = value;\n\t this.optionsChange();\n\t return this;\n\t }\n\n\t return this._userSpace;\n\t },\n\n\t _createStops: function(stops) {\n\t if (stops === void 0) { stops = []; }\n\n\t var result = [];\n\t for (var idx = 0; idx < stops.length; idx++) {\n\t result.push(GradientStop.create(stops[idx]));\n\t }\n\n\t return result;\n\t },\n\n\t addStop: function(offset, color, opacity) {\n\t this.stops.push(new GradientStop(offset, color, opacity));\n\t },\n\n\t removeStop: function(stop) {\n\t var index = this.stops.indexOf(stop);\n\t if (index >= 0) {\n\t this.stops.splice(index, 1);\n\t }\n\t }\n\t});\n\n\tGradient.prototype.nodeType = \"Gradient\";\n\n\tObserversMixin.extend(Gradient.prototype);\n\n\t$.extend(Gradient.prototype, {\n\t optionsChange: function(e) {\n\t this.trigger(\"optionsChange\", {\n\t field: \"gradient\" + (e ? \".\" + e.field : \"\"),\n\t value: this\n\t });\n\t },\n\n\t geometryChange: function() {\n\t this.optionsChange();\n\t }\n\t});\n\n\tvar LinearGradient = Gradient.extend({\n\t init: function(options) {\n\t if (options === void 0) { options = {}; }\n\n\t Gradient.fn.init.call(this, options);\n\n\t this.start(options.start || new Point());\n\n\t this.end(options.end || new Point(1, 0));\n\t }\n\t});\n\n\tdefinePointAccessors(LinearGradient.prototype, [ \"start\", \"end\" ]);\n\n\tvar RadialGradient = Gradient.extend({\n\t init: function(options) {\n\t if (options === void 0) { options = {}; }\n\n\t Gradient.fn.init.call(this, options);\n\n\t this.center(options.center || new Point());\n\t this._radius = defined(options.radius) ? options.radius : 1;\n\t this._fallbackFill = options.fallbackFill;\n\t },\n\n\t radius: function(value) {\n\t if (defined(value)) {\n\t this._radius = value;\n\t this.geometryChange();\n\t return this;\n\t }\n\n\t return this._radius;\n\t },\n\n\t fallbackFill: function(value) {\n\t if (defined(value)) {\n\t this._fallbackFill = value;\n\t this.optionsChange();\n\t return this;\n\t }\n\n\t return this._fallbackFill;\n\t }\n\t});\n\n\tdefinePointAccessors(RadialGradient.prototype, [ \"center\" ]);\n\n\tfunction swing(position) {\n\t return 0.5 - Math.cos(position * Math.PI) / 2;\n\t}\n\n\tfunction linear(position) {\n\t return position;\n\t}\n\n\tfunction easeOutElastic(position, time, start, diff) {\n\t var s = 1.70158,\n\t p = 0,\n\t a = diff;\n\n\t if (position === 0) {\n\t return start;\n\t }\n\n\t if (position === 1) {\n\t return start + diff;\n\t }\n\n\t if (!p) {\n\t p = 0.5;\n\t }\n\n\t if (a < Math.abs(diff)) {\n\t a = diff;\n\t s = p / 4;\n\t } else {\n\t s = p / (2 * Math.PI) * Math.asin(diff / a);\n\t }\n\n\t return a * Math.pow(2, -10 * position) *\n\t Math.sin((Number(position) - s) * (1.1 * Math.PI) / p) + diff + start;\n\t}\n\n\tvar easingFunctions = {\n\t\tswing: swing,\n\t\tlinear: linear,\n\t\teaseOutElastic: easeOutElastic\n\t};\n\n\tvar AnimationFactory = Class.extend({\n\t init: function() {\n\n\t this._items = [];\n\t },\n\n\t register: function(name, type) {\n\t this._items.push({\n\t name: name,\n\t type: type\n\t });\n\t },\n\n\t create: function(element, options) {\n\t var items = this._items;\n\t var match;\n\n\t if (options && options.type) {\n\t var type = options.type.toLowerCase();\n\t for (var i = 0; i < items.length; i++) {\n\t if (items[i].name.toLowerCase() === type) {\n\t match = items[i];\n\t break;\n\t }\n\t }\n\t }\n\n\t if (match) {\n\t return new match.type(element, options);\n\t }\n\t }\n\t});\n\n\tAnimationFactory.current = new AnimationFactory();\n\n\tvar now = Date.now || function() {\n\t return new Date().getTime();\n\t};\n\n\tvar Animation = Class.extend({\n\t init: function(element, options) {\n\n\t this.options = $.extend({}, this.options, options);\n\t this.element = element;\n\t },\n\n\t setup: function() {},\n\n\t step: function() {},\n\n\t play: function() {\n\t var this$1 = this;\n\n\t var options = this.options;\n\t var duration = options.duration;\n\t var delay = options.delay; if (delay === void 0) { delay = 0; }\n\t var easing = easingFunctions[options.easing];\n\t var start = now() + delay;\n\t var finish = start + duration;\n\n\t if (duration === 0) {\n\t this.step(1);\n\t this.abort();\n\t } else {\n\t setTimeout(function () {\n\t var loop = function () {\n\t if (this$1._stopped) {\n\t return;\n\t }\n\n\t var wallTime = now();\n\n\t var time = limitValue(wallTime - start, 0, duration);\n\t var position = time / duration;\n\t var easingPosition = easing(position, time, 0, 1, duration);\n\n\t this$1.step(easingPosition);\n\n\t if (wallTime < finish) {\n\t kendo.animationFrame(loop);\n\t } else {\n\t this$1.abort();\n\t }\n\t };\n\n\t loop();\n\t }, delay);\n\t }\n\t },\n\n\t abort: function() {\n\t this._stopped = true;\n\t },\n\n\t destroy: function() {\n\t this.abort();\n\t }\n\t});\n\n\tAnimation.prototype.options = {\n\t duration: 500,\n\t easing: \"swing\"\n\t};\n\n\tAnimation.create = function(type, element, options) {\n\t return AnimationFactory.current.create(type, element, options);\n\t};\n\n\tvar SurfaceFactory = Class.extend({\n\t init: function() {\n\n\t this._items = [];\n\t },\n\n\t register: function(name, type, order) {\n\t var items = this._items;\n\t var first = items[0];\n\t var entry = {\n\t name: name,\n\t type: type,\n\t order: order\n\t };\n\n\t if (!first || order < first.order) {\n\t items.unshift(entry);\n\t } else {\n\t items.push(entry);\n\t }\n\t },\n\n\t create: function(element, options) {\n\t var items = this._items;\n\t var match = items[0];\n\n\t if (options && options.type) {\n\t var preferred = options.type.toLowerCase();\n\t for (var i = 0; i < items.length; i++) {\n\t if (items[i].name === preferred) {\n\t match = items[i];\n\t break;\n\t }\n\t }\n\t }\n\n\t if (match) {\n\t return new match.type(element, options);\n\t }\n\n\t kendo.logToConsole(\n\t \"Warning: Unable to create Kendo UI Drawing Surface. Possible causes:\\n\" +\n\t \"- The browser does not support SVG and Canvas. User agent: \" + (navigator.userAgent));\n\t }\n\t});\n\n\tSurfaceFactory.current = new SurfaceFactory();\n\n\tvar events = [\n\t \"click\",\n\t \"mouseenter\",\n\t \"mouseleave\",\n\t \"mousemove\",\n\t \"resize\"\n\t];\n\n\tvar Surface = kendo.Observable.extend({\n\t init: function(element, options) {\n\t kendo.Observable.fn.init.call(this);\n\n\t this.options = $.extend({}, options);\n\t this.element = element;\n\t this.element._kendoExportVisual = this.exportVisual.bind(this);\n\n\t this._click = this._handler(\"click\");\n\t this._mouseenter = this._handler(\"mouseenter\");\n\t this._mouseleave = this._handler(\"mouseleave\");\n\t this._mousemove = this._handler(\"mousemove\");\n\n\t this._visual = new Group();\n\n\t elementSize(element, this.options);\n\n\t this.bind(events, this.options);\n\n\t this._enableTracking();\n\t },\n\n\t draw: function(element) {\n\t this._visual.children.push(element);\n\t },\n\n\t clear: function() {\n\t this._visual.children = [];\n\t },\n\n\t destroy: function() {\n\t this._visual = null;\n\t this.element._kendoExportVisual = null;\n\t this.unbind();\n\t },\n\n\t eventTarget: function(e) {\n\t var this$1 = this;\n\n\t var domNode = eventElement(e);\n\t var node;\n\n\t while (!node && domNode) {\n\t node = domNode._kendoNode;\n\t if (domNode === this$1.element) {\n\t break;\n\t }\n\n\t domNode = domNode.parentElement;\n\t }\n\n\t if (node) {\n\t return node.srcElement;\n\t }\n\t },\n\n\t exportVisual: function() {\n\t return this._visual;\n\t },\n\n\t getSize: function() {\n\t return elementSize(this.element);\n\t },\n\n\t currentSize: function(size) {\n\t if (size) {\n\t this._size = size;\n\t } else {\n\t return this._size;\n\t }\n\t },\n\n\t setSize: function(size) {\n\t elementSize(this.element, size);\n\n\t this.currentSize(size);\n\t this._resize();\n\t },\n\n\t resize: function(force) {\n\t var size = this.getSize();\n\t var currentSize = this.currentSize();\n\n\t if (force || (size.width > 0 || size.height > 0) && (!currentSize || size.width !== currentSize.width || size.height !== currentSize.height)) {\n\t this.currentSize(size);\n\t this._resize(size, force);\n\t this.trigger(\"resize\", size);\n\t }\n\t },\n\n\t size: function(value) {\n\t if (!value) {\n\t return this.getSize();\n\t }\n\n\t this.setSize(value);\n\t },\n\n\t suspendTracking: function() {\n\t this._suspendedTracking = true;\n\t },\n\n\t resumeTracking: function() {\n\t this._suspendedTracking = false;\n\t },\n\n\t _enableTracking: function() {},\n\n\t _resize: function() {},\n\n\t _handler: function(eventName) {\n\t var this$1 = this;\n\n\t return function (e) {\n\t var node = this$1.eventTarget(e);\n\t if (node && !this$1._suspendedTracking) {\n\t this$1.trigger(eventName, {\n\t element: node,\n\t originalEvent: e,\n\t type: eventName\n\t });\n\t }\n\t };\n\t },\n\n\t _elementOffset: function() {\n\t var element = this.element;\n\t var ref = elementStyles(element, [ \"paddingLeft\", \"paddingTop\" ]);\n\t var paddingLeft = ref.paddingLeft;\n\t var paddingTop = ref.paddingTop;\n\t var ref$1 = elementOffset(element);\n\t var left = ref$1.left;\n\t var top = ref$1.top;\n\n\t return {\n\t left: left + parseInt(paddingLeft, 10),\n\t top: top + parseInt(paddingTop, 10)\n\t };\n\t },\n\n\t _surfacePoint: function(e) {\n\t var offset = this._elementOffset();\n\t var coord = eventCoordinates(e);\n\t var x = coord.x - offset.left;\n\t var y = coord.y - offset.top;\n\n\t return new Point(x, y);\n\t }\n\t});\n\n\tSurface.create = function(element, options) {\n\t return SurfaceFactory.current.create(element, options);\n\t};\n\n\tSurface.support = {};\n\n\tvar BaseNode = Class.extend({\n\t init: function(srcElement) {\n\n\t this.childNodes = [];\n\t this.parent = null;\n\n\t if (srcElement) {\n\t this.srcElement = srcElement;\n\t this.observe();\n\t }\n\t },\n\n\t destroy: function() {\n\t var this$1 = this;\n\n\t if (this.srcElement) {\n\t this.srcElement.removeObserver(this);\n\t }\n\n\t var children = this.childNodes;\n\t for (var i = 0; i < children.length; i++) {\n\t this$1.childNodes[i].destroy();\n\t }\n\n\t this.parent = null;\n\t },\n\n\t load: function() {},\n\n\t observe: function() {\n\t if (this.srcElement) {\n\t this.srcElement.addObserver(this);\n\t }\n\t },\n\n\t append: function(node) {\n\t this.childNodes.push(node);\n\t node.parent = this;\n\t },\n\n\t insertAt: function(node, pos) {\n\t this.childNodes.splice(pos, 0, node);\n\t node.parent = this;\n\t },\n\n\t remove: function(index, count) {\n\t var this$1 = this;\n\n\t var end = index + count;\n\t for (var i = index; i < end; i++) {\n\t this$1.childNodes[i].removeSelf();\n\t }\n\t this.childNodes.splice(index, count);\n\t },\n\n\t removeSelf: function() {\n\t this.clear();\n\t this.destroy();\n\t },\n\n\t clear: function() {\n\t this.remove(0, this.childNodes.length);\n\t },\n\n\t invalidate: function() {\n\t if (this.parent) {\n\t this.parent.invalidate();\n\t }\n\t },\n\n\t geometryChange: function() {\n\t this.invalidate();\n\t },\n\n\t optionsChange: function() {\n\t this.invalidate();\n\t },\n\n\t childrenChange: function(e) {\n\t if (e.action === \"add\") {\n\t this.load(e.items, e.index);\n\t } else if (e.action === \"remove\") {\n\t this.remove(e.index, e.items.length);\n\t }\n\n\t this.invalidate();\n\t }\n\t});\n\n\tfunction renderAttr(name, value) {\n\t return (defined(value) && value !== null) ? (\" \" + name + \"=\\\"\" + value + \"\\\" \") : \"\";\n\t}\n\n\tfunction renderAllAttr(attrs) {\n\t var output = \"\";\n\t for (var i = 0; i < attrs.length; i++) {\n\t output += renderAttr(attrs[i][0], attrs[i][1]);\n\t }\n\n\t return output;\n\t}\n\n\tfunction renderStyle(attrs) {\n\t var output = \"\";\n\t for (var i = 0; i < attrs.length; i++) {\n\t var value = attrs[i][1];\n\t if (defined(value)) {\n\t output += attrs[i][0] + \":\" + value + \";\";\n\t }\n\t }\n\n\t if (output !== \"\") {\n\t return output;\n\t }\n\t}\n\n\tvar NODE_MAP = {};\n\n\tvar SVG_NS = \"http://www.w3.org/2000/svg\";\n\tvar NONE = \"none\";\n\n\tvar renderSVG = function(container, svg) {\n\t container.innerHTML = svg;\n\t};\n\n\tif (typeof document !== \"undefined\") {\n\t var testFragment = \"\";\n\t var testContainer = document.createElement(\"div\");\n\t var hasParser = typeof DOMParser !== \"undefined\";\n\n\t testContainer.innerHTML = testFragment;\n\n\t if (hasParser && testContainer.firstChild.namespaceURI !== SVG_NS) {\n\t renderSVG = function(container, svg) {\n\t var parser = new DOMParser();\n\t var chartDoc = parser.parseFromString(svg, \"text/xml\");\n\t var importedDoc = document.adoptNode(chartDoc.documentElement);\n\n\t container.innerHTML = \"\";\n\t container.appendChild(importedDoc);\n\t };\n\t }\n\t}\n\n\tvar renderSVG$1 = renderSVG;\n\n\tvar TRANSFORM = \"transform\";\n\tvar DefinitionMap = {\n\t clip: \"clip-path\",\n\t fill: \"fill\"\n\t};\n\n\tfunction isDefinition(type, value) {\n\t return type === \"clip\" || (type === \"fill\" && (!value || value.nodeType === \"Gradient\"));\n\t}\n\n\tfunction baseUrl() {\n\t var base = document.getElementsByTagName(\"base\")[0];\n\t var href = document.location.href;\n\t var url = \"\";\n\n\t if (base && !(supportBrowser || {}).msie) {\n\t var hashIndex = href.indexOf(\"#\");\n\t if (hashIndex !== -1) {\n\t href = href.substring(0, hashIndex);\n\t }\n\n\t url = href;\n\t }\n\n\t return url;\n\t}\n\n\tvar Node = BaseNode.extend({\n\t init: function(srcElement, options) {\n\t BaseNode.fn.init.call(this, srcElement);\n\t this.definitions = {};\n\n\t this.options = options;\n\t },\n\n\t destroy: function() {\n\t if (this.element) {\n\t this.element._kendoNode = null;\n\t this.element = null;\n\t }\n\n\t this.clearDefinitions();\n\t BaseNode.fn.destroy.call(this);\n\t },\n\n\t load: function(elements, pos) {\n\t var this$1 = this;\n\n\t for (var i = 0; i < elements.length; i++) {\n\t var srcElement = elements[i];\n\t var children = srcElement.children;\n\n\t var childNode = new NODE_MAP[srcElement.nodeType](srcElement, this$1.options);\n\n\t if (defined(pos)) {\n\t this$1.insertAt(childNode, pos);\n\t } else {\n\t this$1.append(childNode);\n\t }\n\n\t childNode.createDefinitions();\n\n\t if (children && children.length > 0) {\n\t childNode.load(children);\n\t }\n\n\t var element = this$1.element;\n\t if (element) {\n\t childNode.attachTo(element, pos);\n\t }\n\t }\n\t },\n\n\t root: function() {\n\t var root = this;\n\n\t while (root.parent) {\n\t root = root.parent;\n\t }\n\n\t return root;\n\t },\n\n\t attachTo: function(domElement, pos) {\n\t var container = document.createElement(\"div\");\n\t renderSVG$1(container,\n\t \"\" +\n\t this.render() +\n\t \"\"\n\t );\n\n\t var element = container.firstChild.firstChild;\n\t if (element) {\n\t if (defined(pos)) {\n\t domElement.insertBefore(element, domElement.childNodes[pos] || null);\n\t } else {\n\t domElement.appendChild(element);\n\t }\n\t this.setElement(element);\n\t }\n\t },\n\n\t setElement: function(element) {\n\t if (this.element) {\n\t this.element._kendoNode = null;\n\t }\n\n\t this.element = element;\n\t this.element._kendoNode = this;\n\n\t var nodes = this.childNodes;\n\t for (var i = 0; i < nodes.length; i++) {\n\t var childElement = element.childNodes[i];\n\t nodes[i].setElement(childElement);\n\t }\n\t },\n\n\t clear: function() {\n\t this.clearDefinitions();\n\n\t if (this.element) {\n\t this.element.innerHTML = \"\";\n\t }\n\n\t var children = this.childNodes;\n\t for (var i = 0; i < children.length; i++) {\n\t children[i].destroy();\n\t }\n\n\t this.childNodes = [];\n\t },\n\n\t removeSelf: function() {\n\t if (this.element) {\n\t var parentNode = this.element.parentNode;\n\t if (parentNode) {\n\t parentNode.removeChild(this.element);\n\t }\n\t this.element = null;\n\t }\n\n\t BaseNode.fn.removeSelf.call(this);\n\t },\n\n\t template: function() {\n\t return this.renderChildren();\n\t },\n\n\t render: function() {\n\t return this.template();\n\t },\n\n\t renderChildren: function() {\n\t var nodes = this.childNodes;\n\t var output = \"\";\n\n\t for (var i = 0; i < nodes.length; i++) {\n\t output += nodes[i].render();\n\t }\n\n\t return output;\n\t },\n\n\t optionsChange: function(e) {\n\t var field = e.field;\n\t var value = e.value;\n\n\t if (field === \"visible\") {\n\t this.css(\"display\", value ? \"\" : NONE);\n\t } else if (DefinitionMap[field] && isDefinition(field, value)) {\n\t this.updateDefinition(field, value);\n\t } else if (field === \"opacity\") {\n\t this.attr(\"opacity\", value);\n\t } else if (field === \"cursor\") {\n\t this.css(\"cursor\", value);\n\t } else if (field === \"id\") {\n\t if (value) {\n\t this.attr(\"id\", value);\n\t } else {\n\t this.removeAttr(\"id\");\n\t }\n\t }\n\n\t BaseNode.fn.optionsChange.call(this, e);\n\t },\n\n\t attr: function(name, value) {\n\t if (this.element) {\n\t this.element.setAttribute(name, value);\n\t }\n\t },\n\n\t allAttr: function(attrs) {\n\t var this$1 = this;\n\n\t for (var i = 0; i < attrs.length; i++) {\n\t this$1.attr(attrs[i][0], attrs[i][1]);\n\t }\n\t },\n\n\t css: function(name, value) {\n\t if (this.element) {\n\t this.element.style[name] = value;\n\t }\n\t },\n\n\t allCss: function(styles) {\n\t var this$1 = this;\n\n\t for (var i = 0; i < styles.length; i++) {\n\t this$1.css(styles[i][0], styles[i][1]);\n\t }\n\t },\n\n\t removeAttr: function(name) {\n\t if (this.element) {\n\t this.element.removeAttribute(name);\n\t }\n\t },\n\n\t mapTransform: function(transform) {\n\t var attrs = [];\n\t if (transform) {\n\t attrs.push([\n\t TRANSFORM,\n\t \"matrix(\" + transform.matrix().toString(6) + \")\"\n\t ]);\n\t }\n\n\t return attrs;\n\t },\n\n\t renderTransform: function() {\n\t return renderAllAttr(\n\t this.mapTransform(this.srcElement.transform())\n\t );\n\t },\n\n\t transformChange: function(value) {\n\t if (value) {\n\t this.allAttr(this.mapTransform(value));\n\t } else {\n\t this.removeAttr(TRANSFORM);\n\t }\n\t },\n\n\t mapStyle: function() {\n\t var options = this.srcElement.options;\n\t var style = [ [ \"cursor\", options.cursor ] ];\n\n\t if (options.visible === false) {\n\t style.push([ \"display\", NONE ]);\n\t }\n\n\t return style;\n\t },\n\n\t renderStyle: function() {\n\t return renderAttr(\"style\", renderStyle(this.mapStyle(true)));\n\t },\n\n\t renderOpacity: function() {\n\t return renderAttr(\"opacity\", this.srcElement.options.opacity);\n\t },\n\n\t renderId: function() {\n\t return renderAttr(\"id\", this.srcElement.options.id);\n\t },\n\n\t createDefinitions: function() {\n\t var srcElement = this.srcElement;\n\t var definitions = this.definitions;\n\t if (srcElement) {\n\t var options = srcElement.options;\n\t var hasDefinitions;\n\n\t for (var field in DefinitionMap) {\n\t var definition = options.get(field);\n\t if (definition && isDefinition(field, definition)) {\n\t definitions[field] = definition;\n\t hasDefinitions = true;\n\t }\n\t }\n\t if (hasDefinitions) {\n\t this.definitionChange({\n\t action: \"add\",\n\t definitions: definitions\n\t });\n\t }\n\t }\n\t },\n\n\t definitionChange: function(e) {\n\t if (this.parent) {\n\t this.parent.definitionChange(e);\n\t }\n\t },\n\n\t updateDefinition: function(type, value) {\n\t var definitions = this.definitions;\n\t var current = definitions[type];\n\t var attr = DefinitionMap[type];\n\t var definition = {};\n\t if (current) {\n\t definition[type] = current;\n\t this.definitionChange({\n\t action: \"remove\",\n\t definitions: definition\n\t });\n\t delete definitions[type];\n\t }\n\n\t if (!value) {\n\t if (current) {\n\t this.removeAttr(attr);\n\t }\n\t } else {\n\t definition[type] = value;\n\t this.definitionChange({\n\t action: \"add\",\n\t definitions: definition\n\t });\n\t definitions[type] = value;\n\t this.attr(attr, this.refUrl(value.id));\n\t }\n\t },\n\n\t clearDefinitions: function() {\n\t var definitions = this.definitions;\n\n\t this.definitionChange({\n\t action: \"remove\",\n\t definitions: definitions\n\t });\n\t this.definitions = {};\n\t },\n\n\t renderDefinitions: function() {\n\t return renderAllAttr(this.mapDefinitions());\n\t },\n\n\t mapDefinitions: function() {\n\t var this$1 = this;\n\n\t var definitions = this.definitions;\n\t var attrs = [];\n\n\t for (var field in definitions) {\n\t attrs.push([ DefinitionMap[field], this$1.refUrl(definitions[field].id) ]);\n\t }\n\n\t return attrs;\n\t },\n\n\t refUrl: function(id) {\n\t var skipBaseHref = (this.options || {}).skipBaseHref;\n\t var baseHref = this.baseUrl().replace(/'/g, \"\\\\'\");\n\t var base = skipBaseHref ? '' : baseHref;\n\t return (\"url(\" + base + \"#\" + id + \")\");\n\t },\n\n\t baseUrl: function() {\n\t return baseUrl();\n\t }\n\t});\n\n\tvar GradientStopNode = Node.extend({\n\t template: function() {\n\t return (\"\");\n\t },\n\n\t renderOffset: function() {\n\t return renderAttr(\"offset\", this.srcElement.offset());\n\t },\n\n\t mapStyle: function() {\n\t var srcElement = this.srcElement;\n\t return [\n\t [ \"stop-color\", srcElement.color() ],\n\t [ \"stop-opacity\", srcElement.opacity() ]\n\t ];\n\t },\n\n\t optionsChange: function(e) {\n\t if (e.field === \"offset\") {\n\t this.attr(e.field, e.value);\n\t } else if (e.field === \"color\" || e.field === \"opacity\") {\n\t this.css(\"stop-\" + e.field, e.value);\n\t }\n\t }\n\t});\n\n\tvar GradientNode = Node.extend({\n\t init: function(srcElement) {\n\t Node.fn.init.call(this, srcElement);\n\n\t this.id = srcElement.id;\n\n\t this.loadStops();\n\t },\n\n\t loadStops: function() {\n\t var this$1 = this;\n\n\t var stops = this.srcElement.stops;\n\t var element = this.element;\n\n\t for (var idx = 0; idx < stops.length; idx++) {\n\t var stopNode = new GradientStopNode(stops[idx]);\n\t this$1.append(stopNode);\n\t if (element) {\n\t stopNode.attachTo(element);\n\t }\n\t }\n\t },\n\n\t optionsChange: function(e) {\n\t if (e.field === \"gradient.stops\") {\n\t BaseNode.prototype.clear.call(this);\n\t this.loadStops();\n\t } else if (e.field === \"gradient\") {\n\t this.allAttr(this.mapCoordinates());\n\t }\n\t },\n\n\t renderCoordinates: function() {\n\t return renderAllAttr(this.mapCoordinates());\n\t },\n\n\t mapSpace: function() {\n\t return [ \"gradientUnits\", this.srcElement.userSpace() ? \"userSpaceOnUse\" : \"objectBoundingBox\" ];\n\t }\n\t});\n\n\tvar LinearGradientNode = GradientNode.extend({\n\t template: function() {\n\t return (\"\" + (this.renderChildren()) + \"\");\n\t },\n\n\t mapCoordinates: function() {\n\t var srcElement = this.srcElement;\n\t var start = srcElement.start();\n\t var end = srcElement.end();\n\t var attrs = [\n\t [ \"x1\", start.x ],\n\t [ \"y1\", start.y ],\n\t [ \"x2\", end.x ],\n\t [ \"y2\", end.y ],\n\t this.mapSpace()\n\t ];\n\n\t return attrs;\n\t }\n\t});\n\n\tvar RadialGradientNode = GradientNode.extend({\n\t template: function() {\n\t return (\"\" + (this.renderChildren()) + \"\");\n\t },\n\n\t mapCoordinates: function() {\n\t var srcElement = this.srcElement;\n\t var center = srcElement.center();\n\t var radius = srcElement.radius();\n\t var attrs = [\n\t [ \"cx\", center.x ],\n\t [ \"cy\", center.y ],\n\t [ \"r\", radius ],\n\t this.mapSpace()\n\t ];\n\t return attrs;\n\t }\n\t});\n\n\tvar ClipNode = Node.extend({\n\t init: function(srcElement) {\n\t Node.fn.init.call(this);\n\n\t this.srcElement = srcElement;\n\t this.id = srcElement.id;\n\n\t this.load([ srcElement ]);\n\t },\n\n\t template: function() {\n\t return (\"\" + (this.renderChildren()) + \"\");\n\t }\n\t});\n\n\tvar DefinitionNode = Node.extend({\n\t init: function() {\n\t Node.fn.init.call(this);\n\t this.definitionMap = {};\n\t },\n\n\t attachTo: function(domElement) {\n\t this.element = domElement;\n\t },\n\n\t template: function() {\n\t return (\"\" + (this.renderChildren()) + \"\");\n\t },\n\n\t definitionChange: function(e) {\n\t var definitions = e.definitions;\n\t var action = e.action;\n\n\t if (action === \"add\") {\n\t this.addDefinitions(definitions);\n\t } else if (action === \"remove\") {\n\t this.removeDefinitions(definitions);\n\t }\n\t },\n\n\t createDefinition: function(type, item) {\n\t var nodeType;\n\t if (type === \"clip\") {\n\t nodeType = ClipNode;\n\t } else if (type === \"fill\") {\n\t if (item instanceof LinearGradient) {\n\t nodeType = LinearGradientNode;\n\t } else if (item instanceof RadialGradient) {\n\t nodeType = RadialGradientNode;\n\t }\n\t }\n\t return new nodeType(item);\n\t },\n\n\t addDefinitions: function(definitions) {\n\t var this$1 = this;\n\n\t for (var field in definitions) {\n\t this$1.addDefinition(field, definitions[field]);\n\t }\n\t },\n\n\t addDefinition: function(type, srcElement) {\n\t var ref = this;\n\t var element = ref.element;\n\t var definitionMap = ref.definitionMap;\n\t var id = srcElement.id;\n\t var mapItem = definitionMap[id];\n\t if (!mapItem) {\n\t var node = this.createDefinition(type, srcElement);\n\t definitionMap[id] = {\n\t element: node,\n\t count: 1\n\t };\n\t this.append(node);\n\t if (element) {\n\t node.attachTo(this.element);\n\t }\n\t } else {\n\t mapItem.count++;\n\t }\n\t },\n\n\t removeDefinitions: function(definitions) {\n\t var this$1 = this;\n\n\t for (var field in definitions) {\n\t this$1.removeDefinition(definitions[field]);\n\t }\n\t },\n\n\t removeDefinition: function(srcElement) {\n\t var definitionMap = this.definitionMap;\n\t var id = srcElement.id;\n\t var mapItem = definitionMap[id];\n\n\t if (mapItem) {\n\t mapItem.count--;\n\t if (mapItem.count === 0) {\n\t this.remove(this.childNodes.indexOf(mapItem.element), 1);\n\t delete definitionMap[id];\n\t }\n\t }\n\t }\n\t});\n\n\tvar RootNode = Node.extend({\n\t init: function(options) {\n\t Node.fn.init.call(this);\n\t this.options = options;\n\t this.defs = new DefinitionNode();\n\t },\n\n\t attachTo: function(domElement) {\n\t this.element = domElement;\n\t this.defs.attachTo(domElement.firstElementChild);\n\t },\n\n\t clear: function() {\n\t BaseNode.prototype.clear.call(this);\n\t },\n\n\t template: function() {\n\t return this.defs.render() + this.renderChildren();\n\t },\n\n\t definitionChange: function(e) {\n\t this.defs.definitionChange(e);\n\t }\n\t});\n\n\tvar RTL = 'rtl';\n\n\tfunction alignToScreen(element) {\n\t var ctm;\n\n\t try {\n\t ctm = element.getScreenCTM ? element.getScreenCTM() : null;\n\t } catch (e) { } // eslint-disable-line no-empty\n\n\t if (ctm) {\n\t var left = - ctm.e % 1;\n\t var top = - ctm.f % 1;\n\t var style = element.style;\n\n\t if (left !== 0 || top !== 0) {\n\t style.left = left + \"px\";\n\t style.top = top + \"px\";\n\t }\n\t }\n\t}\n\n\tvar Surface$1 = Surface.extend({\n\t init: function(element, options) {\n\t Surface.fn.init.call(this, element, options);\n\n\t this._root = new RootNode($.extend({\n\t rtl: elementStyles(element, 'direction').direction === RTL\n\t }, this.options));\n\n\t renderSVG$1(this.element, this._template());\n\n\t this._rootElement = this.element.firstElementChild;\n\n\t alignToScreen(this._rootElement);\n\n\t this._root.attachTo(this._rootElement);\n\n\t bindEvents(this.element, {\n\t click: this._click,\n\t mouseover: this._mouseenter,\n\t mouseout: this._mouseleave,\n\t mousemove: this._mousemove\n\t });\n\n\t this.resize();\n\t },\n\n\t destroy: function() {\n\t if (this._root) {\n\t this._root.destroy();\n\t this._root = null;\n\t this._rootElement = null;\n\t unbindEvents(this.element, {\n\t click: this._click,\n\t mouseover: this._mouseenter,\n\t mouseout: this._mouseleave,\n\t mousemove: this._mousemove\n\t });\n\t }\n\n\t Surface.fn.destroy.call(this);\n\t },\n\n\t translate: function(offset) {\n\t var viewBox = (Math.round(offset.x)) + \" \" + (Math.round(offset.y)) + \" \" + (this._size.width) + \" \" + (this._size.height);\n\n\t this._offset = offset;\n\t this._rootElement.setAttribute(\"viewBox\", viewBox);\n\t },\n\n\t draw: function(element) {\n\t Surface.fn.draw.call(this, element);\n\t this._root.load([ element ]);\n\t },\n\n\t clear: function() {\n\t Surface.fn.clear.call(this);\n\t this._root.clear();\n\t },\n\n\t svg: function() {\n\t return \"\" + this._template();\n\t },\n\n\t exportVisual: function() {\n\t var ref = this;\n\t var visual = ref._visual;\n\t var offset = ref._offset;\n\n\t if (offset) {\n\t var wrap = new Group();\n\t wrap.children.push(visual);\n\n\t wrap.transform(\n\t transform().translate(-offset.x, -offset.y)\n\t );\n\n\t visual = wrap;\n\t }\n\n\t return visual;\n\t },\n\n\t _resize: function() {\n\t if (this._offset) {\n\t this.translate(this._offset);\n\t }\n\t },\n\n\t _template: function() {\n\t return (\"\" + (this._root.render()) + \"\");\n\t }\n\t});\n\n\tSurface$1.prototype.type = \"svg\";\n\n\tif (typeof document !== \"undefined\" && document.implementation.hasFeature(\"http://www.w3.org/TR/SVG11/feature#BasicStructure\", \"1.1\")) {\n\t Surface.support.svg = true;\n\t SurfaceFactory.current.register(\"svg\", Surface$1, 10);\n\t}\n\n\tvar GroupNode = Node.extend({\n\t template: function() {\n\t return (\"\" + (this.renderChildren()) + \"\");\n\t },\n\n\t optionsChange: function(e) {\n\t if (e.field === \"transform\") {\n\t this.transformChange(e.value);\n\t }\n\n\t Node.fn.optionsChange.call(this, e);\n\t }\n\t});\n\n\tNODE_MAP.Group = GroupNode;\n\n\tvar DASH_ARRAYS = {\n\t dot: [ 1.5, 3.5 ],\n\t dash: [ 4, 3.5 ],\n\t longdash: [ 8, 3.5 ],\n\t dashdot: [ 3.5, 3.5, 1.5, 3.5 ],\n\t longdashdot: [ 8, 3.5, 1.5, 3.5 ],\n\t longdashdotdot: [ 8, 3.5, 1.5, 3.5, 1.5, 3.5 ]\n\t};\n\n\tvar SOLID = \"solid\";\n\tvar BUTT = \"butt\";\n\n\tvar ATTRIBUTE_MAP = {\n\t \"fill.opacity\": \"fill-opacity\",\n\t \"stroke.color\": \"stroke\",\n\t \"stroke.width\": \"stroke-width\",\n\t \"stroke.opacity\": \"stroke-opacity\"\n\t};\n\tvar SPACE = \" \";\n\n\tvar PathNode = Node.extend({\n\t geometryChange: function() {\n\t this.attr(\"d\", this.renderData());\n\t this.invalidate();\n\t },\n\n\t optionsChange: function(e) {\n\t switch (e.field) {\n\t case \"fill\":\n\t if (e.value) {\n\t this.allAttr(this.mapFill(e.value));\n\t } else {\n\t this.removeAttr(\"fill\");\n\t }\n\t break;\n\n\t case \"fill.color\":\n\t this.allAttr(this.mapFill({ color: e.value }));\n\t break;\n\n\t case \"stroke\":\n\t if (e.value) {\n\t this.allAttr(this.mapStroke(e.value));\n\t } else {\n\t this.removeAttr(\"stroke\");\n\t }\n\t break;\n\n\t case \"transform\":\n\t this.transformChange(e.value);\n\t break;\n\n\t default:\n\t var name = ATTRIBUTE_MAP[e.field];\n\t if (name) {\n\t this.attr(name, e.value);\n\t }\n\t break;\n\t }\n\n\t Node.fn.optionsChange.call(this, e);\n\t },\n\n\t content: function() {\n\t if (this.element) {\n\t this.element.textContent = this.srcElement.content();\n\t }\n\t },\n\n\t renderData: function() {\n\t return this.printPath(this.srcElement);\n\t },\n\n\t printPath: function(path) {\n\t var this$1 = this;\n\n\t var segments = path.segments;\n\t var length = segments.length;\n\t if (length > 0) {\n\t var parts = [];\n\t var output, currentType;\n\n\t for (var i = 1; i < length; i++) {\n\t var segmentType = this$1.segmentType(segments[i - 1], segments[i]);\n\t if (segmentType !== currentType) {\n\t currentType = segmentType;\n\t parts.push(segmentType);\n\t }\n\n\t if (segmentType === \"L\") {\n\t parts.push(this$1.printPoints(segments[i].anchor()));\n\t } else {\n\t parts.push(this$1.printPoints(segments[i - 1].controlOut(), segments[i].controlIn(), segments[i].anchor()));\n\t }\n\t }\n\n\t output = \"M\" + this.printPoints(segments[0].anchor()) + SPACE + parts.join(SPACE);\n\t if (path.options.closed) {\n\t output += \"Z\";\n\t }\n\n\t return output;\n\t }\n\t },\n\n\t printPoints: function() {\n\t var points = arguments;\n\t var length = points.length;\n\t var result = [];\n\n\t for (var i = 0; i < length; i++) {\n\t result.push(points[i].toString(3));\n\t }\n\n\t return result.join(\" \");\n\t },\n\n\t segmentType: function(segmentStart, segmentEnd) {\n\t return segmentStart.controlOut() && segmentEnd.controlIn() ? \"C\" : \"L\";\n\t },\n\n\t mapStroke: function(stroke) {\n\t var attrs = [];\n\n\t if (stroke && !isTransparent(stroke.color)) {\n\t attrs.push([ \"stroke\", stroke.color ]);\n\t attrs.push([ \"stroke-width\", stroke.width ]);\n\t attrs.push([ \"stroke-linecap\", this.renderLinecap(stroke) ]);\n\t attrs.push([ \"stroke-linejoin\", stroke.lineJoin ]);\n\n\t if (defined(stroke.opacity)) {\n\t attrs.push([ \"stroke-opacity\", stroke.opacity ]);\n\t }\n\n\t if (defined(stroke.dashType)) {\n\t attrs.push([ \"stroke-dasharray\", this.renderDashType(stroke) ]);\n\t }\n\t } else {\n\t attrs.push([ \"stroke\", NONE ]);\n\t }\n\n\t return attrs;\n\t },\n\n\t renderStroke: function() {\n\t return renderAllAttr(\n\t this.mapStroke(this.srcElement.options.stroke)\n\t );\n\t },\n\n\t renderDashType: function(stroke) {\n\t var dashType = stroke.dashType;\n\t var width = stroke.width; if (width === void 0) { width = 1; }\n\n\t if (dashType && dashType !== SOLID) {\n\t var dashArray = DASH_ARRAYS[dashType.toLowerCase()];\n\t var result = [];\n\n\t for (var i = 0; i < dashArray.length; i++) {\n\t result.push(dashArray[i] * width);\n\t }\n\n\t return result.join(\" \");\n\t }\n\t },\n\n\t renderLinecap: function(stroke) {\n\t var dashType = stroke.dashType;\n\t var lineCap = stroke.lineCap;\n\n\t return (dashType && dashType !== \"solid\") ? BUTT : lineCap;\n\t },\n\n\t mapFill: function(fill) {\n\t var attrs = [];\n\t if (!(fill && fill.nodeType === \"Gradient\")) {\n\t if (fill && !isTransparent(fill.color)) {\n\t attrs.push([ \"fill\", fill.color ]);\n\n\t if (defined(fill.opacity)) {\n\t attrs.push([ \"fill-opacity\", fill.opacity ]);\n\t }\n\t } else {\n\t attrs.push([ \"fill\", NONE ]);\n\t }\n\t }\n\n\t return attrs;\n\t },\n\n\t renderFill: function() {\n\t return renderAllAttr(\n\t this.mapFill(this.srcElement.options.fill)\n\t );\n\t },\n\n\t template: function() {\n\t return \"\";\n\t }\n\t});\n\n\tNODE_MAP.Path = PathNode;\n\n\tvar ArcNode = PathNode.extend({\n\t renderData: function() {\n\t return this.printPath(this.srcElement.toPath());\n\t }\n\t});\n\n\tNODE_MAP.Arc = ArcNode;\n\n\tvar CircleNode = PathNode.extend({\n\t geometryChange: function() {\n\t var center = this.center();\n\t this.attr(\"cx\", center.x);\n\t this.attr(\"cy\", center.y);\n\t this.attr(\"r\", this.radius());\n\t this.invalidate();\n\t },\n\n\t center: function() {\n\t return this.srcElement.geometry().center;\n\t },\n\n\t radius: function() {\n\t return this.srcElement.geometry().radius;\n\t },\n\n\t template: function() {\n\t return \"\";\n\t }\n\t});\n\n\tNODE_MAP.Circle = CircleNode;\n\n\tvar RectNode = PathNode.extend({\n\t geometryChange: function() {\n\t var geometry = this.srcElement.geometry();\n\t this.attr(\"x\", geometry.origin.x);\n\t this.attr(\"y\", geometry.origin.y);\n\t this.attr(\"width\", geometry.size.width);\n\t this.attr(\"height\", geometry.size.height);\n\t this.invalidate();\n\t },\n\n\t size: function() {\n\t return this.srcElement.geometry().size;\n\t },\n\n\t origin: function() {\n\t return this.srcElement.geometry().origin;\n\t },\n\n\t template: function() {\n\t return \"\";\n\t }\n\t});\n\n\tNODE_MAP.Rect = RectNode;\n\n\tvar ImageNode = PathNode.extend({\n\t geometryChange: function() {\n\t this.allAttr(this.mapPosition());\n\t this.invalidate();\n\t },\n\n\t optionsChange: function(e) {\n\t if (e.field === \"src\") {\n\t this.allAttr(this.mapSource());\n\t }\n\n\t PathNode.fn.optionsChange.call(this, e);\n\t },\n\n\t mapPosition: function() {\n\t var rect = this.srcElement.rect();\n\t var tl = rect.topLeft();\n\n\t return [\n\t [ \"x\", tl.x ],\n\t [ \"y\", tl.y ],\n\t [ \"width\", rect.width() + \"px\" ],\n\t [ \"height\", rect.height() + \"px\" ]\n\t ];\n\t },\n\n\t renderPosition: function() {\n\t return renderAllAttr(this.mapPosition());\n\t },\n\n\t mapSource: function(encode) {\n\t var src = this.srcElement.src();\n\n\t if (encode) {\n\t src = kendo.htmlEncode(src);\n\t }\n\n\t return [ [ \"xlink:href\", src ] ];\n\t },\n\n\t renderSource: function() {\n\t return renderAllAttr(this.mapSource(true));\n\t },\n\n\t template: function() {\n\t return \"\" +\n\t \"\";\n\t }\n\t});\n\n\tNODE_MAP.Image = ImageNode;\n\n\tvar ENTITY_REGEX = /&(?:[a-zA-Z]+|#\\d+);/g;\n\n\tfunction decodeEntities(text) {\n\t if (!text || typeof text !== \"string\" || !ENTITY_REGEX.test(text)) {\n\t return text;\n\t }\n\n\t var element = decodeEntities._element;\n\t ENTITY_REGEX.lastIndex = 0;\n\n\t return text.replace(ENTITY_REGEX, function (match) {\n\t element.innerHTML = match;\n\n\t return element.textContent || element.innerText;\n\t });\n\t}\n\n\tif (typeof document !== \"undefined\") {\n\t decodeEntities._element = document.createElement(\"span\");\n\t}\n\n\tvar TextNode = PathNode.extend({\n\t geometryChange: function() {\n\t var pos = this.pos();\n\t this.attr(\"x\", pos.x);\n\t this.attr(\"y\", pos.y);\n\t this.invalidate();\n\t },\n\n\t optionsChange: function(e) {\n\t if (e.field === \"font\") {\n\t this.attr(\"style\", renderStyle(this.mapStyle()));\n\t this.geometryChange();\n\t } else if (e.field === \"content\") {\n\t PathNode.fn.content.call(this, this.srcElement.content());\n\t }\n\n\t PathNode.fn.optionsChange.call(this, e);\n\t },\n\n\t mapStyle: function(encode) {\n\t var style = PathNode.fn.mapStyle.call(this, encode);\n\t var font = this.srcElement.options.font;\n\n\t if (encode) {\n\t font = kendo.htmlEncode(font);\n\t }\n\n\t style.push([ \"font\", font ], [ \"white-space\", \"pre\" ]);\n\n\t return style;\n\t },\n\n\t pos: function() {\n\t var pos = this.srcElement.position();\n\t var size = this.srcElement.measure();\n\t return pos.clone().setY(pos.y + size.baseline);\n\t },\n\n\t renderContent: function() {\n\t var content = this.srcElement.content();\n\t content = decodeEntities(content);\n\t content = kendo.htmlEncode(content);\n\n\t return kendoUtil.normalizeText(content);\n\t },\n\n\t renderTextAnchor: function() {\n\t var anchor;\n\n\t if ((this.options || {}).rtl && !(supportBrowser.msie || supportBrowser.edge)) {\n\t anchor = 'end';\n\t }\n\n\t return renderAttr(\"text-anchor\", anchor);\n\t },\n\n\t template: function() {\n\t return \"\" + (this.renderContent()) + \"\";\n\t }\n\t});\n\n\tNODE_MAP.Text = TextNode;\n\n\tvar MultiPathNode = PathNode.extend({\n\t renderData: function() {\n\t var this$1 = this;\n\n\t var paths = this.srcElement.paths;\n\n\t if (paths.length > 0) {\n\t var result = [];\n\n\t for (var i = 0; i < paths.length; i++) {\n\t result.push(this$1.printPath(paths[i]));\n\t }\n\n\t return result.join(\" \");\n\t }\n\t }\n\t});\n\n\tNODE_MAP.MultiPath = MultiPathNode;\n\n\tvar geometry = {\n\t\tCircle: Circle$2,\n\t\tArc: Arc$2,\n\t\tRect: Rect,\n\t\tPoint: Point,\n\t\tSegment: Segment,\n\t\tMatrix: Matrix,\n\t\tSize: Size,\n\t\ttoMatrix: toMatrix,\n\t\tTransformation: Transformation,\n\t\ttransform: transform\n\t};\n\n\tfunction exportGroup(group) {\n\t var root = new RootNode({\n\t skipBaseHref: true\n\t });\n\t var bbox = group.clippedBBox();\n\t var rootGroup = group;\n\n\t if (bbox) {\n\t var origin = bbox.getOrigin();\n\t var exportRoot = new Group();\n\t exportRoot.transform(transform().translate(-origin.x, -origin.y));\n\t exportRoot.children.push(group);\n\t rootGroup = exportRoot;\n\t }\n\n\t root.load([ rootGroup ]);\n\n\t var svg = \"\" + (root.render()) + \"\";\n\n\t root.destroy();\n\n\t return svg;\n\t}\n\n\tvar svg = {\n\t\tSurface: Surface$1,\n\t\tRootNode: RootNode,\n\t\tNode: Node,\n\t\tGroupNode: GroupNode,\n\t\tArcNode: ArcNode,\n\t\tCircleNode: CircleNode,\n\t\tRectNode: RectNode,\n\t\tImageNode: ImageNode,\n\t\tTextNode: TextNode,\n\t\tPathNode: PathNode,\n\t\tMultiPathNode: MultiPathNode,\n\t\tDefinitionNode: DefinitionNode,\n\t\tClipNode: ClipNode,\n\t\tGradientStopNode: GradientStopNode,\n\t\tLinearGradientNode: LinearGradientNode,\n\t\tRadialGradientNode: RadialGradientNode,\n\t\texportGroup: exportGroup\n\t};\n\n\tvar NODE_MAP$2 = {};\n\n\tfunction renderPath(ctx, path) {\n\t var segments = path.segments;\n\n\t if (segments.length === 0) {\n\t return;\n\t }\n\n\t var segment = segments[0];\n\t var anchor = segment.anchor();\n\t ctx.moveTo(anchor.x, anchor.y);\n\n\t for (var i = 1; i < segments.length; i++) {\n\t segment = segments[i];\n\t anchor = segment.anchor();\n\n\t var prevSeg = segments[i - 1];\n\t var prevOut = prevSeg.controlOut();\n\t var controlIn = segment.controlIn();\n\n\t if (prevOut && controlIn) {\n\t ctx.bezierCurveTo(prevOut.x, prevOut.y,\n\t controlIn.x, controlIn.y,\n\t anchor.x, anchor.y);\n\t } else {\n\t ctx.lineTo(anchor.x, anchor.y);\n\t }\n\t }\n\n\t if (path.options.closed) {\n\t ctx.closePath();\n\t }\n\t}\n\n\tvar Node$2 = BaseNode.extend({\n\t init: function(srcElement) {\n\t BaseNode.fn.init.call(this, srcElement);\n\t if (srcElement) {\n\t this.initClip();\n\t }\n\t },\n\n\t initClip: function() {\n\t var clip = this.srcElement.clip();\n\t if (clip) {\n\t this.clip = clip;\n\t clip.addObserver(this);\n\t }\n\t },\n\n\t clear: function() {\n\t if (this.srcElement) {\n\t this.srcElement.removeObserver(this);\n\t }\n\n\t this.clearClip();\n\n\t BaseNode.fn.clear.call(this);\n\t },\n\n\t clearClip: function() {\n\t if (this.clip) {\n\t this.clip.removeObserver(this);\n\t delete this.clip;\n\t }\n\t },\n\n\t setClip: function(ctx) {\n\t if (this.clip) {\n\t ctx.beginPath();\n\t renderPath(ctx, this.clip);\n\t ctx.clip();\n\t }\n\t },\n\n\t optionsChange: function(e) {\n\t if (e.field === \"clip\") {\n\t this.clearClip();\n\t this.initClip();\n\t }\n\n\t BaseNode.fn.optionsChange.call(this, e);\n\t },\n\n\t setTransform: function(ctx) {\n\t if (this.srcElement) {\n\t var transform = this.srcElement.transform();\n\t if (transform) {\n\t ctx.transform.apply(ctx, transform.matrix().toArray(6));\n\t }\n\t }\n\t },\n\n\t loadElements: function(elements, pos, cors) {\n\t var this$1 = this;\n\n\t for (var i = 0; i < elements.length; i++) {\n\t var srcElement = elements[i];\n\t var children = srcElement.children;\n\n\t var childNode = new NODE_MAP$2[srcElement.nodeType](srcElement, cors);\n\n\t if (children && children.length > 0) {\n\t childNode.load(children, pos, cors);\n\t }\n\n\t if (defined(pos)) {\n\t this$1.insertAt(childNode, pos);\n\t } else {\n\t this$1.append(childNode);\n\t }\n\t }\n\t },\n\n\t load: function(elements, pos, cors) {\n\t this.loadElements(elements, pos, cors);\n\n\t this.invalidate();\n\t },\n\n\t setOpacity: function(ctx) {\n\t if (this.srcElement) {\n\t var opacity = this.srcElement.opacity();\n\t if (defined(opacity)) {\n\t this.globalAlpha(ctx, opacity);\n\t }\n\t }\n\t },\n\n\t globalAlpha: function(ctx, value) {\n\t var opactity = value;\n\t if (opactity && ctx.globalAlpha) {\n\t opactity *= ctx.globalAlpha;\n\t }\n\t ctx.globalAlpha = opactity;\n\t },\n\n\t visible: function() {\n\t var src = this.srcElement;\n\t return !src || (src && src.options.visible !== false);\n\t }\n\t});\n\n\tvar GroupNode$2 = Node$2.extend({\n\t renderTo: function(ctx) {\n\t if (!this.visible()) {\n\t return;\n\t }\n\n\t ctx.save();\n\n\t this.setTransform(ctx);\n\t this.setClip(ctx);\n\t this.setOpacity(ctx);\n\n\t var childNodes = this.childNodes;\n\t for (var i = 0; i < childNodes.length; i++) {\n\t var child = childNodes[i];\n\t if (child.visible()) {\n\t child.renderTo(ctx);\n\t }\n\t }\n\n\t ctx.restore();\n\t }\n\t});\n\n\tTraversable.extend(GroupNode$2.prototype, \"childNodes\");\n\n\tNODE_MAP$2.Group = GroupNode$2;\n\n\tvar FRAME_DELAY = 1000 / 60;\n\n\tvar RootNode$2 = GroupNode$2.extend({\n\t init: function(canvas, size) {\n\t GroupNode$2.fn.init.call(this);\n\n\t this.canvas = canvas;\n\t this.size = size;\n\t this.ctx = canvas.getContext(\"2d\");\n\n\t var invalidateHandler = this._invalidate.bind(this);\n\t this.invalidate = kendo.throttle(function () {\n\t kendo.animationFrame(invalidateHandler);\n\t }, FRAME_DELAY);\n\t },\n\n\t destroy: function() {\n\t GroupNode$2.fn.destroy.call(this);\n\t this.canvas = null;\n\t this.ctx = null;\n\t },\n\n\t load: function(elements, pos, cors) {\n\t this.loadElements(elements, pos, cors);\n\t this._invalidate();\n\t },\n\n\t _rescale: function() {\n\t var ref = this;\n\t var canvas = ref.canvas;\n\t var size = ref.size;\n\t var scale = 1;\n\n\t if (typeof window.devicePixelRatio === 'number') {\n\t scale = window.devicePixelRatio;\n\t }\n\n\t canvas.width = size.width * scale;\n\t canvas.height = size.height * scale;\n\t this.ctx.scale(scale, scale);\n\t },\n\n\t _invalidate: function() {\n\t if (!this.ctx) {\n\t return;\n\t }\n\n\t this._rescale();\n\n\t this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\t this.renderTo(this.ctx);\n\t }\n\t});\n\n\tTraversable.extend(RootNode$2.prototype, \"childNodes\");\n\n\tvar QuadRoot = Class.extend({\n\t init: function() {\n\n\t this.shapes = [];\n\t },\n\n\t _add: function(shape, bbox) {\n\t this.shapes.push({\n\t bbox: bbox,\n\t shape: shape\n\t });\n\t shape._quadNode = this;\n\t },\n\n\t pointShapes: function(point) {\n\t var shapes = this.shapes;\n\t var length = shapes.length;\n\t var result = [];\n\t for (var idx = 0; idx < length; idx++) {\n\t if (shapes[idx].bbox.containsPoint(point)) {\n\t result.push(shapes[idx].shape);\n\t }\n\t }\n\t return result;\n\t },\n\n\t insert: function(shape, bbox) {\n\t this._add(shape, bbox);\n\t },\n\n\t remove: function(shape) {\n\t var shapes = this.shapes;\n\t var length = shapes.length;\n\n\t for (var idx = 0; idx < length; idx++) {\n\t if (shapes[idx].shape === shape) {\n\t shapes.splice(idx, 1);\n\t break;\n\t }\n\t }\n\t }\n\t});\n\n\tvar QuadNode = QuadRoot.extend({\n\t init: function(rect) {\n\t QuadRoot.fn.init.call(this);\n\t this.children = [];\n\t this.rect = rect;\n\t },\n\n\t inBounds: function(rect) {\n\t var nodeRect = this.rect;\n\t var nodeBottomRight = nodeRect.bottomRight();\n\t var bottomRight = rect.bottomRight();\n\t var inBounds = nodeRect.origin.x <= rect.origin.x && nodeRect.origin.y <= rect.origin.y && bottomRight.x <= nodeBottomRight.x &&\n\t bottomRight.y <= nodeBottomRight.y;\n\t return inBounds;\n\t },\n\n\t pointShapes: function(point) {\n\t var children = this.children;\n\t var length = children.length;\n\t var result = QuadRoot.fn.pointShapes.call(this, point);\n\t for (var idx = 0; idx < length; idx++) {\n\t append(result, children[idx].pointShapes(point));\n\t }\n\t return result;\n\t },\n\n\t insert: function(shape, bbox) {\n\t var children = this.children;\n\t var inserted = false;\n\n\t if (this.inBounds(bbox)) {\n\t if (this.shapes.length < 4) {\n\t this._add(shape, bbox);\n\t } else {\n\t if (!children.length) {\n\t this._initChildren();\n\t }\n\n\t for (var idx = 0; idx < children.length; idx++) {\n\t if (children[idx].insert(shape, bbox)) {\n\t inserted = true;\n\t break;\n\t }\n\t }\n\n\t if (!inserted) {\n\t this._add(shape, bbox);\n\t }\n\t }\n\t inserted = true;\n\t }\n\n\t return inserted;\n\t },\n\n\t _initChildren: function() {\n\t var ref = this;\n\t var rect = ref.rect;\n\t var children = ref.children;\n\t var center = rect.center();\n\t var halfWidth = rect.width() / 2;\n\t var halfHeight = rect.height() / 2;\n\n\t children.push(\n\t new QuadNode(new Rect([ rect.origin.x, rect.origin.y ], [ halfWidth, halfHeight ])),\n\t new QuadNode(new Rect([ center.x, rect.origin.y ], [ halfWidth, halfHeight ])),\n\t new QuadNode(new Rect([ rect.origin.x, center.y ], [ halfWidth, halfHeight ])),\n\t new QuadNode(new Rect([ center.x, center.y ], [ halfWidth, halfHeight ]))\n\t );\n\t }\n\t});\n\n\tvar ROOT_SIZE = 3000;\n\tvar LEVEL_STEP = 10000;\n\tvar MAX_LEVEL = 75;\n\n\tvar ShapesQuadTree = Class.extend({\n\t init: function() {\n\n\t this.initRoots();\n\t },\n\n\t initRoots: function() {\n\t this.rootMap = {};\n\t this.root = new QuadRoot();\n\t this.rootElements = [];\n\t },\n\n\t clear: function() {\n\t var this$1 = this;\n\n\t var rootElements = this.rootElements;\n\t for (var idx = 0; idx < rootElements.length; idx++) {\n\t this$1.remove(rootElements[idx]);\n\t }\n\t this.initRoots();\n\t },\n\n\t pointShape: function(point) {\n\t var sectorRoot = ( this.rootMap[ Math.floor( point.x / ROOT_SIZE ) ] || {} )[ Math.floor( point.y / ROOT_SIZE ) ];\n\t var result = this.root.pointShapes(point);\n\n\t if (sectorRoot) {\n\t result = result.concat(sectorRoot.pointShapes(point));\n\t }\n\n\t this.assignZindex(result);\n\n\t result.sort(zIndexComparer);\n\t for (var idx = 0; idx < result.length; idx++) {\n\t if (result[idx].containsPoint(point)) {\n\t return result[idx];\n\t }\n\t }\n\t },\n\n\t assignZindex: function(elements) {\n\t var this$1 = this;\n\n\t for (var idx = 0; idx < elements.length; idx++) {\n\t var element = elements[idx];\n\t var zIndex = 0;\n\t var levelWeight = Math.pow(LEVEL_STEP, MAX_LEVEL);\n\t var parents = [];\n\n\t while (element) {\n\t parents.push(element);\n\t element = element.parent;\n\t }\n\n\t while (parents.length) {\n\t element = parents.pop();\n\t zIndex += ((element.parent ? element.parent.children : this$1.rootElements).indexOf(element) + 1) * levelWeight;\n\t levelWeight /= LEVEL_STEP;\n\t }\n\n\t elements[idx]._zIndex = zIndex;\n\t }\n\t },\n\n\t optionsChange: function(e) {\n\t if (e.field === \"transform\" || e.field === \"stroke.width\") {\n\t this.bboxChange(e.element);\n\t }\n\t },\n\n\t geometryChange: function(e) {\n\t this.bboxChange(e.element);\n\t },\n\n\t bboxChange: function(element) {\n\t var this$1 = this;\n\n\t if (element.nodeType === \"Group\") {\n\t for (var idx = 0; idx < element.children.length; idx++) {\n\t this$1.bboxChange(element.children[idx]);\n\t }\n\t } else {\n\t if (element._quadNode) {\n\t element._quadNode.remove(element);\n\t }\n\t this._insertShape(element);\n\t }\n\t },\n\n\t add: function(elements) {\n\t var elementsArray = Array.isArray(elements) ? elements.slice(0) : [ elements ];\n\n\t append(this.rootElements, elementsArray);\n\t this._insert(elementsArray);\n\t },\n\n\t childrenChange: function(e) {\n\t var this$1 = this;\n\n\t if (e.action === \"remove\") {\n\t for (var idx = 0; idx < e.items.length; idx++) {\n\t this$1.remove(e.items[idx]);\n\t }\n\t } else {\n\t this._insert(Array.prototype.slice.call(e.items, 0));\n\t }\n\t },\n\n\t _insert: function(elements) {\n\t var this$1 = this;\n\n\t var element;\n\n\t while (elements.length > 0) {\n\t element = elements.pop();\n\t element.addObserver(this$1);\n\t if (element.nodeType === \"Group\") {\n\t append(elements, element.children);\n\t } else {\n\t this$1._insertShape(element);\n\t }\n\t }\n\t },\n\n\t _insertShape: function(shape) {\n\t var bbox = shape.bbox();\n\t if (bbox) {\n\t var sectors = this.getSectors(bbox);\n\t var x = sectors[0][0];\n\t var y = sectors[1][0];\n\n\t if (this.inRoot(sectors)) {\n\t this.root.insert(shape, bbox);\n\t } else {\n\t var rootMap = this.rootMap;\n\t if (!rootMap[x]) {\n\t rootMap[x] = {};\n\t }\n\n\t if (!rootMap[x][y]) {\n\t rootMap[x][y] = new QuadNode(\n\t new Rect([ x * ROOT_SIZE, y * ROOT_SIZE ], [ ROOT_SIZE, ROOT_SIZE ])\n\t );\n\t }\n\n\t rootMap[x][y].insert(shape, bbox);\n\t }\n\t }\n\t },\n\n\t remove: function(element) {\n\t var this$1 = this;\n\n\t element.removeObserver(this);\n\n\t if (element.nodeType === \"Group\") {\n\t var children = element.children;\n\t for (var idx = 0; idx < children.length; idx++) {\n\t this$1.remove(children[idx]);\n\t }\n\t } else if (element._quadNode) {\n\t element._quadNode.remove(element);\n\t delete element._quadNode;\n\t }\n\t },\n\n\t inRoot: function(sectors) {\n\t return sectors[0].length > 1 || sectors[1].length > 1;\n\t },\n\n\t getSectors: function(rect) {\n\t var bottomRight = rect.bottomRight();\n\t var bottomX = Math.floor(bottomRight.x / ROOT_SIZE);\n\t var bottomY = Math.floor(bottomRight.y / ROOT_SIZE);\n\t var sectors = [ [], [] ];\n\t for (var x = Math.floor(rect.origin.x / ROOT_SIZE); x <= bottomX; x++) {\n\t sectors[0].push(x);\n\t }\n\t for (var y = Math.floor(rect.origin.y / ROOT_SIZE); y <= bottomY; y++) {\n\t sectors[1].push(y);\n\t }\n\t return sectors;\n\t }\n\t});\n\n\tfunction zIndexComparer(x1, x2) {\n\t if (x1._zIndex < x2._zIndex) {\n\t return 1;\n\t }\n\t if (x1._zIndex > x2._zIndex) {\n\t return -1;\n\t }\n\n\t return 0;\n\t}\n\n\tvar SurfaceCursor = Class.extend({\n\t init: function(surface) {\n\t surface.bind(\"mouseenter\", this._mouseenter.bind(this));\n\t surface.bind(\"mouseleave\", this._mouseleave.bind(this));\n\n\t this.element = surface.element;\n\t },\n\n\t clear: function() {\n\t this._resetCursor();\n\t },\n\n\t destroy: function() {\n\t this._resetCursor();\n\t delete this.element;\n\t },\n\n\t _mouseenter: function(e) {\n\t var cursor = this._shapeCursor(e);\n\n\t if (!cursor) {\n\t this._resetCursor();\n\t } else {\n\t if (!this._current) {\n\t this._defaultCursor = this._getCursor();\n\t }\n\n\t this._setCursor(cursor);\n\t }\n\t },\n\n\t _mouseleave: function() {\n\t this._resetCursor();\n\t },\n\n\t _shapeCursor: function(e) {\n\t var shape = e.element;\n\n\t while (shape && !defined(shape.options.cursor)) {\n\t shape = shape.parent;\n\t }\n\n\t if (shape) {\n\t return shape.options.cursor;\n\t }\n\t },\n\n\t _getCursor: function() {\n\t if (this.element) {\n\t return this.element.style.cursor;\n\t }\n\t },\n\n\t _setCursor: function(cursor) {\n\t if (this.element) {\n\t this.element.style.cursor = cursor;\n\t this._current = cursor;\n\t }\n\t },\n\n\t _resetCursor: function() {\n\t if (this._current) {\n\t this._setCursor(this._defaultCursor || \"\");\n\t delete this._current;\n\t }\n\t }\n\t});\n\n\tvar Surface$3 = Surface.extend({\n\t init: function(element, options) {\n\t Surface.fn.init.call(this, element, options);\n\n\t this.element.innerHTML = this._template(this);\n\n\t var canvas = this.element.firstElementChild;\n\t var size = elementSize(element);\n\n\t canvas.width = size.width;\n\t canvas.height = size.height;\n\n\t this._rootElement = canvas;\n\n\t this._root = new RootNode$2(canvas, size);\n\n\t this._mouseTrackHandler = this._trackMouse.bind(this);\n\n\t bindEvents(this.element, {\n\t click: this._mouseTrackHandler,\n\t mousemove: this._mouseTrackHandler\n\t });\n\t },\n\n\t destroy: function() {\n\t Surface.fn.destroy.call(this);\n\n\t if (this._root) {\n\t this._root.destroy();\n\t this._root = null;\n\t }\n\n\t if (this._searchTree) {\n\t this._searchTree.clear();\n\t delete this._searchTree;\n\t }\n\n\t if (this._cursor) {\n\t this._cursor.destroy();\n\t delete this._cursor;\n\t }\n\n\t unbindEvents(this.element, {\n\t click: this._mouseTrackHandler,\n\t mousemove: this._mouseTrackHandler\n\t });\n\t },\n\n\t draw: function(element) {\n\t Surface.fn.draw.call(this, element);\n\t this._root.load([ element ], undefined, this.options.cors);\n\n\t if (this._searchTree) {\n\t this._searchTree.add([ element ]);\n\t }\n\t },\n\n\t clear: function() {\n\t Surface.fn.clear.call(this);\n\t this._root.clear();\n\n\t if (this._searchTree) {\n\t this._searchTree.clear();\n\t }\n\n\t if (this._cursor) {\n\t this._cursor.clear();\n\t }\n\t },\n\n\t eventTarget: function(e) {\n\t if (this._searchTree) {\n\t var point = this._surfacePoint(e);\n\t var shape = this._searchTree.pointShape(point);\n\t return shape;\n\t }\n\t },\n\n\t image: function() {\n\t var ref = this;\n\t var root = ref._root;\n\t var rootElement = ref._rootElement;\n\t var loadingStates = [];\n\n\t root.traverse(function (childNode) {\n\t if (childNode.loading) {\n\t loadingStates.push(childNode.loading);\n\t }\n\t });\n\n\t var promise = createPromise();\n\t var resolveDataURL = function () {\n\t root._invalidate();\n\n\t try {\n\t var data = rootElement.toDataURL();\n\t promise.resolve(data);\n\t } catch (e) {\n\t promise.reject(e);\n\t }\n\t };\n\n\t promiseAll(loadingStates).then(resolveDataURL, resolveDataURL);\n\n\t return promise;\n\t },\n\n\t suspendTracking: function() {\n\t Surface.fn.suspendTracking.call(this);\n\t if (this._searchTree) {\n\t this._searchTree.clear();\n\t delete this._searchTree;\n\t }\n\t },\n\n\t resumeTracking: function() {\n\t Surface.fn.resumeTracking.call(this);\n\t if (!this._searchTree) {\n\t this._searchTree = new ShapesQuadTree();\n\n\t var childNodes = this._root.childNodes;\n\t var rootElements = [];\n\t for (var idx = 0; idx < childNodes.length; idx++) {\n\t rootElements.push(childNodes[idx].srcElement);\n\t }\n\t this._searchTree.add(rootElements);\n\t }\n\t },\n\n\t _resize: function() {\n\t this._rootElement.width = this._size.width;\n\t this._rootElement.height = this._size.height;\n\n\t this._root.size = this._size;\n\t this._root.invalidate();\n\t },\n\n\t _template: function() {\n\t return \"\";\n\t },\n\n\t _enableTracking: function() {\n\t this._searchTree = new ShapesQuadTree();\n\t this._cursor = new SurfaceCursor(this);\n\n\t Surface.fn._enableTracking.call(this);\n\t },\n\n\t _trackMouse: function(e) {\n\t if (this._suspendedTracking) {\n\t return;\n\t }\n\n\t var shape = this.eventTarget(e);\n\n\t if (e.type !== \"click\") {\n\t var currentShape = this._currentShape;\n\t if (currentShape && currentShape !== shape) {\n\t this.trigger(\"mouseleave\", {\n\t element: currentShape,\n\t originalEvent: e,\n\t type: \"mouseleave\"\n\t });\n\t }\n\n\t if (shape && currentShape !== shape) {\n\t this.trigger(\"mouseenter\", {\n\t element: shape,\n\t originalEvent: e,\n\t type: \"mouseenter\"\n\t });\n\t }\n\n\t this.trigger(\"mousemove\", {\n\t element: shape,\n\t originalEvent: e,\n\t type: \"mousemove\"\n\t });\n\n\t this._currentShape = shape;\n\t } else if (shape) {\n\t this.trigger(\"click\", {\n\t element: shape,\n\t originalEvent: e,\n\t type: \"click\"\n\t });\n\t }\n\t }\n\t});\n\n\tSurface$3.prototype.type = \"canvas\";\n\n\tif (typeof document !== \"undefined\" && document.createElement(\"canvas\").getContext) {\n\t Surface.support.canvas = true;\n\t SurfaceFactory.current.register(\"canvas\", Surface$3, 20);\n\t}\n\n\tfunction addGradientStops(gradient, stops) {\n\t for (var idx = 0; idx < stops.length; idx++) {\n\t var stop = stops[idx];\n\t var color = kendo.parseColor(stop.color());\n\n\t color.a *= stop.opacity();\n\n\t gradient.addColorStop(stop.offset(), color.toCssRgba());\n\t }\n\t}\n\n\tvar PathNode$2 = Node$2.extend({\n\t renderTo: function(ctx) {\n\t ctx.save();\n\n\t this.setTransform(ctx);\n\t this.setClip(ctx);\n\t this.setOpacity(ctx);\n\n\t ctx.beginPath();\n\n\t this.renderPoints(ctx, this.srcElement);\n\n\t this.setLineDash(ctx);\n\t this.setLineCap(ctx);\n\t this.setLineJoin(ctx);\n\n\t this.setFill(ctx);\n\t this.setStroke(ctx);\n\n\t ctx.restore();\n\t },\n\n\t setFill: function(ctx) {\n\t var fill = this.srcElement.options.fill;\n\t var hasFill = false;\n\n\t if (fill) {\n\t if (fill.nodeType === \"Gradient\") {\n\t this.setGradientFill(ctx, fill);\n\t hasFill = true;\n\t } else if (!isTransparent(fill.color)) {\n\t ctx.fillStyle = fill.color;\n\n\t ctx.save();\n\t this.globalAlpha(ctx, fill.opacity);\n\t ctx.fill();\n\t ctx.restore();\n\n\t hasFill = true;\n\t }\n\t }\n\n\t return hasFill;\n\t },\n\n\t setGradientFill: function(ctx, fill) {\n\t var bbox = this.srcElement.rawBBox();\n\t var gradient;\n\n\t if (fill instanceof LinearGradient) {\n\t var start = fill.start();\n\t var end = fill.end();\n\t gradient = ctx.createLinearGradient(start.x, start.y, end.x, end.y);\n\t } else if (fill instanceof RadialGradient) {\n\t var center = fill.center();\n\t gradient = ctx.createRadialGradient(center.x, center.y, 0, center.x, center.y, fill.radius());\n\t }\n\n\t addGradientStops(gradient, fill.stops);\n\n\t ctx.save();\n\n\t if (!fill.userSpace()) {\n\t ctx.transform(bbox.width(), 0, 0, bbox.height(), bbox.origin.x, bbox.origin.y);\n\t }\n\t ctx.fillStyle = gradient;\n\t ctx.fill();\n\n\t ctx.restore();\n\t },\n\n\t setStroke: function(ctx) {\n\t var stroke = this.srcElement.options.stroke;\n\t if (stroke && !isTransparent(stroke.color) && stroke.width > 0) {\n\t ctx.strokeStyle = stroke.color;\n\t ctx.lineWidth = valueOrDefault(stroke.width, 1);\n\n\t ctx.save();\n\t this.globalAlpha(ctx, stroke.opacity);\n\t ctx.stroke();\n\t ctx.restore();\n\n\t return true;\n\t }\n\t },\n\n\t dashType: function() {\n\t var stroke = this.srcElement.options.stroke;\n\t if (stroke && stroke.dashType) {\n\t return stroke.dashType.toLowerCase();\n\t }\n\t },\n\n\t setLineDash: function(ctx) {\n\t var dashType = this.dashType();\n\t if (dashType && dashType !== SOLID) {\n\t var dashArray = DASH_ARRAYS[dashType];\n\t if (ctx.setLineDash) {\n\t ctx.setLineDash(dashArray);\n\t } else {\n\t ctx.mozDash = dashArray;\n\t ctx.webkitLineDash = dashArray;\n\t }\n\t }\n\t },\n\n\t setLineCap: function(ctx) {\n\t var dashType = this.dashType();\n\t var stroke = this.srcElement.options.stroke;\n\t if (dashType && dashType !== SOLID) {\n\t ctx.lineCap = BUTT;\n\t } else if (stroke && stroke.lineCap) {\n\t ctx.lineCap = stroke.lineCap;\n\t }\n\t },\n\n\t setLineJoin: function(ctx) {\n\t var stroke = this.srcElement.options.stroke;\n\t if (stroke && stroke.lineJoin) {\n\t ctx.lineJoin = stroke.lineJoin;\n\t }\n\t },\n\n\t renderPoints: function(ctx, path) {\n\t renderPath(ctx, path);\n\t }\n\t});\n\n\tNODE_MAP$2.Path = PathNode$2;\n\n\tvar ArcNode$2 = PathNode$2.extend({\n\t renderPoints: function(ctx) {\n\t var path = this.srcElement.toPath();\n\t renderPath(ctx, path);\n\t }\n\t});\n\n\tNODE_MAP$2.Arc = ArcNode$2;\n\n\tvar CircleNode$2 = PathNode$2.extend({\n\t renderPoints: function(ctx) {\n\t var ref = this.srcElement.geometry();\n\t var center = ref.center;\n\t var radius = ref.radius;\n\n\t ctx.arc(center.x, center.y, radius, 0, Math.PI * 2);\n\t }\n\t});\n\n\tNODE_MAP$2.Circle = CircleNode$2;\n\n\tvar RectNode$2 = PathNode$2.extend({\n\t renderPoints: function(ctx) {\n\t var ref = this.srcElement.geometry();\n\t var origin = ref.origin;\n\t var size = ref.size;\n\n\t ctx.rect(origin.x, origin.y, size.width, size.height);\n\t }\n\t});\n\n\tNODE_MAP$2.Rect = RectNode$2;\n\n\tvar ImageNode$2 = PathNode$2.extend({\n\t init: function(srcElement, cors) {\n\t PathNode$2.fn.init.call(this, srcElement);\n\n\t this.onLoad = this.onLoad.bind(this);\n\t this.onError = this.onError.bind(this);\n\n\t this.loading = createPromise();\n\n\t var img = this.img = new Image();\n\n\t if (cors && !(/^data:/i.test(srcElement.src()))) {\n\t img.crossOrigin = cors;\n\t }\n\n\t img.src = srcElement.src();\n\n\t if (img.complete) {\n\t this.onLoad();\n\t } else {\n\t img.onload = this.onLoad;\n\t img.onerror = this.onError;\n\t }\n\t },\n\n\t renderTo: function(ctx) {\n\t if (this.loading.state() === \"resolved\") {\n\t ctx.save();\n\n\t this.setTransform(ctx);\n\t this.setClip(ctx);\n\n\t this.drawImage(ctx);\n\n\t ctx.restore();\n\t }\n\t },\n\n\t optionsChange: function(e) {\n\t if (e.field === \"src\") {\n\t this.loading = createPromise();\n\t this.img.src = this.srcElement.src();\n\t } else {\n\t PathNode$2.fn.optionsChange.call(this, e);\n\t }\n\t },\n\n\t onLoad: function() {\n\t this.loading.resolve();\n\t this.invalidate();\n\t },\n\n\t onError: function() {\n\t this.loading.reject(new Error(\n\t \"Unable to load image '\" + this.img.src +\n\t \"'. Check for connectivity and verify CORS headers.\"\n\t ));\n\t },\n\n\t drawImage: function(ctx) {\n\t var rect = this.srcElement.rect();\n\t var topLeft = rect.topLeft();\n\n\t ctx.drawImage(\n\t this.img, topLeft.x, topLeft.y, rect.width(), rect.height()\n\t );\n\t }\n\t});\n\n\tNODE_MAP$2.Image = ImageNode$2;\n\n\tvar TextNode$2 = PathNode$2.extend({\n\t renderTo: function(ctx) {\n\t var text = this.srcElement;\n\t var pos = text.position();\n\t var size = text.measure();\n\n\t ctx.save();\n\n\t this.setTransform(ctx);\n\t this.setClip(ctx);\n\t this.setOpacity(ctx);\n\n\t ctx.beginPath();\n\n\t ctx.font = text.options.font;\n\t ctx.textAlign = 'left';\n\n\t if (this.setFill(ctx)) {\n\t ctx.fillText(text.content(), pos.x, pos.y + size.baseline);\n\t }\n\n\t if (this.setStroke(ctx)) {\n\t this.setLineDash(ctx);\n\t ctx.strokeText(text.content(), pos.x, pos.y + size.baseline);\n\t }\n\n\t ctx.restore();\n\t }\n\t});\n\n\tNODE_MAP$2.Text = TextNode$2;\n\n\tvar MultiPathNode$2 = PathNode$2.extend({\n\t renderPoints: function(ctx) {\n\t var paths = this.srcElement.paths;\n\t for (var i = 0; i < paths.length; i++) {\n\t renderPath(ctx, paths[i]);\n\t }\n\t }\n\t});\n\n\tNODE_MAP$2.MultiPath = MultiPathNode$2;\n\n\tvar canvas = {\n\t\tSurface: Surface$3,\n\t\tRootNode: RootNode$2,\n\t\tNode: Node$2,\n\t\tGroupNode: GroupNode$2,\n\t\tArcNode: ArcNode$2,\n\t\tCircleNode: CircleNode$2,\n\t\tRectNode: RectNode$2,\n\t\tImageNode: ImageNode$2,\n\t\tTextNode: TextNode$2,\n\t\tPathNode: PathNode$2,\n\t\tMultiPathNode: MultiPathNode$2\n\t};\n\n\tfunction exportImage(group, options) {\n\t var defaults = {\n\t width: \"800px\", height: \"600px\",\n\t cors: \"Anonymous\"\n\t };\n\n\t var exportRoot = group;\n\t var bbox = group.clippedBBox();\n\n\t if (bbox) {\n\t var origin = bbox.getOrigin();\n\t exportRoot = new Group();\n\t exportRoot.transform(transform().translate(-origin.x, -origin.y));\n\t exportRoot.children.push(group);\n\n\t var size = bbox.getSize();\n\t defaults.width = size.width + \"px\";\n\t defaults.height = size.height + \"px\";\n\t }\n\n\t var surfaceOptions = $.extend(defaults, options);\n\n\t var container = document.createElement(\"div\");\n\t var style = container.style;\n\n\t style.display = \"none\";\n\t style.width = surfaceOptions.width;\n\t style.height = surfaceOptions.height;\n\t document.body.appendChild(container);\n\n\t var surface = new Surface$3(container, surfaceOptions);\n\t surface.suspendTracking();\n\t surface.draw(exportRoot);\n\n\t var promise = surface.image();\n\t var destroy = function () {\n\t surface.destroy();\n\t document.body.removeChild(container);\n\t };\n\t promise.then(destroy, destroy);\n\n\t return promise;\n\t}\n\n\tfunction exportSVG(group, options) {\n\t var svg = exportGroup(group);\n\n\t if (!options || !options.raw) {\n\t svg = \"data:image/svg+xml;base64,\" + encodeBase64(svg);\n\t }\n\n\t return createPromise().resolve(svg);\n\t}\n\n\t/* eslint-disable no-multi-spaces, key-spacing, indent, camelcase, space-before-blocks, eqeqeq, brace-style */\n\t/* eslint-disable space-infix-ops, space-before-function-paren, array-bracket-spacing, object-curly-spacing */\n\t/* eslint-disable no-nested-ternary, max-params, default-case, no-else-return, no-empty, yoda */\n\t/* eslint-disable no-param-reassign, no-var, block-scoped-var */\n\n\tvar browser = supportBrowser || {};\n\t/*\n\n\t XXX: to test:\n\n\t - cloneNodes function:\n\t - drawing document containing canvas with page breaking\n\t - drawing document with named radio -s (should not clear selection)\n\t - IE9/IE10 don't support el.dataset; do they copy user data?\n\n\t - repeating table headers/footers on page breaking\n\n\t - forceBreak, keepTogether\n\n\t - avoidLinks\n\n\t */\n\n\t/* -----[ local vars ]----- */\n\n\tfunction slice$1(thing) {\n\t return Array.prototype.slice.call(thing);\n\t}\n\n\tvar KENDO_PSEUDO_ELEMENT = \"KENDO-PSEUDO-ELEMENT\";\n\n\tvar IMAGE_CACHE = {};\n\n\tvar nodeInfo = {};\n\tnodeInfo._root = nodeInfo;\n\n\t/* -----[ Custom Text node to speed up rendering in kendo.pdf ]----- */\n\n\tvar inBrowser = typeof window !== 'undefined';\n\tvar microsoft = inBrowser ? browser.msie || browser.edge : false;\n\n\tvar TextRect = Text.extend({\n\t init: function(str, rect, options) {\n\t Text.fn.init.call(this, str, rect.getOrigin(), options);\n\t this._pdfRect = rect;\n\t },\n\n\t rect: function() {\n\t // this is the crux of it: we can avoid a call to\n\t // measure(), which is what the base class does, since we\n\t // already know the rect. measure() is s-l-o-w.\n\t return this._pdfRect;\n\t },\n\n\t rawBBox: function() {\n\t // also let's avoid creating a new rectangle.\n\t return this._pdfRect;\n\t }\n\t});\n\n\tfunction addClass(el, cls) {\n\t if (el.classList) {\n\t el.classList.add(cls);\n\t } else {\n\t el.className += \" \" + cls;\n\t }\n\t}\n\n\tfunction removeClass(el, cls) {\n\t if (el.classList) {\n\t el.classList.remove(cls);\n\t } else {\n\t el.className = el.className.split(/\\s+/).reduce(function(a, word){\n\t if (word != cls) {\n\t a.push(word);\n\t }\n\t return a;\n\t }, []).join(\" \");\n\t }\n\t}\n\n\tfunction setCSS(el, styles) {\n\t Object.keys(styles).forEach(function(key){\n\t el.style[key] = styles[key];\n\t });\n\t}\n\n\tvar matches = typeof Element !== \"undefined\" && Element.prototype && (function(p){\n\t if (p.matches) {\n\t return function(el, selector) { return el.matches(selector); };\n\t }\n\t if (p.webkitMatchesSelector) {\n\t return function(el, selector) { return el.webkitMatchesSelector(selector); };\n\t }\n\t if (p.mozMatchesSelector) {\n\t return function(el, selector) { return el.mozMatchesSelector(selector); };\n\t }\n\t if (p.msMatchesSelector) {\n\t return function(el, selector) { return el.msMatchesSelector(selector); };\n\t }\n\t return function(s) {\n\t\treturn [].indexOf.call(document.querySelectorAll(s), this) !== -1;\n\t };\n\t})(Element.prototype);\n\n\tfunction closest(el, selector) {\n\t if (el.closest) {\n\t return el.closest(selector);\n\t }\n\t // IE: stringifying rather than simply comparing with `document`,\n\t // which is not iframe-proof and fails in editor export —\n\t // https://github.com/telerik/kendo/issues/6721\n\t while (el && !/^\\[object (?:HTML)?Document\\]$/.test(String(el))) {\n\t if (el.nodeType == 1 /* Element */ && matches(el, selector)) {\n\t return el;\n\t }\n\t el = el.parentNode;\n\t }\n\t}\n\n\t// clone nodes ourselves, so that we redraw (DOM or\n\t// jQuery clone will not)\n\tvar cloneNodes = (function($){\n\t if ($) {\n\t // if we have Kendo and jQuery, use this version as it will\n\t // maintain proper links between cloned element and Kendo\n\t // widgets (i.e. it clones jQuery data(), which isn't the same\n\t // as element's data attributes).\n\t // https://github.com/telerik/kendo-ui-core/issues/2750\n\t return function cloneNodes(el) {\n\t var clone = el.cloneNode(false);\n\t if (el.nodeType == 1 /* Element */) {\n\t var $el = $(el), $clone = $(clone), i;\n\t var data = $el.data();\n\t for (i in data) {\n\t $clone.data(i, data[i]);\n\t }\n\t if (/^canvas$/i.test(el.tagName)) {\n\t clone.getContext(\"2d\").drawImage(el, 0, 0);\n\t } else if (/^(?:input|select|textarea|option)$/i.test(el.tagName)) {\n\t // drop the name attributes so that we don't affect the selection of the\n\t // original nodes (i.e. checked status of radio buttons) when we insert our copy\n\t // into the DOM. https://github.com/telerik/kendo/issues/5409\n\t clone.removeAttribute(\"id\");\n\t clone.removeAttribute(\"name\");\n\t if (!/^textarea$/i.test(el.tagName)) {\n\t clone.value = el.value;\n\t }\n\t clone.checked = el.checked;\n\t clone.selected = el.selected;\n\t }\n\t for (i = el.firstChild; i; i = i.nextSibling) {\n\t clone.appendChild(cloneNodes(i));\n\t }\n\t }\n\t return clone;\n\t };\n\t } else {\n\t // the no-jQuery version\n\t return function cloneNodes(el) {\n\t var clone = (function dive(node){\n\t var clone = node.cloneNode(false);\n\t if (node._kendoExportVisual) {\n\t clone._kendoExportVisual = node._kendoExportVisual;\n\t }\n\t for (var i = node.firstChild; i; i = i.nextSibling) {\n\t clone.appendChild(dive(i));\n\t }\n\t return clone;\n\t })(el);\n\n\t // re-draw canvases - https://github.com/telerik/kendo/issues/4872\n\t var canvases = el.querySelectorAll(\"canvas\");\n\t if (canvases.length) {\n\t slice$1(clone.querySelectorAll(\"canvas\")).forEach(function (canvas$$1, i) {\n\t canvas$$1.getContext(\"2d\").drawImage(canvases[i], 0, 0);\n\t });\n\t }\n\n\t // remove \"name\" attributes from elements -\n\t // https://github.com/telerik/kendo/issues/5409\n\t var orig = el.querySelectorAll(\"input, select, textarea, option\");\n\t slice$1(clone.querySelectorAll(\"input, select, textarea, option\")).forEach(function (el, i) {\n\t el.removeAttribute(\"id\");\n\t el.removeAttribute(\"name\");\n\t if (!/^textarea$/i.test(el.tagName)) {\n\t el.value = orig[i].value;\n\t }\n\t el.checked = orig[i].checked;\n\t el.selected = orig[i].selected;\n\t });\n\n\t return clone;\n\t };\n\t }\n\t})(typeof window !== \"undefined\" && window.kendo && window.kendo.jQuery);\n\n\tfunction getXY(thing) {\n\t if (typeof thing == \"number\") {\n\t return { x: thing, y: thing };\n\t }\n\t if (Array.isArray(thing)) {\n\t return { x: thing[0], y: thing[1] };\n\t }\n\t return { x: thing.x, y: thing.y };\n\t}\n\n\tfunction drawDOM(element, options) {\n\t if (!options) {\n\t options = {};\n\t }\n\t var promise = createPromise();\n\n\t if (!element) {\n\t return promise.reject(\"No element to export\");\n\t }\n\n\t if (typeof window.getComputedStyle != \"function\") {\n\t throw new Error(\"window.getComputedStyle is missing. You are using an unsupported browser, or running in IE8 compatibility mode. Drawing HTML is supported in Chrome, Firefox, Safari and IE9+.\");\n\t }\n\n\t kendo.pdf.defineFont(getFontFaces(element.ownerDocument));\n\n\t var scale = getXY(options.scale || 1);\n\n\t function doOne(element) {\n\t var group = new Group();\n\n\t // translate to start of page\n\t var pos = element.getBoundingClientRect();\n\t setTransform(group, [\n\t scale.x,\n\t 0,\n\t 0,\n\t scale.y,\n\t (-pos.left * scale.x),\n\t (-pos.top * scale.y)\n\t ]);\n\n\t nodeInfo._clipbox = false;\n\t nodeInfo._matrix = Matrix.unit();\n\t nodeInfo._stackingContext = {\n\t element: element,\n\t group: group\n\t };\n\n\t if (options.avoidLinks === true) {\n\t nodeInfo._avoidLinks = \"a\";\n\t } else {\n\t nodeInfo._avoidLinks = options.avoidLinks;\n\t }\n\n\t addClass(element, \"k-pdf-export\");\n\t renderElement(element, group);\n\t removeClass(element, \"k-pdf-export\");\n\n\t return group;\n\t }\n\n\t cacheImages(element, function(){\n\t var forceBreak = options && options.forcePageBreak;\n\t var hasPaperSize = options && options.paperSize && options.paperSize != \"auto\";\n\t var paperOptions = kendo.pdf.getPaperOptions(function(key, def){\n\t if (key == \"paperSize\") {\n\t // PDF.getPaperOptions croaks on \"auto\", just pass dummy A4 as we might\n\t // still be interested in margins.\n\t return hasPaperSize ? options[key] : \"A4\";\n\t }\n\t return key in options ? options[key] : def;\n\t });\n\t var pageWidth = hasPaperSize && paperOptions.paperSize[0];\n\t var pageHeight = hasPaperSize && paperOptions.paperSize[1];\n\t var margin = options.margin && paperOptions.margin;\n\t var hasMargin = Boolean(margin);\n\t if (forceBreak || pageHeight) {\n\t if (!margin) {\n\t margin = { left: 0, top: 0, right: 0, bottom: 0 };\n\t }\n\n\t // we want paper size and margin to be unaffected by\n\t // scaling in the output, so we have to reverse-scale\n\t // before our calculations begin.\n\t if (pageWidth) { pageWidth /= scale.x; }\n\t if (pageHeight) { pageHeight /= scale.y; }\n\t margin.left /= scale.x;\n\t margin.right /= scale.x;\n\t margin.top /= scale.y;\n\t margin.bottom /= scale.y;\n\n\t var group = new Group({\n\t pdf: {\n\t multiPage : true,\n\t paperSize : hasPaperSize ? paperOptions.paperSize : \"auto\",\n\t _ignoreMargin : hasMargin // HACK! see exportPDF in pdf/drawing.js\n\t }\n\t });\n\t handlePageBreaks(\n\t function(x) {\n\t if (options.progress) {\n\t var canceled = false, pageNum = 0;\n\t (function next(){\n\t if (pageNum < x.pages.length) {\n\t var page = doOne(x.pages[pageNum]);\n\t group.append(page);\n\t options.progress({\n\t page: page,\n\t pageNum: ++pageNum,\n\t totalPages: x.pages.length,\n\t cancel: function() {\n\t canceled = true;\n\t }\n\t });\n\t if (!canceled) {\n\t setTimeout(next);\n\t } else {\n\t // XXX: should we also fail() the deferred object?\n\t x.container.parentNode.removeChild(x.container);\n\t }\n\t } else {\n\t x.container.parentNode.removeChild(x.container);\n\t promise.resolve(group);\n\t }\n\t })();\n\t } else {\n\t x.pages.forEach(function(page){\n\t group.append(doOne(page));\n\t });\n\t x.container.parentNode.removeChild(x.container);\n\t promise.resolve(group);\n\t }\n\t },\n\t element,\n\t forceBreak,\n\t pageWidth ? pageWidth - margin.left - margin.right : null,\n\t pageHeight ? pageHeight - margin.top - margin.bottom : null,\n\t margin,\n\t options\n\t );\n\t } else {\n\t promise.resolve(doOne(element));\n\t }\n\t });\n\n\t function makeTemplate(template$$1) {\n\t if (template$$1 != null) {\n\t if (typeof template$$1 == \"string\") {\n\t template$$1 = kendo.template(template$$1.replace(/^\\s+|\\s+$/g, \"\"));\n\t }\n\t if (typeof template$$1 == \"function\") {\n\t return function(data) {\n\t var el = template$$1(data);\n\t if (el && typeof el == \"string\") {\n\t var div = document.createElement(\"div\");\n\t div.innerHTML = el;\n\t el = div.firstElementChild;\n\t }\n\t return el;\n\t };\n\t }\n\t // assumed DOM element\n\t return function() {\n\t return template$$1.cloneNode(true);\n\t };\n\t }\n\t }\n\n\t function handlePageBreaks(callback, element, forceBreak, pageWidth, pageHeight, margin, options) {\n\t var template$$1 = makeTemplate(options.template);\n\t var doc = element.ownerDocument;\n\t var pages = [];\n\t var copy = options._destructive ? element : cloneNodes(element);\n\t var container = doc.createElement(\"KENDO-PDF-DOCUMENT\");\n\t var adjust = 0;\n\n\t // make sure elements are at the end (Grid widget\n\t // places TFOOT before TBODY, tricking our algorithm to\n\t // insert a page break right after the header).\n\t // https://github.com/telerik/kendo/issues/4699\n\t slice$1(copy.querySelectorAll(\"tfoot\")).forEach(function(tfoot){\n\t tfoot.parentNode.appendChild(tfoot);\n\t });\n\n\t // remember the index of each LI from an ordered list.\n\t // we'll use it to reconstruct the proper numbering.\n\t slice$1(copy.querySelectorAll(\"ol\")).forEach(function(ol){\n\t slice$1(ol.children).forEach(function(li, index){\n\t li.setAttribute(\"kendo-split-index\", index);\n\t });\n\t });\n\n\t setCSS(container, {\n\t display : \"block\",\n\t position : \"absolute\",\n\t boxSizing : \"content-box\",\n\t left : \"-10000px\",\n\t top : \"-10000px\"\n\t });\n\n\t if (pageWidth) {\n\t // subtle: if we don't set the width *and* margins here, the layout in this\n\t // container will be different from the one in our final page elements, and we'll\n\t // split at the wrong places.\n\t setCSS(container, {\n\t width : pageWidth + \"px\",\n\t paddingLeft : margin.left + \"px\",\n\t paddingRight : margin.right + \"px\"\n\t });\n\n\t // when the first element has a margin-top (i.e. a

) the page will be\n\t // inadvertently enlarged by that number (the browser will report the container's\n\t // bounding box top to start at the element's top, rather than including its\n\t // margin). Adding overflow: hidden seems to fix it.\n\t //\n\t // to understand the difference, try the following snippets in your browser:\n\t //\n\t // 1.
\n\t //

Foo

\n\t //
\n\t //\n\t // 2.
\n\t //

Foo

\n\t //
\n\t //\n\t // this detail is not important when automatic page breaking is not requested, hence\n\t // doing it only if pageWidth is defined.\n\t setCSS(copy, { overflow: \"hidden\" });\n\t }\n\n\t element.parentNode.insertBefore(container, element);\n\t container.appendChild(copy);\n\n\t // we need the timeouts here, so that images dimensions are\n\t // properly computed in DOM when we start our thing.\n\t if (options.beforePageBreak) {\n\t setTimeout(function(){\n\t options.beforePageBreak(container, doPageBreak);\n\t }, 15);\n\t } else {\n\t setTimeout(doPageBreak, 15);\n\t }\n\n\t function doPageBreak() {\n\t if (forceBreak != \"-\" || pageHeight) {\n\t splitElement(copy);\n\t }\n\n\t {\n\t var page = makePage();\n\t copy.parentNode.insertBefore(page, copy);\n\t page.appendChild(copy);\n\t }\n\n\t if (template$$1) {\n\t pages.forEach(function(page, i){\n\t var el = template$$1({\n\t element : page,\n\t pageNum : i + 1,\n\t totalPages : pages.length\n\t });\n\t if (el) {\n\t page.appendChild(el);\n\t }\n\t });\n\t }\n\n\t cacheImages(pages, function() {\n\t // Even though we already cached images, they simply won't be available\n\t // immediately in the newly created DOM. Previously we'd allow a 10ms timeout,\n\t // but that's arbitrary and clearly not working in all cases\n\t // (https://github.com/telerik/kendo/issues/5399), so this function will wait\n\t // for their .complete attribute.\n\t whenImagesAreActuallyLoaded(pages, function(){\n\t callback({ pages: pages, container: container });\n\t });\n\t });\n\t }\n\n\t function keepTogether(el) {\n\t if (options.keepTogether && matches(el, options.keepTogether) && el.offsetHeight <= pageHeight - adjust) {\n\t return true;\n\t }\n\n\t var tag = el.tagName;\n\t if (/^h[1-6]$/i.test(tag) && el.offsetHeight >= pageHeight - adjust) {\n\t return false;\n\t }\n\n\t return (el.getAttribute(\"data-kendo-chart\") ||\n\t /^(?:img|tr|thead|th|tfoot|iframe|svg|object|canvas|input|textarea|select|video|h[1-6])/i.test(el.tagName));\n\t }\n\n\t function splitElement(element) {\n\t if (element.tagName == \"TABLE\") {\n\t setCSS(element, { tableLayout: \"fixed\" });\n\t }\n\t if (keepTogether(element)) {\n\t return;\n\t }\n\t var style = getComputedStyle(element);\n\t var bottomPadding = parseFloat(getPropertyValue(style, \"padding-bottom\"));\n\t var bottomBorder = parseFloat(getPropertyValue(style, \"border-bottom-width\"));\n\t var saveAdjust = adjust;\n\t adjust += bottomPadding + bottomBorder;\n\t var isFirst = true;\n\t for (var el = element.firstChild; el; el = el.nextSibling) {\n\t if (el.nodeType == 1 /* Element */) {\n\t isFirst = false;\n\t if (matches(el, forceBreak)) {\n\t breakAtElement(el);\n\t continue;\n\t }\n\t if (!pageHeight) {\n\t // we're in \"manual breaks mode\"\n\t splitElement(el);\n\t continue;\n\t }\n\t if (!/^(?:static|relative)$/.test(getPropertyValue(getComputedStyle(el), \"position\"))) {\n\t continue;\n\t }\n\t var fall = fallsOnMargin(el);\n\t if (fall == 1) {\n\t // element starts on next page, break before anyway.\n\t breakAtElement(el);\n\t }\n\t else if (fall) {\n\t // elements ends up on next page, or possibly doesn't fit on a page at\n\t // all. break before it anyway if it's an or , otherwise\n\t // attempt to split.\n\t if (keepTogether(el)) {\n\t breakAtElement(el);\n\t } else {\n\t splitElement(el);\n\t }\n\t }\n\t else {\n\t splitElement(el);\n\t }\n\t }\n\t else if (el.nodeType == 3 /* Text */ && pageHeight) {\n\t splitText(el, isFirst);\n\t isFirst = false;\n\t }\n\t }\n\t adjust = saveAdjust;\n\t }\n\n\t function firstInParent(el) {\n\t var p = el.parentNode, first = p.firstChild;\n\t if (el === first) {\n\t return true;\n\t }\n\t if (el === p.children[0]) {\n\t if (first.nodeType == 7 /* comment */ ||\n\t first.nodeType == 8 /* processing instruction */) {\n\t return true;\n\t }\n\t if (first.nodeType == 3 /* text */) {\n\t // if whitespace only we can probably consider it's first\n\t return !/\\S/.test(first.data);\n\t }\n\t }\n\t return false;\n\t }\n\n\t function breakAtElement(el) {\n\t if (el.nodeType == 1 && el !== copy && firstInParent(el)) {\n\t return breakAtElement(el.parentNode);\n\t }\n\t var table, colgroup, thead, grid, gridHead;\n\t table = closest(el, \"table\");\n\t colgroup = table && table.querySelector(\"colgroup\");\n\t if (options.repeatHeaders) {\n\t thead = table && table.querySelector(\"thead\");\n\n\t // If we break page in a Kendo Grid, repeat its header. This ugly hack is\n\t // necessary because a scrollable grid will keep the header in a separate\n\t // element from its content.\n\t //\n\t // XXX: This is likely to break as soon as the widget HTML is modified.\n\t grid = closest(el, \".k-grid.k-widget\");\n\t if (grid && grid.querySelector(\".k-auto-scrollable\")) {\n\t gridHead = grid.querySelector(\".k-grid-header\");\n\t }\n\t }\n\t var page = makePage();\n\t var range = doc.createRange();\n\t range.setStartBefore(copy);\n\t range.setEndBefore(el);\n\t page.appendChild(range.extractContents());\n\t copy.parentNode.insertBefore(page, copy);\n\t preventBulletOnListItem(el.parentNode);\n\t if (table) {\n\t table = closest(el, \"table\"); // that's the
on next page!\n\t if (options.repeatHeaders && thead) {\n\t table.insertBefore(thead.cloneNode(true), table.firstChild);\n\t }\n\t if (colgroup) {\n\t table.insertBefore(colgroup.cloneNode(true), table.firstChild);\n\t }\n\t }\n\t if (options.repeatHeaders && gridHead) {\n\t grid = closest(el, \".k-grid.k-widget\");\n\t grid.insertBefore(gridHead.cloneNode(true), grid.firstChild);\n\t }\n\t }\n\n\t function makePage() {\n\t var page = doc.createElement(\"KENDO-PDF-PAGE\");\n\t setCSS(page, {\n\t display : \"block\",\n\t boxSizing: \"content-box\",\n\t width : pageWidth ? (pageWidth + \"px\") : \"auto\",\n\t padding : (margin.top + \"px \" +\n\t margin.right + \"px \" +\n\t margin.bottom + \"px \" +\n\t margin.left + \"px\"),\n\n\t // allow absolutely positioned elements to be relative to current page\n\t position : \"relative\",\n\n\t // without the following we might affect layout of subsequent pages\n\t height : pageHeight ? (pageHeight + \"px\") : \"auto\",\n\t overflow : pageHeight || pageWidth ? \"hidden\" : \"visible\",\n\t clear : \"both\"\n\t });\n\n\t // debug\n\t // $(\"
\").css({\n\t // position : \"absolute\",\n\t // left : margin.left,\n\t // top : margin.top,\n\t // width : pageWidth,\n\t // height : pageHeight,\n\t // boxSizing : \"border-box\",\n\t // background: \"rgba(255, 255, 0, 0.5)\"\n\t // //border : \"1px solid red\"\n\t // }).appendTo(page);\n\n\t if (options && options.pageClassName) {\n\t page.className = options.pageClassName;\n\t }\n\t pages.push(page);\n\t return page;\n\t }\n\n\t function fallsOnMargin(thing) {\n\t var box = thing.getBoundingClientRect();\n\t if (box.width === 0 || box.height === 0) {\n\t // I'd say an element with dimensions zero fits on current page.\n\t return 0;\n\t }\n\t var top = copy.getBoundingClientRect().top;\n\t var available = pageHeight - adjust;\n\t return (box.height > available) ? 3\n\t : (box.top - top > available) ? 1\n\t : (box.bottom - top > available) ? 2\n\t : 0;\n\t }\n\n\t function splitText(node, isFirst) {\n\t if (!/\\S/.test(node.data)) {\n\t return;\n\t }\n\n\t var len = node.data.length;\n\t var range = doc.createRange();\n\t range.selectNodeContents(node);\n\t var fall = fallsOnMargin(range);\n\t if (!fall) {\n\t return; // the whole text fits on current page\n\t }\n\n\t var nextnode = node;\n\t if (fall == 1) {\n\t // starts on next page, break before anyway.\n\t if (isFirst) {\n\t // avoid leaving an empty

,

  • , etc. on previous page.\n\t breakAtElement(node.parentNode);\n\t } else {\n\t breakAtElement(node);\n\t }\n\t }\n\t else {\n\t (function findEOP(min, pos, max) {\n\t range.setEnd(node, pos);\n\t if (min == pos || pos == max) {\n\t return pos;\n\t }\n\t if (fallsOnMargin(range)) {\n\t return findEOP(min, (min + pos) >> 1, pos);\n\t } else {\n\t return findEOP(pos, (pos + max) >> 1, max);\n\t }\n\t })(0, len >> 1, len);\n\n\t if (!/\\S/.test(range.toString()) && isFirst) {\n\t // avoid leaving an empty

    ,

  • , etc. on previous page.\n\t breakAtElement(node.parentNode);\n\t } else {\n\t // This is only needed for IE, but it feels cleaner to do it anyway. Without\n\t // it, IE will truncate a very long text (playground/pdf-long-text-2.html).\n\t nextnode = node.splitText(range.endOffset);\n\n\t var page = makePage();\n\t range.setStartBefore(copy);\n\t page.appendChild(range.extractContents());\n\t copy.parentNode.insertBefore(page, copy);\n\t preventBulletOnListItem(nextnode.parentNode);\n\t }\n\t }\n\n\t splitText(nextnode);\n\t }\n\n\t function preventBulletOnListItem(el) {\n\t // set a hint on continued LI elements, to tell the\n\t // renderer not to draw the bullet again.\n\t // https://github.com/telerik/kendo-ui-core/issues/2732\n\t var li = closest(el, \"li\");\n\t if (li) {\n\t li.setAttribute(\"kendo-no-bullet\", \"1\");\n\t preventBulletOnListItem(li.parentNode);\n\t }\n\t }\n\t }\n\n\t return promise;\n\t}\n\n\tdrawDOM.getFontFaces = getFontFaces;\n\n\t// This is needed for the Spreadsheet print functionality. Since\n\t// there we only need to draw text, this cuts through the ceremony\n\t// of drawDOM/renderElement and renders the text node directly.\n\tdrawDOM.drawText = function(element) {\n\t var group = new Group();\n\t nodeInfo._clipbox = false;\n\t nodeInfo._matrix = Matrix.unit();\n\t nodeInfo._stackingContext = {\n\t element: element,\n\t group: group\n\t };\n\t pushNodeInfo(element, getComputedStyle(element), group);\n\t if (element.firstChild.nodeType == 3 /* Text */) {\n\t // avoid the penalty of renderElement\n\t renderText(element, element.firstChild, group);\n\t } else {\n\t _renderElement(element, group);\n\t }\n\t popNodeInfo();\n\t return group;\n\t};\n\n\tvar parseBackgroundImage = (function(){\n\t var tok_linear_gradient = /^((-webkit-|-moz-|-o-|-ms-)?linear-gradient\\s*)\\(/;\n\t //var tok_radial_gradient = /^((-webkit-|-moz-|-o-|-ms-)?radial-gradient\\s*)\\(/;\n\t var tok_percent = /^([-0-9.]+%)/;\n\t var tok_length = /^([-0-9.]+px)/;\n\t var tok_keyword = /^(left|right|top|bottom|to|center)\\W/;\n\t var tok_angle = /^([-0-9.]+(deg|grad|rad|turn)|0)/;\n\t var tok_whitespace = /^(\\s+)/;\n\t var tok_popen = /^(\\()/;\n\t var tok_pclose = /^(\\))/;\n\t var tok_comma = /^(,)/;\n\t var tok_url = /^(url)\\(/;\n\t var tok_content = /^(.*?)\\)/;\n\n\t var cache1 = {}, cache2 = {};\n\n\t function parse(input) {\n\t var orig = input;\n\t if (hasOwnProperty(cache1, orig)) {\n\t return cache1[orig];\n\t }\n\t function skip_ws() {\n\t var m = tok_whitespace.exec(input);\n\t if (m) {\n\t input = input.substr(m[1].length);\n\t }\n\t }\n\t function read(token) {\n\t skip_ws();\n\t var m = token.exec(input);\n\t if (m) {\n\t input = input.substr(m[1].length);\n\t return m[1];\n\t }\n\t }\n\n\t function read_stop() {\n\t var color = kendo.parseColor(input, true);\n\t var length, percent;\n\t if (color) {\n\t var match =\n\t /^#[0-9a-f]+/i.exec(input) ||\n\t /^rgba?\\(.*?\\)/i.exec(input) ||\n\t /^..*?\\b/.exec(input); // maybe named color\n\t input = input.substr(match[0].length);\n\t color = color.toRGB();\n\t if (!(length = read(tok_length))) {\n\t percent = read(tok_percent);\n\t }\n\t return { color: color, length: length, percent: percent };\n\t }\n\t }\n\n\t function read_linear_gradient(propName) {\n\t var angle;\n\t var to1, to2;\n\t var stops = [];\n\t var reverse = false;\n\n\t if (read(tok_popen)) {\n\t // 1. [ || to , ]?\n\t angle = read(tok_angle);\n\t if (angle == \"0\") {\n\t angle = \"0deg\"; // Edge\n\t }\n\t if (angle) {\n\t angle = parseAngle(angle);\n\t read(tok_comma);\n\t }\n\t else {\n\t to1 = read(tok_keyword);\n\t if (to1 == \"to\") {\n\t to1 = read(tok_keyword);\n\t } else if (to1 && /^-/.test(propName)) {\n\t reverse = true;\n\t }\n\t to2 = read(tok_keyword);\n\t read(tok_comma);\n\t }\n\n\t if (/-moz-/.test(propName) && angle == null && to1 == null) {\n\t var x = read(tok_percent), y = read(tok_percent);\n\t reverse = true;\n\t if (x == \"0%\") {\n\t to1 = \"left\";\n\t } else if (x == \"100%\") {\n\t to1 = \"right\";\n\t }\n\t if (y == \"0%\") {\n\t to2 = \"top\";\n\t } else if (y == \"100%\") {\n\t to2 = \"bottom\";\n\t }\n\t read(tok_comma);\n\t }\n\n\t // 2. color stops\n\t while (input && !read(tok_pclose)) {\n\t var stop = read_stop();\n\t if (!stop) {\n\t break;\n\t }\n\t stops.push(stop);\n\t read(tok_comma);\n\t }\n\n\t return {\n\t type : \"linear\",\n\t angle : angle,\n\t to : to1 && to2 ? to1 + \" \" + to2 : to1 ? to1 : to2 ? to2 : null,\n\t stops : stops,\n\t reverse : reverse\n\t };\n\t }\n\t }\n\n\t function read_url() {\n\t if (read(tok_popen)) {\n\t var url = read(tok_content);\n\t url = url.replace(/^['\"]+|[\"']+$/g, \"\");\n\t read(tok_pclose);\n\t return { type: \"url\", url: url };\n\t }\n\t }\n\n\t var tok;\n\n\t if ((tok = read(tok_linear_gradient))) {\n\t tok = read_linear_gradient(tok);\n\t }\n\t else if ((tok = read(tok_url))) {\n\t tok = read_url();\n\t }\n\n\t return (cache1[orig] = tok || { type: \"none\" });\n\t }\n\n\t return function(input) {\n\t if (hasOwnProperty(cache2, input)) {\n\t return cache2[input];\n\t }\n\t return (cache2[input] = splitProperty(input).map(parse));\n\t };\n\t})();\n\n\tvar splitProperty = (function(){\n\t var cache = {};\n\t return function(input, separator) {\n\t if (!separator) {\n\t separator = /^\\s*,\\s*/;\n\t }\n\n\t var cacheKey = input + separator;\n\n\t if (hasOwnProperty(cache, cacheKey)) {\n\t return cache[cacheKey];\n\t }\n\n\t var ret = [];\n\t var last$$1 = 0, pos = 0;\n\t var in_paren = 0;\n\t var in_string = false;\n\t var m;\n\n\t function looking_at(rx) {\n\t return (m = rx.exec(input.substr(pos)));\n\t }\n\n\t function trim(str) {\n\t return str.replace(/^\\s+|\\s+$/g, \"\");\n\t }\n\n\t while (pos < input.length) {\n\t if (!in_string && looking_at(/^[\\(\\[\\{]/)) {\n\t in_paren++;\n\t pos++;\n\t }\n\t else if (!in_string && looking_at(/^[\\)\\]\\}]/)) {\n\t in_paren--;\n\t pos++;\n\t }\n\t else if (!in_string && looking_at(/^[\\\"\\']/)) {\n\t in_string = m[0];\n\t pos++;\n\t }\n\t else if (in_string == \"'\" && looking_at(/^\\\\\\'/)) {\n\t pos += 2;\n\t }\n\t else if (in_string == '\"' && looking_at(/^\\\\\\\"/)) {\n\t pos += 2;\n\t }\n\t else if (in_string == \"'\" && looking_at(/^\\'/)) {\n\t in_string = false;\n\t pos++;\n\t }\n\t else if (in_string == '\"' && looking_at(/^\\\"/)) {\n\t in_string = false;\n\t pos++;\n\t }\n\t else if (looking_at(separator)) {\n\t if (!in_string && !in_paren && pos > last$$1) {\n\t ret.push(trim(input.substring(last$$1, pos)));\n\t last$$1 = pos + m[0].length;\n\t }\n\t pos += m[0].length;\n\t }\n\t else {\n\t pos++;\n\t }\n\t }\n\t if (last$$1 < pos) {\n\t ret.push(trim(input.substring(last$$1, pos)));\n\t }\n\t return (cache[cacheKey] = ret);\n\t };\n\t})();\n\n\tvar getFontURL = (function(cache){\n\t return function(el){\n\t // XXX: for IE we get here the whole cssText of the rule,\n\t // because the computedStyle.src is empty. Next time we need\n\t // to fix these regexps we better write a CSS parser. :-\\\n\t var url = cache[el];\n\t if (!url) {\n\t var m;\n\t if ((m = /url\\((['\"]?)([^'\")]*?)\\1\\)\\s+format\\((['\"]?)truetype\\3\\)/.exec(el))) {\n\t url = cache[el] = m[2];\n\t } else if ((m = /url\\((['\"]?)([^'\")]*?\\.ttf)\\1\\)/.exec(el))) {\n\t url = cache[el] = m[2];\n\t }\n\t }\n\t return url;\n\t };\n\t})(Object.create ? Object.create(null) : {});\n\n\tvar getFontHeight = (function(cache){\n\t return function(font) {\n\t var height = cache[font];\n\t if (height == null) {\n\t height = cache[font] = kendoUtil.measureText(\"Mapq\", { font: font }).height;\n\t }\n\t return height;\n\t };\n\t})(Object.create ? Object.create(null) : {});\n\n\tfunction getFontFaces(doc) {\n\t if (doc == null) {\n\t doc = document;\n\t }\n\t var result = {};\n\t for (var i = 0; i < doc.styleSheets.length; ++i) {\n\t doStylesheet(doc.styleSheets[i]);\n\t }\n\t return result;\n\t function doStylesheet(ss) {\n\t if (ss) {\n\t var rules = null;\n\t try {\n\t rules = ss.cssRules;\n\t } catch (ex) {}\n\t if (rules) {\n\t addRules(ss, rules);\n\t }\n\t }\n\t }\n\t function findFonts(rule) {\n\t var src = getPropertyValue(rule.style, \"src\");\n\t if (src) {\n\t return splitProperty(src).reduce(function(a, el){\n\t var font = getFontURL(el);\n\t if (font) {\n\t a.push(font);\n\t }\n\t return a;\n\t }, []);\n\t } else {\n\t // Internet Explorer\n\t // XXX: this is gross. should work though for valid CSS.\n\t var font = getFontURL(rule.cssText);\n\t return font ? [ font ] : [];\n\t }\n\t }\n\t function addRules(styleSheet, rules) {\n\t for (var i = 0; i < rules.length; ++i) {\n\t var r = rules[i];\n\t switch (r.type) {\n\t case 3: // CSSImportRule\n\t doStylesheet(r.styleSheet);\n\t break;\n\t case 5: // CSSFontFaceRule\n\t var style = r.style;\n\t var family = splitProperty(getPropertyValue(style, \"font-family\"));\n\t var bold = /^([56789]00|bold)$/i.test(getPropertyValue(style, \"font-weight\"));\n\t var italic = \"italic\" == getPropertyValue(style, \"font-style\");\n\t var src = findFonts(r);\n\t if (src.length > 0) {\n\t addRule(styleSheet, family, bold, italic, src[0]);\n\t }\n\t }\n\t }\n\t }\n\t function addRule(styleSheet, names, bold, italic, url) {\n\t // We get full resolved absolute URLs in Chrome, but sadly\n\t // not in Firefox.\n\t if (!(/^data:/i.test(url))) {\n\t if (!(/^[^\\/:]+:\\/\\//.test(url) || /^\\//.test(url))) {\n\t url = String(styleSheet.href).replace(/[^\\/]*$/, \"\") + url;\n\t }\n\t }\n\t names.forEach(function(name){\n\t name = name.replace(/^(['\"]?)(.*?)\\1$/, \"$2\"); // it's quoted\n\t if (bold) {\n\t name += \"|bold\";\n\t }\n\t if (italic) {\n\t name += \"|italic\";\n\t }\n\t result[name] = url;\n\t });\n\t }\n\t}\n\n\tfunction hasOwnProperty(obj, key) {\n\t return Object.prototype.hasOwnProperty.call(obj, key);\n\t}\n\n\tfunction getCounter(name) {\n\t name = \"_counter_\" + name;\n\t return nodeInfo[name];\n\t}\n\n\tfunction getAllCounters(name) {\n\t var values = [], p = nodeInfo;\n\t name = \"_counter_\" + name;\n\t while (p) {\n\t if (hasOwnProperty(p, name)) {\n\t values.push(p[name]);\n\t }\n\t p = Object.getPrototypeOf(p);\n\t }\n\t return values.reverse();\n\t}\n\n\tfunction incCounter(name, inc) {\n\t var p = nodeInfo;\n\t name = \"_counter_\" + name;\n\t while (p && !hasOwnProperty(p, name)) {\n\t p = Object.getPrototypeOf(p);\n\t }\n\t if (!p) {\n\t p = nodeInfo._root;\n\t }\n\t p[name] = (p[name] || 0) + (inc == null ? 1 : inc);\n\t}\n\n\tfunction resetCounter(name, val) {\n\t name = \"_counter_\" + name;\n\t nodeInfo[name] = val == null ? 0 : val;\n\t}\n\n\tfunction doCounters(a, f, def) {\n\t for (var i = 0; i < a.length;) {\n\t var name = a[i++];\n\t var val = parseFloat(a[i]);\n\t if (isNaN(val)) {\n\t f(name, def);\n\t } else {\n\t f(name, val);\n\t ++i;\n\t }\n\t }\n\t}\n\n\tfunction updateCounters(style) {\n\t var counterReset = getPropertyValue(style, \"counter-reset\");\n\t if (counterReset) {\n\t doCounters(splitProperty(counterReset, /^\\s+/), resetCounter, 0);\n\t }\n\t var counterIncrement = getPropertyValue(style, \"counter-increment\");\n\t if (counterIncrement) {\n\t doCounters(splitProperty(counterIncrement, /^\\s+/), incCounter, 1);\n\t }\n\t}\n\n\tfunction parseColor$1(str, css) {\n\t var color = kendo.parseColor(str, true);\n\t if (color) {\n\t color = color.toRGB();\n\t if (css) {\n\t color = color.toCssRgba();\n\t } else if (color.a === 0) {\n\t color = null;\n\t }\n\t }\n\t return color;\n\t}\n\n\tfunction whenImagesAreActuallyLoaded(elements, callback) {\n\t var pending = 0;\n\t elements.forEach(function(el){\n\t var images = el.querySelectorAll(\"img\");\n\t for (var i = 0; i < images.length; ++i) {\n\t var img = images[i];\n\t if (!img.complete) {\n\t pending++;\n\t img.onload = img.onerror = next;\n\t }\n\t }\n\t });\n\t if (!pending) {\n\t next();\n\t }\n\t function next() {\n\t if (--pending <= 0) {\n\t callback();\n\t }\n\t }\n\t}\n\n\tfunction cacheImages(element, callback) {\n\t var urls = [];\n\t function add(url) {\n\t if (!IMAGE_CACHE[url]) {\n\t IMAGE_CACHE[url] = true;\n\t urls.push(url);\n\t }\n\t }\n\t function dive(element){\n\t if (/^img$/i.test(element.tagName)) {\n\t add(element.src);\n\t }\n\t parseBackgroundImage(\n\t getPropertyValue(\n\t getComputedStyle(element), \"background-image\"\n\t )\n\t ).forEach(function(bg){\n\t if (bg.type == \"url\") {\n\t add(bg.url);\n\t }\n\t });\n\n\t if (element.children) {\n\t slice$1(element.children).forEach(dive);\n\t }\n\t }\n\n\t if (Array.isArray(element)) {\n\t element.forEach(dive);\n\t } else {\n\t dive(element);\n\t }\n\n\t var count = urls.length;\n\t function next() {\n\t if (--count <= 0) {\n\t callback();\n\t }\n\t }\n\t if (count === 0) {\n\t next();\n\t }\n\t urls.forEach(function(url){\n\t var img = IMAGE_CACHE[url] = new window.Image();\n\t if (!(/^data:/i.test(url))) {\n\t img.crossOrigin = \"Anonymous\";\n\t }\n\t img.src = url;\n\t if (img.complete) {\n\t next();\n\t } else {\n\t img.onload = next;\n\t img.onerror = function() {\n\t IMAGE_CACHE[url] = null;\n\t next();\n\t };\n\t }\n\t });\n\t}\n\n\tfunction alphaNumeral(n) {\n\t var result = \"\";\n\t do {\n\t var r = n % 26;\n\t result = String.fromCharCode(97 + r) + result;\n\t n = Math.floor(n / 26);\n\t } while (n > 0);\n\t return result;\n\t}\n\n\tfunction pushNodeInfo(element, style, group) {\n\t nodeInfo = Object.create(nodeInfo);\n\t nodeInfo[element.tagName.toLowerCase()] = {\n\t element: element,\n\t style: style\n\t };\n\t var decoration = getPropertyValue(style, \"text-decoration\");\n\t if (decoration && decoration != \"none\") {\n\t var color = getPropertyValue(style, \"color\");\n\t decoration.split(/\\s+/g).forEach(function(name){\n\t if (!nodeInfo[name]) {\n\t nodeInfo[name] = color;\n\t }\n\t });\n\t }\n\n\t if (createsStackingContext(style)) {\n\t nodeInfo._stackingContext = {\n\t element: element,\n\t group: group\n\t };\n\t }\n\t}\n\n\tfunction popNodeInfo() {\n\t nodeInfo = Object.getPrototypeOf(nodeInfo);\n\t}\n\n\tfunction updateClipbox(path) {\n\t if (nodeInfo._clipbox != null) {\n\t var box = path.bbox(nodeInfo._matrix);\n\t if (nodeInfo._clipbox) {\n\t nodeInfo._clipbox = Rect.intersect(nodeInfo._clipbox, box);\n\t } else {\n\t nodeInfo._clipbox = box;\n\t }\n\t }\n\t}\n\n\tfunction emptyClipbox() {\n\t var cb = nodeInfo._clipbox;\n\t if (cb == null) {\n\t return true;\n\t }\n\t if (cb) {\n\t return cb.width() === 0 || cb.height() === 0;\n\t }\n\t}\n\n\tfunction createsStackingContext(style) {\n\t function prop(name) { return getPropertyValue(style, name); }\n\t if (prop(\"transform\") != \"none\" ||\n\t prop(\"position\") != \"static\" ||\n\t prop(\"z-index\") != \"auto\" ||\n\t prop(\"opacity\") < 1) {\n\t return true;\n\t }\n\t}\n\n\tfunction getComputedStyle(element, pseudoElt) {\n\t return window.getComputedStyle(element, pseudoElt || null);\n\t}\n\n\tfunction getPropertyValue(style, prop, defa) {\n\t var val = style.getPropertyValue(prop);\n\t if (val == null || val === \"\") {\n\t if (browser.webkit) {\n\t val = style.getPropertyValue(\"-webkit-\" + prop );\n\t } else if (browser.mozilla) {\n\t val = style.getPropertyValue(\"-moz-\" + prop );\n\t } else if (browser.opera) {\n\t val = style.getPropertyValue(\"-o-\" + prop);\n\t } else if (microsoft) {\n\t val = style.getPropertyValue(\"-ms-\" + prop);\n\t }\n\t }\n\t if (arguments.length > 2 && (val == null || val === \"\")) {\n\t return defa;\n\t } else {\n\t return val;\n\t }\n\t}\n\n\tfunction pleaseSetPropertyValue(style, prop, value, important) {\n\t style.setProperty(prop, value, important);\n\t if (browser.webkit) {\n\t style.setProperty(\"-webkit-\" + prop, value, important);\n\t } else if (browser.mozilla) {\n\t style.setProperty(\"-moz-\" + prop, value, important);\n\t } else if (browser.opera) {\n\t style.setProperty(\"-o-\" + prop, value, important);\n\t } else if (microsoft) {\n\t style.setProperty(\"-ms-\" + prop, value, important);\n\t prop = \"ms\" + prop.replace(/(^|-)([a-z])/g, function(s, p1, p2){\n\t return p1 + p2.toUpperCase();\n\t });\n\t style[prop] = value;\n\t }\n\t}\n\n\tfunction getBorder(style, side) {\n\t side = \"border-\" + side;\n\t return {\n\t width: parseFloat(getPropertyValue(style, side + \"-width\")),\n\t style: getPropertyValue(style, side + \"-style\"),\n\t color: parseColor$1(getPropertyValue(style, side + \"-color\"), true)\n\t };\n\t}\n\n\tfunction saveStyle(element, func) {\n\t var prev = element.style.cssText;\n\t var result = func();\n\t element.style.cssText = prev;\n\t return result;\n\t}\n\n\tfunction getBorderRadius(style, side) {\n\t var r = getPropertyValue(style, \"border-\" + side + \"-radius\").split(/\\s+/g).map(parseFloat);\n\t if (r.length == 1) {\n\t r.push(r[0]);\n\t }\n\t return sanitizeRadius({ x: r[0], y: r[1] });\n\t}\n\n\tfunction getContentBox(element) {\n\t var box = element.getBoundingClientRect();\n\t box = innerBox(box, \"border-*-width\", element);\n\t box = innerBox(box, \"padding-*\", element);\n\t return box;\n\t}\n\n\tfunction innerBox(box, prop, element) {\n\t var style, wt, wr, wb, wl;\n\t if (typeof prop == \"string\") {\n\t style = getComputedStyle(element);\n\t wt = parseFloat(getPropertyValue(style, prop.replace(\"*\", \"top\")));\n\t wr = parseFloat(getPropertyValue(style, prop.replace(\"*\", \"right\")));\n\t wb = parseFloat(getPropertyValue(style, prop.replace(\"*\", \"bottom\")));\n\t wl = parseFloat(getPropertyValue(style, prop.replace(\"*\", \"left\")));\n\t }\n\t else if (typeof prop == \"number\") {\n\t wt = wr = wb = wl = prop;\n\t }\n\t return {\n\t top : box.top + wt,\n\t right : box.right - wr,\n\t bottom : box.bottom - wb,\n\t left : box.left + wl,\n\t width : box.right - box.left - wr - wl,\n\t height : box.bottom - box.top - wb - wt\n\t };\n\t}\n\n\tfunction getTransform(style) {\n\t var transform$$1 = getPropertyValue(style, \"transform\");\n\t if (transform$$1 == \"none\") {\n\t return null;\n\t }\n\t var matrix = /^\\s*matrix\\(\\s*(.*?)\\s*\\)\\s*$/.exec(transform$$1);\n\t if (matrix) {\n\t var origin = getPropertyValue(style, \"transform-origin\");\n\t matrix = matrix[1].split(/\\s*,\\s*/g).map(parseFloat);\n\t origin = origin.split(/\\s+/g).map(parseFloat);\n\t return {\n\t matrix: matrix,\n\t origin: origin\n\t };\n\t }\n\t}\n\n\tfunction radiansToDegrees(radians) {\n\t return ((180 * radians) / Math.PI) % 360;\n\t}\n\n\tfunction parseAngle(angle) {\n\t var num = parseFloat(angle);\n\t if (/grad$/.test(angle)) {\n\t return Math.PI * num / 200;\n\t }\n\t else if (/rad$/.test(angle)) {\n\t return num;\n\t }\n\t else if (/turn$/.test(angle)) {\n\t return Math.PI * num * 2;\n\t }\n\t else if (/deg$/.test(angle)) {\n\t return Math.PI * num / 180;\n\t }\n\t}\n\n\tfunction setTransform(shape, m) {\n\t m = new Matrix(m[0], m[1], m[2], m[3], m[4], m[5]);\n\t shape.transform(m);\n\t return m;\n\t}\n\n\tfunction setClipping(shape, clipPath) {\n\t shape.clip(clipPath);\n\t}\n\n\tfunction addArcToPath(path, x, y, options) {\n\t var points = new Arc$2([ x, y ], options).curvePoints(), i = 1;\n\t while (i < points.length) {\n\t path.curveTo(points[i++], points[i++], points[i++]);\n\t }\n\t}\n\n\tfunction sanitizeRadius(r) {\n\t if (r.x <= 0 || r.y <= 0) {\n\t r.x = r.y = 0;\n\t }\n\t return r;\n\t}\n\n\tfunction adjustBorderRadiusForBox(box, rTL, rTR, rBR, rBL) {\n\t // adjust border radiuses such that the sum of adjacent\n\t // radiuses is not bigger than the length of the side.\n\t // seems the correct algorithm is variant (3) from here:\n\t // http://www.w3.org/Style/CSS/Tracker/issues/29?changelog\n\t var tl_x = Math.max(0, rTL.x), tl_y = Math.max(0, rTL.y);\n\t var tr_x = Math.max(0, rTR.x), tr_y = Math.max(0, rTR.y);\n\t var br_x = Math.max(0, rBR.x), br_y = Math.max(0, rBR.y);\n\t var bl_x = Math.max(0, rBL.x), bl_y = Math.max(0, rBL.y);\n\n\t var f = Math.min(\n\t box.width / (tl_x + tr_x),\n\t box.height / (tr_y + br_y),\n\t box.width / (br_x + bl_x),\n\t box.height / (bl_y + tl_y)\n\t );\n\n\t if (f < 1) {\n\t tl_x *= f; tl_y *= f;\n\t tr_x *= f; tr_y *= f;\n\t br_x *= f; br_y *= f;\n\t bl_x *= f; bl_y *= f;\n\t }\n\n\t return {\n\t tl: { x: tl_x, y: tl_y },\n\t tr: { x: tr_x, y: tr_y },\n\t br: { x: br_x, y: br_y },\n\t bl: { x: bl_x, y: bl_y }\n\t };\n\t}\n\n\tfunction elementRoundBox(element, box, type) {\n\t var style = getComputedStyle(element);\n\n\t var rTL = getBorderRadius(style, \"top-left\");\n\t var rTR = getBorderRadius(style, \"top-right\");\n\t var rBL = getBorderRadius(style, \"bottom-left\");\n\t var rBR = getBorderRadius(style, \"bottom-right\");\n\n\t if (type == \"padding\" || type == \"content\") {\n\t var bt = getBorder(style, \"top\");\n\t var br = getBorder(style, \"right\");\n\t var bb = getBorder(style, \"bottom\");\n\t var bl = getBorder(style, \"left\");\n\t rTL.x -= bl.width; rTL.y -= bt.width;\n\t rTR.x -= br.width; rTR.y -= bt.width;\n\t rBR.x -= br.width; rBR.y -= bb.width;\n\t rBL.x -= bl.width; rBL.y -= bb.width;\n\t if (type == \"content\") {\n\t var pt = parseFloat(getPropertyValue(style, \"padding-top\"));\n\t var pr = parseFloat(getPropertyValue(style, \"padding-right\"));\n\t var pb = parseFloat(getPropertyValue(style, \"padding-bottom\"));\n\t var pl = parseFloat(getPropertyValue(style, \"padding-left\"));\n\t rTL.x -= pl; rTL.y -= pt;\n\t rTR.x -= pr; rTR.y -= pt;\n\t rBR.x -= pr; rBR.y -= pb;\n\t rBL.x -= pl; rBL.y -= pb;\n\t }\n\t }\n\n\t if (typeof type == \"number\") {\n\t rTL.x -= type; rTL.y -= type;\n\t rTR.x -= type; rTR.y -= type;\n\t rBR.x -= type; rBR.y -= type;\n\t rBL.x -= type; rBL.y -= type;\n\t }\n\n\t return roundBox(box, rTL, rTR, rBR, rBL);\n\t}\n\n\t// Create a drawing.Path for a rounded rectangle. Receives the\n\t// bounding box and the border-radiuses in CSS order (top-left,\n\t// top-right, bottom-right, bottom-left). The radiuses must be\n\t// objects containing x (horiz. radius) and y (vertical radius).\n\tfunction roundBox(box, rTL0, rTR0, rBR0, rBL0) {\n\t var tmp = adjustBorderRadiusForBox(box, rTL0, rTR0, rBR0, rBL0);\n\t var rTL = tmp.tl;\n\t var rTR = tmp.tr;\n\t var rBR = tmp.br;\n\t var rBL = tmp.bl;\n\t var path = new Path({ fill: null, stroke: null });\n\t path.moveTo(box.left, box.top + rTL.y);\n\t if (rTL.x) {\n\t addArcToPath(path, box.left + rTL.x, box.top + rTL.y, {\n\t startAngle: -180,\n\t endAngle: -90,\n\t radiusX: rTL.x,\n\t radiusY: rTL.y\n\t });\n\t }\n\t path.lineTo(box.right - rTR.x, box.top);\n\t if (rTR.x) {\n\t addArcToPath(path, box.right - rTR.x, box.top + rTR.y, {\n\t startAngle: -90,\n\t endAngle: 0,\n\t radiusX: rTR.x,\n\t radiusY: rTR.y\n\t });\n\t }\n\t path.lineTo(box.right, box.bottom - rBR.y);\n\t if (rBR.x) {\n\t addArcToPath(path, box.right - rBR.x, box.bottom - rBR.y, {\n\t startAngle: 0,\n\t endAngle: 90,\n\t radiusX: rBR.x,\n\t radiusY: rBR.y\n\t });\n\t }\n\t path.lineTo(box.left + rBL.x, box.bottom);\n\t if (rBL.x) {\n\t addArcToPath(path, box.left + rBL.x, box.bottom - rBL.y, {\n\t startAngle: 90,\n\t endAngle: 180,\n\t radiusX: rBL.x,\n\t radiusY: rBL.y\n\t });\n\t }\n\t return path.close();\n\t}\n\n\tfunction formatCounter(val, style) {\n\t var str = String(parseFloat(val));\n\t switch (style) {\n\t case \"decimal-leading-zero\":\n\t if (str.length < 2) {\n\t str = \"0\" + str;\n\t }\n\t return str;\n\t case \"lower-roman\":\n\t return arabicToRoman(val).toLowerCase();\n\t case \"upper-roman\":\n\t return arabicToRoman(val).toUpperCase();\n\t case \"lower-latin\":\n\t case \"lower-alpha\":\n\t return alphaNumeral(val - 1);\n\t case \"upper-latin\":\n\t case \"upper-alpha\":\n\t return alphaNumeral(val - 1).toUpperCase();\n\t default:\n\t return str;\n\t }\n\t}\n\n\tfunction evalPseudoElementContent(element, content) {\n\t function displayCounter(name, style, separator) {\n\t if (!separator) {\n\t return formatCounter(getCounter(name) || 0, style);\n\t }\n\t separator = separator.replace(/^\\s*([\"'])(.*)\\1\\s*$/, \"$2\");\n\t return getAllCounters(name).map(function(val){\n\t return formatCounter(val, style);\n\t }).join(separator);\n\t }\n\t var a = splitProperty(content, /^\\s+/);\n\t var result = [], m;\n\t a.forEach(function(el){\n\t var tmp;\n\t if ((m = /^\\s*([\"'])(.*)\\1\\s*$/.exec(el))) {\n\t result.push(m[2].replace(/\\\\([0-9a-f]{4})/gi, function(s, p){\n\t return String.fromCharCode(parseInt(p, 16));\n\t }));\n\t }\n\t else if ((m = /^\\s*counter\\((.*?)\\)\\s*$/.exec(el))) {\n\t tmp = splitProperty(m[1]);\n\t result.push(displayCounter(tmp[0], tmp[1]));\n\t }\n\t else if ((m = /^\\s*counters\\((.*?)\\)\\s*$/.exec(el))) {\n\t tmp = splitProperty(m[1]);\n\t result.push(displayCounter(tmp[0], tmp[2], tmp[1]));\n\t }\n\t else if ((m = /^\\s*attr\\((.*?)\\)\\s*$/.exec(el))) {\n\t result.push(element.getAttribute(m[1]) || \"\");\n\t }\n\t else {\n\t result.push(el);\n\t }\n\t });\n\t return result.join(\"\");\n\t}\n\n\tfunction getCssText(style) {\n\t if (style.cssText) {\n\t return style.cssText;\n\t }\n\t // Status: NEW. Report year: 2002. Current year: 2014.\n\t // Nice played, Mozillians.\n\t // https://bugzilla.mozilla.org/show_bug.cgi?id=137687\n\t var result = [];\n\t for (var i = 0; i < style.length; ++i) {\n\t result.push(style[i] + \": \" + getPropertyValue(style, style[i]));\n\t }\n\t return result.join(\";\\n\");\n\t}\n\n\tfunction _renderWithPseudoElements(element, group) {\n\t if (element.tagName == KENDO_PSEUDO_ELEMENT) {\n\t _renderElement(element, group);\n\t return;\n\t }\n\t var fake = [];\n\t function pseudo(kind, place) {\n\t var style = getComputedStyle(element, kind), content = style.content;\n\t updateCounters(style);\n\t if (content && content != \"normal\" && content != \"none\" && style.width != \"0px\") {\n\t var psel = element.ownerDocument.createElement(KENDO_PSEUDO_ELEMENT);\n\t psel.style.cssText = getCssText(style);\n\t psel.textContent = evalPseudoElementContent(element, content);\n\t element.insertBefore(psel, place);\n\t fake.push(psel);\n\t }\n\t }\n\t pseudo(\":before\", element.firstChild);\n\t pseudo(\":after\", null);\n\t if (fake.length > 0) {\n\t var saveClass = element.className;\n\t element.className += \" kendo-pdf-hide-pseudo-elements\";\n\t _renderElement(element, group);\n\t element.className = saveClass;\n\t fake.forEach(function(el){ element.removeChild(el); });\n\t } else {\n\t _renderElement(element, group);\n\t }\n\t}\n\n\tfunction _renderElement(element, group) {\n\t var style = getComputedStyle(element);\n\n\t var top = getBorder(style, \"top\");\n\t var right = getBorder(style, \"right\");\n\t var bottom = getBorder(style, \"bottom\");\n\t var left = getBorder(style, \"left\");\n\n\t var rTL0 = getBorderRadius(style, \"top-left\");\n\t var rTR0 = getBorderRadius(style, \"top-right\");\n\t var rBL0 = getBorderRadius(style, \"bottom-left\");\n\t var rBR0 = getBorderRadius(style, \"bottom-right\");\n\n\t var dir = getPropertyValue(style, \"direction\");\n\n\t var backgroundColor = getPropertyValue(style, \"background-color\");\n\t backgroundColor = parseColor$1(backgroundColor);\n\n\t var backgroundImage = parseBackgroundImage( getPropertyValue(style, \"background-image\") );\n\t var backgroundRepeat = splitProperty( getPropertyValue(style, \"background-repeat\") );\n\t var backgroundPosition = splitProperty( getPropertyValue(style, \"background-position\") );\n\t var backgroundOrigin = splitProperty( getPropertyValue(style, \"background-origin\") );\n\t var backgroundSize = splitProperty( getPropertyValue(style, \"background-size\") );\n\n\t // IE shrinks the text with text-overflow: ellipsis,\n\t // apparently because the returned bounding box for the range\n\t // is limited to the visible area minus space for the dots,\n\t // instead of being the full width of the text.\n\t //\n\t // https://github.com/telerik/kendo/issues/5232\n\t // https://github.com/telerik/kendo-ui-core/issues/1868\n\t //\n\t // We have to test it here rather than in renderText because\n\t // text-overflow: ellipsis could be set on a parent element (not\n\t // necessarily the one containing the text); in this case,\n\t // getComputedStyle(elementWithTheText) will return \"clip\", not\n\t // \"ellipsis\" (which is probably a bug, but oh well...)\n\t var textOverflow, saveTextOverflow;\n\t if (microsoft) {\n\t textOverflow = style.textOverflow; // computed style\n\t if (textOverflow == \"ellipsis\") {\n\t saveTextOverflow = element.style.textOverflow; // own style.\n\t element.style.textOverflow = \"clip\";\n\t }\n\t }\n\n\t if (browser.msie && browser.version < 10) {\n\t // IE9 hacks. getPropertyValue won't return the correct\n\t // value. Sucks that we have to do it here, I'd prefer to\n\t // move it in getPropertyValue, but we don't have the\n\t // element.\n\t backgroundPosition = splitProperty(element.currentStyle.backgroundPosition);\n\t }\n\n\t var innerbox = innerBox(element.getBoundingClientRect(), \"border-*-width\", element);\n\n\t // CSS \"clip\" property - if present, replace the group with a\n\t // new one which is clipped. This must happen before drawing\n\t // the borders and background.\n\t (function(){\n\t var clip = getPropertyValue(style, \"clip\");\n\t var m = /^\\s*rect\\((.*)\\)\\s*$/.exec(clip);\n\t if (m) {\n\t var a = m[1].split(/[ ,]+/g);\n\t var top = a[0] == \"auto\" ? innerbox.top : parseFloat(a[0]) + innerbox.top;\n\t var right = a[1] == \"auto\" ? innerbox.right : parseFloat(a[1]) + innerbox.left;\n\t var bottom = a[2] == \"auto\" ? innerbox.bottom : parseFloat(a[2]) + innerbox.top;\n\t var left = a[3] == \"auto\" ? innerbox.left : parseFloat(a[3]) + innerbox.left;\n\t var tmp = new Group();\n\t var clipPath = new Path()\n\t .moveTo(left, top)\n\t .lineTo(right, top)\n\t .lineTo(right, bottom)\n\t .lineTo(left, bottom)\n\t .close();\n\t setClipping(tmp, clipPath);\n\t group.append(tmp);\n\t group = tmp;\n\t updateClipbox(clipPath);\n\t }\n\t })();\n\n\t var boxes, i, cells;\n\t var display = getPropertyValue(style, \"display\");\n\n\t if (display == \"table-row\") {\n\t // because of rowspan/colspan, we shouldn't draw background of table row elements on the\n\t // box given by its getBoundingClientRect, because if we do we risk overwritting a\n\t // previously rendered cell. https://github.com/telerik/kendo/issues/4881\n\t boxes = [];\n\t for (i = 0, cells = element.children; i < cells.length; ++i) {\n\t boxes.push(cells[i].getBoundingClientRect());\n\t }\n\t } else {\n\t boxes = element.getClientRects();\n\t if (boxes.length == 1) {\n\t // Workaround the missing borders in Chrome! getClientRects() boxes contains values\n\t // rounded to integer. getBoundingClientRect() appears to work fine. We still need\n\t // getClientRects() to support cases where there are more boxes (continued inline\n\t // elements that might have border/background).\n\t boxes = [ element.getBoundingClientRect() ];\n\t }\n\t }\n\n\t // This function workarounds another Chrome bug, where boxes returned for a table with\n\t // border-collapse: collapse will overlap the table border. Our rendering is not perfect in\n\t // such case anyway, but with this is better than without it.\n\t boxes = adjustBoxes(boxes);\n\n\t for (i = 0; i < boxes.length; ++i) {\n\t drawOneBox(boxes[i], i === 0, i == boxes.length - 1);\n\t }\n\n\t // Render links as separate groups. We can't use boxes returned by element's getClientRects\n\t // because if display type is \"inline\" (default for ), boxes will not include the height of\n\t // images inside. https://github.com/telerik/kendo-ui-core/issues/3359\n\t if (element.tagName == \"A\" && element.href && !/^#?$/.test(element.getAttribute(\"href\"))) {\n\t if (!nodeInfo._avoidLinks || !matches(element, nodeInfo._avoidLinks)) {\n\t var r = document.createRange();\n\t r.selectNodeContents(element);\n\t slice$1(r.getClientRects()).forEach(function(box){\n\t var g = new Group();\n\t g._pdfLink = {\n\t url : element.href,\n\t top : box.top,\n\t right : box.right,\n\t bottom : box.bottom,\n\t left : box.left\n\t };\n\t group.append(g);\n\t });\n\t }\n\t }\n\n\t if (boxes.length > 0 && display == \"list-item\" && !element.getAttribute(\"kendo-no-bullet\")) {\n\t drawBullet(boxes[0]);\n\t }\n\n\t // overflow: hidden/auto - if present, replace the group with\n\t // a new one clipped by the inner box.\n\t (function(){\n\t function clipit() {\n\t var clipPath = elementRoundBox(element, innerbox, \"padding\");\n\t var tmp = new Group();\n\t setClipping(tmp, clipPath);\n\t group.append(tmp);\n\t group = tmp;\n\t updateClipbox(clipPath);\n\t }\n\t if (isFormField(element)) {\n\t clipit();\n\t } else if (/^(hidden|auto|scroll)/.test(getPropertyValue(style, \"overflow\"))) {\n\t clipit();\n\t } else if (/^(hidden|auto|scroll)/.test(getPropertyValue(style, \"overflow-x\"))) {\n\t clipit();\n\t } else if (/^(hidden|auto|scroll)/.test(getPropertyValue(style, \"overflow-y\"))) {\n\t clipit();\n\t }\n\t })();\n\n\t if (!maybeRenderWidget(element, group)) {\n\t renderContents(element, group);\n\t }\n\n\t if (microsoft && textOverflow == \"ellipsis\") {\n\t element.style.textOverflow = saveTextOverflow;\n\t }\n\n\t return group; // only utility functions after this line.\n\n\t function adjustBoxes(boxes) {\n\t if (/^td$/i.test(element.tagName)) {\n\t var table = nodeInfo.table;\n\t if (table && getPropertyValue(table.style, \"border-collapse\") == \"collapse\") {\n\t var tableBorderLeft = getBorder(table.style, \"left\").width;\n\t var tableBorderTop = getBorder(table.style, \"top\").width;\n\t // check if we need to adjust\n\t if (tableBorderLeft === 0 && tableBorderTop === 0) {\n\t return boxes; // nope\n\t }\n\t var tableBox = table.element.getBoundingClientRect();\n\t var firstCell = table.element.rows[0].cells[0];\n\t var firstCellBox = firstCell.getBoundingClientRect();\n\t if (firstCellBox.top == tableBox.top || firstCellBox.left == tableBox.left) {\n\t return slice$1(boxes).map(function(box){\n\t return {\n\t left : box.left + tableBorderLeft,\n\t top : box.top + tableBorderTop,\n\t right : box.right + tableBorderLeft,\n\t bottom : box.bottom + tableBorderTop,\n\t height : box.height,\n\t width : box.width\n\t };\n\t });\n\t }\n\t }\n\t }\n\t return boxes;\n\t }\n\n\t // this function will be called to draw each border. it\n\t // draws starting at origin and the resulted path must be\n\t // translated/rotated to be placed in the proper position.\n\t //\n\t // arguments are named as if it draws the top border:\n\t //\n\t // - `len` the length of the edge\n\t // - `Wtop` the width of the edge (i.e. border-top-width)\n\t // - `Wleft` the width of the left edge (border-left-width)\n\t // - `Wright` the width of the right edge\n\t // - `rl` and `rl` -- the border radius on the left and right\n\t // (objects containing x and y, for horiz/vertical radius)\n\t // - `transform` -- transformation to apply\n\t //\n\t function drawEdge(color, len, Wtop, Wleft, Wright, rl, rr, transform$$1) {\n\t if (Wtop <= 0) {\n\t return;\n\t }\n\n\t var path, edge = new Group();\n\t setTransform(edge, transform$$1);\n\t group.append(edge);\n\n\t sanitizeRadius(rl);\n\t sanitizeRadius(rr);\n\n\t // draw main border. this is the area without the rounded corners\n\t path = new Path({\n\t fill: { color: color },\n\t stroke: null\n\t });\n\t edge.append(path);\n\t path.moveTo(rl.x ? Math.max(rl.x, Wleft) : 0, 0)\n\t .lineTo(len - (rr.x ? Math.max(rr.x, Wright) : 0), 0)\n\t .lineTo(len - Math.max(rr.x, Wright), Wtop)\n\t .lineTo(Math.max(rl.x, Wleft), Wtop)\n\t .close();\n\n\t if (rl.x) {\n\t drawRoundCorner(Wleft, rl, [ -1, 0, 0, 1, rl.x, 0 ]);\n\t }\n\n\t if (rr.x) {\n\t drawRoundCorner(Wright, rr, [ 1, 0, 0, 1, len - rr.x, 0 ]);\n\t }\n\n\t // draws one round corner, starting at origin (needs to be\n\t // translated/rotated to be placed properly).\n\t function drawRoundCorner(Wright, r, transform$$1) {\n\t var angle = Math.PI/2 * Wright / (Wright + Wtop);\n\n\t // not sanitizing this one, because negative values\n\t // are useful to fill the box correctly.\n\t var ri = {\n\t x: r.x - Wright,\n\t y: r.y - Wtop\n\t };\n\n\t var path = new Path({\n\t fill: { color: color },\n\t stroke: null\n\t }).moveTo(0, 0);\n\n\t setTransform(path, transform$$1);\n\n\t addArcToPath(path, 0, r.y, {\n\t startAngle: -90,\n\t endAngle: -radiansToDegrees(angle),\n\t radiusX: r.x,\n\t radiusY: r.y\n\t });\n\n\t if (ri.x > 0 && ri.y > 0) {\n\t path.lineTo(ri.x * Math.cos(angle), r.y - ri.y * Math.sin(angle));\n\t addArcToPath(path, 0, r.y, {\n\t startAngle: -radiansToDegrees(angle),\n\t endAngle: -90,\n\t radiusX: ri.x,\n\t radiusY: ri.y,\n\t anticlockwise: true\n\t });\n\t }\n\t else if (ri.x > 0) {\n\t path.lineTo(ri.x, Wtop)\n\t .lineTo(0, Wtop);\n\t }\n\t else {\n\t path.lineTo(ri.x, Wtop)\n\t .lineTo(ri.x, 0);\n\t }\n\n\t edge.append(path.close());\n\t }\n\t }\n\n\t function drawBackground(box) {\n\t var background = new Group();\n\t setClipping(background, roundBox(box, rTL0, rTR0, rBR0, rBL0));\n\t group.append(background);\n\n\t if (backgroundColor) {\n\t var path = new Path({\n\t fill: { color: backgroundColor.toCssRgba() },\n\t stroke: null\n\t });\n\t path.moveTo(box.left, box.top)\n\t .lineTo(box.right, box.top)\n\t .lineTo(box.right, box.bottom)\n\t .lineTo(box.left, box.bottom)\n\t .close();\n\t background.append(path);\n\t }\n\n\t for (var i = backgroundImage.length; --i >= 0;) {\n\t drawOneBackground(\n\t background, box,\n\t backgroundImage[i],\n\t backgroundRepeat[i % backgroundRepeat.length],\n\t backgroundPosition[i % backgroundPosition.length],\n\t backgroundOrigin[i % backgroundOrigin.length],\n\t backgroundSize[i % backgroundSize.length]\n\t );\n\t }\n\t }\n\n\t function drawOneBackground(group, box, background, backgroundRepeat, backgroundPosition, backgroundOrigin, backgroundSize) {\n\t if (!background || (background == \"none\")) {\n\t return;\n\t }\n\n\t if (background.type == \"url\") {\n\t // SVG taints the canvas, can't draw it.\n\t if (/^url\\(\\\"data:image\\/svg/i.test(background.url)) {\n\t return;\n\t }\n\t var img = IMAGE_CACHE[background.url];\n\t if (img && img.width > 0 && img.height > 0) {\n\t drawBackgroundImage(group, box, img.width, img.height, function(group, rect){\n\t group.append(new Image$1(background.url, rect));\n\t });\n\t }\n\t } else if (background.type == \"linear\") {\n\t drawBackgroundImage(group, box, box.width, box.height, gradientRenderer(background));\n\t } else {\n\t return;\n\t }\n\n\t function drawBackgroundImage(group, box, img_width, img_height, renderBG) {\n\t var aspect_ratio = img_width / img_height, f;\n\n\t // for background-origin: border-box the box is already appropriate\n\t var orgBox = box;\n\t if (backgroundOrigin == \"content-box\") {\n\t orgBox = innerBox(orgBox, \"border-*-width\", element);\n\t orgBox = innerBox(orgBox, \"padding-*\", element);\n\t } else if (backgroundOrigin == \"padding-box\") {\n\t orgBox = innerBox(orgBox, \"border-*-width\", element);\n\t }\n\n\t if (!/^\\s*auto(\\s+auto)?\\s*$/.test(backgroundSize)) {\n\t if (backgroundSize == \"contain\") {\n\t f = Math.min(orgBox.width / img_width,\n\t orgBox.height / img_height);\n\t img_width *= f;\n\t img_height *= f;\n\t }\n\t else if (backgroundSize == \"cover\") {\n\t f = Math.max(orgBox.width / img_width,\n\t orgBox.height / img_height);\n\t img_width *= f;\n\t img_height *= f;\n\t }\n\t else {\n\t var size = backgroundSize.split(/\\s+/g);\n\t // compute width\n\t if (/%$/.test(size[0])) {\n\t img_width = orgBox.width * parseFloat(size[0]) / 100;\n\t } else {\n\t img_width = parseFloat(size[0]);\n\t }\n\t // compute height\n\t if (size.length == 1 || size[1] == \"auto\") {\n\t img_height = img_width / aspect_ratio;\n\t } else if (/%$/.test(size[1])) {\n\t img_height = orgBox.height * parseFloat(size[1]) / 100;\n\t } else {\n\t img_height = parseFloat(size[1]);\n\t }\n\t }\n\t }\n\n\t var pos = String(backgroundPosition);\n\n\t // IE sometimes reports single-word positions\n\t // https://github.com/telerik/kendo-ui-core/issues/2786\n\t //\n\t // it seems to switch to percentages when the horizontal\n\t // position is not \"center\", therefore we don't handle\n\t // multi-word cases here. All other browsers return\n\t // percentages or pixels instead of keywords. At least\n\t // for now...\n\t switch (pos) {\n\t case \"bottom\" : pos = \"50% 100%\"; break;\n\t case \"top\" : pos = \"50% 0\"; break;\n\t case \"left\" : pos = \"0 50%\"; break;\n\t case \"right\" : pos = \"100% 50%\"; break;\n\t case \"center\" : pos = \"50% 50%\"; break;\n\t }\n\n\t pos = pos.split(/\\s+/);\n\t if (pos.length == 1) {\n\t pos[1] = \"50%\";\n\t }\n\n\t if (/%$/.test(pos[0])) {\n\t pos[0] = parseFloat(pos[0]) / 100 * (orgBox.width - img_width);\n\t } else {\n\t pos[0] = parseFloat(pos[0]);\n\t }\n\t if (/%$/.test(pos[1])) {\n\t pos[1] = parseFloat(pos[1]) / 100 * (orgBox.height - img_height);\n\t } else {\n\t pos[1] = parseFloat(pos[1]);\n\t }\n\n\t var rect = new Rect([ orgBox.left + pos[0], orgBox.top + pos[1] ], [ img_width, img_height ]);\n\n\t // XXX: background-repeat could be implemented more\n\t // efficiently as a fill pattern (at least for PDF\n\t // output, probably SVG too).\n\n\t function rewX() {\n\t while (rect.origin.x > box.left) {\n\t rect.origin.x -= img_width;\n\t }\n\t }\n\n\t function rewY() {\n\t while (rect.origin.y > box.top) {\n\t rect.origin.y -= img_height;\n\t }\n\t }\n\n\t function repeatX() {\n\t while (rect.origin.x < box.right) {\n\t renderBG(group, rect.clone());\n\t rect.origin.x += img_width;\n\t }\n\t }\n\n\t if (backgroundRepeat == \"no-repeat\") {\n\t renderBG(group, rect);\n\t }\n\t else if (backgroundRepeat == \"repeat-x\") {\n\t rewX();\n\t repeatX();\n\t }\n\t else if (backgroundRepeat == \"repeat-y\") {\n\t rewY();\n\t while (rect.origin.y < box.bottom) {\n\t renderBG(group, rect.clone());\n\t rect.origin.y += img_height;\n\t }\n\t }\n\t else if (backgroundRepeat == \"repeat\") {\n\t rewX();\n\t rewY();\n\t var origin = rect.origin.clone();\n\t while (rect.origin.y < box.bottom) {\n\t rect.origin.x = origin.x;\n\t repeatX();\n\t rect.origin.y += img_height;\n\t }\n\t }\n\t }\n\t }\n\n\t function drawBullet() {\n\t var listStyleType = getPropertyValue(style, \"list-style-type\");\n\t if (listStyleType == \"none\") {\n\t return;\n\t }\n\t var listStylePosition = getPropertyValue(style, \"list-style-position\");\n\n\t function _drawBullet(f) {\n\t saveStyle(element, function(){\n\t element.style.position = \"relative\";\n\t var bullet = element.ownerDocument.createElement(KENDO_PSEUDO_ELEMENT);\n\t bullet.style.position = \"absolute\";\n\t bullet.style.boxSizing = \"border-box\";\n\t if (listStylePosition == \"outside\") {\n\t bullet.style.width = \"6em\";\n\t bullet.style.left = \"-6.8em\";\n\t bullet.style.textAlign = \"right\";\n\t } else {\n\t bullet.style.left = \"0px\";\n\t }\n\t f(bullet);\n\t element.insertBefore(bullet, element.firstChild);\n\t renderElement(bullet, group);\n\t element.removeChild(bullet);\n\t });\n\t }\n\n\t function elementIndex(f) {\n\t var a = element.parentNode.children;\n\t var k = element.getAttribute(\"kendo-split-index\");\n\t if (k != null) {\n\t return f(k|0, a.length);\n\t }\n\t for (var i = 0; i < a.length; ++i) {\n\t if (a[i] === element) {\n\t return f(i, a.length);\n\t }\n\t }\n\t }\n\n\t switch (listStyleType) {\n\t case \"circle\":\n\t case \"disc\":\n\t case \"square\":\n\t _drawBullet(function(bullet){\n\t // XXX: the science behind these values is called \"trial and error\".\n\t bullet.style.fontSize = \"60%\";\n\t bullet.style.lineHeight = \"200%\";\n\t bullet.style.paddingRight = \"0.5em\";\n\t bullet.style.fontFamily = \"DejaVu Serif\";\n\t bullet.innerHTML = {\n\t \"disc\" : \"\\u25cf\",\n\t \"circle\" : \"\\u25ef\",\n\t \"square\" : \"\\u25a0\"\n\t }[listStyleType];\n\t });\n\t break;\n\n\t case \"decimal\":\n\t case \"decimal-leading-zero\":\n\t _drawBullet(function(bullet){\n\t elementIndex(function(idx){\n\t ++idx;\n\t if (listStyleType == \"decimal-leading-zero\" && idx < 10) {\n\t idx = \"0\" + idx;\n\t }\n\t bullet.innerHTML = idx + \".\";\n\t });\n\t });\n\t break;\n\n\t case \"lower-roman\":\n\t case \"upper-roman\":\n\t _drawBullet(function(bullet){\n\t elementIndex(function(idx){\n\t idx = arabicToRoman(idx + 1);\n\t if (listStyleType == \"upper-roman\") {\n\t idx = idx.toUpperCase();\n\t }\n\t bullet.innerHTML = idx + \".\";\n\t });\n\t });\n\t break;\n\n\t case \"lower-latin\":\n\t case \"lower-alpha\":\n\t case \"upper-latin\":\n\t case \"upper-alpha\":\n\t _drawBullet(function(bullet){\n\t elementIndex(function(idx){\n\t idx = alphaNumeral(idx);\n\t if (/^upper/i.test(listStyleType)) {\n\t idx = idx.toUpperCase();\n\t }\n\t bullet.innerHTML = idx + \".\";\n\t });\n\t });\n\t break;\n\t }\n\t }\n\n\t // draws a single border box\n\t function drawOneBox(box, isFirst, isLast) {\n\t if (box.width === 0 || box.height === 0) {\n\t return;\n\t }\n\n\t drawBackground(box);\n\n\t var shouldDrawLeft = (left.width > 0 && ((isFirst && dir == \"ltr\") || (isLast && dir == \"rtl\")));\n\t var shouldDrawRight = (right.width > 0 && ((isLast && dir == \"ltr\") || (isFirst && dir == \"rtl\")));\n\n\t // The most general case is that the 4 borders have different widths and border\n\t // radiuses. The way that is handled is by drawing 3 Paths for each border: the\n\t // straight line, and two round corners which represent half of the entire rounded\n\t // corner. To simplify code those shapes are drawed at origin (by the drawEdge\n\t // function), then translated/rotated into the right position.\n\t //\n\t // However, this leads to poor results due to rounding in the simpler cases where\n\t // borders are straight lines. Therefore we handle a few such cases separately with\n\t // straight lines. C^wC^wC^w -- nope, scratch that. poor rendering was because of a bug\n\t // in Chrome (getClientRects() returns rounded integer values rather than exact floats.\n\t // web dev is still a ghetto.)\n\n\t // first, just in case there is no border...\n\t if (top.width === 0 && left.width === 0 && right.width === 0 && bottom.width === 0) {\n\t return;\n\t }\n\n\t // START paint borders\n\t // if all borders have equal colors...\n\t if (top.color == right.color && top.color == bottom.color && top.color == left.color) {\n\n\t // if same widths too, we can draw the whole border by stroking a single path.\n\t if (top.width == right.width && top.width == bottom.width && top.width == left.width)\n\t {\n\t if (shouldDrawLeft && shouldDrawRight) {\n\t // reduce box by half the border width, so we can draw it by stroking.\n\t box = innerBox(box, top.width/2);\n\n\t // adjust the border radiuses, again by top.width/2, and make the path element.\n\t var path = elementRoundBox(element, box, top.width/2);\n\t path.options.stroke = {\n\t color: top.color,\n\t width: top.width\n\t };\n\t group.append(path);\n\t return;\n\t }\n\t }\n\t }\n\n\t // if border radiuses are zero and widths are at most one pixel, we can again use simple\n\t // paths.\n\t if (rTL0.x === 0 && rTR0.x === 0 && rBR0.x === 0 && rBL0.x === 0) {\n\t // alright, 1.9px will do as well. the difference in color blending should not be\n\t // noticeable.\n\t if (top.width < 2 && left.width < 2 && right.width < 2 && bottom.width < 2) {\n\t // top border\n\t if (top.width > 0) {\n\t group.append(\n\t new Path({\n\t stroke: { width: top.width, color: top.color }\n\t })\n\t .moveTo(box.left, box.top + top.width/2)\n\t .lineTo(box.right, box.top + top.width/2)\n\t );\n\t }\n\n\t // bottom border\n\t if (bottom.width > 0) {\n\t group.append(\n\t new Path({\n\t stroke: { width: bottom.width, color: bottom.color }\n\t })\n\t .moveTo(box.left, box.bottom - bottom.width/2)\n\t .lineTo(box.right, box.bottom - bottom.width/2)\n\t );\n\t }\n\n\t // left border\n\t if (shouldDrawLeft) {\n\t group.append(\n\t new Path({\n\t stroke: { width: left.width, color: left.color }\n\t })\n\t .moveTo(box.left + left.width/2, box.top)\n\t .lineTo(box.left + left.width/2, box.bottom)\n\t );\n\t }\n\n\t // right border\n\t if (shouldDrawRight) {\n\t group.append(\n\t new Path({\n\t stroke: { width: right.width, color: right.color }\n\t })\n\t .moveTo(box.right - right.width/2, box.top)\n\t .lineTo(box.right - right.width/2, box.bottom)\n\t );\n\t }\n\n\t return;\n\t }\n\t }\n\t // END paint borders\n\n\t var tmp = adjustBorderRadiusForBox(box, rTL0, rTR0, rBR0, rBL0);\n\t var rTL = tmp.tl;\n\t var rTR = tmp.tr;\n\t var rBR = tmp.br;\n\t var rBL = tmp.bl;\n\n\t // top border\n\t drawEdge(top.color,\n\t box.width, top.width, left.width, right.width,\n\t rTL, rTR,\n\t [ 1, 0, 0, 1, box.left, box.top ]);\n\n\t // bottom border\n\t drawEdge(bottom.color,\n\t box.width, bottom.width, right.width, left.width,\n\t rBR, rBL,\n\t [ -1, 0, 0, -1, box.right, box.bottom ]);\n\n\t // for left/right borders we need to invert the border-radiuses\n\t function inv(p) {\n\t return { x: p.y, y: p.x };\n\t }\n\n\t // left border\n\t drawEdge(left.color,\n\t box.height, left.width, bottom.width, top.width,\n\t inv(rBL), inv(rTL),\n\t [ 0, -1, 1, 0, box.left, box.bottom ]);\n\n\t // right border\n\t drawEdge(right.color,\n\t box.height, right.width, top.width, bottom.width,\n\t inv(rTR), inv(rBR),\n\t [ 0, 1, -1, 0, box.right, box.top ]);\n\t }\n\t}\n\n\tfunction gradientRenderer(gradient) {\n\t return function(group, rect) {\n\t var width = rect.width(), height = rect.height();\n\n\t switch (gradient.type) {\n\t case \"linear\":\n\n\t // figure out the angle.\n\t var angle = gradient.angle != null ? gradient.angle : Math.PI;\n\t switch (gradient.to) {\n\t case \"top\":\n\t angle = 0;\n\t break;\n\t case \"left\":\n\t angle = -Math.PI / 2;\n\t break;\n\t case \"bottom\":\n\t angle = Math.PI;\n\t break;\n\t case \"right\":\n\t angle = Math.PI / 2;\n\t break;\n\t case \"top left\": case \"left top\":\n\t angle = -Math.atan2(height, width);\n\t break;\n\t case \"top right\": case \"right top\":\n\t angle = Math.atan2(height, width);\n\t break;\n\t case \"bottom left\": case \"left bottom\":\n\t angle = Math.PI + Math.atan2(height, width);\n\t break;\n\t case \"bottom right\": case \"right bottom\":\n\t angle = Math.PI - Math.atan2(height, width);\n\t break;\n\t }\n\n\t if (gradient.reverse) {\n\t angle -= Math.PI;\n\t }\n\n\t // limit the angle between 0..2PI\n\t angle %= 2 * Math.PI;\n\t if (angle < 0) {\n\t angle += 2 * Math.PI;\n\t }\n\n\t // compute gradient's start/end points. here len is the length of the gradient line\n\t // and x,y is the end point relative to the center of the rectangle in conventional\n\t // (math) axis direction.\n\n\t // this is the original (unscaled) length of the gradient line. needed to deal with\n\t // absolutely positioned color stops. formula from the CSS spec:\n\t // http://dev.w3.org/csswg/css-images-3/#linear-gradient-syntax\n\t var pxlen = Math.abs(width * Math.sin(angle)) + Math.abs(height * Math.cos(angle));\n\n\t // The math below is pretty simple, but it took a while to figure out. We compute x\n\t // and y, the *end* of the gradient line. However, we want to transform them into\n\t // element-based coordinates (SVG's gradientUnits=\"objectBoundingBox\"). That means,\n\t // x=0 is the left edge, x=1 is the right edge, y=0 is the top edge and y=1 is the\n\t // bottom edge.\n\t //\n\t // A naive approach would use the original angle for these calculations. Say we'd\n\t // like to draw a gradient angled at 45deg in a 100x400 box. When we use\n\t // objectBoundingBox, the renderer will draw it in a 1x1 *square* box, and then\n\t // scale that to the desired dimensions. The 45deg angle will look more like 70deg\n\t // after scaling. SVG (http://www.w3.org/TR/SVG/pservers.html#LinearGradients) says\n\t // the following:\n\t //\n\t // When gradientUnits=\"objectBoundingBox\" and 'gradientTransform' is the\n\t // identity matrix, the normal of the linear gradient is perpendicular to the\n\t // gradient vector in object bounding box space (i.e., the abstract coordinate\n\t // system where (0,0) is at the top/left of the object bounding box and (1,1) is\n\t // at the bottom/right of the object bounding box). When the object's bounding\n\t // box is not square, the gradient normal which is initially perpendicular to\n\t // the gradient vector within object bounding box space may render\n\t // non-perpendicular relative to the gradient vector in user space. If the\n\t // gradient vector is parallel to one of the axes of the bounding box, the\n\t // gradient normal will remain perpendicular. This transformation is due to\n\t // application of the non-uniform scaling transformation from bounding box space\n\t // to user space.\n\t //\n\t // which is an extremely long and confusing way to tell what I just said above.\n\t //\n\t // For this reason we need to apply the reverse scaling to the original angle, so\n\t // that when it'll finally be rendered it'll actually be at the desired slope. Now\n\t // I'll let you figure out the math yourself.\n\n\t var scaledAngle = Math.atan(width * Math.tan(angle) / height);\n\t var sin = Math.sin(scaledAngle), cos = Math.cos(scaledAngle);\n\t var len = Math.abs(sin) + Math.abs(cos);\n\t var x = len/2 * sin;\n\t var y = len/2 * cos;\n\n\t // Because of the arctangent, our scaledAngle ends up between -PI/2..PI/2, possibly\n\t // losing the intended direction of the gradient. The following fixes it.\n\t if (angle > Math.PI/2 && angle <= 3*Math.PI/2) {\n\t x = -x;\n\t y = -y;\n\t }\n\n\t // compute the color stops.\n\t var implicit = [], right = 0;\n\t var stops = gradient.stops.map(function(s, i){\n\t var offset = s.percent;\n\t if (offset) {\n\t offset = parseFloat(offset) / 100;\n\t } else if (s.length) {\n\t offset = parseFloat(s.length) / pxlen;\n\t } else if (i === 0) {\n\t offset = 0;\n\t } else if (i == gradient.stops.length - 1) {\n\t offset = 1;\n\t }\n\t var stop = {\n\t color: s.color.toCssRgba(),\n\t offset: offset\n\t };\n\t if (offset != null) {\n\t right = offset;\n\t // fix implicit offsets\n\t implicit.forEach(function(s, i){\n\t var stop = s.stop;\n\t stop.offset = s.left + (right - s.left) * (i + 1) / (implicit.length + 1);\n\t });\n\t implicit = [];\n\t } else {\n\t implicit.push({ left: right, stop: stop });\n\t }\n\t return stop;\n\t });\n\n\t var start = [ 0.5 - x, 0.5 + y ];\n\t var end = [ 0.5 + x, 0.5 - y ];\n\n\t // finally, draw it.\n\t group.append(\n\t Path.fromRect(rect)\n\t .stroke(null)\n\t .fill(new LinearGradient({\n\t start : start,\n\t end : end,\n\t stops : stops,\n\t userSpace : false\n\t }))\n\t );\n\t break;\n\t case \"radial\":\n\t // XXX:\n\t if (window.console && window.console.log) {\n\t window.console.log(\"Radial gradients are not yet supported in HTML renderer\");\n\t }\n\t break;\n\t }\n\t };\n\t}\n\n\tfunction maybeRenderWidget(element, group) {\n\t var visual;\n\n\t if (element._kendoExportVisual) {\n\t visual = element._kendoExportVisual();\n\t } else if (window.kendo && window.kendo.jQuery && element.getAttribute(window.kendo.attr(\"role\"))) {\n\t var widget = window.kendo.widgetInstance(window.kendo.jQuery(element));\n\t if (widget && (widget.exportDOMVisual || widget.exportVisual)) {\n\t if (widget.exportDOMVisual) {\n\t visual = widget.exportDOMVisual();\n\t } else {\n\t visual = widget.exportVisual();\n\t }\n\t }\n\t }\n\n\t if (!visual) {\n\t return false;\n\t }\n\n\t var wrap$$1 = new Group();\n\t wrap$$1.children.push(visual);\n\n\t var bbox = element.getBoundingClientRect();\n\t wrap$$1.transform(transform().translate(bbox.left, bbox.top));\n\n\t group.append(wrap$$1);\n\n\t return true;\n\t}\n\n\tfunction renderImage(element, url, group) {\n\t var box = getContentBox(element);\n\t var rect = new Rect([ box.left, box.top ], [ box.width, box.height ]);\n\t var image = new Image$1(url, rect);\n\t setClipping(image, elementRoundBox(element, box, \"content\"));\n\t group.append(image);\n\t}\n\n\tfunction zIndexSort(a, b) {\n\t var sa = getComputedStyle(a);\n\t var sb = getComputedStyle(b);\n\t var za = parseFloat(getPropertyValue(sa, \"z-index\"));\n\t var zb = parseFloat(getPropertyValue(sb, \"z-index\"));\n\t var pa = getPropertyValue(sa, \"position\");\n\t var pb = getPropertyValue(sb, \"position\");\n\t if (isNaN(za) && isNaN(zb)) {\n\t if ((/static|absolute/.test(pa)) && (/static|absolute/.test(pb))) {\n\t return 0;\n\t }\n\t if (pa == \"static\") {\n\t return -1;\n\t }\n\t if (pb == \"static\") {\n\t return 1;\n\t }\n\t return 0;\n\t }\n\t if (isNaN(za)) {\n\t return zb === 0 ? 0 : zb > 0 ? -1 : 1;\n\t }\n\t if (isNaN(zb)) {\n\t return za === 0 ? 0 : za > 0 ? 1 : -1;\n\t }\n\t return parseFloat(za) - parseFloat(zb);\n\t}\n\n\tfunction isFormField(element) {\n\t return /^(?:textarea|select|input)$/i.test(element.tagName);\n\t}\n\n\tfunction getSelectedOption(element) {\n\t if (element.selectedOptions && element.selectedOptions.length > 0) {\n\t return element.selectedOptions[0];\n\t }\n\t return element.options[element.selectedIndex];\n\t}\n\n\tfunction renderCheckbox(element, group) {\n\t var style = getComputedStyle(element);\n\t var color = getPropertyValue(style, \"color\");\n\t var box = element.getBoundingClientRect();\n\t if (element.type == \"checkbox\") {\n\t group.append(\n\t Path.fromRect(\n\t new Rect([ box.left+1, box.top+1 ],\n\t [ box.width-2, box.height-2 ])\n\t ).stroke(color, 1)\n\t );\n\t if (element.checked) {\n\t // fill a rectangle inside? looks kinda ugly.\n\t // group.append(\n\t // Path.fromRect(\n\t // new geo.Rect([ box.left+4, box.top+4 ],\n\t // [ box.width-8, box.height-8])\n\t // ).fill(color).stroke(null)\n\t // );\n\n\t // let's draw a checkmark instead. artistic, eh?\n\t group.append(\n\t new Path()\n\t .stroke(color, 1.2)\n\t .moveTo(box.left + 0.22 * box.width,\n\t box.top + 0.55 * box.height)\n\t .lineTo(box.left + 0.45 * box.width,\n\t box.top + 0.75 * box.height)\n\t .lineTo(box.left + 0.78 * box.width,\n\t box.top + 0.22 * box.width)\n\t );\n\t }\n\t } else {\n\t group.append(\n\t new Circle(\n\t new Circle$2([\n\t (box.left + box.right) / 2,\n\t (box.top + box.bottom) / 2\n\t ], Math.min(box.width-2, box.height-2) / 2)\n\t ).stroke(color, 1)\n\t );\n\t if (element.checked) {\n\t group.append(\n\t new Circle(\n\t new Circle$2([\n\t (box.left + box.right) / 2,\n\t (box.top + box.bottom) / 2\n\t ], Math.min(box.width-8, box.height-8) / 2)\n\t ).fill(color).stroke(null)\n\t );\n\t }\n\t }\n\t}\n\n\tfunction renderFormField(element, group) {\n\t var tag = element.tagName.toLowerCase();\n\t if (tag == \"input\" && (element.type == \"checkbox\" || element.type == \"radio\")) {\n\t return renderCheckbox(element, group);\n\t }\n\t var p = element.parentNode;\n\t var doc = element.ownerDocument;\n\t var el = doc.createElement(KENDO_PSEUDO_ELEMENT);\n\t var option;\n\t el.style.cssText = getCssText(getComputedStyle(element));\n\t if (tag == \"input\") {\n\t el.style.whiteSpace = \"pre\";\n\t }\n\t if (tag == \"select\" || tag == \"textarea\") {\n\t el.style.overflow = \"auto\";\n\t }\n\t if (tag == \"select\") {\n\t if (element.multiple) {\n\t for (var i = 0; i < element.options.length; ++i) {\n\t option = doc.createElement(KENDO_PSEUDO_ELEMENT);\n\t option.style.cssText = getCssText(getComputedStyle(element.options[i]));\n\t option.style.display = \"block\"; // IE9 messes up without this\n\t option.textContent = element.options[i].textContent;\n\t el.appendChild(option);\n\t }\n\t } else {\n\t option = getSelectedOption(element);\n\t if (option) {\n\t el.textContent = option.textContent;\n\t }\n\t }\n\t } else {\n\t el.textContent = element.value;\n\t }\n\t p.insertBefore(el, element);\n\t el.scrollLeft = element.scrollLeft;\n\t el.scrollTop = element.scrollTop;\n\n\t // must temporarily hide the original element, otherwise it\n\t // may affect layout of the fake element we want to render.\n\t element.style.display = \"none\";\n\n\t renderContents(el, group);\n\t element.style.display = \"\";\n\t p.removeChild(el);\n\t}\n\n\tfunction renderContents(element, group) {\n\t if (nodeInfo._stackingContext.element === element) {\n\t // the group that was set in pushNodeInfo might have\n\t // changed due to clipping/transforms, update it here.\n\t nodeInfo._stackingContext.group = group;\n\t }\n\t switch (element.tagName.toLowerCase()) {\n\t case \"img\":\n\t renderImage(element, element.src, group);\n\t break;\n\n\t case \"canvas\":\n\t try {\n\t renderImage(element, element.toDataURL(\"image/png\"), group);\n\t } catch (ex) {\n\t // tainted; can't draw it, ignore.\n\t }\n\t break;\n\n\t case \"textarea\":\n\t case \"input\":\n\t case \"select\":\n\t renderFormField(element, group);\n\t break;\n\n\t default:\n\t var children = [], floats = [], positioned = [];\n\t for (var i = element.firstChild; i; i = i.nextSibling) {\n\t switch (i.nodeType) {\n\t case 3: // Text\n\t if (/\\S/.test(i.data)) {\n\t renderText(element, i, group);\n\t }\n\t break;\n\t case 1: // Element\n\t var style = getComputedStyle(i);\n\t var floating = getPropertyValue(style, \"float\");\n\t var position = getPropertyValue(style, \"position\");\n\t if (position != \"static\") {\n\t positioned.push(i);\n\t }\n\t else if (floating != \"none\") {\n\t floats.push(i);\n\t } else {\n\t children.push(i);\n\t }\n\t break;\n\t }\n\t }\n\n\t mergeSort(children, zIndexSort).forEach(function(el){ renderElement(el, group); });\n\t mergeSort(floats, zIndexSort).forEach(function(el){ renderElement(el, group); });\n\t mergeSort(positioned, zIndexSort).forEach(function(el){ renderElement(el, group); });\n\t }\n\t}\n\n\tfunction renderText(element, node, group) {\n\t if (emptyClipbox()) {\n\t return;\n\t }\n\t var style = getComputedStyle(element);\n\n\t if (parseFloat(getPropertyValue(style, \"text-indent\")) < -500) {\n\t // assume it should not be displayed. the slider's\n\t // draggable handle displays a Drag text for some reason,\n\t // having text-indent: -3333px.\n\t return;\n\t }\n\n\t var text = node.data;\n\t var start = 0;\n\t var end = text.search(/\\S\\s*$/) + 1;\n\n\t if (!end) {\n\t return; // whitespace-only node\n\t }\n\n\t var fontSize = getPropertyValue(style, \"font-size\");\n\t var lineHeight = getPropertyValue(style, \"line-height\");\n\n\t // simply getPropertyValue(\"font\") doesn't work in Firefox :-\\\n\t var font = [\n\t getPropertyValue(style, \"font-style\"),\n\t getPropertyValue(style, \"font-variant\"),\n\t getPropertyValue(style, \"font-weight\"),\n\t fontSize, // no need for line height here; it breaks layout in FF\n\t getPropertyValue(style, \"font-family\")\n\t ].join(\" \");\n\n\t fontSize = parseFloat(fontSize);\n\t lineHeight = parseFloat(lineHeight);\n\n\t if (fontSize === 0) {\n\t return;\n\t }\n\n\t var color = getPropertyValue(style, \"color\");\n\t var range = element.ownerDocument.createRange();\n\t var align$$1 = getPropertyValue(style, \"text-align\");\n\t var isJustified = align$$1 == \"justify\";\n\t var columnCount = getPropertyValue(style, \"column-count\", 1);\n\t var whiteSpace = getPropertyValue(style, \"white-space\");\n\t var textTransform = getPropertyValue(style, \"text-transform\");\n\n\t // A line of 500px, with a font of 12px, contains an average of 80 characters, but since we\n\t // err, we'd like to guess a bigger number rather than a smaller one. Multiplying by 5\n\t // seems to be a good option.\n\t var estimateLineLength = element.getBoundingClientRect().width / fontSize * 5;\n\t if (estimateLineLength === 0) {\n\t estimateLineLength = 500;\n\t }\n\n\t // we'll maintain this so we can workaround bugs in Chrome's Range.getClientRects\n\t // https://github.com/telerik/kendo/issues/5740\n\t var prevLineBottom = null;\n\n\t var underline = nodeInfo[\"underline\"];\n\t var lineThrough = nodeInfo[\"line-through\"];\n\t var overline = nodeInfo[\"overline\"];\n\t var hasDecoration = underline || lineThrough || overline;\n\n\t // doChunk returns true when all text has been rendered\n\t while (!doChunk()) {}\n\n\t if (hasDecoration) {\n\t range.selectNode(node);\n\t slice$1(range.getClientRects()).forEach(decorate);\n\t }\n\n\t return; // only function declarations after this line\n\n\t function actuallyGetRangeBoundingRect(range) {\n\t // XXX: to be revised when this Chrome bug is fixed:\n\t // https://bugs.chromium.org/p/chromium/issues/detail?id=612459\n\t if (microsoft || browser.chrome) {\n\t // Workaround browser bugs: IE and Chrome would sometimes\n\t // return 0 or 1-width rectangles before or after the main\n\t // one. https://github.com/telerik/kendo/issues/4674\n\n\t // Actually Chrome 50 got worse, since the rectangles can now have the width of a\n\t // full character, making it hard to tell whether it's a bogus rectangle or valid\n\t // selection location. The workaround is to ignore rectangles that fall on the\n\t // previous line. https://github.com/telerik/kendo/issues/5740\n\t var rectangles = range.getClientRects(), box = {\n\t top : Infinity,\n\t right : -Infinity,\n\t bottom : -Infinity,\n\t left : Infinity\n\t }, done = false;\n\t for (var i = 0; i < rectangles.length; ++i) {\n\t var b = rectangles[i];\n\t if (b.width <= 1 || b.bottom === prevLineBottom) {\n\t continue; // bogus rectangle\n\t }\n\t box.left = Math.min(b.left , box.left);\n\t box.top = Math.min(b.top , box.top);\n\t box.right = Math.max(b.right , box.right);\n\t box.bottom = Math.max(b.bottom , box.bottom);\n\t done = true;\n\t }\n\t if (!done) {\n\t return range.getBoundingClientRect();\n\t }\n\t box.width = box.right - box.left;\n\t box.height = box.bottom - box.top;\n\t return box;\n\t }\n\t return range.getBoundingClientRect();\n\t }\n\n\t // Render a chunk of text, typically one line (but for justified text we render each word as\n\t // a separate Text object, because spacing is variable). Returns true when it finished the\n\t // current node. After each chunk it updates `start` to just after the last rendered\n\t // character.\n\t function doChunk() {\n\t var origStart = start;\n\t var box, pos = text.substr(start).search(/\\S/);\n\t start += pos;\n\t if (pos < 0 || start >= end) {\n\t return true;\n\t }\n\n\t // Select a single character to determine the height of a line of text. The box.bottom\n\t // will be essential for us to figure out where the next line begins.\n\t range.setStart(node, start);\n\t range.setEnd(node, start + 1);\n\t box = actuallyGetRangeBoundingRect(range);\n\n\t // for justified text we must split at each space, because space has variable width.\n\t var found = false;\n\t if (isJustified || columnCount > 1) {\n\t pos = text.substr(start).search(/\\s/);\n\t if (pos >= 0) {\n\t // we can only split there if it's on the same line, otherwise we'll fall back\n\t // to the default mechanism (see findEOL below).\n\t range.setEnd(node, start + pos);\n\t var r = actuallyGetRangeBoundingRect(range);\n\t if (r.bottom == box.bottom) {\n\t box = r;\n\t found = true;\n\t start += pos;\n\t }\n\t }\n\t }\n\n\t if (!found) {\n\t // This code does three things: (1) it selects one line of text in `range`, (2) it\n\t // leaves the bounding rect of that line in `box` and (3) it returns the position\n\t // just after the EOL. We know where the line starts (`start`) but we don't know\n\t // where it ends. To figure this out, we select a piece of text and look at the\n\t // bottom of the bounding box. If it changes, we have more than one line selected\n\t // and should retry with a smaller selection.\n\t //\n\t // To speed things up, we first try to select all text in the node (`start` ->\n\t // `end`). If there's more than one line there, then select only half of it. And\n\t // so on. When we find a value for `end` that fits in one line, we try increasing\n\t // it (also in halves) until we get to the next line. The algorithm stops when the\n\t // right side of the bounding box does not change.\n\t //\n\t // One more thing to note is that everything happens in a single Text DOM node.\n\t // There's no other tags inside it, therefore the left/top coordinates of the\n\t // bounding box will not change.\n\t pos = (function findEOL(min, eol, max){\n\t range.setEnd(node, eol);\n\t var r = actuallyGetRangeBoundingRect(range);\n\t if (r.bottom != box.bottom && min < eol) {\n\t return findEOL(min, (min + eol) >> 1, eol);\n\t } else if (r.right != box.right) {\n\t box = r;\n\t if (eol < max) {\n\t return findEOL(eol, (eol + max) >> 1, max);\n\t } else {\n\t return eol;\n\t }\n\t } else {\n\t return eol;\n\t }\n\t })(start, Math.min(end, start + estimateLineLength), end);\n\n\t if (pos == start) {\n\t // if EOL is at the start, then no more text fits on this line. Skip the\n\t // remainder of this node entirely to avoid a stack overflow.\n\t return true;\n\t }\n\t start = pos;\n\n\t pos = range.toString().search(/\\s+$/);\n\t if (pos === 0) {\n\t return false; // whitespace only; we should not get here.\n\t }\n\t if (pos > 0) {\n\t // eliminate trailing whitespace\n\t range.setEnd(node, range.startOffset + pos);\n\t box = actuallyGetRangeBoundingRect(range);\n\t }\n\t }\n\n\t // another workaround for IE: if we rely on getBoundingClientRect() we'll overlap with the bullet for LI\n\t // elements. Calling getClientRects() and using the *first* rect appears to give us the correct location.\n\t // Note: not to be used in Chrome as it randomly returns a zero-width rectangle from the previous line.\n\t if (microsoft) {\n\t box = range.getClientRects()[0];\n\t }\n\n\t var str = range.toString();\n\t if (!/^(?:pre|pre-wrap)$/i.test(whiteSpace)) {\n\t // node with non-significant space -- collapse whitespace.\n\t str = str.replace(/\\s+/g, \" \");\n\t }\n\t else if (/\\t/.test(str)) {\n\t // with significant whitespace we need to do something about literal TAB characters.\n\t // There's no TAB glyph in a font so they would be rendered in PDF as an empty box,\n\t // and the whole text will stretch to fill the original width. The core PDF lib\n\t // does not have sufficient context to deal with it.\n\n\t // calculate the starting column here, since we initially discarded any whitespace.\n\t var cc = 0;\n\t for (pos = origStart; pos < range.startOffset; ++pos) {\n\t var code = text.charCodeAt(pos);\n\t if (code == 9) {\n\t // when we meet a TAB we must round up to the next tab stop.\n\t // in all browsers TABs seem to be 8 characters.\n\t cc += 8 - cc % 8;\n\t } else if (code == 10 || code == 13) {\n\t // just in case we meet a newline we must restart.\n\t cc = 0;\n\t } else {\n\t // ordinary character --> advance one column\n\t cc++;\n\t }\n\t }\n\n\t // based on starting column, replace any TAB characters in the string we actually\n\t // have to display with spaces so that they align to columns multiple of 8.\n\t while ((pos = str.search(\"\\t\")) >= 0) {\n\t var indent = \" \".substr(0, 8 - (cc + pos) % 8);\n\t str = str.substr(0, pos) + indent + str.substr(pos + 1);\n\t }\n\t }\n\n\t if (!found) {\n\t prevLineBottom = box.bottom;\n\t }\n\t drawText(str, box);\n\t }\n\n\t function drawText(str, box) {\n\t // In IE the box height will be approximately lineHeight, while in\n\t // other browsers it'll (correctly) be the height of the bounding\n\t // box for the current text/font. Which is to say, IE sucks again.\n\t // The only good solution I can think of is to measure the text\n\t // ourselves and center the bounding box.\n\t if (microsoft && !isNaN(lineHeight)) {\n\t var height = getFontHeight(font);\n\t var top = (box.top + box.bottom - height) / 2;\n\t box = {\n\t top : top,\n\t right : box.right,\n\t bottom : top + height,\n\t left : box.left,\n\t height : height,\n\t width : box.right - box.left\n\t };\n\t }\n\n\t // var path = new Path({ stroke: { color: \"red\" }});\n\t // path.moveTo(box.left, box.top)\n\t // .lineTo(box.right, box.top)\n\t // .lineTo(box.right, box.bottom)\n\t // .lineTo(box.left, box.bottom)\n\t // .close();\n\t // group.append(path);\n\n\t switch (textTransform) {\n\t case \"uppercase\":\n\t str = str.toUpperCase();\n\t break;\n\t case \"lowercase\":\n\t str = str.toLowerCase();\n\t break;\n\t case \"capitalize\":\n\t str = str.replace(/(?:^|\\s)\\S/g, function (l) { return l.toUpperCase(); });\n\t break;\n\t }\n\n\t var text = new TextRect(\n\t str, new Rect([ box.left, box.top ],\n\t [ box.width, box.height ]),\n\t {\n\t font: font,\n\t fill: { color: color }\n\t }\n\t );\n\t group.append(text);\n\t }\n\n\t function decorate(box) {\n\t line(underline, box.bottom);\n\t line(lineThrough, box.bottom - box.height / 2.7);\n\t line(overline, box.top);\n\t function line(color, ypos) {\n\t if (color) {\n\t var width = fontSize / 12;\n\t var path = new Path({ stroke: {\n\t width: width,\n\t color: color\n\t }});\n\n\t ypos -= width;\n\t path.moveTo(box.left, ypos)\n\t .lineTo(box.right, ypos);\n\t group.append(path);\n\t }\n\t }\n\t }\n\t}\n\n\tfunction groupInStackingContext(element, group, zIndex) {\n\t var main;\n\t if (zIndex != \"auto\") {\n\t // use the current stacking context\n\t main = nodeInfo._stackingContext.group;\n\t zIndex = parseFloat(zIndex);\n\t } else {\n\t // normal flow — use given container. we still have to\n\t // figure out where should we insert this element with the\n\t // assumption that its z-index is zero, as the group might\n\t // already contain elements with higher z-index.\n\t main = group;\n\t zIndex = 0;\n\t }\n\t var a = main.children;\n\t for (var i = 0; i < a.length; ++i) {\n\t if (a[i]._dom_zIndex != null && a[i]._dom_zIndex > zIndex) {\n\t break;\n\t }\n\t }\n\n\t var tmp = new Group();\n\t main.insert(i, tmp);\n\t tmp._dom_zIndex = zIndex;\n\n\t if (main !== group) {\n\t // console.log(\"Placing\", element, \"in\", nodeInfo._stackingContext.element, \"at position\", i, \" / \", a.length);\n\t // console.log(a.slice(i+1));\n\n\t // if (nodeInfo._matrix) {\n\t // tmp.transform(nodeInfo._matrix);\n\t // }\n\t if (nodeInfo._clipbox) {\n\t var m = nodeInfo._matrix.invert();\n\t var r = nodeInfo._clipbox.transformCopy(m);\n\t setClipping(tmp, Path.fromRect(r));\n\t // console.log(r);\n\t // tmp.append(Path.fromRect(r));\n\t // tmp.append(new Text(element.className || element.id, r.topLeft()));\n\t }\n\t }\n\n\t return tmp;\n\t}\n\n\tfunction renderElement(element, container) {\n\t var style = getComputedStyle(element);\n\n\t updateCounters(style);\n\n\t if (/^(style|script|link|meta|iframe|svg|col|colgroup)$/i.test(element.tagName)) {\n\t return;\n\t }\n\n\t if (nodeInfo._clipbox == null) {\n\t return;\n\t }\n\n\t var opacity = parseFloat(getPropertyValue(style, \"opacity\"));\n\t var visibility = getPropertyValue(style, \"visibility\");\n\t var display = getPropertyValue(style, \"display\");\n\n\t if (opacity === 0 || visibility == \"hidden\" || display == \"none\") {\n\t return;\n\t }\n\n\t var tr = getTransform(style);\n\t var group;\n\n\t var zIndex = getPropertyValue(style, \"z-index\");\n\t if ((tr || opacity < 1) && zIndex == \"auto\") {\n\t zIndex = 0;\n\t }\n\t group = groupInStackingContext(element, container, zIndex);\n\n\t // XXX: remove at some point\n\t // group._pdfElement = element;\n\t // group.options._pdfDebug = \"\";\n\t // if (element.id) {\n\t // group.options._pdfDebug = \"#\" + element.id;\n\t // }\n\t // if (element.className) {\n\t // group.options._pdfDebug += \".\" + element.className.split(\" \").join(\".\");\n\t // }\n\n\t if (opacity < 1) {\n\t group.opacity(opacity * group.opacity());\n\t }\n\n\t pushNodeInfo(element, style, group);\n\n\t if (!tr) {\n\t _renderWithPseudoElements(element, group);\n\t }\n\t else {\n\t saveStyle(element, function(){\n\t // must clear transform, so getBoundingClientRect returns correct values.\n\t pleaseSetPropertyValue(element.style, \"transform\", \"none\", \"important\");\n\n\t // must also clear transitions, so correct values are returned *immediately*\n\t pleaseSetPropertyValue(element.style, \"transition\", \"none\", \"important\");\n\n\t // the presence of any transform makes it behave like it had position: relative,\n\t // because why not.\n\t // http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/\n\t if (getPropertyValue(style, \"position\") == \"static\") {\n\t // but only if it's not already positioned. :-/\n\t pleaseSetPropertyValue(element.style, \"position\", \"relative\", \"important\");\n\t }\n\n\t // must translate to origin before applying the CSS\n\t // transformation, then translate back.\n\t var bbox = element.getBoundingClientRect();\n\t var x = bbox.left + tr.origin[0];\n\t var y = bbox.top + tr.origin[1];\n\t var m = [ 1, 0, 0, 1, -x, -y ];\n\t m = mmul(m, tr.matrix);\n\t m = mmul(m, [ 1, 0, 0, 1, x, y ]);\n\t m = setTransform(group, m);\n\n\t nodeInfo._matrix = nodeInfo._matrix.multiplyCopy(m);\n\n\t _renderWithPseudoElements(element, group);\n\t });\n\t }\n\n\t popNodeInfo();\n\n\t //drawDebugBox(element.getBoundingClientRect(), container);\n\t}\n\n\t// function drawDebugBox(box, group, color) {\n\t// var path = Path.fromRect(new geo.Rect([ box.left, box.top ], [ box.width, box.height ]));\n\t// if (color) {\n\t// path.stroke(color);\n\t// }\n\t// group.append(path);\n\t// }\n\n\t// function dumpTextNode(node) {\n\t// var txt = node.data.replace(/^\\s+/, \"\");\n\t// if (txt.length < 100) {\n\t// console.log(node.data.length + \": |\" + txt);\n\t// } else {\n\t// console.log(node.data.length + \": |\" + txt.substr(0, 50) + \"|...|\" + txt.substr(-50));\n\t// }\n\t// }\n\n\tfunction mmul(a, b) {\n\t var a1 = a[0], b1 = a[1], c1 = a[2], d1 = a[3], e1 = a[4], f1 = a[5];\n\t var a2 = b[0], b2 = b[1], c2 = b[2], d2 = b[3], e2 = b[4], f2 = b[5];\n\t return [\n\t a1*a2 + b1*c2, a1*b2 + b1*d2,\n\t c1*a2 + d1*c2, c1*b2 + d1*d2,\n\t e1*a2 + f1*c2 + e2, e1*b2 + f1*d2 + f2\n\t ];\n\t}\n\n\tvar drawing = {\n\t\tsvg: svg,\n\t\tcanvas: canvas,\n\t\tutil: util,\n\t\tPathParser: PathParser,\n\t\tSurface: Surface,\n\t\tBaseNode: BaseNode,\n\t\tSurfaceFactory: SurfaceFactory,\n\t\tOptionsStore: OptionsStore,\n\t\texportImage: exportImage,\n\t\texportSVG: exportSVG,\n\t\tQuadNode: QuadNode,\n\t\tShapesQuadTree: ShapesQuadTree,\n\t\tObserversMixin: ObserversMixin,\n\t\tElement: Element$1,\n\t\tCircle: Circle,\n\t\tArc: Arc,\n\t\tPath: Path,\n\t\tMultiPath: MultiPath,\n\t\tText: Text,\n\t\tImage: Image$1,\n\t\tGroup: Group,\n\t\tLayout: Layout,\n\t\tRect: Rect$2,\n\t\talign: align,\n\t\tvAlign: vAlign,\n\t\tstack: stack,\n\t\tvStack: vStack,\n\t\twrap: wrap,\n\t\tvWrap: vWrap,\n\t\tfit: fit,\n\t\tLinearGradient: LinearGradient,\n\t\tRadialGradient: RadialGradient,\n\t\tGradientStop: GradientStop,\n\t\tGradient: Gradient,\n\t\tAnimation: Animation,\n\t\tAnimationFactory: AnimationFactory,\n\t\tdrawDOM: drawDOM\n\t};\n\n\tkendo.deepExtend(kendo, {\n\t drawing: drawing,\n\t geometry: geometry\n\t});\n\n\tkendo.drawing.Segment = kendo.geometry.Segment;\n\tkendo.dataviz.drawing = kendo.drawing;\n\tkendo.dataviz.geometry = kendo.geometry;\n\tkendo.drawing.util.measureText = kendo.util.measureText;\n\tkendo.drawing.util.objectKey = kendo.util.objectKey;\n\tkendo.drawing.Color = kendo.Color;\n\tkendo.util.encodeBase64 = kendo.drawing.util.encodeBase64;\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ }),\n\n/***/ 923:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./util\");\n\n/***/ }),\n\n/***/ 924:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.color\");\n\n/***/ }),\n\n/***/ 925:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../util/text-metrics\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(928);\n\tmodule.exports = __webpack_require__(928);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 921:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo-drawing\");\n\n/***/ }),\n\n/***/ 928:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(929), __webpack_require__(921) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\t var NS = \".kendo\";\n\t var kendo = window.kendo;\n\t var deepExtend = kendo.deepExtend;\n\t var utils = kendo.drawing.util;\n\t var defined = utils.defined;\n\t var limitValue = utils.limitValue;\n\t var eventCoordinates = utils.eventCoordinates;\n\t var outerWidth = kendo._outerWidth;\n\t var outerHeight = kendo._outerHeight;\n\t var proxy = $.proxy;\n\n\t var TOOLTIP_TEMPLATE = '
    ' +\n\t '
    ' +\n\t '
    ';\n\t var TOOLTIP_CLOSE_TEMPLATE = '
    ';\n\n\t var SurfaceTooltip = kendo.Class.extend({\n\t init: function(surface, options) {\n\t this.element = $(TOOLTIP_TEMPLATE);\n\t this.content = this.element.children(\".k-tooltip-content\");\n\n\t options = options || {};\n\n\t this.options = deepExtend({}, this.options, this._tooltipOptions(options));\n\t this.popupOptions = {\n\t appendTo: options.appendTo,\n\t animation: options.animation,\n\t copyAnchorStyles: false,\n\t collision: \"fit fit\"\n\t };\n\n\t this._openPopupHandler = $.proxy(this._openPopup, this);\n\n\t this.surface = surface;\n\t this._bindEvents();\n\t },\n\n\t options: {\n\t position: \"top\",\n\t showOn: \"mouseenter\",\n\t offset: 7,\n\t autoHide: true,\n\t hideDelay: 0,\n\t showAfter: 100\n\t },\n\n\t _bindEvents: function() {\n\t this._showHandler = proxy(this._showEvent, this);\n\t this._surfaceLeaveHandler = proxy(this._surfaceLeave, this);\n\t this._mouseleaveHandler = proxy(this._mouseleave, this);\n\t this._mousemoveHandler = proxy(this._mousemove, this);\n\n\t this.surface.bind(\"click\", this._showHandler);\n\t this.surface.bind(\"mouseenter\", this._showHandler);\n\t this.surface.bind(\"mouseleave\", this._mouseleaveHandler);\n\t this.surface.bind(\"mousemove\", this._mousemoveHandler);\n\n\t this.surface.element.on(\"mouseleave\" + NS, this._surfaceLeaveHandler);\n\n\t this.element.on(\"click\" + NS, \".k-tooltip-button\", proxy(this._hideClick, this));\n\t this.element.on(\"mouseleave\" + NS, proxy(this._tooltipLeave, this));\n\t },\n\n\t getPopup: function() {\n\t if (!this.popup) {\n\t this.popup = new kendo.ui.Popup(this.element, this.popupOptions);\n\t }\n\n\t return this.popup;\n\t },\n\n\t destroy: function() {\n\t var popup = this.popup;\n\n\t this.surface.unbind(\"click\", this._showHandler);\n\t this.surface.unbind(\"mouseenter\", this._showHandler);\n\t this.surface.unbind(\"mouseleave\", this._mouseleaveHandler);\n\t this.surface.unbind(\"mousemove\", this._mousemoveHandler);\n\n\t this.surface.element.off(\"mouseleave\" + NS, this._surfaceLeaveHandler);\n\t this.element.off(\"click\" + NS);\n\t this.element.off(\"mouseleave\" + NS);\n\n\t if (popup) {\n\t popup.destroy();\n\t delete this.popup;\n\t }\n\t delete this.popupOptions;\n\n\t clearTimeout(this._timeout);\n\n\t delete this.element;\n\t delete this.content;\n\t delete this.surface;\n\t },\n\n\t _tooltipOptions: function(options) {\n\t options = options || {};\n\t return {\n\t position: options.position,\n\t showOn: options.showOn,\n\t offset: options.offset,\n\t autoHide: options.autoHide,\n\t width: options.width,\n\t height: options.height,\n\t content: options.content,\n\t shared: options.shared,\n\t hideDelay: options.hideDelay,\n\t showAfter: options.showAfter\n\t };\n\t },\n\n\t _tooltipShape: function(shape) {\n\t while(shape && !shape.options.tooltip) {\n\t shape = shape.parent;\n\t }\n\t return shape;\n\t },\n\n\t _updateContent: function(target, shape, options) {\n\t var content = options.content;\n\t if (kendo.isFunction(content)) {\n\t content = content({\n\t element: shape,\n\t target: target\n\t });\n\t }\n\n\t if (content) {\n\t this.content.html(content);\n\t return true;\n\t }\n\t },\n\n\t _position: function(shape, options, elementSize, event) {\n\t var position = options.position;\n\t var tooltipOffset = options.offset || 0;\n\t var surface = this.surface;\n\t var offset = surface._instance._elementOffset();\n\t var size = surface.getSize();\n\t var surfaceOffset = surface._instance._offset;\n\t var bbox = shape.bbox();\n\t var width = elementSize.width;\n\t var height = elementSize.height;\n\t var left = 0, top = 0;\n\n\t bbox.origin.translate(offset.left, offset.top);\n\t if (surfaceOffset) {\n\t bbox.origin.translate(-surfaceOffset.x, -surfaceOffset.y);\n\t }\n\n\t if (position == \"cursor\" && event) {\n\t var coord = eventCoordinates(event);\n\t left = coord.x - width / 2;\n\t top = coord.y - height - tooltipOffset;\n\t } else if (position == \"left\") {\n\t left = bbox.origin.x - width - tooltipOffset;\n\t top = bbox.center().y - height / 2;\n\t } else if (position == \"right\") {\n\t left = bbox.bottomRight().x + tooltipOffset;\n\t top = bbox.center().y - height / 2;\n\t } else if (position == \"bottom\") {\n\t left = bbox.center().x - width / 2;\n\t top = bbox.bottomRight().y + tooltipOffset;\n\t } else {\n\t left = bbox.center().x - width / 2;\n\t top = bbox.origin.y - height - tooltipOffset;\n\t }\n\n\t return {\n\t left: limitValue(left, offset.left, offset.left + size.width),\n\t top: limitValue(top, offset.top, offset.top + size.height)\n\t };\n\t },\n\n\t show: function(shape, options) {\n\t this._show(shape, shape, deepExtend({}, this.options, this._tooltipOptions(shape.options.tooltip), options));\n\t },\n\n\t hide: function() {\n\t var popup = this.popup;\n\t var current = this._current;\n\n\t delete this._current;\n\t clearTimeout(this._showTimeout);\n\t if (popup && popup.visible() && current &&\n\t !this.surface.trigger(\"tooltipClose\", { element: current.shape, target: current.target, popup: popup})) {\n\t popup.close();\n\t }\n\t },\n\n\t _hideClick: function(e) {\n\t e.preventDefault();\n\t this.hide();\n\t },\n\n\t _show: function(target, shape, options, event, delay) {\n\t var current = this._current;\n\n\t clearTimeout(this._timeout);\n\n\t if (current && ((current.shape === shape && options.shared) || current.target === target)) {\n\t return;\n\t }\n\n\t clearTimeout(this._showTimeout);\n\n\t var popup = this.getPopup();\n\n\t if (!this.surface.trigger(\"tooltipOpen\", { element: shape, target: target, popup: popup }) &&\n\t this._updateContent(target, shape, options)) {\n\n\t this._autoHide(options);\n\t var elementSize = this._measure(options);\n\n\t if (popup.visible()) {\n\t popup.close(true);\n\t }\n\n\t this._current = {\n\t options: options,\n\t elementSize: elementSize,\n\t shape: shape,\n\t target: target,\n\t position: this._position(options.shared ? shape: target, options, elementSize, event)\n\t };\n\n\t if (delay) {\n\t this._showTimeout = setTimeout(this._openPopupHandler, options.showAfter || 0);\n\t } else {\n\t this._openPopup();\n\t }\n\t }\n\t },\n\n\t _openPopup: function() {\n\t var current = this._current;\n\t var position = current.position;\n\n\t this.getPopup().open(position.left, position.top);\n\t },\n\n\t _autoHide: function(options) {\n\t if (options.autoHide && this._closeButton) {\n\t this.element.removeClass(\"k-tooltip-closable\");\n\t this._closeButton.remove();\n\t delete this._closeButton;\n\t }\n\n\t if (!options.autoHide && !this._closeButton) {\n\t this.element.addClass(\"k-tooltip-closable\");\n\t this._closeButton = $(TOOLTIP_CLOSE_TEMPLATE).appendTo(this.element);\n\t }\n\t },\n\n\t _showEvent: function(e) {\n\t var shape = this._tooltipShape(e.element);\n\n\t if (shape) {\n\t var options = deepExtend({}, this.options, this._tooltipOptions(shape.options.tooltip));\n\n\t if (options && options.showOn == e.type) {\n\t this._show(e.element, shape, options, e.originalEvent, true);\n\t }\n\t }\n\t },\n\n\t _measure: function(options) {\n\t var popup = this.getPopup();\n\t var width, height;\n\t this.element.css({\n\t width: \"auto\",\n\t height: \"auto\"\n\t });\n\t var visible = popup.visible();\n\t if (!visible) {\n\t popup.wrapper.show();\n\t }\n\n\t this.element.css({\n\t width: defined(options.width) ? options.width : \"auto\",\n\t height: defined(options.height) ? options.height : \"auto\"\n\t });\n\n\t width = outerWidth(this.element);\n\t height = outerHeight(this.element);\n\n\t if (!visible) {\n\t popup.wrapper.hide();\n\t }\n\n\t return {\n\t width: width,\n\t height: height\n\t };\n\t },\n\n\t _mouseleave: function(e) {\n\t if (this.popup && !this._popupRelatedTarget(e.originalEvent)) {\n\t var tooltip = this;\n\t var current = tooltip._current;\n\n\t if (current && current.options.autoHide) {\n\t tooltip._timeout = setTimeout(function() {\n\t clearTimeout(tooltip._showTimeout);\n\t tooltip.hide();\n\t }, current.options.hideDelay || 0);\n\t }\n\t }\n\t },\n\n\t _mousemove: function(e) {\n\t var current = this._current;\n\t if (current && e.element) {\n\t var options = current.options;\n\t if (options.position == \"cursor\") {\n\t var position = this._position(e.element, options, current.elementSize, e.originalEvent);\n\t current.position = position;\n\t this.getPopup().wrapper.css({left: position.left, top: position.top});\n\t }\n\t }\n\t },\n\n\t _surfaceLeave: function(e) {\n\t if (this.popup && !this._popupRelatedTarget(e)) {\n\t clearTimeout(this._showTimeout);\n\t this.hide();\n\t }\n\t },\n\n\t _popupRelatedTarget: function(e) {\n\t return e.relatedTarget && $(e.relatedTarget).closest(this.popup.wrapper).length;\n\t },\n\n\t _tooltipLeave: function() {\n\t var tooltip = this;\n\t var current = tooltip._current;\n\t if (current && current.options.autoHide) {\n\t tooltip._timeout = setTimeout(function() {\n\t tooltip.hide();\n\t }, current.options.hideDelay || 0);\n\t }\n\t }\n\t });\n\n\t kendo.drawing.SurfaceTooltip = SurfaceTooltip;\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ }),\n\n/***/ 929:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.popup\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(926);\n\tmodule.exports = __webpack_require__(926);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 921:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo-drawing\");\n\n/***/ }),\n\n/***/ 926:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(921), __webpack_require__(927) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\t var kendo = window.kendo;\n\t var draw = kendo.drawing;\n\t var DrawingSurface = draw.Surface;\n\t var Widget = kendo.ui.Widget;\n\t var deepExtend = kendo.deepExtend;\n\t var proxy = $.proxy;\n\n\t kendo.support.svg = DrawingSurface.support.svg;\n\t kendo.support.canvas = DrawingSurface.support.canvas;\n\n\t var Surface = Widget.extend({\n\t init: function(element, options) {\n\t Widget.fn.init.call(this, element, {});\n\n\t this.options = deepExtend({}, this.options, options);\n\n\t this._instance = DrawingSurface.create(this.element[0], options);\n\t if (this._instance.translate) {\n\t this.translate = translate;\n\t }\n\n\t this._triggerInstanceHandler = proxy(this._triggerInstanceEvent, this);\n\t this._bindHandler(\"click\");\n\t this._bindHandler(\"mouseenter\");\n\t this._bindHandler(\"mouseleave\");\n\t this._bindHandler(\"mousemove\");\n\n\t this._enableTracking();\n\t },\n\n\t options: {\n\t name: \"Surface\",\n\t tooltip: {}\n\t },\n\n\t events: [\n\t \"click\",\n\t \"mouseenter\",\n\t \"mouseleave\",\n\t \"mousemove\",\n\t \"resize\",\n\t \"tooltipOpen\",\n\t \"tooltipClose\"\n\t ],\n\n\t _triggerInstanceEvent: function(e) {\n\t this.trigger(e.type, e);\n\t },\n\n\t _bindHandler: function(event) {\n\t this._instance.bind(event, this._triggerInstanceHandler);\n\t },\n\n\t draw: function(element) {\n\t this._instance.draw(element);\n\t },\n\n\t clear: function() {\n\t if (this._instance) {\n\t this._instance.clear();\n\t }\n\t this.hideTooltip();\n\t },\n\n\t destroy: function() {\n\t if (this._instance) {\n\t this._instance.destroy();\n\t delete this._instance;\n\t }\n\n\t if (this._tooltip) {\n\t this._tooltip.destroy();\n\t delete this._tooltip;\n\t }\n\n\t Widget.fn.destroy.call(this);\n\t },\n\n\t exportVisual: function() {\n\t return this._instance.exportVisual();\n\t },\n\n\t eventTarget: function(e) {\n\t return this._instance.eventTarget(e);\n\t },\n\n\t showTooltip: function(shape, options) {\n\t if (this._tooltip) {\n\t this._tooltip.show(shape, options);\n\t }\n\t },\n\n\t hideTooltip: function() {\n\t if (this._tooltip) {\n\t this._tooltip.hide();\n\t }\n\t },\n\n\t suspendTracking: function() {\n\t this._instance.suspendTracking();\n\t this.hideTooltip();\n\t },\n\n\t resumeTracking: function() {\n\t this._instance.resumeTracking();\n\t },\n\n\t getSize: function() {\n\t return {\n\t width: this.element.width(),\n\t height: this.element.height()\n\t };\n\t },\n\n\t setSize: function(size) {\n\t this.element.css({\n\t width: size.width,\n\t height: size.height\n\t });\n\n\t this._size = size;\n\t this._instance.currentSize(size);\n\t this._resize();\n\t },\n\n\t _resize: function() {\n\t this._instance.currentSize(this._size);\n\t this._instance._resize();\n\t },\n\n\t _enableTracking: function() {\n\t if (kendo.ui.Popup) {\n\t this._tooltip = new draw.SurfaceTooltip(this, this.options.tooltip || {});\n\t }\n\t }\n\t });\n\n\t kendo.ui.plugin(Surface);\n\n\t Surface.create = function(element, options) {\n\t return new Surface(element, options);\n\t };\n\n\t kendo.drawing.Surface = Surface;\n\n\t function translate(offset) {\n\t this._instance.translate(offset);\n\t }\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ }),\n\n/***/ 927:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./surface-tooltip\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(930);\n\tmodule.exports = __webpack_require__(930);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 20:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.core\");\n\n/***/ }),\n\n/***/ 930:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(20)], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function($) {\n\n\t function createPromise() {\n\t return $.Deferred();\n\t }\n\n\t function promiseAll(promises) {\n\t return $.when.apply($, promises);\n\t }\n\n\t kendo.drawing.util = kendo.drawing.util || {};\n\t kendo.deepExtend(kendo.drawing.util, {\n\t createPromise: createPromise,\n\t promiseAll: promiseAll\n\t });\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(931);\n\tmodule.exports = __webpack_require__(931);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 931:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(932) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function($, undefined) {\n\n\t var kendo = window.kendo,\n\t ui = kendo.ui,\n\t keys = kendo.keys,\n\t DISABLED = \"k-state-disabled\",\n\t SELECT = \"select\",\n\t CHECKED = \"checked\",\n\t proxy = $.proxy,\n\t DATABOUND = \"dataBound\",\n\t CLICK = \"click\",\n\t NS = \".kendoTreeView\",\n\t INDETERMINATE = \"indeterminate\",\n\t NAVIGATE = \"navigate\",\n\t subGroup,\n\t TreeView = ui.TreeView;\n\n\t function contentChild(filter) {\n\t return function(node) {\n\t var result = node.children(\".k-animation-container\");\n\n\t if (!result.length) {\n\t result = node;\n\t }\n\n\t return result.children(filter);\n\t };\n\t }\n\n\t subGroup = contentChild(\".k-group\");\n\n\t var Tree = TreeView.extend({\n\t init: function(element, options, dropdowntree) {\n\t var that = this;\n\n\t that.dropdowntree = dropdowntree;\n\t that._nodesToLoad = 0;\n\n\t TreeView.fn.init.call(that, element, options);\n\t if(that.dropdowntree._isMultipleSelection()){\n\t that.wrapper.on(CLICK + NS, '.k-in.k-state-selected', proxy(that._clickSelectedItem, that));\n\t }\n\t },\n\n\t _checkOnSelect: function (e) {\n\t if (!e.isDefaultPrevented()) {\n\t var dataItem = this.dataItem(e.node);\n\n\t dataItem.set(\"checked\", !dataItem.checked);\n\t }\n\t },\n\n\t _setCheckedValue: function (node, value){\n\t node.set(CHECKED, value);\n\t },\n\n\t _click: function (e) {\n\t var that = this;\n\n\t if(that.dropdowntree._isMultipleSelection()){\n\t that.one(\"select\", that._checkOnSelect);\n\t }\n\t TreeView.fn._click.call(that, e);\n\t },\n\n\t _clickSelectedItem: function (e) {\n\t var that = this,\n\t node = $(e.currentTarget);\n\n\t that.one(\"select\", that._checkOnSelect);\n\t if (!that._trigger(SELECT, node)) {\n\t that.dataItem(node).set(\"selected\", false);\n\t }\n\t },\n\n\t defaultrefresh: function(e) {\n\t var that = this;\n\t var node = e.node;\n\t var action = e.action;\n\t var items = e.items;\n\t var parentNode = this.wrapper;\n\t var options = this.options;\n\t var loadOnDemand = options.loadOnDemand;\n\t var checkChildren = options.checkboxes && options.checkboxes.checkChildren;\n\t var i;\n\n\t if (this._skip) {\n\t return;\n\t }\n\n\t if (e.field) {\n\t if (!items[0] || !items[0].level) {\n\t return;\n\t }\n\n\t return this._updateNodes(items, e.field);\n\t }\n\n\t if (node) {\n\t parentNode = this.findByUid(node.uid);\n\t this._progress(parentNode, false);\n\t }\n\n\t if (checkChildren && action != \"remove\") {\n\t var bubble = false;\n\n\t for (i = 0; i < items.length; i++) {\n\t if (\"checked\" in items[i]) {\n\t bubble = true;\n\t break;\n\t }\n\t }\n\n\t if (!bubble && node && node.checked) {\n\t for (i = 0; i < items.length; i++) {\n\t items[i].checked = true;\n\t }\n\t }\n\t }\n\n\t if (action == \"add\") {\n\t this._appendItems(e.index, items, parentNode);\n\t } else if (action == \"remove\") {\n\t this._remove(this.findByUid(items[0].uid), false);\n\t } else if (action == \"itemchange\") {\n\t this._updateNodes(items);\n\t } else if (action == \"itemloaded\") {\n\t this._nodesToLoad --;\n\t this._refreshChildren(parentNode, items, e.index);\n\t } else {\n\t this._refreshRoot(items);\n\t }\n\n\t if (action != \"remove\") {\n\t for (i = 0; i < items.length; i++) {\n\t if (!loadOnDemand || items[i].expanded) {\n\t if(items[i].hasChildren){\n\t that._nodesToLoad ++;\n\t }\n\t items[i].load();\n\t }\n\t }\n\t }\n\t if(this._nodesToLoad === 0){\n\t this.dropdowntree.trigger(\"allNodesAreLoaded\");\n\t }\n\t this.trigger(DATABOUND, { node: node ? parentNode : undefined });\n\t this.dropdowntree._treeViewDataBound({ node: node ? parentNode : undefined, sender: this });\n\t if (this.options.checkboxes.checkChildren) {\n\t this.updateIndeterminate();\n\t }\n\t },\n\n\t _previousVisible: function(node) {\n\t var that = this,\n\t lastChild,\n\t result;\n\n\t if (!node.length || node.prev().length) {\n\t if (node.length) {\n\t result = node.prev();\n\t } else {\n\t result = that.root.children().last();\n\t }\n\n\t while (that._expanded(result)) {\n\t lastChild = subGroup(result).children().last();\n\n\t if (!lastChild.length) {\n\t break;\n\t }\n\n\t result = lastChild;\n\t }\n\t } else {\n\t result = that.parent(node) || node;\n\n\t if(!result.length){\n\t if (that.dropdowntree.checkAll && that.dropdowntree.checkAll.is(\":visible\")) {\n\t that.dropdowntree.checkAll.find(\".k-checkbox\").focus();\n\t } else if(that.dropdowntree.filterInput){\n\t that.dropdowntree.filterInput.focus();\n\t } else {\n\t that.dropdowntree.wrapper.focus();\n\t }\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t _keydown: function(e) {\n\t var that = this,\n\t key = e.keyCode,\n\t target,\n\t focused = that.current(),\n\t expanded = that._expanded(focused),\n\t checkbox = focused.find(\".k-checkbox-wrapper:first :checkbox\"),\n\t rtl = kendo.support.isRtl(that.element);\n\n\t if (e.target != e.currentTarget) {\n\t return;\n\t }\n\n\t if ((!rtl && key == keys.RIGHT) || (rtl && key == keys.LEFT)) {\n\t if (expanded) {\n\t target = that._nextVisible(focused);\n\t } else if (!focused.find(\".k-in:first\").hasClass(DISABLED)) {\n\t that.expand(focused);\n\t }\n\t } else if ((!rtl && key == keys.LEFT) || (rtl && key == keys.RIGHT)) {\n\t if (expanded && !focused.find(\".k-in:first\").hasClass(DISABLED)) {\n\t that.collapse(focused);\n\t } else {\n\t target = that.parent(focused);\n\n\t if (!that._enabled(target)) {\n\t target = undefined;\n\t }\n\t }\n\t } else if (key == keys.DOWN) {\n\t target = that._nextVisible(focused);\n\t } else if (key == keys.UP && !e.altKey) {\n\t target = that._previousVisible(focused);\n\t } else if (key == keys.HOME) {\n\t target = that._nextVisible($());\n\t } else if (key == keys.END) {\n\t target = that._previousVisible($());\n\t } else if (key == keys.ENTER && !focused.find(\".k-in:first\").hasClass(DISABLED)) {\n\t if (!focused.find(\".k-in:first\").hasClass(\"k-state-selected\")) {\n\t if (!that._trigger(SELECT, focused)) {\n\t that.select(focused);\n\t }\n\t }\n\t } else if (key == keys.SPACEBAR && checkbox.length && !focused.find(\".k-in:first\").hasClass(DISABLED)) {\n\t checkbox.prop(CHECKED, !checkbox.prop(CHECKED))\n\t .data(INDETERMINATE, false)\n\t .prop(INDETERMINATE, false);\n\n\t that._checkboxChange({ target: checkbox });\n\n\t target = focused;\n\t } else if ((e.altKey && key === keys.UP) || key === keys.ESC) {\n\t that._closePopup();\n\t } else if ( key === keys.TAB) {\n\t e.preventDefault();\n\t that._closePopup();\n\t }\n\n\t if (target) {\n\t e.preventDefault();\n\n\t if (focused[0] != target[0]) {\n\t that._trigger(NAVIGATE, target);\n\t that.current(target);\n\t }\n\t }\n\t },\n\n\t _closePopup: function() {\n\t this.dropdowntree.close();\n\t this.dropdowntree.wrapper.focus();\n\t },\n\n\t refresh: function(e){\n\t this.defaultrefresh(e);\n\n\t if(this.dropdowntree.options.skipUpdateOnBind){\n\t return;\n\t }\n\n\t if (e.action === \"itemchange\") {\n\t if (this.dropdowntree._isMultipleSelection()) {\n\t if(e.field === \"checked\"){\n\t this.dropdowntree._checkValue(e.items[0]);\n\t }\n\t } else {\n\t if(e.field !== \"checked\" && e.field !== \"expanded\" && e.items[0].selected){\n\t this.dropdowntree._selectValue(e.items[0]);\n\t }\n\t }\n\t } else {\n\t this.dropdowntree.refresh(e);\n\t }\n\t }\n\n\t });\n\n\t kendo.ui._dropdowntree = Tree;\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 932:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.treeview\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(996);\n\tmodule.exports = __webpack_require__(996);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 20:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.core\");\n\n/***/ }),\n\n/***/ 996:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/***********************************************************************\n\t * WARNING: this file is auto-generated. If you change it directly,\n\t * your modifications will eventually be lost. The source code is in\n\t * `kendo-ooxml` repository, you should make your changes there and\n\t * run `src-modules/sync.sh` in this repository.\n\t */\n\t(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(20)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($) {\n\n\twindow.kendo.excel = window.kendo.excel || {};\n\n\tvar getter = kendo.getter;\n\tvar map = $.map;\n\n\tvar current = {\n\t compile: function(template) {\n\t return template;\n\t }\n\t};\n\n\tvar TemplateService = kendo.Class.extend({\n\n\t});\n\n\tTemplateService.register = function(userImplementation) {\n\t current = userImplementation;\n\t};\n\n\tTemplateService.compile = function(template) {\n\t return current.compile(template);\n\t};\n\n\tfunction defaultGroupHeaderTemplate(data) {\n\t return ((data.title) + \": \" + (data.value));\n\t}\n\n\tfunction createArray(length, callback) {\n\t var result = [];\n\n\t for (var idx = 0; idx < length; idx++) {\n\t result.push(callback(idx));\n\t }\n\n\t return result;\n\t}\n\n\tvar ExcelExporter = kendo.Class.extend({\n\t init: function(options) {\n\t options.columns = this._trimColumns(options.columns || []);\n\n\t this.allColumns = map(this._leafColumns(options.columns || []), this._prepareColumn);\n\n\t this.columns = this.allColumns.filter(function(column) { return !column.hidden; });\n\n\t this.options = options;\n\t this.data = options.data || [];\n\t this.aggregates = options.aggregates || {};\n\t this.groups = [].concat(options.groups || []);\n\t this.hierarchy = options.hierarchy;\n\t },\n\n\t workbook: function() {\n\t var workbook = {\n\t sheets: [ {\n\t columns: this._columns(),\n\t rows: this.hierarchy ? this._hierarchyRows() : this._rows(),\n\t freezePane: this._freezePane(),\n\t filter: this._filter()\n\t } ]\n\t };\n\n\t return workbook;\n\t },\n\n\t _trimColumns: function(columns) {\n\t var this$1 = this;\n\n\t return columns.filter(function (column) {\n\t var result = Boolean(column.field);\n\n\t if (!result && column.columns) {\n\t result = this$1._trimColumns(column.columns).length > 0;\n\t }\n\n\t return result;\n\t });\n\t },\n\n\t _leafColumns: function(columns) {\n\t var this$1 = this;\n\n\t var result = [];\n\n\t for (var idx = 0; idx < columns.length; idx++) {\n\t if (!columns[idx].columns) {\n\t result.push(columns[idx]);\n\t } else {\n\t result = result.concat(this$1._leafColumns(columns[idx].columns));\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t _prepareColumn: function(column) {\n\t if (!column.field) {\n\t return null;\n\t }\n\n\t var value = function(dataItem) {\n\t return getter(column.field, true)(dataItem);\n\t };\n\n\t var values = null;\n\n\t if (column.values) {\n\t values = {};\n\n\t column.values.forEach(function(item) {\n\t values[item.value] = item.text;\n\t });\n\n\t value = function(dataItem) {\n\t return values[getter(column.field, true)(dataItem)];\n\t };\n\t }\n\n\t return $.extend({}, column, {\n\t value: value,\n\t values: values,\n\t groupHeaderTemplate: column.groupHeaderTemplate ? TemplateService.compile(column.groupHeaderTemplate) : defaultGroupHeaderTemplate,\n\t groupFooterTemplate: column.groupFooterTemplate ? TemplateService.compile(column.groupFooterTemplate) : null,\n\t footerTemplate: column.footerTemplate ? TemplateService.compile(column.footerTemplate) : null\n\t });\n\t },\n\n\t _filter: function() {\n\t if (!this.options.filterable) {\n\t return null;\n\t }\n\n\t var depth = this._depth();\n\n\t return {\n\t from: depth,\n\t to: depth + this.columns.length - 1\n\t };\n\t },\n\n\t _createPaddingCells: function(length) {\n\t var this$1 = this;\n\n\t return createArray(length, function () { return $.extend({\n\t background: \"#dfdfdf\",\n\t color: \"#333\"\n\t }, this$1.options.paddingCellOptions); });\n\t },\n\n\t _dataRow: function(dataItem, level, depth) {\n\t var this$1 = this;\n\n\t var cells = this._createPaddingCells(level);\n\n\t // grouped\n\t if (depth && dataItem.items) {\n\t var column = this.allColumns.filter(function(column) {\n\t return column.field === dataItem.field;\n\t })[0];\n\n\t var title = column && column.title ? column.title : dataItem.field;\n\t var template = column ? column.groupHeaderTemplate : null;\n\t var group = $.extend({\n\t title: title,\n\t field: dataItem.field,\n\t value: column && column.values ? column.values[dataItem.value] : dataItem.value,\n\t aggregates: dataItem.aggregates,\n\t items: dataItem.items\n\t }, dataItem.aggregates[dataItem.field]);\n\n\t var value = title + \": \" + (dataItem.value);\n\n\t if (template) {\n\t value = template(group);\n\t }\n\n\t cells.push($.extend({\n\t value: value,\n\t background: \"#dfdfdf\",\n\t color: \"#333\",\n\t colSpan: this.columns.length + depth - level\n\t }, (column || {}).groupHeaderCellOptions));\n\n\t var rows = this._dataRows(dataItem.items, level + 1);\n\n\t rows.unshift({\n\t type: \"group-header\",\n\t cells: cells,\n\t level: this.options.collapsible ? level : null\n\t });\n\n\t return rows.concat(this._footer(dataItem, level));\n\t }\n\n\t var dataCells = [];\n\n\t for (var cellIdx = 0; cellIdx < this.columns.length; cellIdx++) {\n\t dataCells[cellIdx] = this$1._cell(dataItem, this$1.columns[cellIdx]);\n\t }\n\n\t if (this.hierarchy) {\n\t dataCells[0].colSpan = depth - level + 1;\n\t }\n\n\t return [ {\n\t type: \"data\",\n\t cells: cells.concat(dataCells),\n\t level: this.options.collapsible ? level : null\n\t } ];\n\t },\n\n\t _dataRows: function(dataItems, level) {\n\t var this$1 = this;\n\n\t var depth = this._depth();\n\t var rows = [];\n\n\t for (var idx = 0; idx < dataItems.length; idx++) {\n\t rows.push.apply(rows, this$1._dataRow(dataItems[idx], level, depth));\n\t }\n\n\t return rows;\n\t },\n\n\t _hierarchyRows: function() {\n\t var this$1 = this;\n\n\t var depth = this._depth();\n\t var data = this.data;\n\t var itemLevel = this.hierarchy.itemLevel;\n\t var hasFooter = this._hasFooterTemplate();\n\t var rows = [];\n\t var parents = [];\n\t var previousLevel = 0;\n\t var previousItemId;\n\n\t for (var idx = 0; idx < data.length; idx++) {\n\t var item = data[idx];\n\t var level = itemLevel(item);\n\n\t if (hasFooter) {\n\t if (level > previousLevel) {\n\t parents.push({ id: previousItemId, level: previousLevel });\n\t } else if (level < previousLevel) {\n\t rows.push.apply(rows, this$1._hierarchyFooterRows(parents, level, depth));\n\t }\n\n\t previousLevel = level;\n\t previousItemId = item.id;\n\t }\n\n\t rows.push.apply(rows, this$1._dataRow(item, level + 1, depth));\n\t }\n\n\t if (hasFooter) {\n\t rows.push.apply(rows, this._hierarchyFooterRows(parents, 0, depth));\n\n\t var rootAggregate = data.length ? this.aggregates[data[0].parentId] : {};\n\t rows.push(this._hierarchyFooter(rootAggregate, 0, depth));\n\t }\n\n\t this._prependHeaderRows(rows);\n\n\t return rows;\n\t },\n\n\t _hierarchyFooterRows: function(parents, currentLevel, depth) {\n\t var this$1 = this;\n\n\t var rows = [];\n\t while (parents.length && parents[parents.length - 1].level >= currentLevel) {\n\t var parent = parents.pop();\n\t rows.push(this$1._hierarchyFooter(this$1.aggregates[parent.id], parent.level + 1, depth));\n\t }\n\n\t return rows;\n\t },\n\n\t _hasFooterTemplate: function() {\n\t var columns = this.columns;\n\t for (var idx = 0; idx < columns.length; idx++) {\n\t if (columns[idx].footerTemplate) {\n\t return true;\n\t }\n\t }\n\t },\n\n\t _hierarchyFooter: function(aggregates, level, depth) {\n\t var cells = this.columns.map(function(column, index) {\n\t var colSpan = index ? 1 : depth - level + 1;\n\t if (column.footerTemplate) {\n\t return $.extend({\n\t background: \"#dfdfdf\",\n\t color: \"#333\",\n\t colSpan: colSpan,\n\t value: column.footerTemplate($.extend({}, (aggregates || {})[column.field]))\n\t }, column.footerCellOptions);\n\t }\n\n\t return $.extend({\n\t background: \"#dfdfdf\",\n\t color: \"#333\",\n\t colSpan: colSpan\n\t }, column.footerCellOptions);\n\t });\n\n\t return {\n\t type: \"footer\",\n\t cells: this._createPaddingCells(level).concat(cells)\n\t };\n\t },\n\n\t _footer: function(dataItem, level) {\n\t var rows = [];\n\t var footer = this.columns.some(function (column) { return column.groupFooterTemplate; });\n\n\t var templateData, group;\n\t if (footer) {\n\t group = {\n\t group: { items: dataItem.items,\n\t field: dataItem.field,\n\t value: dataItem.value }\n\t };\n\t templateData = {};\n\t Object.keys(dataItem.aggregates).forEach(function (key) {\n\t templateData[key] = $.extend({}, dataItem.aggregates[key], group);\n\t });\n\t }\n\n\t var cells = this.columns.map(function (column) {\n\t if (column.groupFooterTemplate) {\n\t var data = $.extend({}, templateData, dataItem.aggregates[column.field], group);\n\t return $.extend({\n\t background: \"#dfdfdf\",\n\t color: \"#333\",\n\t value: column.groupFooterTemplate(data)\n\t }, column.groupFooterCellOptions);\n\t }\n\n\t return $.extend({\n\t background: \"#dfdfdf\",\n\t color: \"#333\"\n\t }, column.groupFooterCellOptions);\n\t });\n\n\t if (footer) {\n\t rows.push({\n\t type: \"group-footer\",\n\t cells: this._createPaddingCells(this.groups.length).concat(cells),\n\t level: this.options.collapsible ? level : null\n\t });\n\t }\n\n\t return rows;\n\t },\n\n\t _isColumnVisible: function(column) {\n\t return this._visibleColumns([ column ]).length > 0 && (column.field || column.columns);\n\t },\n\n\t _visibleColumns: function(columns) {\n\t var this$1 = this;\n\n\t return columns.filter(function (column) {\n\t var result = !column.hidden;\n\t if (result && column.columns) {\n\t result = this$1._visibleColumns(column.columns).length > 0;\n\t }\n\t return result;\n\t });\n\t },\n\n\t _headerRow: function(row, groups) {\n\t var this$1 = this;\n\n\t var headers = row.cells.map(function(cell) {\n\t return $.extend(cell, {\n\t colSpan: cell.colSpan > 1 ? cell.colSpan : 1,\n\t rowSpan: row.rowSpan > 1 && !cell.colSpan ? row.rowSpan : 1\n\t });\n\t });\n\n\t if (this.hierarchy) {\n\t headers[0].colSpan = this._depth() + 1;\n\t }\n\n\t return {\n\t type: \"header\",\n\t cells: createArray(groups.length, function () { return $.extend({\n\t background: \"#7a7a7a\",\n\t color: \"#fff\"\n\t }, this$1.options.headerPaddingCellOptions); }).concat(headers)\n\t };\n\t },\n\n\t _prependHeaderRows: function(rows) {\n\t var this$1 = this;\n\n\t var groups = this.groups;\n\n\t var headerRows = [ { rowSpan: 1, cells: [], index: 0 } ];\n\n\t this._prepareHeaderRows(headerRows, this.options.columns);\n\n\t for (var idx = headerRows.length - 1; idx >= 0; idx--) {\n\t rows.unshift(this$1._headerRow(headerRows[idx], groups));\n\t }\n\t },\n\n\t _prepareHeaderRows: function(rows, columns, parentCell, parentRow) {\n\t var this$1 = this;\n\n\t var row = parentRow || rows[rows.length - 1];\n\t var childRow = rows[row.index + 1];\n\t var totalColSpan = 0;\n\n\t for (var idx = 0; idx < columns.length; idx++) {\n\t var column = columns[idx];\n\t if (this$1._isColumnVisible(column)) {\n\n\t var cell = $.extend({\n\t background: \"#7a7a7a\",\n\t color: \"#fff\",\n\t value: column.title || column.field,\n\t colSpan: 0\n\t }, column.headerCellOptions);\n\t row.cells.push(cell);\n\n\t if (column.columns && column.columns.length) {\n\t if (!childRow) {\n\t childRow = { rowSpan: 0, cells: [], index: rows.length };\n\t rows.push(childRow);\n\t }\n\t cell.colSpan = this$1._trimColumns(this$1._visibleColumns(column.columns)).length;\n\t this$1._prepareHeaderRows(rows, column.columns, cell, childRow);\n\t totalColSpan += cell.colSpan - 1;\n\t row.rowSpan = rows.length - row.index;\n\t }\n\t }\n\t }\n\n\t if (parentCell) {\n\t parentCell.colSpan += totalColSpan;\n\t }\n\t },\n\n\t _rows: function() {\n\t var this$1 = this;\n\n\t var rows = this._dataRows(this.data, 0);\n\n\t if (this.columns.length) {\n\t this._prependHeaderRows(rows);\n\t var footer = false;\n\n\t var cells = this.columns.map(function (column) {\n\t if (column.footerTemplate) {\n\t footer = true;\n\n\t return $.extend({\n\t background: \"#dfdfdf\",\n\t color: \"#333\",\n\t value: column.footerTemplate($.extend({}, this$1.aggregates, this$1.aggregates[column.field]))\n\t }, column.footerCellOptions);\n\t }\n\n\t return $.extend({\n\t background: \"#dfdfdf\",\n\t color: \"#333\"\n\t }, column.footerCellOptions);\n\t });\n\n\t if (footer) {\n\t rows.push({\n\t type: \"footer\",\n\t cells: this._createPaddingCells(this.groups.length).concat(cells)\n\t });\n\t }\n\t }\n\n\t return rows;\n\t },\n\n\t _headerDepth: function(columns) {\n\t var this$1 = this;\n\n\t var result = 1;\n\t var max = 0;\n\n\t for (var idx = 0; idx < columns.length; idx++) {\n\t if (columns[idx].columns) {\n\t var temp = this$1._headerDepth(columns[idx].columns);\n\t if (temp > max) {\n\t max = temp;\n\t }\n\t }\n\t }\n\t return result + max;\n\t },\n\n\t _freezePane: function() {\n\t var columns = this._visibleColumns(this.options.columns || []);\n\n\t var colSplit = this._visibleColumns(this._trimColumns(this._leafColumns(columns.filter(function(column) {\n\t return column.locked;\n\t })))).length;\n\n\t return {\n\t rowSplit: this._headerDepth(columns),\n\t colSplit: colSplit ? colSplit + this.groups.length : 0\n\t };\n\t },\n\n\t _cell: function(dataItem, column) {\n\t return $.extend({\n\t value: column.value(dataItem)\n\t }, column.cellOptions);\n\t },\n\n\t _depth: function() {\n\t var depth = 0;\n\n\t if (this.hierarchy) {\n\t depth = this.hierarchy.depth;\n\t } else {\n\t depth = this.groups.length;\n\t }\n\n\t return depth;\n\t },\n\n\t _columns: function() {\n\t var depth = this._depth();\n\t var columns = createArray(depth, function () { return ({ width: 20 }); });\n\n\t return columns.concat(this.columns.map(function(column) {\n\t return {\n\t width: parseInt(column.width, 10),\n\t autoWidth: column.width ? false : true\n\t };\n\t }));\n\t }\n\t});\n\n\tkendo.deepExtend(kendo.excel, {\n\t ExcelExporter: ExcelExporter,\n\t TemplateService: TemplateService\n\t});\n\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(997);\n\tmodule.exports = __webpack_require__(997);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 5:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.data\");\n\n/***/ }),\n\n/***/ 20:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.core\");\n\n/***/ }),\n\n/***/ 997:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(20), __webpack_require__(5), __webpack_require__(998) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function($, kendo){\n\n\t var ExcelExporter = kendo.excel.ExcelExporter;\n\n\t var extend = $.extend;\n\n\t kendo.excel.TemplateService.register({\n\t compile: kendo.template\n\t });\n\n\t kendo.ExcelExporter = kendo.Class.extend({\n\t init: function(options) {\n\t this.options = options;\n\t var dataSource = options.dataSource;\n\n\t if (dataSource instanceof kendo.data.DataSource) {\n\n\t if (!dataSource.filter()) {\n\t dataSource.options.filter = undefined;\n\t }\n\n\t this.dataSource = new dataSource.constructor(extend(\n\t {},\n\t dataSource.options,\n\t {\n\t page: options.allPages ? 0 : dataSource.page(),\n\t filter: dataSource.filter(),\n\t pageSize: options.allPages ? dataSource.total() : dataSource.pageSize() || dataSource.total(),\n\t sort: dataSource.sort(),\n\t group: dataSource.group(),\n\t aggregate: dataSource.aggregate()\n\t }));\n\n\t var data = dataSource.data();\n\n\t if (data.length > 0) {\n\t if (options.hierarchy) {\n\t for (var i = 0; i < data.length; i++) {\n\t if (data[i].expanded === false || data[i].expanded === undefined) {\n\t data[i].expanded = true;\n\t }\n\t }\n\t }\n\t // Avoid toJSON() for perf and avoid data() to prevent reparenting.\n\t this.dataSource._data = data;\n\n\t var transport = this.dataSource.transport;\n\t if (dataSource._isServerGrouped() && transport.options && transport.options.data) { // clear the transport data when using aspnet-mvc transport\n\t transport.options.data = null;\n\t }\n\t }\n\n\t } else {\n\t this.dataSource = kendo.data.DataSource.create(dataSource);\n\t }\n\t },\n\n\t _hierarchy: function() {\n\t var hierarchy = this.options.hierarchy;\n\t var dataSource = this.dataSource;\n\n\t if (hierarchy && dataSource.level) {\n\t hierarchy = {\n\t itemLevel: function(item) {\n\t return dataSource.level(item);\n\t }\n\t };\n\n\t var view = dataSource.view();\n\t var depth = 0;\n\t var level;\n\n\t for (var idx = 0; idx < view.length; idx++) {\n\t level = dataSource.level(view[idx]);\n\n\t if (level > depth) {\n\t depth = level;\n\t }\n\t }\n\n\t hierarchy.depth = depth + 1;\n\t } else {\n\t hierarchy = false;\n\t }\n\n\t return {\n\t hierarchy: hierarchy\n\t };\n\t },\n\n\t workbook: function() {\n\t return $.Deferred($.proxy(function(d) {\n\t this.dataSource.fetch()\n\t .then($.proxy(function() {\n\n\t var workbook = new ExcelExporter(extend({}, this.options, this._hierarchy(), {\n\t data: this.dataSource.view(),\n\t groups: this.dataSource.group(),\n\t aggregates: this.dataSource.aggregates()\n\t })).workbook();\n\n\t d.resolve(workbook, this.dataSource.view());\n\t }, this));\n\t }, this)).promise();\n\t }\n\t });\n\n\n\t})(kendo.jQuery, kendo);\n\n\treturn kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 998:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo-excel\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(999);\n\tmodule.exports = __webpack_require__(999);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 938:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./main\");\n\n/***/ }),\n\n/***/ 999:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(938), __webpack_require__(1000) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function($, kendo){\n\n\n\tkendo.ExcelMixin = {\n\t extend: function(proto) {\n\t proto.events.push(\"excelExport\");\n\t proto.options.excel = $.extend(proto.options.excel, this.options);\n\t proto.saveAsExcel = this.saveAsExcel;\n\t },\n\t options: {\n\t proxyURL: \"\",\n\t allPages: false,\n\t filterable: false,\n\t fileName: \"Export.xlsx\",\n\t collapsible: false\n\t },\n\t saveAsExcel: function() {\n\t var excel = this.options.excel || {};\n\n\t var exporter = new kendo.ExcelExporter({\n\t columns: this.columns,\n\t dataSource: this.dataSource,\n\t allPages: excel.allPages,\n\t filterable: excel.filterable,\n\t hierarchy: excel.hierarchy,\n\t collapsible: excel.collapsible\n\t });\n\n\t exporter.workbook().then($.proxy(function(book, data) {\n\t if (!this.trigger(\"excelExport\", { workbook: book, data: data })) {\n\t var workbook = new kendo.ooxml.Workbook(book);\n\n\t if(!workbook.options) {\n\t workbook.options = {};\n\t }\n\t workbook.options.skipCustomHeight = true;\n\n\t workbook.toDataURLAsync().then(function(dataURI) {\n\t kendo.saveAs({\n\t dataURI: dataURI,\n\t fileName: book.fileName || excel.fileName,\n\t proxyURL: excel.proxyURL,\n\t forceProxy: excel.forceProxy\n\t });\n\t });\n\n\t }\n\t }, this));\n\t }\n\t};\n\n\t})(kendo.jQuery, kendo);\n\n\treturn kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1000:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"../kendo.ooxml\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1016);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1016:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(jQuery) {(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function() {\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"angular\",\n\t name: \"AngularJS Directives\",\n\t category: \"framework\",\n\t description: \"Adds Kendo UI for AngularJS directives\",\n\t depends: [ \"core\" ],\n\t defer: true\n\t};\n\n\t(function ($, angular, undefined) {\n\t \"use strict\";\n\n\t // Angular2 exposes a global angular object, but it does not have an injector...\n\t if (!angular || !angular.injector) {\n\t return;\n\t }\n\n\t /*jshint eqnull:true,loopfunc:true,-W052,-W028 */\n\n\t var module = angular.module('kendo.directives', []),\n\t $injector = angular.injector(['ng']),\n\t $parse = $injector.get('$parse'),\n\t $timeout = $injector.get('$timeout'),\n\t $defaultCompile,\n\t $log = $injector.get('$log');\n\n\t function withoutTimeout(f) {\n\t var save = $timeout;\n\t try {\n\t $timeout = function(f){ return f(); };\n\t return f();\n\t } finally {\n\t $timeout = save;\n\t }\n\t }\n\n\t var OPTIONS_NOW;\n\n\t var createDataSource = (function() {\n\t var types = {\n\t TreeList : 'TreeListDataSource',\n\t TreeView : 'HierarchicalDataSource',\n\t Scheduler : 'SchedulerDataSource',\n\t PivotGrid : 'PivotDataSource',\n\t PivotConfigurator : 'PivotDataSource',\n\t PanelBar : 'HierarchicalDataSource',\n\t Menu : \"$PLAIN\",\n\t ContextMenu : \"$PLAIN\"\n\t };\n\t var toDataSource = function(dataSource, type) {\n\t if (type == '$PLAIN') {\n\t return dataSource;\n\t }\n\t return kendo.data[type].create(dataSource);\n\t };\n\t return function(scope, element, role, source) {\n\t var type = types[role] || 'DataSource';\n\t var current = scope.$eval(source);\n\t var ds = toDataSource(current, type);\n\n\t scope.$watch(source, function(mew) {\n\t var widget = kendoWidgetInstance(element);\n\n\t if (widget && typeof widget.setDataSource == \"function\") {\n\t if (mew !== current && mew !== widget.dataSource) {\n\t var ds = toDataSource(mew, type);\n\t widget.setDataSource(ds);\n\t current = mew;\n\t }\n\t }\n\t });\n\t return ds;\n\t };\n\t }());\n\n\t var ignoredAttributes = {\n\t kDataSource : true,\n\t kOptions : true,\n\t kRebind : true,\n\t kNgModel : true,\n\t kNgDelay : true\n\t };\n\n\t var ignoredOwnProperties = {\n\t // XXX: other names to ignore here?\n\t name : true,\n\t title : true,\n\t style : true\n\t };\n\n\t function createWidget(scope, element, attrs, widget, origAttr, controllers) {\n\t /* jshint latedef: false */\n\t if (!(element instanceof jQuery)) {\n\t throw new Error(\"The Kendo UI directives require jQuery to be available before AngularJS. Please include jquery before angular in the document.\");\n\t }\n\n\t var kNgDelay = attrs.kNgDelay,\n\t delayValue = scope.$eval(kNgDelay);\n\n\t controllers = controllers || [];\n\n\t var ngModel = controllers[0],\n\t ngForm = controllers[1];\n\n\t var ctor = $(element)[widget];\n\n\t if (!ctor) {\n\t window.console.error(\"Could not find: \" + widget);\n\t return null;\n\t }\n\n\t var parsed = parseOptions(scope, element, attrs, widget, ctor);\n\n\t var options = parsed.options;\n\n\t if (parsed.unresolved.length) {\n\t var promises = [];\n\n\t for (var i = 0, len = parsed.unresolved.length; i < len; i++) {\n\n\t var unresolved = parsed.unresolved[i];\n\n\t var promise = $.Deferred(function(d) {\n\t var unwatch = scope.$watch(unresolved.path, function(newValue) {\n\t if (newValue !== undefined) {\n\t unwatch();\n\t d.resolve();\n\t }\n\t });\n\t }).promise();\n\n\t promises.push(promise);\n\t }\n\n\t $.when.apply(null, promises).then(createIt);\n\n\t return;\n\t }\n\n\t if (kNgDelay && !delayValue) {\n\t var root = scope.$root || scope;\n\n\t var register = function() {\n\t var unregister = scope.$watch(kNgDelay, function(newValue) {\n\t if (newValue !== undefined) {\n\t unregister();\n\t // remove subsequent delays, to make ng-rebind work\n\t element.removeAttr(attrs.$attr.kNgDelay);\n\t kNgDelay = null;\n\t $timeout(createIt); // XXX: won't work without `timeout` ;-\\\n\t }\n\t });\n\t };\n\n\t // WARNING: the watchers should be registered in the digest cycle.\n\t // the fork here is for the timeout/non-timeout initiated widgets.\n\t if (/^\\$(digest|apply)$/.test(root.$$phase)) {\n\t register();\n\t } else {\n\t scope.$apply(register);\n\t }\n\n\t return;\n\t } else {\n\t return createIt();\n\t }\n\n\t function createIt() {\n\t var originalElement;\n\n\t if (attrs.kRebind) {\n\t originalElement = $($(element)[0].cloneNode(true));\n\t }\n\n\t // re-parse the options here.\n\t options = parseOptions(scope, element, attrs, widget, ctor).options;\n\n\t if (element.is(\"select\")) {\n\t (function(options){\n\t if (options.length > 0) {\n\t var first = $(options[0]);\n\t if (!/\\S/.test(first.text()) && /^\\?/.test(first.val())) {\n\t first.remove();\n\t }\n\n\t for (var i = 0; i < options.length; i++) {\n\t $(options[i]).off(\"$destroy\");\n\t }\n\t }\n\t }(element[0].options));\n\t }\n\n\t var object = ctor.call(element, OPTIONS_NOW = options).data(widget);\n\n\t exposeWidget(object, scope, attrs, widget, origAttr);\n\n\t scope.$emit(\"kendoWidgetCreated\", object);\n\n\t var destroyRegister = destroyWidgetOnScopeDestroy(scope, object);\n\n\t if (attrs.kRebind) {\n\t setupRebind(object, scope, element, originalElement, attrs.kRebind, destroyRegister, attrs);\n\t }\n\n\t if (attrs.kNgDisabled) {\n\t var kNgDisabled = attrs.kNgDisabled;\n\t var isDisabled = scope.$eval(kNgDisabled);\n\t if (isDisabled) {\n\t object.enable(!isDisabled);\n\t }\n\t bindToKNgDisabled(object, scope, element, kNgDisabled);\n\t }\n\n\t if (attrs.kNgReadonly) {\n\t var kNgReadonly = attrs.kNgReadonly;\n\t var isReadonly = scope.$eval(kNgReadonly);\n\t if (isReadonly) {\n\t object.readonly(isReadonly);\n\t }\n\t bindToKNgReadonly(object, scope, element, kNgReadonly);\n\t }\n\n\t // kNgModel is used for the \"logical\" value\n\t if (attrs.kNgModel) {\n\t bindToKNgModel(object, scope, attrs.kNgModel);\n\t }\n\n\t // 2 way binding: ngModel <-> widget.value()\n\t if (ngModel) {\n\t bindToNgModel(object, scope, element, ngModel, ngForm);\n\t }\n\n\t if (object) {\n\t propagateClassToWidgetWrapper(object, element);\n\t }\n\n\t return object;\n\t }\n\t }\n\n\n\t function parseOptions(scope, element, attrs, widget, ctor) {\n\t var role = widget.replace(/^kendo/, '');\n\t var unresolved = [];\n\t var optionsPath = attrs.kOptions || attrs.options;\n\t var optionsValue = scope.$eval(optionsPath);\n\n\t if (optionsPath && optionsValue === undefined) {\n\t unresolved.push({ option: \"options\", path: optionsPath });\n\t }\n\n\t var options = angular.extend({}, attrs.defaultOptions, optionsValue);\n\n\t function addOption(name, value) {\n\t var scopeValue = angular.copy(scope.$eval(value));\n\t if (scopeValue === undefined) {\n\t unresolved.push({ option: name, path: value });\n\t } else {\n\t options[name] = scopeValue;\n\t }\n\t }\n\n\n\t var widgetOptions = ctor.widget.prototype.options;\n\t var widgetEvents = ctor.widget.prototype.events;\n\n\n\t $.each(attrs, function(name, value) {\n\t if (name === \"source\" || name === \"kDataSource\" || name === \"kScopeField\" || name === \"scopeField\") {\n\t return;\n\t }\n\n\t var dataName = \"data\" + name.charAt(0).toUpperCase() + name.slice(1);\n\n\t if (name.indexOf(\"on\") === 0) { // let's search for such event.\n\t var eventKey = name.replace(/^on./, function(prefix) {\n\t return prefix.charAt(2).toLowerCase();\n\t });\n\n\t if (widgetEvents.indexOf(eventKey) > -1) {\n\t options[eventKey] = value;\n\t }\n\t } // don't elsif here - there are on* options\n\n\t if (widgetOptions.hasOwnProperty(dataName)) {\n\t addOption(dataName, value);\n\t } else if (widgetOptions.hasOwnProperty(name) && !ignoredOwnProperties[name]) {\n\t addOption(name, value);\n\t } else if (!ignoredAttributes[name]) {\n\t var match = name.match(/^k(On)?([A-Z].*)/);\n\t if (match) {\n\t var optionName = match[2].charAt(0).toLowerCase() + match[2].slice(1);\n\t if (match[1] && name != \"kOnLabel\" // XXX: k-on-label can be used on MobileSwitch :-\\\n\t ) {\n\t options[optionName] = value;\n\t } else {\n\t if (name == \"kOnLabel\") {\n\t optionName = \"onLabel\"; // XXX: that's awful.\n\t }\n\t addOption(optionName, value);\n\t }\n\t }\n\t }\n\t });\n\n\t // parse the datasource attribute\n\t var dataSource = attrs.kDataSource || attrs.source;\n\n\t if (dataSource) {\n\t options.dataSource = createDataSource(scope, element, role, dataSource);\n\t }\n\n\t // deepExtend in kendo.core (used in Editor) will fail with stack\n\t // overflow if we don't put it in an array :-\\\n\t options.$angular = [ scope ];\n\n\t return {\n\t options: options,\n\t unresolved: unresolved\n\t };\n\t }\n\n\t function bindToKNgDisabled(widget, scope, element, kNgDisabled) {\n\t if ((kendo.ui.PanelBar && widget instanceof kendo.ui.PanelBar) || (kendo.ui.Menu && widget instanceof kendo.ui.Menu)) {\n\t $log.warn(\"k-ng-disabled specified on a widget that does not have the enable() method: \" + (widget.options.name));\n\t return;\n\t }\n\t scope.$watch(kNgDisabled, function(newValue, oldValue) {\n\t if (newValue != oldValue) {\n\t widget.enable(!newValue);\n\t }\n\t });\n\t }\n\n\t function bindToKNgReadonly(widget, scope, element, kNgReadonly) {\n\t if (typeof widget.readonly != \"function\") {\n\t $log.warn(\"k-ng-readonly specified on a widget that does not have the readonly() method: \" + (widget.options.name));\n\t return;\n\t }\n\t scope.$watch(kNgReadonly, function(newValue, oldValue) {\n\t if (newValue != oldValue) {\n\t widget.readonly(newValue);\n\t }\n\t });\n\t }\n\n\t function exposeWidget(widget, scope, attrs, kendoWidget, origAttr) {\n\t if (attrs[origAttr]) {\n\t var set = $parse(attrs[origAttr]).assign;\n\t if (set) {\n\t // set the value of the expression to the kendo widget object to expose its api\n\t set(scope, widget);\n\t } else {\n\t throw new Error(origAttr + ' attribute used but expression in it is not assignable: ' + attrs[kendoWidget]);\n\t }\n\t }\n\t }\n\n\t function formValue(element) {\n\t if (/checkbox|radio/i.test(element.attr(\"type\"))) {\n\t return element.prop(\"checked\");\n\t }\n\t return element.val();\n\t }\n\n\t var formRegExp = /^(input|select|textarea)$/i;\n\n\t function isForm(element) {\n\t return formRegExp.test(element[0].tagName);\n\t }\n\n\t function bindToNgModel(widget, scope, element, ngModel, ngForm) {\n\t if (!widget.value) {\n\t return;\n\t }\n\n\t var value;\n\t // Some widgets trigger \"change\" on the input field\n\t // and this would result in two events sent (#135)\n\t var haveChangeOnElement = false;\n\n\t if (isForm(element)) {\n\t value = function() {\n\t return formValue(element);\n\t };\n\t } else {\n\t value = function() {\n\t return widget.value();\n\t };\n\t }\n\n\t // Angular will invoke $render when the view needs to be updated with the view value.\n\t var viewRender = function() {\n\t // Update the widget with the view value.\n\n\t // delaying with setTimout for cases where the datasource is set thereafter.\n\t // https://github.com/kendo-labs/angular-kendo/issues/304\n\t var val = ngModel.$viewValue;\n\t if (val === undefined) {\n\t val = ngModel.$modelValue;\n\t }\n\n\t if (val === undefined) {\n\t val = null;\n\t }\n\n\t haveChangeOnElement = true;\n\t setTimeout(function(){\n\t haveChangeOnElement = false;\n\t if (widget) { // might have been destroyed in between. :-(\n\t var kNgModel = scope[widget.element.attr(\"k-ng-model\")];\n\n\t if (kNgModel) {\n\t val = kNgModel;\n\t }\n\n\t if (widget.options.autoBind === false && !widget.listView.bound()) {\n\t if (val) {\n\t widget.value(val);\n\t }\n\t } else {\n\t widget.value(val);\n\t }\n\t }\n\t }, 0);\n\t };\n\n\t ngModel.$render = viewRender;\n\t setTimeout(function() {\n\t if (ngModel.$render !== viewRender) {\n\t ngModel.$render = viewRender;\n\t ngModel.$render();\n\t }\n\t });\n\n\t if (isForm(element)) {\n\t element.on(\"change\", function() {\n\t haveChangeOnElement = true;\n\t });\n\t }\n\n\t var onChange = function(pristine) {\n\t return function() {\n\t var formPristine;\n\t if (haveChangeOnElement && !element.is(\"select\")) {\n\t return;\n\t }\n\t if (pristine && ngForm) {\n\t formPristine = ngForm.$pristine;\n\t }\n\t ngModel.$setViewValue(value());\n\t if (pristine) {\n\t ngModel.$setPristine();\n\t if (formPristine) {\n\t ngForm.$setPristine();\n\t }\n\t }\n\t digest(scope);\n\t };\n\t };\n\n\t widget.first(\"change\", onChange(false));\n\t widget.first(\"spin\", onChange(false));\n\n\t if (!(kendo.ui.AutoComplete && widget instanceof kendo.ui.AutoComplete)) {\n\t widget.first(\"dataBound\", onChange(true));\n\t }\n\n\t var currentVal = value();\n\n\t // if the model value is undefined, then we set the widget value to match ( == null/undefined )\n\t // In telerik/kendo-ui-core#1027 we discovered that after the timeout the $viewValue arives as NaN in some weird, default form.\n\t // Hence the check below.\n\t if (!isNaN(ngModel.$viewValue) && currentVal != ngModel.$viewValue) {\n\t if (!ngModel.$isEmpty(ngModel.$viewValue)) {\n\t widget.value(ngModel.$viewValue);\n\t } else if (currentVal != null && currentVal !== \"\" && currentVal != ngModel.$viewValue) {\n\t ngModel.$setViewValue(currentVal);\n\t }\n\t }\n\n\t ngModel.$setPristine();\n\t }\n\n\t function bindToKNgModel(widget, scope, kNgModel) {\n\t if(kendo.ui.DateRangePicker && widget instanceof kendo.ui.DateRangePicker){\n\t var rangePickerModels = kNgModel.split(\",\");\n\t var rangePickerStartModel = rangePickerModels[0].trim();\n\t var rangePickerEndModel;\n\n\t bindToKNgModel(widget._startDateInput, scope, rangePickerStartModel);\n\t if (rangePickerModels[1]) {\n\t rangePickerEndModel = rangePickerModels[1].trim();\n\t bindToKNgModel(widget._endDateInput, scope, rangePickerEndModel);\n\t widget.range({start:scope[rangePickerStartModel], end:scope[rangePickerEndModel] });\n\t } else {\n\t widget.range({start:scope[rangePickerStartModel], end: null });\n\t }\n\n\t return;\n\t }\n\n\t if (typeof widget.value != \"function\") {\n\t $log.warn(\"k-ng-model specified on a widget that does not have the value() method: \" + (widget.options.name));\n\t return;\n\t }\n\n\t var form = $(widget.element).parents(\"ng-form, form\").first();\n\t var ngForm = kendo.getter(form.attr(\"name\"), true)(scope);\n\t var getter = $parse(kNgModel);\n\t var setter = getter.assign;\n\t var updating = false;\n\n\t var valueIsCollection = kendo.ui.MultiSelect && widget instanceof kendo.ui.MultiSelect ||\n\t kendo.ui.RangeSlider && widget instanceof kendo.ui.RangeSlider;\n\n\t var length = function(value) {\n\t //length is irrelevant when value is not collection\n\t return value && valueIsCollection ? value.length : 0;\n\t };\n\n\t var currentValueLength = length(getter(scope));\n\n\t widget.$angular_setLogicValue(getter(scope));\n\n\t // keep in sync\n\t var watchHandler = function(newValue, oldValue) {\n\t if (newValue === undefined) {\n\t // because widget's value() method usually checks if the new value is undefined,\n\t // in which case it returns the current value rather than clearing the field.\n\t // https://github.com/telerik/kendo-ui-core/issues/299\n\t newValue = null;\n\t }\n\n\t //compare values by reference if a collection\n\t if (updating || (newValue == oldValue && length(newValue) == currentValueLength)) {\n\t return;\n\t }\n\n\t currentValueLength = length(newValue);\n\t widget.$angular_setLogicValue(newValue);\n\t };\n\n\t if (valueIsCollection) {\n\t scope.$watchCollection(kNgModel, watchHandler);\n\t } else {\n\t scope.$watch(kNgModel, watchHandler);\n\t }\n\n\t var changeHandler = function() {\n\t updating = true;\n\n\t if (ngForm && ngForm.$pristine) {\n\t ngForm.$setDirty();\n\t }\n\n\t digest(scope, function(){\n\t setter(scope, widget.$angular_getLogicValue());\n\t currentValueLength = length(getter(scope));\n\t });\n\n\t updating = false;\n\t };\n\n\t widget.first(\"change\", changeHandler);\n\t widget.first(\"spin\", changeHandler);\n\t }\n\n\t function destroyWidgetOnScopeDestroy(scope, widget) {\n\t var deregister = scope.$on(\"$destroy\", function() {\n\t deregister();\n\t if (widget) {\n\t kendo.destroy(widget.element);\n\t widget = null;\n\t }\n\t });\n\n\t return deregister;\n\t }\n\n\t // mutation observers - propagate the original\n\t // element's class to the widget wrapper.\n\t function propagateClassToWidgetWrapper(widget, element) {\n\t if (!(window.MutationObserver && widget.wrapper)) {\n\t return;\n\t }\n\n\t var prevClassList = [].slice.call($(element)[0].classList);\n\n\t var mo = new MutationObserver(function(changes){\n\t suspend(); // make sure we don't trigger a loop\n\t if (!widget) {\n\t return;\n\t }\n\n\t changes.forEach(function(chg){\n\t var w = $(widget.wrapper)[0];\n\t switch (chg.attributeName) {\n\n\t case \"class\":\n\t // sync classes to the wrapper element\n\t var currClassList = [].slice.call(chg.target.classList);\n\t currClassList.forEach(function(cls){\n\t if (prevClassList.indexOf(cls) < 0) {\n\t w.classList.add(cls);\n\t if (kendo.ui.ComboBox && widget instanceof kendo.ui.ComboBox) { // https://github.com/kendo-labs/angular-kendo/issues/356\n\t widget.input[0].classList.add(cls);\n\t }\n\t }\n\t });\n\t prevClassList.forEach(function(cls){\n\t if (currClassList.indexOf(cls) < 0) {\n\t w.classList.remove(cls);\n\t if (kendo.ui.ComboBox && widget instanceof kendo.ui.ComboBox) { // https://github.com/kendo-labs/angular-kendo/issues/356\n\t widget.input[0].classList.remove(cls);\n\t }\n\t }\n\t });\n\t prevClassList = currClassList;\n\t break;\n\n\t case \"disabled\":\n\t if (typeof widget.enable == \"function\" && !widget.element.attr(\"readonly\")) {\n\t widget.enable(!$(chg.target).attr(\"disabled\"));\n\t }\n\t break;\n\n\t case \"readonly\":\n\t if (typeof widget.readonly == \"function\" && !widget.element.attr(\"disabled\")) {\n\t widget.readonly(!!$(chg.target).attr(\"readonly\"));\n\t }\n\t break;\n\t }\n\t });\n\n\t resume();\n\t });\n\n\t function suspend() {\n\t mo.disconnect();\n\t }\n\n\t function resume() {\n\t mo.observe($(element)[0], { attributes: true });\n\t }\n\n\t resume();\n\t widget.first(\"destroy\", suspend);\n\t }\n\n\t function setupRebind(widget, scope, element, originalElement, rebindAttr, destroyRegister, attrs) {\n\t // watch for changes on the expression passed in the k-rebind attribute\n\t var unregister = scope.$watch(rebindAttr, function(newValue, oldValue) {\n\t if (!widget._muteRebind && newValue !== oldValue) {\n\t unregister(); // this watcher will be re-added if we compile again!\n\n\t if (attrs._cleanUp) {\n\t attrs._cleanUp();\n\t }\n\n\t var templateOptions = WIDGET_TEMPLATE_OPTIONS[widget.options.name];\n\n\t if (templateOptions) {\n\t templateOptions.forEach(function(name) {\n\t var templateContents = scope.$eval(attrs[\"k\" + name]);\n\n\t if (templateContents) {\n\t originalElement.append($(templateContents).attr(kendo.toHyphens(\"k\" + name), \"\"));\n\t }\n\t });\n\t }\n\n\t var _wrapper = $(widget.wrapper)[0];\n\t var _element = $(widget.element)[0];\n\t var isUpload = widget.options.name === \"Upload\";\n\n\t if (isUpload) {\n\t element = $(_element);\n\t }\n\n\t var compile = element.injector().get(\"$compile\");\n\t widget._destroy();\n\n\t if (destroyRegister) {\n\t destroyRegister();\n\t }\n\n\t widget = null;\n\n\t if (_element) {\n\t if (_wrapper) {\n\t _wrapper.parentNode.replaceChild(_element, _wrapper);\n\t }\n\t $(element).replaceWith(originalElement);\n\t }\n\n\t compile(originalElement)(scope);\n\t }\n\t }, true); // watch for object equality. Use native or simple values.\n\t digest(scope);\n\t }\n\n\t function bind(f, obj) {\n\t return function(a, b) {\n\t return f.call(obj, a, b);\n\t };\n\t }\n\n\t function setTemplate(key, value) {\n\t this[key] = kendo.stringify(value); // jshint ignore:line\n\t }\n\n\t module.factory('directiveFactory', [ '$compile', function(compile) {\n\t var kendoRenderedTimeout;\n\t var RENDERED = false;\n\n\t // caching $compile for the dirty hack upstairs. This is awful, but we happen to have elements outside of the bootstrapped root :(.\n\t $defaultCompile = compile;\n\n\t var create = function(role, origAttr) {\n\t return {\n\t // Parse the directive for attributes and classes\n\t restrict: \"AC\",\n\t require: [ \"?ngModel\", \"^?form\" ],\n\t scope: false,\n\n\t controller: [ '$scope', '$attrs', '$element', function($scope, $attrs) {\n\t this.template = bind(setTemplate, $attrs);\n\t $attrs._cleanUp = bind(function(){\n\t this.template = null;\n\t $attrs._cleanUp = null;\n\t }, this);\n\t }],\n\n\t link: function(scope, element, attrs, controllers) {\n\t var $element = $(element);\n\n\t // we must remove data-kendo-widget-name attribute because\n\t // it breaks kendo.widgetInstance; can generate all kinds\n\t // of funny issues like\n\t //\n\t // https://github.com/kendo-labs/angular-kendo/issues/167\n\t //\n\t // but we still keep the attribute without the\n\t // `data-` prefix, so k-rebind would work.\n\t var roleattr = role.replace(/([A-Z])/g, \"-$1\");\n\n\t $element.attr(roleattr, $element.attr(\"data-\" + roleattr));\n\t $element[0].removeAttribute(\"data-\" + roleattr);\n\n\t var widget = createWidget(scope, element, attrs, role, origAttr, controllers);\n\n\t if (!widget) {\n\t return;\n\t }\n\n\t if (kendoRenderedTimeout) {\n\t clearTimeout(kendoRenderedTimeout);\n\t }\n\n\t kendoRenderedTimeout = setTimeout(function() {\n\t scope.$emit(\"kendoRendered\");\n\t if (!RENDERED) {\n\t RENDERED = true;\n\t $(\"form\").each(function(){\n\t var form = $(this).controller(\"form\");\n\t if (form) {\n\t form.$setPristine();\n\t }\n\t });\n\t }\n\t });\n\t }\n\t };\n\t };\n\n\t return {\n\t create: create\n\t };\n\t }]);\n\n\t var TAGNAMES = {\n\t Editor : \"textarea\",\n\t NumericTextBox : \"input\",\n\t DatePicker : \"input\",\n\t DateTimePicker : \"input\",\n\t TimePicker : \"input\",\n\t AutoComplete : \"input\",\n\t ColorPicker : \"input\",\n\t MaskedTextBox : \"input\",\n\t MultiSelect : \"input\",\n\t Upload : \"input\",\n\t Validator : \"form\",\n\t Button : \"button\",\n\t MobileButton : \"a\",\n\t MobileBackButton : \"a\",\n\t MobileDetailButton : \"a\",\n\t ListView : \"ul\",\n\t MobileListView: \"ul\",\n\t ScrollView : \"div\",\n\t PanelBar : \"ul\",\n\t TreeView : \"ul\",\n\t Menu : \"ul\",\n\t ContextMenu : \"ul\",\n\t ActionSheet : \"ul\",\n\t Switch : \"input\"\n\t };\n\n\t var SKIP_SHORTCUTS = [\n\t 'MobileView',\n\t 'MobileDrawer',\n\t 'MobileLayout',\n\t 'MobileSplitView',\n\t 'MobilePane',\n\t 'MobileModalView'\n\t ];\n\n\t var MANUAL_DIRECTIVES = [\n\t 'MobileApplication',\n\t 'MobileView',\n\t 'MobileModalView',\n\t 'MobileLayout',\n\t 'MobileActionSheet',\n\t 'MobileDrawer',\n\t 'MobileSplitView',\n\t 'MobilePane',\n\t 'MobileScrollView',\n\t 'MobilePopOver'\n\t ];\n\n\t angular.forEach(['MobileNavBar', 'MobileButton', 'MobileBackButton', 'MobileDetailButton', 'MobileTabStrip', 'MobileScrollView', 'MobileScroller'], function(widget) {\n\t MANUAL_DIRECTIVES.push(widget);\n\t widget = \"kendo\" + widget;\n\t module.directive(widget, function() {\n\t return {\n\t restrict: \"A\",\n\t link: function(scope, element, attrs) {\n\t createWidget(scope, element, attrs, widget, widget);\n\t }\n\t };\n\t });\n\t });\n\n\t function createDirectives(klass, isMobile) {\n\t function make(directiveName, widgetName) {\n\t module.directive(directiveName, [\n\t \"directiveFactory\",\n\t function(directiveFactory) {\n\t return directiveFactory.create(widgetName, directiveName);\n\t }\n\t ]);\n\t }\n\n\t var name = isMobile ? \"Mobile\" : \"\";\n\t name += klass.fn.options.name;\n\n\t var className = name;\n\t var shortcut = \"kendo\" + name.charAt(0) + name.substr(1).toLowerCase();\n\t name = \"kendo\" + name;\n\n\t // -type directives\n\t var dashed = name.replace(/([A-Z])/g, \"-$1\");\n\n\t if (SKIP_SHORTCUTS.indexOf(name.replace(\"kendo\", \"\")) == -1) {\n\t var names = name === shortcut ? [ name ] : [ name, shortcut ];\n\t angular.forEach(names, function(directiveName) {\n\t module.directive(directiveName, function(){\n\t return {\n\t restrict : \"E\",\n\t replace : true,\n\t template : function(element, attributes) {\n\t var tag = TAGNAMES[className] || \"div\";\n\t var scopeField = attributes.kScopeField || attributes.scopeField;\n\n\t return \"<\" + tag + \" \" + dashed + (scopeField ? ('=\"' + scopeField + '\"') : \"\") + \">\" + element.html() + \"\";\n\t }\n\t };\n\t });\n\t });\n\t }\n\n\t if (MANUAL_DIRECTIVES.indexOf(name.replace(\"kendo\", \"\")) > -1) {\n\t return;\n\t }\n\n\t // here name should be like kendoMobileListView so kendo-mobile-list-view works,\n\t // and shortcut like kendoMobilelistview, for kendo-mobilelistview\n\n\t make(name, name);\n\t if (shortcut != name) {\n\t make(shortcut, name);\n\t }\n\n\t }\n\n\t /* -----[ utils ]----- */\n\n\t function kendoWidgetInstance(el) {\n\t el = $(el);\n\t return kendo.widgetInstance(el, kendo.ui) ||\n\t kendo.widgetInstance(el, kendo.mobile.ui) ||\n\t kendo.widgetInstance(el, kendo.dataviz.ui);\n\t }\n\n\t function digest(scope, func) {\n\t var root = scope.$root || scope;\n\t var isDigesting = /^\\$(digest|apply)$/.test(root.$$phase);\n\t if (func) {\n\t if (isDigesting) {\n\t func();\n\t } else {\n\t root.$apply(func);\n\t }\n\t } else if (!isDigesting) {\n\t root.$digest();\n\t }\n\t }\n\n\t function destroyScope(scope, el) {\n\t scope.$destroy();\n\t if (el) {\n\t // prevent leaks. https://github.com/kendo-labs/angular-kendo/issues/237\n\t $(el)\n\t .removeData(\"$scope\")\n\t .removeData(\"$$kendoScope\")\n\t .removeData(\"$isolateScope\")\n\t .removeData(\"$isolateScopeNoTemplate\")\n\t .removeClass(\"ng-scope\");\n\t }\n\t }\n\n\t var encode = kendo.htmlEncode;\n\t var open = /{{/g;\n\t var close = /}}/g;\n\t var encOpen = '{​{';\n\t var encClose = '}​}';\n\n\t kendo.htmlEncode = function(str) {\n\t return encode(str)\n\t .replace(open, encOpen)\n\t .replace(close, encClose);\n\t };\n\n\t var pendingPatches = [];\n\n\t // defadvice will patch a class' method with another function. That\n\t // function will be called in a context containing `next` (to call\n\t // the next method) and `object` (a reference to the original\n\t // object).\n\t function defadvice(klass, methodName, func) {\n\t if ($.isArray(klass)) {\n\t return angular.forEach(klass, function(klass){\n\t defadvice(klass, methodName, func);\n\t });\n\t }\n\t if (typeof klass == \"string\") {\n\t var a = klass.split(\".\");\n\t var x = kendo;\n\t while (x && a.length > 0) {\n\t x = x[a.shift()];\n\t }\n\t if (!x) {\n\t pendingPatches.push([ klass, methodName, func ]);\n\t return false;\n\t }\n\t klass = x.prototype;\n\t }\n\t var origMethod = klass[methodName];\n\t klass[methodName] = function() {\n\t var self = this, args = arguments;\n\t return func.apply({\n\t self: self,\n\t next: function() {\n\t return origMethod.apply(self, arguments.length > 0 ? arguments : args);\n\t }\n\t }, args);\n\t };\n\t return true;\n\t }\n\n\t kendo.onWidgetRegistered(function(entry){\n\t pendingPatches = $.grep(pendingPatches, function(args){\n\t return !defadvice.apply(null, args);\n\t });\n\t createDirectives(entry.widget, entry.prefix == \"Mobile\");\n\t });\n\n\t /* -----[ Customize widgets for Angular ]----- */\n\n\t defadvice([ \"ui.Widget\", \"mobile.ui.Widget\" ], \"angular\", function(cmd, arg){\n\t var self = this.self;\n\t if (cmd == \"init\") {\n\t // `arg` here should be the widget options.\n\t // the Chart doesn't send the options to Widget::init in constructor\n\t // hence the OPTIONS_NOW hack (initialized in createWidget).\n\t if (!arg && OPTIONS_NOW) {\n\t arg = OPTIONS_NOW;\n\t }\n\t OPTIONS_NOW = null;\n\t if (arg && arg.$angular) {\n\t self.$angular_scope = arg.$angular[0];\n\t self.$angular_init(self.element, arg);\n\t }\n\t return;\n\t }\n\n\t var scope = self.$angular_scope;\n\n\t if (scope) {\n\t withoutTimeout(function(){\n\t var x = arg(), elements = x.elements, data = x.data;\n\t if (elements.length > 0) {\n\t switch (cmd) {\n\n\t case \"cleanup\":\n\t angular.forEach(elements, function(el){\n\t var itemScope = $(el).data(\"$$kendoScope\");\n\n\t if (itemScope && itemScope !== scope && itemScope.$$kendoScope) {\n\t destroyScope(itemScope, el);\n\t }\n\t });\n\t break;\n\n\t case \"compile\":\n\t var injector = self.element.injector();\n\t var compile = injector ? injector.get(\"$compile\") : $defaultCompile;\n\n\t angular.forEach(elements, function(el, i){\n\t var itemScope;\n\t if (x.scopeFrom) {\n\t itemScope = x.scopeFrom;\n\t } else {\n\t var vars = data && data[i];\n\t if (vars !== undefined) {\n\t itemScope = $.extend(scope.$new(), vars);\n\t itemScope.$$kendoScope = true;\n\t } else {\n\t itemScope = scope;\n\t }\n\t }\n\n\t $(el).data(\"$$kendoScope\", itemScope);\n\t compile(el)(itemScope);\n\t });\n\t digest(scope);\n\t break;\n\t }\n\t }\n\t });\n\t }\n\t });\n\n\t defadvice(\"ui.Widget\", \"$angular_getLogicValue\", function(){\n\t return this.self.value();\n\t });\n\n\t defadvice(\"ui.Widget\", \"$angular_setLogicValue\", function(val){\n\t this.self.value(val);\n\t });\n\n\t defadvice(\"ui.Select\", \"$angular_getLogicValue\", function(){\n\t var item = this.self.dataItem(),\n\t valueField = this.self.options.dataValueField;\n\n\t if (item) {\n\t if (this.self.options.valuePrimitive) {\n\t if (!!valueField) {\n\t return item[valueField];\n\t } else {\n\t return item;\n\t }\n\t } else {\n\t return item.toJSON();\n\t }\n\t } else {\n\t return null;\n\t }\n\t });\n\n\t defadvice(\"ui.Select\", \"$angular_setLogicValue\", function(val){\n\t var self = this.self;\n\t var options = self.options;\n\t var valueField = options.dataValueField;\n\t var text = options.text || \"\";\n\n\t if (val === undefined) {\n\t val = \"\";\n\t }\n\n\t if (valueField && !options.valuePrimitive && val) {\n\t text = val[options.dataTextField] || \"\";\n\t val = val[valueField || options.dataTextField];\n\t }\n\n\t if (self.options.autoBind === false && !self.listView.bound()) {\n\t if (!text && val && options.valuePrimitive) {\n\t self.value(val);\n\t } else {\n\t self._preselect(val, text);\n\t }\n\t } else {\n\t self.value(val);\n\t }\n\t });\n\n\t defadvice(\"ui.MultiSelect\", \"$angular_getLogicValue\", function() {\n\t var value = this.self.dataItems().slice(0);\n\t var valueField = this.self.options.dataValueField;\n\n\t if (valueField && this.self.options.valuePrimitive) {\n\t value = $.map(value, function(item) {\n\t return item[valueField];\n\t });\n\t }\n\n\t return value;\n\t });\n\n\t defadvice(\"ui.MultiSelect\", \"$angular_setLogicValue\", function(val){\n\t if (val == null) {\n\t val = [];\n\t }\n\n\t var self = this.self;\n\t var options = self.options;\n\t var valueField = options.dataValueField;\n\t var data = val;\n\n\t if (valueField && !options.valuePrimitive) {\n\t val = $.map(val, function(item) {\n\t return item[valueField];\n\t });\n\t }\n\n\t if (options.autoBind === false && !options.valuePrimitive && !self.listView.bound()) {\n\t self._preselect(data, val);\n\t } else {\n\t self.value(val);\n\t }\n\t });\n\n\t /* AutoComplete's getter and setter are removed!\n\t By design, AutoComplete should be bound only to primitive string\n\t value and data items are bound only to serve the list of suggestions.\n\n\t Binding multiple data items is supported by the MultiSelect widget.\n\t */\n\n\t // All event handlers that are strings are compiled the Angular way.\n\t defadvice(\"ui.Widget\", \"$angular_init\", function(element, options) {\n\t var self = this.self;\n\t if (options && !$.isArray(options)) {\n\t var scope = self.$angular_scope;\n\t for (var i = self.events.length; --i >= 0;) {\n\t var event = self.events[i];\n\t var handler = options[event];\n\t if (handler && typeof handler == \"string\") {\n\t options[event] = self.$angular_makeEventHandler(event, scope, handler);\n\t }\n\t }\n\t }\n\t });\n\n\t // most handers will only contain a kendoEvent in the scope.\n\t defadvice(\"ui.Widget\", \"$angular_makeEventHandler\", function(event, scope, handler){\n\t handler = $parse(handler);\n\t return function(e) {\n\t digest(scope, function() {\n\t handler(scope, { kendoEvent: e });\n\t });\n\t };\n\t });\n\n\t // for the Grid and ListView we add `data` and `selected` too.\n\t defadvice([ \"ui.Grid\", \"ui.ListView\", \"ui.TreeView\", \"ui.PanelBar\" ], \"$angular_makeEventHandler\", function(event, scope, handler){\n\t if (event != \"change\") {\n\t return this.next();\n\t }\n\t handler = $parse(handler);\n\t return function(ev) {\n\t var widget = ev.sender;\n\t var options = widget.options;\n\t var cell, multiple, locals = { kendoEvent: ev }, elems, items, columns, colIdx;\n\n\t if (angular.isString(options.selectable)) {\n\t cell = options.selectable.indexOf('cell') !== -1;\n\t multiple = options.selectable.indexOf('multiple') !== -1;\n\t }\n\t if (widget._checkBoxSelection) {\n\t multiple = true;\n\t }\n\n\t elems = locals.selected = this.select();\n\t items = locals.data = [];\n\t columns = locals.columns = [];\n\t for (var i = 0; i < elems.length; i++) {\n\t var item = cell ? elems[i].parentNode : elems[i];\n\t var dataItem = widget.dataItem(item);\n\t if (cell) {\n\t if (angular.element.inArray(dataItem, items) < 0) {\n\t items.push(dataItem);\n\t }\n\t colIdx = angular.element(elems[i]).index();\n\t if (angular.element.inArray(colIdx, columns) < 0 ) {\n\t columns.push(colIdx);\n\t }\n\t } else {\n\t items.push(dataItem);\n\t }\n\t }\n\n\t if (!multiple) {\n\t locals.dataItem = locals.data = items[0];\n\t locals.angularDataItem = kendo.proxyModelSetters(locals.dataItem);\n\t locals.selected = elems[0];\n\t }\n\n\t digest(scope, function() {\n\t handler(scope, locals);\n\t });\n\t };\n\t });\n\n\t // If no `template` is supplied for Grid columns, provide an Angular\n\t // template. The reason is that in this way AngularJS will take\n\t // care to update the view as the data in scope changes.\n\t defadvice(\"ui.Grid\", \"$angular_init\", function(element, options){\n\t this.next();\n\t if (options.columns) {\n\t var settings = $.extend({}, kendo.Template, options.templateSettings);\n\t angular.forEach(options.columns, function(col){\n\t if (col.field && !col.template && !col.format && !col.values && (col.encoded === undefined || col.encoded)) {\n\t col.template = \"#: \" +\n\t kendo.expr(col.field, settings.paramName) + \"#\";\n\t }\n\t });\n\t }\n\t });\n\n\t {\n\t // mobile/ButtonGroup does not have a \"value\" method, but looks\n\t // like it would be useful. We provide it here.\n\n\t defadvice(\"mobile.ui.ButtonGroup\", \"value\", function(mew){\n\t var self = this.self;\n\t if (mew != null) {\n\t self.select(self.element.children(\"li.km-button\").eq(mew));\n\t self.trigger(\"change\");\n\t self.trigger(\"select\", { index: self.selectedIndex });\n\t }\n\t return self.selectedIndex;\n\t });\n\n\t defadvice(\"mobile.ui.ButtonGroup\", \"_select\", function(){\n\t this.next();\n\t this.self.trigger(\"change\");\n\t });\n\t }\n\n\t // mobile directives\n\t module\n\t .directive('kendoMobileApplication', function() {\n\t return {\n\t terminal: true,\n\t link: function(scope, element, attrs) {\n\t createWidget(scope, element, attrs, 'kendoMobileApplication', 'kendoMobileApplication');\n\t }\n\t };\n\t }).directive('kendoMobileView', function() {\n\t return {\n\t scope: true,\n\t link: {\n\t pre: function(scope, element, attrs) {\n\t attrs.defaultOptions = scope.viewOptions;\n\t attrs._instance = createWidget(scope, element, attrs, 'kendoMobileView', 'kendoMobileView');\n\t },\n\n\t post: function(scope, element, attrs) {\n\t attrs._instance._layout();\n\t attrs._instance._scroller();\n\t }\n\t }\n\t };\n\t }).directive('kendoMobileDrawer', function() {\n\t return {\n\t scope: true,\n\t link: {\n\t pre: function(scope, element, attrs) {\n\t attrs.defaultOptions = scope.viewOptions;\n\t attrs._instance = createWidget(scope, element, attrs, 'kendoMobileDrawer', 'kendoMobileDrawer');\n\t },\n\n\t post: function(scope, element, attrs) {\n\t attrs._instance._layout();\n\t attrs._instance._scroller();\n\t }\n\t }\n\t };\n\t }).directive('kendoMobileModalView', function() {\n\t return {\n\t scope: true,\n\t link: {\n\t pre: function(scope, element, attrs) {\n\t attrs.defaultOptions = scope.viewOptions;\n\t attrs._instance = createWidget(scope, element, attrs, 'kendoMobileModalView', 'kendoMobileModalView');\n\t },\n\n\t post: function(scope, element, attrs) {\n\t attrs._instance._layout();\n\t attrs._instance._scroller();\n\t }\n\t }\n\t };\n\t }).directive('kendoMobileSplitView', function() {\n\t return {\n\t terminal: true,\n\t link: {\n\t pre: function(scope, element, attrs) {\n\t attrs.defaultOptions = scope.viewOptions;\n\t attrs._instance = createWidget(scope, element, attrs, 'kendoMobileSplitView', 'kendoMobileSplitView');\n\t },\n\n\t post: function(scope, element, attrs) {\n\t attrs._instance._layout();\n\t }\n\t }\n\t };\n\t }).directive('kendoMobilePane', function() {\n\t return {\n\t terminal: true,\n\t link: {\n\t pre: function(scope, element, attrs) {\n\t attrs.defaultOptions = scope.viewOptions;\n\t createWidget(scope, element, attrs, 'kendoMobilePane', 'kendoMobilePane');\n\t }\n\t }\n\t };\n\t }).directive('kendoMobileLayout', function() {\n\t return {\n\t link: {\n\t pre: function (scope, element, attrs) {\n\t createWidget(scope, element, attrs, 'kendoMobileLayout', 'kendoMobileLayout');\n\t }\n\t }\n\t };\n\t }).directive('kendoMobileActionSheet', function() {\n\t return {\n\t restrict: \"A\",\n\t link: function(scope, element, attrs) {\n\t element.find(\"a[k-action]\").each(function() {\n\t $(this).attr(\"data-\" + kendo.ns + \"action\", $(this).attr(\"k-action\"));\n\t });\n\n\t createWidget(scope, element, attrs, 'kendoMobileActionSheet', 'kendoMobileActionSheet');\n\t }\n\t };\n\t }).directive('kendoMobilePopOver', function() {\n\t return {\n\t terminal: true,\n\t link: {\n\t pre: function(scope, element, attrs) {\n\t attrs.defaultOptions = scope.viewOptions;\n\t createWidget(scope, element, attrs, 'kendoMobilePopOver', 'kendoMobilePopOver');\n\t }\n\t }\n\t };\n\t }).directive('kendoViewTitle', function(){\n\t return {\n\t restrict : \"E\",\n\t replace : true,\n\t template : function(element) {\n\t return \"\" + element.html() + \"\";\n\t }\n\t };\n\t }).directive('kendoMobileHeader', function() {\n\t return {\n\t restrict: \"E\",\n\t link: function(scope, element) {\n\t element.addClass(\"km-header\").attr(\"data-role\", \"header\");\n\t }\n\t };\n\t }).directive('kendoMobileFooter', function() {\n\t return {\n\t restrict: 'E',\n\t link: function(scope, element) {\n\t element.addClass(\"km-footer\").attr(\"data-role\", \"footer\");\n\t }\n\t };\n\t }).directive('kendoMobileScrollViewPage', function(){\n\t return {\n\t restrict : \"E\",\n\t replace : true,\n\t template : function(element) {\n\t return \"
    \" + element.html() + \"
    \";\n\t }\n\t };\n\t });\n\n\t angular.forEach(['align', 'icon', 'rel', 'transition', 'actionsheetContext'], function(attr) {\n\t var kAttr = \"k\" + attr.slice(0, 1).toUpperCase() + attr.slice(1);\n\n\t module.directive(kAttr, function() {\n\t return {\n\t restrict: 'A',\n\t priority: 2,\n\t link: function(scope, element, attrs) {\n\t element.attr(kendo.attr(kendo.toHyphens(attr)), scope.$eval(attrs[kAttr]));\n\t }\n\t };\n\t });\n\t });\n\n\t var WIDGET_TEMPLATE_OPTIONS = {\n\t \"TreeMap\": [ \"Template\" ],\n\t \"MobileListView\": [ \"HeaderTemplate\", \"Template\" ],\n\t \"MobileScrollView\": [ \"EmptyTemplate\", \"Template\" ],\n\t \"Grid\": [ \"AltRowTemplate\", \"DetailTemplate\", \"RowTemplate\" ],\n\t \"ListView\": [ \"EditTemplate\", \"Template\", \"AltTemplate\" ],\n\t \"Pager\": [ \"SelectTemplate\", \"LinkTemplate\" ],\n\t \"PivotGrid\": [ \"ColumnHeaderTemplate\", \"DataCellTemplate\", \"RowHeaderTemplate\" ],\n\t \"Scheduler\": [\"AllDayEventTemplate\", \"DateHeaderTemplate\", \"EventTemplate\", \"MajorTimeHeaderTemplate\", \"MinorTimeHeaderTemplate\"],\n\t \"ScrollView\": [ \"Template\" ],\n\t \"PanelBar\": [ \"Template\" ],\n\t \"TreeView\": [ \"Template\" ],\n\t \"Validator\": [ \"ErrorTemplate\" ]\n\t };\n\n\t (function() {\n\t var templateDirectives = {};\n\t angular.forEach(WIDGET_TEMPLATE_OPTIONS, function(templates, widget) {\n\t angular.forEach(templates, function(template) {\n\t if (!templateDirectives[template]) {\n\t templateDirectives[template] = [ ];\n\t }\n\t templateDirectives[template].push(\"?^^kendo\" + widget);\n\t });\n\t });\n\n\t angular.forEach(templateDirectives, function(parents, directive) {\n\t var templateName = \"k\" + directive;\n\t var attrName = kendo.toHyphens(templateName);\n\n\t module.directive(templateName, function() {\n\t return {\n\t restrict: \"A\",\n\t require: parents,\n\t terminal: true,\n\t compile: function($element, $attrs) {\n\t if ($attrs[templateName] !== \"\") {\n\t return;\n\t }\n\n\t $element.removeAttr(attrName);\n\t var template = $element[0].outerHTML;\n\n\t return function(scope, element, attrs, controllers) {\n\t var controller;\n\n\t while(!controller && controllers.length) {\n\t controller = controllers.shift();\n\t }\n\n\t if (!controller) {\n\t $log.warn(attrName + \" without a matching parent widget found. It can be one of the following: \" + parents.join(\", \"));\n\t } else {\n\t controller.template(templateName, template);\n\t element.remove();\n\t }\n\t };\n\t }\n\t };\n\t });\n\t });\n\n\t })();\n\n\n\t})(window.kendo.jQuery, window.angular);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1017)))\n\n/***/ }),\n\n/***/ 1017:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"jquery\");\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1019);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1019:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(1027), __webpack_require__(1021), __webpack_require__(1022), __webpack_require__(1023), __webpack_require__(1024), __webpack_require__(1025),\n\n\t __webpack_require__(1026),\n\t __webpack_require__(1020),\n\t __webpack_require__(1028),\n\t __webpack_require__(1029),\n\t __webpack_require__(1030),\n\t __webpack_require__(1031),\n\t __webpack_require__(1032),\n\t __webpack_require__(1033),\n\t __webpack_require__(1034)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"aspnetmvc\",\n\t name: \"ASP.NET MVC\",\n\t category: \"wrappers\",\n\t description: \"Scripts required by Telerik UI for ASP.NET MVC\",\n\t depends: [ \"data\", \"combobox\", \"multicolumncombobox\", \"dropdownlist\", \"multiselect\", \"validator\" ]\n\t};\n\n\t(function($, undefined) {\n\t var extend = $.extend;\n\n\t $(function() { kendo.__documentIsReady = true; });\n\n\t function syncReady(cb) {\n\t if(kendo.__documentIsReady) { //sync operation\n\t cb();\n\t }\n\t else { //async operation\n\t $(cb);\n\t }\n\t }\n\n\t extend(kendo, {\n\t syncReady: syncReady\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1020:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./aspnetmvc/kendo.combobox.aspnetmvc\");\n\n/***/ }),\n\n/***/ 1021:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.combobox\");\n\n/***/ }),\n\n/***/ 1022:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dropdownlist\");\n\n/***/ }),\n\n/***/ 1023:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dropdowntree\");\n\n/***/ }),\n\n/***/ 1024:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.multiselect\");\n\n/***/ }),\n\n/***/ 1025:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.validator\");\n\n/***/ }),\n\n/***/ 1026:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./aspnetmvc/kendo.data.aspnetmvc\");\n\n/***/ }),\n\n/***/ 1027:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data\");\n\n/***/ }),\n\n/***/ 1028:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./aspnetmvc/kendo.multicolumncombobox.aspnetmvc\");\n\n/***/ }),\n\n/***/ 1029:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./aspnetmvc/kendo.dropdownlist.aspnetmvc\");\n\n/***/ }),\n\n/***/ 1030:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./aspnetmvc/kendo.dropdowntree.aspnetmvc\");\n\n/***/ }),\n\n/***/ 1031:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./aspnetmvc/kendo.multiselect.aspnetmvc\");\n\n/***/ }),\n\n/***/ 1032:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./aspnetmvc/kendo.imagebrowser.aspnetmvc\");\n\n/***/ }),\n\n/***/ 1033:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./aspnetmvc/kendo.validator.aspnetmvc\");\n\n/***/ }),\n\n/***/ 1034:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./aspnetmvc/kendo.filemanager.aspnetmvc\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1035);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1035:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1036), __webpack_require__(1037), __webpack_require__(1038) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"autocomplete\",\n\t name: \"AutoComplete\",\n\t category: \"web\",\n\t description: \"The AutoComplete widget provides suggestions depending on the typed text.It also allows multiple value entries.\",\n\t depends: [ \"list\" ],\n\t features: [ {\n\t id: \"mobile-scroller\",\n\t name: \"Mobile scroller\",\n\t description: \"Support for kinetic scrolling in mobile device\",\n\t depends: [ \"mobile.scroller\" ]\n\t }, {\n\t id: \"virtualization\",\n\t name: \"VirtualList\",\n\t description: \"Support for virtualization\",\n\t depends: [ \"virtuallist\" ]\n\t } ]\n\t};\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t support = kendo.support,\n\t caret = kendo.caret,\n\t activeElement = kendo._activeElement,\n\t placeholderSupported = support.placeholder,\n\t ui = kendo.ui,\n\t List = ui.List,\n\t keys = kendo.keys,\n\t DataSource = kendo.data.DataSource,\n\t ARIA_DISABLED = \"aria-disabled\",\n\t ARIA_READONLY = \"aria-readonly\",\n\t CHANGE = \"change\",\n\t DEFAULT = \"k-state-default\",\n\t DISABLED = \"disabled\",\n\t READONLY = \"readonly\",\n\t FOCUSED = \"k-state-focused\",\n\t SELECTED = \"k-state-selected\",\n\t STATEDISABLED = \"k-state-disabled\",\n\t AUTOCOMPLETEVALUE = \"off\",\n\t HOVER = \"k-state-hover\",\n\t ns = \".kendoAutoComplete\",\n\t HOVEREVENTS = \"mouseenter\" + ns + \" mouseleave\" + ns,\n\t proxy = $.proxy;\n\n\t function indexOfWordAtCaret(caretIdx, text, separator) {\n\t return separator ? text.substring(0, caretIdx).split(separator).length - 1 : 0;\n\t }\n\n\t function wordAtCaret(caretIdx, text, separator) {\n\t return text.split(separator)[indexOfWordAtCaret(caretIdx, text, separator)];\n\t }\n\n\t function replaceWordAtCaret(caretIdx, text, word, separator, defaultSeparator) {\n\t var words = text.split(separator);\n\n\t words.splice(indexOfWordAtCaret(caretIdx, text, separator), 1, word);\n\n\t if (separator && words[words.length - 1] !== \"\") {\n\t words.push(\"\");\n\t }\n\n\t return words.join(defaultSeparator);\n\t }\n\n\t var AutoComplete = List.extend({\n\t init: function (element, options) {\n\t var that = this, wrapper, disabled;\n\n\t that.ns = ns;\n\t options = $.isArray(options) ? { dataSource: options} : options;\n\n\t List.fn.init.call(that, element, options);\n\n\t element = that.element;\n\t options = that.options;\n\n\t options.placeholder = options.placeholder || element.attr(\"placeholder\");\n\t if (placeholderSupported) {\n\t element.attr(\"placeholder\", options.placeholder);\n\t }\n\n\t that._wrapper();\n\t that._loader();\n\t that._clearButton();\n\n\t that._dataSource();\n\t that._ignoreCase();\n\n\t element[0].type = \"text\";\n\t wrapper = that.wrapper;\n\n\t that._popup();\n\n\t element\n\t .addClass(\"k-input\")\n\t .on(\"keydown\" + ns, proxy(that._keydown, that))\n\t .on(\"keypress\" + ns, proxy(that._keypress, that))\n\t .on(\"input\" + ns, proxy(that._search, that))\n\t .on(\"paste\" + ns, proxy(that._search, that))\n\t .on(\"focus\" + ns, function () {\n\t that._prev = that._accessor();\n\t that._oldText = that._prev;\n\t that._placeholder(false);\n\t wrapper.addClass(FOCUSED);\n\t })\n\t .on(\"focusout\" + ns, function () {\n\t that._change();\n\t that._placeholder();\n\t that.close();\n\t wrapper.removeClass(FOCUSED);\n\t })\n\t .attr({\n\t autocomplete: AUTOCOMPLETEVALUE,\n\t role: \"textbox\",\n\t \"aria-haspopup\": true\n\t });\n\n\t that._clear.on(\"click\" + ns + \" touchend\" + ns, proxy(that._clearValue, that));\n\t that._enable();\n\n\t that._old = that._accessor();\n\n\t if (element[0].id) {\n\t element.attr(\"aria-owns\", that.ul[0].id);\n\t }\n\n\t that._aria();\n\n\t that._placeholder();\n\n\t that._initList();\n\n\t disabled = $(that.element).parents(\"fieldset\").is(':disabled');\n\n\t if (disabled) {\n\t that.enable(false);\n\t }\n\n\t that.listView.bind(\"click\", function(e) { e.preventDefault(); });\n\n\t that._resetFocusItemHandler = $.proxy(that._resetFocusItem, that);\n\n\t kendo.notify(that);\n\t that._toggleCloseVisibility();\n\t },\n\n\t options: {\n\t name: \"AutoComplete\",\n\t enabled: true,\n\t suggest: false,\n\t template: \"\",\n\t groupTemplate: \"#:data#\",\n\t fixedGroupTemplate: \"#:data#\",\n\t dataTextField: \"\",\n\t minLength: 1,\n\t enforceMinLength: false,\n\t delay: 200,\n\t height: 200,\n\t filter: \"startswith\",\n\t ignoreCase: true,\n\t highlightFirst: false,\n\t separator: null,\n\t placeholder: \"\",\n\t animation: {},\n\t virtual: false,\n\t value: null,\n\t clearButton: true,\n\t autoWidth: false,\n\t popup: null\n\t },\n\n\t _dataSource: function() {\n\t var that = this;\n\n\t if (that.dataSource && that._refreshHandler) {\n\t that._unbindDataSource();\n\t } else {\n\t that._progressHandler = proxy(that._showBusy, that);\n\t that._errorHandler = proxy(that._hideBusy, that);\n\t }\n\n\t that.dataSource = DataSource.create(that.options.dataSource)\n\t .bind(\"progress\", that._progressHandler)\n\t .bind(\"error\", that._errorHandler);\n\t },\n\n\t setDataSource: function(dataSource) {\n\t this.options.dataSource = dataSource;\n\t this._dataSource();\n\n\t this.listView.setDataSource(this.dataSource);\n\t },\n\n\t events: [\n\t \"open\",\n\t \"close\",\n\t CHANGE,\n\t \"select\",\n\t \"filtering\",\n\t \"dataBinding\",\n\t \"dataBound\"\n\t ],\n\n\t setOptions: function(options) {\n\t var listOptions = this._listOptions(options);\n\n\t List.fn.setOptions.call(this, options);\n\n\t this.listView.setOptions(listOptions);\n\t this._accessors();\n\t this._aria();\n\t this._clearButton();\n\t },\n\n\t _listOptions: function(options) {\n\t var listOptions = List.fn._listOptions.call(this, $.extend(options, {\n\t skipUpdateOnBind: true\n\t }));\n\n\t listOptions.dataValueField = listOptions.dataTextField;\n\t listOptions.selectedItemChange = null;\n\n\t return listOptions;\n\t },\n\n\t _editable: function(options) {\n\t var that = this,\n\t element = that.element,\n\t wrapper = that.wrapper.off(ns),\n\t readonly = options.readonly,\n\t disable = options.disable;\n\n\t if (!readonly && !disable) {\n\t wrapper\n\t .addClass(DEFAULT)\n\t .removeClass(STATEDISABLED)\n\t .on(HOVEREVENTS, that._toggleHover);\n\n\t element.removeAttr(DISABLED)\n\t .removeAttr(READONLY)\n\t .attr(ARIA_DISABLED, false)\n\t .attr(ARIA_READONLY, false);\n\t } else {\n\t wrapper\n\t .addClass(disable ? STATEDISABLED : DEFAULT)\n\t .removeClass(disable ? DEFAULT : STATEDISABLED);\n\n\t element.attr(DISABLED, disable)\n\t .attr(READONLY, readonly)\n\t .attr(ARIA_DISABLED, disable)\n\t .attr(ARIA_READONLY, readonly);\n\t }\n\t },\n\n\t close: function () {\n\t var that = this;\n\t var current = that.listView.focus();\n\n\t if (current) {\n\t current.removeClass(SELECTED);\n\t }\n\n\t that.popup.close();\n\t },\n\n\t destroy: function() {\n\t var that = this;\n\n\t that.element.off(ns);\n\t that._clear.off(ns);\n\t that.wrapper.off(ns);\n\n\t List.fn.destroy.call(that);\n\t },\n\n\t refresh: function() {\n\t this.listView.refresh();\n\t },\n\n\t select: function (li) {\n\t this._select(li);\n\t },\n\n\t search: function (word) {\n\t var that = this,\n\t options = that.options,\n\t ignoreCase = options.ignoreCase,\n\t separator = that._separator(),\n\t length,\n\t accentFoldingFiltering = that.dataSource.options.accentFoldingFiltering;\n\n\t word = word || that._accessor();\n\n\t clearTimeout(that._typingTimeout);\n\n\t if (separator) {\n\t word = wordAtCaret(caret(that.element)[0], word, separator);\n\t }\n\n\t length = word.length;\n\n\t if ((!options.enforceMinLength && !length) || length >= options.minLength) {\n\t that._open = true;\n\n\t that._mute(function() {\n\t this.listView.value([]);\n\t });\n\n\t that._filterSource({\n\t value: ignoreCase ? (accentFoldingFiltering ? word.toLocaleLowerCase(accentFoldingFiltering) : word.toLowerCase()) : word,\n\t operator: options.filter,\n\t field: options.dataTextField,\n\t ignoreCase: ignoreCase\n\t });\n\n\t that.one(\"close\", $.proxy(that._unifySeparators, that));\n\t }\n\t that._toggleCloseVisibility();\n\t },\n\n\t suggest: function (word) {\n\t var that = this,\n\t key = that._last,\n\t value = that._accessor(),\n\t element = that.element[0],\n\t caretIdx = caret(element)[0],\n\t separator = that._separator(),\n\t words = value.split(separator),\n\t wordIndex = indexOfWordAtCaret(caretIdx, value, separator),\n\t selectionEnd = caretIdx,\n\t idx,\n\t accentFoldingFiltering = that.dataSource.options.accentFoldingFiltering;\n\n\t if (key == keys.BACKSPACE || key == keys.DELETE) {\n\t that._last = undefined;\n\t return;\n\t }\n\n\t word = word || \"\";\n\n\t if (typeof word !== \"string\") {\n\t if (word[0]) {\n\t word = that.dataSource.view()[List.inArray(word[0], that.ul[0])];\n\t }\n\n\t word = word ? that._text(word) : \"\";\n\t }\n\n\t if (caretIdx <= 0) {\n\t caretIdx = (accentFoldingFiltering ? value.toLocaleLowerCase(accentFoldingFiltering) : value.toLowerCase()).indexOf(accentFoldingFiltering ? word.toLocaleLowerCase(accentFoldingFiltering) : word.toLowerCase()) + 1;\n\t }\n\n\t idx = value.substring(0, caretIdx).lastIndexOf(separator);\n\t idx = idx > -1 ? caretIdx - (idx + separator.length) : caretIdx;\n\t value = words[wordIndex].substring(0, idx);\n\n\t if (word) {\n\t word = word.toString();\n\t idx = (accentFoldingFiltering ? word.toLocaleLowerCase(accentFoldingFiltering) : word.toLowerCase()).indexOf(accentFoldingFiltering ? value.toLocaleLowerCase(accentFoldingFiltering) : value.toLowerCase());\n\t if (idx > -1) {\n\t word = word.substring(idx + value.length);\n\n\t selectionEnd = caretIdx + word.length;\n\n\t value += word;\n\t }\n\n\t if (separator && words[words.length - 1] !== \"\") {\n\t words.push(\"\");\n\t }\n\n\t }\n\n\t words[wordIndex] = value;\n\n\t that._accessor(words.join(separator || \"\"));\n\n\t if (element === activeElement()) {\n\t caret(element, caretIdx, selectionEnd);\n\t }\n\t },\n\n\t value: function (value) {\n\t if (value !== undefined) {\n\t this.listView.value(value);\n\n\t this._accessor(value);\n\t this._old = this._accessor();\n\t this._oldText = this._accessor();\n\t } else {\n\t return this._accessor();\n\t }\n\t this._toggleCloseVisibility();\n\t },\n\n\t _click: function(e) {\n\t var item = e.item;\n\t var that = this;\n\t var element = that.element;\n\t var dataItem = that.listView.dataItemByIndex(that.listView.getElementIndex(item));\n\n\t e.preventDefault();\n\n\t that._active = true;\n\n\t if (that.trigger(\"select\", { dataItem: dataItem, item: item })) {\n\t that.close();\n\t return;\n\t }\n\t that._oldText = element.val();\n\t that._select(item).done(function() {\n\t that._blur();\n\n\t caret(element, element.val().length);\n\t });\n\t },\n\n\t _clearText: $.noop,\n\n\t _resetFocusItem: function() {\n\t var index = this.options.highlightFirst ? 0 : -1;\n\n\t if (this.options.virtual) {\n\t this.listView.scrollTo(0);\n\t }\n\n\t this.listView.focus(index);\n\t },\n\n\t _listBound: function() {\n\t var that = this;\n\t var popup = that.popup;\n\t var options = that.options;\n\t var data = that.dataSource.flatView();\n\t var length = data.length;\n\t var groupsLength = that.dataSource._group.length;\n\t var isActive = that.element[0] === activeElement();\n\t var action;\n\n\t that._renderFooter();\n\t that._renderNoData();\n\t that._toggleNoData(!length);\n\t that._toggleHeader(!!groupsLength && !!length);\n\n\t that._resizePopup();\n\n\t popup.position();\n\n\t if (length) {\n\t if (options.suggest && isActive && that._inputValue()) {\n\t that.suggest(data[0]);\n\t }\n\t }\n\n\t if (that._open) {\n\t that._open = false;\n\t action = that._allowOpening() ? \"open\" : \"close\";\n\n\t if (that._typingTimeout && !isActive) {\n\t action = \"close\";\n\t }\n\n\t if (length) {\n\t that._resetFocusItem();\n\n\t if (options.virtual) {\n\t that.popup\n\t .unbind(\"activate\", that._resetFocusItemHandler)\n\t .one(\"activate\", that._resetFocusItemHandler);\n\t }\n\t }\n\n\t popup[action]();\n\t that._typingTimeout = undefined;\n\t }\n\n\t if (that._touchScroller) {\n\t that._touchScroller.reset();\n\t }\n\n\t that._hideBusy();\n\t that._makeUnselectable();\n\n\t that.trigger(\"dataBound\");\n\t },\n\n\t _mute: function(callback) {\n\t this._muted = true;\n\t callback.call(this);\n\t this._muted = false;\n\t },\n\n\t _listChange: function() {\n\t var isActive = this._active || this.element[0] === activeElement();\n\n\t if (isActive && !this._muted) {\n\t this._selectValue(this.listView.selectedDataItems()[0]);\n\t }\n\t },\n\n\t _selectValue: function(dataItem) {\n\t var separator = this._separator();\n\t var text = \"\";\n\n\t if (dataItem) {\n\t text = this._text(dataItem);\n\t }\n\n\t if (text === null) {\n\t text = \"\";\n\t }\n\n\t if (separator) {\n\t text = replaceWordAtCaret(caret(this.element)[0], this._accessor(), text, separator, this._defaultSeparator());\n\t }\n\n\t this._prev = text;\n\t this._accessor(text);\n\t this._placeholder();\n\t },\n\n\t _unifySeparators: function() {\n\t this._accessor(this.value().split(this._separator()).join(this._defaultSeparator()));\n\t return this;\n\t },\n\n\t _preselect: function(value, text) {\n\t this._inputValue(text);\n\t this._accessor(value);\n\n\t this._old = this.oldText = this._accessor();\n\n\t this.listView.setValue(value);\n\t this._placeholder();\n\t },\n\n\t _change: function() {\n\t var that = this;\n\t var value = that._unifySeparators().value();\n\t var trigger = value !== List.unifyType(that._old, typeof value);\n\n\t var valueUpdated = trigger && !that._typing;\n\t var itemSelected = that._oldText !== value;\n\n\t that._old = value;\n\t that._oldText = value;\n\n\t if (valueUpdated || itemSelected) {\n\t // trigger the DOM change event so any subscriber gets notified\n\t that.element.trigger(CHANGE);\n\t }\n\n\t if (trigger) {\n\t that.trigger(CHANGE);\n\t }\n\n\t that.typing = false;\n\t that._toggleCloseVisibility();\n\t },\n\n\t _accessor: function (value) {\n\t var that = this,\n\t element = that.element[0];\n\n\t if (value !== undefined) {\n\t element.value = value === null ? \"\" : value;\n\t that._placeholder();\n\t } else {\n\t value = element.value;\n\n\t if (element.className.indexOf(\"k-readonly\") > -1) {\n\t if (value === that.options.placeholder) {\n\t return \"\";\n\t } else {\n\t return value;\n\t }\n\t }\n\n\t return value;\n\t }\n\t },\n\n\t _keydown: function (e) {\n\t var that = this;\n\t var key = e.keyCode;\n\t var listView = that.listView;\n\t var visible = that.popup.visible();\n\t var current = listView.focus();\n\n\t that._last = key;\n\n\t if (key === keys.DOWN) {\n\t if (visible) {\n\t this._move(current ? \"focusNext\" : \"focusFirst\");\n\t } else if (that.value()) {\n\t that._filterSource({\n\t value: that.ignoreCase ? that.value().toLowerCase() : that.value(),\n\t operator: that.options.filter,\n\t field: that.options.dataTextField,\n\t ignoreCase: that.ignoreCase\n\t }).done(function () {\n\t if (that._allowOpening()) {\n\t that._resetFocusItem();\n\t that.popup.open();\n\t }\n\t });\n\t }\n\t e.preventDefault();\n\t } else if (key === keys.UP) {\n\t if (visible) {\n\t this._move(current ? \"focusPrev\" : \"focusLast\");\n\t }\n\t e.preventDefault();\n\t } else if (key === keys.HOME) {\n\t this._move(\"focusFirst\");\n\t } else if (key === keys.END) {\n\t this._move(\"focusLast\");\n\t } else if (key === keys.ENTER || key === keys.TAB) {\n\n\t if (key === keys.ENTER && visible) {\n\t e.preventDefault();\n\t }\n\n\t if (visible && current) {\n\t var dataItem = listView.dataItemByIndex(listView.getElementIndex(current));\n\t if (that.trigger(\"select\", { dataItem: dataItem, item: current })) {\n\t return;\n\t }\n\n\t this._select(current);\n\t }\n\n\t this._blur();\n\t } else if (key === keys.ESC) {\n\t if (visible) {\n\t e.preventDefault();\n\t } else {\n\t that._clearValue();\n\t }\n\t that.close();\n\t } else if (that.popup.visible() && (key === keys.PAGEDOWN || key === keys.PAGEUP)) {\n\t e.preventDefault();\n\n\t var direction = key === keys.PAGEDOWN ? 1 : -1;\n\t listView.scrollWith(direction * listView.screenHeight());\n\t } else {\n\t // In some cases when the popup is opened resize is triggered which will cause it to close\n\t // Setting the below flag will prevent this from happening\n\t that.popup._hovered = true;\n\t that._search();\n\t }\n\t },\n\n\t _keypress: function() {\n\t this._oldText = this.element.val();\n\t this._typing = true;\n\t },\n\n\t _move: function (action) {\n\t this.listView[action]();\n\n\t if (this.options.suggest) {\n\t this.suggest(this.listView.focus());\n\t }\n\t },\n\n\t _hideBusy: function () {\n\t var that = this;\n\t clearTimeout(that._busy);\n\t that._loading.hide();\n\t that.element.attr(\"aria-busy\", false);\n\t that._busy = null;\n\t that._showClear();\n\t },\n\n\t _showBusy: function () {\n\t var that = this;\n\n\t if (that._busy) {\n\t return;\n\t }\n\n\t that._busy = setTimeout(function () {\n\t that.element.attr(\"aria-busy\", true);\n\t that._loading.show();\n\t that._hideClear();\n\t }, 100);\n\t },\n\n\t _placeholder: function(show) {\n\t if (placeholderSupported) {\n\t return;\n\t }\n\n\t var that = this,\n\t element = that.element,\n\t placeholder = that.options.placeholder,\n\t value;\n\n\t if (placeholder) {\n\t value = element.val();\n\n\t if (show === undefined) {\n\t show = !value;\n\t }\n\n\t if (!show) {\n\t if (value !== placeholder) {\n\t placeholder = value;\n\t } else {\n\t placeholder = \"\";\n\t }\n\t }\n\n\t if (value === that._old && !show) {\n\t return;\n\t }\n\n\t element.toggleClass(\"k-readonly\", show)\n\t .val(placeholder);\n\n\t if (!placeholder && element[0] === document.activeElement) {\n\t caret(element[0], 0, 0);\n\t }\n\t }\n\t },\n\n\t _separator: function() {\n\t var separator = this.options.separator;\n\t if (separator instanceof Array) {\n\t return new RegExp(separator.join(\"|\"), 'gi');\n\t }\n\t return separator;\n\t },\n\n\t _defaultSeparator: function() {\n\t var separator = this.options.separator;\n\t if (separator instanceof Array) {\n\t return separator[0];\n\t }\n\t return separator;\n\t },\n\n\t _inputValue: function() {\n\t return this.element.val();\n\t },\n\n\t _search: function () {\n\t var that = this;\n\t clearTimeout(that._typingTimeout);\n\n\t that._typingTimeout = setTimeout(function () {\n\t if (that._prev !== that._accessor()) {\n\t that._prev = that._accessor();\n\t that.search();\n\t }\n\t }, that.options.delay);\n\t },\n\n\t _select: function(candidate) {\n\t var that = this;\n\t that._active = true;\n\n\t return that.listView.select(candidate).done(function() {\n\t that._active = false;\n\t });\n\t },\n\n\t _loader: function() {\n\t this._loading = $('').insertAfter(this.element);\n\t },\n\n\t _clearButton: function() {\n\t List.fn._clearButton.call(this);\n\n\t if (this.options.clearButton) {\n\t this._clear.insertAfter(this.element);\n\t this.wrapper.addClass(\"k-autocomplete-clearable\");\n\t }\n\t },\n\n\t _toggleHover: function(e) {\n\t $(e.currentTarget).toggleClass(HOVER, e.type === \"mouseenter\");\n\t },\n\n\t _toggleCloseVisibility: function() {\n\t if (this.value()) {\n\t this._showClear();\n\t } else {\n\t this._hideClear();\n\t }\n\t },\n\n\t _wrapper: function () {\n\t var that = this,\n\t element = that.element,\n\t DOMelement = element[0],\n\t wrapper;\n\n\t wrapper = element.parent();\n\n\t if (!wrapper.is(\"span.k-widget\")) {\n\t wrapper = element.wrap(\"\").parent();\n\t }\n\n\t wrapper.attr(\"tabindex\", -1);\n\t wrapper.attr(\"role\", \"presentation\");\n\n\t wrapper[0].style.cssText = DOMelement.style.cssText;\n\t element.css({\n\t width: \"\",\n\t height: DOMelement.style.height\n\t });\n\n\t that._focused = that.element;\n\t that.wrapper = wrapper\n\t .addClass(\"k-widget k-autocomplete\")\n\t .addClass(DOMelement.className)\n\t .removeClass('input-validation-error');\n\n\t that._inputWrapper = $(wrapper[0]);\n\t },\n\n\t _clearValue: function() {\n\t List.fn._clearValue.call(this);\n\t this.element.focus();\n\t }\n\t });\n\n\t ui.plugin(AutoComplete);\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1036:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.list\");\n\n/***/ }),\n\n/***/ 1037:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.mobile.scroller\");\n\n/***/ }),\n\n/***/ 1038:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.virtuallist\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1040);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1027:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data\");\n\n/***/ }),\n\n/***/ 1040:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018), __webpack_require__(1027) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"binder\",\n\t name: \"MVVM\",\n\t category: \"framework\",\n\t description: \"Model View ViewModel (MVVM) is a design pattern which helps developers separate the Model (the data) from the View (the UI).\",\n\t depends: [ \"core\", \"data\" ]\n\t};\n\n\t/*jshint eqnull: true */\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t Observable = kendo.Observable,\n\t ObservableObject = kendo.data.ObservableObject,\n\t ObservableArray = kendo.data.ObservableArray,\n\t toString = {}.toString,\n\t binders = {},\n\t Class = kendo.Class,\n\t proxy = $.proxy,\n\t VALUE = \"value\",\n\t SOURCE = \"source\",\n\t EVENTS = \"events\",\n\t CHECKED = \"checked\",\n\t CSS = \"css\",\n\t deleteExpando = true,\n\t FUNCTION = \"function\",\n\t CHANGE = \"change\";\n\n\t (function() {\n\t var a = document.createElement(\"a\");\n\n\t try {\n\t delete a.test;\n\t } catch(e) {\n\t deleteExpando = false;\n\t }\n\t })();\n\n\t var Binding = Observable.extend( {\n\t init: function(parents, path) {\n\t var that = this;\n\n\t Observable.fn.init.call(that);\n\n\t that.source = parents[0];\n\t that.parents = parents;\n\t that.path = path;\n\t that.dependencies = {};\n\t that.dependencies[path] = true;\n\t that.observable = that.source instanceof Observable;\n\n\t that._access = function(e) {\n\t that.dependencies[e.field] = true;\n\t };\n\n\t if (that.observable) {\n\t that._change = function(e) {\n\t that.change(e);\n\t };\n\n\t that.source.bind(CHANGE, that._change);\n\t }\n\t },\n\n\t _parents: function() {\n\t var parents = this.parents;\n\t var value = this.get();\n\n\t if (value && typeof value.parent == \"function\") {\n\t var parent = value.parent();\n\n\t if ($.inArray(parent, parents) < 0) {\n\t parents = [parent].concat(parents);\n\t }\n\t }\n\n\t return parents;\n\t },\n\n\t change: function(e) {\n\t var dependency,\n\t ch,\n\t field = e.field,\n\t that = this;\n\n\t if (that.path === \"this\") {\n\t that.trigger(CHANGE, e);\n\t } else {\n\t for (dependency in that.dependencies) {\n\t if (dependency.indexOf(field) === 0) {\n\t ch = dependency.charAt(field.length);\n\n\t if (!ch || ch === \".\" || ch === \"[\") {\n\t that.trigger(CHANGE, e);\n\t break;\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t start: function(source) {\n\t source.bind(\"get\", this._access);\n\t },\n\n\t stop: function(source) {\n\t source.unbind(\"get\", this._access);\n\t },\n\n\t get: function() {\n\n\t var that = this,\n\t source = that.source,\n\t index = 0,\n\t path = that.path,\n\t result = source;\n\n\t if (!that.observable) {\n\t return result;\n\t }\n\n\t that.start(that.source);\n\n\t result = source.get(path);\n\n\t // Traverse the observable hierarchy if the binding is not resolved at the current level.\n\t while (result === undefined && source) {\n\n\t source = that.parents[++index];\n\n\t if (source instanceof ObservableObject) {\n\t result = source.get(path);\n\t }\n\t }\n\n\t // second pass try to get the parent from the object hierarchy\n\t if (result === undefined) {\n\t source = that.source; //get the initial source\n\n\t while (result === undefined && source) {\n\t source = source.parent();\n\n\t if (source instanceof ObservableObject) {\n\t result = source.get(path);\n\t }\n\t }\n\t }\n\n\t // If the result is a function - invoke it\n\t if (typeof result === \"function\") {\n\t index = path.lastIndexOf(\".\");\n\n\t // If the function is a member of a nested observable object make that nested observable the context (this) of the function\n\t if (index > 0) {\n\t source = source.get(path.substring(0, index));\n\t }\n\n\t // Invoke the function\n\t that.start(source);\n\n\t if (source !== that.source) {\n\t result = result.call(source, that.source);\n\t } else {\n\t result = result.call(source);\n\t }\n\n\t that.stop(source);\n\t }\n\n\t // If the binding is resolved by a parent object\n\t if (source && source !== that.source) {\n\n\t that.currentSource = source; // save parent object\n\n\t // Listen for changes in the parent object\n\t source.unbind(CHANGE, that._change)\n\t .bind(CHANGE, that._change);\n\t }\n\n\t that.stop(that.source);\n\n\t return result;\n\t },\n\n\t set: function(value) {\n\t var source = this.currentSource || this.source;\n\n\t var field = kendo.getter(this.path)(source);\n\n\t if (typeof field === \"function\") {\n\t if (source !== this.source) {\n\t field.call(source, this.source, value);\n\t } else {\n\t field.call(source, value);\n\t }\n\t } else {\n\t source.set(this.path, value);\n\t }\n\t },\n\n\t destroy: function() {\n\t if (this.observable) {\n\t this.source.unbind(CHANGE, this._change);\n\t if(this.currentSource) {\n\t this.currentSource.unbind(CHANGE, this._change);\n\t }\n\t }\n\n\t this.unbind();\n\t }\n\t });\n\n\t var EventBinding = Binding.extend( {\n\t get: function() {\n\t var source = this.source,\n\t path = this.path,\n\t index = 0,\n\t handler;\n\n\t handler = source.get(path);\n\n\t while (!handler && source) {\n\t source = this.parents[++index];\n\n\t if (source instanceof ObservableObject) {\n\t handler = source.get(path);\n\t }\n\t }\n\n\t return proxy(handler, source);\n\t }\n\t });\n\n\t var TemplateBinding = Binding.extend( {\n\t init: function(source, path, template) {\n\t var that = this;\n\n\t Binding.fn.init.call(that, source, path);\n\n\t that.template = template;\n\t },\n\n\t render: function(value) {\n\t var html;\n\n\t this.start(this.source);\n\n\t html = kendo.render(this.template, value);\n\n\t this.stop(this.source);\n\n\t return html;\n\t }\n\t });\n\n\t var Binder = Class.extend({\n\t init: function(element, bindings, options) {\n\t this.element = element;\n\t this.bindings = bindings;\n\t this.options = options;\n\t },\n\n\t bind: function(binding, attribute) {\n\t var that = this;\n\n\t binding = attribute ? binding[attribute] : binding;\n\n\t binding.bind(CHANGE, function(e) {\n\t that.refresh(attribute || e);\n\t });\n\n\t that.refresh(attribute);\n\t },\n\n\t destroy: function() {\n\t }\n\t });\n\n\t var TypedBinder = Binder.extend({\n\t dataType: function() {\n\t var dataType = this.element.getAttribute(\"data-type\") || this.element.type || \"text\";\n\t return dataType.toLowerCase();\n\t },\n\n\t parsedValue: function() {\n\t return this._parseValue(this.element.value, this.dataType());\n\t },\n\n\t _parseValue: function (value, dataType){\n\t if (dataType == \"date\") {\n\t value = kendo.parseDate(value, \"yyyy-MM-dd\");\n\t } else if (dataType == \"datetime-local\") {\n\t value = kendo.parseDate(value, [\"yyyy-MM-ddTHH:mm:ss\", \"yyyy-MM-ddTHH:mm\"] );\n\t } else if (dataType == \"number\") {\n\t value = kendo.parseFloat(value);\n\t } else if (dataType == \"boolean\"){\n\t value = value.toLowerCase();\n\t if(kendo.parseFloat(value) !== null){\n\t value = Boolean(kendo.parseFloat(value));\n\t }else{\n\t value = (value.toLowerCase() === \"true\");\n\t }\n\t }\n\t return value;\n\t }\n\t });\n\n\t binders.attr = Binder.extend({\n\t refresh: function(key) {\n\t this.element.setAttribute(key, this.bindings.attr[key].get());\n\t }\n\t });\n\n\t binders.css = Binder.extend({\n\t init: function(element, bindings, options) {\n\t Binder.fn.init.call(this, element, bindings, options);\n\t this.classes = {};\n\t },\n\t refresh: function(className) {\n\t var element = $(this.element),\n\t binding = this.bindings.css[className],\n\t hasClass = this.classes[className] = binding.get();\n\t if(hasClass){\n\t element.addClass(className);\n\t }else{\n\t element.removeClass(className);\n\t }\n\t }\n\t });\n\n\t binders.style = Binder.extend({\n\t refresh: function(key) {\n\t this.element.style[key] = this.bindings.style[key].get() || \"\";\n\t }\n\t });\n\n\t binders.enabled = Binder.extend({\n\t refresh: function() {\n\t if (this.bindings.enabled.get()) {\n\t this.element.removeAttribute(\"disabled\");\n\t } else {\n\t this.element.setAttribute(\"disabled\", \"disabled\");\n\t }\n\t }\n\t });\n\n\t binders.readonly = Binder.extend({\n\t refresh: function() {\n\t if (this.bindings.readonly.get()) {\n\t this.element.setAttribute(\"readonly\", \"readonly\");\n\t } else {\n\t this.element.removeAttribute(\"readonly\");\n\t }\n\t }\n\t });\n\n\t binders.disabled = Binder.extend({\n\t refresh: function() {\n\t if (this.bindings.disabled.get()) {\n\t this.element.setAttribute(\"disabled\", \"disabled\");\n\t } else {\n\t this.element.removeAttribute(\"disabled\");\n\t }\n\t }\n\t });\n\n\t binders.events = Binder.extend({\n\t init: function(element, bindings, options) {\n\t Binder.fn.init.call(this, element, bindings, options);\n\t this.handlers = {};\n\t },\n\n\t refresh: function(key) {\n\t var element = $(this.element),\n\t binding = this.bindings.events[key],\n\t handler = this.handlers[key];\n\n\t if (handler) {\n\t element.off(key, handler);\n\t }\n\n\t handler = this.handlers[key] = binding.get();\n\n\t element.on(key, binding.source, handler);\n\t },\n\n\t destroy: function() {\n\t var element = $(this.element),\n\t handler;\n\n\t for (handler in this.handlers) {\n\t element.off(handler, this.handlers[handler]);\n\t }\n\t }\n\t });\n\n\t binders.text = Binder.extend({\n\t refresh: function() {\n\t var text = this.bindings.text.get();\n\t var dataFormat = this.element.getAttribute(\"data-format\") || \"\";\n\t if (text == null) {\n\t text = \"\";\n\t }\n\n\t $(this.element).text(kendo.toString(text, dataFormat));\n\t }\n\t });\n\n\t binders.visible = Binder.extend({\n\t refresh: function() {\n\t if (this.bindings.visible.get()) {\n\t this.element.style.display = \"\";\n\t } else {\n\t this.element.style.display = \"none\";\n\t }\n\t }\n\t });\n\n\t binders.invisible = Binder.extend({\n\t refresh: function() {\n\t if (!this.bindings.invisible.get()) {\n\t this.element.style.display = \"\";\n\t } else {\n\t this.element.style.display = \"none\";\n\t }\n\t }\n\t });\n\n\t binders.html = Binder.extend({\n\t refresh: function() {\n\t this.element.innerHTML = this.bindings.html.get();\n\t }\n\t });\n\n\t binders.value = TypedBinder.extend({\n\t init: function(element, bindings, options) {\n\t TypedBinder.fn.init.call(this, element, bindings, options);\n\n\t this._change = proxy(this.change, this);\n\t this.eventName = options.valueUpdate || CHANGE;\n\n\t $(this.element).on(this.eventName, this._change);\n\n\t this._initChange = false;\n\t },\n\n\t change: function() {\n\t this._initChange = this.eventName != CHANGE;\n\n\t this.bindings[VALUE].set(this.parsedValue());\n\n\t this._initChange = false;\n\t },\n\n\t refresh: function() {\n\t if (!this._initChange) {\n\t var value = this.bindings[VALUE].get();\n\n\t if (value == null) {\n\t value = \"\";\n\t }\n\n\t var type = this.dataType();\n\n\t if (type == \"date\") {\n\t value = kendo.toString(value, \"yyyy-MM-dd\");\n\t } else if (type == \"datetime-local\") {\n\t value = kendo.toString(value, \"yyyy-MM-ddTHH:mm:ss\");\n\t }\n\n\t this.element.value = value;\n\t }\n\n\t this._initChange = false;\n\t },\n\n\t destroy: function() {\n\t $(this.element).off(this.eventName, this._change);\n\t }\n\t });\n\n\t binders.source = Binder.extend({\n\t init: function(element, bindings, options) {\n\t Binder.fn.init.call(this, element, bindings, options);\n\n\t var source = this.bindings.source.get();\n\n\t if (source instanceof kendo.data.DataSource && options.autoBind !== false) {\n\t source.fetch();\n\t }\n\t },\n\n\t refresh: function(e) {\n\t var that = this,\n\t source = that.bindings.source.get();\n\n\t if (source instanceof ObservableArray || source instanceof kendo.data.DataSource) {\n\t e = e || {};\n\n\t if (e.action == \"add\") {\n\t that.add(e.index, e.items);\n\t } else if (e.action == \"remove\") {\n\t that.remove(e.index, e.items);\n\t } else if (e.action != \"itemchange\") {\n\t that.render();\n\t }\n\t } else {\n\t that.render();\n\t }\n\t },\n\n\t container: function() {\n\t var element = this.element;\n\n\t if (element.nodeName.toLowerCase() == \"table\") {\n\t if (!element.tBodies[0]) {\n\t element.appendChild(document.createElement(\"tbody\"));\n\t }\n\t element = element.tBodies[0];\n\t }\n\n\t return element;\n\t },\n\n\t template: function() {\n\t var options = this.options,\n\t template = options.template,\n\t nodeName = this.container().nodeName.toLowerCase();\n\n\t if (!template) {\n\t if (nodeName == \"select\") {\n\t if (options.valueField || options.textField) {\n\t template = kendo.format('',\n\t options.valueField || options.textField, options.textField || options.valueField);\n\t } else {\n\t template = \"\";\n\t }\n\t } else if (nodeName == \"tbody\") {\n\t template = \"
  • \";\n\t } else if (nodeName == \"ul\" || nodeName == \"ol\") {\n\t template = \"
  • #:data#
  • \";\n\t } else {\n\t template = \"#:data#\";\n\t }\n\t template = kendo.template(template);\n\t }\n\n\t return template;\n\t },\n\n\t add: function(index, items) {\n\t var element = this.container(),\n\t parents,\n\t idx,\n\t length,\n\t child,\n\t clone = element.cloneNode(false),\n\t reference = element.children[index];\n\n\t $(clone).html(kendo.render(this.template(), items));\n\n\t if (clone.children.length) {\n\t parents = this.bindings.source._parents();\n\n\t for (idx = 0, length = items.length; idx < length; idx++) {\n\t child = clone.children[0];\n\t element.insertBefore(child, reference || null);\n\t bindElement(child, items[idx], this.options.roles, [items[idx]].concat(parents));\n\t }\n\t }\n\t },\n\n\t remove: function(index, items) {\n\t var idx, element = this.container();\n\n\t for (idx = 0; idx < items.length; idx++) {\n\t var child = element.children[index];\n\t unbindElementTree(child, true);\n\t if (child.parentNode == element) {\n\t element.removeChild(child);\n\t }\n\t }\n\t },\n\n\t render: function() {\n\t var source = this.bindings.source.get(),\n\t parents,\n\t idx,\n\t length,\n\t element = this.container(),\n\t template = this.template();\n\n\t if (source == null) {\n\t return;\n\t }\n\n\t if (source instanceof kendo.data.DataSource) {\n\t source = source.view();\n\t }\n\n\t if (!(source instanceof ObservableArray) && toString.call(source) !== \"[object Array]\") {\n\t source = [source];\n\t }\n\n\t if (this.bindings.template) {\n\t unbindElementChildren(element, true);\n\n\t $(element).html(this.bindings.template.render(source));\n\n\t if (element.children.length) {\n\t parents = this.bindings.source._parents();\n\n\t for (idx = 0, length = source.length; idx < length; idx++) {\n\t bindElement(element.children[idx], source[idx], this.options.roles, [source[idx]].concat(parents));\n\t }\n\t }\n\t } else {\n\t $(element).html(kendo.render(template, source));\n\t }\n\t }\n\t });\n\n\t binders.input = {\n\t checked: TypedBinder.extend({\n\t init: function(element, bindings, options) {\n\t TypedBinder.fn.init.call(this, element, bindings, options);\n\t this._change = proxy(this.change, this);\n\n\t $(this.element).change(this._change);\n\t },\n\n\t change: function() {\n\t var element = this.element;\n\t var value = this.value();\n\n\t if (element.type == \"radio\") {\n\t value = this.parsedValue();\n\t this.bindings[CHECKED].set(value);\n\t } else if (element.type == \"checkbox\") {\n\t var source = this.bindings[CHECKED].get();\n\t var index;\n\n\t if (source instanceof ObservableArray) {\n\t value = this.parsedValue();\n\t if (value instanceof Date) {\n\t for(var i = 0; i < source.length; i++){\n\t if(source[i] instanceof Date && +source[i] === +value){\n\t index = i;\n\t break;\n\t }\n\t }\n\t }else{\n\t index = source.indexOf(value);\n\t }\n\t if (index > -1) {\n\t source.splice(index, 1);\n\t } else {\n\t source.push(value);\n\t }\n\t } else {\n\t this.bindings[CHECKED].set(value);\n\t }\n\t }\n\t },\n\n\t refresh: function() {\n\t var value = this.bindings[CHECKED].get(),\n\t source = value,\n\t type = this.dataType(),\n\t element = this.element;\n\n\t if (element.type == \"checkbox\") {\n\t if (source instanceof ObservableArray) {\n\t var index = -1;\n\t value = this.parsedValue();\n\t if(value instanceof Date){\n\t for(var i = 0; i < source.length; i++){\n\t if(source[i] instanceof Date && +source[i] === +value){\n\t index = i;\n\t break;\n\t }\n\t }\n\t }else{\n\t index = source.indexOf(value);\n\t }\n\t element.checked = (index >= 0);\n\t }else{\n\t element.checked = source;\n\t }\n\t } else if (element.type == \"radio\") {\n\t if (type == \"date\") {\n\t value = kendo.toString(value, \"yyyy-MM-dd\");\n\t } else if (type == \"datetime-local\") {\n\t value = kendo.toString(value, \"yyyy-MM-ddTHH:mm:ss\");\n\t }\n\n\t if (value !== null && typeof(value) !== \"undefined\" && element.value === value.toString()) {\n\t element.checked = true;\n\t } else {\n\t element.checked = false;\n\t }\n\t }\n\t },\n\n\t value: function() {\n\t var element = this.element,\n\t value = element.value;\n\n\t if (element.type == \"checkbox\") {\n\t value = element.checked;\n\t }\n\n\t return value;\n\t },\n\t destroy: function() {\n\t $(this.element).off(CHANGE, this._change);\n\t }\n\t })\n\t };\n\n\t binders.select = {\n\t source: binders.source.extend({\n\t refresh: function(e) {\n\t var that = this,\n\t source = that.bindings.source.get();\n\n\t if (source instanceof ObservableArray || source instanceof kendo.data.DataSource) {\n\t e = e || {};\n\t if (e.action == \"add\") {\n\t that.add(e.index, e.items);\n\t } else if (e.action == \"remove\") {\n\t that.remove(e.index, e.items);\n\t } else if (e.action == \"itemchange\" || e.action === undefined) {\n\t that.render();\n\t if(that.bindings.value){\n\t if (that.bindings.value) {\n\t var val = retrievePrimitiveValues(that.bindings.value.get(), $(that.element).data(\"valueField\"));\n\t if(val === null) {\n\t that.element.selectedIndex = -1;\n\t } else {\n\t that.element.value = val;\n\t }\n\t }\n\t }\n\t }\n\t } else {\n\t that.render();\n\t }\n\t }\n\t }),\n\t value: TypedBinder.extend({\n\t init: function(target, bindings, options) {\n\t TypedBinder.fn.init.call(this, target, bindings, options);\n\n\t this._change = proxy(this.change, this);\n\t $(this.element).change(this._change);\n\t },\n\n\t parsedValue : function() {\n\t var dataType = this.dataType();\n\t var values = [];\n\t var value, option, idx, length;\n\t for (idx = 0, length = this.element.options.length; idx < length; idx++) {\n\t option = this.element.options[idx];\n\n\t if (option.selected) {\n\t value = option.attributes.value;\n\n\t if (value && value.specified) {\n\t value = option.value;\n\t } else {\n\t value = option.text;\n\t }\n\n\t values.push(this._parseValue(value, dataType));\n\t }\n\t }\n\t return values;\n\t },\n\n\t change: function() {\n\t var values = [],\n\t element = this.element,\n\t source,\n\t field = this.options.valueField || this.options.textField,\n\t valuePrimitive = this.options.valuePrimitive,\n\t option,\n\t valueIndex,\n\t value,\n\t idx,\n\t length;\n\n\t for (idx = 0, length = element.options.length; idx < length; idx++) {\n\t option = element.options[idx];\n\n\t if (option.selected) {\n\t value = option.attributes.value;\n\n\t if (value && value.specified) {\n\t value = option.value;\n\t } else {\n\t value = option.text;\n\t }\n\n\t if (field) {\n\t values.push(value);\n\t } else {\n\t values.push(this._parseValue(value, this.dataType()));\n\t }\n\n\t }\n\t }\n\n\t if (field) {\n\t source = this.bindings.source.get();\n\t if (source instanceof kendo.data.DataSource) {\n\t source = source.view();\n\t }\n\n\t for (valueIndex = 0; valueIndex < values.length; valueIndex++) {\n\t for (idx = 0, length = source.length; idx < length; idx++) {\n\t var sourceValue = source[idx].get(field);\n\t var match = (String(sourceValue) === values[valueIndex]);\n\t if (match) {\n\t values[valueIndex] = source[idx];\n\t break;\n\t }\n\t }\n\t }\n\t }\n\n\t value = this.bindings[VALUE].get();\n\t if (value instanceof ObservableArray) {\n\t value.splice.apply(value, [0, value.length].concat(values));\n\t } else if (!valuePrimitive && (value instanceof ObservableObject || value === null || value === undefined || !field)) {\n\t this.bindings[VALUE].set(values[0]);\n\t } else {\n\t this.bindings[VALUE].set(values[0].get(field));\n\t }\n\t },\n\t refresh: function() {\n\t var optionIndex,\n\t element = this.element,\n\t options = element.options,\n\t value = this.bindings[VALUE].get(),\n\t values = value,\n\t field = this.options.valueField || this.options.textField,\n\t found = false,\n\t type = this.dataType(),\n\t optionValue;\n\n\t if (!(values instanceof ObservableArray)) {\n\t values = new ObservableArray([value]);\n\t }\n\n\t element.selectedIndex = -1;\n\n\t for (var valueIndex = 0; valueIndex < values.length; valueIndex++) {\n\t value = values[valueIndex];\n\n\n\t if (field && value instanceof ObservableObject) {\n\t value = value.get(field);\n\t }\n\n\t if (type == \"date\") {\n\t value = kendo.toString(values[valueIndex], \"yyyy-MM-dd\");\n\t } else if (type == \"datetime-local\") {\n\t value = kendo.toString(values[valueIndex], \"yyyy-MM-ddTHH:mm:ss\");\n\t }\n\n\t for (optionIndex = 0; optionIndex < options.length; optionIndex++) {\n\t optionValue = options[optionIndex].value;\n\n\t if (optionValue === \"\" && value !== \"\") {\n\t optionValue = options[optionIndex].text;\n\t }\n\n\t if (value != null && optionValue == value.toString()) {\n\t options[optionIndex].selected = true;\n\t found = true;\n\t }\n\t }\n\t }\n\t },\n\t destroy: function() {\n\t $(this.element).off(CHANGE, this._change);\n\t }\n\t })\n\t };\n\n\t function dataSourceBinding(bindingName, fieldName, setter) {\n\t return Binder.extend({\n\t init: function(widget, bindings, options) {\n\t var that = this;\n\n\t Binder.fn.init.call(that, widget.element[0], bindings, options);\n\n\t that.widget = widget;\n\t that._dataBinding = proxy(that.dataBinding, that);\n\t that._dataBound = proxy(that.dataBound, that);\n\t that._itemChange = proxy(that.itemChange, that);\n\t },\n\n\t itemChange: function(e) {\n\t bindElement(e.item[0], e.data, this._ns(e.ns), [e.data].concat(this.bindings[bindingName]._parents()));\n\t },\n\n\t dataBinding: function(e) {\n\t var idx,\n\t length,\n\t widget = this.widget,\n\t items = e.removedItems || widget.items();\n\n\t for (idx = 0, length = items.length; idx < length; idx++) {\n\t unbindElementTree(items[idx], false);\n\t }\n\t },\n\n\t _ns: function(ns) {\n\t ns = ns || kendo.ui;\n\t var all = [ kendo.ui, kendo.dataviz.ui, kendo.mobile.ui ];\n\t all.splice($.inArray(ns, all), 1);\n\t all.unshift(ns);\n\n\t return kendo.rolesFromNamespaces(all);\n\t },\n\n\t dataBound: function(e) {\n\t var idx,\n\t length,\n\t widget = this.widget,\n\t items = e.addedItems || widget.items(),\n\t dataSource = widget[fieldName],\n\t view,\n\t parents,\n\t hds = kendo.data.HierarchicalDataSource;\n\n\t if (hds && dataSource instanceof hds) {\n\t // suppress binding of HDS items, because calling view() on root\n\t // will return only root items, and widget.items() returns all items\n\t return;\n\t }\n\n\t if (items.length) {\n\t view = e.addedDataItems || dataSource.flatView();\n\t parents = this.bindings[bindingName]._parents();\n\n\t for (idx = 0, length = view.length; idx < length; idx++) {\n\t if (items[idx]) {\n\t bindElement(items[idx], view[idx], this._ns(e.ns), [view[idx]].concat(parents));\n\t }\n\t }\n\t }\n\t },\n\n\t refresh: function(e) {\n\t var that = this,\n\t source,\n\t widget = that.widget,\n\t select, multiselect, dropdowntree;\n\n\t e = e || {};\n\n\t if (!e.action) {\n\t that.destroy();\n\n\t widget.bind(\"dataBinding\", that._dataBinding);\n\t widget.bind(\"dataBound\", that._dataBound);\n\t widget.bind(\"itemChange\", that._itemChange);\n\n\t source = that.bindings[bindingName].get();\n\n\t if (widget[fieldName] instanceof kendo.data.DataSource && widget[fieldName] != source) {\n\t if (source instanceof kendo.data.DataSource) {\n\t widget[setter](source);\n\t } else if (source && source._dataSource) {\n\t widget[setter](source._dataSource);\n\t } else {\n\t select = kendo.ui.Select && widget instanceof kendo.ui.Select;\n\t multiselect = kendo.ui.MultiSelect && widget instanceof kendo.ui.MultiSelect;\n\t dropdowntree = kendo.ui.DropDownTree && widget instanceof kendo.ui.DropDownTree;\n\n\t if(!dropdowntree){\n\t widget[fieldName].data(source);\n\t }else{\n\t widget.treeview[fieldName].data(source);\n\t }\n\n\t if (that.bindings.value && (select || multiselect)) {\n\t widget.value(retrievePrimitiveValues(that.bindings.value.get(), widget.options.dataValueField));\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t destroy: function() {\n\t var widget = this.widget;\n\n\t widget.unbind(\"dataBinding\", this._dataBinding);\n\t widget.unbind(\"dataBound\", this._dataBound);\n\t widget.unbind(\"itemChange\", this._itemChange);\n\t }\n\t });\n\t }\n\n\t binders.widget = {\n\t events : Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\t this.widget = widget;\n\t this.handlers = {};\n\t },\n\n\t refresh: function(key) {\n\t var binding = this.bindings.events[key],\n\t handler = this.handlers[key];\n\n\t if (handler) {\n\t this.widget.unbind(key, handler);\n\t }\n\n\t handler = binding.get();\n\n\t this.handlers[key] = function(e) {\n\t e.data = binding.source;\n\n\t handler(e);\n\n\t if (e.data === binding.source) {\n\t delete e.data;\n\t }\n\t };\n\n\t this.widget.bind(key, this.handlers[key]);\n\t },\n\n\t destroy: function() {\n\t var handler;\n\n\t for (handler in this.handlers) {\n\t this.widget.unbind(handler, this.handlers[handler]);\n\t }\n\t }\n\t }),\n\n\t checked: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\n\t this.widget = widget;\n\t this._change = proxy(this.change, this);\n\t this.widget.bind(CHANGE, this._change);\n\t },\n\t change: function() {\n\t this.bindings[CHECKED].set(this.value());\n\t },\n\n\t refresh: function() {\n\t this.widget.check(this.bindings[CHECKED].get() === true);\n\t },\n\n\t value: function() {\n\t var element = this.element,\n\t value = element.value;\n\n\t if (value == \"on\" || value == \"off\" || this.element.type == \"checkbox\") {\n\t value = element.checked;\n\t }\n\n\t return value;\n\t },\n\n\t destroy: function() {\n\t this.widget.unbind(CHANGE, this._change);\n\t }\n\t }),\n\n\t start: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\t this._change = proxy(this.change, this);\n\t this.widget = widget;\n\t this.widget.bind(CHANGE, this._change);\n\t },\n\n\t change: function() {\n\t this.bindings.start.set(this.widget.range().start);\n\t },\n\n\t refresh: function() {\n\t var that = this;\n\t var start = this.bindings.start.get();\n\t var end = that.widget._range ? that.widget._range.end: null;\n\t this.widget.range({start: start, end: end});\n\t },\n\n\t destroy: function() {\n\t this.widget.unbind(CHANGE, this._change);\n\t }\n\t }),\n\n\t end: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\t this._change = proxy(this.change, this);\n\t this.widget = widget;\n\t this.widget.bind(CHANGE, this._change);\n\t },\n\n\t change: function() {\n\t this.bindings.end.set(this.widget.range().end);\n\t },\n\n\t refresh: function() {\n\t var that = this;\n\t var end = this.bindings.end.get();\n\t var start = that.widget._range ? that.widget._range.start: null;\n\t this.widget.range({start: start, end: end});\n\t },\n\n\t destroy: function() {\n\t this.widget.unbind(CHANGE, this._change);\n\t }\n\t }),\n\n\t visible: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\n\t this.widget = widget;\n\t },\n\n\t refresh: function() {\n\t var visible = this.bindings.visible.get();\n\t this.widget.wrapper[0].style.display = visible ? \"\" : \"none\";\n\t }\n\t }),\n\n\t invisible: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\n\t this.widget = widget;\n\t },\n\n\t refresh: function() {\n\t var invisible = this.bindings.invisible.get();\n\t this.widget.wrapper[0].style.display = invisible ? \"none\" : \"\";\n\t }\n\t }),\n\n\t enabled: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\n\t this.widget = widget;\n\t },\n\n\t refresh: function() {\n\t if (this.widget.enable) {\n\t this.widget.enable(this.bindings.enabled.get());\n\t }\n\t }\n\t }),\n\n\t disabled: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\n\t this.widget = widget;\n\t },\n\n\t refresh: function() {\n\t if (this.widget.enable) {\n\t this.widget.enable(!this.bindings.disabled.get());\n\t }\n\t }\n\t }),\n\n\t source: dataSourceBinding(\"source\", \"dataSource\", \"setDataSource\"),\n\n\t value: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\n\t this.widget = widget;\n\t this._change = $.proxy(this.change, this);\n\t this.widget.first(CHANGE, this._change);\n\n\t var value = this.bindings.value.get();\n\n\t this._valueIsObservableObject = !options.valuePrimitive && (value == null || value instanceof ObservableObject);\n\t this._valueIsObservableArray = value instanceof ObservableArray;\n\t this._initChange = false;\n\t },\n\n\t _source: function() {\n\t var source;\n\n\t if (this.widget.dataItem) {\n\t source = this.widget.dataItem();\n\t if (source && source instanceof ObservableObject) {\n\t return [source];\n\t }\n\t }\n\n\t if (this.bindings.source) {\n\t source = this.bindings.source.get();\n\t }\n\n\t if (!source || source instanceof kendo.data.DataSource) {\n\t source = this.widget.dataSource.flatView();\n\t }\n\n\t return source;\n\t },\n\n\t change: function() {\n\t var value = this.widget.value(),\n\t field = this.options.dataValueField || this.options.dataTextField,\n\t isArray = toString.call(value) === \"[object Array]\",\n\t isObservableObject = this._valueIsObservableObject,\n\t valueIndex, valueLength, values = [],\n\t sourceItem, sourceValue,\n\t idx, length, source;\n\n\t this._initChange = true;\n\n\t if (field) {\n\n\t if (value === \"\" && (isObservableObject || this.options.valuePrimitive)) {\n\t value = null;\n\t } else {\n\t source = this._source();\n\n\t if (isArray) {\n\t valueLength = value.length;\n\t values = value.slice(0);\n\t }\n\n\t for (idx = 0, length = source.length; idx < length; idx++) {\n\t sourceItem = source[idx];\n\t sourceValue = sourceItem.get(field);\n\n\t if (isArray) {\n\t for (valueIndex = 0; valueIndex < valueLength; valueIndex++) {\n\t if (sourceValue == values[valueIndex]) {\n\t values[valueIndex] = sourceItem;\n\t break;\n\t }\n\t }\n\t } else if (sourceValue == value) {\n\t value = isObservableObject ? sourceItem : sourceValue;\n\t break;\n\t }\n\t }\n\n\t if (values[0]) {\n\t if (this._valueIsObservableArray) {\n\t value = values;\n\t } else if (isObservableObject || !field) {\n\t value = values[0];\n\t } else {\n\t value = values[0].get(field);\n\t }\n\t }\n\t }\n\t }\n\n\t this.bindings.value.set(value);\n\t this._initChange = false;\n\t },\n\n\t refresh: function() {\n\t if (!this._initChange) {\n\t var widget = this.widget;\n\t var options = widget.options;\n\t var textField = options.dataTextField;\n\t var valueField = options.dataValueField || textField;\n\t var value = this.bindings.value.get();\n\t var text = options.text || \"\";\n\t var idx = 0, length;\n\t var values = [];\n\n\t if (value === undefined) {\n\t value = null;\n\t }\n\n\t if (valueField) {\n\t if (value instanceof ObservableArray) {\n\t for (length = value.length; idx < length; idx++) {\n\t values[idx] = value[idx].get(valueField);\n\t }\n\t value = values;\n\t } else if (value instanceof ObservableObject) {\n\t text = value.get(textField);\n\t value = value.get(valueField);\n\t }\n\t }\n\n\t if (options.autoBind === false && !options.cascadeFrom && widget.listView && !widget.listView.bound()) {\n\t if (textField === valueField && !text) {\n\t text = value;\n\t }\n\n\t if (!text && (value || value === 0) && options.valuePrimitive) {\n\t widget.value(value);\n\t } else {\n\t widget._preselect(value, text);\n\t }\n\t } else {\n\t widget.value(value);\n\t }\n\t }\n\n\t this._initChange = false;\n\t },\n\n\t destroy: function() {\n\t this.widget.unbind(CHANGE, this._change);\n\t }\n\t }),\n\t dropdowntree: {\n\t value: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\n\t this.widget = widget;\n\t this._change = $.proxy(this.change, this);\n\t this.widget.first(CHANGE, this._change);\n\t this._initChange = false;\n\t },\n\n\t change: function() {\n\t var that = this,\n\t oldValues = that.bindings[VALUE].get(),\n\t valuePrimitive = that.options.valuePrimitive,\n\t selectedNode = that.widget.treeview.select(),\n\t nonPrimitiveValues = that.widget._isMultipleSelection() ? that.widget._getAllChecked(): (that.widget.treeview.dataItem(selectedNode) || that.widget.value()),\n\t newValues = (valuePrimitive || that.widget.options.autoBind === false) ? that.widget.value() : nonPrimitiveValues;\n\n\t var field = this.options.dataValueField || this.options.dataTextField;\n\n\t newValues = newValues.slice ? newValues.slice(0): newValues;\n\n\t that._initChange = true;\n\n\t if (oldValues instanceof ObservableArray) {\n\t var remove = [];\n\t var newLength = newValues.length;\n\t var i = 0, j = 0;\n\t var old = oldValues[i];\n\t var same = false;\n\t var removeIndex;\n\t var newValue;\n\t var found;\n\n\t while (old !== undefined) {\n\t found = false;\n\t for (j = 0; j < newLength; j++) {\n\t if (valuePrimitive) {\n\t same = newValues[j] == old;\n\t } else {\n\t newValue = newValues[j];\n\n\t newValue = newValue.get ? newValue.get(field) : newValue;\n\t same = newValue == (old.get ? old.get(field) : old);\n\t }\n\n\t if (same) {\n\t newValues.splice(j, 1);\n\t newLength -= 1;\n\t found = true;\n\t break;\n\t }\n\t }\n\n\t if (!found) {\n\t remove.push(old);\n\t arraySplice(oldValues, i, 1);\n\t removeIndex = i;\n\t } else {\n\t i += 1;\n\t }\n\n\t old = oldValues[i];\n\t }\n\n\t arraySplice(oldValues, oldValues.length, 0, newValues);\n\n\t if (remove.length) {\n\t oldValues.trigger(\"change\", {\n\t action: \"remove\",\n\t items: remove,\n\t index: removeIndex\n\t });\n\t }\n\n\t if (newValues.length) {\n\t oldValues.trigger(\"change\", {\n\t action: \"add\",\n\t items: newValues,\n\t index: oldValues.length - 1\n\t });\n\t }\n\t } else {\n\t that.bindings[VALUE].set(newValues);\n\t }\n\n\t that._initChange = false;\n\t },\n\n\t refresh: function() {\n\t if (!this._initChange) {\n\t var options = this.options,\n\t widget = this.widget,\n\t field = options.dataValueField || options.dataTextField,\n\t value = this.bindings.value.get(),\n\t data = value,\n\t idx = 0, length,\n\t values = [],\n\t selectedValue;\n\n\t if (field) {\n\t if (value instanceof ObservableArray) {\n\t for (length = value.length; idx < length; idx++) {\n\t selectedValue = value[idx];\n\t values[idx] = selectedValue.get ? selectedValue.get(field) : selectedValue;\n\t }\n\t value = values;\n\t } else if (value instanceof ObservableObject) {\n\t value = value.get(field);\n\t }\n\t }\n\t if (options.autoBind === false && options.valuePrimitive !== true) {\n\t widget._preselect(data, value);\n\t } else {\n\t widget.value(value);\n\t }\n\t }\n\t },\n\n\t destroy: function() {\n\t this.widget.unbind(CHANGE, this._change);\n\t }\n\t })\n\t },\n\t gantt: {\n\t dependencies: dataSourceBinding(\"dependencies\", \"dependencies\", \"setDependenciesDataSource\")\n\t },\n\n\t multiselect: {\n\t value: Binder.extend({\n\t init: function(widget, bindings, options) {\n\t Binder.fn.init.call(this, widget.element[0], bindings, options);\n\n\t this.widget = widget;\n\t this._change = $.proxy(this.change, this);\n\t this.widget.first(CHANGE, this._change);\n\t this._initChange = false;\n\t },\n\n\t change: function() {\n\t var that = this,\n\t oldValues = that.bindings[VALUE].get(),\n\t valuePrimitive = that.options.valuePrimitive,\n\t newValues = valuePrimitive ? that.widget.value() : that.widget.dataItems();\n\n\t var field = this.options.dataValueField || this.options.dataTextField;\n\n\t newValues = newValues.slice(0);\n\n\t that._initChange = true;\n\n\t if (oldValues instanceof ObservableArray) {\n\t var remove = [];\n\n\t var newLength = newValues.length;\n\n\t var i = 0, j = 0;\n\t var old = oldValues[i];\n\t var same = false;\n\t var removeIndex;\n\t var newValue;\n\t var found;\n\n\t while (old !== undefined) {\n\t found = false;\n\t for (j = 0; j < newLength; j++) {\n\t if (valuePrimitive) {\n\t same = newValues[j] == old;\n\t } else {\n\t newValue = newValues[j];\n\n\t newValue = newValue.get ? newValue.get(field) : newValue;\n\t same = newValue == (old.get ? old.get(field) : old);\n\t }\n\n\t if (same) {\n\t newValues.splice(j, 1);\n\t newLength -= 1;\n\t found = true;\n\t break;\n\t }\n\t }\n\n\t if (!found) {\n\t remove.push(old);\n\t arraySplice(oldValues, i, 1);\n\t removeIndex = i;\n\t } else {\n\t i += 1;\n\t }\n\n\t old = oldValues[i];\n\t }\n\n\t arraySplice(oldValues, oldValues.length, 0, newValues);\n\n\t if (remove.length) {\n\t oldValues.trigger(\"change\", {\n\t action: \"remove\",\n\t items: remove,\n\t index: removeIndex\n\t });\n\t }\n\n\t if (newValues.length) {\n\t oldValues.trigger(\"change\", {\n\t action: \"add\",\n\t items: newValues,\n\t index: oldValues.length - 1\n\t });\n\t }\n\t } else {\n\t that.bindings[VALUE].set(newValues);\n\t }\n\n\t that._initChange = false;\n\t },\n\n\t refresh: function() {\n\t if (!this._initChange) {\n\t var options = this.options,\n\t widget = this.widget,\n\t field = options.dataValueField || options.dataTextField,\n\t value = this.bindings.value.get(),\n\t data = value,\n\t idx = 0, length,\n\t values = [],\n\t selectedValue;\n\n\t if (value === undefined) {\n\t value = null;\n\t }\n\n\t if (field) {\n\t if (value instanceof ObservableArray) {\n\t for (length = value.length; idx < length; idx++) {\n\t selectedValue = value[idx];\n\t values[idx] = selectedValue.get ? selectedValue.get(field) : selectedValue;\n\t }\n\t value = values;\n\t } else if (value instanceof ObservableObject) {\n\t value = value.get(field);\n\t }\n\t }\n\n\t if (options.autoBind === false && options.valuePrimitive !== true && !widget._isBound()) {\n\t widget._preselect(data, value);\n\t } else {\n\t widget.value(value);\n\t }\n\t }\n\t },\n\n\t destroy: function() {\n\t this.widget.unbind(CHANGE, this._change);\n\t }\n\n\t })\n\t },\n\t scheduler: {\n\t source: dataSourceBinding(\"source\", \"dataSource\", \"setDataSource\").extend({\n\t dataBound: function(e) {\n\t var idx;\n\t var length;\n\t var widget = this.widget;\n\t var elements = e.addedItems || widget.items();\n\t var data, parents;\n\n\t if (elements.length) {\n\t data = e.addedDataItems || widget.dataItems();\n\t parents = this.bindings.source._parents();\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t bindElement(elements[idx], data[idx], this._ns(e.ns), [data[idx]].concat(parents));\n\t }\n\t }\n\t }\n\t })\n\t },\n\n\t grid: {\n\t source: dataSourceBinding(\"source\", \"dataSource\", \"setDataSource\").extend({\n\t dataBound: function(e) {\n\t var idx,\n\t length,\n\t widget = this.widget,\n\t elements = e.addedItems || widget.items(),\n\t parents,\n\t data;\n\n\t if (elements.length) {\n\t data = e.addedDataItems || widget.dataItems();\n\t parents = this.bindings.source._parents();\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t bindElement(elements[idx], data[idx], this._ns(e.ns), [data[idx]].concat(parents));\n\t }\n\t }\n\t }\n\t })\n\t }\n\t };\n\n\t var arraySplice = function(arr, idx, remove, add) {\n\t add = add || [];\n\t remove = remove || 0;\n\n\t var addLength = add.length;\n\t var oldLength = arr.length;\n\n\t var shifted = [].slice.call(arr, idx + remove);\n\t var shiftedLength = shifted.length;\n\t var index;\n\n\t if (addLength) {\n\t addLength = idx + addLength;\n\t index = 0;\n\n\t for (; idx < addLength; idx++) {\n\t arr[idx] = add[index];\n\t index++;\n\t }\n\n\t arr.length = addLength;\n\t } else if (remove) {\n\t arr.length = idx;\n\n\t remove += idx;\n\t while (idx < remove) {\n\t delete arr[--remove];\n\t }\n\t }\n\n\t if (shiftedLength) {\n\t shiftedLength = idx + shiftedLength;\n\t index = 0;\n\n\t for (; idx < shiftedLength; idx++) {\n\t arr[idx] = shifted[index];\n\t index++;\n\t }\n\n\t arr.length = shiftedLength;\n\t }\n\n\t idx = arr.length;\n\n\t while (idx < oldLength) {\n\t delete arr[idx];\n\t idx++;\n\t }\n\t };\n\n\t var BindingTarget = Class.extend( {\n\t init: function(target, options) {\n\t this.target = target;\n\t this.options = options;\n\t this.toDestroy = [];\n\t },\n\n\t bind: function(bindings) {\n\t var key,\n\t hasValue,\n\t hasSource,\n\t hasEvents,\n\t hasChecked,\n\t hasCss,\n\t widgetBinding = this instanceof WidgetBindingTarget,\n\t specificBinders = this.binders();\n\n\t for (key in bindings) {\n\t if (key == VALUE) {\n\t hasValue = true;\n\t } else if (key == SOURCE) {\n\t hasSource = true;\n\t } else if (key == EVENTS && !widgetBinding) {\n\t hasEvents = true;\n\t } else if (key == CHECKED) {\n\t hasChecked = true;\n\t } else if (key == CSS) {\n\t hasCss = true;\n\t } else {\n\t this.applyBinding(key, bindings, specificBinders);\n\t }\n\t }\n\t if (hasSource) {\n\t this.applyBinding(SOURCE, bindings, specificBinders);\n\t }\n\n\t if (hasValue) {\n\t this.applyBinding(VALUE, bindings, specificBinders);\n\t }\n\n\t if (hasChecked) {\n\t this.applyBinding(CHECKED, bindings, specificBinders);\n\t }\n\n\t if (hasEvents && !widgetBinding) {\n\t this.applyBinding(EVENTS, bindings, specificBinders);\n\t }\n\n\t if (hasCss && !widgetBinding) {\n\t this.applyBinding(CSS, bindings, specificBinders);\n\t }\n\t },\n\n\t binders: function() {\n\t return binders[this.target.nodeName.toLowerCase()] || {};\n\t },\n\n\t applyBinding: function(name, bindings, specificBinders) {\n\t var binder = specificBinders[name] || binders[name],\n\t toDestroy = this.toDestroy,\n\t attribute,\n\t binding = bindings[name];\n\n\t if (binder) {\n\t binder = new binder(this.target, bindings, this.options);\n\n\t toDestroy.push(binder);\n\n\t if (binding instanceof Binding) {\n\t binder.bind(binding);\n\t toDestroy.push(binding);\n\t } else {\n\t for (attribute in binding) {\n\t binder.bind(binding, attribute);\n\t toDestroy.push(binding[attribute]);\n\t }\n\t }\n\t } else if (name !== \"template\") {\n\t throw new Error(\"The \" + name + \" binding is not supported by the \" + this.target.nodeName.toLowerCase() + \" element\");\n\t }\n\t },\n\n\t destroy: function() {\n\t var idx,\n\t length,\n\t toDestroy = this.toDestroy;\n\n\t for (idx = 0, length = toDestroy.length; idx < length; idx++) {\n\t toDestroy[idx].destroy();\n\t }\n\t }\n\t });\n\n\t var WidgetBindingTarget = BindingTarget.extend( {\n\t binders: function() {\n\t return binders.widget[this.target.options.name.toLowerCase()] || {};\n\t },\n\n\t applyBinding: function(name, bindings, specificBinders) {\n\t var binder = specificBinders[name] || binders.widget[name],\n\t toDestroy = this.toDestroy,\n\t attribute,\n\t binding = bindings[name];\n\n\t if (binder) {\n\t binder = new binder(this.target, bindings, this.target.options);\n\n\t toDestroy.push(binder);\n\n\n\t if (binding instanceof Binding) {\n\t binder.bind(binding);\n\t toDestroy.push(binding);\n\t } else {\n\t for (attribute in binding) {\n\t binder.bind(binding, attribute);\n\t toDestroy.push(binding[attribute]);\n\t }\n\t }\n\t } else {\n\t throw new Error(\"The \" + name + \" binding is not supported by the \" + this.target.options.name + \" widget\");\n\t }\n\t }\n\t });\n\n\t function bindingTargetForRole(element, roles) {\n\t var widget = kendo.initWidget(element, {}, roles);\n\n\t if (widget) {\n\t return new WidgetBindingTarget(widget);\n\t }\n\t }\n\n\t var keyValueRegExp = /[A-Za-z0-9_\\-]+:(\\{([^}]*)\\}|[^,}]+)/g,\n\t whiteSpaceRegExp = /\\s/g;\n\n\t function parseBindings(bind) {\n\t var result = {},\n\t idx,\n\t length,\n\t token,\n\t colonIndex,\n\t key,\n\t value,\n\t tokens;\n\n\t tokens = bind.match(keyValueRegExp);\n\n\t for (idx = 0, length = tokens.length; idx < length; idx++) {\n\t token = tokens[idx];\n\t colonIndex = token.indexOf(\":\");\n\n\t key = token.substring(0, colonIndex);\n\t value = token.substring(colonIndex + 1);\n\n\t if (value.charAt(0) == \"{\") {\n\t value = parseBindings(value);\n\t }\n\n\t result[key] = value;\n\t }\n\n\t return result;\n\t }\n\n\t function createBindings(bindings, source, type) {\n\t var binding,\n\t result = {};\n\n\t for (binding in bindings) {\n\t result[binding] = new type(source, bindings[binding]);\n\t }\n\n\t return result;\n\t }\n\n\t function bindElement(element, source, roles, parents) {\n\n\t if(!element || element.getAttribute(\"data-\" + kendo.ns + \"stop\")){\n\t return;\n\t }\n\n\t var role = element.getAttribute(\"data-\" + kendo.ns + \"role\"),\n\t idx,\n\t bind = element.getAttribute(\"data-\" + kendo.ns + \"bind\"),\n\t childrenCopy = [],\n\t deep = true,\n\t bindings,\n\t options = {},\n\t target;\n\n\t parents = parents || [source];\n\n\t if (role || bind) {\n\t unbindElement(element, false);\n\t }\n\n\t if (role) {\n\t target = bindingTargetForRole(element, roles);\n\t }\n\n\t if (bind) {\n\t bind = parseBindings(bind.replace(whiteSpaceRegExp, \"\"));\n\n\t if (!target) {\n\t options = kendo.parseOptions(element, {textField: \"\", valueField: \"\", template: \"\", valueUpdate: CHANGE, valuePrimitive: false, autoBind: true}, source);\n\t options.roles = roles;\n\t target = new BindingTarget(element, options);\n\t }\n\n\t target.source = source;\n\n\t bindings = createBindings(bind, parents, Binding);\n\n\t if (options.template) {\n\t bindings.template = new TemplateBinding(parents, \"\", options.template);\n\t }\n\n\t if (bindings.click) {\n\t bind.events = bind.events || {};\n\t bind.events.click = bind.click;\n\t bindings.click.destroy();\n\t delete bindings.click;\n\t }\n\n\t if (bindings.source) {\n\t deep = false;\n\t }\n\n\t if (bind.attr) {\n\t bindings.attr = createBindings(bind.attr, parents, Binding);\n\t }\n\n\t if (bind.style) {\n\t bindings.style = createBindings(bind.style, parents, Binding);\n\t }\n\n\t if (bind.events) {\n\t bindings.events = createBindings(bind.events, parents, EventBinding);\n\t }\n\n\t if (bind.css) {\n\t bindings.css = createBindings(bind.css, parents, Binding);\n\t }\n\n\t target.bind(bindings);\n\t }\n\n\t if (target) {\n\t element.kendoBindingTarget = target;\n\t }\n\n\t var children = element.children;\n\t if (deep && children && !element.getAttribute(\"data-\" + kendo.ns + \"stop\")) {\n\t // https://github.com/telerik/kendo/issues/1240 for the weirdness.\n\t for (idx = 0; idx < children.length; idx++) {\n\t childrenCopy[idx] = children[idx];\n\t }\n\n\t for (idx = 0; idx < childrenCopy.length; idx++) {\n\t bindElement(childrenCopy[idx], source, roles, parents);\n\t }\n\t }\n\t }\n\n\t function bind(dom, object) {\n\t var idx,\n\t length,\n\t node,\n\t roles = kendo.rolesFromNamespaces([].slice.call(arguments, 2));\n\n\t object = kendo.observable(object);\n\t dom = $(dom);\n\n\t for (idx = 0, length = dom.length; idx < length; idx++) {\n\t node = dom[idx];\n\t if (node.nodeType === 1) {\n\t bindElement(node, object, roles);\n\t }\n\t }\n\t }\n\n\t function unbindElement(element, destroyWidget) {\n\t var bindingTarget = element.kendoBindingTarget;\n\n\t if (bindingTarget) {\n\t bindingTarget.destroy();\n\n\t if (deleteExpando) {\n\t delete element.kendoBindingTarget;\n\t } else if (element.removeAttribute) {\n\t element.removeAttribute(\"kendoBindingTarget\");\n\t } else {\n\t element.kendoBindingTarget = null;\n\t }\n\t }\n\n\t if(destroyWidget) {\n\t var widget = kendo.widgetInstance($(element));\n\t if (widget && typeof widget.destroy === FUNCTION) {\n\t widget.destroy();\n\t }\n\t }\n\t }\n\n\t function unbindElementTree(element, destroyWidgets) {\n\t unbindElement(element, destroyWidgets);\n\n\t unbindElementChildren(element, destroyWidgets);\n\t }\n\n\t function unbindElementChildren(element, destroyWidgets) {\n\t var children = element.children;\n\n\t if (children) {\n\t for (var idx = 0, length = children.length; idx < length; idx++) {\n\t unbindElementTree(children[idx], destroyWidgets);\n\t }\n\t }\n\t }\n\n\t function unbind(dom) {\n\t var idx, length;\n\n\t dom = $(dom);\n\n\t for (idx = 0, length = dom.length; idx < length; idx++ ) {\n\t unbindElementTree(dom[idx], false);\n\t }\n\t }\n\n\t function notify(widget, namespace) {\n\t var element = widget.element,\n\t bindingTarget = element[0].kendoBindingTarget;\n\n\t if (bindingTarget) {\n\t bind(element, bindingTarget.source, namespace);\n\t }\n\t }\n\n\t function retrievePrimitiveValues(value, valueField) {\n\t var values = [];\n\t var idx = 0;\n\t var length;\n\t var item;\n\n\t if (!valueField) {\n\t return value;\n\t }\n\n\t if (value instanceof ObservableArray) {\n\t for (length = value.length; idx < length; idx++) {\n\t item = value[idx];\n\t values[idx] = item.get ? item.get(valueField) : item[valueField];\n\t }\n\t value = values;\n\t } else if (value instanceof ObservableObject) {\n\t value = value.get(valueField);\n\t }\n\n\t return value;\n\t }\n\n\t kendo.unbind = unbind;\n\t kendo.bind = bind;\n\t kendo.data.binders = binders;\n\t kendo.data.Binder = Binder;\n\t kendo.notify = notify;\n\n\t kendo.observable = function(object) {\n\t if (!(object instanceof ObservableObject)) {\n\t object = new ObservableObject(object);\n\t }\n\n\t return object;\n\t };\n\n\t kendo.observableHierarchy = function(array) {\n\t var dataSource = kendo.data.HierarchicalDataSource.create(array);\n\n\t function recursiveRead(data) {\n\t var i, children;\n\n\t for (i = 0; i < data.length; i++) {\n\t data[i]._initChildren();\n\n\t children = data[i].children;\n\n\t children.fetch();\n\n\t data[i].items = children.data();\n\n\t recursiveRead(data[i].items);\n\t }\n\t }\n\n\t dataSource.fetch();\n\n\t recursiveRead(dataSource.data());\n\n\t dataSource._data._dataSource = dataSource;\n\n\t return dataSource._data;\n\t };\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1045);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1045:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018), __webpack_require__(1046) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"calendar\",\n\t name: \"Calendar\",\n\t category: \"web\",\n\t description: \"The Calendar widget renders a graphical calendar that supports navigation and selection.\",\n\t depends: [ \"core\", \"selectable\" ]\n\t};\n\n\t(function($, undefined) {\n\t var kendo = window.kendo,\n\t support = kendo.support,\n\t ui = kendo.ui,\n\t Widget = ui.Widget,\n\t keys = kendo.keys,\n\t parse = kendo.parseDate,\n\t adjustDST = kendo.date.adjustDST,\n\t weekInYear = kendo.date.weekInYear,\n\t Selectable = kendo.ui.Selectable,\n\t extractFormat = kendo._extractFormat,\n\t template = kendo.template,\n\t getCulture = kendo.getCulture,\n\t transitions = kendo.support.transitions,\n\t transitionOrigin = transitions ? transitions.css + \"transform-origin\" : \"\",\n\t cellTemplate = template('#=data.value#', { useWithBlock: false }),\n\t emptyCellTemplate = template('', { useWithBlock: false }),\n\t otherMonthCellTemplate = template('', { useWithBlock: false }),\n\t weekNumberTemplate = template('', { useWithBlock: false }),\n\t browser = kendo.support.browser,\n\t isIE8 = browser.msie && browser.version < 9,\n\t outerWidth = kendo._outerWidth,\n\t ns = \".kendoCalendar\",\n\t CLICK = \"click\" + ns,\n\t KEYDOWN_NS = \"keydown\" + ns,\n\t ID = \"id\",\n\t MIN = \"min\",\n\t LEFT = \"left\",\n\t SLIDE = \"slideIn\",\n\t MONTH = \"month\",\n\t CENTURY = \"century\",\n\t CHANGE = \"change\",\n\t NAVIGATE = \"navigate\",\n\t VALUE = \"value\",\n\t HOVER = \"k-state-hover\",\n\t DISABLED = \"k-state-disabled\",\n\t FOCUSED = \"k-state-focused\",\n\t OTHERMONTH = \"k-other-month\",\n\t OTHERMONTHCLASS = ' class=\"' + OTHERMONTH + '\"',\n\t OUTOFRANGE = \"k-out-of-range\",\n\t TODAY = \"k-nav-today\",\n\t CELLSELECTOR = \"td:has(.k-link)\",\n\t CELLSELECTORVALID = \"td:has(.k-link):not(.\" + DISABLED + \"):not(.\" + OUTOFRANGE + \")\",\n\t WEEKCOLUMNSELECTOR = \"td:not(:has(.k-link))\",\n\t SELECTED = \"k-state-selected\",\n\t BLUR = \"blur\" + ns,\n\t FOCUS = \"focus\",\n\t FOCUS_WITH_NS = FOCUS + ns,\n\t MOUSEENTER = support.touch ? \"touchstart\" : \"mouseenter\",\n\t MOUSEENTER_WITH_NS = support.touch ? \"touchstart\" + ns : \"mouseenter\" + ns,\n\t MOUSELEAVE = support.touch ? \"touchend\" + ns + \" touchmove\" + ns : \"mouseleave\" + ns,\n\t MS_PER_MINUTE = 60000,\n\t MS_PER_DAY = 86400000,\n\t PREVARROW = \"_prevArrow\",\n\t NEXTARROW = \"_nextArrow\",\n\t ARIA_DISABLED = \"aria-disabled\",\n\t ARIA_SELECTED = \"aria-selected\",\n\t ARIA_LABEL = \"aria-label\",\n\t proxy = $.proxy,\n\t extend = $.extend,\n\t DATE = Date,\n\t views = {\n\t month: 0,\n\t year: 1,\n\t decade: 2,\n\t century: 3\n\t },\n\t HEADERSELECTOR = '.k-header, .k-calendar-header',\n\t CLASSIC_HEADER_TEMPLATE = '
    ' +\n\t '' +\n\t '' +\n\t '' +\n\t '
    ',\n\t MODERN_HEADER_TEMPLATE = '
    ' +\n\t '' +\n\t '' +\n\t '' +\n\t '' +\n\t '' +\n\t '#=messages.today#' +\n\t '' +\n\t '' +\n\t '' +\n\t '' +\n\t '
    ';\n\n\t var Calendar = Widget.extend({\n\t init: function(element, options) {\n\t var that = this, value, id;\n\t options = options || {};\n\t options.componentType = options.componentType || \"classic\";\n\t Widget.fn.init.call(that, element, options);\n\n\t element = that.wrapper = that.element;\n\t options = that.options;\n\n\t options.url = kendo.unescape(options.url);\n\n\t that.options.disableDates = getDisabledExpr(that.options.disableDates);\n\n\t that._templates();\n\n\t that._selectable();\n\n\t that._header();\n\n\t that._viewWrapper();\n\n\t if (that.options.hasFooter) {\n\t that._footer(that.footer);\n\t }\n\n\t id = element\n\t .addClass(\"k-widget k-calendar \" + (options.weekNumber ? \" k-week-number\" : \"\"))\n\t .on(MOUSEENTER_WITH_NS + \" \" + MOUSELEAVE, CELLSELECTOR, mousetoggle)\n\t .on(KEYDOWN_NS, \"table.k-content\", proxy(that._move, that))\n\t .on(CLICK + \" touchend\", CELLSELECTOR, function(e) {\n\t var link = e.currentTarget.firstChild,\n\t value = toDateObject(link);\n\n\t if (link.href.indexOf(\"#\") != -1) {\n\t e.preventDefault();\n\t }\n\n\t if (that._view.name == \"month\" && that.options.disableDates(value)) {\n\t return;\n\t }\n\t if(that._view.name != \"month\" || options.selectable == \"single\") {\n\t that._click($(link));\n\t }\n\t })\n\t .on(\"mouseup\" + ns, \"table.k-content, .k-footer\", function() {\n\t that._focusView(that.options.focusOnNav !== false);\n\t })\n\t .attr(ID);\n\n\t if (id) {\n\t that._cellID = id + \"_cell_selected\";\n\t }\n\n\t if(that._isMultipleSelection() && that.options.weekNumber) {\n\t element.on(CLICK, WEEKCOLUMNSELECTOR, function(e) {\n\t var first = $(e.currentTarget).closest(\"tr\").find(CELLSELECTORVALID).first(),\n\t last = that.selectable._lastActive = $(e.currentTarget).closest(\"tr\").find(CELLSELECTORVALID).last();\n\t that.selectable.selectRange(first, last, { event: e});\n\t that._current = that._value = toDateObject(last.find(\"a\"));\n\t that._class(FOCUSED, that._current);\n\t });\n\t }\n\n\t normalize(options);\n\t value = parse(options.value, options.format, options.culture);\n\t that._selectDates = [];\n\n\t that._index = views[options.start];\n\n\t that._current = new DATE(+restrictValue(value, options.min, options.max));\n\n\t that._addClassProxy = function() {\n\t that._active = true;\n\n\t if (that._cell.hasClass(DISABLED)) {\n\t var todayString = that._view.toDateString(getToday());\n\t that._cell = that._cellByDate(todayString);\n\t }\n\n\t that._cell.addClass(FOCUSED);\n\t };\n\n\t that._removeClassProxy = function() {\n\t that._active = false;\n\t that._cell.removeClass(FOCUSED);\n\t };\n\n\t that.value(value);\n\n\t if(that._isMultipleSelection() && options.selectDates.length > 0) {\n\t that.selectDates(options.selectDates);\n\t }\n\t kendo.notify(that);\n\t },\n\n\t options: {\n\t name: \"Calendar\",\n\t value: null,\n\t min: new DATE(1900, 0, 1),\n\t max: new DATE(2099, 11, 31),\n\t dates: [],\n\t disableDates: null,\n\t url: \"\",\n\t culture: \"\",\n\t footer : \"\",\n\t format : \"\",\n\t month : {},\n\t weekNumber: false,\n\t selectable: \"single\",\n\t selectDates: [],\n\t start: MONTH,\n\t depth: MONTH,\n\t animation: {\n\t horizontal: {\n\t effects: SLIDE,\n\t reverse: true,\n\t duration: 500,\n\t divisor: 2\n\t },\n\t vertical: {\n\t effects: \"zoomIn\",\n\t duration: 400\n\t }\n\t },\n\t messages: {\n\t weekColumnHeader: \"\",\n\t today: \"Today\"\n\t }\n\t },\n\n\t events: [\n\t CHANGE,\n\t NAVIGATE\n\t ],\n\n\t componentTypes: {\n\t \"classic\": {\n\t header: {\n\t template: CLASSIC_HEADER_TEMPLATE\n\t },\n\t hasFooter: true,\n\t linksSelector: \".k-link\",\n\t contentClasses: \"k-content\"\n\t },\n\t \"modern\": {\n\t header: {\n\t template: MODERN_HEADER_TEMPLATE\n\t },\n\t hasFooter: false,\n\t linksSelector: \".k-button\",\n\t contentClasses: \"k-content k-calendar-content\"\n\t }\n\t },\n\n\t setOptions: function(options) {\n\t var that = this;\n\n\t normalize(options);\n\n\t options.disableDates = getDisabledExpr(options.disableDates);\n\t that._destroySelectable();\n\n\t Widget.fn.setOptions.call(that, options);\n\n\t that._templates();\n\n\t that._selectable();\n\n\t that._viewWrapper();\n\n\t if (that.options.hasFooter) {\n\t that._footer(that.footer);\n\t } else {\n\t that.element.find(\".k-footer\").hide();\n\t }\n\t that._index = views[that.options.start];\n\n\t that.navigate();\n\n\t if(options.weekNumber) {\n\t that.element.addClass('k-week-number');\n\t }\n\t },\n\n\t destroy: function() {\n\t var that = this,\n\t today = that._today;\n\n\t that.element.off(ns);\n\t that._title.off(ns);\n\t that[PREVARROW].off(ns);\n\t that[NEXTARROW].off(ns);\n\t that._destroySelectable();\n\t kendo.destroy(that._table);\n\n\t if (today) {\n\t kendo.destroy(today.off(ns));\n\t }\n\n\t Widget.fn.destroy.call(that);\n\t },\n\n\t current: function() {\n\t return this._current;\n\t },\n\n\t view: function() {\n\t return this._view;\n\t },\n\n\t focus: function(table) {\n\t table = table || this._table;\n\t this._bindTable(table);\n\t table.trigger(\"focus\");\n\t },\n\n\t min: function(value) {\n\t return this._option(MIN, value);\n\t },\n\n\t max: function(value) {\n\t return this._option(\"max\", value);\n\t },\n\n\t navigateToPast: function() {\n\t this._navigate(PREVARROW, -1);\n\t },\n\n\t navigateToFuture: function() {\n\t this._navigate(NEXTARROW, 1);\n\t },\n\n\t navigateUp: function() {\n\t var that = this,\n\t index = that._index;\n\n\t if (that._title.hasClass(DISABLED)) {\n\t return;\n\t }\n\n\t that.navigate(that._current, ++index);\n\t },\n\n\t navigateDown: function(value) {\n\t var that = this,\n\t index = that._index,\n\t depth = that.options.depth;\n\n\t if (!value) {\n\t return;\n\t }\n\n\t if (index === views[depth]) {\n\t if (!isEqualDate(that._value, that._current) || !isEqualDate(that._value, value)) {\n\t that.value(value);\n\t that.trigger(CHANGE);\n\t }\n\t return;\n\t }\n\n\t that.navigate(value, --index);\n\t },\n\n\t navigate: function(value, view) {\n\t view = isNaN(view) ? views[view] : view;\n\n\t var that = this,\n\t options = that.options,\n\t culture = options.culture,\n\t min = options.min,\n\t max = options.max,\n\t title = that._title,\n\t from = that._table,\n\t old = that._oldTable,\n\t currentValue = that._current,\n\t future = value && +value > +currentValue,\n\t vertical = view !== undefined && view !== that._index,\n\t to, currentView, compare,\n\t disabled,\n\t viewWrapper = that.element.children(\".k-calendar-view\");\n\n\t if (!value) {\n\t value = currentValue;\n\t }\n\n\t that._current = value = new DATE(+restrictValue(value, min, max));\n\n\t if (view === undefined) {\n\t view = that._index;\n\t } else {\n\t that._index = view;\n\t }\n\n\t that._view = currentView = calendar.views[view];\n\t compare = currentView.compare;\n\n\t disabled = view === views[CENTURY];\n\t title.toggleClass(DISABLED, disabled).attr(ARIA_DISABLED, disabled);\n\n\t disabled = compare(value, min) < 1;\n\t that[PREVARROW].toggleClass(DISABLED, disabled).attr(ARIA_DISABLED, disabled);\n\t if (that[PREVARROW].hasClass(DISABLED)) {\n\t that[PREVARROW].removeClass(HOVER);\n\t }\n\n\t disabled = compare(value, max) > -1;\n\t that[NEXTARROW].toggleClass(DISABLED, disabled).attr(ARIA_DISABLED, disabled);\n\t if (that[NEXTARROW].hasClass(DISABLED)) {\n\t that[NEXTARROW].removeClass(HOVER);\n\t }\n\n\t if (from && old && old.data(\"animating\")) {\n\t old.kendoStop(true, true);\n\t from.kendoStop(true, true);\n\t }\n\n\t that._oldTable = from;\n\n\t if (!from || that._changeView) {\n\t title.html(currentView.title(value, min, max, culture));\n\n\t that._table = to = $(currentView.content(extend({\n\t min: min,\n\t max: max,\n\t date: value,\n\t url: options.url,\n\t dates: options.dates,\n\t format: options.format,\n\t otherMonth : true,\n\t culture: culture,\n\t disableDates: options.disableDates,\n\t isWeekColumnVisible: options.weekNumber,\n\t messages: options.messages,\n\t contentClasses: that.options.contentClasses\n\t }, that[currentView.name])));\n\n\t addClassToViewContainer(to, currentView.name);\n\t makeUnselectable(to);\n\t var replace = from && from.data(\"start\") === to.data(\"start\");\n\t that._animate({\n\t from: from,\n\t to: to,\n\t vertical: vertical,\n\t future: future,\n\t replace: replace\n\t });\n\n\t if(that.options.componentType === \"modern\"){\n\t viewWrapper.removeClass(\"k-calendar-monthview k-calendar-yearview k-calendar-decadeview k-calendar-centuryview\");\n\t viewWrapper.addClass(\"k-calendar-\" + currentView.name + \"view\");\n\t }\n\n\t that.trigger(NAVIGATE);\n\n\t that._focus(value);\n\t }\n\n\t if (view === views[options.depth] && that._selectDates.length > 0) {\n\t that._visualizeSelectedDatesInView();\n\t }\n\n\t if(that.options.selectable === \"single\") {\n\t if (view === views[options.depth] && that._value && !that.options.disableDates(that._value)) {\n\t that._class(\"k-state-selected\", that._value);\n\t }\n\t }\n\n\t that._class(FOCUSED, value);\n\n\t if (!from && that._cell) {\n\t that._cell.removeClass(FOCUSED);\n\t }\n\n\t that._changeView = true;\n\t },\n\n\t selectDates: function(dates) {\n\t var that = this,\n\t validSelectedDates,\n\t datesUnique;\n\n\t if(dates === undefined) {\n\t return that._selectDates;\n\t }\n\n\t datesUnique = dates\n\t .map(function (date) { return date.getTime(); })\n\t .filter(function (date, position, array) {\n\t return array.indexOf(date) === position;\n\t })\n\t .map(function (time) { return new Date(time); });\n\n\t validSelectedDates = $.grep(datesUnique, function(value) {\n\t if(value) {\n\t return +that._validateValue(new Date(value.setHours(0, 0, 0, 0))) === +value;\n\t }\n\t });\n\t that._selectDates = validSelectedDates.length > 0 ? validSelectedDates : (datesUnique.length === 0 ? datesUnique : that._selectDates);\n\t that._visualizeSelectedDatesInView();\n\t },\n\n\t value: function(value) {\n\t var that = this,\n\t old = that._view,\n\t view = that._view;\n\n\t if (value === undefined) {\n\t return that._value;\n\t }\n\n\t value = that._validateValue(value);\n\t if (value && that._isMultipleSelection()) {\n\t var date = new Date(+value);\n\t date.setHours(0, 0, 0, 0);\n\t that._selectDates = [date];\n\t that.selectable._lastActive = null;\n\t }\n\t if (old && value === null && that._cell) {\n\t that._cell.removeClass(SELECTED);\n\t } else {\n\t that._changeView = !value || view && view.compare(value, that._current) !== 0;\n\t that.navigate(value);\n\t }\n\t },\n\n\t _validateValue: function(value) {\n\t var that = this,\n\t options = that.options,\n\t min = options.min,\n\t max = options.max;\n\n\t if (value === null) {\n\t that._current = createDate(that._current.getFullYear(), that._current.getMonth(), that._current.getDate());\n\t }\n\n\t value = parse(value, options.format, options.culture);\n\n\t if (value !== null) {\n\t value = new DATE(+value);\n\n\t if (!isInRange(value, min, max)) {\n\t value = null;\n\t }\n\t }\n\n\t if (value === null || !that.options.disableDates(new Date(+value))) {\n\t that._value = value;\n\t } else if (that._value === undefined) {\n\t that._value = null;\n\t }\n\n\t return that._value;\n\t },\n\n\t _visualizeSelectedDatesInView: function() {\n\t var that = this;\n\t var selectedDates = {};\n\t $.each(that._selectDates, function(index, value) {\n\t selectedDates[kendo.calendar.views[0].toDateString(value)] = value;\n\t });\n\t that.selectable.clear();\n\t var cells = that._table\n\t .find(CELLSELECTOR)\n\t .filter(function(index, element) {\n\t return selectedDates[$(element.firstChild).attr(kendo.attr(VALUE))];\n\t });\n\t if(cells.length > 0) {\n\t that.selectable._selectElement(cells, true);\n\t }\n\t },\n\n\t _isMultipleSelection: function() {\n\t var that = this;\n\t return that.options.selectable === \"multiple\";\n\t },\n\n\t _selectable: function() {\n\t var that = this;\n\t if(!that._isMultipleSelection()) {\n\t return;\n\t }\n\n\t var selectable = that.options.selectable,\n\t selectableOptions = Selectable.parseOptions(selectable);\n\n\t if (selectableOptions.multiple) {\n\t that.element.attr(\"aria-multiselectable\", \"true\");\n\t }\n\t that.selectable = new Selectable(that.wrapper, {\n\t aria: true,\n\t //excludes the anchor element\n\t inputSelectors: \"input,textarea,.k-multiselect-wrap,select,button,.k-button>span,.k-button>img,span.k-icon.k-i-arrow-60-down,span.k-icon.k-i-arrow-60-up\",\n\t multiple: selectableOptions.multiple,\n\t filter: \"table.k-month:eq(0) \" + CELLSELECTORVALID,\n\t change: proxy(that._onSelect, that),\n\t relatedTarget: proxy(that._onRelatedTarget, that)\n\t });\n\t },\n\n\t _onRelatedTarget: function(target) {\n\t var that = this;\n\n\t if(that.selectable.options.multiple && target.is(CELLSELECTORVALID)) {\n\t that._current = toDateObject(target.find(\"a\"));\n\t that._class(FOCUSED, toDateObject(target.find(\"a\")));\n\t }\n\n\t },\n\n\t _onSelect: function(e) {\n\t var that = this,\n\t eventArgs = e,\n\t selectableOptions = Selectable.parseOptions(that.options.selectable);\n\n\t if(!selectableOptions.multiple) {\n\t if($(eventArgs.event.currentTarget).is(\"td\") && !$(eventArgs.event.currentTarget).hasClass(\"k-state-selected\")) {\n\t $(eventArgs.event.currentTarget).addClass(\"k-state-selected\");\n\t }\n\t else {\n\t that._click($(eventArgs.event.currentTarget).find(\"a\"));\n\t }\n\t return;\n\t }\n\n\t if(eventArgs.event.ctrlKey || eventArgs.event.metaKey) {\n\t if($(eventArgs.event.currentTarget).is(CELLSELECTORVALID)) {\n\t that._toggleSelection($(eventArgs.event.currentTarget));\n\t }\n\t else {\n\t that._cellsBySelector(CELLSELECTORVALID).each(function(index, element){\n\t var value = toDateObject($(element).find(\"a\"));\n\t that._deselect(value);\n\t });\n\t that._addSelectedCellsToArray();\n\t }\n\t }\n\t else if (eventArgs.event.shiftKey) {\n\t that._rangeSelection(that._cell);\n\t }\n\t else if($(eventArgs.event.currentTarget).is(CELLSELECTOR)) {\n\t that.value(toDateObject($(eventArgs.event.currentTarget).find(\"a\")));\n\t }\n\t else {\n\t that._selectDates = [];\n\t that._addSelectedCellsToArray();\n\t }\n\t that.trigger(CHANGE);\n\t },\n\n\t _destroySelectable: function() {\n\t var that = this;\n\n\t if (that.selectable) {\n\t that.selectable.destroy();\n\t that.selectable = null;\n\t }\n\t },\n\n\t //when ctrl key is clicked\n\t _toggleSelection: function(currentCell) {\n\t var that = this,\n\t date = toDateObject(currentCell.find(\"a\"));\n\t if(currentCell.hasClass(\"k-state-selected\")) {\n\t that._selectDates.push(date);\n\t }\n\t else {\n\t that._deselect(date);\n\t }\n\t },\n\n\t //shift selection\n\t _rangeSelection: function(toDateCell, startDate) {\n\t var that = this,\n\t fromDate = startDate || toDateObject(that.selectable.value().first().find(\"a\")),\n\t toDate = toDateObject(toDateCell.find(\"a\")),\n\t daysDifference;\n\n\t if(that.selectable._lastActive || that._value) {\n\t fromDate = that.selectable._lastActive? toDateObject(that.selectable._lastActive.find(\"a\")): new Date(+that._value);\n\t } else {\n\t that.selectable._lastActive = startDate? that._cellByDate(that._view.toDateString(startDate), CELLSELECTORVALID): that.selectable.value().first();\n\t }\n\n\t that._selectDates = [];\n\t daysDifference = daysBetweenTwoDates(fromDate, toDate);\n\t addDaysToArray(that._selectDates, daysDifference, fromDate, that.options.disableDates);\n\n\t that._visualizeSelectedDatesInView();\n\t },\n\n\t _cellsBySelector: function(selector) {\n\t var that = this;\n\t return that._table.find(selector);\n\t },\n\n\t _addSelectedCellsToArray: function() {\n\t var that = this;\n\t that.selectable.value().each(function(index, item) {\n\t var date = toDateObject($(item.firstChild));\n\t if(!that.options.disableDates(date)) {\n\t that._selectDates.push(date);\n\t }\n\t });\n\t },\n\n\t _deselect: function(date) {\n\t var that = this;\n\t var currentDateIndex = that._selectDates.map(Number).indexOf(+date);\n\t if(currentDateIndex != -1) {\n\t that._selectDates.splice(currentDateIndex, 1);\n\t }\n\t },\n\n\t _dateInView: function(date) {\n\t var that = this,\n\t firstDateInView = toDateObject(that._cellsBySelector(CELLSELECTORVALID + \":first\").find(\"a\")),\n\t lastDateInView = toDateObject(that._cellsBySelector(CELLSELECTORVALID + \":last\").find(\"a\"));\n\n\t return +date <= +lastDateInView && +date >= +firstDateInView;\n\t },\n\n\t _isNavigatable: function(currentValue, cellIndex) {\n\t var that = this;\n\t var isDisabled = that.options.disableDates;\n\t var cell;\n\t var index;\n\n\t if (that._view.name == \"month\") {\n\t return !isDisabled(currentValue);\n\t } else {\n\t index = that.wrapper.find(\".\"+FOCUSED).index();\n\t cell = that.wrapper.find(\".k-content td:eq(\"+(index+cellIndex)+\")\");\n\t return cell.is(CELLSELECTORVALID) || !isDisabled(currentValue);\n\t }\n\t },\n\n\t _move: function(e) {\n\t var that = this,\n\t options = that.options,\n\t key = e.keyCode,\n\t view = that._view,\n\t index = that._index,\n\t min = that.options.min,\n\t max = that.options.max,\n\t currentValue = new DATE(+that._current),\n\t isRtl = kendo.support.isRtl(that.wrapper),\n\t isDisabled = that.options.disableDates,\n\t value, prevent, method, temp;\n\n\t if (e.target === that._table[0]) {\n\t that._active = true;\n\t }\n\n\t if (key == keys.RIGHT && !isRtl || key == keys.LEFT && isRtl) {\n\t value = 1;\n\t prevent = true;\n\t } else if (key == keys.LEFT && !isRtl || key == keys.RIGHT && isRtl) {\n\t value = -1;\n\t prevent = true;\n\t } else if (key == keys.UP) {\n\t value = index === 0 ? -7 : -4;\n\t prevent = true;\n\t } else if (key == keys.DOWN) {\n\t value = index === 0 ? 7 : 4;\n\t prevent = true;\n\t }\n\t else if(key == keys.SPACEBAR) {\n\t value = 0;\n\t prevent = true;\n\t }\n\t else if (key == keys.HOME || key == keys.END) {\n\t method = key == keys.HOME ? \"first\" : \"last\";\n\t temp = view[method](currentValue);\n\t currentValue = new DATE(temp.getFullYear(), temp.getMonth(), temp.getDate(), currentValue.getHours(), currentValue.getMinutes(), currentValue.getSeconds(), currentValue.getMilliseconds());\n\t currentValue.setFullYear(temp.getFullYear());\n\t prevent = true;\n\t }\n\n\t if (e.ctrlKey || e.metaKey) {\n\t if (key == keys.RIGHT && !isRtl || key == keys.LEFT && isRtl) {\n\t that.navigateToFuture();\n\t prevent = true;\n\t } else if (key == keys.LEFT && !isRtl || key == keys.RIGHT && isRtl) {\n\t that.navigateToPast();\n\t prevent = true;\n\t } else if (key == keys.UP) {\n\t that.navigateUp();\n\t prevent = true;\n\t } else if (key == keys.DOWN) {\n\t that._click($(that._cell[0].firstChild));\n\t prevent = true;\n\t }\n\t else if ((key == keys.ENTER || key == keys.SPACEBAR) && that._isMultipleSelection()) {\n\t that._keyboardToggleSelection(e);\n\n\t var focusedDate = toDateObject($(that._cell[0]).find(\"a\"));\n\t that._class(FOCUSED, focusedDate);\n\n\t }\n\t } else if(e.shiftKey) {\n\t if (value !== undefined || method) {\n\t if (!method) {\n\t view.setDate(currentValue, value);\n\t }\n\n\t if (!isInRange(currentValue, min, max)) {\n\t currentValue = restrictValue(currentValue, options.min, options.max);\n\t }\n\n\t if (isDisabled(currentValue)) {\n\t currentValue = that._nextNavigatable(currentValue, value);\n\t }\n\n\t min = createDate(min.getFullYear(), min.getMonth(), min.getDate());\n\t if(that._isMultipleSelection()) {\n\t that._keyboardRangeSelection(e, currentValue);\n\t }\n\t else {\n\t that._focus(currentValue);\n\t }\n\t }\n\t } else {\n\t if (key == keys.ENTER || key == keys.SPACEBAR) {\n\t if(view.name == \"month\" && that._isMultipleSelection()) {\n\t that.value(toDateObject($(that._cell.find(\"a\"))));\n\t that.selectable._lastActive = $(that._cell[0]);\n\t that.trigger(CHANGE);\n\t }\n\t else {\n\t that._click($(that._cell[0].firstChild));\n\t }\n\t prevent = true;\n\t } else if (key == keys.PAGEUP) {\n\t prevent = true;\n\t that.navigateToPast();\n\t } else if (key == keys.PAGEDOWN) {\n\t prevent = true;\n\t that.navigateToFuture();\n\t }\n\n\t if (value || method) {\n\t if (!method) {\n\t view.setDate(currentValue, value);\n\t }\n\n\t min = createDate(min.getFullYear(), min.getMonth(), min.getDate());\n\n\t if (!isInRange(currentValue, min, max)) {\n\t currentValue = restrictValue(currentValue, options.min, options.max);\n\t }\n\n\t if (!that._isNavigatable(currentValue, value)) {\n\t currentValue = that._nextNavigatable(currentValue, value);\n\t }\n\n\t if(that._isMultipleSelection()) {\n\t if(!that._dateInView(currentValue)) {\n\t that.navigate(currentValue);\n\t }\n\t else {\n\t that._current = currentValue;\n\t that._class(FOCUSED, currentValue);\n\t }\n\t }\n\t else {\n\t that._focus(currentValue);\n\t }\n\t }\n\t }\n\n\t if (prevent) {\n\t e.preventDefault();\n\t }\n\n\t return that._current;\n\t },\n\n\t _keyboardRangeSelection: function(event, currentValue) {\n\t var that = this,\n\t fromDate,\n\t daysDifference;\n\n\t if(!that._dateInView(currentValue)) {\n\t that._selectDates = [];\n\n\t fromDate = that.selectable._lastActive? toDateObject(that.selectable._lastActive.find(\"a\")): currentValue;\n\t daysDifference = daysBetweenTwoDates(fromDate, new Date(+currentValue));\n\n\t addDaysToArray(that._selectDates, daysDifference, fromDate, that.options.disableDates);\n\n\t that.navigate(currentValue);\n\t that._current = currentValue;\n\t that.selectable._lastActive = that.selectable._lastActive || that._cellByDate(that._view.toDateString(currentValue), CELLSELECTORVALID);\n\t that.trigger(CHANGE);\n\t return;\n\t }\n\t that.selectable.options.filter = that.wrapper.find(\"table\").length > 1 && +currentValue > +that._current? \"table.k-month:eq(1) \" + CELLSELECTORVALID: \"table.k-month:eq(0) \" + CELLSELECTORVALID;\n\t that._class(FOCUSED, currentValue);\n\t that._current = currentValue;\n\n\t that._rangeSelection(that._cellByDate(that._view.toDateString(currentValue), CELLSELECTORVALID), currentValue);\n\n\t that.trigger(CHANGE);\n\n\t that.selectable.options.filter = \"table.k-month:eq(0) \" + CELLSELECTORVALID;\n\t },\n\n\t _keyboardToggleSelection: function(event) {\n\t var that = this;\n\n\t event.currentTarget = that._cell[0];\n\t that.selectable._lastActive = $(that._cell[0]);\n\n\t if ($(that._cell[0]).hasClass(SELECTED)) {\n\t that.selectable._unselect($(that._cell[0]));\n\t that.selectable.trigger(CHANGE, { event: event});\n\t }\n\t else {\n\t that.selectable.value($(that._cell[0]), { event: event});\n\t }\n\t },\n\n\t _nextNavigatable: function(currentValue, value) {\n\t var that = this,\n\t disabled = true,\n\t view = that._view,\n\t min = that.options.min,\n\t max = that.options.max,\n\t isDisabled = that.options.disableDates,\n\t navigatableDate = new Date(currentValue.getTime());\n\n\t view.setDate(navigatableDate, -value);\n\n\t while (disabled) {\n\t view.setDate(currentValue, value);\n\n\t if (!isInRange(currentValue, min, max)) {\n\t currentValue = navigatableDate;\n\t break;\n\t }\n\t disabled = isDisabled(currentValue);\n\t }\n\t return currentValue;\n\t },\n\n\t _animate: function(options) {\n\t var that = this;\n\t var from = options.from;\n\t var to = options.to;\n\t var active = that._active;\n\t var viewWrapper = that.element.children(\".k-calendar-view\");\n\n\t if (!from) {\n\t viewWrapper.append(to);\n\t that._bindTable(to);\n\t } else if (from.parent().data(\"animating\")) {\n\t from.off(ns);\n\t from.parent().kendoStop(true, true).remove();\n\t from.remove();\n\n\t viewWrapper.append(to);\n\t that._focusView(active);\n\t } else if (!from.is(\":visible\") || that.options.animation === false || options.replace) {\n\t to.insertAfter(from);\n\t from.off(ns).remove();\n\n\t that._focusView(active);\n\t } else {\n\t that[options.vertical ? \"_vertical\" : \"_horizontal\"](from, to, options.future);\n\t }\n\t },\n\n\t _horizontal: function(from, to, future) {\n\t var that = this,\n\t active = that._active,\n\t horizontal = that.options.animation.horizontal,\n\t effects = horizontal.effects,\n\t viewWidth = outerWidth(from);\n\n\t if (effects && effects.indexOf(SLIDE) != -1) {\n\t from.add(to).css({ width: viewWidth });\n\n\t from.wrap(\"
    \");\n\n\t that._focusView(active, from);\n\n\t from.parent()\n\t .css({\n\t position: \"relative\",\n\t width: viewWidth * 2,\n\t \"float\": LEFT,\n\t \"margin-left\": future ? 0 : -viewWidth\n\t });\n\n\t to[future ? \"insertAfter\" : \"insertBefore\"](from);\n\n\t extend(horizontal, {\n\t effects: SLIDE + \":\" + (future ? \"right\" : LEFT),\n\t complete: function() {\n\t from.off(ns).remove();\n\t that._oldTable = null;\n\n\t to.unwrap();\n\n\t that._focusView(active);\n\n\t }\n\t });\n\n\t from.parent().kendoStop(true, true).kendoAnimate(horizontal);\n\t }\n\t },\n\n\t _vertical: function(from, to) {\n\t var that = this,\n\t vertical = that.options.animation.vertical,\n\t effects = vertical.effects,\n\t active = that._active, //active state before from's blur\n\t cell, position;\n\n\t if (effects && effects.indexOf(\"zoom\") != -1) {\n\t to.insertBefore(from);\n\n\t from.css({\n\t position: \"absolute\",\n\t width: to.width()\n\t });\n\n\t if (transitionOrigin) {\n\t cell = that._cellByDate(that._view.toDateString(that._current));\n\t position = cell.position();\n\t position = (position.left + parseInt(cell.width() / 2, 10)) + \"px\" + \" \" + (position.top + parseInt(cell.height() / 2, 10) + \"px\");\n\t to.css(transitionOrigin, position);\n\t }\n\n\t from.kendoStop(true, true).kendoAnimate({\n\t effects: \"fadeOut\",\n\t duration: 600,\n\t complete: function() {\n\t from.off(ns).remove();\n\t that._oldTable = null;\n\n\t that._focusView(active);\n\t }\n\t });\n\n\t to.kendoStop(true, true).kendoAnimate(vertical);\n\t }\n\t },\n\n\t _cellByDate: function(value, selector) {\n\t return this._table.find(selector ? selector : \"td:not(.\" + OTHERMONTH + \")\")\n\t .filter(function() {\n\t return $(this.firstChild).attr(kendo.attr(VALUE)) === value;\n\t });\n\t },\n\n\t _class: function(className, date) {\n\t var that = this,\n\t id = that._cellID,\n\t cell = that._cell,\n\t value = that._view.toDateString(date),\n\t disabledDate;\n\n\t if (cell && cell.length) {\n\t cell[0].removeAttribute(ARIA_SELECTED);\n\t cell[0].removeAttribute(ARIA_LABEL);\n\t cell[0].removeAttribute(ID);\n\t //.removeClass(className);\n\t }\n\n\t if (date && that._view.name == \"month\") {\n\t disabledDate = that.options.disableDates(date);\n\t }\n\t that._cellsBySelector(that._isMultipleSelection() ? CELLSELECTOR: \"td:not(.\" + OTHERMONTH + \")\").removeClass(className);\n\t cell = that._cellByDate(value, that.options.selectable == \"multiple\" ? CELLSELECTOR: \"td:not(.\" + OTHERMONTH + \")\")\n\t .attr(ARIA_SELECTED, true);\n\n\t if (className === FOCUSED && !that._active && that.options.focusOnNav !== false || disabledDate) {\n\t className = \"\";\n\t }\n\n\t cell.addClass(className);\n\n\t if (cell[0]) {\n\t that._cell = cell;\n\t }\n\n\t if (id) {\n\t cell.attr(ID, id);\n\t that._table[0].removeAttribute(\"aria-activedescendant\");\n\t that._table.attr(\"aria-activedescendant\", id);\n\t }\n\t },\n\n\t _bindTable: function (table) {\n\t table\n\t .on(FOCUS_WITH_NS, this._addClassProxy)\n\t .on(BLUR, this._removeClassProxy);\n\t },\n\n\t _click: function(link) {\n\t var that = this,\n\t options = that.options,\n\t currentValue = new Date(+that._current),\n\t value = toDateObject(link);\n\n\t adjustDST(value, 0);\n\n\t if (that._view.name == \"month\" && that.options.disableDates(value)) {\n\t value = that._value;\n\t }\n\n\t that._view.setDate(currentValue, value);\n\n\t that.navigateDown(restrictValue(currentValue, options.min, options.max));\n\t },\n\n\t _focus: function(value) {\n\t var that = this,\n\t view = that._view;\n\n\t if (view.compare(value, that._current) !== 0) {\n\t that.navigate(value);\n\t } else {\n\t that._current = value;\n\t that._class(FOCUSED, value);\n\t }\n\t },\n\n\t _focusView: function(active, table) {\n\t if (active) {\n\t this.focus(table);\n\t }\n\t },\n\n\t _viewWrapper: function() {\n\t var that = this;\n\t var element = that.element;\n\t var viewWrapper = element.children(\".k-calendar-view\");\n\n\t if (!viewWrapper[0]) {\n\t viewWrapper = $(\"
    \").insertAfter(element.find(HEADERSELECTOR));\n\t }\n\t },\n\n\t _footer: function(template) {\n\t var that = this,\n\t today = getToday(),\n\t element = that.element,\n\t footer = element.find(\".k-footer\");\n\n\t if (!template) {\n\t that._toggle(false);\n\t footer.hide();\n\t return;\n\t }\n\n\t if (!footer[0]) {\n\t footer = $('
    ').appendTo(element);\n\t }\n\n\t that._today = footer.show()\n\t .find(\".k-link\")\n\t .html(template(today))\n\t .attr(\"title\", kendo.toString(today, \"D\", that.options.culture));\n\n\t that._toggle();\n\t },\n\n\t _header: function() {\n\t var that = this,\n\t element = that.element,\n\t linksSelector = that.options.linksSelector;\n\n\t if (!element.find(HEADERSELECTOR)[0]) {\n\t element.html(kendo.template(that.options.header.template)(that.options));\n\t }\n\n\t element.find(linksSelector)\n\t .on(MOUSEENTER_WITH_NS + \" \" + MOUSELEAVE + \" \" + FOCUS_WITH_NS + \" \" + BLUR, mousetoggle)\n\t .on(CLICK + \" touchend\" + ns, function() { return false; } );\n\n\t that._title = element.find('[' + kendo.attr(\"action\") + '=\"nav-up\"]').on(CLICK + \" touchend\" + ns, function () {\n\t that._active = that.options.focusOnNav !== false;\n\t that.navigateUp();\n\t });\n\t that[PREVARROW] = element.find('[' + kendo.attr(\"action\") + '=\"prev\"]').on(CLICK + \" touchend\" + ns, function () {\n\t that._active = that.options.focusOnNav !== false;\n\t that.navigateToPast();\n\t });\n\t that[NEXTARROW] = element.find('[' + kendo.attr(\"action\") + '=\"next\"]').on(CLICK + \" touchend\" + ns, function () {\n\t that._active = that.options.focusOnNav !== false;\n\t that.navigateToFuture();\n\t });\n\t element.find('[' + kendo.attr(\"action\") + '=\"today\"]').on(CLICK + \" touchend\" + ns, proxy(that._todayClick, that));\n\n\t },\n\n\t _navigate: function(arrow, modifier) {\n\t var that = this,\n\t index = that._index + 1,\n\t currentValue = new DATE(+that._current);\n\n\t if (that._isMultipleSelection()) {\n\t var firstDayCurrentMonth = that._table.find(\"td:not(.k-other-month):not(.k-out-of-range)\").has(\".k-link\").first();\n\t currentValue = toDateObject(firstDayCurrentMonth.find(\"a\"));\n\t that._current = new Date(+currentValue);\n\t }\n\n\t arrow = that[arrow];\n\n\t if (!arrow.hasClass(DISABLED)) {\n\t if (index > 3) {\n\t currentValue.setFullYear(currentValue.getFullYear() + 100 * modifier);\n\t } else {\n\t calendar.views[index].setDate(currentValue, modifier);\n\t }\n\n\t that.navigate(currentValue);\n\t }\n\t },\n\n\t _option: function(option, value) {\n\t var that = this,\n\t options = that.options,\n\t currentValue = that._value || that._current,\n\t isBigger;\n\n\t if (value === undefined) {\n\t return options[option];\n\t }\n\n\t value = parse(value, options.format, options.culture);\n\n\t if (!value) {\n\t return;\n\t }\n\n\t options[option] = new DATE(+value);\n\n\t if (option === MIN) {\n\t isBigger = value > currentValue;\n\t } else {\n\t isBigger = currentValue > value;\n\t }\n\n\t if (isBigger || isEqualMonth(currentValue, value)) {\n\t if (isBigger) {\n\t that._value = null;\n\t }\n\t that._changeView = true;\n\t }\n\n\t if (!that._changeView) {\n\t that._changeView = !!(options.month.content || options.month.empty);\n\t }\n\n\t that.navigate(that._value);\n\n\t that._toggle();\n\t },\n\n\t _toggle: function(toggle) {\n\t var that = this,\n\t options = that.options,\n\t isTodayDisabled = that.options.disableDates(getToday()),\n\t link = that._today;\n\n\t if (toggle === undefined) {\n\t toggle = isInRange(getToday(), options.min, options.max);\n\t }\n\n\t if (link) {\n\t link.off(CLICK);\n\n\t if (toggle && !isTodayDisabled) {\n\t link.addClass(TODAY)\n\t .removeClass(DISABLED)\n\t .on(CLICK, proxy(that._todayClick, that));\n\t } else {\n\t link.removeClass(TODAY)\n\t .addClass(DISABLED)\n\t .on(CLICK, prevent);\n\t }\n\t }\n\t },\n\n\t _todayClick: function(e) {\n\t var that = this,\n\t depth = views[that.options.depth],\n\t disabled = that.options.disableDates,\n\t today = getToday();\n\n\t e.preventDefault();\n\n\t if (disabled(today)) {\n\t return;\n\t }\n\n\t if (that._view.compare(that._current, today) === 0 && that._index == depth) {\n\t that._changeView = false;\n\t }\n\n\t if(that._isMultipleSelection()) {\n\t that._selectDates = [today];\n\t that.selectable._lastActive = null;\n\t }\n\n\t that._value = today;\n\t that.navigate(today, depth);\n\n\t that.trigger(CHANGE);\n\t },\n\n\t _templates: function() {\n\t var that = this,\n\t options = that.options,\n\t footer = options.footer,\n\t month = options.month,\n\t content = month.content,\n\t weekNumber = month.weekNumber,\n\t empty = month.empty,\n\t footerTemplate = '#= kendo.toString(data,\"D\",\"' + options.culture +'\") #';\n\n\t that.month = {\n\t content: template('' + (content || \"#=data.value#\") + '', { useWithBlock: !!content }),\n\t empty: template('
    \", { useWithBlock: !!empty }),\n\t weekNumber: template('\", { useWithBlock: !!weekNumber })\n\t };\n\n\t if (footer && footer !== true) {\n\t footerTemplate = footer;\n\t }\n\n\t that.footer = footer !== false ? template(footerTemplate, { useWithBlock: false }) : null;\n\t }\n\t });\n\n\t ui.plugin(Calendar);\n\n\t var calendar = {\n\t firstDayOfMonth: function (date) {\n\t return createDate(\n\t date.getFullYear(),\n\t date.getMonth(),\n\t 1\n\t );\n\t },\n\n\t firstVisibleDay: function (date, calendarInfo) {\n\t calendarInfo = calendarInfo || kendo.culture().calendar;\n\n\t var firstDay = calendarInfo.firstDay,\n\t firstVisibleDay = new DATE(date.getFullYear(), date.getMonth(), 1, date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());\n\t firstVisibleDay.setFullYear(date.getFullYear());\n\n\t while (firstVisibleDay.getDay() != firstDay) {\n\t calendar.setTime(firstVisibleDay, -1 * MS_PER_DAY);\n\t }\n\n\t return firstVisibleDay;\n\t },\n\n\t setTime: function (date, time) {\n\t var tzOffsetBefore = date.getTimezoneOffset(),\n\t resultDATE = new DATE(date.getTime() + time),\n\t tzOffsetDiff = resultDATE.getTimezoneOffset() - tzOffsetBefore;\n\n\t date.setTime(resultDATE.getTime() + tzOffsetDiff * MS_PER_MINUTE);\n\t },\n\t views: [{\n\t name: MONTH,\n\t title: function(date, min, max, culture) {\n\t return getCalendarInfo(culture).months.names[date.getMonth()] + \" \" + date.getFullYear();\n\t },\n\t content: function(options) {\n\t var that = this,\n\t idx = 0,\n\t min = options.min,\n\t max = options.max,\n\t date = options.date,\n\t dates = options.dates,\n\t format = options.format,\n\t culture = options.culture,\n\t navigateUrl = options.url,\n\t showHeader = options.showHeader,\n\t otherMonth = options.otherMonth,\n\t isWeekColumnVisible = options.isWeekColumnVisible,\n\t hasUrl = navigateUrl && dates[0],\n\t currentCalendar = getCalendarInfo(culture),\n\t firstDayIdx = currentCalendar.firstDay,\n\t days = currentCalendar.days,\n\t names = shiftArray(days.names, firstDayIdx),\n\t shortNames = shiftArray(days.namesShort, firstDayIdx),\n\t start = calendar.firstVisibleDay(date, currentCalendar),\n\t firstDayOfMonth = that.first(date),\n\t lastDayOfMonth = that.last(date),\n\t toDateString = that.toDateString,\n\t today = getToday(),\n\t contentClasses = options.contentClasses,\n\t html = '
    #:data#
     #= data.weekNumber #' + (empty || \" \") + \"' + (weekNumber || \"#= data.weekNumber #\") + \"
    ';\n\t if (showHeader) {\n\t html += '';\n\t } else {\n\t html += '';\n\t }\n\t if (isWeekColumnVisible) {\n\t html += '';\n\t }\n\n\t for (; idx < 7; idx++) {\n\t html += '';\n\t }\n\n\t adjustDST(today, 0);\n\t today = +today;\n\n\t return view({\n\t cells: 42,\n\t perRow: 7,\n\t html: html += '',\n\t start: start,\n\t isWeekColumnVisible: isWeekColumnVisible,\n\t weekNumber: options.weekNumber,\n\t min: createDate(min.getFullYear(), min.getMonth(), min.getDate()),\n\t max: createDate(max.getFullYear(), max.getMonth(), max.getDate()),\n\t otherMonth : otherMonth,\n\t content: options.content,\n\t lastDayOfMonth : lastDayOfMonth,\n\t empty: options.empty,\n\t setter: that.setDate,\n\t disableDates: options.disableDates,\n\t build: function(date, idx, disableDates) {\n\t var cssClass = [],\n\t day = date.getDay(),\n\t linkClass = \"\",\n\t url = \"#\";\n\n\t if (date < firstDayOfMonth || date > lastDayOfMonth) {\n\t cssClass.push(OTHERMONTH);\n\t }\n\n\t if (disableDates(date)) {\n\t cssClass.push(DISABLED);\n\t }\n\n\t if (+date === today) {\n\t cssClass.push(\"k-today\");\n\t }\n\n\t if (day === 0 || day === 6) {\n\t cssClass.push(\"k-weekend\");\n\t }\n\n\t if (hasUrl && inArray(+date, dates)) {\n\t url = navigateUrl.replace(\"{0}\", kendo.toString(date, format, culture));\n\t linkClass = \" k-action-link\";\n\t }\n\n\t return {\n\t date: date,\n\t dates: dates,\n\t ns: kendo.ns,\n\t title: kendo.toString(date, \"D\", culture),\n\t value: date.getDate(),\n\t dateString: toDateString(date),\n\t cssClass: cssClass[0] ? ' class=\"' + cssClass.join(\" \") + '\"' : \"\",\n\t linkClass: linkClass,\n\t url: url\n\t };\n\t },\n\t weekNumberBuild: function(date) {\n\t return {\n\t weekNumber: weekInYear(date, kendo.culture().calendar.firstDay),\n\t currentDate: date\n\t };\n\t }\n\t });\n\t },\n\t first: function(date) {\n\t return calendar.firstDayOfMonth(date);\n\t },\n\t last: function(date) {\n\t var last = createDate(date.getFullYear(), date.getMonth() + 1, 0),\n\t first = calendar.firstDayOfMonth(date),\n\t timeOffset = Math.abs(last.getTimezoneOffset() - first.getTimezoneOffset());\n\n\t if (timeOffset) {\n\t last.setHours(first.getHours() + (timeOffset / 60));\n\t }\n\n\t return last;\n\t },\n\t compare: function(date1, date2) {\n\t var result,\n\t month1 = date1.getMonth(),\n\t year1 = date1.getFullYear(),\n\t month2 = date2.getMonth(),\n\t year2 = date2.getFullYear();\n\n\t if (year1 > year2) {\n\t result = 1;\n\t } else if (year1 < year2) {\n\t result = -1;\n\t } else {\n\t result = month1 == month2 ? 0 : month1 > month2 ? 1 : -1;\n\t }\n\n\t return result;\n\t },\n\t setDate: function(date, value) {\n\t var hours = date.getHours();\n\t if (value instanceof DATE) {\n\t date.setFullYear(value.getFullYear(), value.getMonth(), value.getDate());\n\t } else {\n\t calendar.setTime(date, value * MS_PER_DAY);\n\t }\n\t adjustDST(date, hours);\n\t },\n\t toDateString: function(date) {\n\t return date.getFullYear() + \"/\" + date.getMonth() + \"/\" + date.getDate();\n\t }\n\t },\n\t {\n\t name: \"year\",\n\t title: function(date) {\n\t return date.getFullYear();\n\t },\n\t content: function(options) {\n\t var namesAbbr = getCalendarInfo(options.culture).months.namesAbbr,\n\t toDateString = this.toDateString,\n\t min = options.min,\n\t max = options.max,\n\t html = \"\";\n\n\t if (options.showHeader) {\n\t html += '
    ' + this.title(date, min, max, culture) + '
    ' + options.messages.weekColumnHeader + '' + shortNames[idx] + '
    ';\n\t }\n\n\t return view({\n\t min: createDate(min.getFullYear(), min.getMonth(), 1),\n\t max: createDate(max.getFullYear(), max.getMonth(), 1),\n\t start: createDate(options.date.getFullYear(), 0, 1),\n\t html: html,\n\t setter: this.setDate,\n\t build: function(date) {\n\t return {\n\t value: namesAbbr[date.getMonth()],\n\t ns: kendo.ns,\n\t dateString: toDateString(date),\n\t cssClass: \"\"\n\t };\n\t }\n\t });\n\t },\n\t first: function(date) {\n\t return createDate(date.getFullYear(), 0, date.getDate());\n\t },\n\t last: function(date) {\n\t return createDate(date.getFullYear(), 11, date.getDate());\n\t },\n\t compare: function(date1, date2){\n\t return compare(date1, date2);\n\t },\n\t setDate: function(date, value) {\n\t var month,\n\t hours = date.getHours();\n\n\t if (value instanceof DATE) {\n\t month = value.getMonth();\n\n\t date.setFullYear(value.getFullYear(), month, date.getDate());\n\n\t if (month !== date.getMonth()) {\n\t date.setDate(0);\n\t }\n\t } else {\n\t month = date.getMonth() + value;\n\n\t date.setMonth(month);\n\n\t if (month > 11) {\n\t month -= 12;\n\t }\n\n\t if (month > 0 && date.getMonth() != month) {\n\t date.setDate(0);\n\t }\n\t }\n\n\t adjustDST(date, hours);\n\t },\n\t toDateString: function(date) {\n\t return date.getFullYear() + \"/\" + date.getMonth() + \"/1\";\n\t }\n\t },\n\t {\n\t name: \"decade\",\n\t title: function(date, min, max) {\n\t return title(date, min, max, 10);\n\t },\n\t content: function(options) {\n\t var year = options.date.getFullYear(),\n\t toDateString = this.toDateString,\n\t html = \"\";\n\n\t if (options.showHeader) {\n\t html += '
    ';\n\t html += this.title(options.date);\n\t html += '
    ';\n\t }\n\n\t return view({\n\t start: createDate(year - year % 10 - 1, 0, 1),\n\t min: createDate(options.min.getFullYear(), 0, 1),\n\t max: createDate(options.max.getFullYear(), 0, 1),\n\t otherMonth : options.otherMonth,\n\t html : html,\n\t setter: this.setDate,\n\t build: function(date, idx) {\n\t return {\n\t value: date.getFullYear(),\n\t ns: kendo.ns,\n\t dateString: toDateString(date),\n\t cssClass: idx === 0 || idx == 11 ? OTHERMONTHCLASS : \"\"\n\t };\n\t }\n\t });\n\t },\n\t first: function(date) {\n\t var year = date.getFullYear();\n\t return createDate(year - year % 10, date.getMonth(), date.getDate());\n\t },\n\t last: function(date) {\n\t var year = date.getFullYear();\n\t return createDate(year - year % 10 + 9, date.getMonth(), date.getDate());\n\t },\n\t compare: function(date1, date2) {\n\t return compare(date1, date2, 10);\n\t },\n\t setDate: function(date, value) {\n\t setDate(date, value, 1);\n\t },\n\t toDateString: function(date) {\n\t return date.getFullYear() + \"/0/1\";\n\t }\n\t },\n\t {\n\t name: CENTURY,\n\t title: function(date, min, max) {\n\t return title(date, min, max, 100);\n\t },\n\t content: function(options) {\n\t var year = options.date.getFullYear(),\n\t min = options.min.getFullYear(),\n\t max = options.max.getFullYear(),\n\t toDateString = this.toDateString,\n\t minYear = min,\n\t maxYear = max,\n\t html = \"\";\n\n\t minYear = minYear - minYear % 10;\n\t maxYear = maxYear - maxYear % 10;\n\n\t if (maxYear - minYear < 10) {\n\t maxYear = minYear + 9;\n\t }\n\n\t if (options.showHeader) {\n\t html += '
    ';\n\t html += this.title(options.date, options.min, options.max);\n\t html += '
    ';\n\t }\n\n\t return view({\n\t start: createDate(year - year % 100 - 10, 0, 1),\n\t min: createDate(minYear, 0, 1),\n\t max: createDate(maxYear, 0, 1),\n\t otherMonth : options.otherMonth,\n\t html : html,\n\t setter: this.setDate,\n\t build: function(date, idx) {\n\t var start = date.getFullYear(),\n\t end = start + 9;\n\n\t if (start < min) {\n\t start = min;\n\t }\n\n\t if (end > max) {\n\t end = max;\n\t }\n\n\t return {\n\t ns: kendo.ns,\n\t value: start + \" - \" + end,\n\t dateString: toDateString(date),\n\t cssClass: idx === 0 || idx == 11 ? OTHERMONTHCLASS : \"\"\n\t };\n\t }\n\t });\n\t },\n\t first: function(date) {\n\t var year = date.getFullYear();\n\t return createDate(year - year % 100, date.getMonth(), date.getDate());\n\t },\n\t last: function(date) {\n\t var year = date.getFullYear();\n\t return createDate(year - year % 100 + 99, date.getMonth(), date.getDate());\n\t },\n\t compare: function(date1, date2) {\n\t return compare(date1, date2, 100);\n\t },\n\t setDate: function(date, value) {\n\t setDate(date, value, 10);\n\t },\n\t toDateString: function(date) {\n\t var year = date.getFullYear();\n\t return (year - year % 10) + \"/0/1\";\n\t }\n\t }]\n\t };\n\n\t function title(date, min, max, modular) {\n\t var start = date.getFullYear(),\n\t minYear = min.getFullYear(),\n\t maxYear = max.getFullYear(),\n\t end;\n\n\t start = start - start % modular;\n\t end = start + (modular - 1);\n\n\t if (start < minYear) {\n\t start = minYear;\n\t }\n\t if (end > maxYear) {\n\t end = maxYear;\n\t }\n\n\t return start + \"-\" + end;\n\t }\n\n\t function view(options) {\n\t var idx = 0,\n\t data,\n\t min = options.min,\n\t max = options.max,\n\t start = options.start,\n\t setter = options.setter,\n\t build = options.build,\n\t weekNumberBuild = options.weekNumberBuild,\n\t length = options.cells || 12,\n\t isWeekColumnVisible = options.isWeekColumnVisible,\n\t cellsPerRow = options.perRow || 4,\n\t otherMonth = options.otherMonth,\n\t lastDayOfMonth = options.lastDayOfMonth,\n\t weekNumber = options.weekNumber || weekNumberTemplate,\n\t content = options.content || cellTemplate,\n\t empty = options.empty || emptyCellTemplate,\n\t otherMonthTemplate = options.otherMonthCellTemplate || otherMonthCellTemplate,\n\t html = options.html || '
    ';\n\t html += this.title(options.date, options.min, options.max);\n\t html += '
    ';\n\t if(isWeekColumnVisible) {\n\t html += weekNumber(weekNumberBuild(start));\n\t }\n\n\n\t for(; idx < length; idx++) {\n\t if (idx > 0 && idx % cellsPerRow === 0) {\n\t html += '';\n\t if (isWeekColumnVisible) {\n\t html += otherMonth || (+start <= +lastDayOfMonth) ? weekNumber(weekNumberBuild(start)) : weekNumber({ weekNumber : \" \"});\n\t }\n\t }\n\n\t start = createDate(start.getFullYear(), start.getMonth(), start.getDate());\n\t adjustDST(start, 0);\n\n\t data = build(start, idx, options.disableDates);\n\n\t html += (data.cssClass.indexOf(OTHERMONTH) !== -1 && !otherMonth) ? otherMonthTemplate(data) : isInRange(start, min, max) ? content(data) : empty(data);\n\n\t setter(start, 1);\n\t }\n\n\t return html + \"
    \";\n\t }\n\n\t function compare(date1, date2, modifier) {\n\t var year1 = date1.getFullYear(),\n\t start = date2.getFullYear(),\n\t end = start,\n\t result = 0;\n\n\t if (modifier) {\n\t start = start - start % modifier;\n\t end = start - start % modifier + modifier - 1;\n\t }\n\n\t if (year1 > end) {\n\t result = 1;\n\t } else if (year1 < start) {\n\t result = -1;\n\t }\n\n\t return result;\n\t }\n\n\t function getToday() {\n\t var today = new DATE();\n\t return new DATE(today.getFullYear(), today.getMonth(), today.getDate());\n\t }\n\n\t function restrictValue (value, min, max) {\n\t var today = getToday();\n\n\t if (value) {\n\t today = new DATE(+value);\n\t }\n\n\t if (min > today) {\n\t today = new DATE(+min);\n\t } else if (max < today) {\n\t today = new DATE(+max);\n\t }\n\t return today;\n\t }\n\n\t function isInRange(date, min, max) {\n\t return +date >= +min && +date <= +max;\n\t }\n\n\t function shiftArray(array, idx) {\n\t return array.slice(idx).concat(array.slice(0, idx));\n\t }\n\n\t function setDate(date, value, multiplier) {\n\t value = value instanceof DATE ? value.getFullYear() : date.getFullYear() + multiplier * value;\n\t date.setFullYear(value);\n\t }\n\n\t function daysBetweenTwoDates(startDate, endDate) {\n\t if(+endDate < +startDate) {\n\t var temp = +startDate;\n\t calendar.views[0].setDate(startDate, endDate);\n\t calendar.views[0].setDate(endDate, new Date(temp));\n\t }\n\t var fromDateUTC = Date.UTC(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());\n\t var endDateUTC = Date.UTC(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());\n\n\t return Math.ceil((+endDateUTC - +fromDateUTC) / kendo.date.MS_PER_DAY);\n\t }\n\n\t function addDaysToArray(array, numberOfDays, fromDate, disableDates) {\n\t for(var i = 0; i <= numberOfDays; i++) {\n\t var nextDay = new Date(fromDate.getTime());\n\t nextDay = new Date(nextDay.setDate(nextDay.getDate() + i));\n\t if(!disableDates(nextDay)) {\n\t array.push(nextDay);\n\t }\n\t }\n\t }\n\n\t function mousetoggle(e) {\n\t var disabled = $(this).hasClass(\"k-state-disabled\");\n\n\t if (!disabled) {\n\t $(this).toggleClass(HOVER, MOUSEENTER.indexOf(e.type) > -1 || e.type == FOCUS);\n\t }\n\t }\n\n\t function prevent (e) {\n\t e.preventDefault();\n\t }\n\n\t // creates date with full year\n\t function createDate(year, month, date) {\n\t var dateObject = new DATE(year, month, date);\n\t dateObject.setFullYear(year, month, date);\n\t return dateObject;\n\t }\n\n\t function getCalendarInfo(culture) {\n\t return getCulture(culture).calendars.standard;\n\t }\n\n\t function normalize(options) {\n\t var start = views[options.start],\n\t depth = views[options.depth],\n\t culture = getCulture(options.culture);\n\n\t options.format = extractFormat(options.format || culture.calendars.standard.patterns.d);\n\n\t if (isNaN(start)) {\n\t start = 0;\n\t options.start = MONTH;\n\t }\n\n\t if (depth === undefined || depth > start) {\n\t options.depth = MONTH;\n\t }\n\n\t if (options.dates === null) {\n\t options.dates = [];\n\t }\n\t }\n\n\t function makeUnselectable(element) {\n\t if (isIE8) {\n\t element.find(\"*\").attr(\"unselectable\", \"on\");\n\t }\n\t }\n\n\t function addClassToViewContainer(element, currentView) {\n\t element.addClass(\"k-\" + currentView);\n\t }\n\n\t function inArray(date, dates) {\n\t for(var i = 0, length = dates.length; i < length; i++) {\n\t if (date === +dates[i]) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t }\n\n\t function isEqualDatePart(value1, value2) {\n\t if (value1) {\n\t return value1.getFullYear() === value2.getFullYear() &&\n\t value1.getMonth() === value2.getMonth() &&\n\t value1.getDate() === value2.getDate();\n\t }\n\n\t return false;\n\t }\n\n\t function isEqualMonth(value1, value2) {\n\t if (value1) {\n\t return value1.getFullYear() === value2.getFullYear() &&\n\t value1.getMonth() === value2.getMonth();\n\t }\n\n\t return false;\n\t }\n\n\n\t function getDisabledExpr(option) {\n\t if (kendo.isFunction(option)) {\n\t return option;\n\t }\n\n\t if ($.isArray(option)) {\n\t return createDisabledExpr(option);\n\t }\n\t return $.noop;\n\t }\n\n\t function convertDatesArray(dates) {\n\t var result = [];\n\t for (var i = 0; i < dates.length; i++) {\n\t result.push(dates[i].setHours(0, 0, 0, 0));\n\t }\n\t return result;\n\t }\n\n\t function createDisabledExpr(dates) {\n\t var body, callback,\n\t disabledDates = [],\n\t days = [\"su\", \"mo\", \"tu\", \"we\", \"th\", \"fr\", \"sa\"],\n\t searchExpression = \"if (found) {\"+\n\t \" return true \" +\n\t \"} else {\" +\n\t \"return false\" +\n\t \"}\";\n\n\t if (dates[0] instanceof DATE) {\n\t disabledDates = convertDatesArray(dates);\n\t body = \"var found = date && window.kendo.jQuery.inArray(date.setHours(0, 0, 0, 0),[\"+ disabledDates +\"]) > -1;\" + searchExpression;\n\t } else {\n\t for (var i = 0; i < dates.length; i++) {\n\t var day = dates[i].slice(0,2).toLowerCase();\n\t var index = $.inArray(day, days);\n\t if (index > -1) {\n\t disabledDates.push(index);\n\t }\n\t }\n\t body = \"var found = date && window.kendo.jQuery.inArray(date.getDay(),[\"+ disabledDates +\"]) > -1;\" + searchExpression;\n\t }\n\n\t callback = new Function(\"date\", body); //jshint ignore:line\n\n\t return callback;\n\t }\n\n\t function isEqualDate(oldValue, newValue) {\n\t if (oldValue instanceof Date && newValue instanceof Date) {\n\t oldValue = oldValue.getTime();\n\t newValue = newValue.getTime();\n\t }\n\n\t return oldValue === newValue;\n\t }\n\n\t function toDateObject(link) {\n\t var value = $(link).attr(kendo.attr(VALUE)).split(\"/\");\n\t //Safari cannot create correctly date from \"1/1/2090\"\n\t value = createDate(value[0], value[1], value[2]);\n\n\t return value;\n\t }\n\n\t calendar.isEqualDatePart = isEqualDatePart;\n\t calendar.isEqualDate = isEqualDate;\n\t calendar.makeUnselectable = makeUnselectable;\n\t calendar.restrictValue = restrictValue;\n\t calendar.isInRange = isInRange;\n\t calendar.addClassToViewContainer = addClassToViewContainer;\n\t calendar.normalize = normalize;\n\t calendar.viewsEnum = views;\n\t calendar.disabled = getDisabledExpr;\n\t calendar.toDateObject = toDateObject;\n\t calendar.getToday = getToday;\n\t calendar.createDate = createDate;\n\n\t kendo.calendar = calendar;\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1046:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.selectable\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1051);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1051:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/***********************************************************************\n\t * WARNING: this file is auto-generated. If you change it directly,\n\t * your modifications will eventually be lost. The source code is in\n\t * `kendo-drawing` repository, you should make your changes there and\n\t * run `src-modules/sync.sh` in this repository.\n\t */\n\t(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t var __meta__ = { // jshint ignore:line\n\t id: \"color\",\n\t name: \"Color utils\",\n\t category: \"framework\",\n\t advanced: true,\n\t description: \"Color utilities used across components\",\n\t depends: [ \"core\" ]\n\t };\n\n\t/*jshint eqnull:true */\n\n\twindow.kendo = window.kendo || {};\n\n\tvar Class = kendo.Class;\n\tvar support = kendo.support;\n\n\tvar namedColors = {\n\t aliceblue: \"f0f8ff\", antiquewhite: \"faebd7\", aqua: \"00ffff\",\n\t aquamarine: \"7fffd4\", azure: \"f0ffff\", beige: \"f5f5dc\",\n\t bisque: \"ffe4c4\", black: \"000000\", blanchedalmond: \"ffebcd\",\n\t blue: \"0000ff\", blueviolet: \"8a2be2\", brown: \"a52a2a\",\n\t burlywood: \"deb887\", cadetblue: \"5f9ea0\", chartreuse: \"7fff00\",\n\t chocolate: \"d2691e\", coral: \"ff7f50\", cornflowerblue: \"6495ed\",\n\t cornsilk: \"fff8dc\", crimson: \"dc143c\", cyan: \"00ffff\",\n\t darkblue: \"00008b\", darkcyan: \"008b8b\", darkgoldenrod: \"b8860b\",\n\t darkgray: \"a9a9a9\", darkgrey: \"a9a9a9\", darkgreen: \"006400\",\n\t darkkhaki: \"bdb76b\", darkmagenta: \"8b008b\", darkolivegreen: \"556b2f\",\n\t darkorange: \"ff8c00\", darkorchid: \"9932cc\", darkred: \"8b0000\",\n\t darksalmon: \"e9967a\", darkseagreen: \"8fbc8f\", darkslateblue: \"483d8b\",\n\t darkslategray: \"2f4f4f\", darkslategrey: \"2f4f4f\", darkturquoise: \"00ced1\",\n\t darkviolet: \"9400d3\", deeppink: \"ff1493\", deepskyblue: \"00bfff\",\n\t dimgray: \"696969\", dimgrey: \"696969\", dodgerblue: \"1e90ff\",\n\t firebrick: \"b22222\", floralwhite: \"fffaf0\", forestgreen: \"228b22\",\n\t fuchsia: \"ff00ff\", gainsboro: \"dcdcdc\", ghostwhite: \"f8f8ff\",\n\t gold: \"ffd700\", goldenrod: \"daa520\", gray: \"808080\",\n\t grey: \"808080\", green: \"008000\", greenyellow: \"adff2f\",\n\t honeydew: \"f0fff0\", hotpink: \"ff69b4\", indianred: \"cd5c5c\",\n\t indigo: \"4b0082\", ivory: \"fffff0\", khaki: \"f0e68c\",\n\t lavender: \"e6e6fa\", lavenderblush: \"fff0f5\", lawngreen: \"7cfc00\",\n\t lemonchiffon: \"fffacd\", lightblue: \"add8e6\", lightcoral: \"f08080\",\n\t lightcyan: \"e0ffff\", lightgoldenrodyellow: \"fafad2\", lightgray: \"d3d3d3\",\n\t lightgrey: \"d3d3d3\", lightgreen: \"90ee90\", lightpink: \"ffb6c1\",\n\t lightsalmon: \"ffa07a\", lightseagreen: \"20b2aa\", lightskyblue: \"87cefa\",\n\t lightslategray: \"778899\", lightslategrey: \"778899\", lightsteelblue: \"b0c4de\",\n\t lightyellow: \"ffffe0\", lime: \"00ff00\", limegreen: \"32cd32\",\n\t linen: \"faf0e6\", magenta: \"ff00ff\", maroon: \"800000\",\n\t mediumaquamarine: \"66cdaa\", mediumblue: \"0000cd\", mediumorchid: \"ba55d3\",\n\t mediumpurple: \"9370d8\", mediumseagreen: \"3cb371\", mediumslateblue: \"7b68ee\",\n\t mediumspringgreen: \"00fa9a\", mediumturquoise: \"48d1cc\", mediumvioletred: \"c71585\",\n\t midnightblue: \"191970\", mintcream: \"f5fffa\", mistyrose: \"ffe4e1\",\n\t moccasin: \"ffe4b5\", navajowhite: \"ffdead\", navy: \"000080\",\n\t oldlace: \"fdf5e6\", olive: \"808000\", olivedrab: \"6b8e23\",\n\t orange: \"ffa500\", orangered: \"ff4500\", orchid: \"da70d6\",\n\t palegoldenrod: \"eee8aa\", palegreen: \"98fb98\", paleturquoise: \"afeeee\",\n\t palevioletred: \"d87093\", papayawhip: \"ffefd5\", peachpuff: \"ffdab9\",\n\t peru: \"cd853f\", pink: \"ffc0cb\", plum: \"dda0dd\",\n\t powderblue: \"b0e0e6\", purple: \"800080\", red: \"ff0000\",\n\t rosybrown: \"bc8f8f\", royalblue: \"4169e1\", saddlebrown: \"8b4513\",\n\t salmon: \"fa8072\", sandybrown: \"f4a460\", seagreen: \"2e8b57\",\n\t seashell: \"fff5ee\", sienna: \"a0522d\", silver: \"c0c0c0\",\n\t skyblue: \"87ceeb\", slateblue: \"6a5acd\", slategray: \"708090\",\n\t slategrey: \"708090\", snow: \"fffafa\", springgreen: \"00ff7f\",\n\t steelblue: \"4682b4\", tan: \"d2b48c\", teal: \"008080\",\n\t thistle: \"d8bfd8\", tomato: \"ff6347\", turquoise: \"40e0d0\",\n\t violet: \"ee82ee\", wheat: \"f5deb3\", white: \"ffffff\",\n\t whitesmoke: \"f5f5f5\", yellow: \"ffff00\", yellowgreen: \"9acd32\"\n\t};\n\n\tvar browser = support.browser;\n\n\tvar matchNamedColor = function (color) {\n\t var colorNames = Object.keys(namedColors);\n\t colorNames.push(\"transparent\");\n\n\t var regexp = new RegExp(\"^(\" + colorNames.join(\"|\") + \")(\\\\W|$)\", \"i\");\n\t matchNamedColor = function (color) { return regexp.exec(color); };\n\n\t return regexp.exec(color);\n\t};\n\n\tvar BaseColor = Class.extend({\n\t init: function() { },\n\n\t toHSV: function() { return this; },\n\n\t toRGB: function() { return this; },\n\n\t toHex: function() { return this.toBytes().toHex(); },\n\n\t toBytes: function() { return this; },\n\n\t toCss: function() { return \"#\" + this.toHex(); },\n\n\t toCssRgba: function() {\n\t var rgb = this.toBytes();\n\t return (\"rgba(\" + (rgb.r) + \", \" + (rgb.g) + \", \" + (rgb.b) + \", \" + (parseFloat((Number(this.a)).toFixed(3))) + \")\");\n\t },\n\n\t toDisplay: function() {\n\t if (browser.msie && browser.version < 9) {\n\t return this.toCss(); // no RGBA support; does it support any opacity in colors?\n\t }\n\t return this.toCssRgba();\n\t },\n\n\t equals: function(c) {\n\t return c === this || c !== null && this.toCssRgba() === parseColor(c).toCssRgba();\n\t },\n\n\t diff: function(other) {\n\t if (other === null) {\n\t return NaN;\n\t }\n\n\t var c1 = this.toBytes();\n\t var c2 = other.toBytes();\n\n\t return Math.sqrt(Math.pow((c1.r - c2.r) * 0.30, 2) +\n\t Math.pow((c1.g - c2.g) * 0.59, 2) +\n\t Math.pow((c1.b - c2.b) * 0.11, 2));\n\t },\n\n\t clone: function() {\n\t var c = this.toBytes();\n\t if (c === this) {\n\t c = new Bytes(c.r, c.g, c.b, c.a);\n\t }\n\n\t return c;\n\t }\n\t});\n\n\tvar RGB = BaseColor.extend({\n\t init: function(r, g, b, a) {\n\t BaseColor.fn.init.call(this);\n\n\t this.r = r;\n\t this.g = g;\n\t this.b = b;\n\t this.a = a;\n\t },\n\n\t toHSV: function() {\n\t var ref = this;\n\t var r = ref.r;\n\t var g = ref.g;\n\t var b = ref.b;\n\t var min = Math.min(r, g, b);\n\t var max = Math.max(r, g, b);\n\t var delta = max - min;\n\t var v = max;\n\t var h, s;\n\n\t if (delta === 0) {\n\t return new HSV(0, 0, v, this.a);\n\t }\n\n\t if (max !== 0) {\n\t s = delta / max;\n\t if (r === max) {\n\t h = (g - b) / delta;\n\t } else if (g === max) {\n\t h = 2 + (b - r) / delta;\n\t } else {\n\t h = 4 + (r - g) / delta;\n\t }\n\n\t h *= 60;\n\t if (h < 0) {\n\t h += 360;\n\t }\n\t } else {\n\t s = 0;\n\t h = -1;\n\t }\n\n\t return new HSV(h, s, v, this.a);\n\t },\n\n\t toHSL: function() {\n\t var ref = this;\n\t var r = ref.r;\n\t var g = ref.g;\n\t var b = ref.b;\n\t var max = Math.max(r, g, b);\n\t var min = Math.min(r, g, b);\n\t var h, s, l = (max + min) / 2;\n\n\t if (max === min) {\n\t h = s = 0;\n\t } else {\n\t var d = max - min;\n\t s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\t switch (max) {\n\t case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n\t case g: h = (b - r) / d + 2; break;\n\t case b: h = (r - g) / d + 4; break;\n\t default: break;\n\t }\n\t }\n\n\t return new HSL(h * 60, s * 100, l * 100, this.a);\n\t },\n\n\t toBytes: function() {\n\t return new Bytes(this.r * 255, this.g * 255, this.b * 255, this.a);\n\t }\n\t});\n\n\tvar Bytes = RGB.extend({\n\t init: function(r, g, b, a) {\n\t RGB.fn.init.call(this, Math.round(r), Math.round(g), Math.round(b), a);\n\t },\n\n\t toRGB: function() {\n\t return new RGB(this.r / 255, this.g / 255, this.b / 255, this.a);\n\t },\n\n\t toHSV: function() {\n\t return this.toRGB().toHSV();\n\t },\n\n\t toHSL: function() {\n\t return this.toRGB().toHSL();\n\t },\n\n\t toHex: function() {\n\t return hex(this.r, 2) + hex(this.g, 2) + hex(this.b, 2);\n\t },\n\n\t toBytes: function() {\n\t return this;\n\t }\n\t});\n\n\tfunction hex(n, width, pad) {\n\t if (pad === void 0) { pad = \"0\"; }\n\n\t var result = n.toString(16);\n\t while (width > result.length) {\n\t result = pad + result;\n\t }\n\n\t return result;\n\t}\n\n\tvar HSV = BaseColor.extend({\n\t init: function(h, s, v, a) {\n\t BaseColor.fn.init.call(this);\n\n\t this.h = h;\n\t this.s = s;\n\t this.v = v;\n\t this.a = a;\n\t },\n\n\t toRGB: function() {\n\t var ref = this;\n\t var h = ref.h;\n\t var s = ref.s;\n\t var v = ref.v;\n\t var r, g, b;\n\n\t if (s === 0) {\n\t r = g = b = v;\n\t } else {\n\t h /= 60;\n\n\t var i = Math.floor(h);\n\t var f = h - i;\n\t var p = v * (1 - s);\n\t var q = v * (1 - s * f);\n\t var t = v * (1 - s * (1 - f));\n\n\t switch (i) {\n\t case 0: r = v; g = t; b = p; break;\n\t case 1: r = q; g = v; b = p; break;\n\t case 2: r = p; g = v; b = t; break;\n\t case 3: r = p; g = q; b = v; break;\n\t case 4: r = t; g = p; b = v; break;\n\t default: r = v; g = p; b = q; break;\n\t }\n\t }\n\n\t return new RGB(r, g, b, this.a);\n\t },\n\n\t toHSL: function() {\n\t return this.toRGB().toHSL();\n\t },\n\n\t toBytes: function() {\n\t return this.toRGB().toBytes();\n\t }\n\t});\n\n\tvar HSL = BaseColor.extend({\n\t init: function(h, s, l, a) {\n\t BaseColor.fn.init.call(this);\n\n\t this.h = h;\n\t this.s = s;\n\t this.l = l;\n\t this.a = a;\n\t },\n\n\t toRGB: function() {\n\t var h = this.h / 360;\n\t var s = this.s / 100;\n\t var l = this.l / 100;\n\t var r, g, b;\n\n\t if (s === 0) {\n\t r = g = b = l; // achromatic\n\t } else {\n\t var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n\t var p = 2 * l - q;\n\t r = hue2rgb(p, q, h + 1 / 3);\n\t g = hue2rgb(p, q, h);\n\t b = hue2rgb(p, q, h - 1 / 3);\n\t }\n\n\t return new RGB(r, g, b, this.a);\n\t },\n\n\t toHSV: function() {\n\t return this.toRGB().toHSV();\n\t },\n\n\t toBytes: function() {\n\t return this.toRGB().toBytes();\n\t }\n\t});\n\n\tfunction hue2rgb(p, q, s) {\n\t var t = s;\n\n\t if (t < 0) {\n\t t += 1;\n\t }\n\n\t if (t > 1) {\n\t t -= 1;\n\t }\n\n\t if (t < 1 / 6) {\n\t return p + (q - p) * 6 * t;\n\t }\n\n\t if (t < 1 / 2) {\n\t return q;\n\t }\n\n\t if (t < 2 / 3) {\n\t return p + (q - p) * (2 / 3 - t) * 6;\n\t }\n\n\t return p;\n\t}\n\n\tfunction parseColor(value, safe) {\n\t var m, ret;\n\n\t if (value == null || value === \"none\") {\n\t return null;\n\t }\n\n\t if (value instanceof BaseColor) {\n\t return value;\n\t }\n\n\t var color = value.toLowerCase();\n\t if ((m = matchNamedColor(color))) {\n\t if (m[1] === \"transparent\") {\n\t color = new RGB(1, 1, 1, 0);\n\t } else {\n\t color = parseColor(namedColors[m[1]], safe);\n\t }\n\t color.match = [ m[1] ];\n\t return color;\n\t }\n\t if ((m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})\\b/i.exec(color))) {\n\t ret = new Bytes(parseInt(m[1], 16),\n\t parseInt(m[2], 16),\n\t parseInt(m[3], 16), 1);\n\t } else if ((m = /^#?([0-9a-f])([0-9a-f])([0-9a-f])\\b/i.exec(color))) {\n\t ret = new Bytes(parseInt(m[1] + m[1], 16),\n\t parseInt(m[2] + m[2], 16),\n\t parseInt(m[3] + m[3], 16), 1);\n\t } else if ((m = /^rgb\\(\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*\\)/.exec(color))) {\n\t ret = new Bytes(parseInt(m[1], 10),\n\t parseInt(m[2], 10),\n\t parseInt(m[3], 10), 1);\n\t } else if ((m = /^rgba\\(\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9.]+)\\s*\\)/.exec(color))) {\n\t ret = new Bytes(parseInt(m[1], 10),\n\t parseInt(m[2], 10),\n\t parseInt(m[3], 10), parseFloat(m[4]));\n\t } else if ((m = /^rgb\\(\\s*([0-9]*\\.?[0-9]+)%\\s*,\\s*([0-9]*\\.?[0-9]+)%\\s*,\\s*([0-9]*\\.?[0-9]+)%\\s*\\)/.exec(color))) {\n\t ret = new RGB(parseFloat(m[1]) / 100,\n\t parseFloat(m[2]) / 100,\n\t parseFloat(m[3]) / 100, 1);\n\t } else if ((m = /^rgba\\(\\s*([0-9]*\\.?[0-9]+)%\\s*,\\s*([0-9]*\\.?[0-9]+)%\\s*,\\s*([0-9]*\\.?[0-9]+)%\\s*,\\s*([0-9.]+)\\s*\\)/.exec(color))) {\n\t ret = new RGB(parseFloat(m[1]) / 100,\n\t parseFloat(m[2]) / 100,\n\t parseFloat(m[3]) / 100, parseFloat(m[4]));\n\t }\n\n\t if (ret) {\n\t ret.match = m;\n\t } else if (!safe) {\n\t throw new Error(\"Cannot parse color: \" + color);\n\t }\n\n\t return ret;\n\t}\n\n\tvar Color = Class.extend({\n\t init: function(value) {\n\t var this$1 = this;\n\n\t if (arguments.length === 1) {\n\t var formats = Color.formats;\n\t var resolvedColor = this.resolveColor(value);\n\n\t for (var idx = 0; idx < formats.length; idx++) {\n\t var formatRegex = formats[idx].re;\n\t var processor = formats[idx].process;\n\t var parts = formatRegex.exec(resolvedColor);\n\n\t if (parts) {\n\t var channels = processor(parts);\n\t this$1.r = channels[0];\n\t this$1.g = channels[1];\n\t this$1.b = channels[2];\n\t }\n\t }\n\t } else {\n\t this.r = arguments[0];\n\t this.g = arguments[1];\n\t this.b = arguments[2];\n\t }\n\n\t this.r = this.normalizeByte(this.r);\n\t this.g = this.normalizeByte(this.g);\n\t this.b = this.normalizeByte(this.b);\n\t },\n\n\t toHex: function() {\n\t var pad = this.padDigit;\n\t var r = this.r.toString(16);\n\t var g = this.g.toString(16);\n\t var b = this.b.toString(16);\n\n\t return \"#\" + pad(r) + pad(g) + pad(b);\n\t },\n\n\t resolveColor: function(value) {\n\t var color = value || \"black\";\n\n\t if (color.charAt(0) === \"#\") {\n\t color = color.substr(1, 6);\n\t }\n\n\t color = color.replace(/ /g, \"\");\n\t color = color.toLowerCase();\n\t color = Color.namedColors[color] || color;\n\n\t return color;\n\t },\n\n\t normalizeByte: function(value) {\n\t if (value < 0 || isNaN(value)) {\n\t return 0;\n\t }\n\n\t return value > 255 ? 255 : value;\n\t },\n\n\t padDigit: function(value) {\n\t return (value.length === 1) ? \"0\" + value : value;\n\t },\n\n\t brightness: function(value) {\n\t var round = Math.round;\n\n\t this.r = round(this.normalizeByte(this.r * value));\n\t this.g = round(this.normalizeByte(this.g * value));\n\t this.b = round(this.normalizeByte(this.b * value));\n\n\t return this;\n\t },\n\n\t percBrightness: function() {\n\t return Math.sqrt(0.241 * this.r * this.r + 0.691 * this.g * this.g + 0.068 * this.b * this.b);\n\t }\n\t});\n\n\tColor.fromBytes = function(r, g, b, a) {\n\t return new Bytes(r, g, b, a != null ? a : 1);\n\t};\n\n\tColor.fromRGB = function(r, g, b, a) {\n\t return new RGB(r, g, b, a != null ? a : 1);\n\t};\n\n\tColor.fromHSV = function(h, s, v, a) {\n\t return new HSV(h, s, v, a != null ? a : 1);\n\t};\n\n\tColor.fromHSL = function(h, s, l, a) {\n\t return new HSL(h, s, l, a != null ? a : 1);\n\t};\n\n\tColor.formats = [ {\n\t re: /^rgb\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})\\)$/,\n\t process: function(parts) {\n\t return [\n\t parseInt(parts[1], 10), parseInt(parts[2], 10), parseInt(parts[3], 10)\n\t ];\n\t }\n\t}, {\n\t re: /^(\\w{2})(\\w{2})(\\w{2})$/,\n\t process: function(parts) {\n\t return [\n\t parseInt(parts[1], 16), parseInt(parts[2], 16), parseInt(parts[3], 16)\n\t ];\n\t }\n\t}, {\n\t re: /^(\\w{1})(\\w{1})(\\w{1})$/,\n\t process: function(parts) {\n\t return [\n\t parseInt(parts[1] + parts[1], 16),\n\t parseInt(parts[2] + parts[2], 16),\n\t parseInt(parts[3] + parts[3], 16)\n\t ];\n\t }\n\t} ];\n\n\tColor.namedColors = namedColors;\n\n\tkendo.deepExtend(kendo, {\n\t parseColor: parseColor,\n\t Color: Color\n\t});\n\n\t}, __webpack_require__(3));\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1058);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1054:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.popup\");\n\n/***/ }),\n\n/***/ 1058:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1054), __webpack_require__(1059), __webpack_require__(1060) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"columnmenu\",\n\t name: \"Column Menu\",\n\t category: \"framework\",\n\t depends: [ \"popup\", \"filtermenu\", \"menu\" ],\n\t advanced: true\n\t};\n\n\t(function($, undefined) {\n\t var kendo = window.kendo,\n\t ui = kendo.ui,\n\t proxy = $.proxy,\n\t extend = $.extend,\n\t grep = $.grep,\n\t map = $.map,\n\t inArray = $.inArray,\n\t ACTIVE = \"k-state-selected\",\n\t ASC = \"asc\",\n\t DESC = \"desc\",\n\t CHANGE = \"change\",\n\t INIT = \"init\",\n\t OPEN = \"open\",\n\t SELECT = \"select\",\n\t POPUP = \"kendoPopup\",\n\t FILTERMENU = \"kendoFilterMenu\",\n\t MENU = \"kendoMenu\",\n\t NS = \".kendoColumnMenu\",\n\t Widget = ui.Widget;\n\n\t function trim(text) {\n\t return kendo.trim(text).replace(/ /gi, \"\");\n\t }\n\n\t function toHash(arr, key) {\n\t var result = {};\n\t var idx, len, current;\n\t for (idx = 0, len = arr.length; idx < len; idx ++) {\n\t current = arr[idx];\n\t result[current[key]] = current;\n\t }\n\t return result;\n\t }\n\n\t function leafColumns(columns) {\n\t var result = [];\n\n\t for (var idx = 0; idx < columns.length; idx++) {\n\t if (!columns[idx].columns) {\n\t result.push(columns[idx]);\n\t continue;\n\t }\n\t result = result.concat(leafColumns(columns[idx].columns));\n\t }\n\n\t return result;\n\t }\n\n\t function attrEquals(attrName, attrValue) {\n\t return \"[\" + kendo.attr(attrName) + \"='\" + (attrValue || \"\").replace(/'/g, \"\\\"\") + \"']\";\n\t }\n\n\t function insertElementAt(index, element, container) {\n\t if (index > 0) {\n\t element.insertAfter(container.children().eq(index - 1));\n\t } else {\n\t container.prepend(element);\n\t }\n\t }\n\n\t function columnOccurrences(columns) {\n\t var columnDict = {};\n\t var signature;\n\n\t for (var i = 0; i < columns.length; i++) {\n\t signature = JSON.stringify(columns[i]);\n\n\t if (columnDict[signature]) {\n\t columnDict[signature].push(i);\n\t } else {\n\t columnDict[signature] = [i];\n\t }\n\t }\n\n\t return columnDict;\n\t }\n\n\t function oldColumnOccurrences(renderedListElements, checkBoxes) {\n\t var indexAttr = kendo.attr(\"index\");\n\t var fieldAttr = kendo.attr(\"field\");\n\t var columnDict = {};\n\t var signature;\n\t var columCheckbox;\n\t var index;\n\t var field;\n\t var title;\n\n\t for (var j = 0; j < renderedListElements.length; j++) {\n\t columCheckbox = checkBoxes.eq(j);\n\t index = parseInt(columCheckbox.attr(indexAttr), 10);\n\t field = columCheckbox.attr(fieldAttr);\n\t title = columCheckbox.attr(\"title\");\n\t signature = field ? field : title;\n\n\t if (columnDict[signature]) {\n\t columnDict[signature].push(index);\n\t } else {\n\t columnDict[signature] = [index];\n\t }\n\t }\n\n\t return columnDict;\n\t }\n\n\t var ColumnMenu = Widget.extend({\n\t init: function(element, options) {\n\t var that = this,\n\t link;\n\n\t Widget.fn.init.call(that, element, options);\n\n\t element = that.element;\n\t options = that.options;\n\t that.owner = options.owner;\n\t that.dataSource = options.dataSource;\n\n\t that.field = element.attr(kendo.attr(\"field\"));\n\t that.title = element.attr(kendo.attr(\"title\"));\n\n\t link = element.find(\".k-header-column-menu\");\n\n\t if (!link[0]) {\n\t link = element.addClass(\"k-with-icon\").prepend('').find(\".k-header-column-menu\");\n\t }\n\n\t that.link = link\n\t .attr(\"tabindex\", -1)\n\t .on(\"click\" + NS, proxy(that._click, that));\n\n\t that.wrapper = $('
    ');\n\n\t that._refreshHandler = proxy(that.refresh, that);\n\n\t that.dataSource.bind(CHANGE, that._refreshHandler);\n\t },\n\n\t _init: function() {\n\t var that = this;\n\n\t that.pane = that.options.pane;\n\t if (that.pane) {\n\t that._isMobile = true;\n\t }\n\n\t if (that._isMobile) {\n\t that._createMobileMenu();\n\t } else {\n\t that._createMenu();\n\t }\n\n\t that.owner._muteAngularRebind(function() {\n\t that._angularItems(\"compile\");\n\t });\n\n\t that._sort();\n\n\t that._columns();\n\n\t that._filter();\n\n\t that._lockColumns();\n\n\t that.trigger(INIT, { field: that.field, container: that.wrapper });\n\t },\n\n\t events: [ INIT, OPEN, \"sort\", \"filtering\" ],\n\n\t options: {\n\t name: \"ColumnMenu\",\n\t messages: {\n\t sortAscending: \"Sort Ascending\",\n\t sortDescending: \"Sort Descending\",\n\t filter: \"Filter\",\n\t column: \"Column\",\n\t columns: \"Columns\",\n\t columnVisibility: \"Column Visibility\",\n\t clear: \"Clear\",\n\t cancel: \"Cancel\",\n\t done: \"Done\",\n\t settings: \"Edit Column Settings\",\n\t lock: \"Lock\",\n\t unlock: \"Unlock\"\n\t },\n\t filter: \"\",\n\t columns: true,\n\t sortable: true,\n\t filterable: true,\n\t animations: {\n\t left: \"slide\"\n\t }\n\t },\n\n\t _createMenu: function() {\n\t var that = this,\n\t options = that.options;\n\n\t that.wrapper.html(kendo.template(template)({\n\t uid: kendo.guid(),\n\t ns: kendo.ns,\n\t messages: options.messages,\n\t sortable: options.sortable,\n\t filterable: options.filterable,\n\t columns: that._ownerColumns(),\n\t showColumns: options.columns,\n\t lockedColumns: options.lockedColumns\n\t }));\n\n\t that.popup = that.wrapper[POPUP]({\n\t anchor: that.link,\n\t open: proxy(that._open, that),\n\t activate: proxy(that._activate, that),\n\t deactivate: proxy(that._deactivate, that),\n\t close: function() {\n\t that.menu._closing = true;\n\t if (that.options.closeCallback) {\n\t that.options.closeCallback(that.element);\n\t }\n\t }\n\t }).data(POPUP);\n\n\t that.menu = that.wrapper.children()[MENU]({\n\t orientation: \"vertical\",\n\t closeOnClick: false,\n\t open: function() {\n\t that._updateMenuItems();\n\t }\n\t }).data(MENU);\n\t },\n\n\t _deactivate: function() {\n\t this.menu._closing = false;\n\t },\n\n\t _createMobileMenu: function() {\n\t var that = this,\n\t options = that.options;\n\n\t var html = kendo.template(mobileTemplate)({\n\t ns: kendo.ns,\n\t field: that.field,\n\t title: that.title || that.field,\n\t messages: options.messages,\n\t sortable: options.sortable,\n\t filterable: options.filterable,\n\t columns: that._ownerColumns(),\n\t showColumns: options.columns,\n\t lockedColumns: options.lockedColumns\n\t });\n\n\t that.view = that.pane.append(html);\n\t that.view.state = { columns: {} };\n\n\t that.wrapper = that.view.element.find(\".k-column-menu\");\n\n\t that.menu = new MobileMenu(that.wrapper.children(), {\n\t pane: that.pane,\n\t columnMenu: that\n\t });\n\n\t // The toggle animation of the switches should not propagate to the view\n\t that.menu.element.on(\"transitionend\" + NS, function(e) {\n\t e.stopPropagation();\n\t });\n\n\t var viewElement = that.view.wrapper && that.view.wrapper[0] ? that.view.wrapper : that.view.element;\n\n\t viewElement.on(\"click\", \".k-header-done\", function(e) {\n\t e.preventDefault();\n\n\t that.menu._applyChanges();\n\t that.menu._cancelChanges(false);\n\t that.close();\n\t });\n\n\t viewElement.on(\"click\", \".k-header-cancel\", function(e) {\n\t e.preventDefault();\n\n\t that.menu._cancelChanges(true);\n\t that.close();\n\t });\n\n\t that.view.bind(\"showStart\", function() {\n\t var view = that.view || { columns: {} };\n\n\t if (that.options.lockedColumns) {\n\t that._updateLockedColumns();\n\t }\n\n\t if (view.element.find(\".k-sort-asc.k-state-selected\").length) {\n\t view.state.initialSort = \"asc\";\n\t } else if (view.element.find(\".k-sort-desc.k-state-selected\").length) {\n\t view.state.initialSort = \"desc\";\n\t }\n\t });\n\t },\n\n\t _angularItems: function(action) {\n\t var that = this;\n\t that.angular(action, function(){\n\t var items = that.wrapper.find(\".k-columns-item input[\" + kendo.attr(\"field\") + \"]\").map(function(){\n\t return $(this).closest(\"li\");\n\t });\n\t var data = map(that._ownerColumns(), function(col){\n\t return { column: col._originalObject };\n\t });\n\t return {\n\t elements: items,\n\t data: data\n\t };\n\t });\n\t },\n\n\t destroy: function() {\n\t var that = this;\n\n\t that._angularItems(\"cleanup\");\n\n\t Widget.fn.destroy.call(that);\n\n\t if (that.filterMenu) {\n\t that.filterMenu.destroy();\n\t }\n\n\t if (that._refreshHandler) {\n\t that.dataSource.unbind(CHANGE, that._refreshHandler);\n\t }\n\n\t if (that.options.columns && that.owner) {\n\t if (that._updateColumnsMenuHandler) {\n\t that.owner.unbind(\"columnShow\", that._updateColumnsMenuHandler);\n\t that.owner.unbind(\"columnHide\", that._updateColumnsMenuHandler);\n\t }\n\n\t if (that._updateColumnsLockedStateHandler) {\n\t that.owner.unbind(\"columnLock\", that._updateColumnsLockedStateHandler);\n\t that.owner.unbind(\"columnUnlock\", that._updateColumnsLockedStateHandler);\n\t }\n\t }\n\n\t if (that.menu) {\n\t that.menu.element.off(NS);\n\t that.menu.destroy();\n\t }\n\n\t that.wrapper.off(NS);\n\n\t if (that.popup) {\n\t that.popup.destroy();\n\t }\n\n\t if (that.view) {\n\t that.view.purge();\n\t }\n\n\t that.link.off(NS);\n\t that.owner = null;\n\t that.wrapper = null;\n\t that.element = null;\n\t },\n\n\t close: function() {\n\t this.menu.close();\n\t if (this.popup) {\n\t this.popup.close();\n\t this.popup.element.off(\"keydown\" + NS);\n\t }\n\t },\n\n\t _click: function(e) {\n\t var that = this;\n\n\t e.preventDefault();\n\t e.stopPropagation();\n\n\t var options = this.options;\n\n\t if (options.filter && this.element.is(!options.filter)) {\n\t return;\n\t }\n\n\t if (!this.popup && !this.pane) {\n\t this._init();\n\t } else {\n\t that._updateMenuItems();\n\t }\n\n\t if (this._isMobile) {\n\t this.pane.navigate(this.view, this.options.animations.left);\n\t } else {\n\t this.popup.toggle();\n\t }\n\t },\n\n\t _updateMenuItems: function() {\n\t var that = this;\n\t if (that.options.columns) {\n\t that._setMenuItemsVisibility();\n\t that._reorderMenuItems();\n\t }\n\t },\n\n\t _setMenuItemsVisibility: function() {\n\t var that = this;\n\n\t that._eachRenderedMenuItem(function(index, column, renderedListElement) {\n\t if (column.matchesMedia === false) {\n\t renderedListElement.hide();\n\t } else {\n\t renderedListElement.show();\n\t }\n\t });\n\t },\n\n\t _reorderMenuItems: function() {\n\t var that = this;\n\n\t that._eachRenderedMenuItem(function(index, column, renderedListElement, renderedList) {\n\t if (renderedListElement[0] && renderedListElement.index() !== index) {\n\t insertElementAt(index, renderedListElement, renderedList);\n\t }\n\t });\n\t that._updateDataIndexes();\n\t },\n\n\t _updateDataIndexes: function () {\n\t var that = this;\n\t var renderedList = that._isMobile && that.view ?\n\t $(that.view.element).find(\".k-columns-item\").children(\"ul\") :\n\t $(that.wrapper).find(\".k-menu-group\").first();\n\n\t renderedList.find(\"span.\" + (this._isMobile ? \"k-listgroup-form-field-wrapper\" : \"k-menu-link\") +\n\t \" input\").each(function (i) {\n\t $(this).attr(kendo.attr(\"index\"), i);\n\t });\n\t },\n\n\t _eachRenderedMenuItem: function(callback) {\n\t var that = this;\n\t var renderedListElement;\n\t var duplicateColumnIndex;\n\t var fieldValue;\n\t var currentColumn;\n\t var columns = grep(leafColumns(that.owner.columns), function(col) {\n\t var result = true,\n\t title = trim(col.title || \"\");\n\n\t if (col.menu === false || (!col.field && !title.length)) {\n\t result = false;\n\t }\n\n\t return result;\n\t }).map(function(col) {\n\t return {\n\t field: col.field,\n\t title: col.title,\n\t matchesMedia: col.matchesMedia\n\t };\n\t });\n\t var renderedList = that._isMobile && that.view ?\n\t $(that.view.element).find(\".k-columns-item\").children(\"ul\") :\n\t $(that.wrapper).find(\".k-menu-group\").first();\n\n\t var renderedListElements = renderedList.find(\"span.\" + (this._isMobile ? \"k-listgroup-form-field-wrapper\" : \"k-menu-link\"));\n\t var oldOccurances = oldColumnOccurrences(renderedListElements, renderedList.find(\"input[type=checkbox]\"));\n\t var columnOccurrence = columnOccurrences(columns);\n\t var columnElements;\n\n\t for (var i = 0; i < columns.length; i++) {\n\t currentColumn = columns[i];\n\t fieldValue = currentColumn.field ? currentColumn.field : currentColumn.title;\n\t duplicateColumnIndex = $.inArray(i, columnOccurrence[JSON.stringify(currentColumn)]);\n\t columnElements = $();\n\n\t for (var idx = 0; idx < oldOccurances[fieldValue].length; idx++) {\n\t columnElements = columnElements.add(renderedListElements.eq(oldOccurances[fieldValue][idx]));\n\t }\n\t renderedListElement = columnElements.find(attrEquals(\"field\", fieldValue)).closest(\"li\").eq(duplicateColumnIndex);\n\t callback(i, currentColumn, renderedListElement, renderedList);\n\t }\n\t },\n\n\t _open: function() {\n\t var that = this;\n\t $(\".k-column-menu\").not(that.wrapper).each(function() {\n\t $(this).data(POPUP).close();\n\t });\n\t that.popup.element.on(\"keydown\" + NS, function(e) {\n\t if (e.keyCode == kendo.keys.ESC) {\n\t that.close();\n\t }\n\t });\n\n\t if (that.options.lockedColumns) {\n\t that._updateLockedColumns();\n\t }\n\t },\n\n\t _activate: function() {\n\t this.menu.element.focus();\n\n\t this.trigger(OPEN, { field: this.field, container: this.wrapper });\n\t },\n\n\t _ownerColumns: function() {\n\t var columns = leafColumns(this.owner.columns),\n\t menuColumns = grep(columns, function(col) {\n\t var result = true,\n\t title = trim(col.title || \"\");\n\n\t if (col.menu === false || (!col.field && !title.length)) {\n\t result = false;\n\t }\n\n\t return result;\n\t });\n\n\t return map(menuColumns, function(col) {\n\t return {\n\t originalField: col.field,\n\t field: col.field || col.title,\n\t title: col.title || col.field,\n\t hidden: col.hidden,\n\t matchesMedia: col.matchesMedia,\n\t index: inArray(col, columns),\n\t locked: !!col.locked,\n\t _originalObject: col,\n\t uid: col.headerAttributes.id\n\t };\n\t });\n\t },\n\n\t _sort: function() {\n\t var that = this;\n\n\t if (that.options.sortable) {\n\t that.refresh();\n\n\t that.menu.bind(SELECT, function(e) {\n\t var item = $(e.item),\n\t dir;\n\n\t if (item.hasClass(\"k-sort-asc\")) {\n\t dir = ASC;\n\t } else if (item.hasClass(\"k-sort-desc\")) {\n\t dir = DESC;\n\t }\n\n\t if (!dir) {\n\t return;\n\t }\n\n\t item.parent().find(\".k-sort-\" + (dir == ASC ? DESC : ASC)).removeClass(ACTIVE);\n\n\t that._sortDataSource(item, dir);\n\n\t if (!that._isMobile) {\n\t that.close();\n\t }\n\t });\n\t }\n\t },\n\n\t _sortDataSource: function(item, dir) {\n\t var that = this,\n\t sortable = that.options.sortable,\n\t compare = sortable.compare === null ? undefined : sortable.compare,\n\t dataSource = that.dataSource,\n\t idx,\n\t length,\n\t sort = dataSource.sort() || [];\n\n\t var removeClass = item.hasClass(ACTIVE) && sortable && sortable.allowUnsort !== false;\n\n\t dir = !removeClass ? dir : undefined;\n\n\t if (that.trigger(\"sort\", { sort: { field: that.field, dir: dir, compare: compare } })) {\n\t return;\n\t }\n\n\t if (removeClass) {\n\t item.removeClass(ACTIVE);\n\t } else {\n\t item.addClass(ACTIVE);\n\t }\n\n\t if (sortable.mode === \"multiple\") {\n\t for (idx = 0, length = sort.length; idx < length; idx++) {\n\t if (sort[idx].field === that.field) {\n\t sort.splice(idx, 1);\n\t break;\n\t }\n\t }\n\t sort.push({ field: that.field, dir: dir, compare: compare });\n\t } else {\n\t sort = [ { field: that.field, dir: dir, compare: compare} ];\n\t }\n\n\t dataSource.sort(sort);\n\t },\n\n\t _columns: function() {\n\t var that = this;\n\n\t if (that.options.columns) {\n\n\t that._updateColumnsMenu();\n\n\t that._updateColumnsMenuHandler = proxy(that._updateColumnsMenu, that);\n\n\t that.owner.bind([\"columnHide\", \"columnShow\"], that._updateColumnsMenuHandler);\n\n\t that._updateColumnsLockedStateHandler = proxy(that._updateColumnsLockedState, that);\n\n\t that.owner.bind([\"columnUnlock\", \"columnLock\" ], that._updateColumnsLockedStateHandler);\n\n\t that.menu.bind(SELECT, function(e) {\n\t var item = $(e.item),\n\t input,\n\t column,\n\t indexAttr = kendo.attr(\"index\"),\n\t columnIndexMap = {},\n\t columnsCount = 0,\n\t columns = grep(leafColumns(that.owner.columns), function(col, idx) {\n\t var result = true,\n\t title = trim(col.title || \"\");\n\n\t if (col.menu === false || (!col.field && !title.length)) {\n\t result = false;\n\t }\n\n\t if (result) {\n\t columnIndexMap[idx] = columnsCount;\n\t columnsCount++;\n\t }\n\n\t return result;\n\t });\n\n\t if (that._isMobile) {\n\t e.preventDefault();\n\t }\n\n\t if (!item.parent().closest(\"li.k-columns-item\")[0]) {\n\t return;\n\t }\n\n\t input = item.find(\":checkbox\");\n\t if (input.attr(\"disabled\")) {\n\t return;\n\t }\n\n\t column = columns[columnIndexMap[parseInt(input.attr(indexAttr), 10)]];\n\n\t if (column.hidden === true) {\n\t that.owner.showColumn(column);\n\t } else {\n\t that.owner.hideColumn(column);\n\t }\n\t });\n\t }\n\t },\n\n\t _updateColumnsMenu: function() {\n\t var idx, length, current, checked, locked;\n\t var fieldAttr = kendo.attr(\"field\"),\n\t lockedAttr = kendo.attr(\"locked\"),\n\t uidAttr = kendo.attr(\"uid\"),\n\t columnIndexMap = {},\n\t columnsCount = 0,\n\t colIdx = 0,\n\t columnsInMenu = grep(leafColumns(this.owner.columns), function(col, idx) {\n\t var result = true,\n\t title = trim(col.title || \"\");\n\n\t if (col.menu === false || (!col.field && !title.length)) {\n\t result = false;\n\t }\n\n\t if (result) {\n\t columnIndexMap[idx] = columnsCount;\n\t columnsCount++;\n\t }\n\n\t return result;\n\t }),\n\t visibleFields = grep(this._ownerColumns(), function(field) {\n\t return !field.hidden && field.matchesMedia !== false;\n\t }),\n\t visibleDataFields = grep(visibleFields, function(field) {\n\t return field.originalField;\n\t }),\n\t lockedCount = grep(visibleDataFields, function(col) {\n\t return col.locked === true;\n\t }).length,\n\t nonLockedCount = grep(visibleDataFields, function(col) {\n\t return col.locked !== true;\n\t }).length,\n\t columnsNotInMenu = grep(this.owner.columns, function(col) {\n\t return col.menu === false;\n\t }),\n\t hiddenColumnsNotInMenu = grep(columnsNotInMenu, function(col) {\n\t return col.hidden;\n\t });\n\n\t this.wrapper.find(\"[role='menuitemcheckbox']\").attr(\"aria-checked\", false);\n\n\t var checkboxes = this.wrapper\n\t .find(\".k-columns-item input[\" + fieldAttr + \"]\")\n\t .prop(\"disabled\", false)\n\t .prop(\"checked\", false);\n\t var switchWidget;\n\n\t for (idx = 0, length = checkboxes.length; idx < length; idx ++) {\n\t current = checkboxes.eq(idx);\n\t locked = current.attr(lockedAttr) === \"true\";\n\t checked = false;\n\t switchWidget = current.data(\"kendoSwitch\");\n\t colIdx = columnsInMenu.map(function (col) {\n\t return col.headerAttributes.id;\n\t }).indexOf(current.attr(uidAttr));\n\n\t checked = !columnsInMenu[colIdx].hidden && columnsInMenu[colIdx].matchesMedia !== false;\n\t current.prop(\"checked\", checked);\n\n\t if (switchWidget) {\n\t switchWidget.enable(true);\n\t switchWidget.check(checked);\n\t }\n\n\t current.closest(\"[role='menuitemcheckbox']\").attr(\"aria-checked\", checked);\n\n\t if (checked) {\n\t if (lockedCount == 1 && locked) {\n\t current.prop(\"disabled\", true);\n\n\t if (switchWidget) {\n\t switchWidget.enable(false);\n\t }\n\t }\n\n\t if ((columnsNotInMenu.length === 0 || (columnsNotInMenu.length === hiddenColumnsNotInMenu.length)) && nonLockedCount == 1 && !locked) {\n\t current.prop(\"disabled\", true);\n\n\t if (switchWidget) {\n\t switchWidget.enable(false);\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t _updateColumnsLockedState: function() {\n\t var idx, length, current, column;\n\t var fieldAttr = kendo.attr(\"field\");\n\t var lockedAttr = kendo.attr(\"locked\");\n\t var columns = toHash(this._ownerColumns(), \"field\");\n\t var checkboxes = this.wrapper\n\t .find(\".k-columns-item input[type=checkbox]\");\n\n\t for (idx = 0, length = checkboxes.length; idx < length; idx ++ ) {\n\t current = checkboxes.eq(idx);\n\t column = columns[current.attr(fieldAttr)];\n\t if (column) {\n\t current.attr(lockedAttr, column.locked);\n\t }\n\t }\n\n\t this._updateColumnsMenu();\n\t },\n\n\t _filter: function() {\n\t var that = this,\n\t widget = FILTERMENU,\n\t options = that.options;\n\n\t if (options.filterable !== false) {\n\n\t if (options.filterable.multi) {\n\t widget = \"kendoFilterMultiCheck\";\n\t if (options.filterable.dataSource) {\n\t options.filterable.checkSource = options.filterable.dataSource;\n\t delete options.filterable.dataSource;\n\t }\n\t }\n\t that.filterMenu = that.wrapper.find(\".k-filterable\")[widget](\n\t extend(true, {}, {\n\t appendToElement: true,\n\t dataSource: options.dataSource,\n\t values: options.values,\n\t field: that.field,\n\t title: that.title,\n\t change: function(e) {\n\t if (that.trigger(\"filtering\", { filter: e.filter, field: e.field })) {\n\t e.preventDefault();\n\t }\n\t }\n\t },\n\t options.filterable)\n\t ).data(widget);\n\n\t if (that._isMobile) {\n\t that.menu.bind(SELECT, function(e) {\n\t var item = $(e.item);\n\n\t if (item.hasClass(\"k-filter-item\")) {\n\t that.pane.navigate(that.filterMenu.view, that.options.animations.left);\n\t }\n\t });\n\t }\n\t }\n\t },\n\n\t _lockColumns: function() {\n\t var that = this;\n\t that.menu.bind(SELECT, function(e) {\n\t var item = $(e.item);\n\n\t if (item.hasClass(\"k-lock\")) {\n\t that.owner.lockColumn(that.field);\n\t if (!that._isMobile) {\n\t that.close();\n\t }\n\t } else if (item.hasClass(\"k-unlock\")) {\n\t that.owner.unlockColumn(that.field);\n\t if (!that._isMobile) {\n\t that.close();\n\t }\n\t }\n\t });\n\t },\n\n\t _updateLockedColumns: function() {\n\t var field = this.field;\n\t var columns = this.owner.columns;\n\t var column = grep(columns, function(column) {\n\t return column.field == field || column.title == field;\n\t })[0];\n\n\t if (!column) {\n\t return;\n\t }\n\n\t var locked = column.locked === true;\n\t var length = grep(columns, function(column) {\n\t return !column.hidden && ((column.locked && locked) || (!column.locked && !locked));\n\t }).length;\n\n\t var lockItem = this.wrapper.find(\".k-lock\").removeClass(\"k-state-disabled\");\n\t var unlockItem = this.wrapper.find(\".k-unlock\").removeClass(\"k-state-disabled\");\n\n\t if (locked || length == 1) {\n\t lockItem.addClass(\"k-state-disabled\");\n\t }\n\n\t if (!locked || length == 1) {\n\t unlockItem.addClass(\"k-state-disabled\");\n\t }\n\n\t this._updateColumnsLockedState();\n\t },\n\n\t refresh: function() {\n\t var that = this,\n\t sort = that.options.dataSource.sort() || [],\n\t descriptor,\n\t field = that.field,\n\t idx,\n\t length;\n\n\t that.wrapper.find(\".k-sort-asc, .k-sort-desc\").removeClass(ACTIVE);\n\n\t for (idx = 0, length = sort.length; idx < length; idx++) {\n\t descriptor = sort[idx];\n\n\t if (field == descriptor.field) {\n\t that.wrapper.find(\".k-sort-\" + descriptor.dir).addClass(ACTIVE);\n\t }\n\t }\n\n\t that.link[that._filterExist(that.dataSource.filter()) ? \"addClass\" : \"removeClass\"](\"k-state-active\");\n\t },\n\n\t _filterExist: function(filters) {\n\t var found = false;\n\t var filter;\n\n\t if (!filters) {\n\t return;\n\t }\n\n\t filters = filters.filters;\n\n\t for (var idx = 0, length = filters.length; idx < length; idx++) {\n\t filter = filters[idx];\n\n\t if (filter.field == this.field) {\n\t found = true;\n\t } else if (filter.filters) {\n\t found = found || this._filterExist(filter);\n\t }\n\t }\n\n\t return found;\n\t }\n\t });\n\n\t var template = '
      '+\n\t '#if(sortable){#'+\n\t '
    • ${messages.sortAscending}
    • '+\n\t '
    • ${messages.sortDescending}
    • '+\n\t '#if(showColumns || filterable){#'+\n\t '
    • '+\n\t '#}#'+\n\t '#}#'+\n\t '#if(showColumns){#'+\n\t '
    • ${messages.columns}
        '+\n\t '#for (var idx = 0; idx < columns.length; idx++) {#'+\n\t '
      • #=columns[idx].title#
      • '+\n\t '#}#'+\n\t '
    • '+\n\t '#if(filterable || lockedColumns){#'+\n\t '
    • '+\n\t '#}#'+\n\t '#}#'+\n\t '#if(filterable){#'+\n\t '
    • ${messages.filter}
        '+\n\t '
      • '+\n\t '
    • '+\n\t '#if(lockedColumns){#'+\n\t '
    • '+\n\t '#}#'+\n\t '#}#'+\n\t '#if(lockedColumns){#'+\n\t '
    • ${messages.lock}
    • '+\n\t '
    • ${messages.unlock}
    • '+\n\t '#}#'+\n\t '
    ';\n\n\t var mobileTemplate =\n\t '
    ' +\n\t '
    ' +\n\t '' +\n\t '${messages.settings}' +\n\t '' +\n\t '
    ' +\n\t '
    ' +\n\t '
      ' +\n\t '
    • ' +\n\t '#=messages.column#: ${title}' +\n\t '
        ' +\n\t '#if(sortable){#' +\n\t '
      • ${messages.sortAscending}
      • ' +\n\t '
      • ${messages.sortDescending}
      • ' +\n\t '#}#' +\n\t '#if(lockedColumns){#' +\n\t '
      • ${messages.lock}
      • ' +\n\t '
      • ${messages.unlock}
      • ' +\n\t '#}#' +\n\t '#if(filterable){#' +\n\t '
      • ' +\n\t '' +\n\t '' +\n\t '${messages.filter}' +\n\t '' +\n\t '' +\n\t '
      • ' +\n\t '#}#' +\n\t '
      ' +\n\t '
    • ' +\n\t '#if(showColumns){#' +\n\t '
    • ${messages.columnVisibility}' +\n\t '
        ' +\n\t '#for (var idx = 0; idx < columns.length; idx++) {#' +\n\t '
      • ' +\n\t '' +\n\t '' +\n\t '#=columns[idx].title#' +\n\t '' +\n\t '' +\n\t '' +\n\t '' +\n\t '' +\n\t '
      • ' +\n\t '#}#' +\n\t '
      ' +\n\t '
    • '+\n\t '#}#'+\n\t '
    • ' +\n\t ' ' +\n\t '
        ' +\n\t '
      • ' +\n\t '' +\n\t '#=messages.clear#' +\n\t '' +\n\t '
      • ' +\n\t '
      ' +\n\t '
    • ' +\n\t '
    ' +\n\t '
    '+\n\t '
    ';\n\n\t var MobileMenu = Widget.extend({\n\t init: function(element, options) {\n\t var that = this;\n\n\t Widget.fn.init.call(that, element, options);\n\n\t that._createCheckBoxes();\n\n\t that.element.on(\"click\" + NS, \"li.k-item:not(.k-separator):not(.k-state-disabled):not(:has(.k-switch))\", \"_click\");\n\t },\n\n\t events: [ SELECT ],\n\n\t _click: function(e) {\n\t var that = this;\n\n\t if (!$(e.target).is(\"[type=checkbox]\")) {\n\t e.preventDefault();\n\t }\n\n\t if ($(e.target).hasClass(\"k-clear\")) {\n\t that._cancelChanges(true);\n\n\t return;\n\t }\n\n\t if ($(e.target).hasClass(\"k-filterable\")) {\n\t that._cancelChanges(true);\n\t that.trigger(SELECT, { item: e.currentTarget });\n\n\t return;\n\t }\n\n\t that._updateSelectedItems(e.currentTarget);\n\t },\n\n\t _updateSelectedItems: function(el) {\n\t var that = this;\n\t var item = $(el);\n\t var state = that.options.columnMenu.view.state || { columns: {} };\n\t var id = item.prop(\"id\");\n\n\t if (item.hasClass(\"k-filter-item\")) {\n\t return;\n\t }\n\n\t if (state[id]) {\n\t state[id] = false;\n\t } else {\n\t state[id] = true;\n\t }\n\n\t if (item.hasClass(\"k-sort-asc\") || item.hasClass(\"k-sort-desc\")) {\n\t var dir;\n\t var otherItem;\n\t var otherItemId;\n\n\t if (item.hasClass(\"k-sort-asc\")) {\n\t dir = \"asc\";\n\t otherItem = that.element.find(\".k-sort-desc\");\n\t } else {\n\t dir = \"desc\";\n\t otherItem = that.element.find(\".k-sort-asc\");\n\t }\n\n\t otherItemId = otherItem.prop(\"id\");\n\n\t if (dir === state.initialSort && !item.hasClass(\"k-state-selected\")) {\n\t state[id] = false;\n\t }\n\n\t if (state[otherItemId]) {\n\t state[otherItemId] = false;\n\t }\n\n\t otherItem.removeClass(ACTIVE);\n\t }\n\n\t if (item.hasClass(ACTIVE)) {\n\t item.removeClass(ACTIVE);\n\t } else {\n\t item.addClass(ACTIVE);\n\t }\n\t },\n\n\t _cancelChanges: function(force) {\n\t var that = this;\n\t var menu = that.options.columnMenu;\n\t var view = menu.view;\n\t var state = view.state || { columns: {} };\n\t var columns = state.columns;\n\n\t that.element.find(\".\" + ACTIVE).removeClass(ACTIVE);\n\t menu.refresh();\n\n\t if (force) {\n\t var selectedItems = [];\n\n\t for (var key in columns) {\n\t if (columns.hasOwnProperty(key)) {\n\t if (columns[key] === true) {\n\t var item = view.element.find(\"#\" + key);\n\n\t selectedItems.push(item[0]);\n\t }\n\t }\n\t }\n\t // In order to use the columns hide/show validation,\n\t // triggering the Select event must be done backwards\n\t for (var i = selectedItems.length - 1; i >= 0; i--) {\n\t that.trigger(SELECT, { item: selectedItems[i] });\n\t }\n\n\t if (menu.options.lockedColumns) {\n\t menu._updateLockedColumns();\n\t }\n\t }\n\n\t that.options.columnMenu.view.state = { columns: {} };\n\t },\n\n\t _applyChanges: function() {\n\t var that = this;\n\t var view = that.options.columnMenu.view;\n\t var state = view.state || { columns: {} };\n\n\t for (var key in state) {\n\t if (state.hasOwnProperty(key)) {\n\t if (key !== \"initialSort\" && key !== \"columns\" && state[key] === true) {\n\t var item = view.element.find(\"#\" + key);\n\n\t if (item.hasClass(ACTIVE)) {\n\t item.removeClass(ACTIVE);\n\t } else {\n\t item.addClass(ACTIVE);\n\t }\n\n\t that.trigger(SELECT, { item: item[0] });\n\t }\n\t }\n\t }\n\t },\n\n\t _createCheckBoxes: function() {\n\t var that = this;\n\n\t that.element.find(\".k-columns-item\").find(\"[type='checkbox']\").kendoSwitch({\n\t messages: {\n\t checked: \"\",\n\t unchecked: \"\"\n\t },\n\t change: function(e) {\n\t var item = e.sender.element.closest(\".k-item\");\n\t var state = that.options.columnMenu.view.state || { columns: {} };\n\t var id = item.prop(\"id\");\n\n\t if (state.columns[id]) {\n\t state.columns[id] = false;\n\t } else {\n\t state.columns[id] = true;\n\t }\n\n\t that.trigger(SELECT, { item: item });\n\t }\n\t });\n\t },\n\n\t _destroyCheckBoxes: function() {\n\t var that = this;\n\t var elements = that.element.find(\".k-columns-item\").find(\"[type='checkbox']\");\n\t var switchWidget;\n\n\t for (var i = 0; i < elements.length; i++) {\n\t switchWidget = elements.eq(i).data(\"kendoSwitch\");\n\n\t if (switchWidget) {\n\t switchWidget.destroy();\n\t }\n\t }\n\t },\n\n\t close: function() {\n\t this.options.pane.navigate(\"\");\n\t },\n\n\t destroy: function() {\n\t var that = this;\n\n\t Widget.fn.destroy.call(that);\n\n\t that.element.off(NS);\n\t that._destroyCheckBoxes();\n\t }\n\t });\n\n\t ui.plugin(ColumnMenu);\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1059:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.filtermenu\");\n\n/***/ }),\n\n/***/ 1060:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.menu\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1061);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1061:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"columnsorter\",\n\t name: \"Column Sorter\",\n\t category: \"framework\",\n\t depends: [\"core\"],\n\t advanced: true\n\t};\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo;\n\t var ui = kendo.ui;\n\t var Widget = ui.Widget;\n\t var DIR = \"dir\";\n\t var ASC = \"asc\";\n\t var SINGLE = \"single\";\n\t var FIELD = \"field\";\n\t var DESC = \"desc\";\n\t var sorterNS = \".kendoColumnSorter\";\n\t var TLINK = \".k-link\";\n\t var ARIASORT = \"aria-sort\";\n\t var proxy = $.proxy;\n\n\t var ColumnSorter = Widget.extend({\n\t init: function (element, options) {\n\n\t var that = this, link;\n\n\t Widget.fn.init.call(that, element, options);\n\n\t that._refreshHandler = proxy(that.refresh, that);\n\n\t that.dataSource = that.options.dataSource.bind(\"change\", that._refreshHandler);\n\n\t that.directions = that.options.initialDirection === ASC ? [ASC, DESC] : [DESC, ASC];\n\n\t link = that.element.find(TLINK);\n\n\t if (!link[0]) {\n\t link = that.element.wrapInner('').find(TLINK);\n\t }\n\n\t that.link = link;\n\n\t that.element.on(\"click\" + sorterNS, proxy(that._click, that));\n\t },\n\n\t options: {\n\t name: \"ColumnSorter\",\n\t mode: SINGLE,\n\t allowUnsort: true,\n\t compare: null,\n\t filter: \"\",\n\t initialDirection: ASC,\n\t showIndexes: false\n\t },\n\n\t events: [\"change\"],\n\n\t destroy: function () {\n\t var that = this;\n\n\t Widget.fn.destroy.call(that);\n\n\t that.element.off(sorterNS);\n\n\t that.dataSource.unbind(\"change\", that._refreshHandler);\n\t that._refreshHandler = that.element = that.link = that.dataSource = null;\n\t },\n\n\t refresh: function (e) {\n\t if (e && (e.action === \"itemchange\" || e.action === \"sync\")) {\n\t return;\n\t }\n\t var that = this,\n\t sort = that.dataSource.sort() || [],\n\t dir,\n\t table,\n\t leafCells,\n\t element = that.element,\n\t field = element.attr(kendo.attr(FIELD)),\n\t descriptor = (that.dataSource._sortFields || {})[field],\n\t headerIndex,\n\t sortOrder;\n\n\t element.removeAttr(kendo.attr(DIR));\n\t element.removeAttr(ARIASORT);\n\n\n\t if (descriptor) {\n\t dir = descriptor.dir;\n\t element.attr(kendo.attr(DIR), dir);\n\t sortOrder = descriptor.index;\n\t }\n\n\t if (element.is(\"th\") && descriptor) {\n\t table = getColsTable(element);\n\n\t if (table) {\n\t if (element.attr(kendo.attr(\"index\"))) {\n\t leafCells = leafDataCells(element.closest(\"table\"));\n\t headerIndex = leafCells.index(element);\n\t } else {\n\t headerIndex = element.parent().children(\":visible\").index(element);\n\t }\n\n\t table.find(\"col:not(.k-group-col):not(.k-hierarchy-col)\").eq(headerIndex).toggleClass(\"k-sorted\", dir !== undefined);\n\t }\n\t }\n\t element.toggleClass(\"k-sorted\", dir !== undefined);\n\t element.find(\".k-i-sort-asc-sm,.k-i-sort-desc-sm,.k-sort-order\").remove();\n\n\t if (dir === ASC) {\n\t $('').appendTo(that.link);\n\t element.attr(ARIASORT, \"ascending\");\n\t } else if (dir === DESC) {\n\t $('').appendTo(that.link);\n\t element.attr(ARIASORT, \"descending\");\n\t }\n\t if (that.options.showIndexes && sort.length > 1 && sortOrder) {\n\t $('').html(sortOrder).appendTo(that.link);\n\t }\n\t },\n\n\t _toggleSortDirection: function(dir) {\n\t var directions = this.directions;\n\t if (dir === directions[directions.length - 1] && this.options.allowUnsort) {\n\t return undefined;\n\t }\n\t return directions[0] === dir ? directions[1] : directions[0];\n\t },\n\n\t _click: function (e) {\n\t var that = this,\n\t element = that.element,\n\t field = element.attr(kendo.attr(FIELD)),\n\t dir = element.attr(kendo.attr(DIR)),\n\t options = that.options,\n\t compare = that.options.compare === null ? undefined : that.options.compare,\n\t sort = that.dataSource.sort() || [],\n\t idx,\n\t length;\n\n\t e.preventDefault();\n\n\t if (options.filter && !element.is(options.filter)) {\n\t return;\n\t }\n\n\t dir = this._toggleSortDirection(dir);\n\n\t if (this.trigger(\"change\", { sort: { field: field, dir: dir, compare: compare } })) {\n\t return;\n\t }\n\n\t if (options.mode === SINGLE) {\n\t sort = [{ field: field, dir: dir, compare: compare }];\n\t } else if (options.mode === \"multiple\") {\n\t for (idx = 0, length = sort.length; idx < length; idx++) {\n\t if (sort[idx].field === field) {\n\t sort.splice(idx, 1);\n\t break;\n\t }\n\t }\n\t sort.push({ field: field, dir: dir, compare: compare });\n\t }\n\n\t if (this.dataSource.options.endless) {\n\t this.dataSource.options.endless = null;\n\t element.closest(\".k-grid\").getKendoGrid()._endlessPageSize = that.dataSource.options.pageSize;\n\t this.dataSource.pageSize(that.dataSource.options.pageSize);\n\t }\n\t this.dataSource.sort(sort);\n\t }\n\t });\n\n\t function leafDataCells(container) {\n\t var rows = container.find(\"tr:not(.k-filter-row)\");\n\t var indexAttr = kendo.attr(\"index\");\n\n\t var cells = rows.find(\"th[\" + indexAttr + \"]:visible\");\n\n\t cells.sort(function(a, b) {\n\t a = $(a);\n\t b = $(b);\n\n\t var indexA = a.attr(indexAttr);\n\t var indexB = b.attr(indexAttr);\n\n\t if (indexA === undefined) {\n\t indexA = $(a).index();\n\t }\n\t if (indexB === undefined) {\n\t indexB = $(b).index();\n\t }\n\n\t indexA = parseInt(indexA, 10);\n\t indexB = parseInt(indexB, 10);\n\t return indexA > indexB ? 1 : (indexA < indexB ? -1 : 0);\n\t });\n\n\t return cells;\n\t }\n\n\t function getColsTable(element) {\n\t var table = null;\n\t if (element.is(\"th\")) {\n\t table = element.closest(\"table\");\n\t if (table.parent().hasClass(\"k-grid-header-wrap\")) {\n\t table = table.closest(\".k-grid\").find(\".k-grid-content > table\");\n\t } else if (table.parent().hasClass(\"k-grid-header-locked\")) {\n\t table = table.closest(\".k-grid\").find(\".k-grid-content-locked > table\");\n\t }\n\t }\n\t return table;\n\t }\n\n\t ui.plugin(ColumnSorter);\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1062);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1036:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.list\");\n\n/***/ }),\n\n/***/ 1037:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.mobile.scroller\");\n\n/***/ }),\n\n/***/ 1038:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.virtuallist\");\n\n/***/ }),\n\n/***/ 1062:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1036), __webpack_require__(1037), __webpack_require__(1038) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"combobox\",\n\t name: \"ComboBox\",\n\t category: \"web\",\n\t description: \"The ComboBox widget allows the selection from pre-defined values or entering a new value.\",\n\t depends: [ \"list\" ],\n\t features: [ {\n\t id: \"mobile-scroller\",\n\t name: \"Mobile scroller\",\n\t description: \"Support for kinetic scrolling in mobile device\",\n\t depends: [ \"mobile.scroller\" ]\n\t }, {\n\t id: \"virtualization\",\n\t name: \"VirtualList\",\n\t description: \"Support for virtualization\",\n\t depends: [ \"virtuallist\" ]\n\t } ]\n\t};\n\n\t(function($, undefined) {\n\t var kendo = window.kendo,\n\t ui = kendo.ui,\n\t List = ui.List,\n\t Select = ui.Select,\n\t caret = kendo.caret,\n\t support = kendo.support,\n\t placeholderSupported = support.placeholder,\n\t activeElement = kendo._activeElement,\n\t keys = kendo.keys,\n\t ns = \".kendoComboBox\",\n\t nsFocusEvent = ns + \"FocusEvent\",\n\t CLICK = \"click\" + ns,\n\t MOUSEDOWN = \"mousedown\" + ns,\n\t DISABLED = \"disabled\",\n\t READONLY = \"readonly\",\n\t CHANGE = \"change\",\n\t LOADING = \"k-i-loading\",\n\t DEFAULT = \"k-state-default\",\n\t FOCUSED = \"k-state-focused\",\n\t STATEDISABLED = \"k-state-disabled\",\n\t ARIA_DISABLED = \"aria-disabled\",\n\t AUTOCOMPLETEVALUE = \"off\",\n\t STATE_FILTER = \"filter\",\n\t STATE_ACCEPT = \"accept\",\n\t STATE_REBIND = \"rebind\",\n\t HOVEREVENTS = \"mouseenter\" + ns + \" mouseleave\" + ns,\n\t proxy = $.proxy,\n\t newLineRegEx = /(\\r\\n|\\n|\\r)/gm;\n\n\t var ComboBox = Select.extend({\n\t init: function(element, options) {\n\t var that = this, text, disabled;\n\n\t that.ns = ns;\n\n\t options = $.isArray(options) ? { dataSource: options } : options;\n\n\t Select.fn.init.call(that, element, options);\n\n\t options = that.options;\n\t element = that.element.on(\"focus\" + ns, proxy(that._focusHandler, that));\n\n\t options.placeholder = options.placeholder || element.attr(\"placeholder\");\n\n\t that._reset();\n\n\t that._wrapper();\n\n\t that._input();\n\n\t that._clearButton();\n\n\t that._tabindex(that.input);\n\n\t that._popup();\n\n\t that._dataSource();\n\t that._ignoreCase();\n\n\t that._enable();\n\n\t that._attachFocusEvents();\n\n\t that._oldIndex = that.selectedIndex = -1;\n\n\t that._aria();\n\n\t that._initialIndex = options.index;\n\n\t that.requireValueMapper(that.options);\n\t that._initList();\n\n\t that._cascade();\n\n\t if (options.autoBind) {\n\t that._filterSource();\n\t } else {\n\t text = options.text;\n\n\t if (!text && that._isSelect) {\n\t text = element.children(\":selected\").text();\n\t }\n\n\t if (text) {\n\t that._setText(text);\n\t }\n\t }\n\n\t if (!text) {\n\t that._placeholder();\n\t }\n\n\t disabled = $(that.element).parents(\"fieldset\").is(':disabled');\n\n\t if (disabled) {\n\t that.enable(false);\n\t }\n\n\t kendo.notify(that);\n\t that._toggleCloseVisibility();\n\t },\n\n\t options: {\n\t name: \"ComboBox\",\n\t enabled: true,\n\t index: -1,\n\t text: null,\n\t value: null,\n\t autoBind: true,\n\t delay: 200,\n\t dataTextField: \"\",\n\t dataValueField: \"\",\n\t minLength: 1,\n\t enforceMinLength: false,\n\t height: 200,\n\t highlightFirst: true,\n\t filter: \"none\",\n\t placeholder: \"\",\n\t suggest: false,\n\t cascadeFrom: \"\",\n\t cascadeFromField: \"\",\n\t cascadeFromParentField: \"\",\n\t ignoreCase: true,\n\t animation: {},\n\t virtual: false,\n\t template: null,\n\t groupTemplate: \"#:data#\",\n\t fixedGroupTemplate: \"#:data#\",\n\t clearButton: true,\n\t syncValueAndText: true,\n\t autoWidth: false,\n\t popup: null\n\t },\n\n\t events:[\n\t \"open\",\n\t \"close\",\n\t CHANGE,\n\t \"select\",\n\t \"filtering\",\n\t \"dataBinding\",\n\t \"dataBound\",\n\t \"cascade\",\n\t \"set\"\n\t ],\n\n\t setOptions: function(options) {\n\t var listOptions = this._listOptions(options);\n\n\t Select.fn.setOptions.call(this, options);\n\n\t this.listView.setOptions(listOptions);\n\n\t this._accessors();\n\t this._aria();\n\t this._clearButton();\n\t },\n\n\t destroy: function() {\n\t var that = this;\n\n\t that.input.off(ns);\n\t that.input.off(nsFocusEvent);\n\t that.element.off(ns);\n\t that.wrapper.off(ns);\n\t that._inputWrapper.off(ns);\n\t clearTimeout(that._pasteTimeout);\n\n\t that._arrow.off(CLICK + \" \" + MOUSEDOWN);\n\t that._clear.off(CLICK + \" \" + MOUSEDOWN);\n\n\t Select.fn.destroy.call(that);\n\t },\n\n\t _change: function() {\n\t var that = this;\n\t var text = that.text();\n\t var hasText = text && text !== that._oldText && text !== that.options.placeholder;\n\t var index = that.selectedIndex;\n\t var isCustom = index === -1;\n\n\t if (!that.options.syncValueAndText && !that.value() && isCustom && hasText) {\n\t that._old = \"\";\n\t that._oldIndex = index;\n\t that._oldText = text;\n\n\t if (!that._typing) {\n\t // trigger the DOM change event so any subscriber gets notified\n\t that.element.trigger(CHANGE);\n\t }\n\n\t that.trigger(CHANGE);\n\t that._typing = false;\n\t return;\n\t }\n\n\t Select.fn._change.call(that);\n\t that._toggleCloseVisibility();\n\t },\n\n\t _attachFocusEvents: function() {\n\t var that = this;\n\t that.input.on(\"focus\" + nsFocusEvent, proxy(that._inputFocus, that))\n\t .on(\"focusout\" + nsFocusEvent, proxy(that._inputFocusout, that));\n\t },\n\n\t _focusHandler: function(e) {\n\t if(e.target === this.element[0]) {\n\t this.input.focus();\n\t }\n\t },\n\n\t _arrowClick: function() {\n\t this._toggle();\n\t },\n\n\t _inputFocus: function() {\n\t this._inputWrapper.addClass(FOCUSED);\n\t this._placeholder(false);\n\t },\n\n\t _inputFocusout: function() {\n\t var that = this;\n\t var value = that.value();\n\n\t that._userTriggered = true;\n\t that._inputWrapper.removeClass(FOCUSED);\n\t clearTimeout(that._typingTimeout);\n\t that._typingTimeout = null;\n\n\t that.text(that.text());\n\n\t var item = that._focus();\n\t var dataItem = this.listView.dataItemByIndex(this.listView.getElementIndex(item));\n\n\t if (value !== that.value() && that.trigger(\"select\", { dataItem: dataItem, item: item })) {\n\t that.value(value);\n\t return;\n\t }\n\n\t that._placeholder();\n\t that._valueBeforeCascade = that._old;\n\t that._blur();\n\n\t that.element.blur();\n\t },\n\n\t _inputPaste: function() {\n\t var that = this;\n\t clearTimeout(that._pasteTimeout);\n\t that._pasteTimeout = null;\n\n\t that._pasteTimeout = setTimeout(function() {\n\t that.search();\n\t });\n\t },\n\n\t _editable: function(options) {\n\t var that = this,\n\t disable = options.disable,\n\t readonly = options.readonly,\n\t wrapper = that._inputWrapper.off(ns),\n\t input = that.element.add(that.input.off(ns)),\n\t arrow = that._arrow.off(CLICK + \" \" + MOUSEDOWN),\n\t clear = that._clear;\n\n\t if (!readonly && !disable) {\n\t wrapper\n\t .addClass(DEFAULT)\n\t .removeClass(STATEDISABLED)\n\t .on(HOVEREVENTS, that._toggleHover);\n\n\t input.removeAttr(DISABLED)\n\t .removeAttr(READONLY)\n\t .attr(ARIA_DISABLED, false);\n\n\t arrow.on(CLICK, proxy(that._arrowClick, that))\n\t .on(MOUSEDOWN, function(e) { e.preventDefault(); });\n\n\t clear.on(CLICK + \" touchend\" + ns, proxy(that._clearValue, that));\n\n\t that.input\n\t .on(\"keydown\" + ns, proxy(that._keydown, that))\n\t .on(\"input\" + ns, proxy(that._search, that))\n\t .on(\"paste\" + ns, proxy(that._inputPaste, that));\n\n\t that.wrapper.on(CLICK + ns, proxy(that._focusHandler, that));\n\t } else {\n\t wrapper\n\t .addClass(disable ? STATEDISABLED : DEFAULT)\n\t .removeClass(disable ? DEFAULT : STATEDISABLED);\n\n\t input.attr(DISABLED, disable)\n\t .attr(READONLY, readonly)\n\t .attr(ARIA_DISABLED, disable);\n\t }\n\n\t that._toggleCloseVisibility();\n\t },\n\n\t open: function() {\n\t var that = this;\n\t var state = that._state;\n\t var isFiltered = that.dataSource.filter() ? that.dataSource.filter().filters.length > 0 : false;\n\t var reinitialized = !that.ul.find(that.listView.focus()).length;\n\n\t if (that.popup.visible()) {\n\t return;\n\t }\n\n\t if ((!that.listView.bound() && state !== STATE_FILTER) || state === STATE_ACCEPT) {\n\t that._open = true;\n\t that._state = STATE_REBIND;\n\t if ((that.options.minLength !== 1 && !isFiltered) || (isFiltered && that.value() && that.selectedIndex === -1 )) {\n\t that.refresh();\n\t that._openPopup();\n\t if (!this.options.virtual) {\n\t that.listView.bound(false);\n\t }\n\t } else {\n\t that._filterSource();\n\t }\n\t } else if (that._allowOpening()) {\n\t // In some cases when the popup is opened resize is triggered which will cause it to close\n\t // Setting the below flag will prevent this from happening\n\t that.popup._hovered = true;\n\t that._openPopup();\n\t if(that.options.virtual) {\n\t that._focusItem();\n\t } else if (reinitialized && that.options.highlightFirst) {\n\t that.listView.focus(0);\n\t }\n\t }\n\t },\n\n\t _scrollToFocusedItem: function() {\n\t var listView = this.listView;\n\n\t listView.scrollToIndex(listView.getElementIndex(listView.focus()));\n\t },\n\n\t _openPopup: function() {\n\t this.popup.one(\"activate\", proxy(this._scrollToFocusedItem, this));\n\t this.popup.open();\n\t },\n\n\t _updateSelectionState: function() {\n\t var that = this;\n\t var text = that.options.text;\n\t var value = that.options.value;\n\n\t if (that.listView.isFiltered()) {\n\t return;\n\t }\n\n\t if (that.selectedIndex === -1) {\n\t if (text === undefined || text === null) {\n\t text = value;\n\t }\n\n\t that._accessor(value);\n\t that.input.val(text || that.input.val());\n\t that._placeholder();\n\t } else if (that._oldIndex === -1) {\n\t that._oldIndex = that.selectedIndex;\n\t }\n\t },\n\n\t _buildOptions: function(data) {\n\t var that = this;\n\t if (!that._isSelect) {\n\t return;\n\t }\n\n\t var custom = that._customOption;\n\n\t if (that._state === STATE_REBIND) {\n\t that._state = \"\";\n\t }\n\n\t that._customOption = undefined;\n\t that._options(data, \"\", that.value());\n\n\t if (custom && custom[0].selected && !that.listView._emptySearch) {\n\t that._custom(custom.val());\n\t }\n\t },\n\n\t _updateSelection: function() {\n\t var that = this;\n\t var listView = that.listView;\n\t var initialIndex = that._initialIndex;\n\t var hasInitialIndex = initialIndex !== null && initialIndex > -1;\n\t var filtered = that._state === STATE_FILTER;\n\n\t if (filtered) {\n\t $(listView.focus()).removeClass(\"k-state-selected\");\n\t return;\n\t }\n\n\t if (that._fetch) {\n\t return;\n\t }\n\n\t if (!listView.value().length) {\n\t if (hasInitialIndex) {\n\t that.select(initialIndex);\n\t } else if (that._accessor()) {\n\t listView.value(that._accessor());\n\t }\n\t }\n\n\t that._initialIndex = null;\n\t var dataItem = listView.selectedDataItems()[0];\n\n\t if (!dataItem) {\n\t return;\n\t }\n\n\t if (that._value(dataItem) !== that.value()) {\n\t that._custom(that._value(dataItem));\n\t } else if (that._value(dataItem) !== that.element[0].value){\n\t that._accessor(that._value(dataItem));\n\t }\n\n\t if (that.text() && that.text() !== that._text(dataItem)) {\n\t that._selectValue(dataItem);\n\t }\n\t },\n\n\t _updateItemFocus: function() {\n\t var listView = this.listView;\n\n\t if (!this.options.highlightFirst) {\n\t listView.focus(-1);\n\t } else if (!listView.focus() && !listView.focusIndex()) {\n\t listView.focus(0);\n\t }\n\t },\n\n\t _listBound: function() {\n\t var that = this;\n\t var isActive = that.input[0] === activeElement();\n\n\t var data = that.dataSource.flatView();\n\t var skip = that.listView.skip();\n\t var length = data.length;\n\t var groupsLength = that.dataSource._group ? that.dataSource._group.length : 0;\n\t var isFirstPage = skip === undefined || skip === 0;\n\n\t that._presetValue = false;\n\n\t that._renderFooter();\n\t that._renderNoData();\n\t that._toggleNoData(!length);\n\t that._toggleHeader(!!groupsLength && !!length);\n\n\t that._resizePopup();\n\n\t that.popup.position();\n\n\t that._buildOptions(data);\n\n\t that._makeUnselectable();\n\n\t that._updateSelection();\n\n\t if (data.length && isFirstPage) {\n\t that._updateItemFocus();\n\n\t if (that.options.suggest && isActive && that.input.val()) {\n\t that.suggest(data[0]);\n\t }\n\t }\n\n\t if (that._open) {\n\t that._open = false;\n\n\t if (that._typingTimeout && !isActive) {\n\t that.popup.close();\n\t } else {\n\t that.toggle(that._allowOpening());\n\t }\n\n\t that._typingTimeout = null;\n\t }\n\n\t that._hideBusy();\n\t that.trigger(\"dataBound\");\n\t },\n\n\t _listChange: function() {\n\t this._selectValue(this.listView.selectedDataItems()[0]);\n\n\t if (this._presetValue) {\n\t this._oldIndex = this.selectedIndex;\n\t }\n\t },\n\n\t _get: function(candidate) {\n\t var data, found, idx;\n\n\t if (typeof candidate === \"function\") {\n\t data = this.dataSource.flatView();\n\n\t for (idx = 0; idx < data.length; idx++) {\n\t if (candidate(data[idx])) {\n\t candidate = idx;\n\t found = true;\n\t break;\n\t }\n\t }\n\n\t if (!found) {\n\t candidate = -1;\n\t }\n\t }\n\n\t return candidate;\n\t },\n\n\t _select: function(candidate, keepState) {\n\t var that = this;\n\n\t candidate = that._get(candidate);\n\n\t if (candidate === -1) {\n\t that.input[0].value = \"\";\n\t that._accessor(\"\");\n\t }\n\n\t return that.listView.select(candidate).done(function() {\n\t if (!keepState && that._state === STATE_FILTER) {\n\t that._state = STATE_ACCEPT;\n\t }\n\t that._toggleCloseVisibility();\n\t });\n\t },\n\n\t _selectValue: function(dataItem) {\n\t var idx = this.listView.select();\n\t var value = \"\";\n\t var text = \"\";\n\n\t idx = idx[idx.length - 1];\n\t if (idx === undefined) {\n\t idx = -1;\n\t }\n\n\t this.selectedIndex = idx;\n\n\t if (this.listView.isFiltered() && idx !== -1) {\n\t this._valueBeforeCascade = this._old;\n\t }\n\n\t if (idx === -1 && !dataItem) {\n\t if (this.options.syncValueAndText) {\n\t if (this.options.dataTextField === this.options.dataValueField) {\n\t text = this._accessor();\n\t } else {\n\t text = this.input[0].value;\n\t }\n\t value = text;\n\t }\n\t else {\n\t text = this.text();\n\t }\n\t this.listView.focus(-1);\n\t } else {\n\t if (dataItem || dataItem === 0) {\n\t value = this._dataValue(dataItem);\n\t text = this._text(dataItem);\n\t }\n\n\t if (value === null) {\n\t value = \"\";\n\t }\n\t }\n\n\t this._setDomInputValue(text);\n\t this._accessor(value !== undefined ? value : text, idx);\n\n\t this._placeholder();\n\t this._triggerCascade();\n\t },\n\n\t _setDomInputValue: function(text){\n\t var that = this;\n\t var currentCaret = caret(this.input);\n\t var caretStart;\n\n\t if(currentCaret && currentCaret.length){\n\t caretStart = currentCaret[0];\n\t }\n\n\t this._prev = this.input[0].value = text;\n\n\t if(caretStart && this.selectedIndex === -1){\n\t var mobile = support.mobileOS;\n\t if(mobile.wp || mobile.android) {// without the timeout the caret is at the end of the input\n\t setTimeout(function() { that.input[0].setSelectionRange(caretStart, caretStart); }, 0);\n\t }\n\t else {\n\t this.input[0].setSelectionRange(caretStart, caretStart);\n\t }\n\t }\n\t },\n\n\t refresh: function() {\n\t this.listView.refresh();\n\t },\n\n\t _toggleCloseVisibility: function() {\n\t var preventShow = this.element.is(\":disabled\") || this.element.is(\"[readonly]\");\n\n\t if (this.text() && !preventShow) {\n\t this._showClear();\n\t } else {\n\t this._hideClear();\n\t }\n\t },\n\n\t suggest: function(word) {\n\t var that = this;\n\t var element = that.input[0];\n\t var value = that.text();\n\t var caretIdx = caret(element)[0];\n\t var key = that._last;\n\t var idx;\n\t var accentFoldingFiltering = that.dataSource.options.accentFoldingFiltering;\n\n\t if (key == keys.BACKSPACE || key == keys.DELETE) {\n\t that._last = undefined;\n\t return;\n\t }\n\n\t word = word || \"\";\n\n\t if (typeof word !== \"string\") {\n\t if (word[0]) {\n\t word = that.dataSource.view()[List.inArray(word[0], that.ul[0])];\n\t }\n\n\t word = word ? that._text(word) : \"\";\n\t }\n\n\t if (caretIdx <= 0) {\n\t caretIdx = (accentFoldingFiltering ? value.toLocaleLowerCase(accentFoldingFiltering) : value.toLowerCase()).indexOf(accentFoldingFiltering ? word.toLocaleLowerCase(accentFoldingFiltering) : word.toLowerCase()) + 1;\n\t }\n\n\t if (word) {\n\t word = word.toString();\n\t idx = (accentFoldingFiltering ? word.toLocaleLowerCase(accentFoldingFiltering) : word.toLowerCase()).indexOf(accentFoldingFiltering ? value.toLocaleLowerCase(accentFoldingFiltering) : value.toLowerCase());\n\t if (idx > -1) {\n\t value += word.substring(idx + value.length);\n\t }\n\t } else {\n\t value = value.substring(0, caretIdx);\n\t }\n\n\t if (value.length !== caretIdx || !word) {\n\t element.value = value;\n\t if (element === activeElement()) {\n\t caret(element, caretIdx, value.length);\n\t }\n\t }\n\t },\n\n\t text: function (text) {\n\t text = text === null ? \"\" : text;\n\n\t var that = this;\n\t var input = that.input[0];\n\t var ignoreCase = that.options.ignoreCase;\n\t var loweredText = text;\n\t var dataItem;\n\t var value;\n\n\t if (text === undefined) {\n\t return input.value;\n\t }\n\n\t if (that.options.autoBind === false && !that.listView.bound()) {\n\t that._setText(text);\n\t return;\n\t }\n\n\t dataItem = that.dataItem();\n\n\t if (dataItem && that._text(dataItem).replace && that._text(dataItem).replace(newLineRegEx,\"\") === text) {\n\t value = that._value(dataItem);\n\n\t if (value === List.unifyType(that._old, typeof value)) {\n\t that._triggerCascade();\n\t return;\n\t }\n\t }\n\n\t if (ignoreCase) {\n\t loweredText = loweredText.toLowerCase();\n\t }\n\n\t if(that.dataItem() && that._text(that.dataItem()) === text){\n\t return;\n\t }\n\n\t that._select(function(data) {\n\t data = that._text(data);\n\t if (ignoreCase) {\n\t data = (data + \"\").toLowerCase();\n\t }\n\n\t return data === loweredText;\n\t }).done(function() {\n\t if (that.selectedIndex < 0) {\n\t input.value = text;\n\n\t if (that.options.syncValueAndText) {\n\t that._accessor(text);\n\t }\n\n\t that._cascadeTriggered = true;\n\t that._triggerCascade();\n\t }\n\n\t that._prev = input.value;\n\t });\n\n\t that._toggleCloseVisibility();\n\t },\n\n\t toggle: function(toggle) {\n\t this._toggle(toggle, true);\n\t },\n\n\t value: function(value) {\n\t var that = this;\n\t var options = that.options;\n\t var listView = that.listView;\n\n\t if (value === undefined) {\n\t value = that._accessor() || that.listView.value()[0];\n\t return value === undefined || value === null ? \"\" : value;\n\t }\n\n\t that.requireValueMapper(that.options, value);\n\n\t that.trigger(\"set\", { value: value });\n\n\t if (value === options.value && that.input.val() === options.text &&\n\t !that.options.cascadeFrom) {\n\t return;\n\t }\n\n\t that._accessor(value);\n\n\t if (that._isFilterEnabled() && listView.bound() && listView.isFiltered()) {\n\t that._clearFilter();\n\t } else {\n\t that._fetchData();\n\t }\n\n\t listView\n\t .value(value)\n\t .done(function() {\n\t if (that.selectedIndex === -1 && (!listView._selectedDataItems || !listView._selectedDataItems.length)) {\n\t that._accessor(value);\n\t that.input.val(value);\n\t that._placeholder(true);\n\t }\n\n\t if(that._userTriggered) {\n\t that._old = that._accessor();\n\t } else {\n\t that._old = that._valueBeforeCascade = that._accessor();\n\t }\n\n\t that._oldIndex = that.selectedIndex;\n\n\t that._prev = that._oldText = that.input.val();\n\n\t if (that._state === STATE_FILTER) {\n\t that._state = STATE_ACCEPT;\n\t }\n\t that._toggleCloseVisibility();\n\t });\n\t },\n\n\t _hideBusy: function () {\n\t var that = this;\n\t clearTimeout(that._busy);\n\t that._arrowIcon.removeClass(LOADING);\n\t that._focused.attr(\"aria-busy\", false);\n\t that._busy = null;\n\t that._toggleCloseVisibility();\n\t },\n\n\t _click: function(e) {\n\t var that = this;\n\t var item = e.item;\n\t var dataItem = that.listView.dataItemByIndex(that.listView.getElementIndex(item));\n\t var shouldTrigger = true;\n\t e.preventDefault();\n\n\t if(dataItem){\n\t shouldTrigger = that._value(dataItem) !== List.unifyType(that.value(), typeof that._value(dataItem));\n\n\t if(!shouldTrigger){\n\t that.input.val(that._text(dataItem));\n\t }\n\t }\n\n\t if (shouldTrigger && that.trigger(\"select\", { dataItem: dataItem, item: item })) {\n\t that.close();\n\t return;\n\t }\n\n\t that._userTriggered = true;\n\n\t that._select(item).done(function() {\n\t that._blur();\n\t });\n\t },\n\n\t _syncValueAndText: function () {\n\t return this.options.syncValueAndText;\n\t },\n\n\t _inputValue: function() {\n\t return this.text();\n\t },\n\n\t _searchByWord: function(word) {\n\t var that = this;\n\t var options = that.options;\n\t var dataSource = that.dataSource;\n\t var ignoreCase = options.ignoreCase;\n\t var predicate = function (dataItem) {\n\t var text = that._text(dataItem);\n\t if (text !== undefined) {\n\t text = text + \"\";\n\t if (text !== \"\" && word === \"\") {\n\t return false;\n\t }\n\n\t if (ignoreCase) {\n\t text = text.toLowerCase();\n\t }\n\n\t return text.indexOf(word) === 0;\n\t }\n\t };\n\n\t if (ignoreCase) {\n\t word = word.toLowerCase();\n\t }\n\n\t if (!that.ul[0].firstChild) {\n\t dataSource.one(CHANGE, function () {\n\t if (dataSource.view()[0]) {\n\t that.search(word);\n\t }\n\t }).fetch();\n\t return;\n\t }\n\n\t this.listView.focus(this._get(predicate));\n\n\t var current = this.listView.focus();\n\n\t if (current) {\n\t if (options.suggest) {\n\t that.suggest(current);\n\t }\n\n\t this.open();\n\t }\n\n\t if (this.options.highlightFirst && !word) {\n\t this.listView.focusFirst();\n\t }\n\t },\n\n\t _input: function() {\n\t var that = this,\n\t element = that.element.removeClass(\"k-input\")[0],\n\t accessKey = element.accessKey,\n\t wrapper = that.wrapper,\n\t SELECTOR = \"input.k-input\",\n\t name = element.name || \"\",\n\t input,\n\t maxLength;\n\n\t if (name) {\n\t name = 'name=\"' + name + '_input\" ';\n\t }\n\n\t input = wrapper.find(SELECTOR);\n\n\t if (!input[0]) {\n\t wrapper.append('')\n\t .append(that.element);\n\n\t input = wrapper.find(SELECTOR);\n\t }\n\n\t input[0].style.cssText = element.style.cssText;\n\t input[0].title = element.title;\n\n\t maxLength = parseInt(this.element.prop(\"maxlength\") || this.element.attr(\"maxlength\"), 10);\n\t if (maxLength > -1) {\n\t input[0].maxLength = maxLength;\n\t }\n\n\t input.addClass(element.className)\n\t .css({\n\t width: \"\",\n\t height: element.style.height\n\t })\n\t .attr({\n\t \"role\": \"combobox\",\n\t \"aria-expanded\": false\n\t })\n\t .show();\n\n\t if (placeholderSupported) {\n\t input.attr(\"placeholder\", that.options.placeholder);\n\t }\n\n\t if (accessKey) {\n\t element.accessKey = \"\";\n\t input[0].accessKey = accessKey;\n\t }\n\n\t that._focused = that.input = input;\n\t that._inputWrapper = $(wrapper[0].firstChild);\n\t that._arrow = wrapper.find(\".k-select\")\n\t .attr({\n\t \"role\": \"button\",\n\t \"tabIndex\": -1\n\t });\n\t that._arrowIcon = that._arrow.find(\".k-icon\");\n\n\t if (element.id) {\n\t that._arrow.attr(\"aria-controls\", that.ul[0].id);\n\t }\n\t },\n\n\t _clearButton: function() {\n\t List.fn._clearButton.call(this);\n\n\t if (this.options.clearButton) {\n\t this._clear.insertAfter(this.input);\n\t this.wrapper.addClass(\"k-combobox-clearable\");\n\t }\n\t },\n\n\t _keydown: function(e) {\n\t var that = this,\n\t key = e.keyCode;\n\n\t that._last = key;\n\n\t clearTimeout(that._typingTimeout);\n\t that._typingTimeout = null;\n\n\t if (key === keys.HOME) {\n\t that._firstItem();\n\t } else if (key === keys.END) {\n\t that._lastItem();\n\t } else if (key === keys.ENTER || (key === keys.TAB && that.popup.visible())) {\n\t var current = that.listView.focus();\n\t var dataItem = that.dataItem();\n\t var shouldTrigger = true;\n\n\t if (!that.popup.visible() && (!dataItem || that.text() !== that._text(dataItem))) {\n\t current = null;\n\t }\n\n\t if (current) {\n\t if (that.popup.visible()) {\n\t e.preventDefault();\n\t }\n\n\t dataItem = that.listView.dataItemByIndex(that.listView.getElementIndex(current));\n\n\t if(dataItem){\n\t shouldTrigger = that._value(dataItem) !== List.unifyType(that.value(), typeof that._value(dataItem));\n\t }\n\n\t if (shouldTrigger && that.trigger(\"select\", { dataItem: dataItem, item: current })) {\n\t return;\n\t }\n\n\t that._userTriggered = true;\n\n\t that._select(current).done(function() {\n\t that._blur();\n\t that._valueBeforeCascade = that._old = that.value();\n\t });\n\t } else {\n\t if(that._syncValueAndText() || that._isSelect){\n\t that._accessor(that.input.val());\n\t }\n\n\t if (that.options.highlightFirst) {\n\t that.listView.value(that.input.val());\n\t that._blur();\n\t } else {\n\t that._oldText = that.text();\n\t }\n\t }\n\t } else if (key != keys.TAB && !that._move(e)) {\n\t that._search();\n\t } else if (key === keys.ESC && !that.popup.visible() && that.text()) {\n\t that._clearValue();\n\t }\n\t },\n\n\t _placeholder: function(show) {\n\t if (placeholderSupported) {\n\t return;\n\t }\n\n\t var that = this,\n\t input = that.input,\n\t placeholder = that.options.placeholder,\n\t value;\n\n\t if (placeholder) {\n\t value = that.value();\n\n\t if (show === undefined) {\n\t show = !value;\n\t }\n\n\t input.toggleClass(\"k-readonly\", show);\n\n\t if (!show) {\n\t if (!value) {\n\t placeholder = \"\";\n\t } else {\n\t return;\n\t }\n\t }\n\n\t input.val(placeholder);\n\n\t if (!placeholder && input[0] === activeElement()) {\n\t caret(input[0], 0, 0);\n\t }\n\t }\n\t },\n\n\t _search: function() {\n\t var that = this;\n\n\t clearTimeout(that._typingTimeout);\n\n\t that._typingTimeout = setTimeout(function() {\n\t var value = that.text();\n\n\t if (value !== \"\" && that._prev !== value) {\n\t that._prev = value;\n\n\t if (that.options.filter === \"none\" && that.options.virtual) {\n\t that.listView.select(-1);\n\t }\n\n\t that.search(value);\n\n\t that._toggleCloseVisibility();\n\t }\n\t else if (value === \"\" && that._prev !== \"\") {\n\t that._clearValue();\n\t that.search(\"\");\n\t }\n\n\t that._typingTimeout = null;\n\t }, that.options.delay);\n\t },\n\n\t _setText: function(text) {\n\t this.input.val(text);\n\t this._prev = text;\n\t },\n\n\t _wrapper: function() {\n\t var that = this,\n\t element = that.element,\n\t wrapper = element.parent();\n\n\t if (!wrapper.is(\"span.k-widget\")) {\n\t wrapper = element.hide().wrap(\"\").parent();\n\t wrapper[0].style.cssText = element[0].style.cssText;\n\t }\n\n\t that.wrapper = wrapper.addClass(\"k-widget k-combobox\")\n\t .addClass(element[0].className)\n\t .removeClass('input-validation-error')\n\t .css(\"display\", \"\");\n\t },\n\n\t _clearSelection: function(parent, isFiltered) {\n\t var that = this;\n\t var hasValue = parent.value();\n\t var custom = hasValue && parent.selectedIndex === -1;\n\n\t if (this.selectedIndex == -1 && this.value()) {\n\t return;\n\t }\n\n\t if (isFiltered || !hasValue || custom) {\n\t that.options.value = \"\";\n\t that.value(\"\");\n\t }\n\t },\n\n\t _preselect: function(value, text) {\n\t this.input.val(text);\n\t this._accessor(value);\n\n\t this._old = this._accessor();\n\t this._oldIndex = this.selectedIndex;\n\n\t this.listView.setValue(value);\n\t this._placeholder();\n\n\t this._initialIndex = null;\n\t this._presetValue = true;\n\t this._toggleCloseVisibility();\n\t },\n\n\t _clearText: function() {\n\t this._old = this.value();\n\t this.text(\"\");\n\t },\n\n\t _clearValue: function() {\n\t Select.fn._clearValue.call(this);\n\t this.input.focus();\n\t }\n\t });\n\n\t ui.plugin(ComboBox);\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1063);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1017:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"jquery\");\n\n/***/ }),\n\n/***/ 1063:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(jQuery) {(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1017)], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"core\",\n\t name: \"Core\",\n\t category: \"framework\",\n\t description: \"The core of the Kendo framework.\"\n\t};\n\n\t/*jshint eqnull: true, loopfunc: true, evil: true, boss: true, freeze: false*/\n\t(function($, window, undefined) {\n\t var kendo = window.kendo = window.kendo || { cultures: {} },\n\t extend = $.extend,\n\t each = $.each,\n\t isArray = $.isArray,\n\t proxy = $.proxy,\n\t noop = $.noop,\n\t math = Math,\n\t Template,\n\t JSON = window.JSON || {},\n\t support = {},\n\t percentRegExp = /%/,\n\t formatRegExp = /\\{(\\d+)(:[^\\}]+)?\\}/g,\n\t boxShadowRegExp = /(\\d+(?:\\.?)\\d*)px\\s*(\\d+(?:\\.?)\\d*)px\\s*(\\d+(?:\\.?)\\d*)px\\s*(\\d+)?/i,\n\t numberRegExp = /^(\\+|-?)\\d+(\\.?)\\d*$/,\n\t FUNCTION = \"function\",\n\t STRING = \"string\",\n\t NUMBER = \"number\",\n\t OBJECT = \"object\",\n\t NULL = \"null\",\n\t BOOLEAN = \"boolean\",\n\t UNDEFINED = \"undefined\",\n\t getterCache = {},\n\t setterCache = {},\n\t slice = [].slice,\n\t // avoid extending the depricated properties in latest verions of jQuery\n\t noDepricateExtend = function() {\n\t var src, copyIsArray, copy, name, options, clone,\n\t target = arguments[ 0 ] || {},\n\t i = 1,\n\t length = arguments.length,\n\t deep = false;\n\n\t // Handle a deep copy situation\n\t if ( typeof target === \"boolean\" ) {\n\t deep = target;\n\n\t // skip the boolean and the target\n\t target = arguments[ i ] || {};\n\t i++;\n\t }\n\n\t // Handle case when target is a string or something (possible in deep copy)\n\t if ( typeof target !== \"object\" && !jQuery.isFunction( target ) ) {\n\t target = {};\n\t }\n\n\t // extend jQuery itself if only one argument is passed\n\t if ( i === length ) {\n\t target = this;\n\t i--;\n\t }\n\n\t for ( ; i < length; i++ ) {\n\n\t // Only deal with non-null/undefined values\n\t if ( ( options = arguments[ i ] ) != null ) {\n\n\t // Extend the base object\n\t for ( name in options ) {\n\t // filters, concat and : properties are depricated in the jQuery 3.3.0\n\t // accessing these properties throw a warning when jQuery migrate is included\n\t if (name == \"filters\" || name == \"concat\" || name == \":\") {\n\t continue;\n\t }\n\t src = target[ name ];\n\t copy = options[ name ];\n\n\t // Prevent never-ending loop\n\t if ( target === copy ) {\n\t continue;\n\t }\n\n\t // Recurse if we're merging plain objects or arrays\n\t if ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t ( copyIsArray = jQuery.isArray( copy ) ) ) ) {\n\n\t if ( copyIsArray ) {\n\t copyIsArray = false;\n\t clone = src && jQuery.isArray( src ) ? src : [];\n\n\t } else {\n\t clone = src && jQuery.isPlainObject( src ) ? src : {};\n\t }\n\n\t // Never move original objects, clone them\n\t target[ name ] = noDepricateExtend( deep, clone, copy );\n\n\t // Don't bring in undefined values\n\t } else if ( copy !== undefined ) {\n\t target[ name ] = copy;\n\t }\n\t }\n\t }\n\t }\n\n\t // Return the modified object\n\t return target;\n\t };\n\n\t kendo.version = \"2020.2.617\".replace(/^\\s+|\\s+$/g, '');\n\n\t function Class() {}\n\n\t Class.extend = function(proto) {\n\t var base = function() {},\n\t member,\n\t that = this,\n\t subclass = proto && proto.init ? proto.init : function () {\n\t that.apply(this, arguments);\n\t },\n\t fn;\n\n\t base.prototype = that.prototype;\n\t fn = subclass.fn = subclass.prototype = new base();\n\n\t for (member in proto) {\n\t if (proto[member] != null && proto[member].constructor === Object) {\n\t // Merge object members\n\t fn[member] = extend(true, {}, base.prototype[member], proto[member]);\n\t } else {\n\t fn[member] = proto[member];\n\t }\n\t }\n\n\t fn.constructor = subclass;\n\t subclass.extend = that.extend;\n\n\t return subclass;\n\t };\n\n\t Class.prototype._initOptions = function(options) {\n\t this.options = deepExtend({}, this.options, options);\n\t };\n\n\t var isFunction = kendo.isFunction = function(fn) {\n\t return typeof fn === \"function\";\n\t };\n\n\t var preventDefault = function() {\n\t this._defaultPrevented = true;\n\t };\n\n\t var isDefaultPrevented = function() {\n\t return this._defaultPrevented === true;\n\t };\n\n\t var Observable = Class.extend({\n\t init: function() {\n\t this._events = {};\n\t },\n\n\t bind: function(eventName, handlers, one) {\n\t var that = this,\n\t idx,\n\t eventNames = typeof eventName === STRING ? [eventName] : eventName,\n\t length,\n\t original,\n\t handler,\n\t handlersIsFunction = typeof handlers === FUNCTION,\n\t events;\n\n\t if (handlers === undefined) {\n\t for (idx in eventName) {\n\t that.bind(idx, eventName[idx]);\n\t }\n\t return that;\n\t }\n\n\t for (idx = 0, length = eventNames.length; idx < length; idx++) {\n\t eventName = eventNames[idx];\n\n\t handler = handlersIsFunction ? handlers : handlers[eventName];\n\n\t if (handler) {\n\t if (one) {\n\t original = handler;\n\t handler = function() {\n\t that.unbind(eventName, handler);\n\t original.apply(that, arguments);\n\t };\n\t handler.original = original;\n\t }\n\t events = that._events[eventName] = that._events[eventName] || [];\n\t events.push(handler);\n\t }\n\t }\n\n\t return that;\n\t },\n\n\t one: function(eventNames, handlers) {\n\t return this.bind(eventNames, handlers, true);\n\t },\n\n\t first: function(eventName, handlers) {\n\t var that = this,\n\t idx,\n\t eventNames = typeof eventName === STRING ? [eventName] : eventName,\n\t length,\n\t handler,\n\t handlersIsFunction = typeof handlers === FUNCTION,\n\t events;\n\n\t for (idx = 0, length = eventNames.length; idx < length; idx++) {\n\t eventName = eventNames[idx];\n\n\t handler = handlersIsFunction ? handlers : handlers[eventName];\n\n\t if (handler) {\n\t events = that._events[eventName] = that._events[eventName] || [];\n\t events.unshift(handler);\n\t }\n\t }\n\n\t return that;\n\t },\n\n\t trigger: function(eventName, e) {\n\t var that = this,\n\t events = that._events[eventName],\n\t idx,\n\t length;\n\n\t if (events) {\n\t e = e || {};\n\n\t e.sender = that;\n\n\t e._defaultPrevented = false;\n\n\t e.preventDefault = preventDefault;\n\n\t e.isDefaultPrevented = isDefaultPrevented;\n\n\t events = events.slice();\n\n\t for (idx = 0, length = events.length; idx < length; idx++) {\n\t events[idx].call(that, e);\n\t }\n\n\t return e._defaultPrevented === true;\n\t }\n\n\t return false;\n\t },\n\n\t unbind: function(eventName, handler) {\n\t var that = this,\n\t events = that._events[eventName],\n\t idx;\n\n\t if (eventName === undefined) {\n\t that._events = {};\n\t } else if (events) {\n\t if (handler) {\n\t for (idx = events.length - 1; idx >= 0; idx--) {\n\t if (events[idx] === handler || events[idx].original === handler) {\n\t events.splice(idx, 1);\n\t }\n\t }\n\t } else {\n\t that._events[eventName] = [];\n\t }\n\t }\n\n\t return that;\n\t }\n\t });\n\n\n\t function compilePart(part, stringPart) {\n\t if (stringPart) {\n\t return \"'\" +\n\t part.split(\"'\").join(\"\\\\'\")\n\t .split('\\\\\"').join('\\\\\\\\\\\\\"')\n\t .replace(/\\n/g, \"\\\\n\")\n\t .replace(/\\r/g, \"\\\\r\")\n\t .replace(/\\t/g, \"\\\\t\") + \"'\";\n\t } else {\n\t var first = part.charAt(0),\n\t rest = part.substring(1);\n\n\t if (first === \"=\") {\n\t return \"+(\" + rest + \")+\";\n\t } else if (first === \":\") {\n\t return \"+$kendoHtmlEncode(\" + rest + \")+\";\n\t } else {\n\t return \";\" + part + \";$kendoOutput+=\";\n\t }\n\t }\n\t }\n\n\t var argumentNameRegExp = /^\\w+/,\n\t encodeRegExp = /\\$\\{([^}]*)\\}/g,\n\t escapedCurlyRegExp = /\\\\\\}/g,\n\t curlyRegExp = /__CURLY__/g,\n\t escapedSharpRegExp = /\\\\#/g,\n\t sharpRegExp = /__SHARP__/g,\n\t zeros = [\"\", \"0\", \"00\", \"000\", \"0000\"];\n\n\t Template = {\n\t paramName: \"data\", // name of the parameter of the generated template\n\t useWithBlock: true, // whether to wrap the template in a with() block\n\t render: function(template, data) {\n\t var idx,\n\t length,\n\t html = \"\";\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t html += template(data[idx]);\n\t }\n\n\t return html;\n\t },\n\t compile: function(template, options) {\n\t var settings = extend({}, this, options),\n\t paramName = settings.paramName,\n\t argumentName = paramName.match(argumentNameRegExp)[0],\n\t useWithBlock = settings.useWithBlock,\n\t functionBody = \"var $kendoOutput, $kendoHtmlEncode = kendo.htmlEncode;\",\n\t fn,\n\t parts,\n\t idx;\n\n\t if (isFunction(template)) {\n\t return template;\n\t }\n\n\t functionBody += useWithBlock ? \"with(\" + paramName + \"){\" : \"\";\n\n\t functionBody += \"$kendoOutput=\";\n\n\t parts = template\n\t .replace(escapedCurlyRegExp, \"__CURLY__\")\n\t .replace(encodeRegExp, \"#=$kendoHtmlEncode($1)#\")\n\t .replace(curlyRegExp, \"}\")\n\t .replace(escapedSharpRegExp, \"__SHARP__\")\n\t .split(\"#\");\n\n\t for (idx = 0; idx < parts.length; idx ++) {\n\t functionBody += compilePart(parts[idx], idx % 2 === 0);\n\t }\n\n\t functionBody += useWithBlock ? \";}\" : \";\";\n\n\t functionBody += \"return $kendoOutput;\";\n\n\t functionBody = functionBody.replace(sharpRegExp, \"#\");\n\n\t try {\n\t fn = new Function(argumentName, functionBody);\n\t fn._slotCount = Math.floor(parts.length / 2);\n\t return fn;\n\t } catch(e) {\n\t throw new Error(kendo.format(\"Invalid template:'{0}' Generated code:'{1}'\", template, functionBody));\n\t }\n\t }\n\t };\n\n\tfunction pad(number, digits, end) {\n\t number = number + \"\";\n\t digits = digits || 2;\n\t end = digits - number.length;\n\n\t if (end) {\n\t return zeros[digits].substring(0, end) + number;\n\t }\n\n\t return number;\n\t}\n\n\t //JSON stringify\n\t(function() {\n\t var escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n\t gap,\n\t indent,\n\t meta = {\n\t \"\\b\": \"\\\\b\",\n\t \"\\t\": \"\\\\t\",\n\t \"\\n\": \"\\\\n\",\n\t \"\\f\": \"\\\\f\",\n\t \"\\r\": \"\\\\r\",\n\t \"\\\"\" : '\\\\\"',\n\t \"\\\\\": \"\\\\\\\\\"\n\t },\n\t rep,\n\t toString = {}.toString;\n\n\n\t if (typeof Date.prototype.toJSON !== FUNCTION) {\n\n\t Date.prototype.toJSON = function () {\n\t var that = this;\n\n\t return isFinite(that.valueOf()) ?\n\t pad(that.getUTCFullYear(), 4) + \"-\" +\n\t pad(that.getUTCMonth() + 1) + \"-\" +\n\t pad(that.getUTCDate()) + \"T\" +\n\t pad(that.getUTCHours()) + \":\" +\n\t pad(that.getUTCMinutes()) + \":\" +\n\t pad(that.getUTCSeconds()) + \"Z\" : null;\n\t };\n\n\t String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function () {\n\t return this.valueOf();\n\t };\n\t }\n\n\t function quote(string) {\n\t escapable.lastIndex = 0;\n\t return escapable.test(string) ? \"\\\"\" + string.replace(escapable, function (a) {\n\t var c = meta[a];\n\t return typeof c === STRING ? c :\n\t \"\\\\u\" + (\"0000\" + a.charCodeAt(0).toString(16)).slice(-4);\n\t }) + \"\\\"\" : \"\\\"\" + string + \"\\\"\";\n\t }\n\n\t function str(key, holder) {\n\t var i,\n\t k,\n\t v,\n\t length,\n\t mind = gap,\n\t partial,\n\t value = holder[key],\n\t type;\n\n\t if (value && typeof value === OBJECT && typeof value.toJSON === FUNCTION) {\n\t value = value.toJSON(key);\n\t }\n\n\t if (typeof rep === FUNCTION) {\n\t value = rep.call(holder, key, value);\n\t }\n\n\t type = typeof value;\n\t if (type === STRING) {\n\t return quote(value);\n\t } else if (type === NUMBER) {\n\t return isFinite(value) ? String(value) : NULL;\n\t } else if (type === BOOLEAN || type === NULL) {\n\t return String(value);\n\t } else if (type === OBJECT) {\n\t if (!value) {\n\t return NULL;\n\t }\n\t gap += indent;\n\t partial = [];\n\t if (toString.apply(value) === \"[object Array]\") {\n\t length = value.length;\n\t for (i = 0; i < length; i++) {\n\t partial[i] = str(i, value) || NULL;\n\t }\n\t v = partial.length === 0 ? \"[]\" : gap ?\n\t \"[\\n\" + gap + partial.join(\",\\n\" + gap) + \"\\n\" + mind + \"]\" :\n\t \"[\" + partial.join(\",\") + \"]\";\n\t gap = mind;\n\t return v;\n\t }\n\t if (rep && typeof rep === OBJECT) {\n\t length = rep.length;\n\t for (i = 0; i < length; i++) {\n\t if (typeof rep[i] === STRING) {\n\t k = rep[i];\n\t v = str(k, value);\n\t if (v) {\n\t partial.push(quote(k) + (gap ? \": \" : \":\") + v);\n\t }\n\t }\n\t }\n\t } else {\n\t for (k in value) {\n\t if (Object.hasOwnProperty.call(value, k)) {\n\t v = str(k, value);\n\t if (v) {\n\t partial.push(quote(k) + (gap ? \": \" : \":\") + v);\n\t }\n\t }\n\t }\n\t }\n\n\t v = partial.length === 0 ? \"{}\" : gap ?\n\t \"{\\n\" + gap + partial.join(\",\\n\" + gap) + \"\\n\" + mind + \"}\" :\n\t \"{\" + partial.join(\",\") + \"}\";\n\t gap = mind;\n\t return v;\n\t }\n\t }\n\n\t if (typeof JSON.stringify !== FUNCTION) {\n\t JSON.stringify = function (value, replacer, space) {\n\t var i;\n\t gap = \"\";\n\t indent = \"\";\n\n\t if (typeof space === NUMBER) {\n\t for (i = 0; i < space; i += 1) {\n\t indent += \" \";\n\t }\n\n\t } else if (typeof space === STRING) {\n\t indent = space;\n\t }\n\n\t rep = replacer;\n\t if (replacer && typeof replacer !== FUNCTION && (typeof replacer !== OBJECT || typeof replacer.length !== NUMBER)) {\n\t throw new Error(\"JSON.stringify\");\n\t }\n\n\t return str(\"\", {\"\": value});\n\t };\n\t }\n\t})();\n\n\t// Date and Number formatting\n\t(function() {\n\t var dateFormatRegExp = /dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|HH|H|hh|h|mm|m|fff|ff|f|tt|ss|s|zzz|zz|z|\"[^\"]*\"|'[^']*'/g,\n\t standardFormatRegExp = /^(n|c|p|e)(\\d*)$/i,\n\t literalRegExp = /(\\\\.)|(['][^']*[']?)|([\"][^\"]*[\"]?)/g,\n\t commaRegExp = /\\,/g,\n\t EMPTY = \"\",\n\t POINT = \".\",\n\t COMMA = \",\",\n\t SHARP = \"#\",\n\t ZERO = \"0\",\n\t PLACEHOLDER = \"??\",\n\t EN = \"en-US\",\n\t objectToString = {}.toString;\n\n\t //cultures\n\t kendo.cultures[\"en-US\"] = {\n\t name: EN,\n\t numberFormat: {\n\t pattern: [\"-n\"],\n\t decimals: 2,\n\t \",\": \",\",\n\t \".\": \".\",\n\t groupSize: [3],\n\t percent: {\n\t pattern: [\"-n %\", \"n %\"],\n\t decimals: 2,\n\t \",\": \",\",\n\t \".\": \".\",\n\t groupSize: [3],\n\t symbol: \"%\"\n\t },\n\t currency: {\n\t name: \"US Dollar\",\n\t abbr: \"USD\",\n\t pattern: [\"($n)\", \"$n\"],\n\t decimals: 2,\n\t \",\": \",\",\n\t \".\": \".\",\n\t groupSize: [3],\n\t symbol: \"$\"\n\t }\n\t },\n\t calendars: {\n\t standard: {\n\t days: {\n\t names: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n\t namesAbbr: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n\t namesShort: [ \"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\" ]\n\t },\n\t months: {\n\t names: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n\t namesAbbr: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n\t },\n\t AM: [ \"AM\", \"am\", \"AM\" ],\n\t PM: [ \"PM\", \"pm\", \"PM\" ],\n\t patterns: {\n\t d: \"M/d/yyyy\",\n\t D: \"dddd, MMMM dd, yyyy\",\n\t F: \"dddd, MMMM dd, yyyy h:mm:ss tt\",\n\t g: \"M/d/yyyy h:mm tt\",\n\t G: \"M/d/yyyy h:mm:ss tt\",\n\t m: \"MMMM dd\",\n\t M: \"MMMM dd\",\n\t s: \"yyyy'-'MM'-'ddTHH':'mm':'ss\",\n\t t: \"h:mm tt\",\n\t T: \"h:mm:ss tt\",\n\t u: \"yyyy'-'MM'-'dd HH':'mm':'ss'Z'\",\n\t y: \"MMMM, yyyy\",\n\t Y: \"MMMM, yyyy\"\n\t },\n\t \"/\": \"/\",\n\t \":\": \":\",\n\t firstDay: 0,\n\t twoDigitYearMax: 2029\n\t }\n\t }\n\t };\n\n\n\t function findCulture(culture) {\n\t if (culture) {\n\t if (culture.numberFormat) {\n\t return culture;\n\t }\n\n\t if (typeof culture === STRING) {\n\t var cultures = kendo.cultures;\n\t return cultures[culture] || cultures[culture.split(\"-\")[0]] || null;\n\t }\n\n\t return null;\n\t }\n\n\t return null;\n\t }\n\n\t function getCulture(culture) {\n\t if (culture) {\n\t culture = findCulture(culture);\n\t }\n\n\t return culture || kendo.cultures.current;\n\t }\n\n\t kendo.culture = function(cultureName) {\n\t var cultures = kendo.cultures, culture;\n\n\t if (cultureName !== undefined) {\n\t culture = findCulture(cultureName) || cultures[EN];\n\t culture.calendar = culture.calendars.standard;\n\t cultures.current = culture;\n\t } else {\n\t return cultures.current;\n\t }\n\t };\n\n\t kendo.findCulture = findCulture;\n\t kendo.getCulture = getCulture;\n\n\t //set current culture to en-US.\n\t kendo.culture(EN);\n\n\t function formatDate(date, format, culture) {\n\t culture = getCulture(culture);\n\n\t var calendar = culture.calendars.standard,\n\t days = calendar.days,\n\t months = calendar.months;\n\n\t format = calendar.patterns[format] || format;\n\n\t return format.replace(dateFormatRegExp, function (match) {\n\t var minutes;\n\t var result;\n\t var sign;\n\n\t if (match === \"d\") {\n\t result = date.getDate();\n\t } else if (match === \"dd\") {\n\t result = pad(date.getDate());\n\t } else if (match === \"ddd\") {\n\t result = days.namesAbbr[date.getDay()];\n\t } else if (match === \"dddd\") {\n\t result = days.names[date.getDay()];\n\t } else if (match === \"M\") {\n\t result = date.getMonth() + 1;\n\t } else if (match === \"MM\") {\n\t result = pad(date.getMonth() + 1);\n\t } else if (match === \"MMM\") {\n\t result = months.namesAbbr[date.getMonth()];\n\t } else if (match === \"MMMM\") {\n\t result = months.names[date.getMonth()];\n\t } else if (match === \"yy\") {\n\t result = pad(date.getFullYear() % 100);\n\t } else if (match === \"yyyy\") {\n\t result = pad(date.getFullYear(), 4);\n\t } else if (match === \"h\" ) {\n\t result = date.getHours() % 12 || 12;\n\t } else if (match === \"hh\") {\n\t result = pad(date.getHours() % 12 || 12);\n\t } else if (match === \"H\") {\n\t result = date.getHours();\n\t } else if (match === \"HH\") {\n\t result = pad(date.getHours());\n\t } else if (match === \"m\") {\n\t result = date.getMinutes();\n\t } else if (match === \"mm\") {\n\t result = pad(date.getMinutes());\n\t } else if (match === \"s\") {\n\t result = date.getSeconds();\n\t } else if (match === \"ss\") {\n\t result = pad(date.getSeconds());\n\t } else if (match === \"f\") {\n\t result = math.floor(date.getMilliseconds() / 100);\n\t } else if (match === \"ff\") {\n\t result = date.getMilliseconds();\n\t if (result > 99) {\n\t result = math.floor(result / 10);\n\t }\n\t result = pad(result);\n\t } else if (match === \"fff\") {\n\t result = pad(date.getMilliseconds(), 3);\n\t } else if (match === \"tt\") {\n\t result = date.getHours() < 12 ? calendar.AM[0] : calendar.PM[0];\n\t } else if (match === \"zzz\") {\n\t minutes = date.getTimezoneOffset();\n\t sign = minutes < 0;\n\n\t result = math.abs(minutes / 60).toString().split(\".\")[0];\n\t minutes = math.abs(minutes) - (result * 60);\n\n\t result = (sign ? \"+\" : \"-\") + pad(result);\n\t result += \":\" + pad(minutes);\n\t } else if (match === \"zz\" || match === \"z\") {\n\t result = date.getTimezoneOffset() / 60;\n\t sign = result < 0;\n\n\t result = math.abs(result).toString().split(\".\")[0];\n\t result = (sign ? \"+\" : \"-\") + (match === \"zz\" ? pad(result) : result);\n\t }\n\n\t return result !== undefined ? result : match.slice(1, match.length - 1);\n\t });\n\t }\n\n\t //number formatting\n\t function formatNumber(number, format, culture) {\n\t culture = getCulture(culture);\n\n\t var numberFormat = culture.numberFormat,\n\t decimal = numberFormat[POINT],\n\t precision = numberFormat.decimals,\n\t pattern = numberFormat.pattern[0],\n\t literals = [],\n\t symbol,\n\t isCurrency, isPercent,\n\t customPrecision,\n\t formatAndPrecision,\n\t negative = number < 0,\n\t integer,\n\t fraction,\n\t integerLength,\n\t fractionLength,\n\t replacement = EMPTY,\n\t value = EMPTY,\n\t idx,\n\t length,\n\t ch,\n\t hasGroup,\n\t hasNegativeFormat,\n\t decimalIndex,\n\t sharpIndex,\n\t zeroIndex,\n\t hasZero, hasSharp,\n\t percentIndex,\n\t currencyIndex,\n\t startZeroIndex,\n\t start = -1,\n\t end;\n\n\t //return empty string if no number\n\t if (number === undefined) {\n\t return EMPTY;\n\t }\n\n\t if (!isFinite(number)) {\n\t return number;\n\t }\n\n\t //if no format then return number.toString() or number.toLocaleString() if culture.name is not defined\n\t if (!format) {\n\t return culture.name.length ? number.toLocaleString() : number.toString();\n\t }\n\n\t formatAndPrecision = standardFormatRegExp.exec(format);\n\n\t // standard formatting\n\t if (formatAndPrecision) {\n\t format = formatAndPrecision[1].toLowerCase();\n\n\t isCurrency = format === \"c\";\n\t isPercent = format === \"p\";\n\n\t if (isCurrency || isPercent) {\n\t //get specific number format information if format is currency or percent\n\t numberFormat = isCurrency ? numberFormat.currency : numberFormat.percent;\n\t decimal = numberFormat[POINT];\n\t precision = numberFormat.decimals;\n\t symbol = numberFormat.symbol;\n\t pattern = numberFormat.pattern[negative ? 0 : 1];\n\t }\n\n\t customPrecision = formatAndPrecision[2];\n\n\t if (customPrecision) {\n\t precision = +customPrecision;\n\t }\n\n\t //return number in exponential format\n\t if (format === \"e\") {\n\t var exp = customPrecision ? number.toExponential(precision) : number.toExponential(); // toExponential() and toExponential(undefined) differ in FF #653438.\n\n\t return exp.replace(POINT, numberFormat[POINT]);\n\t }\n\n\t // multiply if format is percent\n\t if (isPercent) {\n\t number *= 100;\n\t }\n\n\t number = round(number, precision);\n\t negative = number < 0;\n\t number = number.split(POINT);\n\n\t integer = number[0];\n\t fraction = number[1];\n\n\t //exclude \"-\" if number is negative.\n\t if (negative) {\n\t integer = integer.substring(1);\n\t }\n\n\t value = groupInteger(integer, 0, integer.length, numberFormat);\n\n\t if (fraction) {\n\t value += decimal + fraction;\n\t }\n\n\t if (format === \"n\" && !negative) {\n\t return value;\n\t }\n\n\t number = EMPTY;\n\n\t for (idx = 0, length = pattern.length; idx < length; idx++) {\n\t ch = pattern.charAt(idx);\n\n\t if (ch === \"n\") {\n\t number += value;\n\t } else if (ch === \"$\" || ch === \"%\") {\n\t number += symbol;\n\t } else {\n\t number += ch;\n\t }\n\t }\n\n\t return number;\n\t }\n\n\t //custom formatting\n\t //\n\t //separate format by sections.\n\n\t if (format.indexOf(\"'\") > -1 || format.indexOf(\"\\\"\") > -1 || format.indexOf(\"\\\\\") > -1) {\n\t format = format.replace(literalRegExp, function (match) {\n\t var quoteChar = match.charAt(0).replace(\"\\\\\", \"\"),\n\t literal = match.slice(1).replace(quoteChar, \"\");\n\n\t literals.push(literal);\n\n\t return PLACEHOLDER;\n\t });\n\t }\n\n\t format = format.split(\";\");\n\t if (negative && format[1]) {\n\t //get negative format\n\t format = format[1];\n\t hasNegativeFormat = true;\n\t } else if (number === 0 && format[2]) {\n\t //format for zeros\n\t format = format[2];\n\t if (format.indexOf(SHARP) == -1 && format.indexOf(ZERO) == -1) {\n\t //return format if it is string constant.\n\t return format;\n\t }\n\t } else {\n\t format = format[0];\n\t }\n\n\t percentIndex = format.indexOf(\"%\");\n\t currencyIndex = format.indexOf(\"$\");\n\n\t isPercent = percentIndex != -1;\n\t isCurrency = currencyIndex != -1;\n\n\t //multiply number if the format has percent\n\t if (isPercent) {\n\t number *= 100;\n\t }\n\n\t if (isCurrency && format[currencyIndex - 1] === \"\\\\\") {\n\t format = format.split(\"\\\\\").join(\"\");\n\t isCurrency = false;\n\t }\n\n\t if (isCurrency || isPercent) {\n\t //get specific number format information if format is currency or percent\n\t numberFormat = isCurrency ? numberFormat.currency : numberFormat.percent;\n\t decimal = numberFormat[POINT];\n\t precision = numberFormat.decimals;\n\t symbol = numberFormat.symbol;\n\t }\n\n\t hasGroup = format.indexOf(COMMA) > -1;\n\t if (hasGroup) {\n\t format = format.replace(commaRegExp, EMPTY);\n\t }\n\n\t decimalIndex = format.indexOf(POINT);\n\t length = format.length;\n\n\t if (decimalIndex != -1) {\n\t fraction = number.toString().split(\"e\");\n\t if (fraction[1]) {\n\t fraction = round(number, Math.abs(fraction[1]));\n\t } else {\n\t fraction = fraction[0];\n\t }\n\t fraction = fraction.split(POINT)[1] || EMPTY;\n\t zeroIndex = format.lastIndexOf(ZERO) - decimalIndex;\n\t sharpIndex = format.lastIndexOf(SHARP) - decimalIndex;\n\t hasZero = zeroIndex > -1;\n\t hasSharp = sharpIndex > -1;\n\t idx = fraction.length;\n\n\t if (!hasZero && !hasSharp) {\n\t format = format.substring(0, decimalIndex) + format.substring(decimalIndex + 1);\n\t length = format.length;\n\t decimalIndex = -1;\n\t idx = 0;\n\t }\n\n\t if (hasZero && zeroIndex > sharpIndex) {\n\t idx = zeroIndex;\n\t } else if (sharpIndex > zeroIndex) {\n\t if (hasSharp && idx > sharpIndex) {\n\t var rounded = round(number, sharpIndex, negative);\n\n\t while (rounded.charAt(rounded.length - 1) === ZERO && sharpIndex > 0 && sharpIndex > zeroIndex) {\n\t sharpIndex--;\n\n\t rounded = round(number, sharpIndex, negative);\n\t }\n\n\t idx = sharpIndex;\n\t } else if (hasZero && idx < zeroIndex) {\n\t idx = zeroIndex;\n\t }\n\t }\n\t }\n\n\t number = round(number, idx, negative);\n\n\t sharpIndex = format.indexOf(SHARP);\n\t startZeroIndex = zeroIndex = format.indexOf(ZERO);\n\n\t //define the index of the first digit placeholder\n\t if (sharpIndex == -1 && zeroIndex != -1) {\n\t start = zeroIndex;\n\t } else if (sharpIndex != -1 && zeroIndex == -1) {\n\t start = sharpIndex;\n\t } else {\n\t start = sharpIndex > zeroIndex ? zeroIndex : sharpIndex;\n\t }\n\n\t sharpIndex = format.lastIndexOf(SHARP);\n\t zeroIndex = format.lastIndexOf(ZERO);\n\n\t //define the index of the last digit placeholder\n\t if (sharpIndex == -1 && zeroIndex != -1) {\n\t end = zeroIndex;\n\t } else if (sharpIndex != -1 && zeroIndex == -1) {\n\t end = sharpIndex;\n\t } else {\n\t end = sharpIndex > zeroIndex ? sharpIndex : zeroIndex;\n\t }\n\n\t if (start == length) {\n\t end = start;\n\t }\n\n\t if (start != -1) {\n\t value = number.toString().split(POINT);\n\t integer = value[0];\n\t fraction = value[1] || EMPTY;\n\n\t integerLength = integer.length;\n\t fractionLength = fraction.length;\n\n\t if (negative && (number * -1) >= 0) {\n\t negative = false;\n\t }\n\n\t number = format.substring(0, start);\n\n\t if (negative && !hasNegativeFormat) {\n\t number += \"-\";\n\t }\n\n\t for (idx = start; idx < length; idx++) {\n\t ch = format.charAt(idx);\n\n\t if (decimalIndex == -1) {\n\t if (end - idx < integerLength) {\n\t number += integer;\n\t break;\n\t }\n\t } else {\n\t if (zeroIndex != -1 && zeroIndex < idx) {\n\t replacement = EMPTY;\n\t }\n\n\t if ((decimalIndex - idx) <= integerLength && decimalIndex - idx > -1) {\n\t number += integer;\n\t idx = decimalIndex;\n\t }\n\n\t if (decimalIndex === idx) {\n\t number += (fraction ? decimal : EMPTY) + fraction;\n\t idx += end - decimalIndex + 1;\n\t continue;\n\t }\n\t }\n\n\t if (ch === ZERO) {\n\t number += ch;\n\t replacement = ch;\n\t } else if (ch === SHARP) {\n\t number += replacement;\n\t }\n\t }\n\n\t if (hasGroup) {\n\t number = groupInteger(number, start + (negative && !hasNegativeFormat ? 1 : 0), Math.max(end, (integerLength + start)), numberFormat);\n\t }\n\n\t if (end >= start) {\n\t number += format.substring(end + 1);\n\t }\n\n\t //replace symbol placeholders\n\t if (isCurrency || isPercent) {\n\t value = EMPTY;\n\t for (idx = 0, length = number.length; idx < length; idx++) {\n\t ch = number.charAt(idx);\n\t value += (ch === \"$\" || ch === \"%\") ? symbol : ch;\n\t }\n\t number = value;\n\t }\n\n\t length = literals.length;\n\n\t if (length) {\n\t for (idx = 0; idx < length; idx++) {\n\t number = number.replace(PLACEHOLDER, literals[idx]);\n\t }\n\t }\n\t }\n\n\t return number;\n\t }\n\n\t var groupInteger = function(number, start, end, numberFormat) {\n\t var decimalIndex = number.indexOf(numberFormat[POINT]);\n\t var groupSizes = numberFormat.groupSize.slice();\n\t var groupSize = groupSizes.shift();\n\t var integer, integerLength;\n\t var idx, parts, value;\n\t var newGroupSize;\n\n\t end = decimalIndex !== -1 ? decimalIndex : end + 1;\n\n\t integer = number.substring(start, end);\n\t integerLength = integer.length;\n\n\t if (integerLength >= groupSize) {\n\t idx = integerLength;\n\t parts = [];\n\n\t while (idx > -1) {\n\t value = integer.substring(idx - groupSize, idx);\n\t if (value) {\n\t parts.push(value);\n\t }\n\t idx -= groupSize;\n\t newGroupSize = groupSizes.shift();\n\t groupSize = newGroupSize !== undefined ? newGroupSize : groupSize;\n\n\t if (groupSize === 0) {\n\t if (idx > 0) {\n\t parts.push(integer.substring(0, idx));\n\t }\n\t break;\n\t }\n\t }\n\n\t integer = parts.reverse().join(numberFormat[COMMA]);\n\t number = number.substring(0, start) + integer + number.substring(end);\n\t }\n\n\t return number;\n\t };\n\n\t var round = function(value, precision, negative) {\n\t precision = precision || 0;\n\n\t value = value.toString().split('e');\n\t value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + precision) : precision)));\n\n\t if (negative) {\n\t value = -value;\n\t }\n\n\t value = value.toString().split('e');\n\t value = +(value[0] + 'e' + (value[1] ? (+value[1] - precision) : -precision));\n\n\t return value.toFixed(Math.min(precision, 20));\n\t };\n\n\t var toString = function(value, fmt, culture) {\n\t if (fmt) {\n\t if (objectToString.call(value) === \"[object Date]\") {\n\t return formatDate(value, fmt, culture);\n\t } else if (typeof value === NUMBER) {\n\t return formatNumber(value, fmt, culture);\n\t }\n\t }\n\n\t return value !== undefined ? value : \"\";\n\t };\n\n\t kendo.format = function(fmt) {\n\t var values = arguments;\n\n\t return fmt.replace(formatRegExp, function(match, index, placeholderFormat) {\n\t var value = values[parseInt(index, 10) + 1];\n\n\t return toString(value, placeholderFormat ? placeholderFormat.substring(1) : \"\");\n\t });\n\t };\n\n\t kendo._extractFormat = function (format) {\n\t if (format.slice(0,3) === \"{0:\") {\n\t format = format.slice(3, format.length - 1);\n\t }\n\n\t return format;\n\t };\n\n\t kendo._activeElement = function() {\n\t try {\n\t return document.activeElement;\n\t } catch(e) {\n\t return document.documentElement.activeElement;\n\t }\n\t };\n\n\t kendo._round = round;\n\t kendo._outerWidth = function (element, includeMargin) { return $(element).outerWidth(includeMargin || false) || 0; };\n\t kendo._outerHeight = function (element, includeMargin) { return $(element).outerHeight(includeMargin || false) || 0; };\n\t kendo.toString = toString;\n\t})();\n\n\n\t(function() {\n\t var nonBreakingSpaceRegExp = /\\u00A0/g,\n\t exponentRegExp = /[eE][\\-+]?[0-9]+/,\n\t shortTimeZoneRegExp = /[+|\\-]\\d{1,2}/,\n\t longTimeZoneRegExp = /[+|\\-]\\d{1,2}:?\\d{2}/,\n\t dateRegExp = /^\\/Date\\((.*?)\\)\\/$/,\n\t offsetRegExp = /[+-]\\d*/,\n\t FORMATS_SEQUENCE = [ [], [ \"G\", \"g\", \"F\" ], [ \"D\", \"d\", \"y\", \"m\", \"T\", \"t\" ] ],\n\t STANDARD_FORMATS = [\n\t [\n\t \"yyyy-MM-ddTHH:mm:ss.fffffffzzz\",\n\t \"yyyy-MM-ddTHH:mm:ss.fffffff\",\n\t \"yyyy-MM-ddTHH:mm:ss.fffzzz\",\n\t \"yyyy-MM-ddTHH:mm:ss.fff\",\n\t \"ddd MMM dd yyyy HH:mm:ss\",\n\t \"yyyy-MM-ddTHH:mm:sszzz\",\n\t \"yyyy-MM-ddTHH:mmzzz\",\n\t \"yyyy-MM-ddTHH:mmzz\",\n\t \"yyyy-MM-ddTHH:mm:ss\",\n\t \"yyyy-MM-dd HH:mm:ss\",\n\t \"yyyy/MM/dd HH:mm:ss\"\n\t ], [\n\t \"yyyy-MM-ddTHH:mm\",\n\t \"yyyy-MM-dd HH:mm\",\n\t \"yyyy/MM/dd HH:mm\"\n\t ], [\n\t \"yyyy/MM/dd\",\n\t \"yyyy-MM-dd\",\n\t \"HH:mm:ss\",\n\t \"HH:mm\"\n\t ]\n\t ],\n\t numberRegExp = {\n\t 2: /^\\d{1,2}/,\n\t 3: /^\\d{1,3}/,\n\t 4: /^\\d{4}/\n\t },\n\t objectToString = {}.toString;\n\n\t function outOfRange(value, start, end) {\n\t return !(value >= start && value <= end);\n\t }\n\n\t function designatorPredicate(designator) {\n\t return designator.charAt(0);\n\t }\n\n\t function mapDesignators(designators) {\n\t return $.map(designators, designatorPredicate);\n\t }\n\n\t //if date's day is different than the typed one - adjust\n\t function adjustDST(date, hours) {\n\t if (!hours && date.getHours() === 23) {\n\t date.setHours(date.getHours() + 2);\n\t }\n\t }\n\n\t function lowerArray(data) {\n\t var idx = 0,\n\t length = data.length,\n\t array = [];\n\n\t for (; idx < length; idx++) {\n\t array[idx] = (data[idx] + \"\").toLowerCase();\n\t }\n\n\t return array;\n\t }\n\n\t function lowerLocalInfo(localInfo) {\n\t var newLocalInfo = {}, property;\n\n\t for (property in localInfo) {\n\t newLocalInfo[property] = lowerArray(localInfo[property]);\n\t }\n\n\t return newLocalInfo;\n\t }\n\n\t function parseExact(value, format, culture, strict) {\n\t if (!value) {\n\t return null;\n\t }\n\n\t var lookAhead = function (match) {\n\t var i = 0;\n\t while (format[idx] === match) {\n\t i++;\n\t idx++;\n\t }\n\t if (i > 0) {\n\t idx -= 1;\n\t }\n\t return i;\n\t },\n\t getNumber = function(size) {\n\t var rg = numberRegExp[size] || new RegExp('^\\\\d{1,' + size + '}'),\n\t match = value.substr(valueIdx, size).match(rg);\n\n\t if (match) {\n\t match = match[0];\n\t valueIdx += match.length;\n\t return parseInt(match, 10);\n\t }\n\t return null;\n\t },\n\t getIndexByName = function (names, lower) {\n\t var i = 0,\n\t length = names.length,\n\t name, nameLength,\n\t matchLength = 0,\n\t matchIdx = 0,\n\t subValue;\n\n\t for (; i < length; i++) {\n\t name = names[i];\n\t nameLength = name.length;\n\t subValue = value.substr(valueIdx, nameLength);\n\n\t if (lower) {\n\t subValue = subValue.toLowerCase();\n\t }\n\n\t if (subValue == name && nameLength > matchLength) {\n\t matchLength = nameLength;\n\t matchIdx = i;\n\t }\n\t }\n\n\t if (matchLength) {\n\t valueIdx += matchLength;\n\t return matchIdx + 1;\n\t }\n\n\t return null;\n\t },\n\t checkLiteral = function() {\n\t var result = false;\n\t if (value.charAt(valueIdx) === format[idx]) {\n\t valueIdx++;\n\t result = true;\n\t }\n\t return result;\n\t },\n\t calendar = culture.calendars.standard,\n\t year = null,\n\t month = null,\n\t day = null,\n\t hours = null,\n\t minutes = null,\n\t seconds = null,\n\t milliseconds = null,\n\t idx = 0,\n\t valueIdx = 0,\n\t literal = false,\n\t date = new Date(),\n\t twoDigitYearMax = calendar.twoDigitYearMax || 2029,\n\t defaultYear = date.getFullYear(),\n\t ch, count, length, pattern,\n\t pmHour, UTC, matches,\n\t amDesignators, pmDesignators,\n\t hoursOffset, minutesOffset,\n\t hasTime, match;\n\n\t if (!format) {\n\t format = \"d\"; //shord date format\n\t }\n\n\t //if format is part of the patterns get real format\n\t pattern = calendar.patterns[format];\n\t if (pattern) {\n\t format = pattern;\n\t }\n\n\t format = format.split(\"\");\n\t length = format.length;\n\n\t for (; idx < length; idx++) {\n\t ch = format[idx];\n\n\t if (literal) {\n\t if (ch === \"'\") {\n\t literal = false;\n\t } else {\n\t checkLiteral();\n\t }\n\t } else {\n\t if (ch === \"d\") {\n\t count = lookAhead(\"d\");\n\t if (!calendar._lowerDays) {\n\t calendar._lowerDays = lowerLocalInfo(calendar.days);\n\t }\n\n\t if (day !== null && count > 2) {\n\t continue;\n\t }\n\n\t day = count < 3 ? getNumber(2) : getIndexByName(calendar._lowerDays[count == 3 ? \"namesAbbr\" : \"names\"], true);\n\n\t if (day === null || outOfRange(day, 1, 31)) {\n\t return null;\n\t }\n\t } else if (ch === \"M\") {\n\t count = lookAhead(\"M\");\n\t if (!calendar._lowerMonths) {\n\t calendar._lowerMonths = lowerLocalInfo(calendar.months);\n\t }\n\t month = count < 3 ? getNumber(2) : getIndexByName(calendar._lowerMonths[count == 3 ? 'namesAbbr' : 'names'], true);\n\n\t if (month === null || outOfRange(month, 1, 12)) {\n\t return null;\n\t }\n\t month -= 1; //because month is zero based\n\t } else if (ch === \"y\") {\n\t count = lookAhead(\"y\");\n\t year = getNumber(count);\n\n\t if (year === null) {\n\t return null;\n\t }\n\n\t if (count == 2) {\n\t if (typeof twoDigitYearMax === \"string\") {\n\t twoDigitYearMax = defaultYear + parseInt(twoDigitYearMax, 10);\n\t }\n\n\t year = (defaultYear - defaultYear % 100) + year;\n\t if (year > twoDigitYearMax) {\n\t year -= 100;\n\t }\n\t }\n\t } else if (ch === \"h\" ) {\n\t lookAhead(\"h\");\n\t hours = getNumber(2);\n\t if (hours == 12) {\n\t hours = 0;\n\t }\n\t if (hours === null || outOfRange(hours, 0, 11)) {\n\t return null;\n\t }\n\t } else if (ch === \"H\") {\n\t lookAhead(\"H\");\n\t hours = getNumber(2);\n\t if (hours === null || outOfRange(hours, 0, 23)) {\n\t return null;\n\t }\n\t } else if (ch === \"m\") {\n\t lookAhead(\"m\");\n\t minutes = getNumber(2);\n\t if (minutes === null || outOfRange(minutes, 0, 59)) {\n\t return null;\n\t }\n\t } else if (ch === \"s\") {\n\t lookAhead(\"s\");\n\t seconds = getNumber(2);\n\t if (seconds === null || outOfRange(seconds, 0, 59)) {\n\t return null;\n\t }\n\t } else if (ch === \"f\") {\n\t count = lookAhead(\"f\");\n\n\t match = value.substr(valueIdx, count).match(numberRegExp[3]);\n\t milliseconds = getNumber(count); //move value index position\n\n\t if (milliseconds !== null) {\n\t milliseconds = parseFloat(\"0.\" + match[0], 10);\n\t milliseconds = kendo._round(milliseconds, 3);\n\t milliseconds *= 1000;\n\t }\n\n\t if (milliseconds === null || outOfRange(milliseconds, 0, 999)) {\n\t return null;\n\t }\n\n\t } else if (ch === \"t\") {\n\t count = lookAhead(\"t\");\n\t amDesignators = calendar.AM;\n\t pmDesignators = calendar.PM;\n\n\t if (count === 1) {\n\t amDesignators = mapDesignators(amDesignators);\n\t pmDesignators = mapDesignators(pmDesignators);\n\t }\n\n\t pmHour = getIndexByName(pmDesignators);\n\t if (!pmHour && !getIndexByName(amDesignators)) {\n\t return null;\n\t }\n\t }\n\t else if (ch === \"z\") {\n\t UTC = true;\n\t count = lookAhead(\"z\");\n\n\t if (value.substr(valueIdx, 1) === \"Z\") {\n\t checkLiteral();\n\t continue;\n\t }\n\n\t matches = value.substr(valueIdx, 6)\n\t .match(count > 2 ? longTimeZoneRegExp : shortTimeZoneRegExp);\n\n\t if (!matches) {\n\t return null;\n\t }\n\n\t matches = matches[0].split(\":\");\n\n\t hoursOffset = matches[0];\n\t minutesOffset = matches[1];\n\n\t if (!minutesOffset && hoursOffset.length > 3) { //(+|-)[hh][mm] format is used\n\t valueIdx = hoursOffset.length - 2;\n\t minutesOffset = hoursOffset.substring(valueIdx);\n\t hoursOffset = hoursOffset.substring(0, valueIdx);\n\t }\n\n\t hoursOffset = parseInt(hoursOffset, 10);\n\t if (outOfRange(hoursOffset, -12, 13)) {\n\t return null;\n\t }\n\n\t if (count > 2) {\n\t minutesOffset = matches[0][0] + minutesOffset;\n\t minutesOffset = parseInt(minutesOffset, 10);\n\t if (isNaN(minutesOffset) || outOfRange(minutesOffset, -59, 59)) {\n\t return null;\n\t }\n\t }\n\t } else if (ch === \"'\") {\n\t literal = true;\n\t checkLiteral();\n\t } else if (!checkLiteral()) {\n\t return null;\n\t }\n\t }\n\t }\n\n\t // if more characters follow, assume wrong format\n\t // https://github.com/telerik/kendo-ui-core/issues/3476\n\t if (strict && !/^\\s*$/.test(value.substr(valueIdx))) {\n\t return null;\n\t }\n\n\t hasTime = hours !== null || minutes !== null || seconds || null;\n\n\t if (year === null && month === null && day === null && hasTime) {\n\t year = defaultYear;\n\t month = date.getMonth();\n\t day = date.getDate();\n\t } else {\n\t if (year === null) {\n\t year = defaultYear;\n\t }\n\n\t if (day === null) {\n\t day = 1;\n\t }\n\t }\n\n\t if (pmHour && hours < 12) {\n\t hours += 12;\n\t }\n\n\t if (UTC) {\n\t if (hoursOffset) {\n\t hours += -hoursOffset;\n\t }\n\n\t if (minutesOffset) {\n\t minutes += -minutesOffset;\n\t }\n\n\t value = new Date(Date.UTC(year, month, day, hours, minutes, seconds, milliseconds));\n\t } else {\n\t value = new Date(year, month, day, hours, minutes, seconds, milliseconds);\n\t adjustDST(value, hours);\n\t }\n\n\t if (year < 100) {\n\t value.setFullYear(year);\n\t }\n\n\t if (value.getDate() !== day && UTC === undefined) {\n\t return null;\n\t }\n\n\t return value;\n\t }\n\n\t function parseMicrosoftFormatOffset(offset) {\n\t var sign = offset.substr(0, 1) === \"-\" ? -1 : 1;\n\n\t offset = offset.substring(1);\n\t offset = (parseInt(offset.substr(0, 2), 10) * 60) + parseInt(offset.substring(2), 10);\n\n\t return sign * offset;\n\t }\n\n\t function getDefaultFormats(culture) {\n\t var length = math.max(FORMATS_SEQUENCE.length, STANDARD_FORMATS.length);\n\t var calendar = culture.calendar || culture.calendars.standard;\n\t var patterns = calendar.patterns;\n\t var cultureFormats, formatIdx, idx;\n\t var formats = [];\n\n\t for (idx = 0; idx < length; idx++) {\n\t cultureFormats = FORMATS_SEQUENCE[idx];\n\t for (formatIdx = 0; formatIdx < cultureFormats.length; formatIdx++) {\n\t formats.push(patterns[cultureFormats[formatIdx]]);\n\t }\n\t formats = formats.concat(STANDARD_FORMATS[idx]);\n\t }\n\n\t return formats;\n\t }\n\n\t function internalParseDate(value, formats, culture, strict) {\n\t if (objectToString.call(value) === \"[object Date]\") {\n\t return value;\n\t }\n\n\t var idx = 0;\n\t var date = null;\n\t var length;\n\t var tzoffset;\n\n\t if (value && value.indexOf(\"/D\") === 0) {\n\t date = dateRegExp.exec(value);\n\t if (date) {\n\t date = date[1];\n\t tzoffset = offsetRegExp.exec(date.substring(1));\n\n\t date = new Date(parseInt(date, 10));\n\n\t if (tzoffset) {\n\t tzoffset = parseMicrosoftFormatOffset(tzoffset[0]);\n\t date = kendo.timezone.apply(date, 0);\n\t date = kendo.timezone.convert(date, 0, -1 * tzoffset);\n\t }\n\n\t return date;\n\t }\n\t }\n\n\t culture = kendo.getCulture(culture);\n\n\t if (!formats) {\n\t formats = getDefaultFormats(culture);\n\t }\n\n\t formats = isArray(formats) ? formats: [formats];\n\t length = formats.length;\n\n\t for (; idx < length; idx++) {\n\t date = parseExact(value, formats[idx], culture, strict);\n\t if (date) {\n\t return date;\n\t }\n\t }\n\n\t return date;\n\t }\n\n\t kendo.parseDate = function(value, formats, culture) {\n\t return internalParseDate(value, formats, culture, false);\n\t };\n\n\t kendo.parseExactDate = function(value, formats, culture) {\n\t return internalParseDate(value, formats, culture, true);\n\t };\n\n\t kendo.parseInt = function(value, culture) {\n\t var result = kendo.parseFloat(value, culture);\n\t if (result) {\n\t result = result | 0;\n\t }\n\t return result;\n\t };\n\n\t kendo.parseFloat = function(value, culture, format) {\n\t if (!value && value !== 0) {\n\t return null;\n\t }\n\n\t if (typeof value === NUMBER) {\n\t return value;\n\t }\n\n\t value = value.toString();\n\t culture = kendo.getCulture(culture);\n\n\t var number = culture.numberFormat,\n\t percent = number.percent,\n\t currency = number.currency,\n\t symbol = currency.symbol,\n\t percentSymbol = percent.symbol,\n\t negative = value.indexOf(\"-\"),\n\t parts, isPercent;\n\n\t //handle exponential number\n\t if (exponentRegExp.test(value)) {\n\t value = parseFloat(value.replace(number[\".\"], \".\"));\n\t if (isNaN(value)) {\n\t value = null;\n\t }\n\t return value;\n\t }\n\n\t if (negative > 0) {\n\t return null;\n\t } else {\n\t negative = negative > -1;\n\t }\n\n\t if (value.indexOf(symbol) > -1 || (format && format.toLowerCase().indexOf(\"c\") > -1)) {\n\t number = currency;\n\t parts = number.pattern[0].replace(\"$\", symbol).split(\"n\");\n\t if (value.indexOf(parts[0]) > -1 && value.indexOf(parts[1]) > -1) {\n\t value = value.replace(parts[0], \"\").replace(parts[1], \"\");\n\t negative = true;\n\t }\n\t } else if (value.indexOf(percentSymbol) > -1) {\n\t isPercent = true;\n\t number = percent;\n\t symbol = percentSymbol;\n\t }\n\n\t value = value.replace(\"-\", \"\")\n\t .replace(symbol, \"\")\n\t .replace(nonBreakingSpaceRegExp, \" \")\n\t .split(number[\",\"].replace(nonBreakingSpaceRegExp, \" \")).join(\"\")\n\t .replace(number[\".\"], \".\");\n\n\t value = parseFloat(value);\n\n\t if (isNaN(value)) {\n\t value = null;\n\t } else if (negative) {\n\t value *= -1;\n\t }\n\n\t if (value && isPercent) {\n\t value /= 100;\n\t }\n\n\t return value;\n\t };\n\t})();\n\n\t function getShadows(element) {\n\t var shadow = element.css(kendo.support.transitions.css + \"box-shadow\") || element.css(\"box-shadow\"),\n\t radius = shadow ? shadow.match(boxShadowRegExp) || [ 0, 0, 0, 0, 0 ] : [ 0, 0, 0, 0, 0 ],\n\t blur = math.max((+radius[3]), +(radius[4] || 0));\n\n\t return {\n\t left: (-radius[1]) + blur,\n\t right: (+radius[1]) + blur,\n\t bottom: (+radius[2]) + blur\n\t };\n\t }\n\n\t function wrap(element, autosize) {\n\t var browser = support.browser,\n\t percentage,\n\t outerWidth = kendo._outerWidth,\n\t outerHeight = kendo._outerHeight,\n\t parent = element.parent(),\n\t windowOuterWidth = outerWidth(window);\n\n\t parent.removeClass(\"k-animation-container-sm\");\n\n\t if (!parent.hasClass(\"k-animation-container\")) {\n\t var width = element[0].style.width,\n\t height = element[0].style.height,\n\t percentWidth = percentRegExp.test(width),\n\t percentHeight = percentRegExp.test(height),\n\t forceWidth = element.hasClass(\"k-tooltip\") || element.is(\".k-menu-horizontal.k-context-menu\");\n\n\t percentage = percentWidth || percentHeight;\n\n\t if (!percentWidth && (!autosize || (autosize && width) || forceWidth)) { width = autosize ? outerWidth(element) + 1 : outerWidth(element); }\n\t if (!percentHeight && (!autosize || (autosize && height)) || element.is(\".k-menu-horizontal.k-context-menu\")) { height = outerHeight(element); }\n\n\t element.wrap(\n\t $(\"
    \")\n\t .addClass(\"k-animation-container\")\n\t .css({\n\t width: width,\n\t height: height\n\t }));\n\t parent = element.parent();\n\n\t if (percentage) {\n\t element.css({\n\t width: \"100%\",\n\t height: \"100%\",\n\t boxSizing: \"border-box\",\n\t mozBoxSizing: \"border-box\",\n\t webkitBoxSizing: \"border-box\"\n\t });\n\t }\n\t } else {\n\t wrapResize(element, autosize);\n\t }\n\n\t if(windowOuterWidth < outerWidth(parent)){\n\t parent.addClass(\"k-animation-container-sm\");\n\n\t wrapResize(element, autosize);\n\t }\n\n\t if (browser.msie && math.floor(browser.version) <= 7) {\n\t element.css({ zoom: 1 });\n\t element.children(\".k-menu\").width(element.width());\n\t }\n\n\t return parent;\n\t }\n\n\t function wrapResize(element, autosize) {\n\t var percentage,\n\t outerWidth = kendo._outerWidth,\n\t outerHeight = kendo._outerHeight,\n\t wrapper = element.parent(\".k-animation-container\"),\n\t wrapperStyle = wrapper[0].style;\n\n\t if (wrapper.is(\":hidden\")) {\n\t wrapper.css({\n\t display: \"\",\n\t position: \"\"\n\t });\n\t }\n\n\t percentage = percentRegExp.test(wrapperStyle.width) || percentRegExp.test(wrapperStyle.height);\n\n\t if (!percentage) {\n\t wrapper.css({\n\t width: autosize ? outerWidth(element) + 1 : outerWidth(element),\n\t height: outerHeight(element),\n\t boxSizing: \"content-box\",\n\t mozBoxSizing: \"content-box\",\n\t webkitBoxSizing: \"content-box\"\n\t });\n\t }\n\t }\n\n\t function deepExtend(destination) {\n\t var i = 1,\n\t length = arguments.length;\n\n\t for (i = 1; i < length; i++) {\n\t deepExtendOne(destination, arguments[i]);\n\t }\n\n\t return destination;\n\t }\n\n\t function deepExtendOne(destination, source) {\n\t var ObservableArray = kendo.data.ObservableArray,\n\t LazyObservableArray = kendo.data.LazyObservableArray,\n\t DataSource = kendo.data.DataSource,\n\t HierarchicalDataSource = kendo.data.HierarchicalDataSource,\n\t property,\n\t propValue,\n\t propType,\n\t propInit,\n\t destProp;\n\n\t for (property in source) {\n\t propValue = source[property];\n\t propType = typeof propValue;\n\n\t if (propType === OBJECT && propValue !== null) {\n\t propInit = propValue.constructor;\n\t } else {\n\t propInit = null;\n\t }\n\n\t if (propInit &&\n\t propInit !== Array && propInit !== ObservableArray && propInit !== LazyObservableArray &&\n\t propInit !== DataSource && propInit !== HierarchicalDataSource && propInit !== RegExp &&\n\t (!kendo.isFunction(window.ArrayBuffer) || propInit !== ArrayBuffer)) {\n\n\t if (propValue instanceof Date) {\n\t destination[property] = new Date(propValue.getTime());\n\t } else if (isFunction(propValue.clone)) {\n\t destination[property] = propValue.clone();\n\t } else {\n\t destProp = destination[property];\n\t if (typeof (destProp) === OBJECT) {\n\t destination[property] = destProp || {};\n\t } else {\n\t destination[property] = {};\n\t }\n\t deepExtendOne(destination[property], propValue);\n\t }\n\t } else if (propType !== UNDEFINED) {\n\t destination[property] = propValue;\n\t }\n\t }\n\n\t return destination;\n\t }\n\n\t function testRx(agent, rxs, dflt) {\n\t for (var rx in rxs) {\n\t if (rxs.hasOwnProperty(rx) && rxs[rx].test(agent)) {\n\t return rx;\n\t }\n\t }\n\t return dflt !== undefined ? dflt : agent;\n\t }\n\n\t function toHyphens(str) {\n\t return str.replace(/([a-z][A-Z])/g, function (g) {\n\t return g.charAt(0) + '-' + g.charAt(1).toLowerCase();\n\t });\n\t }\n\n\t function toCamelCase(str) {\n\t return str.replace(/\\-(\\w)/g, function (strMatch, g1) {\n\t return g1.toUpperCase();\n\t });\n\t }\n\n\t function getComputedStyles(element, properties) {\n\t var styles = {}, computedStyle;\n\n\t if (document.defaultView && document.defaultView.getComputedStyle) {\n\t computedStyle = document.defaultView.getComputedStyle(element, \"\");\n\n\t if (properties) {\n\t $.each(properties, function(idx, value) {\n\t styles[value] = computedStyle.getPropertyValue(value);\n\t });\n\t }\n\t } else {\n\t computedStyle = element.currentStyle;\n\n\t if (properties) {\n\t $.each(properties, function(idx, value) {\n\t styles[value] = computedStyle[toCamelCase(value)];\n\t });\n\t }\n\t }\n\n\t if (!kendo.size(styles)) {\n\t styles = computedStyle;\n\t }\n\n\t return styles;\n\t }\n\n\t function isScrollable(element) {\n\t if (element && element.className && typeof(element.className) === \"string\" && element.className.indexOf(\"k-auto-scrollable\") > -1) {\n\t return true;\n\t }\n\n\t var overflow = getComputedStyles(element, [\"overflow\"]).overflow;\n\t return overflow == \"auto\" || overflow == \"scroll\";\n\t }\n\n\t function scrollLeft(element, value) {\n\t var webkit = support.browser.webkit;\n\t var mozila = support.browser.mozilla;\n\t var el = element instanceof $ ? element[0] : element;\n\t var isRtl;\n\n\t if (!element) {\n\t return;\n\t }\n\n\t isRtl = support.isRtl(element);\n\n\t if (value !== undefined) {\n\t if (isRtl && webkit) {\n\t el.scrollLeft = el.scrollWidth - el.clientWidth - value;\n\t } else if (isRtl && mozila) {\n\t el.scrollLeft = -value;\n\t } else {\n\t el.scrollLeft = value;\n\t }\n\t } else {\n\t if (isRtl && webkit) {\n\t return el.scrollWidth - el.clientWidth - el.scrollLeft;\n\t } else {\n\t return Math.abs(el.scrollLeft);\n\t }\n\t }\n\t }\n\n\t (function () {\n\t support._scrollbar = undefined;\n\n\t support.scrollbar = function (refresh) {\n\t if (!isNaN(support._scrollbar) && !refresh) {\n\t return support._scrollbar;\n\t } else {\n\t var div = document.createElement(\"div\"),\n\t result;\n\n\t div.style.cssText = \"overflow:scroll;overflow-x:hidden;zoom:1;clear:both;display:block\";\n\t div.innerHTML = \" \";\n\t document.body.appendChild(div);\n\n\t support._scrollbar = result = div.offsetWidth - div.scrollWidth;\n\n\t document.body.removeChild(div);\n\n\t return result;\n\t }\n\t };\n\n\t support.isRtl = function(element) {\n\t return $(element).closest(\".k-rtl\").length > 0;\n\t };\n\n\t var table = document.createElement(\"table\");\n\n\t // Internet Explorer does not support setting the innerHTML of TBODY and TABLE elements\n\t try {\n\t table.innerHTML = \"\";\n\n\t support.tbodyInnerHtml = true;\n\t } catch (e) {\n\t support.tbodyInnerHtml = false;\n\t }\n\n\t support.touch = \"ontouchstart\" in window;\n\n\t var docStyle = document.documentElement.style;\n\t var transitions = support.transitions = false,\n\t transforms = support.transforms = false,\n\t elementProto = \"HTMLElement\" in window ? HTMLElement.prototype : [];\n\n\t support.hasHW3D = (\"WebKitCSSMatrix\" in window && \"m11\" in new window.WebKitCSSMatrix()) || \"MozPerspective\" in docStyle || \"msPerspective\" in docStyle;\n\t support.cssFlexbox = (\"flexWrap\" in docStyle) || (\"WebkitFlexWrap\" in docStyle) || (\"msFlexWrap\" in docStyle);\n\n\t each([ \"Moz\", \"webkit\", \"O\", \"ms\" ], function () {\n\t var prefix = this.toString(),\n\t hasTransitions = typeof table.style[prefix + \"Transition\"] === STRING;\n\n\t if (hasTransitions || typeof table.style[prefix + \"Transform\"] === STRING) {\n\t var lowPrefix = prefix.toLowerCase();\n\n\t transforms = {\n\t css: (lowPrefix != \"ms\") ? \"-\" + lowPrefix + \"-\" : \"\",\n\t prefix: prefix,\n\t event: (lowPrefix === \"o\" || lowPrefix === \"webkit\") ? lowPrefix : \"\"\n\t };\n\n\t if (hasTransitions) {\n\t transitions = transforms;\n\t transitions.event = transitions.event ? transitions.event + \"TransitionEnd\" : \"transitionend\";\n\t }\n\n\t return false;\n\t }\n\t });\n\n\t table = null;\n\n\t support.transforms = transforms;\n\t support.transitions = transitions;\n\n\t support.devicePixelRatio = window.devicePixelRatio === undefined ? 1 : window.devicePixelRatio;\n\n\t try {\n\t support.screenWidth = window.outerWidth || window.screen ? window.screen.availWidth : window.innerWidth;\n\t support.screenHeight = window.outerHeight || window.screen ? window.screen.availHeight : window.innerHeight;\n\t } catch(e) {\n\t //window.outerWidth throws error when in IE showModalDialog.\n\t support.screenWidth = window.screen.availWidth;\n\t support.screenHeight = window.screen.availHeight;\n\t }\n\n\t support.detectOS = function (ua) {\n\t var os = false, minorVersion, match = [],\n\t notAndroidPhone = !/mobile safari/i.test(ua),\n\t agentRxs = {\n\t wp: /(Windows Phone(?: OS)?)\\s(\\d+)\\.(\\d+(\\.\\d+)?)/,\n\t fire: /(Silk)\\/(\\d+)\\.(\\d+(\\.\\d+)?)/,\n\t android: /(Android|Android.*(?:Opera|Firefox).*?\\/)\\s*(\\d+)\\.?(\\d+(\\.\\d+)?)?/,\n\t iphone: /(iPhone|iPod).*OS\\s+(\\d+)[\\._]([\\d\\._]+)/,\n\t ipad: /(iPad).*OS\\s+(\\d+)[\\._]([\\d_]+)/,\n\t meego: /(MeeGo).+NokiaBrowser\\/(\\d+)\\.([\\d\\._]+)/,\n\t webos: /(webOS)\\/(\\d+)\\.(\\d+(\\.\\d+)?)/,\n\t blackberry: /(BlackBerry|BB10).*?Version\\/(\\d+)\\.(\\d+(\\.\\d+)?)/,\n\t playbook: /(PlayBook).*?Tablet\\s*OS\\s*(\\d+)\\.(\\d+(\\.\\d+)?)/,\n\t windows: /(MSIE)\\s+(\\d+)\\.(\\d+(\\.\\d+)?)/,\n\t tizen: /(tizen).*?Version\\/(\\d+)\\.(\\d+(\\.\\d+)?)/i,\n\t sailfish: /(sailfish).*rv:(\\d+)\\.(\\d+(\\.\\d+)?).*firefox/i,\n\t ffos: /(Mobile).*rv:(\\d+)\\.(\\d+(\\.\\d+)?).*Firefox/\n\t },\n\t osRxs = {\n\t ios: /^i(phone|pad|pod)$/i,\n\t android: /^android|fire$/i,\n\t blackberry: /^blackberry|playbook/i,\n\t windows: /windows/,\n\t wp: /wp/,\n\t flat: /sailfish|ffos|tizen/i,\n\t meego: /meego/\n\t },\n\t formFactorRxs = {\n\t tablet: /playbook|ipad|fire/i\n\t },\n\t browserRxs = {\n\t omini: /Opera\\sMini/i,\n\t omobile: /Opera\\sMobi/i,\n\t firefox: /Firefox|Fennec/i,\n\t mobilesafari: /version\\/.*safari/i,\n\t ie: /MSIE|Windows\\sPhone/i,\n\t chrome: /chrome|crios/i,\n\t webkit: /webkit/i\n\t };\n\n\t for (var agent in agentRxs) {\n\t if (agentRxs.hasOwnProperty(agent)) {\n\t match = ua.match(agentRxs[agent]);\n\t if (match) {\n\t if (agent == \"windows\" && \"plugins\" in navigator) { return false; } // Break if not Metro/Mobile Windows\n\n\t os = {};\n\t os.device = agent;\n\t os.tablet = testRx(agent, formFactorRxs, false);\n\t os.browser = testRx(ua, browserRxs, \"default\");\n\t os.name = testRx(agent, osRxs);\n\t os[os.name] = true;\n\t os.majorVersion = match[2];\n\t os.minorVersion = (match[3] || \"0\").replace(\"_\", \".\");\n\t minorVersion = os.minorVersion.replace(\".\", \"\").substr(0, 2);\n\t os.flatVersion = os.majorVersion + minorVersion + (new Array(3 - (minorVersion.length < 3 ? minorVersion.length : 2)).join(\"0\"));\n\t os.cordova = typeof window.PhoneGap !== UNDEFINED || typeof window.cordova !== UNDEFINED; // Use file protocol to detect appModes.\n\t os.appMode = window.navigator.standalone || (/file|local|wmapp/).test(window.location.protocol) || os.cordova; // Use file protocol to detect appModes.\n\n\t if (os.android && (support.devicePixelRatio < 1.5 && os.flatVersion < 400 || notAndroidPhone) && (support.screenWidth > 800 || support.screenHeight > 800)) {\n\t os.tablet = agent;\n\t }\n\n\t break;\n\t }\n\t }\n\t }\n\t return os;\n\t };\n\n\t var mobileOS = support.mobileOS = support.detectOS(navigator.userAgent);\n\n\t support.wpDevicePixelRatio = mobileOS.wp ? screen.width / 320 : 0;\n\n\t support.hasNativeScrolling = false;\n\n\t if (mobileOS.ios || (mobileOS.android && mobileOS.majorVersion > 2) || mobileOS.wp) {\n\t support.hasNativeScrolling = mobileOS;\n\t }\n\n\t support.delayedClick = function() {\n\n\t // only the mobile devices with touch events do this.\n\t if (support.touch) {\n\t // All iOS devices so far (by the time I am writing this, iOS 9.0.2 is the latest),\n\t // delay their click events.\n\t if (mobileOS.ios) {\n\t return true;\n\t }\n\n\t if (mobileOS.android) {\n\n\t if (!support.browser.chrome) { // older webkits and webviews delay the click\n\t return true;\n\t }\n\n\t // from here on, we deal with Chrome on Android.\n\t if (support.browser.version < 32) {\n\t return false;\n\t }\n\n\t // Chrome 32+ does conditional fast clicks if the view port is not user scalable.\n\t return !($(\"meta[name=viewport]\").attr(\"content\") || \"\").match(/user-scalable=no/i);\n\t }\n\t }\n\n\t return false;\n\t };\n\n\t support.mouseAndTouchPresent = support.touch && !(support.mobileOS.ios || support.mobileOS.android);\n\n\t support.detectBrowser = function(ua) {\n\t var browser = false, match = [],\n\t browserRxs = {\n\t edge: /(edge)[ \\/]([\\w.]+)/i,\n\t webkit: /(chrome|crios)[ \\/]([\\w.]+)/i,\n\t safari: /(webkit)[ \\/]([\\w.]+)/i,\n\t opera: /(opera)(?:.*version|)[ \\/]([\\w.]+)/i,\n\t msie: /(msie\\s|trident.*? rv:)([\\w.]+)/i,\n\t mozilla: /(mozilla)(?:.*? rv:([\\w.]+)|)/i\n\t };\n\n\t for (var agent in browserRxs) {\n\t if (browserRxs.hasOwnProperty(agent)) {\n\t match = ua.match(browserRxs[agent]);\n\t if (match) {\n\t browser = {};\n\t browser[agent] = true;\n\t browser[match[1].toLowerCase().split(\" \")[0].split(\"/\")[0]] = true;\n\t browser.version = parseInt(document.documentMode || match[2], 10);\n\n\t break;\n\t }\n\t }\n\t }\n\n\t return browser;\n\t };\n\n\t support.browser = support.detectBrowser(navigator.userAgent);\n\n\t support.detectClipboardAccess = function() {\n\t var commands = {\n\t copy: document.queryCommandSupported ? document.queryCommandSupported(\"copy\") : false,\n\t cut: document.queryCommandSupported ? document.queryCommandSupported(\"cut\") : false,\n\t paste : document.queryCommandSupported ? document.queryCommandSupported(\"paste\") : false\n\t };\n\n\t if (support.browser.chrome) {\n\t //not using queryCommandSupported due to chromium issues 476508 and 542948\n\t commands.paste = false;\n\t if(support.browser.version >= 43) {\n\t commands.copy = true;\n\t commands.cut = true;\n\t }\n\t }\n\n\t return commands;\n\t };\n\n\t support.clipboard = support.detectClipboardAccess();\n\n\t support.zoomLevel = function() {\n\t try {\n\t var browser = support.browser;\n\t var ie11WidthCorrection = 0;\n\t var docEl = document.documentElement;\n\n\t if (browser.msie && browser.version == 11 && docEl.scrollHeight > docEl.clientHeight && !support.touch) {\n\t ie11WidthCorrection = support.scrollbar();\n\t }\n\n\t return support.touch ? (docEl.clientWidth / window.innerWidth) :\n\t browser.msie && browser.version >= 10 ? (((top || window).document.documentElement.offsetWidth + ie11WidthCorrection) / (top || window).innerWidth) : 1;\n\t } catch(e) {\n\t return 1;\n\t }\n\t };\n\n\t support.cssBorderSpacing = typeof docStyle.borderSpacing != \"undefined\" && !(support.browser.msie && support.browser.version < 8);\n\n\t (function(browser) {\n\t // add browser-specific CSS class\n\t var cssClass = \"\",\n\t docElement = $(document.documentElement),\n\t majorVersion = parseInt(browser.version, 10);\n\n\t if (browser.msie) {\n\t cssClass = \"ie\";\n\t } else if (browser.mozilla) {\n\t cssClass = \"ff\";\n\t } else if (browser.safari) {\n\t cssClass = \"safari\";\n\t } else if (browser.webkit) {\n\t cssClass = \"webkit\";\n\t } else if (browser.opera) {\n\t cssClass = \"opera\";\n\t } else if (browser.edge) {\n\t cssClass = \"edge\";\n\t }\n\n\t if (cssClass) {\n\t cssClass = \"k-\" + cssClass + \" k-\" + cssClass + majorVersion;\n\t }\n\t if (support.mobileOS) {\n\t cssClass += \" k-mobile\";\n\t }\n\n\t if (!support.cssFlexbox) {\n\t cssClass += \" k-no-flexbox\";\n\t }\n\n\t docElement.addClass(cssClass);\n\t })(support.browser);\n\n\t support.eventCapture = document.documentElement.addEventListener;\n\n\t var input = document.createElement(\"input\");\n\n\t support.placeholder = \"placeholder\" in input;\n\t support.propertyChangeEvent = \"onpropertychange\" in input;\n\n\t support.input = (function() {\n\t var types = [\"number\", \"date\", \"time\", \"month\", \"week\", \"datetime\", \"datetime-local\"];\n\t var length = types.length;\n\t var value = \"test\";\n\t var result = {};\n\t var idx = 0;\n\t var type;\n\n\t for (;idx < length; idx++) {\n\t type = types[idx];\n\t input.setAttribute(\"type\", type);\n\t input.value = value;\n\n\t result[type.replace(\"-\", \"\")] = input.type !== \"text\" && input.value !== value;\n\t }\n\n\t return result;\n\t })();\n\n\t input.style.cssText = \"float:left;\";\n\n\t support.cssFloat = !!input.style.cssFloat;\n\n\t input = null;\n\n\t support.stableSort = (function() {\n\t // Chrome sort is not stable for more than *10* items\n\t // IE9+ sort is not stable for than *512* items\n\t var threshold = 513;\n\n\t var sorted = [{\n\t index: 0,\n\t field: \"b\"\n\t }];\n\n\t for (var i = 1; i < threshold; i++) {\n\t sorted.push({\n\t index: i,\n\t field: \"a\"\n\t });\n\t }\n\n\t sorted.sort(function(a, b) {\n\t return a.field > b.field ? 1 : (a.field < b.field ? -1 : 0);\n\t });\n\n\t return sorted[0].index === 1;\n\t })();\n\n\t support.matchesSelector = elementProto.webkitMatchesSelector || elementProto.mozMatchesSelector ||\n\t elementProto.msMatchesSelector || elementProto.oMatchesSelector ||\n\t elementProto.matchesSelector || elementProto.matches ||\n\t function( selector ) {\n\t var nodeList = document.querySelectorAll ? ( this.parentNode || document ).querySelectorAll( selector ) || [] : $(selector),\n\t i = nodeList.length;\n\n\t while (i--) {\n\t if (nodeList[i] == this) {\n\t return true;\n\t }\n\t }\n\n\t return false;\n\t };\n\n\t support.matchMedia = \"matchMedia\" in window;\n\n\t support.pushState = window.history && window.history.pushState;\n\n\t var documentMode = document.documentMode;\n\n\t support.hashChange = (\"onhashchange\" in window) && !(support.browser.msie && (!documentMode || documentMode <= 8)); // old IE detection\n\n\t support.customElements = (\"registerElement\" in window.document);\n\n\t var chrome = support.browser.chrome,\n\t mobileChrome = support.browser.crios,\n\t mozilla = support.browser.mozilla,\n\t safari = support.browser.safari;\n\t support.msPointers = !chrome && window.MSPointerEvent;\n\t support.pointers = !chrome && !mobileChrome && !mozilla && !safari && window.PointerEvent;\n\t support.kineticScrollNeeded = mobileOS && (support.touch || support.msPointers || support.pointers);\n\t })();\n\n\n\t function size(obj) {\n\t var result = 0, key;\n\t for (key in obj) {\n\t if (obj.hasOwnProperty(key) && key != \"toJSON\") { // Ignore fake IE7 toJSON.\n\t result++;\n\t }\n\t }\n\n\t return result;\n\t }\n\n\t function getOffset(element, type, positioned) {\n\t if (!type) {\n\t type = \"offset\";\n\t }\n\n\t var offset = element[type]();\n\t // clone ClientRect object to JS object (jQuery3)\n\t var result = {\n\t top: offset.top,\n\t right: offset.right,\n\t bottom: offset.bottom,\n\t left: offset.left\n\t };\n\n\t // IE10 touch zoom is living in a separate viewport\n\t if (support.browser.msie && (support.pointers || support.msPointers) && !positioned) {\n\t var sign = support.isRtl(element) ? 1 : -1;\n\n\t result.top -= (window.pageYOffset - (document.documentElement.scrollTop));\n\t result.left -= (window.pageXOffset + (sign * document.documentElement.scrollLeft));\n\t }\n\n\t return result;\n\t }\n\n\t var directions = {\n\t left: { reverse: \"right\" },\n\t right: { reverse: \"left\" },\n\t down: { reverse: \"up\" },\n\t up: { reverse: \"down\" },\n\t top: { reverse: \"bottom\" },\n\t bottom: { reverse: \"top\" },\n\t \"in\": { reverse: \"out\" },\n\t out: { reverse: \"in\" }\n\t };\n\n\t function parseEffects(input) {\n\t var effects = {};\n\n\t each((typeof input === \"string\" ? input.split(\" \") : input), function(idx) {\n\t effects[idx] = this;\n\t });\n\n\t return effects;\n\t }\n\n\t function fx(element) {\n\t return new kendo.effects.Element(element);\n\t }\n\n\t var effects = {};\n\n\t $.extend(effects, {\n\t enabled: true,\n\t Element: function(element) {\n\t this.element = $(element);\n\t },\n\n\t promise: function(element, options) {\n\t if (!element.is(\":visible\")) {\n\t element.css({ display: element.data(\"olddisplay\") || \"block\" }).css(\"display\");\n\t }\n\n\t if (options.hide) {\n\t element.data(\"olddisplay\", element.css(\"display\")).hide();\n\t }\n\n\t if (options.init) {\n\t options.init();\n\t }\n\n\t if (options.completeCallback) {\n\t options.completeCallback(element); // call the external complete callback with the element\n\t }\n\n\t element.dequeue();\n\t },\n\n\t disable: function() {\n\t this.enabled = false;\n\t this.promise = this.promiseShim;\n\t },\n\n\t enable: function() {\n\t this.enabled = true;\n\t this.promise = this.animatedPromise;\n\t }\n\t });\n\n\t effects.promiseShim = effects.promise;\n\n\t function prepareAnimationOptions(options, duration, reverse, complete) {\n\t if (typeof options === STRING) {\n\t // options is the list of effect names separated by space e.g. animate(element, \"fadeIn slideDown\")\n\n\t // only callback is provided e.g. animate(element, options, function() {});\n\t if (isFunction(duration)) {\n\t complete = duration;\n\t duration = 400;\n\t reverse = false;\n\t }\n\n\t if (isFunction(reverse)) {\n\t complete = reverse;\n\t reverse = false;\n\t }\n\n\t if (typeof duration === BOOLEAN){\n\t reverse = duration;\n\t duration = 400;\n\t }\n\n\t options = {\n\t effects: options,\n\t duration: duration,\n\t reverse: reverse,\n\t complete: complete\n\t };\n\t }\n\n\t return extend({\n\t //default options\n\t effects: {},\n\t duration: 400, //jQuery default duration\n\t reverse: false,\n\t init: noop,\n\t teardown: noop,\n\t hide: false\n\t }, options, { completeCallback: options.complete, complete: noop }); // Move external complete callback, so deferred.resolve can be always executed.\n\n\t }\n\n\t function animate(element, options, duration, reverse, complete) {\n\t var idx = 0,\n\t length = element.length,\n\t instance;\n\n\t for (; idx < length; idx ++) {\n\t instance = $(element[idx]);\n\t instance.queue(function() {\n\t effects.promise(instance, prepareAnimationOptions(options, duration, reverse, complete));\n\t });\n\t }\n\n\t return element;\n\t }\n\n\t function toggleClass(element, classes, options, add) {\n\t if (classes) {\n\t classes = classes.split(\" \");\n\n\t each(classes, function(idx, value) {\n\t element.toggleClass(value, add);\n\t });\n\t }\n\n\t return element;\n\t }\n\n\t if (!(\"kendoAnimate\" in $.fn)) {\n\t extend($.fn, {\n\t kendoStop: function(clearQueue, gotoEnd) {\n\t return this.stop(clearQueue, gotoEnd);\n\t },\n\n\t kendoAnimate: function(options, duration, reverse, complete) {\n\t return animate(this, options, duration, reverse, complete);\n\t },\n\n\t kendoAddClass: function(classes, options){\n\t return kendo.toggleClass(this, classes, options, true);\n\t },\n\n\t kendoRemoveClass: function(classes, options){\n\t return kendo.toggleClass(this, classes, options, false);\n\t },\n\t kendoToggleClass: function(classes, options, toggle){\n\t return kendo.toggleClass(this, classes, options, toggle);\n\t }\n\t });\n\t }\n\n\t var ampRegExp = /&/g,\n\t ltRegExp = //g;\n\t function htmlEncode(value) {\n\t return (\"\" + value).replace(ampRegExp, \"&\").replace(ltRegExp, \"<\").replace(gtRegExp, \">\").replace(quoteRegExp, \""\").replace(aposRegExp, \"'\");\n\t }\n\n\t function unescape(value) {\n\t var template;\n\n\t try {\n\t template = window.decodeURIComponent(value);\n\t } catch(error) {\n\t // If the string contains Unicode characters\n\t // the decodeURIComponent() will throw an error.\n\t // Therefore: convert to UTF-8 character\n\t template = value.replace(/%u([\\dA-F]{4})|%([\\dA-F]{2})/gi, function(_, m1, m2) {\n\t return String.fromCharCode(parseInt(\"0x\" + (m1 || m2), 16));\n\t });\n\t }\n\n\t return template;\n\t }\n\n\t var eventTarget = function (e) {\n\t return e.target;\n\t };\n\n\t if (support.touch) {\n\n\t eventTarget = function(e) {\n\t var touches = \"originalEvent\" in e ? e.originalEvent.changedTouches : \"changedTouches\" in e ? e.changedTouches : null;\n\n\t return touches ? document.elementFromPoint(touches[0].clientX, touches[0].clientY) : e.target;\n\t };\n\n\t each([\"swipe\", \"swipeLeft\", \"swipeRight\", \"swipeUp\", \"swipeDown\", \"doubleTap\", \"tap\"], function(m, value) {\n\t $.fn[value] = function(callback) {\n\t return this.bind(value, callback);\n\t };\n\t });\n\t }\n\n\t if (support.touch) {\n\t if (!support.mobileOS) {\n\t support.mousedown = \"mousedown touchstart\";\n\t support.mouseup = \"mouseup touchend\";\n\t support.mousemove = \"mousemove touchmove\";\n\t support.mousecancel = \"mouseleave touchcancel\";\n\t support.click = \"click\";\n\t support.resize = \"resize\";\n\t } else {\n\t support.mousedown = \"touchstart\";\n\t support.mouseup = \"touchend\";\n\t support.mousemove = \"touchmove\";\n\t support.mousecancel = \"touchcancel\";\n\t support.click = \"touchend\";\n\t support.resize = \"orientationchange\";\n\t }\n\t } else if (support.pointers) {\n\t support.mousemove = \"pointermove\";\n\t support.mousedown = \"pointerdown\";\n\t support.mouseup = \"pointerup\";\n\t support.mousecancel = \"pointercancel\";\n\t support.click = \"pointerup\";\n\t support.resize = \"orientationchange resize\";\n\t } else if (support.msPointers) {\n\t support.mousemove = \"MSPointerMove\";\n\t support.mousedown = \"MSPointerDown\";\n\t support.mouseup = \"MSPointerUp\";\n\t support.mousecancel = \"MSPointerCancel\";\n\t support.click = \"MSPointerUp\";\n\t support.resize = \"orientationchange resize\";\n\t } else {\n\t support.mousemove = \"mousemove\";\n\t support.mousedown = \"mousedown\";\n\t support.mouseup = \"mouseup\";\n\t support.mousecancel = \"mouseleave\";\n\t support.click = \"click\";\n\t support.resize = \"resize\";\n\t }\n\n\t var wrapExpression = function(members, paramName) {\n\t var result = paramName || \"d\",\n\t index,\n\t idx,\n\t length,\n\t member,\n\t count = 1;\n\n\t for (idx = 0, length = members.length; idx < length; idx++) {\n\t member = members[idx];\n\t if (member !== \"\") {\n\t index = member.indexOf(\"[\");\n\n\t if (index !== 0) {\n\t if (index == -1) {\n\t member = \".\" + member;\n\t } else {\n\t count++;\n\t member = \".\" + member.substring(0, index) + \" || {})\" + member.substring(index);\n\t }\n\t }\n\n\t count++;\n\t result += member + ((idx < length - 1) ? \" || {})\" : \")\");\n\t }\n\t }\n\t return new Array(count).join(\"(\") + result;\n\t },\n\t localUrlRe = /^([a-z]+:)?\\/\\//i;\n\n\t extend(kendo, {\n\t widgets: [],\n\t _widgetRegisteredCallbacks: [],\n\t ui: kendo.ui || {},\n\t fx: kendo.fx || fx,\n\t effects: kendo.effects || effects,\n\t mobile: kendo.mobile || { },\n\t data: kendo.data || {},\n\t dataviz: kendo.dataviz || {},\n\t drawing: kendo.drawing || {},\n\t spreadsheet: { messages: {} },\n\t keys: {\n\t INSERT: 45,\n\t DELETE: 46,\n\t BACKSPACE: 8,\n\t TAB: 9,\n\t ENTER: 13,\n\t ESC: 27,\n\t LEFT: 37,\n\t UP: 38,\n\t RIGHT: 39,\n\t DOWN: 40,\n\t END: 35,\n\t HOME: 36,\n\t SPACEBAR: 32,\n\t PAGEUP: 33,\n\t PAGEDOWN: 34,\n\t F2: 113,\n\t F10: 121,\n\t F12: 123,\n\t NUMPAD_PLUS: 107,\n\t NUMPAD_MINUS: 109,\n\t NUMPAD_DOT: 110\n\t },\n\t support: kendo.support || support,\n\t animate: kendo.animate || animate,\n\t ns: \"\",\n\t attr: function(value) {\n\t return \"data-\" + kendo.ns + value;\n\t },\n\t getShadows: getShadows,\n\t wrap: wrap,\n\t deepExtend: deepExtend,\n\t getComputedStyles: getComputedStyles,\n\t isScrollable: isScrollable,\n\t scrollLeft: scrollLeft,\n\t size: size,\n\t toCamelCase: toCamelCase,\n\t toHyphens: toHyphens,\n\t getOffset: kendo.getOffset || getOffset,\n\t parseEffects: kendo.parseEffects || parseEffects,\n\t toggleClass: kendo.toggleClass || toggleClass,\n\t directions: kendo.directions || directions,\n\t Observable: Observable,\n\t Class: Class,\n\t Template: Template,\n\t template: proxy(Template.compile, Template),\n\t render: proxy(Template.render, Template),\n\t stringify: proxy(JSON.stringify, JSON),\n\t eventTarget: eventTarget,\n\t htmlEncode: htmlEncode,\n\t unescape: unescape,\n\t isLocalUrl: function(url) {\n\t return url && !localUrlRe.test(url);\n\t },\n\n\t expr: function(expression, safe, paramName) {\n\t expression = expression || \"\";\n\n\t if (typeof safe == STRING) {\n\t paramName = safe;\n\t safe = false;\n\t }\n\n\t paramName = paramName || \"d\";\n\n\t if (expression && expression.charAt(0) !== \"[\") {\n\t expression = \".\" + expression;\n\t }\n\n\t if (safe) {\n\t expression = expression.replace(/\"([^.]*)\\.([^\"]*)\"/g,'\"$1_$DOT$_$2\"');\n\t expression = expression.replace(/'([^.]*)\\.([^']*)'/g,\"'$1_$DOT$_$2'\");\n\t expression = wrapExpression(expression.split(\".\"), paramName);\n\t expression = expression.replace(/_\\$DOT\\$_/g, \".\");\n\t } else {\n\t expression = paramName + expression;\n\t }\n\n\t return expression;\n\t },\n\n\t getter: function(expression, safe) {\n\t var key = expression + safe;\n\t return getterCache[key] = getterCache[key] || new Function(\"d\", \"return \" + kendo.expr(expression, safe));\n\t },\n\n\t setter: function(expression) {\n\t return setterCache[expression] = setterCache[expression] || new Function(\"d,value\", kendo.expr(expression) + \"=value\");\n\t },\n\n\t accessor: function(expression) {\n\t return {\n\t get: kendo.getter(expression),\n\t set: kendo.setter(expression)\n\t };\n\t },\n\n\t guid: function() {\n\t var id = \"\", i, random;\n\n\t for (i = 0; i < 32; i++) {\n\t random = math.random() * 16 | 0;\n\n\t if (i == 8 || i == 12 || i == 16 || i == 20) {\n\t id += \"-\";\n\t }\n\t id += (i == 12 ? 4 : (i == 16 ? (random & 3 | 8) : random)).toString(16);\n\t }\n\n\t return id;\n\t },\n\n\t roleSelector: function(role) {\n\t return role.replace(/(\\S+)/g, \"[\" + kendo.attr(\"role\") + \"=$1],\").slice(0, -1);\n\t },\n\n\t directiveSelector: function(directives) {\n\t var selectors = directives.split(\" \");\n\n\t if (selectors) {\n\t for (var i = 0; i < selectors.length; i++) {\n\t if (selectors[i] != \"view\") {\n\t selectors[i] = selectors[i].replace(/(\\w*)(view|bar|strip|over)$/, \"$1-$2\");\n\t }\n\t }\n\t }\n\n\t return selectors.join(\" \").replace(/(\\S+)/g, \"kendo-mobile-$1,\").slice(0, -1);\n\t },\n\n\t triggeredByInput: function(e) {\n\t return (/^(label|input|textarea|select)$/i).test(e.target.tagName);\n\t },\n\n\t onWidgetRegistered: function(callback) {\n\t for (var i = 0, len = kendo.widgets.length; i < len; i++) {\n\t callback(kendo.widgets[i]);\n\t }\n\n\t kendo._widgetRegisteredCallbacks.push(callback);\n\t },\n\n\t logToConsole: function(message, type) {\n\t var console = window.console;\n\n\t if (!kendo.suppressLog && typeof(console) != \"undefined\" && console.log) {\n\t console[type || \"log\"](message);\n\t }\n\t }\n\t });\n\n\t var Widget = Observable.extend( {\n\t init: function(element, options) {\n\t var that = this;\n\n\t that.element = kendo.jQuery(element).handler(that);\n\n\t that.angular(\"init\", options);\n\n\t Observable.fn.init.call(that);\n\n\t var dataSource = options ? options.dataSource : null;\n\t var props;\n\n\t if (options) {\n\t props = (that.componentTypes || {})[(options || {}).componentType];\n\t }\n\n\t if (dataSource) {\n\t // avoid deep cloning the data source\n\t options = extend({}, options, { dataSource: {} });\n\t }\n\n\t options = that.options = extend(true, {}, that.options, that.defaults, props || {}, options);\n\n\t if (dataSource) {\n\t options.dataSource = dataSource;\n\t }\n\n\t if (!that.element.attr(kendo.attr(\"role\"))) {\n\t that.element.attr(kendo.attr(\"role\"), (options.name || \"\").toLowerCase());\n\t }\n\n\t that.element.data(\"kendo\" + options.prefix + options.name, that);\n\n\t that.bind(that.events, options);\n\t },\n\n\t events: [],\n\n\t options: {\n\t prefix: \"\"\n\t },\n\n\t _hasBindingTarget: function() {\n\t return !!this.element[0].kendoBindingTarget;\n\t },\n\n\t _tabindex: function(target) {\n\t target = target || this.wrapper;\n\n\t var element = this.element,\n\t TABINDEX = \"tabindex\",\n\t tabindex = target.attr(TABINDEX) || element.attr(TABINDEX);\n\n\t element.removeAttr(TABINDEX);\n\n\t target.attr(TABINDEX, !isNaN(tabindex) ? tabindex : 0);\n\t },\n\n\t setOptions: function(options) {\n\t this._setEvents(options);\n\t $.extend(this.options, options);\n\t },\n\n\t _setEvents: function(options) {\n\t var that = this,\n\t idx = 0,\n\t length = that.events.length,\n\t e;\n\n\t for (; idx < length; idx ++) {\n\t e = that.events[idx];\n\t if (that.options[e] && options[e]) {\n\t that.unbind(e, that.options[e]);\n\t if (that._events && that._events[e]) {\n\t delete that._events[e];\n\t }\n\t }\n\t }\n\n\t that.bind(that.events, options);\n\t },\n\n\t resize: function(force) {\n\t var size = this.getSize(),\n\t currentSize = this._size;\n\n\t if (force || (size.width > 0 || size.height > 0) && (!currentSize || size.width !== currentSize.width || size.height !== currentSize.height)) {\n\t this._size = size;\n\t this._resize(size, force);\n\t this.trigger(\"resize\", size);\n\t }\n\t },\n\n\t getSize: function() {\n\t return kendo.dimensions(this.element);\n\t },\n\n\t size: function(size) {\n\t if (!size) {\n\t return this.getSize();\n\t } else {\n\t this.setSize(size);\n\t }\n\t },\n\n\t setSize: $.noop,\n\t _resize: $.noop,\n\n\t destroy: function() {\n\t var that = this;\n\n\t that.element.removeData(\"kendo\" + that.options.prefix + that.options.name);\n\t that.element.removeData(\"handler\");\n\t that.unbind();\n\t },\n\t _destroy: function() {\n\t this.destroy();\n\t },\n\t angular: function(){},\n\n\t _muteAngularRebind: function(callback) {\n\t this._muteRebind = true;\n\n\t callback.call(this);\n\n\t this._muteRebind = false;\n\t }\n\t });\n\n\t var DataBoundWidget = Widget.extend({\n\t // Angular consumes these.\n\t dataItems: function() {\n\t return this.dataSource.flatView();\n\t },\n\n\t _angularItems: function(cmd) {\n\t var that = this;\n\t that.angular(cmd, function(){\n\t return {\n\t elements: that.items(),\n\t data: $.map(that.dataItems(), function(dataItem){\n\t return { dataItem: dataItem };\n\t })\n\t };\n\t });\n\t }\n\t });\n\n\t kendo.dimensions = function(element, dimensions) {\n\t var domElement = element[0];\n\n\t if (dimensions) {\n\t element.css(dimensions);\n\t }\n\n\t return { width: domElement.offsetWidth, height: domElement.offsetHeight };\n\t };\n\n\t kendo.notify = noop;\n\n\t var templateRegExp = /template$/i,\n\t jsonRegExp = /^\\s*(?:\\{(?:.|\\r\\n|\\n)*\\}|\\[(?:.|\\r\\n|\\n)*\\])\\s*$/,\n\t jsonFormatRegExp = /^\\{(\\d+)(:[^\\}]+)?\\}|^\\[[A-Za-z_]+\\]$/,\n\t dashRegExp = /([A-Z])/g;\n\n\t function parseOption(element, option) {\n\t var value;\n\n\t if (option.indexOf(\"data\") === 0) {\n\t option = option.substring(4);\n\t option = option.charAt(0).toLowerCase() + option.substring(1);\n\t }\n\n\t option = option.replace(dashRegExp, \"-$1\");\n\t value = element.getAttribute(\"data-\" + kendo.ns + option);\n\n\t if (value === null) {\n\t value = undefined;\n\t } else if (value === \"null\") {\n\t value = null;\n\t } else if (value === \"true\") {\n\t value = true;\n\t } else if (value === \"false\") {\n\t value = false;\n\t } else if (numberRegExp.test(value) && option != \"mask\") {\n\t value = parseFloat(value);\n\t } else if (jsonRegExp.test(value) && !jsonFormatRegExp.test(value)) {\n\t value = new Function(\"return (\" + value + \")\")();\n\t }\n\n\t return value;\n\t }\n\n\t function parseOptions(element, options, source) {\n\t var result = {},\n\t option,\n\t value,\n\t role = element.getAttribute(\"data-\" + kendo.ns + \"role\");\n\n\t for (option in options) {\n\t value = parseOption(element, option);\n\n\t if (value !== undefined) {\n\n\t if (templateRegExp.test(option) && role != \"drawer\") {\n\t if(typeof value === \"string\") {\n\t if($(\"#\" + value).length){\n\t value = kendo.template($(\"#\" + value).html());\n\t }else if (source){\n\t value = kendo.template(source[value]);\n\t }\n\t } else {\n\t value = element.getAttribute(option);\n\t }\n\t }\n\n\t result[option] = value;\n\t }\n\t }\n\n\t return result;\n\t }\n\n\t kendo.initWidget = function(element, options, roles) {\n\t var result,\n\t option,\n\t widget,\n\t idx,\n\t length,\n\t role,\n\t value,\n\t dataSource,\n\t fullPath,\n\t widgetKeyRegExp;\n\n\t // Preserve backwards compatibility with (element, options, namespace) signature, where namespace was kendo.ui\n\t if (!roles) {\n\t roles = kendo.ui.roles;\n\t } else if (roles.roles) {\n\t roles = roles.roles;\n\t }\n\n\t element = element.nodeType ? element : element[0];\n\n\t role = element.getAttribute(\"data-\" + kendo.ns + \"role\");\n\n\t if (!role) {\n\t return;\n\t }\n\n\t fullPath = role.indexOf(\".\") === -1;\n\n\t // look for any widget that may be already instantiated based on this role.\n\t // The prefix used is unknown, hence the regexp\n\t //\n\n\t if (fullPath) {\n\t widget = roles[role];\n\t } else { // full namespace path - like kendo.ui.Widget\n\t widget = kendo.getter(role)(window);\n\t }\n\n\t var data = $(element).data(),\n\t widgetKey = widget ? \"kendo\" + widget.fn.options.prefix + widget.fn.options.name : \"\";\n\n\t if (fullPath) {\n\t widgetKeyRegExp = new RegExp(\"^kendo.*\" + role + \"$\", \"i\");\n\t } else { // full namespace path - like kendo.ui.Widget\n\t widgetKeyRegExp = new RegExp(\"^\" + widgetKey + \"$\", \"i\");\n\t }\n\n\t for(var key in data) {\n\t if (key.match(widgetKeyRegExp)) {\n\t // we have detected a widget of the same kind - save its reference, we will set its options\n\t if (key === widgetKey) {\n\t result = data[key];\n\t } else {\n\t return data[key];\n\t }\n\t }\n\t }\n\n\t if (!widget) {\n\t return;\n\t }\n\n\t dataSource = parseOption(element, \"dataSource\");\n\n\t options = $.extend({}, parseOptions(element, $.extend({}, widget.fn.options, widget.fn.defaults) ), options);\n\n\t if (dataSource) {\n\t if (typeof dataSource === STRING) {\n\t options.dataSource = kendo.getter(dataSource)(window);\n\t } else {\n\t options.dataSource = dataSource;\n\t }\n\t }\n\n\t for (idx = 0, length = widget.fn.events.length; idx < length; idx++) {\n\t option = widget.fn.events[idx];\n\n\t value = parseOption(element, option);\n\n\t if (value !== undefined) {\n\t options[option] = kendo.getter(value)(window);\n\t }\n\t }\n\n\t if (!result) {\n\t result = new widget(element, options);\n\t } else if (!$.isEmptyObject(options)) {\n\t result.setOptions(options);\n\t }\n\n\t return result;\n\t };\n\n\t kendo.rolesFromNamespaces = function(namespaces) {\n\t var roles = [],\n\t idx,\n\t length;\n\n\t if (!namespaces[0]) {\n\t namespaces = [kendo.ui, kendo.dataviz.ui];\n\t }\n\n\t for (idx = 0, length = namespaces.length; idx < length; idx ++) {\n\t roles[idx] = namespaces[idx].roles;\n\t }\n\n\t return extend.apply(null, [{}].concat(roles.reverse()));\n\t };\n\n\t kendo.init = function(element) {\n\t var roles = kendo.rolesFromNamespaces(slice.call(arguments, 1));\n\n\t $(element).find(\"[data-\" + kendo.ns + \"role]\").addBack().each(function(){\n\t kendo.initWidget(this, {}, roles);\n\t });\n\t };\n\n\t kendo.destroy = function(element) {\n\t $(element).find(\"[data-\" + kendo.ns + \"role]\").addBack().each(function(){\n\t var data = $(this).data();\n\n\t for (var key in data) {\n\t if (key.indexOf(\"kendo\") === 0 && typeof data[key].destroy === FUNCTION) {\n\t data[key].destroy();\n\t }\n\t }\n\t });\n\t };\n\n\t function containmentComparer(a, b) {\n\t return $.contains(a, b) ? -1 : 1;\n\t }\n\n\t function resizableWidget() {\n\t var widget = $(this);\n\t return ($.inArray(widget.attr(\"data-\" + kendo.ns + \"role\"), [\"slider\", \"rangeslider\", \"breadcrumb\"]) > -1) || widget.is(\":visible\");\n\t }\n\n\t kendo.resize = function(element, force) {\n\t var widgets = $(element).find(\"[data-\" + kendo.ns + \"role]\").addBack().filter(resizableWidget);\n\n\t if (!widgets.length) {\n\t return;\n\t }\n\n\t // sort widgets based on their parent-child relation\n\t var widgetsArray = $.makeArray(widgets);\n\t widgetsArray.sort(containmentComparer);\n\n\t // resize widgets\n\t $.each(widgetsArray, function () {\n\t var widget = kendo.widgetInstance($(this));\n\t if (widget) {\n\t widget.resize(force);\n\t }\n\t });\n\t };\n\n\t kendo.parseOptions = parseOptions;\n\n\t extend(kendo.ui, {\n\t Widget: Widget,\n\t DataBoundWidget: DataBoundWidget,\n\t roles: {},\n\t progress: function(container, toggle, options) {\n\t var mask = container.find(\".k-loading-mask\"),\n\t support = kendo.support,\n\t browser = support.browser,\n\t isRtl, leftRight, webkitCorrection, containerScrollLeft, cssClass;\n\n\t options = $.extend({}, {\n\t width: \"100%\",\n\t height: \"100%\",\n\t top: container.scrollTop(),\n\t opacity: false\n\t }, options);\n\n\t cssClass = options.opacity ? 'k-loading-mask k-opaque' : 'k-loading-mask';\n\n\t if (toggle) {\n\t if (!mask.length) {\n\t isRtl = support.isRtl(container);\n\t leftRight = isRtl ? \"right\" : \"left\";\n\t containerScrollLeft = container.scrollLeft();\n\t webkitCorrection = browser.webkit ? (!isRtl ? 0 : container[0].scrollWidth - container.width() - 2 * containerScrollLeft) : 0;\n\n\t mask = $(kendo.format(\"
    {1}
    \", cssClass, kendo.ui.progress.messages.loading))\n\t .width(options.width).height(options.height)\n\t .css(\"top\", options.top)\n\t .css(leftRight, Math.abs(containerScrollLeft) + webkitCorrection)\n\t .prependTo(container);\n\t }\n\t } else if (mask) {\n\t mask.remove();\n\t }\n\t },\n\t plugin: function(widget, register, prefix) {\n\t var name = widget.fn.options.name,\n\t getter;\n\n\t register = register || kendo.ui;\n\t prefix = prefix || \"\";\n\n\t register[name] = widget;\n\n\t register.roles[name.toLowerCase()] = widget;\n\n\t getter = \"getKendo\" + prefix + name;\n\t name = \"kendo\" + prefix + name;\n\n\t var widgetEntry = { name: name, widget: widget, prefix: prefix || \"\" };\n\t kendo.widgets.push(widgetEntry);\n\n\t for (var i = 0, len = kendo._widgetRegisteredCallbacks.length; i < len; i++) {\n\t kendo._widgetRegisteredCallbacks[i](widgetEntry);\n\t }\n\n\t $.fn[name] = function(options) {\n\t var value = this,\n\t args;\n\n\t if (typeof options === STRING) {\n\t args = slice.call(arguments, 1);\n\n\t this.each(function(){\n\t var widget = $.data(this, name),\n\t method,\n\t result;\n\n\t if (!widget) {\n\t throw new Error(kendo.format(\"Cannot call method '{0}' of {1} before it is initialized\", options, name));\n\t }\n\n\t method = widget[options];\n\n\t if (typeof method !== FUNCTION) {\n\t throw new Error(kendo.format(\"Cannot find method '{0}' of {1}\", options, name));\n\t }\n\n\t result = method.apply(widget, args);\n\n\t if (result !== undefined) {\n\t value = result;\n\t return false;\n\t }\n\t });\n\t } else {\n\t this.each(function() {\n\t return new widget(this, options);\n\t });\n\t }\n\n\t return value;\n\t };\n\n\t $.fn[name].widget = widget;\n\n\t $.fn[getter] = function() {\n\t return this.data(name);\n\t };\n\t }\n\t });\n\n\t kendo.ui.progress.messages = {\n\t loading: \"Loading...\"\n\t };\n\n\t var ContainerNullObject = { bind: function () { return this; }, nullObject: true, options: {} };\n\n\t var MobileWidget = Widget.extend({\n\t init: function(element, options) {\n\t Widget.fn.init.call(this, element, options);\n\t this.element.autoApplyNS();\n\t this.wrapper = this.element;\n\t this.element.addClass(\"km-widget\");\n\t },\n\n\t destroy: function() {\n\t Widget.fn.destroy.call(this);\n\t this.element.kendoDestroy();\n\t },\n\n\t options: {\n\t prefix: \"Mobile\"\n\t },\n\n\t events: [],\n\n\t view: function() {\n\t var viewElement = this.element.closest(kendo.roleSelector(\"view splitview modalview drawer\"));\n\t return kendo.widgetInstance(viewElement, kendo.mobile.ui) || ContainerNullObject;\n\t },\n\n\t viewHasNativeScrolling: function() {\n\t var view = this.view();\n\t return view && view.options.useNativeScrolling;\n\t },\n\n\t container: function() {\n\t var element = this.element.closest(kendo.roleSelector(\"view layout modalview drawer splitview\"));\n\t return kendo.widgetInstance(element.eq(0), kendo.mobile.ui) || ContainerNullObject;\n\t }\n\t });\n\n\t extend(kendo.mobile, {\n\t init: function(element) {\n\t kendo.init(element, kendo.mobile.ui, kendo.ui, kendo.dataviz.ui);\n\t },\n\n\t appLevelNativeScrolling: function() {\n\t return kendo.mobile.application && kendo.mobile.application.options && kendo.mobile.application.options.useNativeScrolling;\n\t },\n\n\t roles: {},\n\n\t ui: {\n\t Widget: MobileWidget,\n\t DataBoundWidget: DataBoundWidget.extend(MobileWidget.prototype),\n\t roles: {},\n\t plugin: function(widget) {\n\t kendo.ui.plugin(widget, kendo.mobile.ui, \"Mobile\");\n\t }\n\t }\n\t });\n\n\t deepExtend(kendo.dataviz, {\n\t init: function(element) {\n\t kendo.init(element, kendo.dataviz.ui);\n\t },\n\t ui: {\n\t roles: {},\n\t themes: {},\n\t views: [],\n\t plugin: function(widget) {\n\t kendo.ui.plugin(widget, kendo.dataviz.ui);\n\t }\n\t },\n\t roles: {}\n\t });\n\n\t kendo.touchScroller = function(elements, options) {\n\t // return the first touch scroller\n\t if (!options){ options = {}; }\n\n\t options.useNative = true;\n\n\t return $(elements).map(function(idx, element) {\n\t element = $(element);\n\t if (support.kineticScrollNeeded && kendo.mobile.ui.Scroller && !element.data(\"kendoMobileScroller\")) {\n\t element.kendoMobileScroller(options);\n\t return element.data(\"kendoMobileScroller\");\n\t } else {\n\t return false;\n\t }\n\t })[0];\n\t };\n\n\t kendo.preventDefault = function(e) {\n\t e.preventDefault();\n\t };\n\n\t kendo.widgetInstance = function(element, suites) {\n\t var role = element.data(kendo.ns + \"role\"),\n\t widgets = [], i, length,\n\t elementData = element.data(\"kendoView\");\n\n\t if (role) {\n\t // HACK!!! mobile view scroller widgets are instantiated on data-role=\"content\" elements. We need to discover them when resizing.\n\t if (role === \"content\") {\n\t role = \"scroller\";\n\t }\n\n\t // kendoEditorToolbar is not a public plugin, thus it does not exist in kendo.ui.roles.\n\t // Therefore, this is needed in order to be resized when placed in Kendo Window.\n\t if (role === \"editortoolbar\") {\n\t var editorToolbar = element.data(\"kendoEditorToolbar\");\n\t if (editorToolbar) {\n\t return editorToolbar;\n\t }\n\t }\n\n\t // kendo.View is not a ui plugin\n\n\t if (role === \"view\" && elementData) {\n\t return elementData;\n\t }\n\n\t if (suites) {\n\t if (suites[0]) {\n\t for (i = 0, length = suites.length; i < length; i ++) {\n\t widgets.push(suites[i].roles[role]);\n\t }\n\t } else {\n\t widgets.push(suites.roles[role]);\n\t }\n\t }\n\t else {\n\t widgets = [ kendo.ui.roles[role], kendo.dataviz.ui.roles[role], kendo.mobile.ui.roles[role] ];\n\t }\n\n\t if (role.indexOf(\".\") >= 0) {\n\t widgets = [ kendo.getter(role)(window) ];\n\t }\n\n\t for (i = 0, length = widgets.length; i < length; i ++) {\n\t var widget = widgets[i];\n\t if (widget) {\n\t var instance = element.data(\"kendo\" + widget.fn.options.prefix + widget.fn.options.name);\n\t if (instance) {\n\t return instance;\n\t }\n\t }\n\t }\n\t }\n\t };\n\n\t kendo.onResize = function(callback) {\n\t var handler = callback;\n\t if (support.mobileOS.android) {\n\t handler = function() { setTimeout(callback, 600); };\n\t }\n\n\t $(window).on(support.resize, handler);\n\t return handler;\n\t };\n\n\t kendo.unbindResize = function(callback) {\n\t $(window).off(support.resize, callback);\n\t };\n\n\t kendo.attrValue = function(element, key) {\n\t return element.data(kendo.ns + key);\n\t };\n\n\t kendo.days = {\n\t Sunday: 0,\n\t Monday: 1,\n\t Tuesday: 2,\n\t Wednesday: 3,\n\t Thursday: 4,\n\t Friday: 5,\n\t Saturday: 6\n\t };\n\n\t function focusable(element, isTabIndexNotNaN) {\n\t var nodeName = element.nodeName.toLowerCase();\n\n\t return (/input|select|textarea|button|object/.test(nodeName) ?\n\t !element.disabled :\n\t \"a\" === nodeName ?\n\t element.href || isTabIndexNotNaN :\n\t isTabIndexNotNaN\n\t ) &&\n\t visible(element);\n\t }\n\n\t function visible(element) {\n\t return $.expr.pseudos.visible(element) &&\n\t !$(element).parents().addBack().filter(function() {\n\t return $.css(this,\"visibility\") === \"hidden\";\n\t }).length;\n\t }\n\n\t $.extend($.expr.pseudos, {\n\t kendoFocusable: function(element) {\n\t var idx = $.attr(element, \"tabindex\");\n\t return focusable(element, !isNaN(idx) && idx > -1);\n\t }\n\t });\n\n\t var MOUSE_EVENTS = [\"mousedown\", \"mousemove\", \"mouseenter\", \"mouseleave\", \"mouseover\", \"mouseout\", \"mouseup\", \"click\"];\n\t var EXCLUDE_BUST_CLICK_SELECTOR = \"label, input, [data-rel=external]\";\n\n\t var MouseEventNormalizer = {\n\t setupMouseMute: function() {\n\t var idx = 0,\n\t length = MOUSE_EVENTS.length,\n\t element = document.documentElement;\n\n\t if (MouseEventNormalizer.mouseTrap || !support.eventCapture) {\n\t return;\n\t }\n\n\t MouseEventNormalizer.mouseTrap = true;\n\n\t MouseEventNormalizer.bustClick = false;\n\t MouseEventNormalizer.captureMouse = false;\n\n\t var handler = function(e) {\n\t if (MouseEventNormalizer.captureMouse) {\n\t if (e.type === \"click\") {\n\t if (MouseEventNormalizer.bustClick && !$(e.target).is(EXCLUDE_BUST_CLICK_SELECTOR)) {\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t } else {\n\t e.stopPropagation();\n\t }\n\t }\n\t };\n\n\t for (; idx < length; idx++) {\n\t element.addEventListener(MOUSE_EVENTS[idx], handler, true);\n\t }\n\t },\n\n\t muteMouse: function(e) {\n\t MouseEventNormalizer.captureMouse = true;\n\t if (e.data.bustClick) {\n\t MouseEventNormalizer.bustClick = true;\n\t }\n\t clearTimeout(MouseEventNormalizer.mouseTrapTimeoutID);\n\t },\n\n\t unMuteMouse: function() {\n\t clearTimeout(MouseEventNormalizer.mouseTrapTimeoutID);\n\t MouseEventNormalizer.mouseTrapTimeoutID = setTimeout(function() {\n\t MouseEventNormalizer.captureMouse = false;\n\t MouseEventNormalizer.bustClick = false;\n\t }, 400);\n\t }\n\t };\n\n\t var eventMap = {\n\t down: \"touchstart mousedown\",\n\t move: \"mousemove touchmove\",\n\t up: \"mouseup touchend touchcancel\",\n\t cancel: \"mouseleave touchcancel\"\n\t };\n\n\t if (support.touch && (support.mobileOS.ios || support.mobileOS.android)) {\n\t eventMap = {\n\t down: \"touchstart\",\n\t move: \"touchmove\",\n\t up: \"touchend touchcancel\",\n\t cancel: \"touchcancel\"\n\t };\n\t } else if (support.pointers) {\n\t eventMap = {\n\t down: \"pointerdown\",\n\t move: \"pointermove\",\n\t up: \"pointerup\",\n\t cancel: \"pointercancel pointerleave\"\n\t };\n\t } else if (support.msPointers) {\n\t eventMap = {\n\t down: \"MSPointerDown\",\n\t move: \"MSPointerMove\",\n\t up: \"MSPointerUp\",\n\t cancel: \"MSPointerCancel MSPointerLeave\"\n\t };\n\t }\n\n\t if (support.msPointers && !(\"onmspointerenter\" in window)) { // IE10\n\t // Create MSPointerEnter/MSPointerLeave events using mouseover/out and event-time checks\n\t $.each({\n\t MSPointerEnter: \"MSPointerOver\",\n\t MSPointerLeave: \"MSPointerOut\"\n\t }, function( orig, fix ) {\n\t $.event.special[ orig ] = {\n\t delegateType: fix,\n\t bindType: fix,\n\n\t handle: function( event ) {\n\t var ret,\n\t target = this,\n\t related = event.relatedTarget,\n\t handleObj = event.handleObj;\n\n\t // For mousenter/leave call the handler if related is outside the target.\n\t // NB: No relatedTarget if the mouse left/entered the browser window\n\t if ( !related || (related !== target && !$.contains( target, related )) ) {\n\t event.type = handleObj.origType;\n\t ret = handleObj.handler.apply( this, arguments );\n\t event.type = fix;\n\t }\n\t return ret;\n\t }\n\t };\n\t });\n\t }\n\n\n\t var getEventMap = function(e) { return (eventMap[e] || e); },\n\t eventRegEx = /([^ ]+)/g;\n\n\t kendo.applyEventMap = function(events, ns) {\n\t events = events.replace(eventRegEx, getEventMap);\n\n\t if (ns) {\n\t events = events.replace(eventRegEx, \"$1.\" + ns);\n\t }\n\n\t return events;\n\t };\n\n\t kendo.keyDownHandler = function(e, widget) {\n\t var events = widget._events.kendoKeydown;\n\n\t if(!events){\n\t return true;\n\t }\n\n\t events = events.slice();\n\t e.sender = widget;\n\t e.preventKendoKeydown = false;\n\t for (var idx = 0, length = events.length; idx < length; idx++) {\n\t events[idx].call(widget, e);\n\t }\n\n\t return !e.preventKendoKeydown;\n\t };\n\n\t var on = $.fn.on;\n\n\t function kendoJQuery(selector, context) {\n\t return new kendoJQuery.fn.init(selector, context);\n\t }\n\n\t noDepricateExtend(true, kendoJQuery, $);\n\n\t kendoJQuery.fn = kendoJQuery.prototype = new $();\n\n\t kendoJQuery.fn.constructor = kendoJQuery;\n\n\t kendoJQuery.fn.init = function(selector, context) {\n\t if (context && context instanceof $ && !(context instanceof kendoJQuery)) {\n\t context = kendoJQuery(context);\n\t }\n\n\t return $.fn.init.call(this, selector, context, rootjQuery);\n\t };\n\n\t kendoJQuery.fn.init.prototype = kendoJQuery.fn;\n\n\t var rootjQuery = kendoJQuery(document);\n\n\t extend(kendoJQuery.fn, {\n\t handler: function(handler) {\n\t this.data(\"handler\", handler);\n\t return this;\n\t },\n\n\t autoApplyNS: function(ns) {\n\t this.data(\"kendoNS\", ns || kendo.guid());\n\t return this;\n\t },\n\n\t on: function() {\n\t var that = this,\n\t ns = that.data(\"kendoNS\");\n\n\t // support for event map signature\n\t if (arguments.length === 1) {\n\t return on.call(that, arguments[0]);\n\t }\n\n\t var context = that,\n\t args = slice.call(arguments);\n\n\t if (typeof args[args.length -1] === UNDEFINED) {\n\t args.pop();\n\t }\n\n\t var callback = args[args.length - 1],\n\t events = kendo.applyEventMap(args[0], ns);\n\n\t // setup mouse trap\n\t if (support.mouseAndTouchPresent && events.search(/mouse|click/) > -1 && this[0] !== document.documentElement) {\n\t MouseEventNormalizer.setupMouseMute();\n\n\t var selector = args.length === 2 ? null : args[1],\n\t bustClick = events.indexOf(\"click\") > -1 && events.indexOf(\"touchend\") > -1;\n\n\t on.call(this,\n\t {\n\t touchstart: MouseEventNormalizer.muteMouse,\n\t touchend: MouseEventNormalizer.unMuteMouse\n\t },\n\t selector,\n\t {\n\t bustClick: bustClick\n\t });\n\t }\n\n\t if(arguments[0].indexOf(\"keydown\") !== -1 && args[1] && args[1].options){\n\t args[0] = events;\n\t var widget = args[1];\n\t var keyDownCallBack = args[args.length - 1];\n\t args[args.length - 1]= function(e){\n\t if(kendo.keyDownHandler(e, widget)){\n\t return keyDownCallBack.apply(this, [e]);\n\t }\n\t };\n\t on.apply(that, args);\n\t return that;\n\t }\n\n\t if (typeof callback === STRING) {\n\t context = that.data(\"handler\");\n\t callback = context[callback];\n\n\t args[args.length - 1] = function(e) {\n\t callback.call(context, e);\n\t };\n\t }\n\n\t args[0] = events;\n\n\t on.apply(that, args);\n\n\t return that;\n\t },\n\n\t kendoDestroy: function(ns) {\n\t ns = ns || this.data(\"kendoNS\");\n\n\t if (ns) {\n\t this.off(\".\" + ns);\n\t }\n\n\t return this;\n\t }\n\t });\n\n\t kendo.jQuery = kendoJQuery;\n\t kendo.eventMap = eventMap;\n\n\t kendo.timezone = (function(){\n\t var months = { Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5, Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11 };\n\t var days = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 };\n\n\t function ruleToDate(year, rule) {\n\t var date;\n\t var targetDay;\n\t var ourDay;\n\t var month = rule[3];\n\t var on = rule[4];\n\t var time = rule[5];\n\t var cache = rule[8];\n\n\t if (!cache) {\n\t rule[8] = cache = {};\n\t }\n\n\t if (cache[year]) {\n\t return cache[year];\n\t }\n\n\t if (!isNaN(on)) {\n\t date = new Date(Date.UTC(year, months[month], on, time[0], time[1], time[2], 0));\n\t } else if (on.indexOf(\"last\") === 0) {\n\t date = new Date(Date.UTC(year, months[month] + 1, 1, time[0] - 24, time[1], time[2], 0));\n\n\t targetDay = days[on.substr(4, 3)];\n\t ourDay = date.getUTCDay();\n\n\t date.setUTCDate(date.getUTCDate() + targetDay - ourDay - (targetDay > ourDay ? 7 : 0));\n\t } else if (on.indexOf(\">=\") >= 0) {\n\t date = new Date(Date.UTC(year, months[month], on.substr(5), time[0], time[1], time[2], 0));\n\n\t targetDay = days[on.substr(0, 3)];\n\t ourDay = date.getUTCDay();\n\n\t date.setUTCDate(date.getUTCDate() + targetDay - ourDay + (targetDay < ourDay ? 7 : 0));\n\t } else if (on.indexOf(\"<=\") >= 0) {\n\t date = new Date(Date.UTC(year, months[month], on.substr(5), time[0], time[1], time[2], 0));\n\n\t targetDay = days[on.substr(0, 3)];\n\t ourDay = date.getUTCDay();\n\n\t date.setUTCDate(date.getUTCDate() + targetDay - ourDay - (targetDay > ourDay ? 7 : 0));\n\t }\n\n\t return cache[year] = date;\n\t }\n\n\t function findRule(utcTime, rules, zone) {\n\t rules = rules[zone];\n\n\t if (!rules) {\n\t var time = zone.split(\":\");\n\t var offset = 0;\n\n\t if (time.length > 1) {\n\t offset = time[0] * 60 + Number(time[1]);\n\t }\n\n\t return [-1000000, 'max', '-', 'Jan', 1, [0, 0, 0], offset, '-'];\n\t }\n\n\t var year = new Date(utcTime).getUTCFullYear();\n\n\t rules = jQuery.grep(rules, function(rule) {\n\t var from = rule[0];\n\t var to = rule[1];\n\n\t return from <= year && (to >= year || (from == year && to == \"only\") || to == \"max\");\n\t });\n\n\t rules.push(utcTime);\n\n\t rules.sort(function(a, b) {\n\t if (typeof a != \"number\") {\n\t a = Number(ruleToDate(year, a));\n\t }\n\n\t if (typeof b != \"number\") {\n\t b = Number(ruleToDate(year, b));\n\t }\n\n\t return a - b;\n\t });\n\n\t var rule = rules[jQuery.inArray(utcTime, rules) - 1] || rules[rules.length - 1];\n\n\t return isNaN(rule) ? rule : null;\n\t }\n\n\t function findZone(utcTime, zones, timezone) {\n\t var zoneRules = zones[timezone];\n\n\t if (typeof zoneRules === \"string\") {\n\t zoneRules = zones[zoneRules];\n\t }\n\n\t if (!zoneRules) {\n\t throw new Error('Timezone \"' + timezone + '\" is either incorrect, or kendo.timezones.min.js is not included.');\n\t }\n\n\t for (var idx = zoneRules.length - 1; idx >= 0; idx--) {\n\t var until = zoneRules[idx][3];\n\n\t if (until && utcTime > until) {\n\t break;\n\t }\n\t }\n\n\t var zone = zoneRules[idx + 1];\n\n\t if (!zone) {\n\t throw new Error('Timezone \"' + timezone + '\" not found on ' + utcTime + \".\");\n\t }\n\n\t return zone;\n\t }\n\n\t function zoneAndRule(utcTime, zones, rules, timezone) {\n\t if (typeof utcTime != NUMBER) {\n\t utcTime = Date.UTC(utcTime.getFullYear(), utcTime.getMonth(),\n\t utcTime.getDate(), utcTime.getHours(), utcTime.getMinutes(),\n\t utcTime.getSeconds(), utcTime.getMilliseconds());\n\t }\n\n\t var zone = findZone(utcTime, zones, timezone);\n\n\t return {\n\t zone: zone,\n\t rule: findRule(utcTime, rules, zone[1])\n\t };\n\t }\n\n\t function offset(utcTime, timezone) {\n\t if (timezone == \"Etc/UTC\" || timezone == \"Etc/GMT\") {\n\t return 0;\n\t }\n\n\t var info = zoneAndRule(utcTime, this.zones, this.rules, timezone);\n\t var zone = info.zone;\n\t var rule = info.rule;\n\n\t return kendo.parseFloat(rule? zone[0] - rule[6] : zone[0]);\n\t }\n\n\t function abbr(utcTime, timezone) {\n\t var info = zoneAndRule(utcTime, this.zones, this.rules, timezone);\n\t var zone = info.zone;\n\t var rule = info.rule;\n\n\t var base = zone[2];\n\n\t if (base.indexOf(\"/\") >= 0) {\n\t return base.split(\"/\")[rule && +rule[6] ? 1 : 0];\n\t } else if (base.indexOf(\"%s\") >= 0) {\n\t return base.replace(\"%s\", (!rule || rule[7] == \"-\") ? '' : rule[7]);\n\t }\n\n\t return base;\n\t }\n\n\t function convert(date, fromOffset, toOffset) {\n\t var tempToOffset = toOffset;\n\t var diff;\n\n\t if (typeof fromOffset == STRING) {\n\t fromOffset = this.offset(date, fromOffset);\n\t }\n\n\t if (typeof toOffset == STRING) {\n\t toOffset = this.offset(date, toOffset);\n\t }\n\n\t var fromLocalOffset = date.getTimezoneOffset();\n\n\t date = new Date(date.getTime() + (fromOffset - toOffset) * 60000);\n\n\t var toLocalOffset = date.getTimezoneOffset();\n\n\t if (typeof tempToOffset == STRING) {\n\t tempToOffset = this.offset(date, tempToOffset);\n\t }\n\n\t diff = (toLocalOffset - fromLocalOffset) + (toOffset - tempToOffset);\n\n\t return new Date(date.getTime() + diff * 60000);\n\t }\n\n\t function apply(date, timezone) {\n\t return this.convert(date, date.getTimezoneOffset(), timezone);\n\t }\n\n\t function remove(date, timezone) {\n\t return this.convert(date, timezone, date.getTimezoneOffset());\n\t }\n\n\t function toLocalDate(time) {\n\t return this.apply(new Date(time), \"Etc/UTC\");\n\t }\n\n\t return {\n\t zones: {},\n\t rules: {},\n\t offset: offset,\n\t convert: convert,\n\t apply: apply,\n\t remove: remove,\n\t abbr: abbr,\n\t toLocalDate: toLocalDate\n\t };\n\t })();\n\n\t kendo.date = (function(){\n\t var MS_PER_MINUTE = 60000,\n\t MS_PER_DAY = 86400000;\n\n\t function adjustDST(date, hours) {\n\t if (hours === 0 && date.getHours() === 23) {\n\t date.setHours(date.getHours() + 2);\n\t return true;\n\t }\n\n\t return false;\n\t }\n\n\t function setDayOfWeek(date, day, dir) {\n\t var hours = date.getHours();\n\n\t dir = dir || 1;\n\t day = ((day - date.getDay()) + (7 * dir)) % 7;\n\n\t date.setDate(date.getDate() + day);\n\t adjustDST(date, hours);\n\t }\n\n\t function dayOfWeek(date, day, dir) {\n\t date = new Date(date);\n\t setDayOfWeek(date, day, dir);\n\t return date;\n\t }\n\n\t function firstDayOfMonth(date) {\n\t return new Date(\n\t date.getFullYear(),\n\t date.getMonth(),\n\t 1\n\t );\n\t }\n\n\t function lastDayOfMonth(date) {\n\t var last = new Date(date.getFullYear(), date.getMonth() + 1, 0),\n\t first = firstDayOfMonth(date),\n\t timeOffset = Math.abs(last.getTimezoneOffset() - first.getTimezoneOffset());\n\n\t if (timeOffset) {\n\t last.setHours(first.getHours() + (timeOffset / 60));\n\t }\n\n\t return last;\n\t }\n\n\t function moveDateToWeekStart(date, weekStartDay) {\n\t if (weekStartDay !== 1) {\n\t return addDays(dayOfWeek(date, weekStartDay, -1), 4);\n\t }\n\n\t return addDays(date, (4 - (date.getDay() || 7)));\n\t }\n\n\t function calcWeekInYear(date, weekStartDay) {\n\t var firstWeekInYear = new Date(date.getFullYear(), 0, 1, -6);\n\n\t var newDate = moveDateToWeekStart(date, weekStartDay);\n\n\t var diffInMS = newDate.getTime() - firstWeekInYear.getTime();\n\n\t var days = Math.floor(diffInMS / MS_PER_DAY);\n\n\t return 1 + Math.floor(days / 7);\n\t }\n\n\t function weekInYear(date, weekStartDay) {\n\t if(weekStartDay === undefined) {\n\t weekStartDay = kendo.culture().calendar.firstDay;\n\t }\n\n\t var prevWeekDate = addDays(date, -7);\n\t var nextWeekDate = addDays(date, 7);\n\n\t var weekNumber = calcWeekInYear(date, weekStartDay);\n\n\t if (weekNumber === 0) {\n\t return calcWeekInYear(prevWeekDate, weekStartDay) + 1;\n\t }\n\n\t if (weekNumber === 53 && calcWeekInYear(nextWeekDate, weekStartDay) > 1) {\n\t return 1;\n\t }\n\n\t return weekNumber;\n\t }\n\n\t function getDate(date) {\n\t date = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);\n\t adjustDST(date, 0);\n\t return date;\n\t }\n\n\t function toUtcTime(date) {\n\t return Date.UTC(date.getFullYear(), date.getMonth(),\n\t date.getDate(), date.getHours(), date.getMinutes(),\n\t date.getSeconds(), date.getMilliseconds());\n\t }\n\n\t function getMilliseconds(date) {\n\t return toInvariantTime(date).getTime() - getDate(toInvariantTime(date));\n\t }\n\n\t function isInTimeRange(value, min, max) {\n\t var msMin = getMilliseconds(min),\n\t msMax = getMilliseconds(max),\n\t msValue;\n\n\t if (!value || msMin == msMax) {\n\t return true;\n\t }\n\n\t if (min >= max) {\n\t max += MS_PER_DAY;\n\t }\n\n\t msValue = getMilliseconds(value);\n\n\t if (msMin > msValue) {\n\t msValue += MS_PER_DAY;\n\t }\n\n\t if (msMax < msMin) {\n\t msMax += MS_PER_DAY;\n\t }\n\n\t return msValue >= msMin && msValue <= msMax;\n\t }\n\n\t function isInDateRange(value, min, max) {\n\t var msMin = min.getTime(),\n\t msMax = max.getTime(),\n\t msValue;\n\n\t if (msMin >= msMax) {\n\t msMax += MS_PER_DAY;\n\t }\n\n\t msValue = value.getTime();\n\n\t return msValue >= msMin && msValue <= msMax;\n\t }\n\n\t function addDays(date, offset) {\n\t var hours = date.getHours();\n\t date = new Date(date);\n\n\t setTime(date, offset * MS_PER_DAY);\n\t adjustDST(date, hours);\n\t return date;\n\t }\n\n\t function setTime(date, milliseconds, ignoreDST) {\n\t var offset = date.getTimezoneOffset();\n\t var difference;\n\n\t date.setTime(date.getTime() + milliseconds);\n\n\t if (!ignoreDST) {\n\t difference = date.getTimezoneOffset() - offset;\n\t date.setTime(date.getTime() + difference * MS_PER_MINUTE);\n\t }\n\t }\n\n\t function setHours(date, time) {\n\t date = new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds());\n\t adjustDST(date, time.getHours());\n\t return date;\n\t }\n\n\t function today() {\n\t return getDate(new Date());\n\t }\n\n\t function isToday(date) {\n\t return getDate(date).getTime() == today().getTime();\n\t }\n\n\t function toInvariantTime(date) {\n\t var staticDate = new Date(1980, 1, 1, 0, 0, 0);\n\n\t if (date) {\n\t staticDate.setHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());\n\t }\n\n\t return staticDate;\n\t }\n\n\t return {\n\t adjustDST: adjustDST,\n\t dayOfWeek: dayOfWeek,\n\t setDayOfWeek: setDayOfWeek,\n\t getDate: getDate,\n\t isInDateRange: isInDateRange,\n\t isInTimeRange: isInTimeRange,\n\t isToday: isToday,\n\t nextDay: function(date) {\n\t return addDays(date, 1);\n\t },\n\t previousDay: function(date) {\n\t return addDays(date, -1);\n\t },\n\t toUtcTime: toUtcTime,\n\t MS_PER_DAY: MS_PER_DAY,\n\t MS_PER_HOUR: 60 * MS_PER_MINUTE,\n\t MS_PER_MINUTE: MS_PER_MINUTE,\n\t setTime: setTime,\n\t setHours: setHours,\n\t addDays: addDays,\n\t today: today,\n\t toInvariantTime: toInvariantTime,\n\t firstDayOfMonth: firstDayOfMonth,\n\t lastDayOfMonth: lastDayOfMonth,\n\t weekInYear: weekInYear,\n\t getMilliseconds: getMilliseconds\n\t };\n\t })();\n\n\n\t kendo.stripWhitespace = function(element) {\n\t if (document.createNodeIterator) {\n\t var iterator = document.createNodeIterator(element, NodeFilter.SHOW_TEXT, function(node) {\n\t return node.parentNode == element ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;\n\t }, false);\n\n\t while (iterator.nextNode()) {\n\t if (iterator.referenceNode && !iterator.referenceNode.textContent.trim()) {\n\t iterator.referenceNode.parentNode.removeChild(iterator.referenceNode);\n\t }\n\t }\n\t } else { // IE7/8 support\n\t for (var i = 0; i < element.childNodes.length; i++) {\n\t var child = element.childNodes[i];\n\n\t if (child.nodeType == 3 && !/\\S/.test(child.nodeValue)) {\n\t element.removeChild(child);\n\t i--;\n\t }\n\n\t if (child.nodeType == 1) {\n\t kendo.stripWhitespace(child);\n\t }\n\t }\n\t }\n\t };\n\n\t var animationFrame = window.requestAnimationFrame ||\n\t window.webkitRequestAnimationFrame ||\n\t window.mozRequestAnimationFrame ||\n\t window.oRequestAnimationFrame ||\n\t window.msRequestAnimationFrame ||\n\t function(callback){ setTimeout(callback, 1000 / 60); };\n\n\t kendo.animationFrame = function(callback) {\n\t animationFrame.call(window, callback);\n\t };\n\n\t var animationQueue = [];\n\n\t kendo.queueAnimation = function(callback) {\n\t animationQueue[animationQueue.length] = callback;\n\t if (animationQueue.length === 1) {\n\t kendo.runNextAnimation();\n\t }\n\t };\n\n\t kendo.runNextAnimation = function() {\n\t kendo.animationFrame(function() {\n\t if (animationQueue[0]) {\n\t animationQueue.shift()();\n\t if (animationQueue[0]) {\n\t kendo.runNextAnimation();\n\t }\n\t }\n\t });\n\t };\n\n\t kendo.parseQueryStringParams = function(url) {\n\t var queryString = url.split('?')[1] || \"\",\n\t params = {},\n\t paramParts = queryString.split(/&|=/),\n\t length = paramParts.length,\n\t idx = 0;\n\n\t for (; idx < length; idx += 2) {\n\t if(paramParts[idx] !== \"\") {\n\t params[decodeURIComponent(paramParts[idx])] = decodeURIComponent(paramParts[idx + 1]);\n\t }\n\t }\n\n\t return params;\n\t };\n\n\t kendo.elementUnderCursor = function(e) {\n\t if (typeof e.x.client != \"undefined\") {\n\t return document.elementFromPoint(e.x.client, e.y.client);\n\t }\n\t };\n\n\t kendo.wheelDeltaY = function(jQueryEvent) {\n\t var e = jQueryEvent.originalEvent,\n\t deltaY = e.wheelDeltaY,\n\t delta;\n\n\t if (e.wheelDelta) { // Webkit and IE\n\t if (deltaY === undefined || deltaY) { // IE does not have deltaY, thus always scroll (horizontal scrolling is treated as vertical)\n\t delta = e.wheelDelta;\n\t }\n\t } else if (e.detail && e.axis === e.VERTICAL_AXIS) { // Firefox and Opera\n\t delta = (-e.detail) * 10;\n\t }\n\n\t return delta;\n\t };\n\n\t kendo.throttle = function(fn, delay) {\n\t var timeout;\n\t var lastExecTime = 0;\n\n\t if (!delay || delay <= 0) {\n\t return fn;\n\t }\n\n\t var throttled = function() {\n\t var that = this;\n\t var elapsed = +new Date() - lastExecTime;\n\t var args = arguments;\n\n\t function exec() {\n\t fn.apply(that, args);\n\t lastExecTime = +new Date();\n\t }\n\n\t // first execution\n\t if (!lastExecTime) {\n\t return exec();\n\t }\n\n\t if (timeout) {\n\t clearTimeout(timeout);\n\t }\n\n\t if (elapsed > delay) {\n\t exec();\n\t } else {\n\t timeout = setTimeout(exec, delay - elapsed);\n\t }\n\t };\n\n\t throttled.cancel = function() {\n\t clearTimeout(timeout);\n\t };\n\n\t return throttled;\n\t };\n\n\n\t kendo.caret = function (element, start, end) {\n\t var rangeElement;\n\t var isPosition = start !== undefined;\n\n\t if (end === undefined) {\n\t end = start;\n\t }\n\n\t if (element[0]) {\n\t element = element[0];\n\t }\n\n\t if (isPosition && element.disabled) {\n\t return;\n\t }\n\n\t try {\n\t if (element.selectionStart !== undefined) {\n\t if (isPosition) {\n\t element.focus();\n\t var mobile = support.mobileOS;\n\t if(mobile.wp || mobile.android) {// without the timeout the caret is at the end of the input\n\t setTimeout(function() { element.setSelectionRange(start, end); }, 0);\n\t }\n\t else {\n\t element.setSelectionRange(start, end);\n\t }\n\t } else {\n\t start = [element.selectionStart, element.selectionEnd];\n\t }\n\t } else if (document.selection) {\n\t if ($(element).is(\":visible\")) {\n\t element.focus();\n\t }\n\n\t rangeElement = element.createTextRange();\n\n\t if (isPosition) {\n\t rangeElement.collapse(true);\n\t rangeElement.moveStart(\"character\", start);\n\t rangeElement.moveEnd(\"character\", end - start);\n\t rangeElement.select();\n\t } else {\n\t var rangeDuplicated = rangeElement.duplicate(),\n\t selectionStart, selectionEnd;\n\n\t rangeElement.moveToBookmark(document.selection.createRange().getBookmark());\n\t rangeDuplicated.setEndPoint('EndToStart', rangeElement);\n\t selectionStart = rangeDuplicated.text.length;\n\t selectionEnd = selectionStart + rangeElement.text.length;\n\n\t start = [selectionStart, selectionEnd];\n\t }\n\t }\n\t } catch(e) {\n\t /* element is not focused or it is not in the DOM */\n\t start = [];\n\t }\n\n\t return start;\n\t };\n\n\t kendo.compileMobileDirective = function(element, scope) {\n\t var angular = window.angular;\n\n\t element.attr(\"data-\" + kendo.ns + \"role\", element[0].tagName.toLowerCase().replace('kendo-mobile-', '').replace('-', ''));\n\n\t angular.element(element).injector().invoke([\"$compile\", function($compile) {\n\t $compile(element)(scope);\n\n\t if (!/^\\$(digest|apply)$/.test(scope.$$phase)) {\n\t scope.$digest();\n\t }\n\t }]);\n\n\t return kendo.widgetInstance(element, kendo.mobile.ui);\n\t };\n\n\t kendo.antiForgeryTokens = function() {\n\t var tokens = { },\n\t csrf_token = $(\"meta[name=csrf-token],meta[name=_csrf]\").attr(\"content\"),\n\t csrf_param = $(\"meta[name=csrf-param],meta[name=_csrf_header]\").attr(\"content\");\n\n\t $(\"input[name^='__RequestVerificationToken']\").each(function() {\n\t tokens[this.name] = this.value;\n\t });\n\n\t if (csrf_param !== undefined && csrf_token !== undefined) {\n\t tokens[csrf_param] = csrf_token;\n\t }\n\n\t return tokens;\n\t };\n\n\t kendo.cycleForm = function(form) {\n\t var firstElement = form.find(\"input, .k-widget\").first();\n\t var lastElement = form.find(\"button, .k-button\").last();\n\n\t function focus(el) {\n\t var widget = kendo.widgetInstance(el);\n\n\t if (widget && widget.focus) {\n\t widget.focus();\n\t } else {\n\t el.focus();\n\t }\n\t }\n\n\t lastElement.on(\"keydown\", function(e) {\n\t if (e.keyCode == kendo.keys.TAB && !e.shiftKey) {\n\t e.preventDefault();\n\t focus(firstElement);\n\t }\n\t });\n\n\t firstElement.on(\"keydown\", function(e) {\n\t if (e.keyCode == kendo.keys.TAB && e.shiftKey) {\n\t e.preventDefault();\n\t focus(lastElement);\n\t }\n\t });\n\t };\n\n\t kendo.focusElement = function(element) {\n\t var scrollTopPositions = [];\n\t var scrollableParents = element.parentsUntil(\"body\")\n\t .filter(function(index, element) {\n\t var computedStyle = kendo.getComputedStyles(element, [\"overflow\"]);\n\t return computedStyle.overflow !== \"visible\";\n\t })\n\t .add(window);\n\n\t scrollableParents.each(function(index, parent) {\n\t scrollTopPositions[index] = $(parent).scrollTop();\n\t });\n\n\t try {\n\t //The setActive method does not cause the document to scroll to the active object in the current page\n\t element[0].setActive();\n\t } catch (e) {\n\t element[0].focus();\n\t }\n\n\t scrollableParents.each(function(index, parent) {\n\t $(parent).scrollTop(scrollTopPositions[index]);\n\t });\n\t };\n\n\t kendo.focusNextElement = function () {\n\t if (document.activeElement) {\n\t var focussable = $(\":kendoFocusable\");\n\t var index = focussable.index(document.activeElement);\n\n\t if(index > -1) {\n\t var nextElement = focussable[index + 1] || focussable[0];\n\t nextElement.focus();\n\t }\n\t }\n\t };\n\n\t kendo.trim = function(value) {\n\t if(!!value) {\n\t return value.toString().trim();\n\t } else {\n\t return \"\";\n\t }\n\t };\n\n\t kendo.getWidgetFocusableElement = function(element) {\n\t var nextFocusable = element.closest(\":kendoFocusable\"),\n\t widgetInstance = kendo.widgetInstance(element),\n\t target;\n\n\t if (nextFocusable.length) {\n\t target = nextFocusable;\n\t } else if (widgetInstance) {\n\t target = widgetInstance.options.name === 'Editor' ?\n\t $(widgetInstance.body) :\n\t widgetInstance.wrapper.find(\":kendoFocusable\").first();\n\t } else {\n\t target = element;\n\t }\n\n\t return target;\n\t };\n\n\t kendo.addAttribute = function(element, attribute, value) {\n\t var current = element.attr(attribute) || \"\";\n\n\t if (current.indexOf(value) < 0) {\n\t element.attr(attribute, (current + \" \" + value).trim());\n\t }\n\t };\n\n\t kendo.removeAttribute = function(element, attribute, value) {\n\t var current = element.attr(attribute) || \"\";\n\n\t element.attr(attribute, current.replace(value, \"\").trim());\n\t };\n\n\t kendo.toggleAttribute = function(element, attribute, value) {\n\t var current = element.attr(attribute) || \"\";\n\n\t if (current.indexOf(value) < 0) {\n\t kendo.addAttribute(element, attribute, value);\n\t } else {\n\t kendo.removeAttribute(element, attribute, value);\n\t }\n\t };\n\n\t kendo.matchesMedia = function(mediaQuery) {\n\t var media = kendo._bootstrapToMedia(mediaQuery) || mediaQuery;\n\t return support.matchMedia && window.matchMedia(media).matches;\n\t };\n\n\t kendo._bootstrapToMedia = function(bootstrapMedia) {\n\t return {\n\t \"xs\": \"(max-width: 576px)\",\n\t \"sm\": \"(min-width: 576px)\",\n\t \"md\": \"(min-width: 768px)\",\n\t \"lg\": \"(min-width: 992px)\",\n\t \"xl\": \"(min-width: 1200px)\"\n\t }[bootstrapMedia];\n\t };\n\n\t kendo.fileGroupMap = {\n\t audio: [\".aif\", \".iff\", \".m3u\", \".m4a\", \".mid\", \".mp3\", \".mpa\", \".wav\", \".wma\", \".ogg\", \".wav\", \".wma\", \".wpl\"],\n\t video: [\".3g2\", \".3gp\", \".avi\", \".asf\", \".flv\", \".m4u\", \".rm\", \".h264\", \".m4v\", \".mkv\", \".mov\", \".mp4\", \".mpg\",\n\t \".rm\", \".swf\", \".vob\", \".wmv\"],\n\t image: [\".ai\", \".dds\", \".heic\", \".jpe\", \"jfif\", \".jif\", \".jp2\", \".jps\", \".eps\", \".bmp\", \".gif\", \".jpeg\",\n\t \".jpg\", \".png\", \".ps\", \".psd\", \".svg\", \".svgz\", \".tif\", \".tiff\"],\n\t txt: [\".doc\", \".docx\", \".log\", \".pages\", \".tex\", \".wpd\", \".wps\", \".odt\", \".rtf\", \".text\", \".txt\", \".wks\"],\n\t presentation: [\".key\", \".odp\", \".pps\", \".ppt\", \".pptx\"],\n\t data: [\".xlr\", \".xls\", \".xlsx\"],\n\t programming: [\".tmp\", \".bak\", \".msi\", \".cab\", \".cpl\", \".cur\", \".dll\", \".dmp\", \".drv\", \".icns\", \".ico\", \".link\",\n\t \".sys\", \".cfg\", \".ini\", \".asp\", \".aspx\", \".cer\", \".csr\", \".css\", \".dcr\", \".htm\", \".html\", \".js\",\n\t \".php\", \".rss\", \".xhtml\"],\n\t pdf: [\".pdf\"],\n\t config: [\".apk\", \".app\", \".bat\", \".cgi\", \".com\", \".exe\", \".gadget\", \".jar\", \".wsf\"],\n\t zip: [\".7z\", \".cbr\", \".gz\", \".sitx\", \".arj\", \".deb\", \".pkg\", \".rar\", \".rpm\", \".tar.gz\", \".z\", \".zip\", \".zipx\"],\n\t \"disc-image\": [\".dmg\", \".iso\", \".toast\", \".vcd\", \".bin\", \".cue\", \".mdf\"]\n\t };\n\n\t kendo.getFileGroup = function(extension, withPrefix) {\n\t var fileTypeMap = kendo.fileGroupMap;\n\t var groups = Object.keys(fileTypeMap);\n\t var type = \"file\";\n\n\t if (extension === undefined || !extension.length) {\n\t return type;\n\t }\n\n\t for (var i = 0; i < groups.length; i += 1) {\n\t var extensions = fileTypeMap[groups[i]];\n\n\t if (extensions.indexOf(extension.toLowerCase()) > -1) {\n\t return withPrefix ? \"file-\" + groups[i] : groups[i];\n\t }\n\t }\n\n\t return type;\n\t };\n\n\t kendo.getFileSizeMessage = function(size) {\n\t var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n\n\t if (size === 0) {\n\t return '0 Byte';\n\t }\n\n\t var i = parseInt(Math.floor(Math.log(size) / Math.log(1024)), 10);\n\t return Math.round(size / Math.pow(1024, i), 2) + ' ' + sizes[i];\n\t };\n\n\t kendo.selectorFromClasses = function(classes) {\n\t return \".\"+classes.split(\" \").join(\".\");\n\t };\n\n\t // kendo.saveAs -----------------------------------------------\n\t (function() {\n\t function postToProxy(dataURI, fileName, proxyURL, proxyTarget) {\n\t var form = $(\"
    \").attr({\n\t action: proxyURL,\n\t method: \"POST\",\n\t target: proxyTarget\n\t });\n\n\t var data = kendo.antiForgeryTokens();\n\t data.fileName = fileName;\n\n\t var parts = dataURI.split(\";base64,\");\n\t data.contentType = parts[0].replace(\"data:\", \"\");\n\t data.base64 = parts[1];\n\n\t for (var name in data) {\n\t if (data.hasOwnProperty(name)) {\n\t $('').attr({\n\t value: data[name],\n\t name: name,\n\t type: \"hidden\"\n\t }).appendTo(form);\n\t }\n\t }\n\n\t form.appendTo(\"body\").submit().remove();\n\t }\n\n\t var fileSaver = document.createElement(\"a\");\n\t var downloadAttribute = \"download\" in fileSaver && !kendo.support.browser.edge;\n\n\t function saveAsBlob(dataURI, fileName) {\n\t var blob = dataURI; // could be a Blob object\n\n\t if (typeof dataURI == \"string\") {\n\t var parts = dataURI.split(\";base64,\");\n\t var contentType = parts[0];\n\t var base64 = atob(parts[1]);\n\t var array = new Uint8Array(base64.length);\n\n\t for (var idx = 0; idx < base64.length; idx++) {\n\t array[idx] = base64.charCodeAt(idx);\n\t }\n\t blob = new Blob([array.buffer], { type: contentType });\n\t }\n\n\t navigator.msSaveBlob(blob, fileName);\n\t }\n\n\t function saveAsDataURI(dataURI, fileName) {\n\t if (window.Blob && dataURI instanceof Blob) {\n\t dataURI = URL.createObjectURL(dataURI);\n\t }\n\n\t fileSaver.download = fileName;\n\t fileSaver.href = dataURI;\n\n\t var e = document.createEvent(\"MouseEvents\");\n\t e.initMouseEvent(\"click\", true, false, window,\n\t 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n\n\t fileSaver.dispatchEvent(e);\n\t setTimeout(function(){\n\t URL.revokeObjectURL(dataURI);\n\t });\n\t }\n\n\t kendo.saveAs = function(options) {\n\t var save = postToProxy;\n\n\t if (!options.forceProxy) {\n\t if (downloadAttribute) {\n\t save = saveAsDataURI;\n\t } else if (navigator.msSaveBlob) {\n\t save = saveAsBlob;\n\t }\n\t }\n\n\t save(options.dataURI, options.fileName, options.proxyURL, options.proxyTarget);\n\t };\n\t })();\n\n\t // kendo proxySetters\n\t kendo.proxyModelSetters = function proxyModelSetters(data) {\n\t var observable = {};\n\n\t Object.keys(data || {}).forEach(function(property) {\n\t Object.defineProperty(observable, property, {\n\t get: function() {\n\t return data[property];\n\t },\n\t set: function(value) {\n\t data[property] = value;\n\t data.dirty = true;\n\t }\n\t });\n\t });\n\n\t return observable;\n\t };\n\n\n\t // Kendo defaults\n\t (function() {\n\n\t kendo.defaults = kendo.defaults || {};\n\t kendo.setDefaults = function(key, value) {\n\t var path = key.split(\".\");\n\t var curr = kendo.defaults;\n\n\t key = path.pop();\n\n\t path.forEach(function(part) {\n\t if (curr[part] === undefined) {\n\t curr[part] = {};\n\t }\n\n\t curr = curr[part];\n\t });\n\n\t if (value.constructor === Object) {\n\t curr[key] = deepExtend({}, curr[key], value);\n\t } else {\n\t curr[key] = value;\n\t }\n\t };\n\n\t })();\n\n\t})(jQuery, window);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1017)))\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1064);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1064:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018), __webpack_require__(1065), __webpack_require__(1066) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"data\",\n\t name: \"Data source\",\n\t category: \"framework\",\n\t description: \"Powerful component for using local and remote data.Fully supports CRUD, Sorting, Paging, Filtering, Grouping, and Aggregates.\",\n\t depends: [ \"core\" ],\n\t features: [ {\n\t id: \"data-odata\",\n\t name: \"OData\",\n\t description: \"Support for accessing Open Data Protocol (OData) services.\",\n\t depends: [ \"data.odata\" ]\n\t }, {\n\t id: \"data-signalr\",\n\t name: \"SignalR\",\n\t description: \"Support for binding to SignalR hubs.\",\n\t depends: [ \"data.signalr\" ]\n\t }, {\n\t id: \"data-XML\",\n\t name: \"XML\",\n\t description: \"Support for binding to XML.\",\n\t depends: [ \"data.xml\" ]\n\t }]\n\t};\n\n\t/*jshint eqnull: true, loopfunc: true, evil: true */\n\t(function($, undefined) {\n\t var extend = $.extend,\n\t proxy = $.proxy,\n\t isPlainObject = $.isPlainObject,\n\t isEmptyObject = $.isEmptyObject,\n\t isArray = $.isArray,\n\t grep = $.grep,\n\t ajax = $.ajax,\n\t map,\n\t each = $.each,\n\t noop = $.noop,\n\t kendo = window.kendo,\n\t isFunction = kendo.isFunction,\n\t Observable = kendo.Observable,\n\t Class = kendo.Class,\n\t STRING = \"string\",\n\t FUNCTION = \"function\",\n\t ASCENDING = \"asc\",\n\t CREATE = \"create\",\n\t READ = \"read\",\n\t UPDATE = \"update\",\n\t DESTROY = \"destroy\",\n\t CHANGE = \"change\",\n\t SYNC = \"sync\",\n\t GET = \"get\",\n\t ERROR = \"error\",\n\t REQUESTSTART = \"requestStart\",\n\t PROGRESS = \"progress\",\n\t REQUESTEND = \"requestEnd\",\n\t crud = [CREATE, READ, UPDATE, DESTROY],\n\t identity = function(o) { return o; },\n\t getter = kendo.getter,\n\t stringify = kendo.stringify,\n\t math = Math,\n\t push = [].push,\n\t join = [].join,\n\t pop = [].pop,\n\t splice = [].splice,\n\t shift = [].shift,\n\t slice = [].slice,\n\t unshift = [].unshift,\n\t toString = {}.toString,\n\t stableSort = kendo.support.stableSort,\n\t dateRegExp = /^\\/Date\\((.*?)\\)\\/$/;\n\n\t var ObservableArray = Observable.extend({\n\t init: function(array, type) {\n\t var that = this;\n\n\t that.type = type || ObservableObject;\n\n\t Observable.fn.init.call(that);\n\n\t that.length = array.length;\n\n\t that.wrapAll(array, that);\n\t },\n\n\t at: function(index) {\n\t return this[index];\n\t },\n\n\t toJSON: function(serializeFunctions) {\n\t var idx, length = this.length, value, json = new Array(length);\n\n\t for (idx = 0; idx < length; idx++){\n\t value = this[idx];\n\n\t if (value instanceof ObservableObject) {\n\t value = value.toJSON(serializeFunctions);\n\t }\n\n\t json[idx] = value;\n\t }\n\n\t return json;\n\t },\n\n\t parent: noop,\n\n\t wrapAll: function(source, target) {\n\t var that = this,\n\t idx,\n\t length,\n\t parent = function() {\n\t return that;\n\t };\n\n\t target = target || [];\n\n\t for (idx = 0, length = source.length; idx < length; idx++) {\n\t target[idx] = that.wrap(source[idx], parent);\n\t }\n\n\t return target;\n\t },\n\n\t wrap: function(object, parent) {\n\t var that = this,\n\t observable;\n\n\t if (object !== null && toString.call(object) === \"[object Object]\") {\n\t observable = object instanceof that.type || object instanceof Model;\n\n\t if (!observable) {\n\t object = object instanceof ObservableObject ? object.toJSON() : object;\n\t object = new that.type(object);\n\t }\n\n\t object.parent = parent;\n\n\t object.bind(CHANGE, function(e) {\n\t that.trigger(CHANGE, {\n\t field: e.field,\n\t node: e.node,\n\t index: e.index,\n\t items: e.items || [this],\n\t action: e.node ? (e.action || \"itemloaded\") : \"itemchange\"\n\t });\n\t });\n\t }\n\n\t return object;\n\t },\n\n\t push: function() {\n\t var index = this.length,\n\t items = this.wrapAll(arguments),\n\t result;\n\n\t result = push.apply(this, items);\n\n\t if (!this.omitChangeEvent) {\n\t this.trigger(CHANGE, {\n\t action: \"add\",\n\t index: index,\n\t items: items\n\t });\n\t }\n\n\t return result;\n\t },\n\n\t slice: slice,\n\n\t sort: [].sort,\n\n\t join: join,\n\n\t pop: function() {\n\t var length = this.length, result = pop.apply(this);\n\n\t if (length) {\n\t this.trigger(CHANGE, {\n\t action: \"remove\",\n\t index: length - 1,\n\t items:[result]\n\t });\n\t }\n\n\t return result;\n\t },\n\n\t splice: function(index, howMany, item) {\n\t var items = this.wrapAll(slice.call(arguments, 2)),\n\t result, i, len;\n\n\t result = splice.apply(this, [index, howMany].concat(items));\n\n\t if (result.length) {\n\t this.trigger(CHANGE, {\n\t action: \"remove\",\n\t index: index,\n\t items: result\n\t });\n\n\t for (i = 0, len = result.length; i < len; i++) {\n\t if (result[i] && result[i].children) {\n\t result[i].unbind(CHANGE);\n\t }\n\t }\n\t }\n\n\t if (item) {\n\t this.trigger(CHANGE, {\n\t action: \"add\",\n\t index: index,\n\t items: items\n\t });\n\t }\n\t return result;\n\t },\n\n\t shift: function() {\n\t var length = this.length, result = shift.apply(this);\n\n\t if (length) {\n\t this.trigger(CHANGE, {\n\t action: \"remove\",\n\t index: 0,\n\t items:[result]\n\t });\n\t }\n\n\t return result;\n\t },\n\n\t unshift: function() {\n\t var items = this.wrapAll(arguments),\n\t result;\n\n\t result = unshift.apply(this, items);\n\n\t this.trigger(CHANGE, {\n\t action: \"add\",\n\t index: 0,\n\t items: items\n\t });\n\n\t return result;\n\t },\n\n\t indexOf: function(item) {\n\t var that = this,\n\t idx,\n\t length;\n\n\t for (idx = 0, length = that.length; idx < length; idx++) {\n\t if (that[idx] === item) {\n\t return idx;\n\t }\n\t }\n\t return -1;\n\t },\n\n\t forEach: function(callback, thisArg) {\n\t var idx = 0;\n\t var length = this.length;\n\t var context = thisArg || window;\n\n\t for (; idx < length; idx++) {\n\t callback.call(context, this[idx], idx, this);\n\t }\n\t },\n\n\t map: function(callback, thisArg) {\n\t var idx = 0;\n\t var result = [];\n\t var length = this.length;\n\t var context = thisArg || window;\n\n\t for (; idx < length; idx++) {\n\t result[idx] = callback.call(context, this[idx], idx, this);\n\t }\n\n\t return result;\n\t },\n\n\t reduce: function(callback) {\n\t var idx = 0,\n\t result,\n\t length = this.length;\n\n\t if (arguments.length == 2) {\n\t result = arguments[1];\n\t } else if (idx < length) {\n\t result = this[idx++];\n\t }\n\n\t for (; idx < length; idx++) {\n\t result = callback(result, this[idx], idx, this);\n\t }\n\n\t return result;\n\t },\n\n\t reduceRight: function(callback) {\n\t var idx = this.length - 1,\n\t result;\n\n\t if (arguments.length == 2) {\n\t result = arguments[1];\n\t } else if (idx > 0) {\n\t result = this[idx--];\n\t }\n\n\t for (; idx >= 0; idx--) {\n\t result = callback(result, this[idx], idx, this);\n\t }\n\n\t return result;\n\t },\n\n\t filter: function(callback, thisArg) {\n\t var idx = 0;\n\t var result = [];\n\t var item;\n\t var length = this.length;\n\t var context = thisArg || window;\n\n\t for (; idx < length; idx++) {\n\t item = this[idx];\n\t if (callback.call(context, item, idx, this)) {\n\t result[result.length] = item;\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t find: function(callback, thisArg) {\n\t var idx = 0;\n\t var item;\n\t var length = this.length;\n\t var context = thisArg || window;\n\n\t for (; idx < length; idx++) {\n\t item = this[idx];\n\t if (callback.call(context, item, idx, this)) {\n\t return item;\n\t }\n\t }\n\t },\n\n\t every: function(callback, thisArg) {\n\t var idx = 0;\n\t var item;\n\t var length = this.length;\n\t var context = thisArg || window;\n\n\t for (; idx < length; idx++) {\n\t item = this[idx];\n\t if (!callback.call(context, item, idx, this)) {\n\t return false;\n\t }\n\t }\n\n\t return true;\n\t },\n\n\t some: function(callback, thisArg) {\n\t var idx = 0;\n\t var item;\n\t var length = this.length;\n\t var context = thisArg || window;\n\n\t for (; idx < length; idx++) {\n\t item = this[idx];\n\t if (callback.call(context, item, idx, this)) {\n\t return true;\n\t }\n\t }\n\n\t return false;\n\t },\n\n\t // non-standard collection methods\n\t remove: function(item) {\n\t var idx = this.indexOf(item);\n\n\t if (idx !== -1) {\n\t this.splice(idx, 1);\n\t }\n\t },\n\n\t empty: function() {\n\t this.splice(0, this.length);\n\t }\n\t });\n\n\t // Polyfill for Symbol.iterator\n\t if (typeof Symbol !== \"undefined\" && Symbol.iterator && !ObservableArray.prototype[Symbol.iterator]) {\n\t ObservableArray.prototype[Symbol.iterator] = [][Symbol.iterator];\n\t }\n\n\t var LazyObservableArray = ObservableArray.extend({\n\t init: function (data, type, events) {\n\t Observable.fn.init.call(this);\n\n\t this.type = type || ObservableObject;\n\n\t if (events) {\n\t this._events = events;\n\t }\n\n\t for (var idx = 0; idx < data.length; idx++) {\n\t this[idx] = data[idx];\n\t }\n\n\t this.length = idx;\n\t this._parent = proxy(function() { return this; }, this);\n\t },\n\t at: function(index) {\n\t var item = this[index];\n\n\t if (!(item instanceof this.type)) {\n\t item = this[index] = this.wrap(item, this._parent);\n\t } else {\n\t item.parent = this._parent;\n\t }\n\n\t return item;\n\t }\n\t });\n\n\t function eventHandler(context, type, field, prefix) {\n\t return function(e) {\n\t var event = {}, key;\n\n\t for (key in e) {\n\t event[key] = e[key];\n\t }\n\n\t if (prefix) {\n\t event.field = field + \".\" + e.field;\n\t } else {\n\t event.field = field;\n\t }\n\n\t if (type == CHANGE && context._notifyChange) {\n\t context._notifyChange(event);\n\t }\n\n\t context.trigger(type, event);\n\t };\n\t }\n\n\t var ObservableObject = Observable.extend({\n\t init: function(value) {\n\t var that = this,\n\t member,\n\t field,\n\t parent = function() {\n\t return that;\n\t };\n\n\t Observable.fn.init.call(this);\n\n\t this._handlers = {};\n\n\t for (field in value) {\n\t member = value[field];\n\n\t if (typeof member === \"object\" && member && !member.getTime && field.charAt(0) != \"_\") {\n\t member = that.wrap(member, field, parent);\n\t }\n\n\t that[field] = member;\n\t }\n\n\t that.uid = kendo.guid();\n\t },\n\n\t shouldSerialize: function(field, serializeFunctions) {\n\t return this.hasOwnProperty(field) && field !== \"_handlers\" && field !== \"_events\" && ((serializeFunctions && serializeFunctions[field]) || typeof this[field] !== FUNCTION) && field !== \"uid\";\n\t },\n\n\t forEach: function(f) {\n\t for (var i in this) {\n\t if (this.shouldSerialize(i)) {\n\t f(this[i], i);\n\t }\n\t }\n\t },\n\n\t toJSON: function (serializeFunctions) {\n\t var result = {}, value, field;\n\n\t for (field in this) {\n\t if (this.shouldSerialize(field, serializeFunctions)) {\n\t value = this[field];\n\n\t if (value instanceof ObservableObject || value instanceof ObservableArray) {\n\t value = value.toJSON(serializeFunctions);\n\t }\n\n\t result[field] = value;\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t get: function(field) {\n\t var that = this, result;\n\n\t that.trigger(GET, { field: field });\n\n\t if (field === \"this\") {\n\t result = that;\n\t } else {\n\t result = kendo.getter(field, true)(that);\n\t }\n\n\t return result;\n\t },\n\n\t _set: function(field, value) {\n\t var that = this;\n\t var composite = field.indexOf(\".\") >= 0;\n\n\t if (composite) {\n\t var paths = field.split(\".\"),\n\t path = \"\";\n\n\t while (paths.length > 1) {\n\t path += paths.shift();\n\t var obj = kendo.getter(path, true)(that);\n\t if (obj instanceof ObservableObject) {\n\t obj.set(paths.join(\".\"), value);\n\t return composite;\n\t }\n\t path += \".\";\n\t }\n\t }\n\n\t kendo.setter(field)(that, value);\n\n\t return composite;\n\t },\n\n\t set: function(field, value) {\n\t var that = this,\n\t isSetPrevented = false,\n\t composite = field.indexOf(\".\") >= 0,\n\t current = kendo.getter(field, true)(that);\n\n\t if (current !== value) {\n\t if (current instanceof Observable && this._handlers[field]) {\n\t if (this._handlers[field].get) {\n\t current.unbind(GET, this._handlers[field].get);\n\t }\n\t current.unbind(CHANGE, this._handlers[field].change);\n\t }\n\n\t isSetPrevented = that.trigger(\"set\", { field: field, value: value });\n\n\t if (!isSetPrevented) {\n\t if (!composite) {\n\t value = that.wrap(value, field, function() { return that; });\n\t }\n\t if (!that._set(field, value) || field.indexOf(\"(\") >= 0 || field.indexOf(\"[\") >= 0) {\n\t that.trigger(CHANGE, { field: field });\n\t }\n\t }\n\t }\n\n\t return isSetPrevented;\n\t },\n\n\t parent: noop,\n\n\t wrap: function(object, field, parent) {\n\t var that = this;\n\t var get;\n\t var change;\n\t var type = toString.call(object);\n\n\t if (object != null && (type === \"[object Object]\" || type === \"[object Array]\")) {\n\t var isObservableArray = object instanceof ObservableArray;\n\t var isDataSource = object instanceof DataSource;\n\n\t if (type === \"[object Object]\" && !isDataSource && !isObservableArray) {\n\t if (!(object instanceof ObservableObject)) {\n\t object = new ObservableObject(object);\n\t }\n\n\t get = eventHandler(that, GET, field, true);\n\t object.bind(GET, get);\n\t change = eventHandler(that, CHANGE, field, true);\n\t object.bind(CHANGE, change);\n\n\t that._handlers[field] = { get: get, change: change };\n\t } else if (type === \"[object Array]\" || isObservableArray || isDataSource) {\n\t if (!isObservableArray && !isDataSource) {\n\t object = new ObservableArray(object);\n\t }\n\n\t change = eventHandler(that, CHANGE, field, false);\n\n\t object.bind(CHANGE, change);\n\n\t that._handlers[field] = { change: change };\n\t }\n\n\t object.parent = parent;\n\t }\n\n\t return object;\n\t }\n\t });\n\n\t function equal(x, y) {\n\t if (x === y) {\n\t return true;\n\t }\n\n\t var xtype = $.type(x), ytype = $.type(y), field;\n\n\t if (xtype !== ytype) {\n\t return false;\n\t }\n\n\t if (xtype === \"date\") {\n\t return x.getTime() === y.getTime();\n\t }\n\n\t if (xtype !== \"object\" && xtype !== \"array\") {\n\t return false;\n\t }\n\n\t for (field in x) {\n\t if (!equal(x[field], y[field])) {\n\t return false;\n\t }\n\t }\n\n\t return true;\n\t }\n\n\t var parsers = {\n\t \"number\": function(value) {\n\t if (typeof value === STRING && value.toLowerCase() === \"null\") {\n\t return null;\n\t }\n\t return kendo.parseFloat(value);\n\t },\n\n\t \"date\": function(value) {\n\t if (typeof value === STRING && value.toLowerCase() === \"null\") {\n\t return null;\n\t }\n\t return kendo.parseDate(value);\n\t },\n\n\t \"boolean\": function(value) {\n\t if (typeof value === STRING) {\n\t if (value.toLowerCase() === \"null\") {\n\t return null;\n\t } else {\n\t return value.toLowerCase() === \"true\";\n\t }\n\t }\n\t return value != null ? !!value : value;\n\t },\n\n\t \"string\": function(value) {\n\t if (typeof value === STRING && value.toLowerCase() === \"null\") {\n\t return null;\n\t }\n\t return value != null ? (value + \"\") : value;\n\t },\n\n\t \"default\": function(value) {\n\t return value;\n\t }\n\t };\n\n\t var defaultValues = {\n\t \"string\": \"\",\n\t \"number\": 0,\n\t \"date\": new Date(),\n\t \"boolean\": false,\n\t \"default\": \"\"\n\t };\n\n\t function getFieldByName(obj, name) {\n\t var field,\n\t fieldName;\n\n\t for (fieldName in obj) {\n\t field = obj[fieldName];\n\t if (isPlainObject(field) && field.field && field.field === name) {\n\t return field;\n\t } else if (field === name) {\n\t return field;\n\t }\n\t }\n\t return null;\n\t }\n\n\t var Model = ObservableObject.extend({\n\t init: function(data) {\n\t var that = this;\n\n\t if (!data || $.isEmptyObject(data)) {\n\t data = $.extend({}, that.defaults, data);\n\n\t if (that._initializers) {\n\t for (var idx = 0; idx < that._initializers.length; idx++) {\n\t var name = that._initializers[idx];\n\t data[name] = that.defaults[name]();\n\t }\n\t }\n\t }\n\n\t ObservableObject.fn.init.call(that, data);\n\n\t that.dirty = false;\n\t that.dirtyFields = {};\n\n\t if (that.idField) {\n\t that.id = that.get(that.idField);\n\n\t if (that.id === undefined) {\n\t that.id = that._defaultId;\n\t }\n\t }\n\t },\n\n\t shouldSerialize: function(field) {\n\t return ObservableObject.fn.shouldSerialize.call(this, field) &&\n\t field !== \"uid\" && !(this.idField !== \"id\" && field === \"id\") &&\n\t field !== \"dirty\" && field !== \"dirtyFields\" && field !== \"_accessors\";\n\t },\n\n\t _parse: function(field, value) {\n\t var that = this,\n\t fieldName = field,\n\t fields = (that.fields || {}),\n\t parse;\n\n\t field = fields[field];\n\t if (!field) {\n\t field = getFieldByName(fields, fieldName);\n\t }\n\t if (field) {\n\t parse = field.parse;\n\t if (!parse && field.type) {\n\t parse = parsers[field.type.toLowerCase()];\n\t }\n\t }\n\n\t return parse ? parse(value) : value;\n\t },\n\n\t _notifyChange: function(e) {\n\t var action = e.action;\n\n\t if (action == \"add\" || action == \"remove\") {\n\t this.dirty = true;\n\t this.dirtyFields[e.field] = true;\n\t }\n\t },\n\n\t editable: function(field) {\n\t field = (this.fields || {})[field];\n\t return field ? field.editable !== false : true;\n\t },\n\n\t set: function(field, value) {\n\t var that = this;\n\t var dirty = that.dirty;\n\n\t if (that.editable(field)) {\n\t value = that._parse(field, value);\n\n\t if (!equal(value, that.get(field))) {\n\t that.dirty = true;\n\t that.dirtyFields[field] = true;\n\n\t if (ObservableObject.fn.set.call(that, field, value) && !dirty) {\n\t that.dirty = dirty;\n\n\t if (!that.dirty) {\n\t that.dirtyFields[field] = false;\n\t }\n\t }\n\t } else {\n\t that.trigger(\"equalSet\", { field: field, value: value });\n\t }\n\t }\n\t },\n\n\t accept: function(data) {\n\t var that = this,\n\t parent = function() { return that; },\n\t field;\n\n\t for (field in data) {\n\t var value = data[field];\n\n\t if (field.charAt(0) != \"_\") {\n\t value = that.wrap(data[field], field, parent);\n\t }\n\n\t that._set(field, value);\n\t }\n\n\t if (that.idField) {\n\t that.id = that.get(that.idField);\n\t }\n\n\t that.dirty = false;\n\t that.dirtyFields = {};\n\t },\n\n\t isNew: function() {\n\t return this.id === this._defaultId;\n\t }\n\t });\n\n\t Model.define = function(base, options) {\n\t if (options === undefined) {\n\t options = base;\n\t base = Model;\n\t }\n\n\t var model,\n\t proto = extend({ defaults: {} }, options),\n\t name,\n\t field,\n\t type,\n\t value,\n\t idx,\n\t length,\n\t fields = {},\n\t originalName,\n\t id = proto.id,\n\t functionFields = [];\n\n\t if (id) {\n\t proto.idField = id;\n\t }\n\n\t if (proto.id) {\n\t delete proto.id;\n\t }\n\n\t if (id) {\n\t proto.defaults[id] = proto._defaultId = \"\";\n\t }\n\n\t if (toString.call(proto.fields) === \"[object Array]\") {\n\t for (idx = 0, length = proto.fields.length; idx < length; idx++) {\n\t field = proto.fields[idx];\n\t if (typeof field === STRING) {\n\t fields[field] = {};\n\t } else if (field.field) {\n\t fields[field.field] = field;\n\t }\n\t }\n\t proto.fields = fields;\n\t }\n\n\t for (name in proto.fields) {\n\t field = proto.fields[name];\n\t type = field.type || \"default\";\n\t value = null;\n\t originalName = name;\n\n\t name = typeof (field.field) === STRING ? field.field : name;\n\n\t if (!field.nullable) {\n\t value = proto.defaults[originalName !== name ? originalName : name] = field.defaultValue !== undefined ? field.defaultValue : defaultValues[type.toLowerCase()];\n\n\t if (typeof value === \"function\") {\n\t functionFields.push(name);\n\t }\n\t }\n\n\t if (options.id === name) {\n\t proto._defaultId = value;\n\t }\n\n\t proto.defaults[originalName !== name ? originalName : name] = value;\n\n\t field.parse = field.parse || parsers[type];\n\t }\n\n\t if (functionFields.length > 0) {\n\t proto._initializers = functionFields;\n\t }\n\n\t model = base.extend(proto);\n\t model.define = function(options) {\n\t return Model.define(model, options);\n\t };\n\n\t if (proto.fields) {\n\t model.fields = proto.fields;\n\t model.idField = proto.idField;\n\t }\n\n\t return model;\n\t };\n\n\t var Comparer = {\n\t selector: function(field) {\n\t return isFunction(field) ? field : getter(field);\n\t },\n\n\t compare: function(field) {\n\t var selector = this.selector(field);\n\t return function (a, b) {\n\t a = selector(a);\n\t b = selector(b);\n\n\t if (a == null && b == null) {\n\t return 0;\n\t }\n\n\t if (a == null) {\n\t return -1;\n\t }\n\n\t if (b == null) {\n\t return 1;\n\t }\n\n\t if (a.localeCompare) {\n\t return a.localeCompare(b);\n\t }\n\n\t return a > b ? 1 : (a < b ? -1 : 0);\n\t };\n\t },\n\n\t create: function(sort) {\n\t var compare = sort.compare || this.compare(sort.field);\n\n\t if (sort.dir == \"desc\") {\n\t return function(a, b) {\n\t return compare(b, a, true);\n\t };\n\t }\n\n\t return compare;\n\t },\n\n\t combine: function(comparers) {\n\t return function(a, b) {\n\t var result = comparers[0](a, b),\n\t idx,\n\t length;\n\n\t for (idx = 1, length = comparers.length; idx < length; idx ++) {\n\t result = result || comparers[idx](a, b);\n\t }\n\n\t return result;\n\t };\n\t }\n\t };\n\n\t var StableComparer = extend({}, Comparer, {\n\t asc: function(field) {\n\t var selector = this.selector(field);\n\t return function (a, b) {\n\t var valueA = selector(a);\n\t var valueB = selector(b);\n\n\t if (valueA && valueA.getTime && valueB && valueB.getTime) {\n\t valueA = valueA.getTime();\n\t valueB = valueB.getTime();\n\t }\n\n\t if (valueA === valueB) {\n\t return a.__position - b.__position;\n\t }\n\n\t if (valueA == null) {\n\t return -1;\n\t }\n\n\t if (valueB == null) {\n\t return 1;\n\t }\n\n\t if (valueA.localeCompare) {\n\t return valueA.localeCompare(valueB);\n\t }\n\n\t return valueA > valueB ? 1 : -1;\n\t };\n\t },\n\n\t desc: function(field) {\n\t var selector = this.selector(field);\n\t return function (a, b) {\n\t var valueA = selector(a);\n\t var valueB = selector(b);\n\n\t if (valueA && valueA.getTime && valueB && valueB.getTime) {\n\t valueA = valueA.getTime();\n\t valueB = valueB.getTime();\n\t }\n\n\t if (valueA === valueB) {\n\t return a.__position - b.__position;\n\t }\n\n\t if (valueA == null) {\n\t return 1;\n\t }\n\n\t if (valueB == null) {\n\t return -1;\n\t }\n\n\t if (valueB.localeCompare) {\n\t return valueB.localeCompare(valueA);\n\t }\n\n\t return valueA < valueB ? 1 : -1;\n\t };\n\t },\n\t create: function(sort) {\n\t return this[sort.dir](sort.field);\n\t }\n\t });\n\n\t map = function (array, callback) {\n\t var idx, length = array.length, result = new Array(length);\n\n\t for (idx = 0; idx < length; idx++) {\n\t result[idx] = callback(array[idx], idx, array);\n\t }\n\n\t return result;\n\t };\n\n\t var operators = (function(){\n\n\t function quote(str) {\n\t if (typeof str == \"string\") {\n\t str = str.replace(/[\\r\\n]+/g, \"\");\n\t }\n\t return JSON.stringify(str);\n\t }\n\n\t function textOp(impl) {\n\t return function(a, b, ignore, accentFoldingFiltering) {\n\t b += \"\";\n\t if (ignore) {\n\t a = \"(\" + a + \" + '').toString()\" + ((accentFoldingFiltering) ? \".toLocaleLowerCase('\" + accentFoldingFiltering +\"')\" : \".toLowerCase()\");\n\t b = ((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase());\n\t }\n\t return impl(a, quote(b), ignore);\n\t };\n\t }\n\n\t function operator(op, a, b, ignore, accentFoldingFiltering) {\n\t if (b != null) {\n\t if (typeof b === STRING) {\n\t var date = dateRegExp.exec(b);\n\t if (date) {\n\t b = new Date(+date[1]);\n\t } else if (ignore) {\n\t b = quote(((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase()));\n\t a = \"((\" + a + \" || '')+'')\" + ((accentFoldingFiltering) ? \".toLocaleLowerCase('\" + accentFoldingFiltering +\"')\" : \".toLowerCase()\");\n\t } else {\n\t b = quote(b);\n\t }\n\t }\n\n\t if (b.getTime) {\n\t //b looks like a Date\n\t a = \"(\" + a + \"&&\" + a + \".getTime?\" + a + \".getTime():\" + a + \")\";\n\t b = b.getTime();\n\t }\n\t }\n\n\t return a + \" \" + op + \" \" + b;\n\t }\n\n\t function getMatchRegexp(pattern) {\n\t // take a pattern, as supported by Excel match filter, and\n\t // convert it to the equivalent JS regular expression.\n\t // Excel patterns support:\n\t //\n\t // * - match any sequence of characters\n\t // ? - match a single character\n\t //\n\t // to match a literal * or ?, they must be prefixed by a tilde (~)\n\t for (var rx = \"/^\", esc = false, i = 0; i < pattern.length; ++i) {\n\t var ch = pattern.charAt(i);\n\t if (esc) {\n\t rx += \"\\\\\" + ch;\n\t } else if (ch == \"~\") {\n\t esc = true;\n\t continue;\n\t } else if (ch == \"*\") {\n\t rx += \".*\";\n\t } else if (ch == \"?\") {\n\t rx += \".\";\n\t } else if (\".+^$()[]{}|\\\\/\\n\\r\\u2028\\u2029\\xA0\".indexOf(ch) >= 0) {\n\t rx += \"\\\\\" + ch;\n\t } else {\n\t rx += ch;\n\t }\n\t esc = false;\n\t }\n\t return rx + \"$/\";\n\t }\n\n\t return {\n\t quote: function(value) {\n\t if (value && value.getTime) {\n\t return \"new Date(\" + value.getTime() + \")\";\n\t }\n\t return quote(value);\n\t },\n\t eq: function(a, b, ignore, accentFoldingFiltering) {\n\t return operator(\"==\", a, b, ignore, accentFoldingFiltering);\n\t },\n\t neq: function(a, b, ignore, accentFoldingFiltering) {\n\t return operator(\"!=\", a, b, ignore, accentFoldingFiltering);\n\t },\n\t gt: function(a, b, ignore) {\n\t return operator(\">\", a, b, ignore);\n\t },\n\t gte: function(a, b, ignore) {\n\t return operator(\">=\", a, b, ignore);\n\t },\n\t lt: function(a, b, ignore) {\n\t return operator(\"<\", a, b, ignore);\n\t },\n\t lte: function(a, b, ignore) {\n\t return operator(\"<=\", a, b, ignore);\n\t },\n\t startswith: textOp(function(a, b) {\n\t return a + \".lastIndexOf(\" + b + \", 0) == 0\";\n\t }),\n\t doesnotstartwith: textOp(function(a, b) {\n\t return a + \".lastIndexOf(\" + b + \", 0) == -1\";\n\t }),\n\t endswith: textOp(function(a, b) {\n\t var n = b ? b.length - 2 : 0;\n\t return a + \".indexOf(\" + b + \", \" + a + \".length - \" + n + \") >= 0\";\n\t }),\n\t doesnotendwith: textOp(function(a, b) {\n\t var n = b ? b.length - 2 : 0;\n\t return a + \".indexOf(\" + b + \", \" + a + \".length - \" + n + \") < 0\";\n\t }),\n\t contains: textOp(function(a, b) {\n\t return a + \".indexOf(\" + b + \") >= 0\";\n\t }),\n\t doesnotcontain: textOp(function(a, b) {\n\t return a + \".indexOf(\" + b + \") == -1\";\n\t }),\n\t matches: textOp(function(a, b){\n\t b = b.substring(1, b.length - 1);\n\t return getMatchRegexp(b) + \".test(\" + a + \")\";\n\t }),\n\t doesnotmatch: textOp(function(a, b){\n\t b = b.substring(1, b.length - 1);\n\t return \"!\" + getMatchRegexp(b) + \".test(\" + a + \")\";\n\t }),\n\t isempty: function(a) {\n\t return a + \" === ''\";\n\t },\n\t isnotempty: function(a) {\n\t return a + \" !== ''\";\n\t },\n\t isnull: function(a) {\n\t return \"(\" + a + \" == null)\";\n\t },\n\t isnotnull: function(a) {\n\t return \"(\" + a + \" != null)\";\n\t },\n\t isnullorempty: function(a) {\n\t return \"(\" + a + \" === null) || (\" + a + \" === '')\";\n\t },\n\t isnotnullorempty: function(a) {\n\t return \"(\" + a + \" !== null) && (\" + a + \" !== '')\";\n\t }\n\t };\n\t })();\n\n\t function Query(data) {\n\t this.data = data || [];\n\t }\n\n\t Query.filterExpr = function(expression) {\n\t var expressions = [],\n\t logic = { and: \" && \", or: \" || \" },\n\t idx,\n\t length,\n\t filter,\n\t expr,\n\t fieldFunctions = [],\n\t operatorFunctions = [],\n\t field,\n\t operator,\n\t filters = expression.filters;\n\n\t for (idx = 0, length = filters.length; idx < length; idx++) {\n\t filter = filters[idx];\n\t field = filter.field;\n\t operator = filter.operator;\n\n\t if (filter.filters) {\n\t expr = Query.filterExpr(filter);\n\t //Nested function fields or operators - update their index e.g. __o[0] -> __o[1]\n\t filter = expr.expression\n\t .replace(/__o\\[(\\d+)\\]/g, function(match, index) {\n\t index = +index;\n\t return \"__o[\" + (operatorFunctions.length + index) + \"]\";\n\t })\n\t .replace(/__f\\[(\\d+)\\]/g, function(match, index) {\n\t index = +index;\n\t return \"__f[\" + (fieldFunctions.length + index) + \"]\";\n\t });\n\n\t operatorFunctions.push.apply(operatorFunctions, expr.operators);\n\t fieldFunctions.push.apply(fieldFunctions, expr.fields);\n\t } else {\n\t if (typeof field === FUNCTION) {\n\t expr = \"__f[\" + fieldFunctions.length +\"](d)\";\n\t fieldFunctions.push(field);\n\t } else {\n\t expr = kendo.expr(field);\n\t }\n\n\t if (typeof operator === FUNCTION) {\n\t filter = \"__o[\" + operatorFunctions.length + \"](\" + expr + \", \" + operators.quote(filter.value) + \")\";\n\t operatorFunctions.push(operator);\n\t } else {\n\t filter = operators[(operator || \"eq\").toLowerCase()](expr, filter.value, filter.ignoreCase !== undefined? filter.ignoreCase : true, expression.accentFoldingFiltering);\n\t }\n\t }\n\n\t expressions.push(filter);\n\t }\n\n\t return { expression: \"(\" + expressions.join(logic[expression.logic]) + \")\", fields: fieldFunctions, operators: operatorFunctions };\n\t };\n\n\t function normalizeSort(field, dir) {\n\t if (field) {\n\t var descriptor = typeof field === STRING ? { field: field, dir: dir } : field,\n\t descriptors = isArray(descriptor) ? descriptor : (descriptor !== undefined ? [descriptor] : []);\n\n\t return grep(descriptors, function(d) { return !!d.dir; });\n\t }\n\t }\n\n\t function sortFields(sorts, dir) {\n\t var sortObject = {};\n\n\t if (sorts) {\n\t var descriptor = typeof sorts === STRING ? { field: sorts, dir: dir } : sorts,\n\t descriptors = isArray(descriptor) ? descriptor : (descriptor !== undefined ? [descriptor] : []);\n\n\t for (var i = 0; i < descriptors.length; i++) {\n\t sortObject[descriptors[i].field] = { dir: descriptors[i].dir, index: i + 1 };\n\t }\n\t }\n\n\t return sortObject;\n\t }\n\n\t var operatorMap = {\n\t \"==\": \"eq\",\n\t equals: \"eq\",\n\t isequalto: \"eq\",\n\t equalto: \"eq\",\n\t equal: \"eq\",\n\t \"!=\": \"neq\",\n\t ne: \"neq\",\n\t notequals: \"neq\",\n\t isnotequalto: \"neq\",\n\t notequalto: \"neq\",\n\t notequal: \"neq\",\n\t \"<\": \"lt\",\n\t islessthan: \"lt\",\n\t lessthan: \"lt\",\n\t less: \"lt\",\n\t \"<=\": \"lte\",\n\t le: \"lte\",\n\t islessthanorequalto: \"lte\",\n\t lessthanequal: \"lte\",\n\t \">\": \"gt\",\n\t isgreaterthan: \"gt\",\n\t greaterthan: \"gt\",\n\t greater: \"gt\",\n\t \">=\": \"gte\",\n\t isgreaterthanorequalto: \"gte\",\n\t greaterthanequal: \"gte\",\n\t ge: \"gte\",\n\t notsubstringof: \"doesnotcontain\",\n\t isnull: \"isnull\",\n\t isempty: \"isempty\",\n\t isnotempty: \"isnotempty\"\n\t };\n\n\t function normalizeOperator(expression) {\n\t var idx,\n\t length,\n\t filter,\n\t operator,\n\t filters = expression.filters;\n\n\t if (filters) {\n\t for (idx = 0, length = filters.length; idx < length; idx++) {\n\t filter = filters[idx];\n\t operator = filter.operator;\n\n\t if (operator && typeof operator === STRING) {\n\t filter.operator = operatorMap[operator.toLowerCase()] || operator;\n\t }\n\n\t normalizeOperator(filter);\n\t }\n\t }\n\t }\n\n\t function normalizeFilter(expression) {\n\t if (expression && !isEmptyObject(expression)) {\n\t if (isArray(expression) || !expression.filters) {\n\t expression = {\n\t logic: \"and\",\n\t filters: isArray(expression) ? expression : [expression]\n\t };\n\t }\n\n\t normalizeOperator(expression);\n\n\t return expression;\n\t }\n\t }\n\n\t Query.normalizeFilter = normalizeFilter;\n\n\t function compareDescriptor(f1, f2) {\n\t if (f1.logic || f2.logic) {\n\t return false;\n\t }\n\n\t return f1.field === f2.field && f1.value === f2.value && f1.operator === f2.operator;\n\t }\n\n\t function normalizeDescriptor(filter) {\n\t filter = filter || {};\n\n\t if (isEmptyObject(filter)) {\n\t return { logic: \"and\", filters: [] };\n\t }\n\n\t return normalizeFilter(filter);\n\t }\n\n\t function fieldComparer(a, b) {\n\t if (b.logic || (a.field > b.field)) {\n\t return 1;\n\t } else if (a.field < b.field) {\n\t return -1;\n\t } else {\n\t return 0;\n\t }\n\t }\n\n\t function compareFilters(expr1, expr2) {\n\t expr1 = normalizeDescriptor(expr1);\n\t expr2 = normalizeDescriptor(expr2);\n\n\t if (expr1.logic !== expr2.logic) {\n\t return false;\n\t }\n\n\t var f1, f2;\n\t var filters1 = (expr1.filters || []).slice();\n\t var filters2 = (expr2.filters || []).slice();\n\n\t if (filters1.length !== filters2.length) {\n\t return false;\n\t }\n\n\t filters1 = filters1.sort(fieldComparer);\n\t filters2 = filters2.sort(fieldComparer);\n\n\t for (var idx = 0; idx < filters1.length; idx++) {\n\t f1 = filters1[idx];\n\t f2 = filters2[idx];\n\n\t if (f1.logic && f2.logic) {\n\t if (!compareFilters(f1, f2)) {\n\t return false;\n\t }\n\t } else if (!compareDescriptor(f1, f2)) {\n\t return false;\n\t }\n\t }\n\n\t return true;\n\t }\n\n\t Query.compareFilters = compareFilters;\n\n\t function normalizeAggregate(expressions) {\n\t return isArray(expressions) ? expressions : [expressions];\n\t }\n\n\t function normalizeGroup(field, dir, compare, skipItemSorting) {\n\t var descriptor = typeof field === STRING ? { field: field, dir: dir, compare: compare, skipItemSorting : skipItemSorting } : field,\n\t descriptors = isArray(descriptor) ? descriptor : (descriptor !== undefined ? [descriptor] : []);\n\n\t return map(descriptors, function(d) {\n\t return {\n\t field: d.field,\n\t dir: d.dir || \"asc\",\n\t aggregates: d.aggregates,\n\t compare: d.compare,\n\t skipItemSorting: d.skipItemSorting\n\t };\n\t });\n\t }\n\n\t function normalizeGroupWithoutCompare(field, dir, compare) {\n\t var descriptors = normalizeGroup(field, dir, compare);\n\n\t for (var i = 0; i < descriptors.length; i++) {\n\t delete descriptors[i].compare;\n\t }\n\n\t return descriptors;\n\t }\n\n\t function anyGroupDescriptorHasCompare(groupDescriptors) {\n\t var descriptors = isArray(groupDescriptors) ? groupDescriptors : [groupDescriptors];\n\n\t for (var i = 0; i < descriptors.length; i++) {\n\t if (descriptors[i] && isFunction(descriptors[i].compare)) {\n\t return true;\n\t }\n\t }\n\n\t return false;\n\t }\n\n\t Query.prototype = {\n\t toArray: function () {\n\t return this.data;\n\t },\n\t range: function(index, count) {\n\t return new Query(this.data.slice(index, index + count));\n\t },\n\t skip: function (count) {\n\t return new Query(this.data.slice(count));\n\t },\n\t take: function (count) {\n\t return new Query(this.data.slice(0, count));\n\t },\n\t select: function (selector) {\n\t return new Query(map(this.data, selector));\n\t },\n\t order: function(selector, dir, inPlace) {\n\t var sort = { dir: dir };\n\n\t if (selector) {\n\t if (selector.compare) {\n\t sort.compare = selector.compare;\n\t } else {\n\t sort.field = selector;\n\t }\n\t }\n\n\t if (inPlace) {\n\t return new Query(this.data.sort(Comparer.create(sort)));\n\t }\n\n\t return new Query(this.data.slice(0).sort(Comparer.create(sort)));\n\t },\n\t orderBy: function(selector, inPlace) {\n\t return this.order(selector, \"asc\", inPlace);\n\t },\n\t orderByDescending: function(selector, inPlace) {\n\t return this.order(selector, \"desc\", inPlace);\n\t },\n\t sort: function(field, dir, comparer, inPlace) {\n\t var idx,\n\t length,\n\t descriptors = normalizeSort(field, dir),\n\t comparers = [];\n\n\t comparer = comparer || Comparer;\n\n\t if (descriptors.length) {\n\t for (idx = 0, length = descriptors.length; idx < length; idx++) {\n\t comparers.push(comparer.create(descriptors[idx]));\n\t }\n\n\t return this.orderBy({ compare: comparer.combine(comparers) }, inPlace);\n\t }\n\n\t return this;\n\t },\n\n\t filter: function(expressions) {\n\t var idx,\n\t current,\n\t length,\n\t compiled,\n\t predicate,\n\t data = this.data,\n\t fields,\n\t operators,\n\t result = [],\n\t filter;\n\n\t expressions = normalizeFilter(expressions);\n\n\t if (!expressions || expressions.filters.length === 0) {\n\t return this;\n\t }\n\n\t compiled = Query.filterExpr(expressions);\n\t fields = compiled.fields;\n\t operators = compiled.operators;\n\n\t predicate = filter = new Function(\"d, __f, __o\", \"return \" + compiled.expression);\n\n\t if (fields.length || operators.length) {\n\t filter = function(d) {\n\t return predicate(d, fields, operators);\n\t };\n\t }\n\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t current = data[idx];\n\n\t if (filter(current)) {\n\t result.push(current);\n\t }\n\t }\n\n\t return new Query(result);\n\t },\n\n\t group: function(descriptors, allData, options) {\n\t descriptors = normalizeGroup(descriptors || []);\n\t allData = allData || this.data;\n\n\t var that = this,\n\t result = new Query(that.data),\n\t descriptor;\n\n\t if (descriptors.length > 0) {\n\t descriptor = descriptors[0];\n\n\t if (options && options.groupPaging) {\n\t result = new Query(allData).groupAllData(descriptor, allData).select(function (group) {\n\t var data = new Query(allData).filter([{\n\t field: group.field,\n\t operator: \"eq\",\n\t value: group.value,\n\t ignoreCase: false\n\t }]);\n\t var items = descriptors.length > 1 ? new Query(group.items).group(descriptors.slice(1), data.toArray(), options).toArray() : group.items;\n\t return {\n\t field: group.field,\n\t value: group.value,\n\t hasSubgroups: descriptors.length > 1,\n\t items: items,\n\t aggregates: data.aggregate(descriptor.aggregates),\n\t uid: kendo.guid(),\n\t itemCount: items.length,\n\t subgroupCount: items.length\n\t };\n\t });\n\n\t } else {\n\t result = result.groupBy(descriptor).select(function(group) {\n\t var data = new Query(allData).filter([ { field: group.field, operator: \"eq\", value: group.value, ignoreCase: false } ]);\n\t return {\n\t field: group.field,\n\t value: group.value,\n\t items: descriptors.length > 1 ? new Query(group.items).group(descriptors.slice(1), data.toArray()).toArray() : group.items,\n\t hasSubgroups: descriptors.length > 1,\n\t aggregates: data.aggregate(descriptor.aggregates)\n\t };\n\t });\n\t }\n\t }\n\t return result;\n\t },\n\n\t groupBy: function(descriptor) {\n\t var that = this;\n\n\t if (isEmptyObject(descriptor) || !this.data.length) {\n\t return new Query([]);\n\t }\n\n\t var field = descriptor.field,\n\t sorted = descriptor.skipItemSorting ? this.data : this._sortForGrouping(field, descriptor.dir || \"asc\"),\n\t accessor = kendo.accessor(field),\n\t item,\n\t groupValue = accessor.get(sorted[0], field),\n\t group = {\n\t field: field,\n\t value: groupValue,\n\t items: []\n\t },\n\t currentValue,\n\t idx,\n\t len,\n\t result = [group];\n\n\t for(idx = 0, len = sorted.length; idx < len; idx++) {\n\t item = sorted[idx];\n\t currentValue = accessor.get(item, field);\n\t if(!groupValueComparer(groupValue, currentValue)) {\n\t groupValue = currentValue;\n\t group = {\n\t field: field,\n\t value: groupValue,\n\t items: []\n\t };\n\t result.push(group);\n\t }\n\t group.items.push(item);\n\t }\n\n\t result = that._sortGroups(result, descriptor);\n\n\t return new Query(result);\n\t },\n\n\t groupAllData: function (descriptor, allData) {\n\t if (isEmptyObject(descriptor) || this.data && !this.data.length) {\n\t return new Query([]);\n\t }\n\n\t var field = descriptor.field,\n\t sorted = descriptor.skipItemSorting ? allData : new Query(allData).sort(field, descriptor.dir || \"asc\", StableComparer).toArray(),\n\t accessor = kendo.accessor(field),\n\t item,\n\t groupValue = accessor.get(sorted[0], field),\n\t group = {\n\t field: field,\n\t value: groupValue,\n\t items: []\n\t },\n\t currentValue,\n\t idx,\n\t len,\n\t result = [group];\n\n\t for (idx = 0, len = sorted.length; idx < len; idx++) {\n\t item = sorted[idx];\n\t currentValue = accessor.get(item, field);\n\t if (!groupValueComparer(groupValue, currentValue)) {\n\t groupValue = currentValue;\n\t group = {\n\t field: field,\n\t value: groupValue,\n\t items: []\n\t };\n\t result.push(group);\n\t }\n\t group.items.push(item);\n\t }\n\n\t result = this._sortGroups(result, descriptor);\n\n\t return new Query(result);\n\t },\n\n\t _sortForGrouping: function(field, dir) {\n\t var idx, length,\n\t data = this.data;\n\n\t if (!stableSort) {\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t data[idx].__position = idx;\n\t }\n\n\t data = new Query(data).sort(field, dir, StableComparer).toArray();\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t delete data[idx].__position;\n\t }\n\t return data;\n\t }\n\n\t return this.sort(field, dir).toArray();\n\t },\n\n\t _sortGroups: function(groups, descriptor) {\n\t var result = groups;\n\n\t if (descriptor && isFunction(descriptor.compare)) {\n\t result = new Query(result).order({ compare: descriptor.compare }, descriptor.dir || ASCENDING).toArray();\n\t }\n\n\t return result;\n\t },\n\n\t aggregate: function (aggregates) {\n\t var idx,\n\t len,\n\t result = {},\n\t state = {};\n\n\t if (aggregates && aggregates.length) {\n\t for(idx = 0, len = this.data.length; idx < len; idx++) {\n\t calculateAggregate(result, aggregates, this.data[idx], idx, len, state);\n\t }\n\t }\n\t return result;\n\t }\n\t };\n\n\t function groupValueComparer(a, b) {\n\t if (a && a.getTime && b && b.getTime) {\n\t return a.getTime() === b.getTime();\n\t }\n\t return a === b;\n\t }\n\n\t function calculateAggregate(accumulator, aggregates, item, index, length, state) {\n\t aggregates = aggregates || [];\n\t var idx,\n\t aggr,\n\t functionName,\n\t len = aggregates.length;\n\n\t for (idx = 0; idx < len; idx++) {\n\t aggr = aggregates[idx];\n\t functionName = aggr.aggregate;\n\t var field = aggr.field;\n\t accumulator[field] = accumulator[field] || {};\n\t state[field] = state[field] || {};\n\t state[field][functionName] = state[field][functionName] || {};\n\t accumulator[field][functionName] = functions[functionName.toLowerCase()](accumulator[field][functionName], item, kendo.accessor(field), index, length, state[field][functionName]);\n\t }\n\t }\n\n\t var functions = {\n\t sum: function(accumulator, item, accessor) {\n\t var value = accessor.get(item);\n\n\t if (!isNumber(accumulator)) {\n\t accumulator = value;\n\t } else if (isNumber(value)) {\n\t accumulator += value;\n\t }\n\n\t return accumulator;\n\t },\n\t count: function(accumulator) {\n\t return (accumulator || 0) + 1;\n\t },\n\t average: function(accumulator, item, accessor, index, length, state) {\n\t var value = accessor.get(item);\n\n\t if (state.count === undefined) {\n\t state.count = 0;\n\t }\n\n\t if (!isNumber(accumulator)) {\n\t accumulator = value;\n\t } else if (isNumber(value)) {\n\t accumulator += value;\n\t }\n\n\t if (isNumber(value)) {\n\t state.count++;\n\t }\n\n\t if(index == length - 1 && isNumber(accumulator)) {\n\t accumulator = accumulator / state.count;\n\t }\n\t return accumulator;\n\t },\n\t max: function(accumulator, item, accessor) {\n\t var value = accessor.get(item);\n\n\t if (!isNumber(accumulator) && !isDate(accumulator)) {\n\t accumulator = value;\n\t }\n\n\t if(accumulator < value && (isNumber(value) || isDate(value))) {\n\t accumulator = value;\n\t }\n\t return accumulator;\n\t },\n\t min: function(accumulator, item, accessor) {\n\t var value = accessor.get(item);\n\n\t if (!isNumber(accumulator) && !isDate(accumulator)) {\n\t accumulator = value;\n\t }\n\n\t if(accumulator > value && (isNumber(value) || isDate(value))) {\n\t accumulator = value;\n\t }\n\t return accumulator;\n\t }\n\t };\n\n\t function isNumber(val) {\n\t return typeof val === \"number\" && !isNaN(val);\n\t }\n\n\t function isDate(val) {\n\t return val && val.getTime;\n\t }\n\n\t function toJSON(array) {\n\t var idx, length = array.length, result = new Array(length);\n\n\t for (idx = 0; idx < length; idx++) {\n\t result[idx] = array[idx].toJSON();\n\t }\n\n\t return result;\n\t }\n\n\t Query.normalizeGroup = normalizeGroup;\n\t Query.normalizeSort = normalizeSort;\n\n\t Query.process = function(data, options, inPlace) {\n\t options = options || {};\n\n\t var group = options.group;\n\t var customGroupSort = anyGroupDescriptorHasCompare(normalizeGroup(group || []));\n\t var query = new Query(data),\n\t groupDescriptorsWithoutCompare = normalizeGroupWithoutCompare(group || []),\n\t normalizedSort = normalizeSort(options.sort || []),\n\t sort = customGroupSort ? normalizedSort : groupDescriptorsWithoutCompare.concat(normalizedSort),\n\t groupDescriptorsWithoutSort,\n\t total,\n\t filterCallback = options.filterCallback,\n\t filter = options.filter,\n\t skip = options.skip,\n\t take = options.take;\n\n\t if (sort && inPlace) {\n\t query = query.sort(sort, undefined, undefined, inPlace);\n\t }\n\n\t if (filter) {\n\t query = query.filter(filter);\n\n\t if (filterCallback) {\n\t query = filterCallback(query);\n\t }\n\n\t total = query.toArray().length;\n\t }\n\n\t if (sort) {\n\t if (!inPlace) {\n\t query = query.sort(sort);\n\t }\n\n\t if (group) {\n\t data = query.toArray();\n\t }\n\t }\n\n\t if (customGroupSort) {\n\t query = query.group(group, data);\n\n\t if (skip !== undefined && take !== undefined) {\n\t query = new Query(flatGroups(query.toArray())).range(skip, take);\n\n\t groupDescriptorsWithoutSort = map(groupDescriptorsWithoutCompare, function(groupDescriptor) {\n\t return extend({}, groupDescriptor, {\n\t skipItemSorting: true\n\t });\n\t });\n\n\t query = query.group(groupDescriptorsWithoutSort, data);\n\t }\n\t } else {\n\t if (skip !== undefined && take !== undefined) {\n\t query = query.range(skip, take);\n\t }\n\n\t if (group) {\n\t query = query.group(group, data, options);\n\t }\n\t }\n\n\t return {\n\t total: total,\n\t data: query.toArray()\n\t };\n\t };\n\n\t var LocalTransport = Class.extend({\n\t init: function(options) {\n\t this.data = options.data;\n\t },\n\n\t read: function(options) {\n\t options.success(this.data);\n\t },\n\t update: function(options) {\n\t options.success(options.data);\n\t },\n\t create: function(options) {\n\t options.success(options.data);\n\t },\n\t destroy: function(options) {\n\t options.success(options.data);\n\t }\n\t });\n\n\t var RemoteTransport = Class.extend( {\n\t init: function(options) {\n\t var that = this, parameterMap;\n\n\t options = that.options = extend({}, that.options, options);\n\n\t each(crud, function(index, type) {\n\t if (typeof options[type] === STRING) {\n\t options[type] = {\n\t url: options[type]\n\t };\n\t }\n\t });\n\n\t that.cache = options.cache? Cache.create(options.cache) : {\n\t find: noop,\n\t add: noop\n\t };\n\n\t parameterMap = options.parameterMap;\n\n\t if (options.submit) {\n\t that.submit = options.submit;\n\t }\n\n\t if (isFunction(options.push)) {\n\t that.push = options.push;\n\t }\n\n\t if (!that.push) {\n\t that.push = identity;\n\t }\n\n\t that.parameterMap = isFunction(parameterMap) ? parameterMap : function(options) {\n\t var result = {};\n\n\t each(options, function(option, value) {\n\t if (option in parameterMap) {\n\t option = parameterMap[option];\n\t if (isPlainObject(option)) {\n\t value = option.value(value);\n\t option = option.key;\n\t }\n\t }\n\n\t result[option] = value;\n\t });\n\n\t return result;\n\t };\n\t },\n\n\t options: {\n\t parameterMap: identity\n\t },\n\n\t create: function(options) {\n\t return ajax(this.setup(options, CREATE));\n\t },\n\n\t read: function(options) {\n\t var that = this,\n\t success,\n\t error,\n\t result,\n\t cache = that.cache;\n\n\t options = that.setup(options, READ);\n\n\t success = options.success || noop;\n\t error = options.error || noop;\n\n\t result = cache.find(options.data);\n\n\t if(result !== undefined) {\n\t success(result);\n\t } else {\n\t options.success = function(result) {\n\t cache.add(options.data, result);\n\n\t success(result);\n\t };\n\n\t $.ajax(options);\n\t }\n\t },\n\n\t update: function(options) {\n\t return ajax(this.setup(options, UPDATE));\n\t },\n\n\t destroy: function(options) {\n\t return ajax(this.setup(options, DESTROY));\n\t },\n\n\t setup: function(options, type) {\n\t options = options || {};\n\n\t var that = this,\n\t parameters,\n\t operation = that.options[type],\n\t data = isFunction(operation.data) ? operation.data(options.data) : operation.data;\n\n\t options = extend(true, {}, operation, options);\n\t parameters = extend(true, {}, data, options.data);\n\n\t options.data = that.parameterMap(parameters, type);\n\n\t if (isFunction(options.url)) {\n\t options.url = options.url(parameters);\n\t }\n\n\t return options;\n\t }\n\t });\n\n\t var Cache = Class.extend({\n\t init: function() {\n\t this._store = {};\n\t },\n\t add: function(key, data) {\n\t if(key !== undefined) {\n\t this._store[stringify(key)] = data;\n\t }\n\t },\n\t find: function(key) {\n\t return this._store[stringify(key)];\n\t },\n\t clear: function() {\n\t this._store = {};\n\t },\n\t remove: function(key) {\n\t delete this._store[stringify(key)];\n\t }\n\t });\n\n\t Cache.create = function(options) {\n\t var store = {\n\t \"inmemory\": function() { return new Cache(); }\n\t };\n\n\t if (isPlainObject(options) && isFunction(options.find)) {\n\t return options;\n\t }\n\n\t if (options === true) {\n\t return new Cache();\n\t }\n\n\t return store[options]();\n\t };\n\n\t function serializeRecords(data, getters, modelInstance, originalFieldNames, fieldNames) {\n\t var record,\n\t getter,\n\t originalName,\n\t idx,\n\t setters = {},\n\t length;\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t record = data[idx];\n\t for (getter in getters) {\n\t originalName = fieldNames[getter];\n\n\t if (originalName && originalName !== getter) {\n\t if (!setters[originalName]) {\n\t setters[originalName] = kendo.setter(originalName);\n\t }\n\t setters[originalName](record, getters[getter](record));\n\t delete record[getter];\n\t }\n\t }\n\t }\n\t }\n\n\t function convertRecords(data, getters, modelInstance, originalFieldNames, fieldNames) {\n\t var record,\n\t getter,\n\t originalName,\n\t idx,\n\t length;\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t record = data[idx];\n\t for (getter in getters) {\n\t record[getter] = modelInstance._parse(getter, getters[getter](record));\n\n\t originalName = fieldNames[getter];\n\t if (originalName && originalName !== getter) {\n\t delete record[originalName];\n\t }\n\t }\n\t }\n\t }\n\n\t function convertGroup(data, getters, modelInstance, originalFieldNames, fieldNames) {\n\t var record,\n\t idx,\n\t fieldName,\n\t length;\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t record = data[idx];\n\n\t fieldName = originalFieldNames[record.field];\n\t if (fieldName && fieldName != record.field) {\n\t record.field = fieldName;\n\t }\n\n\t record.value = modelInstance._parse(record.field, record.value);\n\n\t if (record.items) {\n\t if (record.hasSubgroups) {\n\t convertGroup(record.items, getters, modelInstance, originalFieldNames, fieldNames);\n\t } else {\n\t convertRecords(record.items, getters, modelInstance, originalFieldNames, fieldNames);\n\t }\n\t }\n\t }\n\t }\n\n\t function wrapDataAccess(originalFunction, model, converter, getters, originalFieldNames, fieldNames) {\n\t return function(data) {\n\t data = originalFunction(data);\n\n\t return wrapDataAccessBase(model, converter, getters, originalFieldNames, fieldNames)(data);\n\t };\n\t }\n\n\t function wrapDataAccessBase(model, converter, getters, originalFieldNames, fieldNames) {\n\t return function(data) {\n\n\t if (data && !isEmptyObject(getters)) {\n\t if (toString.call(data) !== \"[object Array]\" && !(data instanceof ObservableArray)) {\n\t data = [data];\n\t }\n\n\t converter(data, getters, new model(), originalFieldNames, fieldNames);\n\t }\n\n\t return data || [];\n\t };\n\t }\n\n\t var DataReader = Class.extend({\n\t init: function(schema) {\n\t var that = this, member, get, model, base;\n\n\t schema = schema || {};\n\n\t for (member in schema) {\n\t get = schema[member];\n\n\t that[member] = typeof get === STRING ? getter(get) : get;\n\t }\n\n\t base = schema.modelBase || Model;\n\n\t if (isPlainObject(that.model)) {\n\t that.model = model = base.define(that.model);\n\t }\n\n\t var dataFunction = proxy(that.data, that);\n\n\t that._dataAccessFunction = dataFunction;\n\n\t if (that.model) {\n\t var groupsFunction = proxy(that.groups, that),\n\t serializeFunction = proxy(that.serialize, that),\n\t originalFieldNames = {},\n\t getters = {},\n\t serializeGetters = {},\n\t fieldNames = {},\n\t shouldSerialize = false,\n\t fieldName,\n\t name;\n\n\t model = that.model;\n\n\t if (model.fields) {\n\t each(model.fields, function(field, value) {\n\t var fromName;\n\n\t fieldName = field;\n\n\t if (isPlainObject(value) && value.field) {\n\t fieldName = value.field;\n\t } else if (typeof value === STRING) {\n\t fieldName = value;\n\t }\n\n\t if (isPlainObject(value) && value.from) {\n\t fromName = value.from;\n\t }\n\n\t shouldSerialize = shouldSerialize || (fromName && fromName !== field) || fieldName !== field;\n\t name = fromName || fieldName;\n\t getters[field] = name.indexOf(\".\") !== -1 ? getter(name, true) : getter(name);\n\t serializeGetters[field] = getter(field);\n\t originalFieldNames[fromName || fieldName] = field;\n\t fieldNames[field] = fromName || fieldName;\n\t });\n\n\t if (!schema.serialize && shouldSerialize) {\n\t that.serialize = wrapDataAccess(serializeFunction, model, serializeRecords, serializeGetters, originalFieldNames, fieldNames);\n\t }\n\t }\n\n\t that._dataAccessFunction = dataFunction;\n\t that._wrapDataAccessBase = wrapDataAccessBase(model, convertRecords, getters, originalFieldNames, fieldNames);\n\t that.data = wrapDataAccess(dataFunction, model, convertRecords, getters, originalFieldNames, fieldNames);\n\t that.groups = wrapDataAccess(groupsFunction, model, convertGroup, getters, originalFieldNames, fieldNames);\n\t }\n\t },\n\t errors: function(data) {\n\t return data ? data.errors : null;\n\t },\n\t parse: identity,\n\t data: identity,\n\t total: function(data) {\n\t return data.length;\n\t },\n\t groups: identity,\n\t aggregates: function() {\n\t return {};\n\t },\n\t serialize: function(data) {\n\t return data;\n\t }\n\t });\n\n\t function fillLastGroup(originalGroup, newGroup) {\n\t var currOriginal;\n\t var currentNew;\n\n\t if (newGroup.items && newGroup.items.length) {\n\t for (var i = 0; i < newGroup.items.length; i++) {\n\t currOriginal = originalGroup.items[i];\n\t currentNew = newGroup.items[i];\n\t if (currOriginal && currentNew) {\n\t if (currOriginal.hasSubgroups) {\n\t fillLastGroup(currOriginal, currentNew);\n\t } else if (currOriginal.field && currOriginal.value == currentNew.value) {\n\t currOriginal.items.push.apply(currOriginal.items, currentNew.items);\n\t } else {\n\t originalGroup.items.push.apply(originalGroup.items, [currentNew]);\n\t }\n\t } else if (currentNew) {\n\t originalGroup.items.push.apply(originalGroup.items, [currentNew]);\n\t }\n\t }\n\t }\n\t }\n\t function mergeGroups(target, dest, skip, take) {\n\t var group,\n\t idx = 0,\n\t items;\n\n\t while (dest.length && take) {\n\t group = dest[idx];\n\t items = group.items;\n\n\t var length = items.length;\n\n\t if (target && target.field === group.field && target.value === group.value) {\n\t if (target.hasSubgroups && target.items.length) {\n\t mergeGroups(target.items[target.items.length - 1], group.items, skip, take);\n\t } else {\n\t items = items.slice(skip, skip + take);\n\t target.items = target.items.concat(items);\n\t }\n\t dest.splice(idx--, 1);\n\t } else if (group.hasSubgroups && items.length) {\n\t mergeGroups(group, items, skip, take);\n\t if (!group.items.length) {\n\t dest.splice(idx--, 1);\n\t }\n\t } else {\n\t items = items.slice(skip, skip + take);\n\t group.items = items;\n\n\t if (!group.items.length) {\n\t dest.splice(idx--, 1);\n\t }\n\t }\n\n\t if (items.length === 0) {\n\t skip -= length;\n\t } else {\n\t skip = 0;\n\t take -= items.length;\n\t }\n\n\t if (++idx >= dest.length) {\n\t break;\n\t }\n\t }\n\n\t if (idx < dest.length) {\n\t dest.splice(idx, dest.length - idx);\n\t }\n\t }\n\n\t function flatGroups(groups, indexFunction) {\n\t var result = [];\n\t var groupsLength = (groups || []).length;\n\t var group;\n\t var items;\n\t var indexFn = isFunction(indexFunction) ? indexFunction : function(array, index) {\n\t return array[index];\n\t };\n\n\t for (var groupIndex = 0; groupIndex < groupsLength; groupIndex++) {\n\t group = indexFn(groups, groupIndex);\n\n\t if (group.hasSubgroups) {\n\t result = result.concat(flatGroups(group.items));\n\t } else {\n\t items = group.items;\n\n\t for (var itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t result.push(indexFn(items, itemIndex));\n\t }\n\t }\n\t }\n\t return result;\n\t }\n\n\t function flattenGroups(data) {\n\t var idx,\n\t result = [],\n\t length,\n\t items,\n\t itemIndex;\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t var group = data.at(idx);\n\t if (group.items) {\n\t if (group.hasSubgroups) {\n\t result = result.concat(flattenGroups(group.items));\n\t } else {\n\t items = group.items;\n\t for (itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t result.push(items.at(itemIndex));\n\t }\n\t }\n\t }\n\t }\n\t return result;\n\t }\n\n\t function wrapGroupItems(data, model) {\n\t var idx, length, group;\n\t if (model) {\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t group = data.at(idx);\n\t if (group.items) {\n\t if (group.hasSubgroups) {\n\t wrapGroupItems(group.items, model);\n\t } else {\n\t group.items = new LazyObservableArray(group.items, model, group.items._events);\n\t }\n\t }\n\t }\n\t }\n\t }\n\n\t function eachGroupItems(data, func) {\n\t for (var idx = 0; idx < data.length; idx++) {\n\t if (data[idx].hasSubgroups) {\n\t if (eachGroupItems(data[idx].items, func)) {\n\t return true;\n\t }\n\t } else if (func(data[idx].items, data[idx])) {\n\t return true;\n\t }\n\t }\n\t }\n\n\t function replaceInRanges(ranges, data, item, observable) {\n\t for (var idx = 0; idx < ranges.length; idx++) {\n\t if (ranges[idx].data === data) {\n\t break;\n\t }\n\t if (replaceInRange(ranges[idx].data, item, observable)) {\n\t break;\n\t }\n\t }\n\t }\n\n\t function replaceInRange(items, item, observable) {\n\t for (var idx = 0, length = items.length; idx < length; idx++) {\n\t if (items[idx] && items[idx].hasSubgroups) {\n\t return replaceInRange(items[idx].items, item, observable);\n\t } else if (items[idx] === item || items[idx] === observable) {\n\t items[idx] = observable;\n\t return true;\n\t }\n\t }\n\t }\n\n\t function replaceWithObservable(view, data, ranges, type, serverGrouping) {\n\t for (var viewIndex = 0, length = view.length; viewIndex < length; viewIndex++) {\n\t var item = view[viewIndex];\n\n\t if (!item || item instanceof type) {\n\t continue;\n\t }\n\n\t if (item.hasSubgroups !== undefined && !serverGrouping) {\n\t replaceWithObservable(item.items, data, ranges, type, serverGrouping);\n\t } else {\n\t for (var idx = 0; idx < data.length; idx++) {\n\t if (data[idx] === item) {\n\t view[viewIndex] = data.at(idx);\n\t replaceInRanges(ranges, data, item, view[viewIndex]);\n\t break;\n\t }\n\t }\n\t }\n\t }\n\t }\n\n\t function removeModel(data, model) {\n\t if (!data) {\n\t return;\n\t }\n\t var length = data.length;\n\t var dataItem;\n\t var idx;\n\n\t for (idx = 0; idx < length; idx++) {\n\t dataItem = data[idx];\n\n\t if (dataItem.uid && dataItem.uid == model.uid) {\n\t data.splice(idx, 1);\n\t return dataItem;\n\t }\n\t }\n\t }\n\n\t function indexOfPristineModel(data, model) {\n\t if (model) {\n\t return indexOf(data, function(item) {\n\t return (item.uid && item.uid == model.uid) || (item[model.idField] === model.id && model.id !== model._defaultId);\n\t });\n\t }\n\t return -1;\n\t }\n\n\t function indexOfModel(data, model) {\n\t if (model) {\n\t return indexOf(data, function(item) {\n\t return item.uid == model.uid;\n\t });\n\t }\n\t return -1;\n\t }\n\n\t function indexOf(data, comparer) {\n\t var idx, length;\n\t if (!data) {\n\t return;\n\t }\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t if (comparer(data[idx])) {\n\t return idx;\n\t }\n\t }\n\n\t return -1;\n\t }\n\n\t function fieldNameFromModel(fields, name) {\n\t if (fields && !isEmptyObject(fields)) {\n\t var descriptor = fields[name];\n\t var fieldName;\n\t if (isPlainObject(descriptor)) {\n\t fieldName = descriptor.from || descriptor.field || name;\n\t } else {\n\t fieldName = fields[name] || name;\n\t }\n\n\t if (isFunction(fieldName)) {\n\t return name;\n\t }\n\n\t return fieldName;\n\t }\n\t return name;\n\t }\n\n\t function convertFilterDescriptorsField(descriptor, model) {\n\t var idx,\n\t length,\n\t target = {};\n\n\t for (var field in descriptor) {\n\t if (field !== \"filters\") {\n\t target[field] = descriptor[field];\n\t }\n\t }\n\n\t if (descriptor.filters) {\n\t target.filters = [];\n\t for (idx = 0, length = descriptor.filters.length; idx < length; idx++) {\n\t target.filters[idx] = convertFilterDescriptorsField(descriptor.filters[idx], model);\n\t }\n\t } else {\n\t target.field = fieldNameFromModel(model.fields, target.field);\n\t }\n\t return target;\n\t }\n\n\t function convertDescriptorsField(descriptors, model) {\n\t var idx,\n\t length,\n\t result = [],\n\t target,\n\t descriptor;\n\n\t for (idx = 0, length = descriptors.length; idx < length; idx ++) {\n\t target = {};\n\n\t descriptor = descriptors[idx];\n\n\t for (var field in descriptor) {\n\t target[field] = descriptor[field];\n\t }\n\n\t target.field = fieldNameFromModel(model.fields, target.field);\n\n\t if (target.aggregates && isArray(target.aggregates)) {\n\t target.aggregates = convertDescriptorsField(target.aggregates, model);\n\t }\n\t result.push(target);\n\t }\n\t return result;\n\t }\n\n\t var DataSource = Observable.extend({\n\t init: function(options) {\n\t var that = this, model, data;\n\n\t if (options) {\n\t data = options.data;\n\t }\n\n\t options = that.options = extend({}, that.options, options);\n\n\t that._map = {};\n\t that._prefetch = {};\n\t that._data = [];\n\t that._pristineData = [];\n\t that._ranges = [];\n\t that._view = [];\n\t that._pristineTotal = 0;\n\t that._destroyed = [];\n\t that._pageSize = options.pageSize;\n\t that._page = options.page || (options.pageSize ? 1 : undefined);\n\t that._sort = normalizeSort(options.sort);\n\t that._filter = normalizeFilter(options.filter);\n\t that._group = normalizeGroup(options.group);\n\t that._aggregate = options.aggregate;\n\t that._total = options.total;\n\t that._groupPaging = options.groupPaging;\n\n\t if (that._groupPaging) {\n\t that._groupsState = {};\n\t }\n\t that._shouldDetachObservableParents = true;\n\n\t Observable.fn.init.call(that);\n\n\t that.transport = Transport.create(options, data, that);\n\n\t if (isFunction(that.transport.push)) {\n\t that.transport.push({\n\t pushCreate: proxy(that._pushCreate, that),\n\t pushUpdate: proxy(that._pushUpdate, that),\n\t pushDestroy: proxy(that._pushDestroy, that)\n\t });\n\t }\n\n\t if (options.offlineStorage != null) {\n\t if (typeof options.offlineStorage == \"string\") {\n\t var key = options.offlineStorage;\n\n\t that._storage = {\n\t getItem: function() {\n\t return JSON.parse(localStorage.getItem(key));\n\t },\n\t setItem: function(item) {\n\t localStorage.setItem(key, stringify(that.reader.serialize(item)));\n\t }\n\t };\n\t } else {\n\t that._storage = options.offlineStorage;\n\t }\n\t }\n\n\t that.reader = new kendo.data.readers[options.schema.type || \"json\" ](options.schema);\n\n\t model = that.reader.model || {};\n\n\t that._detachObservableParents();\n\n\t that._data = that._observe(that._data);\n\t that._online = true;\n\n\t that.bind([\"push\", ERROR, CHANGE, REQUESTSTART, SYNC, REQUESTEND, PROGRESS], options);\n\t },\n\n\t options: {\n\t data: null,\n\t schema: {\n\t modelBase: Model\n\t },\n\t offlineStorage: null,\n\t serverSorting: false,\n\t serverPaging: false,\n\t serverFiltering: false,\n\t serverGrouping: false,\n\t serverAggregates: false,\n\t batch: false,\n\t inPlaceSort: false\n\t },\n\n\t clone: function() {\n\t return this;\n\t },\n\n\t online: function(value) {\n\t if (value !== undefined) {\n\t if (this._online != value) {\n\t this._online = value;\n\n\t if (value) {\n\t return this.sync();\n\t }\n\t }\n\n\t return $.Deferred().resolve().promise();\n\t } else {\n\t return this._online;\n\t }\n\t },\n\n\t offlineData: function(state) {\n\t if (this.options.offlineStorage == null) {\n\t return null;\n\t }\n\n\t if (state !== undefined) {\n\t return this._storage.setItem(state);\n\t }\n\n\t return this._storage.getItem() || [];\n\t },\n\n\t _isServerGrouped: function() {\n\t var group = this.group() || [];\n\n\t return this.options.serverGrouping && group.length;\n\t },\n\n\t _isServerGroupPaged: function(){\n\t return this._isServerGrouped() && this._groupPaging;\n\t },\n\n\t _isGroupPaged: function(){\n\t var group = this.group() || [];\n\n\t return this._groupPaging && group.length;\n\t },\n\n\t _pushCreate: function(result) {\n\t this._push(result, \"pushCreate\");\n\t },\n\n\t _pushUpdate: function(result) {\n\t this._push(result, \"pushUpdate\");\n\t },\n\n\t _pushDestroy: function(result) {\n\t this._push(result, \"pushDestroy\");\n\t },\n\n\t _push: function(result, operation) {\n\t var data = this._readData(result);\n\n\t if (!data) {\n\t data = result;\n\t }\n\n\t this[operation](data);\n\t },\n\n\t _flatData: function(data, skip) {\n\t if (data) {\n\t if (this._isServerGrouped()) {\n\t return flattenGroups(data);\n\t }\n\n\t if (!skip) {\n\t for (var idx = 0; idx < data.length; idx++) {\n\t data.at(idx);\n\t }\n\t }\n\t }\n\n\t return data;\n\t },\n\n\t parent: noop,\n\n\t get: function(id) {\n\t var idx, length, data = this._flatData(this._data, this.options.useRanges);\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t if (data[idx].id == id) {\n\t return data[idx];\n\t }\n\t }\n\t },\n\n\t getByUid: function(id) {\n\t return this._getByUid(id, this._data);\n\t },\n\n\t _getByUid: function(id, dataItems) {\n\t var idx, length, data = this._flatData(dataItems, this.options.useRanges);\n\n\t if (!data) {\n\t return;\n\t }\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t if (data[idx].uid == id) {\n\t return data[idx];\n\t }\n\t }\n\t },\n\n\t indexOf: function(model) {\n\t return indexOfModel(this._data, model);\n\t },\n\n\t at: function(index) {\n\t return this._data.at(index);\n\t },\n\n\t data: function(value) {\n\t var that = this;\n\t if (value !== undefined) {\n\t that._detachObservableParents();\n\t that._data = this._observe(value);\n\n\t that._pristineData = value.slice(0);\n\n\t that._storeData();\n\n\t that._ranges = [];\n\t that.trigger(\"reset\");\n\t that._addRange(that._data);\n\n\t that._total = that._data.length;\n\t that._pristineTotal = that._total;\n\n\t that._process(that._data);\n\t } else {\n\t if (that._data) {\n\t for (var idx = 0; idx < that._data.length; idx++) {\n\t that._data.at(idx);\n\t }\n\t }\n\n\t return that._data;\n\t }\n\t },\n\n\t view: function(value) {\n\t if (value === undefined) {\n\t return this._view;\n\t } else {\n\t this._view = this._observeView(value);\n\t }\n\t },\n\n\t _observeView: function(data) {\n\t var that = this;\n\t replaceWithObservable(data, that._data, that._ranges, that.reader.model || ObservableObject, that._isServerGrouped());\n\n\t var view = new LazyObservableArray(data, that.reader.model);\n\t view.parent = function() { return that.parent(); };\n\t return view;\n\t },\n\n\t flatView: function() {\n\t var groups = this.group() || [];\n\n\t if (groups.length) {\n\t return flattenGroups(this._view);\n\t } else {\n\t return this._view;\n\t }\n\t },\n\n\t add: function(model) {\n\t return this.insert(this._data.length, model);\n\t },\n\n\t _createNewModel: function(model) {\n\t if (this.reader.model) {\n\t return new this.reader.model(model);\n\t }\n\n\t if (model instanceof ObservableObject) {\n\t return model;\n\t }\n\n\t return new ObservableObject(model);\n\t },\n\n\t insert: function(index, model) {\n\t if (!model) {\n\t model = index;\n\t index = 0;\n\t }\n\n\t if (!(model instanceof Model)) {\n\t model = this._createNewModel(model);\n\t }\n\n\t if (this._isServerGrouped()) {\n\t this._data.splice(index, 0, this._wrapInEmptyGroup(model));\n\t } else {\n\t this._data.splice(index, 0, model);\n\t }\n\n\t this._insertModelInRange(index, model);\n\n\t return model;\n\t },\n\n\t pushInsert: function(index, items) {\n\t var that = this;\n\t var rangeSpan = that._getCurrentRangeSpan();\n\n\t if (!items) {\n\t items = index;\n\t index = 0;\n\t }\n\n\t if (!isArray(items)) {\n\t items = [items];\n\t }\n\n\t var pushed = [];\n\t var autoSync = this.options.autoSync;\n\t this.options.autoSync = false;\n\n\t try {\n\t for (var idx = 0; idx < items.length; idx ++) {\n\t var item = items[idx];\n\n\t var result = this.insert(index, item);\n\n\t pushed.push(result);\n\n\t var pristine = result.toJSON();\n\n\t if (this._isServerGrouped()) {\n\t pristine = this._wrapInEmptyGroup(pristine);\n\t }\n\n\t this._pristineData.push(pristine);\n\n\t if (rangeSpan && rangeSpan.length) {\n\t $(rangeSpan).last()[0].pristineData.push(pristine);\n\t }\n\n\t index++;\n\t }\n\t } finally {\n\t this.options.autoSync = autoSync;\n\t }\n\n\t if (pushed.length) {\n\t this.trigger(\"push\", {\n\t type: \"create\",\n\t items: pushed\n\t });\n\t }\n\t },\n\n\t pushCreate: function(items) {\n\t this.pushInsert(this._data.length, items);\n\t },\n\n\t pushUpdate: function(items) {\n\t if (!isArray(items)) {\n\t items = [items];\n\t }\n\n\t var pushed = [];\n\n\t for (var idx = 0; idx < items.length; idx ++) {\n\t var item = items[idx];\n\t var model = this._createNewModel(item);\n\n\t var target = this.get(model.id);\n\n\t if (target) {\n\t pushed.push(target);\n\n\t target.accept(item);\n\n\t target.trigger(CHANGE);\n\n\t this._updatePristineForModel(target, item);\n\t } else {\n\t this.pushCreate(item);\n\t }\n\t }\n\n\t if (pushed.length) {\n\t this.trigger(\"push\", {\n\t type: \"update\",\n\t items: pushed\n\t });\n\t }\n\t },\n\n\t pushDestroy: function(items) {\n\t var pushed = this._removeItems(items);\n\n\t if (pushed.length) {\n\t this.trigger(\"push\", {\n\t type: \"destroy\",\n\t items: pushed\n\t });\n\t }\n\t },\n\n\t _removeItems: function(items, removePristine) {\n\t if (!isArray(items)) {\n\t items = [items];\n\t }\n\n\t var shouldRemovePristine = typeof removePristine !== \"undefined\" ? removePristine : true;\n\n\t var destroyed = [];\n\t var autoSync = this.options.autoSync;\n\t this.options.autoSync = false;\n\t try {\n\t for (var idx = 0; idx < items.length; idx ++) {\n\t var item = items[idx];\n\t var model = this._createNewModel(item);\n\t var found = false;\n\n\t this._eachItem(this._data, function(items){\n\t for (var idx = 0; idx < items.length; idx++) {\n\t var item = items.at(idx);\n\t if (item.id === model.id) {\n\t destroyed.push(item);\n\t items.splice(idx, 1);\n\t found = true;\n\t break;\n\t }\n\t }\n\t });\n\n\t if (found && shouldRemovePristine) {\n\t this._removePristineForModel(model);\n\t this._destroyed.pop();\n\t }\n\t }\n\t } finally {\n\t this.options.autoSync = autoSync;\n\t }\n\n\t return destroyed;\n\t },\n\n\t remove: function(model) {\n\t var result,\n\t that = this,\n\t hasGroups = that._isServerGrouped();\n\n\t this._eachItem(that._data, function(items) {\n\t result = removeModel(items, model);\n\n\t if (result && hasGroups) {\n\t if (!result.isNew || !result.isNew()) {\n\t that._destroyed.push(result);\n\t }\n\t return true;\n\t }\n\t });\n\n\t this._removeModelFromRanges(model);\n\n\t return model;\n\t },\n\n\t destroyed: function() {\n\t return this._destroyed;\n\t },\n\n\t created: function() {\n\t var idx,\n\t length,\n\t result = [],\n\t data = this._flatData(this._data, this.options.useRanges);\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t if (data[idx].isNew && data[idx].isNew()) {\n\t result.push(data[idx]);\n\t }\n\t }\n\t return result;\n\t },\n\n\t updated: function() {\n\t var idx,\n\t length,\n\t result = [],\n\t data = this._flatData(this._data, this.options.useRanges);\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t if ((data[idx].isNew && !data[idx].isNew()) && data[idx].dirty) {\n\t result.push(data[idx]);\n\t }\n\t }\n\t return result;\n\t },\n\n\t sync: function() {\n\t var that = this,\n\t created = [],\n\t updated = [],\n\t destroyed = that._destroyed;\n\n\t var promise = $.Deferred().resolve().promise();\n\n\t if (that.online()) {\n\n\t if (!that.reader.model) {\n\t return promise;\n\t }\n\n\t created = that.created();\n\t updated = that.updated();\n\n\t var promises = [];\n\n\t if (that.options.batch && that.transport.submit) {\n\t promises = that._sendSubmit(created, updated, destroyed);\n\t } else {\n\t promises.push.apply(promises, that._send(\"create\", created));\n\t promises.push.apply(promises, that._send(\"update\", updated));\n\t promises.push.apply(promises, that._send(\"destroy\", destroyed));\n\t }\n\n\t promise = $.when\n\t .apply(null, promises)\n\t .then(function() {\n\t var idx, length;\n\n\t for (idx = 0, length = arguments.length; idx < length; idx++){\n\t if (arguments[idx]) {\n\t that._accept(arguments[idx]);\n\t }\n\t }\n\n\t that._storeData(true);\n\n\t that._syncEnd();\n\n\t that._change({ action: \"sync\" });\n\n\t that.trigger(SYNC);\n\n\t if (that._isServerGroupPaged()) {\n\t that.read();\n\t }\n\t });\n\t } else {\n\t that._storeData(true);\n\n\t that._syncEnd();\n\n\t that._change({ action: \"sync\" });\n\t }\n\n\t return promise;\n\t },\n\n\t _syncEnd: noop,\n\n\t cancelChanges: function(model) {\n\t var that = this;\n\n\t if (model instanceof kendo.data.Model) {\n\t that._cancelModel(model);\n\t } else {\n\t that._destroyed = [];\n\t that._detachObservableParents();\n\t that._data = that._observe(that._pristineData);\n\t if (that.options.serverPaging) {\n\t that._total = that._pristineTotal;\n\t }\n\n\t that._ranges = [];\n\t that._addRange(that._data, 0);\n\n\t that._changesCanceled();\n\n\t that._change();\n\n\t that._markOfflineUpdatesAsDirty();\n\n\t if (that._isServerGrouped()) {\n\t that.read();\n\t }\n\t }\n\t },\n\n\t _changesCanceled: noop,\n\n\t _markOfflineUpdatesAsDirty: function() {\n\t var that = this;\n\n\t if (that.options.offlineStorage != null) {\n\t that._eachItem(that._data, function(items) {\n\t for (var idx = 0; idx < items.length; idx++) {\n\t var item = items.at(idx);\n\t if (item.__state__ == \"update\" || item.__state__ == \"create\") {\n\t item.dirty = true;\n\t }\n\t }\n\t });\n\t }\n\t },\n\n\t hasChanges: function() {\n\t var idx,\n\t length,\n\t data = this._flatData(this._data, this.options.useRanges);\n\n\t if (this._destroyed.length) {\n\t return true;\n\t }\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t if ((data[idx].isNew && data[idx].isNew()) || data[idx].dirty) {\n\t return true;\n\t }\n\t }\n\n\t return false;\n\t },\n\n\t _accept: function(result) {\n\t var that = this,\n\t models = result.models,\n\t response = result.response,\n\t idx = 0,\n\t serverGroup = that._isServerGrouped(),\n\t pristine = that._pristineData,\n\t type = result.type,\n\t length;\n\n\t that.trigger(REQUESTEND, { response: response, type: type });\n\n\t if (response && !isEmptyObject(response)) {\n\t response = that.reader.parse(response);\n\n\t if (that._handleCustomErrors(response)) {\n\t return;\n\t }\n\n\t response = that.reader.data(response);\n\n\t if (!isArray(response)) {\n\t response = [response];\n\t }\n\t } else {\n\t response = $.map(models, function(model) { return model.toJSON(); } );\n\t }\n\n\t if (type === \"destroy\") {\n\t that._destroyed = [];\n\t }\n\n\t for (idx = 0, length = models.length; idx < length; idx++) {\n\t if (type !== \"destroy\") {\n\t models[idx].accept(response[idx]);\n\n\t if (type === \"create\") {\n\t pristine.push(serverGroup ? that._wrapInEmptyGroup(models[idx].toJSON()) : response[idx]);\n\t } else if (type === \"update\") {\n\t that._updatePristineForModel(models[idx], response[idx]);\n\t }\n\t } else {\n\t that._removePristineForModel(models[idx]);\n\t }\n\t }\n\t },\n\n\t _updatePristineForModel: function(model, values) {\n\t this._executeOnPristineForModel(model, function(index, items) {\n\t kendo.deepExtend(items[index], values);\n\t });\n\t },\n\n\t _executeOnPristineForModel: function(model, callback) {\n\t this._eachPristineItem(\n\t function(items) {\n\t var index = indexOfPristineModel(items, model);\n\t if (index > -1) {\n\t callback(index, items);\n\t return true;\n\t }\n\t });\n\t },\n\n\t _removePristineForModel: function(model) {\n\t this._executeOnPristineForModel(model, function(index, items) {\n\t items.splice(index, 1);\n\t });\n\t },\n\n\t _readData: function(data) {\n\t var read = !this._isServerGrouped() ? this.reader.data : this.reader.groups;\n\t return read.call(this.reader, data);\n\t },\n\n\t _eachPristineItem: function(callback) {\n\t var that = this;\n\t var options = that.options;\n\t var rangeSpan = that._getCurrentRangeSpan();\n\n\t that._eachItem(that._pristineData, callback);\n\n\t if (options.serverPaging && options.useRanges) {\n\t each(rangeSpan, function(i, range) {\n\t that._eachItem(range.pristineData, callback);\n\t });\n\t }\n\t },\n\n\t _eachItem: function(data, callback) {\n\t if (data && data.length) {\n\t if (this._isServerGrouped()) {\n\t eachGroupItems(data, callback);\n\t } else {\n\t callback(data);\n\t }\n\t }\n\t },\n\n\t _pristineForModel: function(model) {\n\t var pristine,\n\t idx,\n\t callback = function(items) {\n\t idx = indexOfPristineModel(items, model);\n\t if (idx > -1) {\n\t pristine = items[idx];\n\t return true;\n\t }\n\t };\n\n\t this._eachPristineItem(callback);\n\n\t return pristine;\n\t },\n\n\t _cancelModel: function(model) {\n\t var that = this;\n\t var pristine = this._pristineForModel(model);\n\n\t this._eachItem(this._data, function(items) {\n\t var idx = indexOfModel(items, model);\n\t if (idx >= 0) {\n\t if (pristine && (!model.isNew() || pristine.__state__)) {\n\t items[idx].accept(pristine);\n\n\t if (pristine.__state__ == \"update\") {\n\t items[idx].dirty = true;\n\t }\n\n\t } else {\n\t that._modelCanceled(model);\n\n\t items.splice(idx, 1);\n\n\t that._removeModelFromRanges(model);\n\t }\n\t }\n\t });\n\t },\n\n\t _modelCanceled: noop,\n\n\t _submit: function(promises, data) {\n\t var that = this;\n\n\t that.trigger(REQUESTSTART, { type: \"submit\" });\n\n\t that.trigger(PROGRESS);\n\n\t that.transport.submit(extend({\n\t success: function(response, type) {\n\t var promise = $.grep(promises, function(x) {\n\t return x.type == type;\n\t })[0];\n\n\t if (promise) {\n\t promise.resolve({\n\t response: response,\n\t models: promise.models,\n\t type: type\n\t });\n\t }\n\t },\n\t error: function(response, status, error) {\n\t for (var idx = 0; idx < promises.length; idx++) {\n\t promises[idx].reject(response);\n\t }\n\n\t that.error(response, status, error);\n\t }\n\t }, data));\n\t },\n\n\t _sendSubmit: function(created, updated, destroyed) {\n\t var that = this,\n\t promises = [];\n\n\t if (that.options.batch) {\n\t if (created.length) {\n\t promises.push($.Deferred(function(deferred) {\n\t deferred.type = \"create\";\n\t deferred.models = created;\n\t }));\n\t }\n\n\t if (updated.length) {\n\t promises.push($.Deferred(function(deferred) {\n\t deferred.type = \"update\";\n\t deferred.models = updated;\n\t }));\n\t }\n\n\t if (destroyed.length) {\n\t promises.push($.Deferred(function(deferred) {\n\t deferred.type = \"destroy\";\n\t deferred.models = destroyed;\n\t }));\n\t }\n\n\t that._submit(promises, {\n\t data: {\n\t created: that.reader.serialize(toJSON(created)),\n\t updated: that.reader.serialize(toJSON(updated)),\n\t destroyed: that.reader.serialize(toJSON(destroyed))\n\t }\n\t });\n\t }\n\n\t return promises;\n\t },\n\n\t _promise: function(data, models, type) {\n\t var that = this;\n\n\t return $.Deferred(function(deferred) {\n\t that.trigger(REQUESTSTART, { type: type });\n\n\t that.trigger(PROGRESS);\n\n\t that.transport[type].call(that.transport, extend({\n\t success: function(response) {\n\t deferred.resolve({\n\t response: response,\n\t models: models,\n\t type: type\n\t });\n\t },\n\t error: function(response, status, error) {\n\t deferred.reject(response);\n\t that.error(response, status, error);\n\t }\n\t }, data));\n\t }).promise();\n\t },\n\n\t _send: function(method, data) {\n\t var that = this,\n\t idx,\n\t length,\n\t promises = [],\n\t converted = that.reader.serialize(toJSON(data));\n\n\t if (that.options.batch) {\n\t if (data.length) {\n\t promises.push(that._promise( { data: { models: converted } }, data , method));\n\t }\n\t } else {\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t promises.push(that._promise( { data: converted[idx] }, [ data[idx] ], method));\n\t }\n\t }\n\n\t return promises;\n\t },\n\n\t read: function(data) {\n\t var that = this, params = that._params(data);\n\t var deferred = $.Deferred();\n\n\t that._queueRequest(params, function() {\n\t var isPrevented = that.trigger(REQUESTSTART, { type: \"read\" });\n\t if (!isPrevented) {\n\t that.trigger(PROGRESS);\n\n\t that._ranges = [];\n\t that.trigger(\"reset\");\n\t if (that.online()) {\n\t that.transport.read({\n\t data: params,\n\t success: function(data) {\n\t that._ranges = [];\n\t that.success(data, params);\n\n\t deferred.resolve();\n\t },\n\t error: function() {\n\t var args = slice.call(arguments);\n\n\t that.error.apply(that, args);\n\n\t deferred.reject.apply(deferred, args);\n\t }\n\t });\n\t } else if (that.options.offlineStorage != null){\n\t that.success(that.offlineData(), params);\n\n\t deferred.resolve();\n\t }\n\t } else {\n\t that._dequeueRequest();\n\n\t deferred.resolve(isPrevented);\n\t }\n\t });\n\n\t return deferred.promise();\n\t },\n\n\t _readAggregates: function(data) {\n\t return this.reader.aggregates(data);\n\t },\n\n\t success: function(data) {\n\t var that = this,\n\t options = that.options,\n\t items,\n\t replaceSubset;\n\n\t that.trigger(REQUESTEND, { response: data, type: \"read\" });\n\n\t if (that.online()) {\n\t data = that.reader.parse(data);\n\n\t if (that._handleCustomErrors(data)) {\n\t that._dequeueRequest();\n\t return;\n\t }\n\n\t that._total = that.reader.total(data);\n\n\t if (that._isServerGroupPaged()) {\n\t that._serverGroupsTotal = that._total;\n\t }\n\n\t if (that._pageSize > that._total) {\n\t that._pageSize = that._total;\n\t if (that.options.pageSize && that.options.pageSize > that._pageSize) {\n\t that._pageSize = that.options.pageSize;\n\t }\n\t }\n\n\t if (that._aggregate && options.serverAggregates) {\n\t that._aggregateResult = that._readAggregates(data);\n\t }\n\n\t data = that._readData(data);\n\n\t that._destroyed = [];\n\t } else {\n\t data = that._readData(data);\n\n\t items = [];\n\t var itemIds = {};\n\t var model = that.reader.model;\n\t var idField = model ? model.idField : \"id\";\n\t var idx;\n\n\t for (idx = 0; idx < this._destroyed.length; idx++) {\n\t var id = this._destroyed[idx][idField];\n\t itemIds[id] = id;\n\t }\n\n\t for (idx = 0; idx < data.length; idx++) {\n\t var item = data[idx];\n\t var state = item.__state__;\n\t if (state == \"destroy\") {\n\t if (!itemIds[item[idField]]) {\n\t this._destroyed.push(this._createNewModel(item));\n\t }\n\t } else {\n\t items.push(item);\n\t }\n\t }\n\n\t data = items;\n\n\t that._total = data.length;\n\t }\n\n\t that._pristineTotal = that._total;\n\t replaceSubset = that._skip && that._data.length && that._skip < that._data.length;\n\n\t if (that.options.endless) {\n\t if (replaceSubset) {\n\t that._pristineData.splice(that._skip, that._pristineData.length);\n\t }\n\t items = data.slice(0);\n\t for (var j = 0; j < items.length; j++) {\n\t that._pristineData.push(items[j]);\n\t }\n\t } else {\n\t that._pristineData = data.slice(0);\n\t }\n\n\t that._detachObservableParents();\n\n\t if (that.options.endless) {\n\t that._data.unbind(CHANGE, that._changeHandler);\n\n\t if (that._isServerGrouped() && that._data[that._data.length - 1].value === data[0].value) {\n\t fillLastGroup(that._data[that._data.length - 1], data[0]);\n\t data.shift();\n\t }\n\n\t data = that._observe(data);\n\t if (replaceSubset) {\n\t that._data.splice(that._skip, that._data.length);\n\t }\n\t for (var i = 0; i < data.length; i++) {\n\t that._data.push(data[i]);\n\t }\n\t that._data.bind(CHANGE, that._changeHandler);\n\t } else {\n\t that._data = that._observe(data);\n\t }\n\n\t that._markOfflineUpdatesAsDirty();\n\n\t that._storeData();\n\n\t that._addRange(that._data);\n\n\t that._process(that._data);\n\n\t that._dequeueRequest();\n\t },\n\n\t _detachObservableParents: function() {\n\t if (this._data && this._shouldDetachObservableParents) {\n\t for (var idx = 0; idx < this._data.length; idx++) {\n\t if (this._data[idx].parent) {\n\t this._data[idx].parent = noop;\n\t }\n\t }\n\t }\n\t },\n\n\t _storeData: function(updatePristine) {\n\t var serverGrouping = this._isServerGrouped();\n\t var model = this.reader.model;\n\n\t function items(data) {\n\t var state = [];\n\n\t for (var idx = 0; idx < data.length; idx++) {\n\t var dataItem = data.at(idx);\n\t var item = dataItem.toJSON();\n\n\t if (serverGrouping && dataItem.items) {\n\t item.items = items(dataItem.items);\n\t } else {\n\t item.uid = dataItem.uid;\n\n\t if (model) {\n\t if (dataItem.isNew()) {\n\t item.__state__ = \"create\";\n\t } else if (dataItem.dirty) {\n\t item.__state__ = \"update\";\n\t }\n\t }\n\t }\n\t state.push(item);\n\t }\n\n\t return state;\n\t }\n\n\t if (this.options.offlineStorage != null) {\n\t var state = items(this._data);\n\n\t var destroyed = [];\n\n\t for (var idx = 0; idx < this._destroyed.length; idx++) {\n\t var item = this._destroyed[idx].toJSON();\n\t item.__state__ = \"destroy\";\n\t destroyed.push(item);\n\t }\n\n\t this.offlineData(state.concat(destroyed));\n\n\t if (updatePristine) {\n\t this._pristineData = this.reader.reader ? this.reader.reader._wrapDataAccessBase(state) : this.reader._wrapDataAccessBase(state);\n\t }\n\t }\n\t },\n\n\t _addRange: function (data, skip) {\n\t var that = this,\n\t start = typeof (skip) !== \"undefined\" ? skip : (that._skip || 0),\n\t end,\n\t range = {\n\t data: data,\n\t pristineData: data.toJSON(),\n\t timestamp: that._timeStamp()\n\t };\n\n\t if (this._isGroupPaged()) {\n\t end = start + data.length;\n\t range.outerStart = start;\n\t range.outerEnd = end;\n\t } else {\n\t end = start + that._flatData(data, true).length;\n\t }\n\n\t range.start = start;\n\t range.end = end;\n\t that._ranges.push(range);\n\t that._sortRanges();\n\n\t if (that._isGroupPaged()) {\n\t if (!that._groupsFlat) {\n\t that._groupsFlat = [];\n\t }\n\t that._appendToGroupsFlat(range.data);\n\t that._updateOuterRangesLength();\n\t }\n\t },\n\n\t _appendToGroupsFlat: function (data) {\n\t var length = data.length;\n\n\t for (var i = 0; i < length; i++) {\n\t this._groupsFlat.push(data[i]);\n\t }\n\t },\n\n\t _getGroupByUid: function(uid){\n\t var length = this._groupsFlat.length;\n\t var group;\n\n\t for (var i = 0; i < length; i++) {\n\t group = this._groupsFlat[i];\n\t if (group.uid === uid) {\n\t return group;\n\t }\n\t }\n\t },\n\n\t _sortRanges: function() {\n\t this._ranges.sort(function(x, y) {\n\t return x.start - y.start;\n\t });\n\t },\n\n\t error: function(xhr, status, errorThrown) {\n\t this._dequeueRequest();\n\t this.trigger(REQUESTEND, { });\n\t this.trigger(ERROR, { xhr: xhr, status: status, errorThrown: errorThrown });\n\t },\n\n\t _params: function(data) {\n\t var that = this,\n\t options = extend({\n\t take: that.take(),\n\t skip: that.skip(),\n\t page: that.page(),\n\t pageSize: that.pageSize(),\n\t sort: that._sort,\n\t filter: that._filter,\n\t group: that._group,\n\t aggregate: that._aggregate,\n\t groupPaging: !!that._groupPaging\n\t }, data);\n\n\t if (!that.options.serverPaging) {\n\t delete options.take;\n\t delete options.skip;\n\t delete options.page;\n\t delete options.pageSize;\n\t }\n\n\t if (!that.options.serverGrouping) {\n\t delete options.group;\n\t } else if (that.reader.model && options.group) {\n\t options.group = convertDescriptorsField(options.group, that.reader.model);\n\t }\n\n\t if (!that.options.serverFiltering) {\n\t delete options.filter;\n\t } else if (that.reader.model && options.filter) {\n\t options.filter = convertFilterDescriptorsField(options.filter, that.reader.model);\n\t }\n\n\t if (!that.options.serverSorting) {\n\t delete options.sort;\n\t } else if (that.reader.model && options.sort) {\n\t options.sort = convertDescriptorsField(options.sort, that.reader.model);\n\t }\n\n\t if (!that.options.serverAggregates) {\n\t delete options.aggregate;\n\t } else if (that.reader.model && options.aggregate) {\n\t options.aggregate = convertDescriptorsField(options.aggregate, that.reader.model);\n\t }\n\n\t if (!that.options.groupPaging) {\n\t delete options.groupPaging;\n\t }\n\n\t return options;\n\t },\n\n\t _queueRequest: function(options, callback) {\n\t var that = this;\n\t if (!that._requestInProgress) {\n\t that._requestInProgress = true;\n\t that._pending = undefined;\n\t callback();\n\t } else {\n\t that._pending = { callback: proxy(callback, that), options: options };\n\t }\n\t },\n\n\t _dequeueRequest: function() {\n\t var that = this;\n\t that._requestInProgress = false;\n\t if (that._pending) {\n\t that._queueRequest(that._pending.options, that._pending.callback);\n\t }\n\t },\n\n\t _handleCustomErrors: function(response) {\n\t if (this.reader.errors) {\n\t var errors = this.reader.errors(response);\n\t if (errors) {\n\t this.trigger(ERROR, { xhr: null, status: \"customerror\", errorThrown: \"custom error\", errors: errors });\n\t return true;\n\t }\n\t }\n\t return false;\n\t },\n\n\t _shouldWrap: function(data) {\n\t var model = this.reader.model;\n\n\t if (model && data.length) {\n\t return !(data[0] instanceof model);\n\t }\n\n\t return false;\n\t },\n\n\t _observe: function(data) {\n\t var that = this,\n\t model = that.reader.model;\n\n\t that._shouldDetachObservableParents = true;\n\n\t if (data instanceof ObservableArray) {\n\t that._shouldDetachObservableParents = false;\n\t if (that._shouldWrap(data)) {\n\t data.type = that.reader.model;\n\t data.wrapAll(data, data);\n\t }\n\t } else {\n\t var arrayType = that.pageSize() && !that.options.serverPaging ? LazyObservableArray : ObservableArray;\n\t data = new arrayType(data, that.reader.model);\n\t data.parent = function() { return that.parent(); };\n\t }\n\n\t if (that._isServerGrouped()) {\n\t wrapGroupItems(data, model);\n\t }\n\n\t if (that._changeHandler && that._data && that._data instanceof ObservableArray &&\n\t !(that.options.useRanges && that.options.serverPaging)) {\n\t that._data.unbind(CHANGE, that._changeHandler);\n\t } else {\n\t that._changeHandler = proxy(that._change, that);\n\t }\n\n\t return data.bind(CHANGE, that._changeHandler);\n\t },\n\n\t _updateTotalForAction: function(action, items) {\n\t var that = this;\n\n\t var total = parseInt(that._total, 10);\n\n\t if (!isNumber(that._total)) {\n\t total = parseInt(that._pristineTotal, 10);\n\t }\n\t if (action === \"add\") {\n\t total += items.length;\n\t } else if (action === \"remove\") {\n\t total -= items.length;\n\t } else if (action !== \"itemchange\" && action !== \"sync\" && !that.options.serverPaging) {\n\t total = that._pristineTotal;\n\t } else if (action === \"sync\") {\n\t total = that._pristineTotal = parseInt(that._total, 10);\n\t }\n\n\t that._total = total;\n\t },\n\n\t _change: function(e) {\n\t var that = this, idx, length, action = e ? e.action : \"\";\n\n\t if (action === \"remove\") {\n\t for (idx = 0, length = e.items.length; idx < length; idx++) {\n\t if (!e.items[idx].isNew || !e.items[idx].isNew()) {\n\t that._destroyed.push(e.items[idx]);\n\t }\n\t }\n\t }\n\n\t if (that.options.autoSync && (action === \"add\" || action === \"remove\" || action === \"itemchange\")) {\n\n\t var handler = function(args) {\n\t if (args.action === \"sync\") {\n\t that.unbind(\"change\", handler);\n\t that._updateTotalForAction(action, e.items);\n\t }\n\t };\n\n\t that.first(\"change\", handler);\n\n\t that.sync();\n\n\t } else {\n\t that._updateTotalForAction(action, e ? e.items : []);\n\n\t that._process(that._data, e);\n\t }\n\t },\n\n\t _calculateAggregates: function (data, options) {\n\t options = options || {};\n\n\t var query = new Query(data),\n\t aggregates = options.aggregate,\n\t filter = options.filter;\n\n\t if (filter) {\n\t query = query.filter(filter);\n\t }\n\n\t return query.aggregate(aggregates);\n\t },\n\n\t _process: function (data, e) {\n\t var that = this,\n\t options = {},\n\t result;\n\n\t if (that.options.serverPaging !== true) {\n\t options.skip = that._skip;\n\t options.take = that._take || that._pageSize;\n\n\t if(options.skip === undefined && that._page !== undefined && that._pageSize !== undefined) {\n\t options.skip = (that._page - 1) * that._pageSize;\n\t }\n\n\t if (that.options.useRanges) {\n\t options.skip = that.currentRangeStart();\n\t }\n\t }\n\n\t if (that.options.serverSorting !== true) {\n\t options.sort = that._sort;\n\t }\n\n\t if (that.options.serverFiltering !== true) {\n\t options.filter = that._filter;\n\t }\n\n\t if (that.options.serverGrouping !== true) {\n\t options.group = that._group;\n\t }\n\n\t if (that.options.serverAggregates !== true) {\n\t options.aggregate = that._aggregate;\n\t }\n\n\t if (that.options.serverGrouping) {\n\t that._clearEmptyGroups(data);\n\t }\n\n\t options.groupPaging = that._groupPaging;\n\n\t if (that._isGroupPaged() && e && (e.action === \"page\" || e.action === \"expandGroup\" || e.action === \"collapseGroup\")) {\n\t result = that._queryProcess(data, {\n\t aggregate: that._aggregate\n\t });\n\t } else {\n\t result = that._queryProcess(data, options);\n\t }\n\n\t if (that.options.serverAggregates !== true) {\n\t // for performance reasons, calculate aggregates for part of the data only after query process\n\t // this is necessary in the TreeList when paging\n\t that._aggregateResult = that._calculateAggregates(result.dataToAggregate || data, options);\n\t }\n\n\t that._setView(result, options, e);\n\n\t that._setFilterTotal(result.total, false);\n\n\t e = e || {};\n\n\t e.items = e.items || that._view;\n\n\t that.trigger(CHANGE, e);\n\t },\n\n\t _setView: function (result, options, e) {\n\t var that = this;\n\n\t if (that._isGroupPaged() && !that._isServerGrouped()) {\n\t if (e && (e.action === \"page\" || e.action === \"expandGroup\" || e.action === \"collapseGroup\")) {\n\t that.view(result.data);\n\t that._updateOuterRangesLength();\n\t } else {\n\t that._ranges = [];\n\t var query = new Query(result.data);\n\t that._addRange(that._observe(result.data));\n\n\t if (options.skip > (result.data.length / options.take + 1)) {\n\t options.skip = 0;\n\t }\n\n\t that.view(query.range(options.skip, options.take).toArray());\n\t }\n\n\t } else {\n\t that.view(result.data);\n\t }\n\t },\n\n\t _clearEmptyGroups: function(data) {\n\t for (var idx = data.length - 1; idx >=0; idx--) {\n\t var group = data[idx];\n\t if (group.hasSubgroups) {\n\t this._clearEmptyGroups(group.items);\n\t } else {\n\t if (group.items && !group.items.length) {\n\t splice.apply(group.parent(), [idx, 1]);\n\t }\n\t }\n\t }\n\t },\n\n\t _queryProcess: function(data, options) {\n\t if (this.options.inPlaceSort) {\n\t return Query.process(data, options, this.options.inPlaceSort);\n\t }\n\t else {\n\t return Query.process(data, options);\n\t }\n\t },\n\n\t _mergeState: function(options) {\n\t var that = this;\n\n\t if (options !== undefined) {\n\t that._pageSize = options.pageSize;\n\t that._page = options.page;\n\t that._sort = options.sort;\n\t that._filter = options.filter;\n\t that._group = options.group;\n\t that._aggregate = options.aggregate;\n\t that._skip = that._currentRangeStart = options.skip;\n\t that._take = options.take;\n\n\t if(that._skip === undefined) {\n\t that._skip = that._currentRangeStart = that.skip();\n\t options.skip = that.skip();\n\t }\n\n\t if(that._take === undefined && that._pageSize !== undefined) {\n\t that._take = that._pageSize;\n\t options.take = that._take;\n\t }\n\n\t if (options.sort) {\n\t that._sort = options.sort = normalizeSort(options.sort);\n\t that._sortFields = sortFields(options.sort);\n\t }\n\n\t if (options.filter) {\n\t that._filter = options.filter = (that.options.accentFoldingFiltering && !$.isEmptyObject(options.filter)) ? $.extend({}, normalizeFilter(options.filter), { accentFoldingFiltering: that.options.accentFoldingFiltering}) : normalizeFilter(options.filter);\n\t }\n\n\t if (options.group) {\n\t that._group = options.group = normalizeGroup(options.group);\n\t }\n\t if (options.aggregate) {\n\t that._aggregate = options.aggregate = normalizeAggregate(options.aggregate);\n\t }\n\t }\n\t return options;\n\t },\n\n\t query: function(options) {\n\t var result;\n\t var remote = this.options.serverSorting || this.options.serverPaging || this.options.serverFiltering || this.options.serverGrouping || this.options.serverAggregates;\n\n\t if (remote || ((this._data === undefined || this._data.length === 0) && !this._destroyed.length)) {\n\t if (this.options.endless) {\n\t var moreItemsCount = options.pageSize - this.pageSize();\n\t if (moreItemsCount > 0) {\n\t moreItemsCount = this.pageSize();\n\t options.page = options.pageSize / moreItemsCount;\n\t options.pageSize = moreItemsCount;\n\t } else {\n\t options.page = 1;\n\t this.options.endless = false;\n\t }\n\t }\n\t return this.read(this._mergeState(options));\n\t }\n\n\t var isPrevented = this.trigger(REQUESTSTART, { type: \"read\" });\n\t if (!isPrevented) {\n\t this.trigger(PROGRESS);\n\t if (options) {\n\t options.groupPaging = this._groupPaging;\n\t }\n\t result = this._queryProcess(this._data, this._mergeState(options));\n\n\t this._setFilterTotal(result.total, true);\n\n\t this._aggregateResult = this._calculateAggregates(result.dataToAggregate || this._data, options);\n\t this._setView(result, options);\n\t this.trigger(REQUESTEND, { type: \"read\" });\n\t this.trigger(CHANGE, { items: result.data, action: options ? options.action : \"\" });\n\t }\n\n\t return $.Deferred().resolve(isPrevented).promise();\n\t },\n\n\t _hasExpandedSubGroups: function (group) {\n\t var result = false;\n\t var length = group.items ? group.items.length : 0;\n\n\t if (!group.hasSubgroups) {\n\t return false;\n\t }\n\n\t for (var i = 0; i < length; i++) {\n\t if (this._groupsState[group.items[i].uid]) {\n\t result = true;\n\t break;\n\t }\n\t }\n\t return result;\n\t },\n\n\t _findGroupedRange: function (data, result, options, parents, callback) {\n\t var that = this;\n\t var length = data.length;\n\t var group;\n\t var current;\n\t var itemsLength;\n\t var hasNotRequestedItems;\n\t var groupCount;\n\t var itemsToSkip;\n\n\t for (var i = 0; i < length; i++) {\n\t group = data[i];\n\n\t if (options.taken >= options.take) {\n\t break;\n\t }\n\n\t if (!that._getGroupByUid(group.uid)) {\n\t that._groupsFlat.push(group);\n\t }\n\n\t if (that._groupsState[group.uid]) {\n\t if (that._isServerGroupPaged()) {\n\t if (group.hasSubgroups && !group.subgroupCount) {\n\t that.getGroupSubGroupCount(group, options, parents, callback);\n\t that._fetchingGroupItems = true;\n\t return;\n\t }\n\t groupCount = (group.subgroupCount || group.itemCount) + 1;\n\t itemsToSkip = options.skip - options.skipped;\n\t hasNotRequestedItems = !group.items || (group.items.length - itemsToSkip) < (options.take - options.taken);\n\n\t if (!that._hasExpandedSubGroups(group) && itemsToSkip > groupCount) {\n\t options.skipped += groupCount;\n\t continue;\n\t }\n\n\t if ((group.hasSubgroups && (!group.items || hasNotRequestedItems && group.items.length < group.subgroupCount)) ||\n\t (!group.hasSubgroups && (!group.items || hasNotRequestedItems && group.items.length < group.itemCount))) {\n\t that.getGroupItems(group, options, parents, callback);\n\t that._fetchingGroupItems = true;\n\t return;\n\t }\n\t }\n\n\t if (options.includeParents && options.skipped < options.skip) {\n\t options.skipped++;\n\t group.excludeHeader = true;\n\t } else if (options.includeParents) {\n\t options.taken++;\n\t }\n\n\t if (group.hasSubgroups && group.items && group.items.length) {\n\t group.currentItems = [];\n\n\t if (!parents) {\n\t parents = [];\n\t }\n\t parents.push(group);\n\n\t that._findGroupedRange(group.items, group.currentItems, options, parents, callback);\n\t parents.pop();\n\n\t if (group.currentItems.length || options.taken > 0) {\n\t result.push(group);\n\t } else {\n\t group.excludeHeader = false;\n\t }\n\t } else {\n\t current = [];\n\t itemsLength = group.items.length;\n\n\t for (var j = 0; j < itemsLength; j++) {\n\t if (options.skipped < options.skip) {\n\t options.skipped++;\n\t continue;\n\t }\n\n\t if (options.taken >= options.take) {\n\t break;\n\t }\n\t current.push(group.items[j]);\n\t options.taken++;\n\t }\n\n\t if (current.length || options.taken > 0) {\n\t group.currentItems = current;\n\t result.push(group);\n\t } else {\n\t group.excludeHeader = false;\n\t }\n\t }\n\t } else {\n\t if (options.skipped < options.skip) {\n\t options.skipped++;\n\t continue;\n\t }\n\t result.push(group);\n\t options.taken++;\n\t }\n\t }\n\t },\n\n\t getGroupItems: function (group, options, parents, callback) {\n\t var that = this;\n\t var skip;\n\t var take;\n\t var filter;\n\t var data;\n\t var subgroups;\n\n\t if (!group.items) {\n\t group.items = [];\n\t }\n\n\t skip = group.items.length;\n\t take = that.take();\n\t filter = this._composeItemsFilter(group, parents);\n\t data = {\n\t page: math.floor((skip || 0) / (take || 1)) || 1,\n\t pageSize: take,\n\t skip: skip,\n\t take: take,\n\t filter: filter,\n\t aggregate: that._aggregate,\n\t sort: that._sort\n\t };\n\t subgroups = that.findSubgroups(group);\n\n\t if (subgroups && subgroups.length) {\n\t data.group = subgroups;\n\t data.groupPaging = true;\n\t }\n\n\t clearTimeout(that._timeout);\n\t that._timeout = setTimeout(function () {\n\t that._queueRequest(data, function () {\n\t if (!that.trigger(REQUESTSTART, {\n\t type: \"read\"\n\t })) {\n\t that.transport.read({\n\t data: data,\n\t success: that._groupItemsSuccessHandler(group, options.skip, that.take(), callback),\n\t error: function () {\n\t var args = slice.call(arguments);\n\t that.error.apply(that, args);\n\t }\n\t });\n\t } else {\n\t that._dequeueRequest();\n\t }\n\t });\n\t }, 100);\n\t },\n\n\t getGroupSubGroupCount: function (group, options, parents, callback) {\n\t var that = this;\n\t var filter;\n\t var groupIndex;\n\t var data;\n\n\t if (!group.items) {\n\t group.items = [];\n\t }\n\n\t filter = this._composeItemsFilter(group, parents);\n\t groupIndex = this._group.map(function (g) {\n\t return g.field;\n\t }).indexOf(group.field);\n\t data = {\n\t filter: filter,\n\t group: [that._group[groupIndex + 1]],\n\t groupPaging: true,\n\t includeSubGroupCount: true\n\t };\n\n\t clearTimeout(that._timeout);\n\t that._timeout = setTimeout(function () {\n\t that._queueRequest(data, function () {\n\t if (!that.trigger(REQUESTSTART, {\n\t type: \"read\"\n\t })) {\n\t that.transport.read({\n\t data: data,\n\t success: that._subGroupCountSuccessHandler(group, options.skip, that.take(), callback),\n\t error: function () {\n\t var args = slice.call(arguments);\n\t that.error.apply(that, args);\n\t }\n\t });\n\t } else {\n\t that._dequeueRequest();\n\t }\n\t });\n\t }, 100);\n\t },\n\n\t _subGroupCountSuccessHandler: function (group, skip, take, callback) {\n\t var that = this;\n\t callback = isFunction(callback) ? callback : noop;\n\t var totalField = that.options.schema && that.options.schema.total ? that.options.schema.total : \"Total\";\n\n\t return function (data) {\n\n\t that._dequeueRequest();\n\n\t that.trigger(REQUESTEND, {\n\t response: data,\n\t type: \"read\"\n\t });\n\t that._fetchingGroupItems = false;\n\t group.subgroupCount = data[totalField];\n\t that.range(skip, take, callback, \"expandGroup\");\n\t };\n\t },\n\n\t _groupItemsSuccessHandler: function (group, skip, take, callback) {\n\t var that = this;\n\t var timestamp = that._timeStamp();\n\t callback = isFunction(callback) ? callback : noop;\n\n\t return function (data) {\n\t var temp;\n\t var model = Model.define(that.options.schema.model);\n\n\t that._dequeueRequest();\n\n\t that.trigger(REQUESTEND, {\n\t response: data,\n\t type: \"read\"\n\t });\n\n\t data = that.reader.parse(data);\n\n\t if (group.hasSubgroups) {\n\t temp = that.reader.groups(data);\n\t } else {\n\t temp = that.reader.data(data);\n\t temp = temp.map(function (item) {\n\t return new model(item);\n\t });\n\t }\n\n\t group.items.omitChangeEvent = true;\n\t for (var i = 0; i < temp.length; i++) {\n\t group.items.push(temp[i]);\n\t }\n\t group.items.omitChangeEvent = false;\n\n\t that._updateRangePristineData(group);\n\t that._fetchingGroupItems = false;\n\t that._serverGroupsTotal += temp.length;\n\t that.range(skip, take, callback, \"expandGroup\");\n\n\t if (timestamp >= that._currentRequestTimeStamp || !that._skipRequestsInProgress) {\n\t that.trigger(CHANGE, {});\n\t }\n\t };\n\n\t },\n\n\t findSubgroups: function (group) {\n\t var indexOfCurrentGroup = this._group.map(function (g) {\n\t return g.field;\n\t }).indexOf(group.field);\n\n\t return this._group.slice(indexOfCurrentGroup + 1, this._group.length);\n\t },\n\n\t _composeItemsFilter: function (group, parents) {\n\t var filter = this.filter() || {\n\t logic: \"and\",\n\t filters: []\n\t };\n\n\t filter = extend(true, {}, filter);\n\t filter.filters.push({\n\t field: group.field,\n\t operator: \"eq\",\n\t value: group.value\n\t });\n\n\t if (parents) {\n\t for (var i = 0; i < parents.length; i++) {\n\t filter.filters.push({\n\t field: parents[i].field,\n\t operator: \"eq\",\n\t value: parents[i].value\n\t });\n\t }\n\t }\n\n\t return filter;\n\t },\n\n\t _updateRangePristineData: function (group) {\n\t var that = this;\n\t var ranges = that._ranges;\n\t var rangesLength = ranges.length;\n\t var temp;\n\t var currentGroup;\n\t var range;\n\t var dataLength;\n\t var indexes;\n\n\t for (var i = 0; i < rangesLength; i++) {\n\t range = ranges[i];\n\t dataLength = range.data.length;\n\t indexes = [];\n\n\t for (var j = 0; j < dataLength; j++) {\n\t currentGroup = range.data[j];\n\t indexes.push(j);\n\n\t if ((currentGroup.uid === group.uid) || (currentGroup.hasSubgroups && currentGroup.items.length && that._containsSubGroup(currentGroup, group, indexes))) {\n\t break;\n\t }\n\t indexes.pop();\n\t }\n\n\t if (indexes.length) {\n\t temp = ranges[i].pristineData;\n\n\t while (indexes.length > 1) {\n\t temp = temp[indexes.splice(0, 1)[0]].items;\n\t }\n\t temp[indexes[0]] = that._cloneGroup(group);\n\t break;\n\t }\n\t }\n\t },\n\n\t _containsSubGroup: function (group, subgroup, indexes) {\n\t var that = this;\n\t var length = group.items.length;\n\t var currentSubGroup;\n\n\t if (group.hasSubgroups && length) {\n\t for (var i = 0; i < length; i++) {\n\t currentSubGroup = group.items[i];\n\t indexes.push(i);\n\t if (currentSubGroup.uid === subgroup.uid) {\n\t return true;\n\t } else if (currentSubGroup.hasSubgroups && currentSubGroup.items.length) {\n\t return that._containsSubGroup(currentSubGroup, subgroup, indexes);\n\t }\n\t indexes.pop();\n\t }\n\t }\n\n\t },\n\n\t _cloneGroup: function (group) {\n\t var that = this;\n\t group = typeof group.toJSON == \"function\" ? group.toJSON() : group;\n\n\t if (group.items && group.items.length) {\n\t group.items = group.items.map(function (item) {\n\t return that._cloneGroup(item);\n\t });\n\t }\n\n\t return group;\n\t },\n\n\t _setFilterTotal: function(filterTotal, setDefaultValue) {\n\t var that = this;\n\n\t if (!that.options.serverFiltering) {\n\t if (filterTotal !== undefined) {\n\t that._total = filterTotal;\n\t } else if (setDefaultValue) {\n\t that._total = that._data.length;\n\t }\n\t }\n\t },\n\n\t fetch: function(callback) {\n\t var that = this;\n\t var fn = function(isPrevented) {\n\t if (isPrevented !== true && isFunction(callback)) {\n\t callback.call(that);\n\t }\n\t };\n\n\t return this._query().done(fn);\n\t },\n\n\t _query: function(options) {\n\t var that = this;\n\n\t return that.query(extend({}, {\n\t page: that.page(),\n\t pageSize: that.pageSize(),\n\t sort: that.sort(),\n\t filter: that.filter(),\n\t group: that.group(),\n\t aggregate: that.aggregate()\n\t }, options));\n\t },\n\n\t next: function(options) {\n\t var that = this,\n\t page = that.page(),\n\t total = that.total();\n\n\t options = options || {};\n\n\t if (!page || (total && page + 1 > that.totalPages())) {\n\t return;\n\t }\n\n\t that._skip = that._currentRangeStart = page * that.take();\n\n\t page += 1;\n\t options.page = page;\n\n\t that._query(options);\n\n\t return page;\n\t },\n\n\t prev: function(options) {\n\t var that = this,\n\t page = that.page();\n\n\t options = options || {};\n\n\t if (!page || page === 1) {\n\t return;\n\t }\n\n\t that._skip = that._currentRangeStart = that._skip - that.take();\n\n\t page -= 1;\n\t options.page = page;\n\n\t that._query(options);\n\n\t return page;\n\t },\n\n\t page: function(val) {\n\t var that = this,\n\t skip;\n\n\t if(val !== undefined) {\n\t val = math.max(math.min(math.max(val, 1), that.totalPages()), 1);\n\t var take = that.take();\n\n\t if (that._isGroupPaged()) {\n\t val -= 1;\n\t that.range(val * take, take, null, \"page\");\n\t return;\n\t }\n\t that._query(that._pageableQueryOptions({ page: val }));\n\t return;\n\t }\n\t skip = that.skip();\n\n\t return skip !== undefined ? math.round((skip || 0) / (that.take() || 1)) + 1 : undefined;\n\t },\n\n\t pageSize: function(val) {\n\t var that = this;\n\n\t if (val !== undefined) {\n\t that._query(that._pageableQueryOptions({ pageSize: val, page: 1 }));\n\t return;\n\t }\n\n\t return that.take();\n\t },\n\n\t sort: function(val) {\n\t var that = this;\n\n\t if(val !== undefined) {\n\t that.trigger(\"sort\");\n\t that._query({ sort: val });\n\t return;\n\t }\n\n\t return that._sort;\n\t },\n\n\t filter: function(val) {\n\t var that = this;\n\n\t if (val === undefined) {\n\t return that._filter;\n\t }\n\n\t that.trigger(\"reset\");\n\t that._query({ filter: val, page: 1 });\n\t },\n\n\t group: function(val) {\n\t var that = this;\n\n\t if(val !== undefined) {\n\t that._query({ group: val });\n\t return;\n\t }\n\n\t return that._group;\n\t },\n\n\t getGroupsFlat: function (data) {\n\t var idx,\n\t result = [],\n\t length;\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t var group = data[idx];\n\t if (group.hasSubgroups) {\n\t result = result.concat(this.getGroupsFlat(group.items));\n\t }\n\n\t result.push(group);\n\t }\n\n\t return result;\n\t },\n\n\t total: function() {\n\t return parseInt(this._total || 0, 10);\n\t },\n\n\t groupsTotal: function (includeExpanded) {\n\t var that = this;\n\n\t if (!that._group.length) {\n\t return that.total();\n\t }\n\n\t if (that._isServerGrouped()) {\n\t if (that._serverGroupsTotal) {\n\t return that._serverGroupsTotal;\n\t }\n\t that._serverGroupsTotal = that.total();\n\n\t return that._serverGroupsTotal;\n\t }\n\n\t return that._calculateGroupsTotal(that._ranges.length ? that._ranges[0].data : [], includeExpanded);\n\t },\n\n\t _calculateGroupsTotal: function (groups, includeExpanded, itemsField, ignoreState) {\n\t var that = this;\n\t itemsField = itemsField || \"items\";\n\t var total;\n\t var length;\n\n\t if (that._group.length && groups) {\n\t total = 0;\n\t length = groups.length;\n\n\t for (var i = 0; i < length; i++) {\n\t total += that.groupCount(groups[i], includeExpanded, itemsField, ignoreState);\n\t }\n\t that._groupsTotal = total;\n\t return total;\n\t }\n\n\t that._groupsTotal = that._data.length;\n\t return that._groupsTotal;\n\t },\n\n\t groupCount: function (group, includeExpanded, itemsField, ignoreState) {\n\t var that = this;\n\t var total = 0;\n\n\t if (group.hasSubgroups && that._groupsState[group.uid]) {\n\t if (includeExpanded && !group.excludeHeader || ignoreState) {\n\t total += 1;\n\t }\n\n\t group[itemsField].forEach(function (subgroup) {\n\t total += that.groupCount(subgroup, includeExpanded, itemsField, ignoreState);\n\t });\n\t } else {\n\t if (that._groupsState[group.uid]) {\n\t if (includeExpanded && !group.excludeHeader || ignoreState) {\n\t total++;\n\t }\n\t total += group[itemsField] ? group[itemsField].length : 0;\n\t } else {\n\t total++;\n\t }\n\t }\n\t return total;\n\t },\n\n\t countGroupRange: function (range) {\n\t var total = 0;\n\t var length = range.length;\n\n\t for (var i = 0; i < length; i++) {\n\t total += this.groupCount(range[i], true);\n\t }\n\n\t return total;\n\t },\n\n\t aggregate: function(val) {\n\t var that = this;\n\n\t if(val !== undefined) {\n\t that._query({ aggregate: val });\n\t return;\n\t }\n\n\t return that._aggregate;\n\t },\n\n\t aggregates: function() {\n\t var result = this._aggregateResult;\n\n\t if (isEmptyObject(result)) {\n\t result = this._emptyAggregates(this.aggregate());\n\t }\n\n\t return result;\n\t },\n\n\t _emptyAggregates: function(aggregates) {\n\t var result = {};\n\n\t if (!isEmptyObject(aggregates)) {\n\t var aggregate = {};\n\n\t if (!isArray(aggregates)){\n\t aggregates = [aggregates];\n\t }\n\n\t for (var idx = 0; idx = length; idx--) {\n\t group = groups[idx];\n\t parent = {\n\t value: model.get ? model.get(group.field) : model[group.field],\n\t field: group.field,\n\t items: parent ? [parent] : [model],\n\t hasSubgroups: !!parent,\n\t aggregates: this._emptyAggregates(group.aggregates)\n\t };\n\t }\n\n\t return parent;\n\t },\n\n\t totalPages: function() {\n\t var that = this,\n\t pageSize = that.pageSize() || that.total(),\n\t total = that._isGroupPaged() ? that.groupsTotal(true) : that.total();\n\n\t return math.ceil((total || 0) / pageSize);\n\t },\n\n\t inRange: function(skip, take) {\n\t var that = this,\n\t end = math.min(skip + take, that.total());\n\n\t if (!that.options.serverPaging && that._data.length > 0) {\n\t return true;\n\t }\n\n\t return that._findRange(skip, end).length > 0;\n\t },\n\n\t lastRange: function() {\n\t var ranges = this._ranges;\n\t return ranges[ranges.length - 1] || { start: 0, end: 0, data: [] };\n\t },\n\n\t firstItemUid: function() {\n\t var ranges = this._ranges;\n\t return ranges.length && ranges[0].data.length && ranges[0].data[0].uid;\n\t },\n\n\t enableRequestsInProgress: function() {\n\t this._skipRequestsInProgress = false;\n\t },\n\n\t _timeStamp: function() {\n\t return new Date().getTime();\n\t },\n\n\t range: function(skip, take, callback, action) {\n\t this._currentRequestTimeStamp = this._timeStamp();\n\t this._skipRequestsInProgress = true;\n\t var total = this._isGroupPaged() ? this.groupsTotal(true) : this.total();\n\n\t if (action === \"expandGroup\" || action === \"collapseGroup\") {\n\t this._updateOuterRangesLength();\n\t }\n\n\t skip = math.min(skip || 0, total);\n\t callback = isFunction(callback) ? callback : noop;\n\n\t var that = this,\n\t pageSkip = math.max(math.floor(skip / take), 0) * take,\n\t size = math.min(pageSkip + take, total),\n\t data;\n\n\t data = that._findRange(skip, math.min(skip + take, total), callback);\n\n\t if ((data.length || total === 0) && !that._fetchingGroupItems) {\n\t that._processRangeData(data, skip, take, that._originalPageSkip || pageSkip, that._originalSize || size, {\n\t action: action\n\t });\n\t that._originalPageSkip = null;\n\t that._originalSize = null;\n\t callback();\n\t return;\n\t }\n\n\t if (that._isGroupPaged()) {\n\t that._originalPageSkip = pageSkip;\n\t that._originalSize = size;\n\n\t pageSkip = math.max(math.floor(that._adjustPageSkip(skip, take) / take), 0) * take;\n\t size = math.min(pageSkip + take, total);\n\t }\n\n\t if (take !== undefined && !that._fetchingGroupItems) {\n\t if ((that._isGroupPaged() && !that._groupRangeExists(pageSkip, take)) || !that._rangeExists(pageSkip, size)) {\n\t that.prefetch(pageSkip, take, function() {\n\t if (skip > pageSkip && size < that.total() && !that._rangeExists(size, math.min(size + take, that.total()))) {\n\t that.prefetch(size, take, function() {\n\t that.range(skip, take, callback );\n\t });\n\t } else {\n\t that.range(skip, take, callback);\n\t }\n\t });\n\t } else if (pageSkip < skip) {\n\t that.prefetch(size, take, function() {\n\t that.range(skip, take, callback );\n\t });\n\t }\n\t }\n\t },\n\n\t _findRange: function(start, end, callback) {\n\t var that = this,\n\t ranges = that._ranges,\n\t range,\n\t data = [],\n\t skipIdx,\n\t takeIdx,\n\t startIndex,\n\t endIndex,\n\t rangeData,\n\t rangeEnd,\n\t processed,\n\t options = that.options,\n\t remote = options.serverSorting || options.serverPaging || options.serverFiltering || options.serverGrouping || options.serverAggregates,\n\t flatData,\n\t count,\n\t length,\n\t groupMapOptions = {\n\t take: end - start,\n\t skip: start,\n\t skipped: 0,\n\t taken: 0,\n\t includeParents: true\n\t },\n\t prevRangeEnd,\n\t isGroupPaged = that._isGroupPaged(),\n\t startField = isGroupPaged ? \"outerStart\" : \"start\",\n\t endField = isGroupPaged ? \"outerEnd\" : \"end\",\n\t currentDataLength;\n\n\t for (skipIdx = 0, length = ranges.length; skipIdx < length; skipIdx++) {\n\t range = ranges[skipIdx];\n\n\t if (isGroupPaged) {\n\t if (range.outerStart >= end) {\n\t return [];\n\t }\n\n\t if (start > range.outerEnd) {\n\t groupMapOptions.skipped += range.outerEnd - (prevRangeEnd || 0);\n\t prevRangeEnd = range.outerEnd;\n\t continue;\n\t }\n\n\t if (typeof prevRangeEnd !== \"undefined\" && prevRangeEnd != range.outerStart) {\n\t groupMapOptions.skipped += range.outerStart - prevRangeEnd;\n\t }\n\n\t if (groupMapOptions.skipped > groupMapOptions.skip) {\n\t return [];\n\t }\n\n\t if (typeof prevRangeEnd === \"undefined\" && start > 0 && range.start > 0) {\n\t groupMapOptions.skipped = range.outerStart;\n\t }\n\n\t takeIdx = skipIdx;\n\t while (true) {\n\t this._findGroupedRange(range.data, data, groupMapOptions, null, callback);\n\t currentDataLength = that._calculateGroupsTotal(data, true, \"currentItems\");\n\n\t if (currentDataLength >= groupMapOptions.take) {\n\t return data;\n\t }\n\n\t if (that._fetchingGroupItems) {\n\t return [];\n\t }\n\t takeIdx++;\n\n\t if (ranges[takeIdx] && ranges[takeIdx].outerStart === range.outerEnd) {\n\t range = ranges[takeIdx];\n\t } else {\n\t break;\n\t }\n\t }\n\t } else if (start >= range[startField] && start <= range[endField]) {\n\t count = 0;\n\n\t for (takeIdx = skipIdx; takeIdx < length; takeIdx++) {\n\t range = ranges[takeIdx];\n\t flatData = that._flatData(range.data, true);\n\n\t if (flatData.length && start + count >= range.start) {\n\t rangeData = range.data;\n\t rangeEnd = range.end;\n\n\t if (!remote) {\n\t if (options.inPlaceSort) {\n\t processed = that._queryProcess(range.data, { filter: that.filter() });\n\t } else {\n\t var sort = normalizeGroupWithoutCompare(that.group() || []).concat(normalizeSort(that.sort() || []));\n\t processed = that._queryProcess(range.data, { sort: sort, filter: that.filter() });\n\t }\n\t flatData = rangeData = processed.data;\n\n\t if (processed.total !== undefined) {\n\t rangeEnd = processed.total;\n\t }\n\t }\n\n\t startIndex = 0;\n\t if (start + count > range.start) {\n\t startIndex = (start + count) - range.start;\n\t }\n\t endIndex = flatData.length;\n\t if (rangeEnd > end) {\n\t endIndex = endIndex - (rangeEnd - end);\n\t }\n\t count += endIndex - startIndex;\n\t data = that._mergeGroups(data, rangeData, startIndex, endIndex);\n\n\t if (end <= range.end && count == end - start) {\n\t return data;\n\t }\n\t }\n\t }\n\t break;\n\t }\n\t prevRangeEnd = range.outerEnd;\n\t }\n\t return [];\n\t },\n\n\t _getRangesMismatch: function (pageSkip) {\n\t var that = this;\n\t var ranges = that._ranges;\n\t var mismatch = 0;\n\t var i = 0;\n\n\t while (true) {\n\t var range = ranges[i];\n\t if (!range || range.outerStart > pageSkip) {\n\t break;\n\t }\n\n\t if (range.outerEnd != range.end) {\n\t mismatch = range.outerEnd - range.end;\n\t }\n\t i++;\n\t }\n\n\t return mismatch;\n\t },\n\n\t _mergeGroups: function(data, range, skip, take) {\n\t if (this._isServerGrouped()) {\n\t var temp = range.toJSON(),\n\t prevGroup;\n\n\t if (data.length) {\n\t prevGroup = data[data.length - 1];\n\t }\n\n\t mergeGroups(prevGroup, temp, skip, take);\n\n\t return data.concat(temp);\n\t }\n\t return data.concat(range.slice(skip, take));\n\t },\n\n\t _processRangeData: function(data, skip, take, pageSkip, size, eventData) {\n\t var that = this;\n\n\t that._pending = undefined;\n\n\t that._skip = skip > that.skip() && !that._omitPrefetch ? math.min(size, (that.totalPages() - 1) * that.take()) : pageSkip;\n\n\t that._currentRangeStart = skip;\n\n\t that._take = take;\n\n\t var paging = that.options.serverPaging;\n\t var sorting = that.options.serverSorting;\n\t var filtering = that.options.serverFiltering;\n\t var aggregates = that.options.serverAggregates;\n\t try {\n\t that.options.serverPaging = true;\n\t if (!that._isServerGrouped() && !(that.group() && that.group().length)) {\n\t that.options.serverSorting = true;\n\t }\n\t that.options.serverFiltering = true;\n\t that.options.serverPaging = true;\n\t that.options.serverAggregates = true;\n\n\t if (paging) {\n\t that._detachObservableParents();\n\t that._data = data = that._observe(data);\n\t }\n\t that._process(data, eventData);\n\t } finally {\n\t that.options.serverPaging = paging;\n\t that.options.serverSorting = sorting;\n\t that.options.serverFiltering = filtering;\n\t that.options.serverAggregates = aggregates;\n\t }\n\t },\n\n\t skip: function() {\n\t var that = this;\n\n\t if (that._skip === undefined) {\n\t return (that._page !== undefined ? (that._page - 1) * (that.take() || 1) : undefined);\n\t }\n\t return that._skip;\n\t },\n\n\t currentRangeStart: function() {\n\t return this._currentRangeStart || 0;\n\t },\n\n\t take: function() {\n\t return this._take || this._pageSize;\n\t },\n\n\t _prefetchSuccessHandler: function (skip, size, callback, force) {\n\t var that = this;\n\t var timestamp = that._timeStamp();\n\n\t return function(data) {\n\t var found = false,\n\t range = { start: skip, end: size, data: [], timestamp: that._timeStamp() },\n\t idx,\n\t length,\n\t temp;\n\n\t that._dequeueRequest();\n\n\t that.trigger(REQUESTEND, { response: data, type: \"read\" });\n\n\t data = that.reader.parse(data);\n\n\t temp = that._readData(data);\n\n\t if (temp.length) {\n\t for (idx = 0, length = that._ranges.length; idx < length; idx++) {\n\t if (that._ranges[idx].start === skip) {\n\t found = true;\n\t range = that._ranges[idx];\n\n\t if (!that._isGroupPaged()) {\n\t range.pristineData = temp;\n\t range.data = that._observe(temp);\n\t range.end = range.start + that._flatData(range.data, true).length;\n\t that._sortRanges();\n\t }\n\n\t break;\n\t }\n\t }\n\n\t if (!found) {\n\t that._addRange(that._observe(temp), skip);\n\t }\n\t }\n\n\t that._total = that.reader.total(data);\n\n\t if (force || (timestamp >= that._currentRequestTimeStamp || !that._skipRequestsInProgress)) {\n\t if (callback && temp.length) {\n\t callback();\n\t } else {\n\t that.trigger(CHANGE, {});\n\t }\n\t }\n\t };\n\t },\n\n\t prefetch: function(skip, take, callback) {\n\t var that = this,\n\t size = math.min(skip + take, that.total()),\n\t options = {\n\t take: take,\n\t skip: skip,\n\t page: skip / take + 1,\n\t pageSize: take,\n\t sort: that._sort,\n\t filter: that._filter,\n\t group: that._group,\n\t aggregate: that._aggregate\n\t };\n\n\n\t if ((that._isGroupPaged() && !that._isServerGrouped() && that._groupRangeExists(skip, size))) {\n\t if (callback) {\n\t callback();\n\t }\n\t return;\n\t }\n\n\t if ((that._isServerGroupPaged() && !that._groupRangeExists(skip, size)) || !that._rangeExists(skip, size)) {\n\t clearTimeout(that._timeout);\n\n\t that._timeout = setTimeout(function() {\n\t that._queueRequest(options, function() {\n\t if (!that.trigger(REQUESTSTART, { type: \"read\" })) {\n\t if (that._omitPrefetch) {\n\t that.trigger(PROGRESS);\n\t }\n\t that.transport.read({\n\t data: that._params(options),\n\t success: that._prefetchSuccessHandler(skip, size, callback),\n\t error: function() {\n\t var args = slice.call(arguments);\n\t that.error.apply(that, args);\n\t }\n\t });\n\t } else {\n\t that._dequeueRequest();\n\t }\n\t });\n\t }, 100);\n\t } else if (callback) {\n\t callback();\n\t }\n\t },\n\n\t _multiplePrefetch: function(skip, take, callback) {\n\t var that = this,\n\t size = math.min(skip + take, that.total()),\n\t options = {\n\t take: take,\n\t skip: skip,\n\t page: skip / take + 1,\n\t pageSize: take,\n\t sort: that._sort,\n\t filter: that._filter,\n\t group: that._group,\n\t aggregate: that._aggregate\n\t };\n\n\t if (!that._rangeExists(skip, size)) {\n\t if (!that.trigger(REQUESTSTART, { type: \"read\" })) {\n\t that.transport.read({\n\t data: that._params(options),\n\t success: that._prefetchSuccessHandler(skip, size, callback, true)\n\t });\n\t }\n\t } else if (callback) {\n\t callback();\n\t }\n\t },\n\n\t _adjustPageSkip: function (start, take) {\n\t var that = this;\n\t var prevRange = that._getPrevRange(start);\n\t var result;\n\t var total = that.total();\n\t var mismatch;\n\n\t if (prevRange) {\n\t mismatch = that._getRangesMismatch(start);\n\n\t if (!mismatch) {\n\t return start;\n\t }\n\t start -= mismatch;\n\t }\n\t result = math.max(math.floor(start / take), 0) * take;\n\n\t if (result > total) {\n\t while (true) {\n\t result -= take;\n\t if (result < total) {\n\t break;\n\t }\n\t }\n\t }\n\t return result;\n\t },\n\n\t _getNextRange: function (end) {\n\t var that = this,\n\t ranges = that._ranges,\n\t idx,\n\t length;\n\n\t for (idx = 0, length = ranges.length; idx < length; idx++) {\n\t if (ranges[idx].start <= end && ranges[idx].end >= end) {\n\t return ranges[idx];\n\t }\n\t }\n\t },\n\n\t _getPrevRange: function (start) {\n\t var that = this,\n\t ranges = that._ranges,\n\t idx,\n\t range,\n\t length = ranges.length;\n\n\t for (idx = length - 1; idx >= 0; idx--) {\n\t if (ranges[idx].outerStart <= start) {\n\t range = ranges[idx];\n\t break;\n\t }\n\n\t }\n\n\t return range;\n\t },\n\n\t _rangeExists: function(start, end) {\n\t var that = this,\n\t ranges = that._ranges,\n\t idx,\n\t length;\n\n\t for (idx = 0, length = ranges.length; idx < length; idx++) {\n\t if (ranges[idx].start <= start && ranges[idx].end >= end) {\n\t return true;\n\t }\n\t }\n\n\t return false;\n\t },\n\n\t _groupRangeExists: function (start, end) {\n\t var that = this,\n\t ranges = that._ranges,\n\t idx,\n\t length,\n\t availableItemsCount = 0,\n\t total = that.groupsTotal(true);\n\n\t if (end > total && !that._isServerGrouped()) {\n\t end = total;\n\t }\n\n\t for (idx = 0, length = ranges.length; idx < length; idx++) {\n\t var range = ranges[idx];\n\t if (range.outerStart <= start && range.outerEnd >= start) {\n\t availableItemsCount += range.outerEnd - start;\n\t } else if (range.outerStart <= end && range.outerEnd >= end) {\n\t availableItemsCount += end - range.outerStart;\n\t }\n\t }\n\n\t return availableItemsCount >= end - start;\n\t },\n\n\t _getCurrentRangeSpan: function() {\n\t var that = this;\n\t var ranges = that._ranges;\n\t var start = that.currentRangeStart();\n\t var end = start + (that.take() || 0);\n\t var rangeSpan = [];\n\t var range;\n\t var idx;\n\t var length = ranges.length;\n\n\t for (idx = 0; idx < length; idx++) {\n\t range = ranges[idx];\n\n\t if ((range.start <= start && range.end >= start) || (range.start >= start && range.start <= end)) {\n\t rangeSpan.push(range);\n\t }\n\t }\n\n\t return rangeSpan;\n\t },\n\n\t _removeModelFromRanges: function(model) {\n\t var that = this;\n\t var range;\n\n\t for (var idx = 0, length = this._ranges.length; idx < length; idx++) {\n\t range = this._ranges[idx];\n\n\t that._removeModelFromRange(range, model);\n\t }\n\n\t that._updateRangesLength();\n\t },\n\n\t _removeModelFromRange: function(range, model) {\n\t this._eachItem(range.data, function(data) {\n\t if (!data) {\n\t return;\n\t }\n\t for (var idx = 0; idx < data.length; idx++) {\n\t var dataItem = data[idx];\n\n\t if (dataItem.uid && dataItem.uid == model.uid) {\n\t [].splice.call(data, idx, 1);\n\t break;\n\t }\n\t }\n\t });\n\t },\n\n\t _insertModelInRange: function(index, model) {\n\t var that = this;\n\t var ranges = that._ranges || [];\n\t var rangesLength = ranges.length;\n\t var range;\n\t var i;\n\n\t for (i = 0; i < rangesLength; i++) {\n\t range = ranges[i];\n\n\t if (range.start <= index && range.end >= index) {\n\t if (!that._getByUid(model.uid, range.data)) {\n\t if (that._isServerGrouped()) {\n\t range.data.splice(index, 0, that._wrapInEmptyGroup(model));\n\t } else {\n\t range.data.splice(index, 0, model);\n\t }\n\t }\n\n\t break;\n\t }\n\t }\n\n\t that._updateRangesLength();\n\t },\n\n\t _updateRangesLength: function() {\n\t var that = this;\n\t var ranges = that._ranges || [];\n\t var rangesLength = ranges.length;\n\t var mismatchFound = false;\n\t var mismatchLength = 0;\n\t var lengthDifference = 0;\n\t var rangeLength;\n\t var range;\n\t var i;\n\n\t for (i = 0; i < rangesLength; i++) {\n\t range = ranges[i];\n\t rangeLength = that._isGroupPaged() ? range.data.length : that._flatData(range.data, true).length;\n\t lengthDifference = rangeLength - math.abs(range.end - range.start);\n\n\t if (!mismatchFound && lengthDifference !== 0) {\n\t mismatchFound = true;\n\t mismatchLength = lengthDifference;\n\t range.end += mismatchLength;\n\t continue;\n\t }\n\n\t if (mismatchFound) {\n\t range.start += mismatchLength;\n\t range.end += mismatchLength;\n\t }\n\t }\n\t },\n\n\t _updateOuterRangesLength: function () {\n\t var that = this;\n\t var ranges = that._ranges || [];\n\t var rangesLength = ranges.length;\n\t var mismatchLength = 0;\n\t var range;\n\t var i;\n\t var prevRange;\n\t var rangeLength;\n\n\t for (i = 0; i < rangesLength; i++) {\n\t range = ranges[i];\n\t rangeLength = that._isGroupPaged() ? that._calculateGroupsTotal(range.data, true, \"items\", true) : that._flatData(range.data, true).length;\n\n\t if (prevRange) {\n\t if (prevRange.end != range.start) {\n\t mismatchLength = range.start - prevRange.end;\n\t }\n\t range.outerStart = prevRange.outerEnd + mismatchLength;\n\t mismatchLength = 0;\n\t } else {\n\t range.outerStart = range.start;\n\t }\n\n\t range.outerEnd = range.outerStart + rangeLength;\n\t prevRange = range;\n\t }\n\t }\n\t });\n\n\t var Transport = {};\n\n\t Transport.create = function(options, data, dataSource) {\n\t var transport,\n\t transportOptions = options.transport ? $.extend({}, options.transport) : null;\n\n\t if (transportOptions) {\n\t transportOptions.read = typeof transportOptions.read === STRING ? { url: transportOptions.read } : transportOptions.read;\n\n\t if (options.type === \"jsdo\") {\n\t transportOptions.dataSource = dataSource;\n\t }\n\n\t if (options.type) {\n\t kendo.data.transports = kendo.data.transports || {};\n\t kendo.data.schemas = kendo.data.schemas || {};\n\n\t if (!kendo.data.transports[options.type]) {\n\t kendo.logToConsole(\"Unknown DataSource transport type '\" + options.type + \"'.\\nVerify that registration scripts for this type are included after Kendo UI on the page.\", \"warn\");\n\t } else if (!isPlainObject(kendo.data.transports[options.type])) {\n\t transport = new kendo.data.transports[options.type](extend(transportOptions, { data: data }));\n\t } else {\n\t transportOptions = extend(true, {}, kendo.data.transports[options.type], transportOptions);\n\t }\n\n\t options.schema = extend(true, {}, kendo.data.schemas[options.type], options.schema);\n\t }\n\n\t if (!transport) {\n\t transport = isFunction(transportOptions.read) ? transportOptions : new RemoteTransport(transportOptions);\n\t }\n\t } else {\n\t transport = new LocalTransport({ data: options.data || [] });\n\t }\n\t return transport;\n\t };\n\n\t DataSource.create = function(options) {\n\t if (isArray(options) || options instanceof ObservableArray) {\n\t options = { data: options };\n\t }\n\n\t var dataSource = options || {},\n\t data = dataSource.data,\n\t fields = dataSource.fields,\n\t table = dataSource.table,\n\t select = dataSource.select,\n\t idx,\n\t length,\n\t model = {},\n\t field;\n\n\t if (!data && fields && !dataSource.transport) {\n\t if (table) {\n\t data = inferTable(table, fields);\n\t } else if (select) {\n\t data = inferSelect(select, fields);\n\n\t if (dataSource.group === undefined && data[0] && data[0].optgroup !== undefined) {\n\t dataSource.group = \"optgroup\";\n\t }\n\t }\n\t }\n\n\t if (kendo.data.Model && fields && (!dataSource.schema || !dataSource.schema.model)) {\n\t for (idx = 0, length = fields.length; idx < length; idx++) {\n\t field = fields[idx];\n\t if (field.type) {\n\t model[field.field] = field;\n\t }\n\t }\n\n\t if (!isEmptyObject(model)) {\n\t dataSource.schema = extend(true, dataSource.schema, { model: { fields: model } });\n\t }\n\t }\n\n\t dataSource.data = data;\n\n\t select = null;\n\t dataSource.select = null;\n\t table = null;\n\t dataSource.table = null;\n\n\t return dataSource instanceof DataSource ? dataSource : new DataSource(dataSource);\n\t };\n\n\t function inferSelect(select, fields) {\n\t select = $(select)[0];\n\t var options = select.options;\n\t var firstField = fields[0];\n\t var secondField = fields[1];\n\n\t var data = [];\n\t var idx, length;\n\t var optgroup;\n\t var option;\n\t var record;\n\t var value;\n\n\t for (idx = 0, length = options.length; idx < length; idx++) {\n\t record = {};\n\t option = options[idx];\n\t optgroup = option.parentNode;\n\n\t if (optgroup === select) {\n\t optgroup = null;\n\t }\n\n\t if (option.disabled || (optgroup && optgroup.disabled)) {\n\t continue;\n\t }\n\n\t if (optgroup) {\n\t record.optgroup = optgroup.label;\n\t }\n\n\t record[firstField.field] = option.text;\n\n\t value = option.attributes.value;\n\n\t if (value && value.specified) {\n\t value = option.value;\n\t } else {\n\t value = option.text;\n\t }\n\n\t record[secondField.field] = value;\n\n\t data.push(record);\n\t }\n\n\t return data;\n\t }\n\n\t function inferTable(table, fields) {\n\t var tbody = $(table)[0].tBodies[0],\n\t rows = tbody ? tbody.rows : [],\n\t idx,\n\t length,\n\t fieldIndex,\n\t fieldCount = fields.length,\n\t data = [],\n\t cells,\n\t record,\n\t cell,\n\t empty;\n\n\t for (idx = 0, length = rows.length; idx < length; idx++) {\n\t record = {};\n\t empty = true;\n\t cells = rows[idx].cells;\n\n\t for (fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {\n\t cell = cells[fieldIndex];\n\t if(cell.nodeName.toLowerCase() !== \"th\") {\n\t empty = false;\n\t record[fields[fieldIndex].field] = cell.innerHTML;\n\t }\n\t }\n\t if(!empty) {\n\t data.push(record);\n\t }\n\t }\n\n\t return data;\n\t }\n\n\t var Node = Model.define({\n\t idField: \"id\",\n\n\t init: function(value) {\n\t var that = this,\n\t hasChildren = that.hasChildren || value && value.hasChildren,\n\t childrenField = \"items\",\n\t childrenOptions = {};\n\n\t kendo.data.Model.fn.init.call(that, value);\n\n\t if (typeof that.children === STRING) {\n\t childrenField = that.children;\n\t }\n\n\t childrenOptions = {\n\t schema: {\n\t data: childrenField,\n\t model: {\n\t hasChildren: hasChildren,\n\t id: that.idField,\n\t fields: that.fields\n\t }\n\t }\n\t };\n\n\t if (typeof that.children !== STRING) {\n\t extend(childrenOptions, that.children);\n\t }\n\n\t childrenOptions.data = value;\n\n\t if (!hasChildren) {\n\t hasChildren = childrenOptions.schema.data;\n\t }\n\n\t if (typeof hasChildren === STRING) {\n\t hasChildren = kendo.getter(hasChildren);\n\t }\n\n\t if (isFunction(hasChildren)) {\n\t var hasChildrenObject = hasChildren.call(that, that);\n\n\t if(hasChildrenObject && hasChildrenObject.length === 0){\n\t that.hasChildren = false;\n\t } else{\n\t that.hasChildren = !!hasChildrenObject;\n\t }\n\t }\n\n\t that._childrenOptions = childrenOptions;\n\n\t if (that.hasChildren) {\n\t that._initChildren();\n\t }\n\n\t that._loaded = !!(value && value._loaded);\n\t },\n\n\t _initChildren: function() {\n\t var that = this;\n\t var children, transport, parameterMap;\n\n\t if (!(that.children instanceof HierarchicalDataSource)) {\n\t children = that.children = new HierarchicalDataSource(that._childrenOptions);\n\n\t transport = children.transport;\n\t parameterMap = transport.parameterMap;\n\n\t transport.parameterMap = function(data, type) {\n\t data[that.idField || \"id\"] = that.id;\n\n\t if (parameterMap) {\n\t data = parameterMap.call(that, data, type);\n\t }\n\n\t return data;\n\t };\n\n\t children.parent = function(){\n\t return that;\n\t };\n\n\t children.bind(CHANGE, function(e){\n\t e.node = e.node || that;\n\t that.trigger(CHANGE, e);\n\t });\n\n\t children.bind(ERROR, function(e){\n\t var collection = that.parent();\n\n\t if (collection) {\n\t e.node = e.node || that;\n\t collection.trigger(ERROR, e);\n\t }\n\t });\n\n\t that._updateChildrenField();\n\t }\n\t },\n\n\t append: function(model) {\n\t this._initChildren();\n\t this.loaded(true);\n\t this.children.add(model);\n\t },\n\n\t hasChildren: false,\n\n\t level: function() {\n\t var parentNode = this.parentNode(),\n\t level = 0;\n\n\t while (parentNode && parentNode.parentNode) {\n\t level++;\n\t parentNode = parentNode.parentNode ? parentNode.parentNode() : null;\n\t }\n\n\t return level;\n\t },\n\n\t _updateChildrenField: function() {\n\t var fieldName = this._childrenOptions.schema.data;\n\n\t this[fieldName || \"items\"] = this.children.data();\n\t },\n\n\t _childrenLoaded: function() {\n\t this._loaded = true;\n\n\t this._updateChildrenField();\n\t },\n\n\t load: function() {\n\t var options = {};\n\t var method = \"_query\";\n\t var children, promise;\n\n\t if (this.hasChildren) {\n\t this._initChildren();\n\n\t children = this.children;\n\n\t options[this.idField || \"id\"] = this.id;\n\n\t if (!this._loaded) {\n\t children._data = undefined;\n\t method = \"read\";\n\t }\n\n\t children.one(CHANGE, proxy(this._childrenLoaded, this));\n\n\t if(this._matchFilter){\n\t options.filter = { field: '_matchFilter', operator: 'eq', value: true };\n\t }\n\n\t promise = children[method](options);\n\t } else {\n\t this.loaded(true);\n\t }\n\n\t return promise || $.Deferred().resolve().promise();\n\t },\n\n\t parentNode: function() {\n\t var array = this.parent();\n\n\t return array.parent();\n\t },\n\n\t loaded: function(value) {\n\t if (value !== undefined) {\n\t this._loaded = value;\n\t } else {\n\t return this._loaded;\n\t }\n\t },\n\n\t shouldSerialize: function(field) {\n\t return Model.fn.shouldSerialize.call(this, field) &&\n\t field !== \"children\" &&\n\t field !== \"_loaded\" &&\n\t field !== \"hasChildren\" &&\n\t field !== \"_childrenOptions\";\n\t }\n\t });\n\n\t function dataMethod(name) {\n\t return function() {\n\t var data = this._data,\n\t result = DataSource.fn[name].apply(this, slice.call(arguments));\n\n\t if (this._data != data) {\n\t this._attachBubbleHandlers();\n\t }\n\n\t return result;\n\t };\n\t }\n\n\t var HierarchicalDataSource = DataSource.extend({\n\t init: function(options) {\n\t var node = Node.define({\n\t children: options\n\t });\n\n\t if(options.filter && !options.serverFiltering){\n\t this._hierarchicalFilter = options.filter;\n\t options.filter = null;\n\t }\n\n\t DataSource.fn.init.call(this, extend(true, {}, { schema: { modelBase: node, model: node } }, options));\n\n\t this._attachBubbleHandlers();\n\t },\n\n\t _attachBubbleHandlers: function() {\n\t var that = this;\n\n\t that._data.bind(ERROR, function(e) {\n\t that.trigger(ERROR, e);\n\t });\n\t },\n\n\t read: function(data) {\n\t var result = DataSource.fn.read.call(this, data);\n\n\t if(this._hierarchicalFilter){\n\t if(this._data && this._data.length > 0){\n\t this.filter(this._hierarchicalFilter);\n\t }else{\n\t this.options.filter = this._hierarchicalFilter;\n\t this._filter = normalizeFilter(this.options.filter);\n\t this._hierarchicalFilter = null;\n\t }\n\t }\n\n\t return result;\n\t },\n\n\t remove: function(node){\n\t var parentNode = node.parentNode(),\n\t dataSource = this,\n\t result;\n\n\t if (parentNode && parentNode._initChildren) {\n\t dataSource = parentNode.children;\n\t }\n\n\t result = DataSource.fn.remove.call(dataSource, node);\n\n\t if (parentNode && !dataSource.data().length) {\n\t parentNode.hasChildren = false;\n\t }\n\n\t return result;\n\t },\n\n\t success: dataMethod(\"success\"),\n\n\t data: dataMethod(\"data\"),\n\n\t insert: function(index, model) {\n\t var parentNode = this.parent();\n\n\t if (parentNode && parentNode._initChildren) {\n\t parentNode.hasChildren = true;\n\t parentNode._initChildren();\n\t }\n\n\t return DataSource.fn.insert.call(this, index, model);\n\t },\n\n\t filter: function(val) {\n\t if (val === undefined) {\n\t return this._filter;\n\t }\n\n\t if(!this.options.serverFiltering && this._markHierarchicalQuery(val)){\n\t val = { logic: \"or\", filters: [val, {field:'_matchFilter', operator: 'equals', value: true }]};\n\t }\n\n\t this.trigger(\"reset\");\n\t this._query({ filter: val, page: 1 });\n\t },\n\n\t _markHierarchicalQuery: function(expressions){\n\t var compiled;\n\t var predicate;\n\t var fields;\n\t var operators;\n\t var filter;\n\t var accentFoldingFiltering = this.options.accentFoldingFiltering;\n\n\t expressions = accentFoldingFiltering ? $.extend({}, normalizeFilter(expressions), { accentFoldingFiltering: accentFoldingFiltering}) : normalizeFilter(expressions);\n\n\t if (!expressions || expressions.filters.length === 0) {\n\t this._updateHierarchicalFilter(function(){return true;});\n\t return false;\n\t }\n\n\t compiled = Query.filterExpr(expressions);\n\t fields = compiled.fields;\n\t operators = compiled.operators;\n\n\t predicate = filter = new Function(\"d, __f, __o\", \"return \" + compiled.expression);\n\n\t if (fields.length || operators.length) {\n\t filter = function(d) {\n\t return predicate(d, fields, operators);\n\t };\n\t }\n\n\t this._updateHierarchicalFilter(filter);\n\t return true;\n\t },\n\n\t _updateHierarchicalFilter: function(filter){\n\t var current;\n\t var data = this._data;\n\t var result = false;\n\n\t for (var idx = 0; idx < data.length; idx++) {\n\t current = data[idx];\n\n\t if(current.hasChildren){\n\t current._matchFilter = current.children._updateHierarchicalFilter(filter);\n\t if(!current._matchFilter){\n\t current._matchFilter = filter(current);\n\t }\n\t }else{\n\t current._matchFilter = filter(current);\n\t }\n\n\t if(current._matchFilter){\n\t result = true;\n\t }\n\t }\n\t return result;\n\t },\n\n\t _find: function(method, value) {\n\t var idx, length, node, children;\n\t var data = this._data;\n\n\t if (!data) {\n\t return;\n\t }\n\n\t node = DataSource.fn[method].call(this, value);\n\n\t if (node) {\n\t return node;\n\t }\n\n\t data = this._flatData(this._data);\n\n\t for (idx = 0, length = data.length; idx < length; idx++) {\n\t children = data[idx].children;\n\n\t if (!(children instanceof HierarchicalDataSource)) {\n\t continue;\n\t }\n\n\t node = children[method](value);\n\n\t if (node) {\n\t return node;\n\t }\n\t }\n\t },\n\n\t get: function(id) {\n\t return this._find(\"get\", id);\n\t },\n\n\t getByUid: function(uid) {\n\t return this._find(\"getByUid\", uid);\n\t }\n\t });\n\n\t function inferList(list, fields) {\n\t var items = $(list).children(),\n\t idx,\n\t length,\n\t data = [],\n\t record,\n\t textField = fields[0].field,\n\t urlField = fields[1] && fields[1].field,\n\t spriteCssClassField = fields[2] && fields[2].field,\n\t imageUrlField = fields[3] && fields[3].field,\n\t item,\n\t id,\n\t textChild,\n\t className,\n\t children;\n\n\t function elements(collection, tagName) {\n\t return collection.filter(tagName).add(collection.find(tagName));\n\t }\n\n\t for (idx = 0, length = items.length; idx < length; idx++) {\n\t record = { _loaded: true };\n\t item = items.eq(idx);\n\n\t textChild = item[0].firstChild;\n\t children = item.children();\n\t list = children.filter(\"ul\");\n\t children = children.filter(\":not(ul)\");\n\n\t id = item.attr(\"data-id\");\n\n\t if (id) {\n\t record.id = id;\n\t }\n\n\t if (textChild) {\n\t record[textField] = textChild.nodeType == 3 ? textChild.nodeValue : children.text();\n\t }\n\n\t if (urlField) {\n\t record[urlField] = elements(children, \"a\").attr(\"href\");\n\t }\n\n\t if (imageUrlField) {\n\t record[imageUrlField] = elements(children, \"img\").attr(\"src\");\n\t }\n\n\t if (spriteCssClassField) {\n\t className = elements(children, \".k-sprite\").prop(\"className\");\n\t record[spriteCssClassField] = className && kendo.trim(className.replace(\"k-sprite\", \"\"));\n\t }\n\n\t if (list.length) {\n\t record.items = inferList(list.eq(0), fields);\n\t }\n\n\t if (item.attr(\"data-hasChildren\") == \"true\") {\n\t record.hasChildren = true;\n\t }\n\n\t data.push(record);\n\t }\n\n\t return data;\n\t }\n\n\t HierarchicalDataSource.create = function(options) {\n\t options = options && options.push ? { data: options } : options;\n\n\t var dataSource = options || {},\n\t data = dataSource.data,\n\t fields = dataSource.fields,\n\t list = dataSource.list;\n\n\t if (data && data._dataSource) {\n\t return data._dataSource;\n\t }\n\n\t if (!data && fields && !dataSource.transport) {\n\t if (list) {\n\t data = inferList(list, fields);\n\t }\n\t }\n\n\t dataSource.data = data;\n\n\t return dataSource instanceof HierarchicalDataSource ? dataSource : new HierarchicalDataSource(dataSource);\n\t };\n\n\t var Buffer = kendo.Observable.extend({\n\t init: function(dataSource, viewSize, disablePrefetch) {\n\t kendo.Observable.fn.init.call(this);\n\n\t this._prefetching = false;\n\t this.dataSource = dataSource;\n\t this.prefetch = !disablePrefetch;\n\n\t var buffer = this;\n\n\t dataSource.bind(\"change\", function() {\n\t buffer._change();\n\t });\n\n\t dataSource.bind(\"reset\", function() {\n\t buffer._reset();\n\t });\n\n\t this._syncWithDataSource();\n\n\t this.setViewSize(viewSize);\n\t },\n\n\t setViewSize: function(viewSize) {\n\t this.viewSize = viewSize;\n\t this._recalculate();\n\t },\n\n\t at: function(index) {\n\t var pageSize = this.pageSize,\n\t itemPresent = true;\n\n\t if (index >= this.total()) {\n\t this.trigger(\"endreached\", {index: index });\n\t return null;\n\t }\n\n\t if (!this.useRanges) {\n\t return this.dataSource.view()[index];\n\t }\n\t if (this.useRanges) {\n\t // out of range request\n\t if (index < this.dataOffset || index >= this.skip + pageSize) {\n\t itemPresent = this.range(Math.floor(index / pageSize) * pageSize);\n\t }\n\n\t // prefetch\n\t if (index === this.prefetchThreshold) {\n\t this._prefetch();\n\t }\n\n\t // mid-range jump - prefetchThreshold and nextPageThreshold may be equal, do not change to else if\n\t if (index === this.midPageThreshold) {\n\t this.range(this.nextMidRange, true);\n\t }\n\t // next range jump\n\t else if (index === this.nextPageThreshold) {\n\t this.range(this.nextFullRange);\n\t }\n\t // pull-back\n\t else if (index === this.pullBackThreshold) {\n\t if (this.offset === this.skip) { // from full range to mid range\n\t this.range(this.previousMidRange);\n\t } else { // from mid range to full range\n\t this.range(this.previousFullRange);\n\t }\n\t }\n\n\t if (itemPresent) {\n\t return this.dataSource.at(index - this.dataOffset);\n\t } else {\n\t this.trigger(\"endreached\", { index: index });\n\t return null;\n\t }\n\t }\n\t },\n\n\t indexOf: function(item) {\n\t return this.dataSource.data().indexOf(item) + this.dataOffset;\n\t },\n\n\t total: function() {\n\t return parseInt(this.dataSource.total(), 10);\n\t },\n\n\t next: function() {\n\t var buffer = this,\n\t pageSize = buffer.pageSize,\n\t offset = buffer.skip - buffer.viewSize + pageSize,\n\t pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize;\n\n\t this.offset = offset;\n\t this.dataSource.prefetch(pageSkip, pageSize, function() {\n\t buffer._goToRange(offset, true);\n\t });\n\t },\n\n\t range: function(offset, nextRange) {\n\t if (this.offset === offset) {\n\t return true;\n\t }\n\n\t var buffer = this,\n\t pageSize = this.pageSize,\n\t pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize,\n\t dataSource = this.dataSource;\n\n\t if (nextRange) {\n\t pageSkip += pageSize;\n\t }\n\n\t if (dataSource.inRange(offset, pageSize)) {\n\t this.offset = offset;\n\t this._recalculate();\n\t this._goToRange(offset);\n\t return true;\n\t } else if (this.prefetch) {\n\t dataSource.prefetch(pageSkip, pageSize, function() {\n\t buffer.offset = offset;\n\t buffer._recalculate();\n\t buffer._goToRange(offset, true);\n\t });\n\t return false;\n\t }\n\n\t return true;\n\t },\n\n\t syncDataSource: function() {\n\t var offset = this.offset;\n\t this.offset = null;\n\t this.range(offset);\n\t },\n\n\t destroy: function() {\n\t this.unbind();\n\t },\n\n\t _prefetch: function() {\n\t var buffer = this,\n\t pageSize = this.pageSize,\n\t prefetchOffset = this.skip + pageSize,\n\t dataSource = this.dataSource;\n\n\t if (!dataSource.inRange(prefetchOffset, pageSize) && !this._prefetching && this.prefetch) {\n\t this._prefetching = true;\n\t this.trigger(\"prefetching\", { skip: prefetchOffset, take: pageSize });\n\n\t dataSource.prefetch(prefetchOffset, pageSize, function() {\n\t buffer._prefetching = false;\n\t buffer.trigger(\"prefetched\", { skip: prefetchOffset, take: pageSize });\n\t });\n\t }\n\t },\n\n\t _goToRange: function(offset, expanding) {\n\t if (this.offset !== offset) {\n\t return;\n\t }\n\n\t this.dataOffset = offset;\n\t this._expanding = expanding;\n\t this.dataSource.range(offset, this.pageSize);\n\t this.dataSource.enableRequestsInProgress();\n\t },\n\n\t _reset: function() {\n\t this._syncPending = true;\n\t },\n\n\t _change: function() {\n\t var dataSource = this.dataSource;\n\n\t this.length = this.useRanges ? dataSource.lastRange().end : dataSource.view().length;\n\n\t if (this._syncPending) {\n\t this._syncWithDataSource();\n\t this._recalculate();\n\t this._syncPending = false;\n\t this.trigger(\"reset\", { offset: this.offset });\n\t }\n\n\t this.trigger(\"resize\");\n\n\t if (this._expanding) {\n\t this.trigger(\"expand\");\n\t }\n\n\t delete this._expanding;\n\t },\n\n\t _syncWithDataSource: function() {\n\t var dataSource = this.dataSource;\n\n\t this._firstItemUid = dataSource.firstItemUid();\n\t this.dataOffset = this.offset = dataSource.skip() || 0;\n\t this.pageSize = dataSource.pageSize();\n\t this.useRanges = dataSource.options.serverPaging;\n\t },\n\n\t _recalculate: function() {\n\t var pageSize = this.pageSize,\n\t offset = this.offset,\n\t viewSize = this.viewSize,\n\t skip = Math.ceil(offset / pageSize) * pageSize;\n\n\t this.skip = skip;\n\t this.midPageThreshold = skip + pageSize - 1;\n\t this.nextPageThreshold = skip + viewSize - 1;\n\t this.prefetchThreshold = skip + Math.floor(pageSize / 3 * 2);\n\t this.pullBackThreshold = this.offset - 1;\n\n\t this.nextMidRange = skip + pageSize - viewSize;\n\t this.nextFullRange = skip;\n\t this.previousMidRange = offset - viewSize;\n\t this.previousFullRange = skip - pageSize;\n\t }\n\t });\n\n\t var BatchBuffer = kendo.Observable.extend({\n\t init: function(dataSource, batchSize) {\n\t var batchBuffer = this;\n\n\t kendo.Observable.fn.init.call(batchBuffer);\n\n\t this.dataSource = dataSource;\n\t this.batchSize = batchSize;\n\t this._total = 0;\n\n\t this.buffer = new Buffer(dataSource, batchSize * 3);\n\n\t this.buffer.bind({\n\t \"endreached\": function (e) {\n\t batchBuffer.trigger(\"endreached\", { index: e.index });\n\t },\n\t \"prefetching\": function (e) {\n\t batchBuffer.trigger(\"prefetching\", { skip: e.skip, take: e.take });\n\t },\n\t \"prefetched\": function (e) {\n\t batchBuffer.trigger(\"prefetched\", { skip: e.skip, take: e.take });\n\t },\n\t \"reset\": function () {\n\t batchBuffer._total = 0;\n\t batchBuffer.trigger(\"reset\");\n\t },\n\t \"resize\": function () {\n\t batchBuffer._total = Math.ceil(this.length / batchBuffer.batchSize);\n\t batchBuffer.trigger(\"resize\", { total: batchBuffer.total(), offset: this.offset });\n\t }\n\t });\n\t },\n\n\t syncDataSource: function() {\n\t this.buffer.syncDataSource();\n\t },\n\n\t at: function(index) {\n\t var buffer = this.buffer,\n\t skip = index * this.batchSize,\n\t take = this.batchSize,\n\t view = [],\n\t item;\n\n\t if (buffer.offset > skip) {\n\t buffer.at(buffer.offset - 1);\n\t }\n\n\t for (var i = 0; i < take; i++) {\n\t item = buffer.at(skip + i);\n\n\t if (item === null) {\n\t break;\n\t }\n\n\t view.push(item);\n\t }\n\n\t return view;\n\t },\n\n\t total: function() {\n\t return this._total;\n\t },\n\n\t destroy: function() {\n\t this.buffer.destroy();\n\t this.unbind();\n\t }\n\t });\n\n\t extend(true, kendo.data, {\n\t readers: {\n\t json: DataReader\n\t },\n\t Query: Query,\n\t DataSource: DataSource,\n\t HierarchicalDataSource: HierarchicalDataSource,\n\t Node: Node,\n\t ObservableObject: ObservableObject,\n\t ObservableArray: ObservableArray,\n\t LazyObservableArray: LazyObservableArray,\n\t LocalTransport: LocalTransport,\n\t RemoteTransport: RemoteTransport,\n\t Cache: Cache,\n\t DataReader: DataReader,\n\t Model: Model,\n\t Buffer: Buffer,\n\t BatchBuffer: BatchBuffer\n\t });\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1065:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.odata\");\n\n/***/ }),\n\n/***/ 1066:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.xml\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1067);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1067:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"data.odata\",\n\t name: \"OData\",\n\t category: \"framework\",\n\t depends: [ \"core\" ],\n\t hidden: true\n\t};\n\n\t(function($, undefined) {\n\t var kendo = window.kendo,\n\t extend = $.extend,\n\t NEWLINE = \"\\r\\n\",\n\t DOUBLELINE = \"\\r\\n\\r\\n\",\n\t isFunction = kendo.isFunction,\n\t odataFilters = {\n\t eq: \"eq\",\n\t neq: \"ne\",\n\t gt: \"gt\",\n\t gte: \"ge\",\n\t lt: \"lt\",\n\t lte: \"le\",\n\t contains : \"substringof\",\n\t doesnotcontain: \"substringof\",\n\t endswith: \"endswith\",\n\t startswith: \"startswith\",\n\t isnull: \"eq\",\n\t isnotnull: \"ne\",\n\t isnullorempty: \"eq\",\n\t isnotnullorempty: \"ne\",\n\t isempty: \"eq\",\n\t isnotempty: \"ne\"\n\t },\n\t odataFiltersVersionFour = extend({}, odataFilters, {\n\t contains: \"contains\"\n\t }),\n\t mappers = {\n\t pageSize: $.noop,\n\t page: $.noop,\n\t filter: function(params, filter, useVersionFour) {\n\t if (filter) {\n\t filter = toOdataFilter(filter, useVersionFour);\n\t if (filter) {\n\t params.$filter = filter;\n\t }\n\t }\n\t },\n\t sort: function(params, orderby) {\n\t var expr = $.map(orderby, function(value) {\n\t var order = value.field.replace(/\\./g, \"/\");\n\n\t if (value.dir === \"desc\") {\n\t order += \" desc\";\n\t }\n\n\t return order;\n\t }).join(\",\");\n\n\t if (expr) {\n\t params.$orderby = expr;\n\t }\n\t },\n\t skip: function(params, skip) {\n\t if (skip) {\n\t params.$skip = skip;\n\t }\n\t },\n\t take: function(params, take) {\n\t if (take) {\n\t params.$top = take;\n\t }\n\t }\n\t },\n\t defaultDataType = {\n\t read: {\n\t dataType: \"jsonp\"\n\t }\n\t };\n\n\t function toOdataFilter(filter, useOdataFour) {\n\t var result = [],\n\t logic = filter.logic || \"and\",\n\t idx,\n\t length,\n\t field,\n\t type,\n\t format,\n\t operator,\n\t value,\n\t ignoreCase,\n\t filters = filter.filters;\n\n\t for (idx = 0, length = filters.length; idx < length; idx++) {\n\t filter = filters[idx];\n\t field = filter.field;\n\t value = filter.value;\n\t operator = filter.operator;\n\n\t if (filter.filters) {\n\t filter = toOdataFilter(filter, useOdataFour);\n\t } else {\n\t ignoreCase = filter.ignoreCase;\n\t field = field.replace(/\\./g, \"/\");\n\t filter = odataFilters[operator];\n\t if (useOdataFour) {\n\t filter = odataFiltersVersionFour[operator];\n\t }\n\n\t if (operator === \"isnullorempty\") {\n\t filter = kendo.format(\"{0} {1} null or {0} {1} ''\", field, filter);\n\t } else if(operator === \"isnotnullorempty\") {\n\t filter = kendo.format(\"{0} {1} null and {0} {1} ''\", field, filter);\n\t } else if (operator === \"isnull\" || operator === \"isnotnull\") {\n\t filter = kendo.format(\"{0} {1} null\", field, filter);\n\t } else if (operator === \"isempty\" || operator === \"isnotempty\") {\n\t filter = kendo.format(\"{0} {1} ''\", field, filter);\n\t } else if (filter && value !== undefined) {\n\t type = $.type(value);\n\t if (type === \"string\") {\n\t format = \"'{1}'\";\n\t value = value.replace(/'/g, \"''\");\n\n\t if (ignoreCase === true) {\n\t field = \"tolower(\" + field + \")\";\n\t }\n\n\t } else if (type === \"date\") {\n\t if (useOdataFour) {\n\t format = \"{1:yyyy-MM-ddTHH:mm:ss+00:00}\";\n\t value = kendo.timezone.apply(value, 'Etc/UTC');\n\t } else {\n\t format = \"datetime'{1:yyyy-MM-ddTHH:mm:ss}'\";\n\t }\n\t } else {\n\t format = \"{1}\";\n\t }\n\n\t if (filter.length > 3) {\n\t if (filter !== \"substringof\") {\n\t format = \"{0}({2},\" + format + \")\";\n\t } else {\n\t format = \"{0}(\" + format + \",{2})\";\n\t if (operator === \"doesnotcontain\") {\n\t if (useOdataFour) {\n\t format = \"{0}({2},'{1}') eq -1\";\n\t filter = \"indexof\";\n\t } else {\n\t format += \" eq false\";\n\t }\n\t }\n\t }\n\t } else {\n\t format = \"{2} {0} \" + format;\n\t }\n\n\t filter = kendo.format(format, filter, value, field);\n\t }\n\t }\n\n\t result.push(filter);\n\t }\n\n\t filter = result.join(\" \" + logic + \" \");\n\n\t if (result.length > 1) {\n\t filter = \"(\" + filter + \")\";\n\t }\n\n\t return filter;\n\t }\n\n\t function stripMetadata(obj) {\n\t for (var name in obj) {\n\t if(name.indexOf(\"@odata\") === 0) {\n\t delete obj[name];\n\t }\n\t }\n\t }\n\n\t function hex16() {\n\t return Math.floor((1 + Math.random()) * 0x10000).toString(16).substr(1);\n\t }\n\n\t function createBoundary(prefix) {\n\t return prefix + hex16() + '-' + hex16() + '-' + hex16();\n\t }\n\n\t function createDelimeter(boundary, close) {\n\t var result = NEWLINE + \"--\" + boundary;\n\n\t if (close) {\n\t result += \"--\";\n\t }\n\n\t return result;\n\t }\n\n\t function createCommand(transport, item, httpVerb, command) {\n\t var transportUrl = transport.options[command].url;\n\t var commandPrefix = kendo.format(\"{0} \", httpVerb);\n\n\t if (isFunction(transportUrl)) {\n\t return commandPrefix + transportUrl(item);\n\t } else {\n\t return commandPrefix + transportUrl;\n\t }\n\t }\n\n\t function getOperationHeader(changeset, changeId) {\n\t var header = \"\";\n\n\t header += createDelimeter(changeset, false);\n\t header += NEWLINE + 'Content-Type: application/http';\n\t header += NEWLINE + 'Content-Transfer-Encoding: binary';\n\t header += NEWLINE + 'Content-ID: ' + changeId;\n\n\t return header;\n\t }\n\n\t function getOperationContent(item) {\n\t var content = \"\";\n\n\t content += NEWLINE + \"Content-Type: application/json;odata=minimalmetadata\";\n\t content += NEWLINE + \"Prefer: return=representation\";\n\t content += DOUBLELINE + kendo.stringify(item);\n\n\t return content;\n\t }\n\n\t function getOperations(collection, changeset, changeId, command, transport, skipContent) {\n\t var requestBody = \"\";\n\n\t for (var i = 0; i < collection.length; i++) {\n\t requestBody += getOperationHeader(changeset, changeId);\n\t requestBody += DOUBLELINE + createCommand(transport, collection[i], transport.options[command].type, command) + ' HTTP/1.1';\n\t if (!skipContent) {\n\t requestBody += getOperationContent(collection[i]);\n\t }\n\t requestBody += NEWLINE;\n\t changeId++;\n\t }\n\n\t return requestBody;\n\t }\n\n\t function processCollection(colection, boundary, changeset, changeId, transport, command, skipContent) {\n\t var requestBody = \"\";\n\n\t requestBody += getBoundary(boundary, changeset);\n\t requestBody += getOperations(colection, changeset, changeId, command, transport, skipContent);\n\t requestBody += createDelimeter(changeset, true);\n\t requestBody += NEWLINE;\n\n\t return requestBody;\n\t }\n\n\t function getBoundary(boundary,changeset) {\n\t var requestBody = \"\";\n\n\t requestBody += \"--\" + boundary + NEWLINE;\n\t requestBody += \"Content-Type: multipart/mixed; boundary=\" + changeset + NEWLINE;\n\n\t return requestBody;\n\t }\n\n\t function createBatchRequest(transport, colections) {\n\t var options = {};\n\t var boundary = createBoundary(\"sf_batch_\");\n\t var requestBody = \"\";\n\t var changeId = 0;\n\t var batchURL = transport.options.batch.url;\n\t var changeset = createBoundary(\"sf_changeset_\");\n\n\t options.type = transport.options.batch.type;\n\t options.url = isFunction(batchURL) ? batchURL() : batchURL;\n\t options.headers = {\n\t \"Content-Type\": \"multipart/mixed; boundary=\" + boundary\n\t };\n\n\t if (colections.updated.length) {\n\t requestBody += processCollection(colections.updated, boundary, changeset, changeId, transport, \"update\", false);\n\t changeId += colections.updated.length;\n\t changeset = createBoundary(\"sf_changeset_\");\n\t }\n\n\t if (colections.destroyed.length) {\n\t requestBody += processCollection(colections.destroyed, boundary, changeset, changeId, transport, \"destroy\", true);\n\t changeId += colections.destroyed.length;\n\t changeset = createBoundary(\"sf_changeset_\");\n\t }\n\n\t if (colections.created.length) {\n\t requestBody += processCollection(colections.created, boundary, changeset, changeId, transport, \"create\", false);\n\t }\n\n\t requestBody += createDelimeter(boundary, true);\n\n\t options.data = requestBody;\n\n\t return options;\n\t }\n\n\t function parseBatchResponse(responseText) {\n\t var responseMarkers = responseText.match(/--changesetresponse_[a-z0-9-]+$/gm);\n\t var markerIndex = 0;\n\t var collections = [];\n\t var changeBody;\n\t var status;\n\t var code;\n\t var marker;\n\t var jsonModel;\n\n\t collections.push({ models: [], passed: true });\n\n\t for (var i = 0; i < responseMarkers.length; i++) {\n\t marker = responseMarkers[i];\n\t if (marker.lastIndexOf('--', marker.length - 1)) {\n\t if (i < responseMarkers.length - 1) {\n\t collections.push({ models: [], passed: true });\n\t }\n\t continue;\n\t }\n\n\t if (!markerIndex) {\n\t markerIndex = responseText.indexOf(marker);\n\t } else {\n\t markerIndex = responseText.indexOf(marker, markerIndex + marker.length);\n\t }\n\n\t changeBody = responseText.substring(markerIndex, responseText.indexOf(\"--\", markerIndex + 1));\n\t status = changeBody.match(/^HTTP\\/1\\.\\d (\\d{3}) (.*)$/gm).pop();\n\t code = kendo.parseFloat(status.match(/\\d{3}/g).pop());\n\n\t if (code >= 200 && code <= 299) {\n\t jsonModel = changeBody.match(/\\{.*\\}/gm);\n\t if (jsonModel) {\n\t collections[collections.length - 1].models.push(JSON.parse(jsonModel[0]));\n\t }\n\t } else {\n\t collections[collections.length - 1].passed = false;\n\t }\n\n\t }\n\n\t return collections;\n\t }\n\n\t extend(true, kendo.data, {\n\t schemas: {\n\t odata: {\n\t type: \"json\",\n\t data: function(data) {\n\t return data.d.results || [data.d];\n\t },\n\t total: \"d.__count\"\n\t }\n\t },\n\t transports: {\n\t odata: {\n\t read: {\n\t cache: true, // to prevent jQuery from adding cache buster\n\t dataType: \"jsonp\",\n\t jsonp: \"$callback\"\n\t },\n\t update: {\n\t cache: true,\n\t dataType: \"json\",\n\t contentType: \"application/json\", // to inform the server the the request body is JSON encoded\n\t type: \"PUT\" // can be PUT or MERGE\n\t },\n\t create: {\n\t cache: true,\n\t dataType: \"json\",\n\t contentType: \"application/json\",\n\t type: \"POST\" // must be POST to create new entity\n\t },\n\t destroy: {\n\t cache: true,\n\t dataType: \"json\",\n\t type: \"DELETE\"\n\t },\n\t parameterMap: function(options, type, useVersionFour) {\n\t var params,\n\t value,\n\t option,\n\t dataType;\n\n\t options = options || {};\n\t type = type || \"read\";\n\t dataType = (this.options || defaultDataType)[type];\n\t dataType = dataType ? dataType.dataType : \"json\";\n\n\t if (type === \"read\") {\n\t params = {\n\t $inlinecount: \"allpages\"\n\t };\n\n\t if (dataType != \"json\") {\n\t params.$format = \"json\";\n\t }\n\n\t for (option in options) {\n\t if (mappers[option]) {\n\t mappers[option](params, options[option], useVersionFour);\n\t } else {\n\t params[option] = options[option];\n\t }\n\t }\n\t } else {\n\t if (dataType !== \"json\") {\n\t throw new Error(\"Only json dataType can be used for \" + type + \" operation.\");\n\t }\n\n\t if (type !== \"destroy\") {\n\t for (option in options) {\n\t value = options[option];\n\t if (typeof value === \"number\") {\n\t options[option] = value + \"\";\n\t }\n\t }\n\n\t params = kendo.stringify(options);\n\t }\n\t }\n\n\t return params;\n\t }\n\t }\n\t }\n\t });\n\n\t extend(true, kendo.data, {\n\t schemas: {\n\t \"odata-v4\": {\n\t type: \"json\",\n\t data: function(data) {\n\t if ($.isArray(data)) {\n\t for (var i = 0; i < data.length; i++) {\n\t stripMetadata(data[i]);\n\t }\n\t return data;\n\t } else {\n\t data = $.extend({}, data);\n\t stripMetadata(data);\n\n\t if (data.value) {\n\t return data.value;\n\t }\n\t return [data];\n\t }\n\t },\n\t total: function(data) {\n\t return data[\"@odata.count\"];\n\t }\n\t }\n\t },\n\t transports: {\n\t \"odata-v4\": {\n\t batch: {\n\t type: \"POST\"\n\t },\n\t read: {\n\t cache: true, // to prevent jQuery from adding cache buster\n\t dataType: \"json\"\n\t },\n\t update: {\n\t cache: true,\n\t dataType: \"json\",\n\t contentType: \"application/json;IEEE754Compatible=true\", // to inform the server the the request body is JSON encoded\n\t type: \"PUT\" // can be PUT or MERGE\n\t },\n\t create: {\n\t cache: true,\n\t dataType: \"json\",\n\t contentType: \"application/json;IEEE754Compatible=true\",\n\t type: \"POST\" // must be POST to create new entity\n\t },\n\t destroy: {\n\t cache: true,\n\t dataType: \"json\",\n\t type: \"DELETE\"\n\t },\n\t parameterMap: function(options, type) {\n\t var result = kendo.data.transports.odata.parameterMap(options, type, true);\n\t if (type == \"read\") {\n\t result.$count = true;\n\t delete result.$inlinecount;\n\t }\n\n\t return result;\n\t },\n\t submit: function(e) {\n\t var that = this;\n\t var options = createBatchRequest(that, e.data);\n\t var collections = e.data;\n\n\t if (!collections.updated.length && !collections.destroyed.length && !collections.created.length) {\n\t return;\n\t }\n\n\t $.ajax(extend(true, {}, {\n\t success: function (response) {\n\t var responses = parseBatchResponse(response);\n\t var index = 0;\n\t var current;\n\n\t if (collections.updated.length) {\n\t current = responses[index];\n\t if (current.passed) {\n\t // Pass either the obtained models or an empty array if only status codes are returned.\n\t e.success(current.models.length ? current.models : [], \"update\");\n\t }\n\t index++;\n\t }\n\t if (collections.destroyed.length) {\n\t current = responses[index];\n\t if (current.passed) {\n\t // For delete operations OData returns only status codes.\n\t // Passing empty array to datasource will force it to correctly remove the deleted items from the pristine collection.\n\t e.success([], \"destroy\");\n\t }\n\t index++;\n\t }\n\t if (collections.created.length) {\n\t current = responses[index];\n\t if (current.passed) {\n\t e.success(current.models, \"create\");\n\t }\n\t }\n\t },\n\t error: function (response, status, error) {\n\t e.error(response, status, error);\n\t }\n\t }, options));\n\t }\n\t }\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1068);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1027:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data\");\n\n/***/ }),\n\n/***/ 1068:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\r\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1027) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n\t})(function(){\r\n\r\n\tvar __meta__ = { // jshint ignore:line\r\n\t id: \"data.signalr\",\r\n\t name: \"SignalR\",\r\n\t category: \"framework\",\r\n\t depends: [ \"data\" ],\r\n\t hidden: true\r\n\t};\r\n\r\n\t(function($) {\r\n\t var kendo = window.kendo;\r\n\t var isFunction = kendo.isFunction;\r\n\r\n\t function isJQueryPromise(promise) {\r\n\t return promise && isFunction(promise.done) && isFunction(promise.fail);\r\n\t }\r\n\r\n\t function isNativePromise(promise) {\r\n\t return promise && isFunction(promise.then) && isFunction(promise.catch); // jshint ignore:line\r\n\t }\r\n\r\n\t var transport = kendo.data.RemoteTransport.extend({\r\n\t init: function (options) {\r\n\t var signalr = options && options.signalr ? options.signalr : {};\r\n\r\n\t var promise = signalr.promise;\r\n\r\n\t if (!promise) {\r\n\t throw new Error('The \"promise\" option must be set.');\r\n\t }\r\n\r\n\t if (!isJQueryPromise(promise) && !isNativePromise(promise)) {\r\n\t throw new Error('The \"promise\" option must be a Promise.');\r\n\t }\r\n\r\n\t this.promise = promise;\r\n\r\n\t var hub = signalr.hub;\r\n\r\n\t if (!hub) {\r\n\t throw new Error('The \"hub\" option must be set.');\r\n\t }\r\n\r\n\t if (typeof hub.on != \"function\" || typeof hub.invoke != \"function\") {\r\n\t throw new Error('The \"hub\" option is not a valid SignalR hub proxy.');\r\n\t }\r\n\r\n\t this.hub = hub;\r\n\r\n\t kendo.data.RemoteTransport.fn.init.call(this, options);\r\n\t },\r\n\r\n\t push: function(callbacks) {\r\n\t var client = this.options.signalr.client || {};\r\n\r\n\t if (client.create) {\r\n\t this.hub.on(client.create, callbacks.pushCreate);\r\n\t }\r\n\r\n\t if (client.update) {\r\n\t this.hub.on(client.update, callbacks.pushUpdate);\r\n\t }\r\n\r\n\t if (client.destroy) {\r\n\t this.hub.on(client.destroy, callbacks.pushDestroy);\r\n\t }\r\n\t },\r\n\r\n\t _crud: function(options, type) {\r\n\t var hub = this.hub;\r\n\t var promise = this.promise;\r\n\t var server = this.options.signalr.server;\r\n\r\n\t if (!server || !server[type]) {\r\n\t throw new Error(kendo.format('The \"server.{0}\" option must be set.', type));\r\n\t }\r\n\r\n\t var args = [server[type]];\r\n\r\n\t var data = this.parameterMap(options.data, type);\r\n\r\n\t if (!$.isEmptyObject(data)) {\r\n\t args.push(data);\r\n\t }\r\n\r\n\t if (isJQueryPromise(promise)) {\r\n\t promise.done(function() {\r\n\t hub.invoke.apply(hub, args)\r\n\t .done(options.success)\r\n\t .fail(options.error);\r\n\t });\r\n\t } else if (isNativePromise(promise)) {\r\n\t promise.then(function() {\r\n\t hub.invoke.apply(hub, args)\r\n\t .then(options.success)\r\n\t .catch(options.error); // jshint ignore:line\r\n\t });\r\n\t }\r\n\t },\r\n\r\n\t read: function(options) {\r\n\t this._crud(options, \"read\");\r\n\t },\r\n\r\n\t create: function(options) {\r\n\t this._crud(options, \"create\");\r\n\t },\r\n\r\n\t update: function(options) {\r\n\t this._crud(options, \"update\");\r\n\t },\r\n\r\n\t destroy: function(options) {\r\n\t this._crud(options, \"destroy\");\r\n\t }\r\n\t });\r\n\r\n\t $.extend(true, kendo.data, {\r\n\t transports: {\r\n\t signalr: transport\r\n\t }\r\n\t });\r\n\r\n\t})(window.kendo.jQuery);\r\n\r\n\treturn window.kendo;\r\n\r\n\t}, __webpack_require__(3));\r\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1069);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1069:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\r\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n\t})(function(){\r\n\r\n\tvar __meta__ = { // jshint ignore:line\r\n\t id: \"data.xml\",\r\n\t name: \"XML\",\r\n\t category: \"framework\",\r\n\t depends: [ \"core\" ],\r\n\t hidden: true\r\n\t};\r\n\r\n\t/*jshint eqnull: true, boss: true */\r\n\t(function($, undefined) {\r\n\t var kendo = window.kendo,\r\n\t isArray = $.isArray,\r\n\t isPlainObject = $.isPlainObject,\r\n\t map = $.map,\r\n\t each = $.each,\r\n\t extend = $.extend,\r\n\t getter = kendo.getter,\r\n\t Class = kendo.Class;\r\n\r\n\t var XmlDataReader = Class.extend({\r\n\t init: function(options) {\r\n\t var that = this,\r\n\t total = options.total,\r\n\t model = options.model,\r\n\t parse = options.parse,\r\n\t errors = options.errors,\r\n\t serialize = options.serialize,\r\n\t data = options.data;\r\n\r\n\t if (model) {\r\n\t if (isPlainObject(model)) {\r\n\t var base = options.modelBase || kendo.data.Model;\r\n\r\n\t if (model.fields) {\r\n\t each(model.fields, function(field, value) {\r\n\t if (isPlainObject(value) && value.field) {\r\n\t if (!$.isFunction(value.field)) {\r\n\t value = extend(value, { field: that.getter(value.field) });\r\n\t }\r\n\t } else {\r\n\t value = { field: that.getter(value) };\r\n\t }\r\n\t model.fields[field] = value;\r\n\t });\r\n\t }\r\n\r\n\t var id = model.id;\r\n\t if (id) {\r\n\t var idField = {};\r\n\r\n\t idField[that.xpathToMember(id, true)] = { field : that.getter(id) };\r\n\t model.fields = extend(idField, model.fields);\r\n\t model.id = that.xpathToMember(id);\r\n\t }\r\n\t model = base.define(model);\r\n\t }\r\n\r\n\t that.model = model;\r\n\t }\r\n\r\n\t if (total) {\r\n\t if (typeof total == \"string\") {\r\n\t total = that.getter(total);\r\n\t that.total = function(data) {\r\n\t return parseInt(total(data), 10);\r\n\t };\r\n\t } else if (typeof total == \"function\"){\r\n\t that.total = total;\r\n\t }\r\n\t }\r\n\r\n\t if (errors) {\r\n\t if (typeof errors == \"string\") {\r\n\t errors = that.getter(errors);\r\n\t that.errors = function(data) {\r\n\t return errors(data) || null;\r\n\t };\r\n\t } else if (typeof errors == \"function\"){\r\n\t that.errors = errors;\r\n\t }\r\n\t }\r\n\r\n\t if (data) {\r\n\t if (typeof data == \"string\") {\r\n\t data = that.xpathToMember(data);\r\n\t that.data = function(value) {\r\n\t var result = that.evaluate(value, data),\r\n\t modelInstance;\r\n\r\n\t result = isArray(result) ? result : [result];\r\n\r\n\t if (that.model && model.fields) {\r\n\t modelInstance = new that.model();\r\n\r\n\t return map(result, function(value) {\r\n\t if (value) {\r\n\t var record = {}, field;\r\n\r\n\t for (field in model.fields) {\r\n\t record[field] = modelInstance._parse(field, model.fields[field].field(value));\r\n\t }\r\n\r\n\t return record;\r\n\t }\r\n\t });\r\n\t }\r\n\r\n\t return result;\r\n\t };\r\n\t } else if (typeof data == \"function\") {\r\n\t that.data = data;\r\n\t }\r\n\t }\r\n\r\n\t if (typeof parse == \"function\") {\r\n\t var xmlParse = that.parse;\r\n\r\n\t that.parse = function(data) {\r\n\t var xml = parse.call(that, data);\r\n\t return xmlParse.call(that, xml);\r\n\t };\r\n\t }\r\n\r\n\t if (typeof serialize == \"function\") {\r\n\t that.serialize = serialize;\r\n\t }\r\n\t },\r\n\t total: function(result) {\r\n\t return this.data(result).length;\r\n\t },\r\n\t errors: function(data) {\r\n\t return data ? data.errors : null;\r\n\t },\r\n\t serialize: function(data) {\r\n\t return data;\r\n\t },\r\n\t parseDOM: function(element) {\r\n\t var result = {},\r\n\t parsedNode,\r\n\t node,\r\n\t nodeType,\r\n\t nodeName,\r\n\t member,\r\n\t attribute,\r\n\t attributes = element.attributes,\r\n\t attributeCount = attributes.length,\r\n\t idx;\r\n\r\n\t for (idx = 0; idx < attributeCount; idx++) {\r\n\t attribute = attributes[idx];\r\n\t result[\"@\" + attribute.nodeName] = attribute.nodeValue;\r\n\t }\r\n\r\n\t for (node = element.firstChild; node; node = node.nextSibling) {\r\n\t nodeType = node.nodeType;\r\n\r\n\t if (nodeType === 3 || nodeType === 4) {\r\n\t // text nodes or CDATA are stored as #text field\r\n\t result[\"#text\"] = node.nodeValue;\r\n\t } else if (nodeType === 1) {\r\n\t // elements are stored as fields\r\n\t parsedNode = this.parseDOM(node);\r\n\r\n\t nodeName = node.nodeName;\r\n\r\n\t member = result[nodeName];\r\n\r\n\t if (isArray(member)) {\r\n\t // elements of same nodeName are stored as array\r\n\t member.push(parsedNode);\r\n\t } else if (member !== undefined) {\r\n\t member = [member, parsedNode];\r\n\t } else {\r\n\t member = parsedNode;\r\n\t }\r\n\r\n\t result[nodeName] = member;\r\n\t }\r\n\t }\r\n\t return result;\r\n\t },\r\n\r\n\t evaluate: function(value, expression) {\r\n\t var members = expression.split(\".\"),\r\n\t member,\r\n\t result,\r\n\t length,\r\n\t intermediateResult,\r\n\t idx;\r\n\r\n\t while (member = members.shift()) {\r\n\t value = value[member];\r\n\r\n\t if (isArray(value)) {\r\n\t result = [];\r\n\t expression = members.join(\".\");\r\n\r\n\t for (idx = 0, length = value.length; idx < length; idx++) {\r\n\t intermediateResult = this.evaluate(value[idx], expression);\r\n\r\n\t intermediateResult = isArray(intermediateResult) ? intermediateResult : [intermediateResult];\r\n\r\n\t result.push.apply(result, intermediateResult);\r\n\t }\r\n\r\n\t return result;\r\n\t }\r\n\t }\r\n\r\n\t return value;\r\n\t },\r\n\r\n\t parse: function(xml) {\r\n\t var documentElement,\r\n\t tree,\r\n\t result = {};\r\n\r\n\t documentElement = xml.documentElement || $.parseXML(xml).documentElement;\r\n\r\n\t tree = this.parseDOM(documentElement);\r\n\r\n\t result[documentElement.nodeName] = tree;\r\n\r\n\t return result;\r\n\t },\r\n\r\n\t xpathToMember: function(member, raw) {\r\n\t if (!member) {\r\n\t return \"\";\r\n\t }\r\n\r\n\t member = member.replace(/^\\//, \"\") // remove the first \"/\"\r\n\t .replace(/\\//g, \".\"); // replace all \"/\" with \".\"\r\n\r\n\t if (member.indexOf(\"@\") >= 0) {\r\n\t // replace @attribute with '[\"@attribute\"]'\r\n\t return member.replace(/\\.?(@.*)/, raw? '$1':'[\"$1\"]');\r\n\t }\r\n\r\n\t if (member.indexOf(\"text()\") >= 0) {\r\n\t // replace \".text()\" with '[\"#text\"]'\r\n\t return member.replace(/(\\.?text\\(\\))/, raw? '#text':'[\"#text\"]');\r\n\t }\r\n\r\n\t return member;\r\n\t },\r\n\t getter: function(member) {\r\n\t return getter(this.xpathToMember(member), true);\r\n\t }\r\n\t });\r\n\r\n\t $.extend(true, kendo.data, {\r\n\t XmlDataReader: XmlDataReader,\r\n\t readers: {\r\n\t xml: XmlDataReader\r\n\t }\r\n\t });\r\n\t})(window.kendo.jQuery);\r\n\r\n\treturn window.kendo;\r\n\r\n\t}, __webpack_require__(3));\r\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1090);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1014:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.drawing\");\n\n/***/ }),\n\n/***/ 1078:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 1090:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1078), __webpack_require__(1014) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dataviz.barcode\",\n\t name: \"Barcode\",\n\t category: \"dataviz\",\n\t description: \"Barcode widget\",\n\t depends: [ \"dataviz.core\" ]\n\t};\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t Widget = kendo.ui.Widget,\n\n\t extend = $.extend,\n\t deepExtend = kendo.deepExtend,\n\t inArray = $.inArray,\n\t isPlainObject = $.isPlainObject,\n\n\t draw = kendo.drawing,\n\t geom = kendo.geometry,\n\t util = kendo.drawing.util,\n\t defined = util.defined,\n\t dataviz = kendo.dataviz,\n\t Box2D = dataviz.Box2D,\n\t TextBox = dataviz.TextBox,\n\t DEFAULT_WIDTH = 300,\n\t DEFAULT_HEIGHT = 100,\n\t DEFAULT_QUIETZONE_LENGTH = 10,\n\t numberRegex = /^\\d+$/,\n\t alphanumericRegex = /^[a-z0-9]+$/i,\n\t InvalidCharacterErrorTemplate = \"Character '{0}' is not valid for symbology {1}\";\n\n\t function getNext(value, index, count){\n\t return value.substring(index, index + count);\n\t }\n\n\t var Encoding = kendo.Class.extend({\n\t init: function (options) {\n\t this.setOptions(options);\n\t },\n\t setOptions: function(options){\n\t var that = this;\n\t that.options = extend({}, that.options, options);\n\t that.quietZoneLength = that.options.addQuietZone ? 2 * that.options.quietZoneLength : 0;\n\t },\n\t encode: function (value, width, height) {\n\t var that = this;\n\t if (defined(value)) {\n\t value+='';\n\t }\n\n\t that.initValue(value, width, height);\n\n\t if (that.options.addQuietZone) {\n\t that.addQuietZone();\n\t }\n\n\t that.addData();\n\n\t if (that.options.addQuietZone) {\n\t that.addQuietZone();\n\t }\n\n\t return {\n\t baseUnit: that.baseUnit,\n\t pattern: that.pattern\n\t };\n\t },\n\t options: {\n\t quietZoneLength: DEFAULT_QUIETZONE_LENGTH,\n\t addQuietZone: true,\n\t addCheckSum: true\n\t },\n\t initValue: function () {},\n\t addQuietZone: function () {\n\t this.pattern.push(this.options.quietZoneLength || DEFAULT_QUIETZONE_LENGTH);\n\t },\n\t addData: function () {\n\t },\n\t invalidCharacterError: function(character){\n\t throw new Error(kendo.format(InvalidCharacterErrorTemplate, character, this.name));\n\t }\n\t });\n\n\t var encodings = {};\n\n\t var code39Base = Encoding.extend({\n\t minBaseUnitLength: 0.7,\n\t addData: function(){\n\t var that = this,\n\t value = that.value;\n\n\t that.addStart();\n\n\t for(var idx = 0; idx < value.length; idx++){\n\t that.addCharacter(value.charAt(idx));\n\t }\n\n\t if(that.options.addCheckSum){\n\t that.pushCheckSum();\n\t }\n\n\t that.addStop();\n\t that.prepareValues();\n\t },\n\t addCharacter: function(character){\n\t var that = this,\n\t charData = that.characterMap[character];\n\t if(!charData){\n\t that.invalidCharacterError(character);\n\t }\n\t that.addBase(charData);\n\t },\n\t addBase: function(){}\n\t });\n\n\t var code39ExtendedBase = {\n\t addCharacter: function(character){\n\t var that = this;\n\t if(that.characterMap[character]){\n\t that.addBase(that.characterMap[character]);\n\t }\n\t else if(character.charCodeAt(0) > 127){\n\t that.invalidCharacterError(character);\n\t }\n\t else{\n\t that.addExtended(character.charCodeAt(0));\n\t }\n\t },\n\t addExtended: function(code){\n\t var that = this,\n\t patterns;\n\t for(var i = 0; i < that.extendedMappings.length; i++){\n\t if((patterns = that.extendedMappings[i].call(that, code))){\n\t for(var j = 0; j < patterns.length; j++){\n\t that.addBase(patterns[j]);\n\t }\n\t that.dataLength+= patterns.length - 1;\n\t return;\n\t }\n\t }\n\t },\n\t extendedMappings: [\n\t function(code){\n\t if(97 <= code && code <= 122){\n\t var that = this;\n\t return [that.characterMap[that.shiftCharacters[0]], that.characterMap[String.fromCharCode(code - 32)]];\n\t }\n\t },\n\t function(code){\n\t if(33 <= code && code <= 58){\n\t var that = this;\n\t return [that.characterMap[that.shiftCharacters[1]], that.characterMap[String.fromCharCode(code + 32)]];\n\t }\n\t },\n\t function(code){\n\t if(1 <= code && code <= 26){\n\t var that = this;\n\t return [that.characterMap[that.shiftCharacters[2]], that.characterMap[String.fromCharCode(code + 64)]];\n\t }\n\t },\n\t function(code){\n\t var that = this,\n\t result,\n\t dataCharacter;\n\t if(!that.specialAsciiCodes[code]){\n\t dataCharacter = Math.floor(code / 32) * 6 + (code - 27) % 32 + 64;\n\t result = [that.characterMap[that.shiftCharacters[3]], that.characterMap[String.fromCharCode(dataCharacter)]];\n\t }\n\t else{\n\t result = [];\n\t for(var i = 0; i < that.specialAsciiCodes[code].length; i++){\n\t result.push(that.characterMap[that.shiftCharacters[3]]);\n\t result.push(that.characterMap[that.specialAsciiCodes[code][i]]);\n\t }\n\t }\n\n\t return result;\n\t }\n\t ],\n\t specialAsciiCodes: {\n\t \"0\": [\"U\"],\n\t \"64\": [\"V\"],\n\t \"96\": [\"W\"],\n\t \"127\": [\"T\",\"X\",\"Y\",\"Z\"]\n\t },\n\t shiftValuesAsciiCodes:{\n\t \"39\": 36,\n\t \"40\": 47,\n\t \"41\": 43,\n\t \"42\": 37\n\t },\n\t characterMap: {\n\t \"+\": false,\n\t \"/\": false,\n\t \"$\": false,\n\t \"%\": false\n\t },\n\t shiftCharacters: [\"SHIFT0\", \"SHIFT1\", \"SHIFT2\", \"SHIFT3\"]\n\t };\n\n\t encodings.code39 = code39Base.extend({\n\t name: \"Code 39\",\n\t checkSumMod: 43,\n\t minRatio: 2.5,\n\t maxRatio: 3,\n\t gapWidth: 1,\n\t splitCharacter: \"|\",\n\t initValue: function (value, width, height) {\n\t var that = this;\n\t that.width = width;\n\t that.height = height;\n\t that.value = value;\n\t that.dataLength = value.length;\n\t that.pattern = [];\n\t that.patternString = \"\";\n\t },\n\t prepareValues: function(){\n\t var that = this,\n\t baseUnit,\n\t minBaseUnit = that.minBaseUnitLength,\n\t ratio = that.maxRatio,\n\t minRatio = that.minRatio,\n\t minHeight = Math.max(0.15 * that.width, 24);\n\t if (that.height < minHeight) {\n\t throw new Error(\"Insufficient Height. The minimum height for value: \" + that.value + \" is: \" + minHeight);\n\t }\n\n\t while((baseUnit = that.getBaseUnit(ratio)) < minBaseUnit && ratio > minRatio){\n\t ratio = parseFloat((ratio - 0.1).toFixed(1));\n\t }\n\n\t if(baseUnit < minBaseUnit){\n\t var minWidth = Math.ceil(that.getBaseWidth(minRatio) * minBaseUnit);\n\t throw new Error(\"Insufficient width. The minimum width for value: \" + that.value + \" is: \" + minWidth);\n\t }\n\n\t that.ratio = ratio;\n\t that.baseUnit = baseUnit;\n\t that.patternString = that.patternString.substring(0, that.patternString.length - 1);\n\t that.pattern = that.pattern.concat(that.patternString.replace(/ratio/g, ratio).split(that.splitCharacter));\n\t },\n\t getBaseUnit: function(ratio){\n\t return this.width / this.getBaseWidth(ratio);\n\t },\n\t getBaseWidth: function(ratio){\n\t var that = this,\n\t characterLength = 3 * (ratio + 2);\n\t return that.quietZoneLength + characterLength * (that.dataLength + 2) + that.gapWidth * (that.dataLength + 1);\n\t },\n\t addStart: function () {\n\t var that = this;\n\t that.addPattern(that.characterMap.START.pattern);\n\t that.addCharacterGap();\n\t },\n\t addBase: function(character){\n\t this.addPattern(character.pattern);\n\t this.addCharacterGap();\n\t },\n\t addStop: function () {\n\t this.addPattern(this.characterMap.START.pattern);\n\t },\n\t addPattern: function (pattern) {\n\t for (var i = 0; i < pattern.length; i++) {\n\t this.patternString+= this.patternMappings[pattern.charAt(i)];\n\t }\n\t },\n\t addCharacterGap: function () {\n\t var that = this;\n\t that.patternString+=that.gapWidth + that.splitCharacter;\n\t },\n\t patternMappings: {\n\t \"b\": \"1|\",\n\t \"w\": \"1|\",\n\t \"B\": \"ratio|\",\n\t \"W\": \"ratio|\"\n\t },\n\t characterMap: {\n\t \"0\":{\"pattern\":\"bwbWBwBwb\",\"value\":0},\n\t \"1\":{\"pattern\":\"BwbWbwbwB\",\"value\":1},\n\t \"2\":{\"pattern\":\"bwBWbwbwB\",\"value\":2},\n\t \"3\":{\"pattern\":\"BwBWbwbwb\",\"value\":3},\n\t \"4\":{\"pattern\":\"bwbWBwbwB\",\"value\":4},\n\t \"5\":{\"pattern\":\"BwbWBwbwb\",\"value\":5},\n\t \"6\":{\"pattern\":\"bwBWBwbwb\",\"value\":6},\n\t \"7\":{\"pattern\":\"bwbWbwBwB\",\"value\":7},\n\t \"8\":{\"pattern\":\"BwbWbwBwb\",\"value\":8},\n\t \"9\":{\"pattern\":\"bwBWbwBwb\",\"value\":9},\n\t \"A\":{\"pattern\":\"BwbwbWbwB\",\"value\":10},\n\t \"B\":{\"pattern\":\"bwBwbWbwB\",\"value\":11},\n\t \"C\":{\"pattern\":\"BwBwbWbwb\",\"value\":12},\n\t \"D\":{\"pattern\":\"bwbwBWbwB\",\"value\":13},\n\t \"E\":{\"pattern\":\"BwbwBWbwb\",\"value\":14},\n\t \"F\":{\"pattern\":\"bwBwBWbwb\",\"value\":15},\n\t \"G\":{\"pattern\":\"bwbwbWBwB\",\"value\":16},\n\t \"H\":{\"pattern\":\"BwbwbWBwb\",\"value\":17},\n\t \"I\":{\"pattern\":\"bwBwbWBwb\",\"value\":18},\n\t \"J\":{\"pattern\":\"bwbwBWBwb\",\"value\":19},\n\t \"K\":{\"pattern\":\"BwbwbwbWB\",\"value\":20},\n\t \"L\":{\"pattern\":\"bwBwbwbWB\",\"value\":21},\n\t \"M\":{\"pattern\":\"BwBwbwbWb\",\"value\":22},\n\t \"N\":{\"pattern\":\"bwbwBwbWB\",\"value\":23},\n\t \"O\":{\"pattern\":\"BwbwBwbWb\",\"value\":24},\n\t \"P\":{\"pattern\":\"bwBwBwbWb\",\"value\":25},\n\t \"Q\":{\"pattern\":\"bwbwbwBWB\",\"value\":26},\n\t \"R\":{\"pattern\":\"BwbwbwBWb\",\"value\":27},\n\t \"S\":{\"pattern\":\"bwBwbwBWb\",\"value\":28},\n\t \"T\":{\"pattern\":\"bwbwBwBWb\",\"value\":29},\n\t \"U\":{\"pattern\":\"BWbwbwbwB\",\"value\":30},\n\t \"V\":{\"pattern\":\"bWBwbwbwB\",\"value\":31},\n\t \"W\":{\"pattern\":\"BWBwbwbwb\",\"value\":32},\n\t \"X\":{\"pattern\":\"bWbwBwbwB\",\"value\":33},\n\t \"Y\":{\"pattern\":\"BWbwBwbwb\",\"value\":34},\n\t \"Z\":{\"pattern\":\"bWBwBwbwb\",\"value\":35},\n\t \"-\":{\"pattern\":\"bWbwbwBwB\",\"value\":36},\n\t \".\":{\"pattern\":\"BWbwbwBwb\",\"value\":37},\n\t \" \":{\"pattern\":\"bWBwbwBwb\",\"value\":38},\n\t \"$\":{\"pattern\":\"bWbWbWbwb\",\"value\":39},\n\t \"/\":{\"pattern\":\"bWbWbwbWb\",\"value\":40},\n\t \"+\":{\"pattern\":\"bWbwbWbWb\",\"value\":41},\n\t \"%\":{\"pattern\":\"bwbWbWbWb\",\"value\":42},\n\t START: { pattern: \"bWbwBwBwb\"}\n\t },\n\t options: {\n\t addCheckSum: false\n\t }\n\t });\n\n\t encodings.code39extended = encodings.code39.extend(deepExtend({}, code39ExtendedBase, {\n\t name: \"Code 39 extended\",\n\t characterMap: {\n\t SHIFT0: {\"pattern\":\"bWbwbWbWb\",\"value\":41},\n\t SHIFT1: {\"pattern\":\"bWbWbwbWb\",\"value\":40},\n\t SHIFT2: {\"pattern\":\"bWbWbWbwb\",\"value\":39},\n\t SHIFT3: {\"pattern\":\"bwbWbWbWb\",\"value\":42}\n\t }\n\t }));\n\n\t encodings.code93 = code39Base.extend({\n\t name: \"Code 93\",\n\t cCheckSumTotal: 20,\n\t kCheckSumTotal: 15,\n\t checkSumMod: 47,\n\t initValue: function(value, width, height){\n\t var that = this;\n\t that.value = value;\n\t that.width = width;\n\t that.height = height;\n\t that.pattern = [];\n\t that.values = [];\n\t that.dataLength = value.length;\n\t },\n\t prepareValues: function(){\n\t var that = this,\n\t minHeight = Math.max(0.15 * that.width, 24);\n\t if (that.height < minHeight) {\n\t throw new Error(\"Insufficient Height\");\n\t }\n\n\t that.setBaseUnit();\n\n\t if(that.baseUnit < that.minBaseUnitLength){\n\t throw new Error(\"Insufficient Width\");\n\t }\n\t },\n\t setBaseUnit: function(){\n\t var that = this,\n\t checkSumLength = 2;\n\t that.baseUnit = that.width / (9 * (that.dataLength + 2 + checkSumLength) + that.quietZoneLength + 1);\n\t },\n\t addStart: function(){\n\t var pattern = this.characterMap.START.pattern;\n\t this.addPattern(pattern);\n\t },\n\t addStop: function(){\n\t var that = this;\n\t that.addStart();\n\t that.pattern.push(that.characterMap.TERMINATION_BAR);\n\t },\n\t addBase: function(charData){\n\t this.addPattern(charData.pattern);\n\t this.values.push(charData.value);\n\t },\n\t pushCheckSum: function(){\n\t var that = this,\n\t checkValues = that._getCheckValues(),\n\t charData;\n\n\t that.checksum = checkValues.join(\"\");\n\t for(var i = 0; i < checkValues.length; i++){\n\t charData = that.characterMap[that._findCharacterByValue(checkValues[i])];\n\t that.addPattern(charData.pattern);\n\t }\n\t },\n\t _getCheckValues: function(){\n\t var that = this,\n\t values = that.values,\n\t length = values.length,\n\t wightedSum = 0,\n\t cValue,\n\t kValue,\n\t idx;\n\n\t for(idx = length - 1; idx >= 0; idx--){\n\t wightedSum += that.weightedValue(values[idx],length - idx, that.cCheckSumTotal);\n\t }\n\t cValue = wightedSum % that.checkSumMod;\n\n\t wightedSum = that.weightedValue(cValue, 1, that.kCheckSumTotal);\n\t for(idx = length - 1; idx >= 0; idx--){\n\t wightedSum += that.weightedValue(values[idx], length - idx + 1, that.kCheckSumTotal);\n\t }\n\n\t kValue = wightedSum % that.checkSumMod;\n\t return [cValue, kValue];\n\t },\n\t _findCharacterByValue: function (value) {\n\t for (var character in this.characterMap) {\n\t if (this.characterMap[character].value === value) {\n\t return character;\n\t }\n\t }\n\t },\n\t weightedValue: function(value, index, total){\n\t return (index % total || total) * value;\n\t },\n\t addPattern: function(pattern){\n\t var value;\n\n\t for(var i = 0; i < pattern.length; i++){\n\t value = parseInt(pattern.charAt(i),10);\n\t this.pattern.push(value);\n\t }\n\t },\n\t characterMap: {\n\t \"0\":{\"pattern\":\"131112\",\"value\":0},\n\t \"1\":{\"pattern\":\"111213\",\"value\":1},\n\t \"2\":{\"pattern\":\"111312\",\"value\":2},\n\t \"3\":{\"pattern\":\"111411\",\"value\":3},\n\t \"4\":{\"pattern\":\"121113\",\"value\":4},\n\t \"5\":{\"pattern\":\"121212\",\"value\":5},\n\t \"6\":{\"pattern\":\"121311\",\"value\":6},\n\t \"7\":{\"pattern\":\"111114\",\"value\":7},\n\t \"8\":{\"pattern\":\"131211\",\"value\":8},\n\t \"9\":{\"pattern\":\"141111\",\"value\":9},\n\t \"A\":{\"pattern\":\"211113\",\"value\":10},\n\t \"B\":{\"pattern\":\"211212\",\"value\":11},\n\t \"C\":{\"pattern\":\"211311\",\"value\":12},\n\t \"D\":{\"pattern\":\"221112\",\"value\":13},\n\t \"E\":{\"pattern\":\"221211\",\"value\":14},\n\t \"F\":{\"pattern\":\"231111\",\"value\":15},\n\t \"G\":{\"pattern\":\"112113\",\"value\":16},\n\t \"H\":{\"pattern\":\"112212\",\"value\":17},\n\t \"I\":{\"pattern\":\"112311\",\"value\":18},\n\t \"J\":{\"pattern\":\"122112\",\"value\":19},\n\t \"K\":{\"pattern\":\"132111\",\"value\":20},\n\t \"L\":{\"pattern\":\"111123\",\"value\":21},\n\t \"M\":{\"pattern\":\"111222\",\"value\":22},\n\t \"N\":{\"pattern\":\"111321\",\"value\":23},\n\t \"O\":{\"pattern\":\"121122\",\"value\":24},\n\t \"P\":{\"pattern\":\"131121\",\"value\":25},\n\t \"Q\":{\"pattern\":\"212112\",\"value\":26},\n\t \"R\":{\"pattern\":\"212211\",\"value\":27},\n\t \"S\":{\"pattern\":\"211122\",\"value\":28},\n\t \"T\":{\"pattern\":\"211221\",\"value\":29},\n\t \"U\":{\"pattern\":\"221121\",\"value\":30},\n\t \"V\":{\"pattern\":\"222111\",\"value\":31},\n\t \"W\":{\"pattern\":\"112122\",\"value\":32},\n\t \"X\":{\"pattern\":\"112221\",\"value\":33},\n\t \"Y\":{\"pattern\":\"122121\",\"value\":34},\n\t \"Z\":{\"pattern\":\"123111\",\"value\":35},\n\t \"-\":{\"pattern\":\"121131\",\"value\":36},\n\t \".\":{\"pattern\":\"311112\",\"value\":37},\n\t \" \":{\"pattern\":\"311211\",\"value\":38},\n\t \"$\":{\"pattern\":\"321111\",\"value\":39},\n\t \"/\":{\"pattern\":\"112131\",\"value\":40},\n\t \"+\":{\"pattern\":\"113121\",\"value\":41},\n\t \"%\":{\"pattern\":\"211131\",\"value\":42},\n\t SHIFT0:{\"pattern\":\"122211\",\"value\":46},\n\t SHIFT1:{\"pattern\":\"311121\",\"value\":45},\n\t SHIFT2:{\"pattern\":\"121221\",\"value\":43},\n\t SHIFT3:{\"pattern\":\"312111\",\"value\":44},\n\t START: {\"pattern\":\"111141\"},\n\t TERMINATION_BAR: \"1\"\n\t }\n\t });\n\n\t encodings.code93extended = encodings.code93.extend(deepExtend({}, code39ExtendedBase, {\n\t name: \"Code 93 extended\",\n\t pushCheckSum: function(){\n\t var that = this,\n\t checkValues = that._getCheckValues(),\n\t value;\n\n\t that.checksum = checkValues.join(\"\");\n\n\t for(var i = 0; i < checkValues.length; i++){\n\t value = checkValues[i];\n\t if(that.shiftValuesAsciiCodes[value]){\n\t that.addExtended(that.shiftValuesAsciiCodes[value]);\n\t }\n\t else{\n\t that.addPattern(that.characterMap[that._findCharacterByValue(value)].pattern);\n\t }\n\t }\n\t }\n\t }));\n\n\t var state128 = kendo.Class.extend({\n\t init: function(encoding){\n\t this.encoding = encoding;\n\t },\n\t addStart: function(){},\n\t is: function (){},\n\t move: function (){},\n\t pushState: function(){}\n\t });\n\n\t var state128AB = state128.extend({\n\t FNC4: \"FNC4\",\n\t init: function(encoding, states){\n\t var that = this;\n\t that.encoding = encoding;\n\t that.states = states;\n\t that._initMoves(states);\n\t },\n\t addStart: function(){\n\t this.encoding.addPattern(this.START);\n\t },\n\t is: function (value, index){\n\t var code = value.charCodeAt(index);\n\t return this.isCode(code);\n\t },\n\t move: function(encodingState){\n\t var that = this,\n\t idx = 0;\n\n\t while(!that._moves[idx].call(that, encodingState) && idx < that._moves.length){\n\t idx++;\n\t }\n\t },\n\t pushState: function(encodingState){\n\t var that = this,\n\t states = that.states,\n\t value = encodingState.value,\n\t maxLength = value.length,\n\t code;\n\n\t if(inArray(\"C\", states) >= 0){\n\t var numberMatch = value.substr(encodingState.index).match(/\\d{4,}/g);\n\t if(numberMatch){\n\t maxLength = value.indexOf(numberMatch[0], encodingState.index);\n\t }\n\t }\n\n\t while((code = encodingState.value.charCodeAt(encodingState.index)) >= 0 &&\n\t that.isCode(code) && encodingState.index < maxLength){\n\t that.encoding.addPattern(that.getValue(code));\n\t encodingState.index++;\n\t }\n\t },\n\t _initMoves: function(states){\n\t var that = this;\n\t that._moves = [];\n\n\t if(inArray(that.FNC4, states) >= 0){\n\t that._moves.push(that._moveFNC);\n\t }\n\n\t if(inArray(that.shiftKey, states) >= 0){\n\t that._moves.push(that._shiftState);\n\t }\n\t that._moves.push(that._moveState);\n\t },\n\t _moveFNC: function(encodingState){\n\t if(encodingState.fnc){\n\t encodingState.fnc = false;\n\t return encodingState.previousState == this.key;\n\t }\n\t },\n\t _shiftState: function(encodingState){\n\t var that = this;\n\t if(encodingState.previousState == that.shiftKey &&\n\t (encodingState.index + 1 >= encodingState.value.length ||\n\t that.encoding[that.shiftKey].is(encodingState.value, encodingState.index + 1))){\n\t that.encoding.addPattern(that.SHIFT);\n\t encodingState.shifted = true;\n\t return true;\n\t }\n\t },\n\t _moveState: function(){\n\t this.encoding.addPattern(this.MOVE);\n\t return true;\n\t },\n\t SHIFT: 98\n\t });\n\n\t var states128 = {};\n\n\t states128.A = state128AB.extend({\n\t key: \"A\",\n\t shiftKey: \"B\",\n\t isCode: function(code){\n\t return 0 <= code && code < 96;\n\t },\n\t getValue: function(code){\n\t if(code < 32){\n\t return code + 64;\n\t }\n\n\t return code - 32;\n\t },\n\t MOVE: 101,\n\t START: 103\n\t });\n\n\t states128.B = state128AB.extend({\n\t key: \"B\",\n\t shiftKey: \"A\",\n\t isCode: function(code){\n\t return 32 <= code && code < 128;\n\t },\n\t getValue: function(code){\n\t return code - 32;\n\t },\n\t MOVE: 100,\n\t START: 104\n\t });\n\n\t states128.C = state128.extend({\n\t key: \"C\",\n\t addStart: function(){\n\t this.encoding.addPattern(this.START);\n\t },\n\t is: function (value, index){\n\t var next4 = getNext(value, index, 4);\n\t return (index + 4 <= value.length || value.length == 2) && numberRegex.test(next4);\n\t },\n\t move: function (){\n\t this.encoding.addPattern(this.MOVE);\n\t },\n\t pushState: function(encodingState){\n\t var code;\n\t while(( code = getNext(encodingState.value, encodingState.index, 2)) &&\n\t numberRegex.test(code) && code.length == 2)\n\t {\n\t this.encoding.addPattern(parseInt(code, 10));\n\t encodingState.index+=2;\n\t }\n\t },\n\t getValue: function(code){\n\t return code;\n\t },\n\t MOVE: 99,\n\t START: 105\n\t });\n\n\t states128.FNC4 = state128.extend({\n\t key: \"FNC4\",\n\t dependentStates: [\"A\",\"B\"],\n\t init: function(encoding, states){\n\t this.encoding = encoding;\n\t this._initSubStates(states);\n\t },\n\t addStart: function(encodingState){\n\t var code = encodingState.value.charCodeAt(0) - 128,\n\t subState = this._getSubState(code);\n\n\t this.encoding[subState].addStart();\n\t },\n\t is: function(value, index){\n\t var code = value.charCodeAt(index);\n\t return this.isCode(code);\n\t },\n\t isCode: function(code){\n\t return 128 <= code && code < 256;\n\t },\n\t pushState: function(encodingState){\n\t var that = this,\n\t subState = that._initSubState(encodingState),\n\t encoding = that.encoding,\n\t length = subState.value.length;\n\t encodingState.index += length;\n\n\t if(length < 3){\n\t var code;\n\t for(; subState.index < length; subState.index++){\n\t code = subState.value.charCodeAt(subState.index);\n\t subState.state = that._getSubState(code);\n\t if(subState.previousState != subState.state){\n\t subState.previousState = subState.state;\n\t encoding[subState.state].move(subState);\n\t }\n\t encoding.addPattern(encoding[subState.state].MOVE);\n\t encoding.addPattern(encoding[subState.state].getValue(code));\n\t }\n\t }\n\t else{\n\t if(subState.state != subState.previousState){\n\t encoding[subState.state].move(subState);\n\t }\n\t that._pushStart(subState);\n\t encoding.pushData(subState, that.subStates);\n\t if(encodingState.index < encodingState.value.length){\n\t that._pushStart(subState);\n\t }\n\t }\n\n\t encodingState.fnc = true;\n\t encodingState.state = subState.state;\n\t },\n\t _pushStart: function(subState){\n\t var that = this;\n\t that.encoding.addPattern(that.encoding[subState.state].MOVE);\n\t that.encoding.addPattern(that.encoding[subState.state].MOVE);\n\t },\n\t _initSubState: function(encodingState){\n\t var that = this,\n\t subState = {\n\t value: that._getAll(encodingState.value, encodingState.index),\n\t index: 0\n\t };\n\t subState.state = that._getSubState(subState.value.charCodeAt(0));\n\t subState.previousState = encodingState.previousState == that.key ?\n\t subState.state : encodingState.previousState;\n\t return subState;\n\t },\n\t _initSubStates: function(states){\n\t var that = this;\n\t that.subStates = [];\n\t for(var i = 0; i < states.length; i++){\n\t if(inArray(states[i], that.dependentStates) >= 0){\n\t that.subStates.push(states[i]);\n\t }\n\t }\n\t },\n\t _getSubState: function(code){\n\t var that = this;\n\t for(var i = 0; i < that.subStates.length; i++){\n\t if(that.encoding[that.subStates[i]].isCode(code)){\n\t return that.subStates[i];\n\t }\n\t }\n\t },\n\t _getAll: function(value, index){\n\t var code,\n\t result = \"\";\n\t while((code = value.charCodeAt(index++)) && this.isCode(code)){\n\t result += String.fromCharCode(code - 128);\n\t }\n\t return result;\n\t }\n\t });\n\n\t states128.FNC1 = state128.extend({\n\t key: \"FNC1\",\n\t startState: \"C\",\n\t dependentStates: [\"C\",\"B\"],\n\t startAI: \"(\",\n\t endAI: \")\",\n\t init: function(encoding, states){\n\t this.encoding = encoding;\n\t this.states = states;\n\t },\n\t addStart: function(){\n\t this.encoding[this.startState].addStart();\n\t },\n\t is: function(){\n\t return inArray(this.key, this.states) >= 0;\n\t },\n\t pushState: function(encodingState){\n\t var that = this,\n\t encoding = that.encoding,\n\t value = encodingState.value.replace(/\\s/g, \"\"),\n\t regexSeparators = new RegExp(\"[\" + that.startAI + that.endAI + \"]\", \"g\"),\n\t index = encodingState.index,\n\t subState= {\n\t state: that.startState\n\t },\n\t current,\n\t nextStart,\n\t separatorLength;\n\n\t encoding.addPattern(that.START);\n\n\t while(true){\n\t subState.index = 0;\n\n\t separatorLength = value.charAt(index) === that.startAI ? 2 : 0;\n\t current = separatorLength > 0 ? that.getBySeparator(value, index) : that.getByLength(value, index);\n\t if(current.ai.length){\n\t nextStart = index + separatorLength + current.id.length + current.ai.length;\n\t }\n\t else{\n\t nextStart = value.indexOf(that.startAI, index + 1);\n\t if(nextStart < 0){\n\t if(index + current.ai.max + current.id.length + separatorLength < value.length){\n\t throw new Error(\"Separators are required after variable length identifiers\");\n\t }\n\t nextStart = value.length;\n\t }\n\t }\n\t subState.value = value.substring(index, nextStart).replace(regexSeparators, \"\");\n\t that.validate(current, subState.value);\n\n\t encoding.pushData(subState, that.dependentStates);\n\n\t if(nextStart >= value.length){\n\t break;\n\t }\n\n\t index = nextStart;\n\n\t if(subState.state != that.startState){\n\t encoding[that.startState].move(subState);\n\t subState.state = that.startState;\n\t }\n\n\t if(!current.ai.length){\n\t encoding.addPattern(that.START);\n\t }\n\t }\n\t encodingState.index = encodingState.value.length;\n\t },\n\t validate: function(current, value){\n\t var code = value.substr(current.id.length),\n\t ai = current.ai;\n\t if(!ai.type && !numberRegex.test(code)){\n\t throw new Error(\"Application identifier \" + current.id+ \" is numeric only but contains non numeric character(s).\");\n\t }\n\n\t if(ai.type == \"alphanumeric\" && !alphanumericRegex.test(code)){\n\t throw new Error(\"Application identifier \" + current.id+ \" is alphanumeric only but contains non alphanumeric character(s).\");\n\t }\n\n\t if(ai.length && ai.length !== code.length){\n\t throw new Error(\"Application identifier \" + current.id + \" must be \" + ai.length + \" characters long.\");\n\t }\n\n\t if(ai.min && ai.min > code.length){\n\t throw new Error(\"Application identifier \" + current.id + \" must be at least \" + ai.min + \" characters long.\");\n\t }\n\n\t if(ai.max && ai.max < code.length){\n\t throw new Error(\"Application identifier \" + current.id + \" must be at most \" + ai.max + \" characters long.\");\n\t }\n\t },\n\t getByLength: function(value, index){\n\t var that = this,\n\t id,\n\t ai;\n\t for(var i = 2; i <= 4; i++){\n\t id = getNext(value, index, i);\n\t ai = that.getAI(id) || that.getAI(id.substring(0, id.length - 1));\n\t if(ai){\n\t return {\n\t id: id,\n\t ai: ai\n\t };\n\t }\n\t }\n\t that.unsupportedAIError(id);\n\t },\n\t unsupportedAIError: function(id){\n\t throw new Error(kendo.format(\"'{0}' is not a supported Application Identifier\"),id);\n\t },\n\t getBySeparator: function(value, index){\n\t var that = this,\n\t start = value.indexOf(that.startAI, index),\n\t end = value.indexOf(that.endAI, start),\n\t id = value.substring(start + 1,end),\n\t ai = that.getAI(id) || that.getAI(id.substr(id.length - 1));\n\t if(!ai){\n\t that.unsupportedAIError(id);\n\t }\n\n\t return {\n\t ai: ai,\n\t id: id\n\t };\n\t },\n\t getAI: function(id){\n\t var ai = this.applicationIdentifiers,\n\t multiKey = ai.multiKey;\n\t if(ai[id]){\n\t return ai[id];\n\t }\n\n\t for(var i = 0; i < multiKey.length; i++){\n\t if(multiKey[i].ids && inArray(id, multiKey[i].ids) >= 0){\n\t return multiKey[i].type;\n\t }\n\t else if(multiKey[i].ranges){\n\t var ranges = multiKey[i].ranges;\n\t for(var j = 0; j < ranges.length; j++){\n\t if(ranges[j][0] <= id && id <= ranges[j][1]){\n\t return multiKey[i].type;\n\t }\n\t }\n\t }\n\t }\n\t },\n\t applicationIdentifiers: {\n\t \"22\": {max: 29, type: \"alphanumeric\"},\n\t \"402\": {length: 17},\n\t \"7004\": {max: 4, type: \"alphanumeric\"},\n\t \"242\": {max: 6, type: \"alphanumeric\"},\n\t \"8020\": {max: 25, type: \"alphanumeric\"},\n\t \"703\": { min: 3, max: 30, type: \"alphanumeric\"},\n\t \"8008\": { min: 8, max: 12, type: \"alphanumeric\"},\n\t \"253\": { min: 13, max: 17, type: \"alphanumeric\"},\n\t \"8003\": { min: 14, max: 30, type: \"alphanumeric\"},\n\t multiKey: [{\n\t ids: [\"15\", \"17\", \"8005\", \"8100\"],\n\t ranges: [\n\t [11, 13],\n\t [310, 316],\n\t [320, 336],\n\t [340, 369]\n\t ],\n\t type: { length: 6}\n\t },{\n\t ids: [\"240\", \"241\", \"250\", \"251\", \"400\", \"401\", \"403\", \"7002\", \"8004\", \"8007\", \"8110\"],\n\t ranges: [[90-99]],\n\t type: {max: 30, type: \"alphanumeric\"}\n\t },{\n\t ids: [\"7001\"],\n\t ranges: [[410, 414]],\n\t type: { length: 13}\n\t },{\n\t ids: [\"10\",\"21\", \"254\", \"420\", \"8002\"],\n\t type: {max: 20, type: \"alphanumeric\"}\n\t },{\n\t ids: [\"00\", \"8006\", \"8017\", \"8018\"],\n\t type: {length: 18}\n\t },{\n\t ids: [\"01\", \"02\", \"8001\"],\n\t type: { length: 14}\n\t },{\n\t ids: [\"422\"],\n\t ranges: [\n\t [424, 426]\n\t ],\n\t type: {length: 3}\n\t },{\n\t ids: [\"20\", \"8102\"],\n\t type: { length: 2}\n\t },{\n\t ids: [\"30\",\"37\"],\n\t type: {max: 8, type: \"alphanumeric\"}\n\t },{\n\t ids: [\"390\",\"392\"],\n\t type: {max: 15, type: \"alphanumeric\"}\n\t },{\n\t ids: [\"421\", \"423\"],\n\t type: { min: 3, max: 15, type: \"alphanumeric\"}\n\t }, {\n\t ids: [\"391\", \"393\"],\n\t type: { min: 3, max: 18, type: \"alphanumeric\"}\n\t },{\n\t ids: [\"7003\", \"8101\"],\n\t type: {length: 10}\n\t }]\n\t },\n\t START: 102\n\t });\n\n\t var code128Base = Encoding.extend({\n\t init: function (options) {\n\t Encoding.fn.init.call(this, options);\n\t this._initStates();\n\t },\n\t _initStates: function(){\n\t var that = this;\n\t for(var i = 0; i < that.states.length; i++){\n\t that[that.states[i]] = new states128[that.states[i]](that, that.states);\n\t }\n\t },\n\t initValue: function (value, width, height) {\n\t var that = this;\n\t that.pattern = [];\n\t that.value = value;\n\t that.width = width;\n\t that.height = height;\n\t that.checkSum = 0;\n\t that.totalUnits = 0;\n\t that.index = 0;\n\t that.position = 1;\n\t },\n\t addData: function(){\n\t var that = this,\n\t encodingState = {\n\t value: that.value,\n\t index: 0,\n\t state: \"\"\n\t };\n\t if(that.value.length === 0){\n\t return;\n\t }\n\n\t encodingState.state =\n\t encodingState.previousState = that.getNextState(encodingState, that.states);\n\n\t that.addStart(encodingState);\n\n\t that.pushData(encodingState, that.states);\n\n\t that.addCheckSum();\n\t that.addStop();\n\t that.setBaseUnit();\n\t },\n\t pushData: function(encodingState, states){\n\t var that = this;\n\t while(true){\n\t that[encodingState.state].pushState(encodingState);\n\t if(encodingState.index >= encodingState.value.length){\n\t break;\n\t }\n\n\t if(!encodingState.shifted){\n\t encodingState.previousState = encodingState.state;\n\t encodingState.state = that.getNextState(encodingState, states);\n\t that[encodingState.state].move(encodingState);\n\t }\n\t else{\n\t var temp = encodingState.state;\n\t encodingState.state = encodingState.previousState;\n\t encodingState.previousState = temp;\n\t encodingState.shifted = false;\n\t }\n\t }\n\t },\n\t addStart: function(encodingState){\n\t this[encodingState.state].addStart(encodingState);\n\t this.position = 1;\n\t },\n\t addCheckSum: function(){\n\t var that = this;\n\n\t that.checksum = that.checkSum % 103;\n\t that.addPattern(that.checksum);\n\t },\n\t addStop: function(){\n\t this.addPattern(this.STOP);\n\t },\n\t setBaseUnit: function(){\n\t var that = this;\n\t that.baseUnit = that.width / (that.totalUnits + that.quietZoneLength);\n\t },\n\t addPattern: function(code){\n\t var that = this,\n\t pattern = that.characterMap[code].toString(),\n\t value;\n\n\t for(var i = 0; i < pattern.length; i++){\n\t value = parseInt(pattern.charAt(i),10);\n\t that.pattern.push(value);\n\t that.totalUnits += value;\n\t }\n\t that.checkSum += code * that.position++;\n\t },\n\t getNextState: function(encodingState, states){\n\t for(var i = 0; i < states.length; i++){\n\t if(this[states[i]].is(encodingState.value, encodingState.index)){\n\t return states[i];\n\t }\n\t }\n\t this.invalidCharacterError(encodingState.value.charAt(encodingState.index));\n\t },\n\t characterMap: [\n\t 212222,222122,222221,121223,121322,131222,122213,122312,132212,221213,\n\t 221312,231212,112232,122132,122231,113222,123122,123221,223211,221132,\n\t 221231,213212,223112,312131,311222,321122,321221,312212,322112,322211,\n\t 212123,212321,232121,111323,131123,131321,112313,132113,132311,211313,\n\t 231113,231311,112133,112331,132131,113123,113321,133121,313121,211331,\n\t 231131,213113,213311,213131,311123,311321,331121,312113,312311,332111,\n\t 314111,221411,431111,111224,111422,121124,121421,141122,141221,112214,\n\t 112412,122114,122411,142112,142211,241211,221114,413111,241112,134111,\n\t 111242,121142,121241,114212,124112,124211,411212,421112,421211,212141,\n\t 214121,412121,111143,111341,131141,114113,114311,411113,411311,113141,\n\t 114131,311141,411131,211412,211214,211232,2331112\n\t ],\n\t STOP: 106\n\t });\n\n\t encodings.code128a = code128Base.extend({\n\t name: \"Code 128 A\",\n\t states: [\"A\"]\n\t });\n\n\n\t encodings.code128b = code128Base.extend({\n\t name: \"Code 128 B\",\n\t states: [\"B\"]\n\t });\n\n\t encodings.code128c = code128Base.extend({\n\t name: \"Code 128 C\",\n\t states: [\"C\"]\n\t });\n\n\t encodings.code128 = code128Base.extend({\n\t name: \"Code 128\",\n\t states: [\"C\", \"B\", \"A\", \"FNC4\"]\n\t });\n\n\t encodings[\"gs1-128\"] = code128Base.extend({\n\t name: \"Code GS1-128\",\n\t states: [\"FNC1\", \"C\", \"B\"]\n\t });\n\n\t var msiBase = Encoding.extend({\n\t initValue: function(value, width){\n\t var that = this;\n\t that.pattern = [];\n\t that.value = value;\n\t that.checkSumLength = 0;\n\t that.width = width;\n\t },\n\t setBaseUnit: function(){\n\t var that = this,\n\t startStopLength = 7;\n\n\t that.baseUnit = that.width /\n\t ( 12 * (that.value.length + that.checkSumLength) + that.quietZoneLength + startStopLength);\n\t },\n\t addData: function(){\n\t var that = this,\n\t value = that.value;\n\t that.addPattern(that.START);\n\n\t for(var i = 0; i < value.length; i++){\n\t that.addCharacter(value.charAt(i));\n\t }\n\n\t if(that.options.addCheckSum){\n\t that.addCheckSum();\n\t }\n\n\t that.addPattern(that.STOP);\n\t that.setBaseUnit();\n\t },\n\t addCharacter: function(character){\n\t var that = this,\n\t pattern = that.characterMap[character];\n\t if(!pattern){\n\t that.invalidCharacterError(character);\n\t }\n\t that.addPattern(pattern);\n\t },\n\t addPattern: function(pattern){\n\t for(var i = 0; i < pattern.length; i++){\n\t this.pattern.push(parseInt(pattern.charAt(i),10));\n\t }\n\t },\n\t addCheckSum: function(){\n\t var that = this,\n\t checkSumFunction = that.checkSums[that.checkSumType],\n\t checkValues;\n\n\t checkValues = checkSumFunction.call(that.checkSums, that.value);\n\n\t that.checksum = checkValues.join(\"\");\n\t for(var i = 0; i < checkValues.length; i++){\n\t that.checkSumLength++;\n\t that.addPattern(that.characterMap[checkValues[i]]);\n\t }\n\t },\n\t checkSums: {\n\t Modulo10: function(value){\n\t var checkValues = [0, \"\"],\n\t odd = value.length % 2,\n\t idx,\n\t evenSum,\n\t oddSum;\n\n\t for(idx = 0; idx < value.length; idx++){\n\t checkValues[(idx + odd) % 2] += parseInt(value.charAt(idx),10);\n\t }\n\n\t oddSum = checkValues[0];\n\t evenSum = (checkValues[1] * 2).toString();\n\n\t for(idx = 0; idx < evenSum.length; idx++){\n\t oddSum += parseInt(evenSum.charAt(idx),10);\n\t }\n\n\t return [(10 - (oddSum % 10)) % 10];\n\t },\n\t Modulo11: function(value){\n\t var weightedSum = 0,\n\t mod = 11,\n\t length = value.length,\n\t weight,\n\t checkValue;\n\n\t for(var i = 0; i < length; i++){\n\t weight = ((length - i) % 6 || 6) + 1;\n\t weightedSum += weight * value.charAt(i);\n\t }\n\t checkValue = (mod - weightedSum % mod) % mod;\n\t if(checkValue != 10){\n\t return [checkValue];\n\t }\n\t return [1, 0];\n\t },\n\t Modulo11Modulo10: function(value){\n\t var checkValues = this.Modulo11(value),\n\t mod11Value;\n\t mod11Value = value + checkValues[0];\n\n\t return checkValues.concat(this.Modulo10(mod11Value));\n\t },\n\t Modulo10Modulo10: function(value){\n\t var checkValues = this.Modulo10(value),\n\t mod10Value;\n\t mod10Value = value + checkValues[0];\n\n\t return checkValues.concat(this.Modulo10(mod10Value));\n\t }\n\t },\n\t characterMap: [\"12121212\", \"12121221\",\"12122112\", \"12122121\", \"12211212\", \"12211221\", \"12212112\", \"12212121\", \"21121212\", \"21121221\"],\n\t START: \"21\",\n\t STOP: \"121\",\n\t checkSumType: \"\"\n\t });\n\n\t encodings.msimod10 = msiBase.extend({\n\t name: \"MSI Modulo10\",\n\t checkSumType: \"Modulo10\"\n\t });\n\n\t encodings.msimod11 = msiBase.extend({\n\t name: \"MSI Modulo11\",\n\t checkSumType: \"Modulo11\"\n\t });\n\n\t encodings.msimod1110 = msiBase.extend({\n\t name: \"MSI Modulo11 Modulo10\",\n\t checkSumType: \"Modulo11Modulo10\"\n\t });\n\n\t encodings.msimod1010 = msiBase.extend({\n\t name: \"MSI Modulo10 Modulo10\",\n\t checkSumType: \"Modulo10Modulo10\"\n\t });\n\n\t encodings.code11 = Encoding.extend({\n\t name: \"Code 11\",\n\t cCheckSumTotal: 10,\n\t kCheckSumTotal: 9,\n\t kCheckSumMinLength: 10,\n\t checkSumMod: 11,\n\t DASH_VALUE: 10,\n\t DASH: \"-\",\n\t START: \"112211\",\n\t STOP: \"11221\",\n\t initValue: function(value, width){\n\t var that = this;\n\t that.pattern = [];\n\t that.value = value;\n\t that.width = width;\n\t that.totalUnits = 0;\n\t },\n\t addData: function(){\n\t var that = this;\n\t var value = that.value;\n\t that.addPattern(that.START);\n\n\t for(var i = 0; i < value.length; i++){\n\t that.addCharacter(value.charAt(i));\n\t }\n\n\t if(that.options.addCheckSum){\n\t that.addCheckSum();\n\t }\n\n\t that.addPattern(that.STOP);\n\t that.setBaseUnit();\n\t },\n\t setBaseUnit: function(){\n\t var that = this;\n\t that.baseUnit = that.width / (that.totalUnits + that.quietZoneLength);\n\t },\n\t addCheckSum: function(){\n\t var that = this,\n\t value = that.value,\n\t length = value.length,\n\t cValue;\n\n\t cValue = that.getWeightedSum(value, length, that.cCheckSumTotal) % that.checkSumMod;\n\t that.checksum = cValue + \"\";\n\t that.addPattern(that.characterMap[cValue]);\n\n\t length++;\n\t if(length >= that.kCheckSumMinLength){\n\t var kValue = (cValue + that.getWeightedSum(value, length, that.kCheckSumTotal)) % that.checkSumMod;\n\t that.checksum += kValue;\n\t that.addPattern(that.characterMap[kValue]);\n\t }\n\t },\n\t getWeightedSum: function(value, length, total){\n\t var weightedSum = 0;\n\t for(var i = 0; i < value.length; i++){\n\t weightedSum+= this.weightedValue(this.getValue(value.charAt(i)), length, i, total);\n\t }\n\n\t return weightedSum;\n\t },\n\t weightedValue: function(value, length, index, total){\n\t var weight = (length - index) % total || total;\n\t return weight * value;\n\t },\n\t getValue: function(character){\n\t var that = this;\n\t if(!isNaN(character)){\n\t return parseInt(character,10);\n\t }\n\t else if(character !== that.DASH){\n\t that.invalidCharacterError(character);\n\t }\n\t return that.DASH_VALUE;\n\t },\n\t addCharacter: function(character){\n\t var that = this,\n\t value = that.getValue(character),\n\t pattern = that.characterMap[value];\n\t that.addPattern(pattern);\n\t },\n\t addPattern: function(pattern){\n\t var value;\n\t for(var i = 0; i < pattern.length; i++){\n\t value = parseInt(pattern.charAt(i),10);\n\t this.pattern.push(value);\n\t this.totalUnits+=value;\n\t }\n\t },\n\t characterMap: [\"111121\", \"211121\", \"121121\", \"221111\", \"112121\", \"212111\", \"122111\", \"111221\", \"211211\", \"211111\", \"112111\"],\n\t options: {\n\t addCheckSum: true\n\t }\n\t });\n\n\t encodings.postnet = Encoding.extend({\n\t name: \"Postnet\",\n\t START: \"2\",\n\t VALID_CODE_LENGTHS: [5,9, 11],\n\t DIGIT_SEPARATOR: \"-\",\n\t initValue: function(value, width, height){\n\t var that = this;\n\t that.height = height;\n\t that.width = width;\n\t that.baseHeight = height /2;\n\t that.value = value.replace(new RegExp(that.DIGIT_SEPARATOR,\"g\"), \"\");\n\t that.pattern = [];\n\t that.validate(that.value);\n\t that.checkSum = 0;\n\t that.setBaseUnit();\n\t },\n\t addData: function(){\n\t var that = this,\n\t value = that.value;\n\t that.addPattern(that.START);\n\n\t for(var i = 0; i < value.length; i++){\n\t that.addCharacter(value.charAt(i));\n\t }\n\n\t if(that.options.addCheckSum){\n\t that.addCheckSum();\n\t }\n\n\t that.addPattern(that.START);\n\t that.pattern.pop();\n\t },\n\t addCharacter: function(character){\n\t var that = this,\n\t pattern = that.characterMap[character];\n\t that.checkSum+= parseInt(character,10);\n\t that.addPattern(pattern);\n\t },\n\t addCheckSum: function(){\n\t var that = this;\n\t that.checksum = (10 - (that.checkSum % 10)) % 10;\n\t that.addCharacter(that.checksum);\n\t },\n\t setBaseUnit: function(){\n\t var that=this,\n\t startStopLength = 3;\n\t that.baseUnit = that.width / ((that.value.length + 1) * 10 + startStopLength + that.quietZoneLength);\n\t },\n\t validate: function(value){\n\t var that = this;\n\n\t if(!numberRegex.test(value)){\n\t that.invalidCharacterError(value.match(/[^0-9]/)[0]);\n\t }\n\t if(inArray(value.length, that.VALID_CODE_LENGTHS) < 0){\n\t throw new Error(\"Invalid value length. Valid lengths for the Postnet symbology are \" + that.VALID_CODE_LENGTHS.join(\",\"));\n\t }\n\t },\n\t addPattern: function(pattern){\n\t var that = this,\n\t y1;\n\t for(var i = 0; i < pattern.length; i++){\n\t y1 = that.height - that.baseHeight * pattern.charAt(i);\n\t that.pattern.push({width: 1, y1: y1, y2: that.height});\n\t that.pattern.push(1);\n\t }\n\t },\n\t characterMap: [\"22111\", \"11122\", \"11212\", \"11221\", \"12112\", \"12121\", \"12211\", \"21112\", \"21121\", \"21211\"]\n\t });\n\n\t encodings.ean13 = Encoding.extend({\n\t initValue: function(value, width, height){\n\t value+=\"\";\n\n\t if(value.length!=12 || /\\D/.test(value)){\n\t throw new Error('The value of the \"EAN13\" encoding should be 12 symbols');\n\t }\n\n\t var that = this;\n\t that.pattern = [];\n\t that.options.height = height;\n\t that.baseUnit = width /(95 + that.quietZoneLength);\n\t that.value = value;\n\t that.checksum = that.calculateChecksum();\n\t that.leftKey = value[0];\n\t that.leftPart = value.substr(1,6);\n\t that.rightPart = value.substr(7)+that.checksum;\n\t },\n\t addData: function(){\n\t var that = this;\n\t that.addPieces(that.characterMap.start);\n\t that.addSide(that.leftPart,that.leftKey);\n\t that.addPieces(that.characterMap.middle);\n\t that.addSide(that.rightPart);\n\t that.addPieces(that.characterMap.start);\n\t },\n\t addSide:function(leftPart,key){\n\t var that = this;\n\t for(var i = 0; i < leftPart.length; i++){\n\t if(key && parseInt(that.keyTable[key].charAt(i),10)){\n\t that.addPieces(Array.prototype.slice.call(that.characterMap.digits[leftPart.charAt(i)]).reverse(),true);\n\t }else{\n\t that.addPieces(that.characterMap.digits[leftPart.charAt(i)],true);\n\t }\n\t }\n\t },\n\t addPieces:function(arrToAdd,limitedHeight){\n\t var that = this;\n\t for(var i=0;i\").css(\"position\", \"relative\").appendTo(this.element);\n\t that.surface = draw.Surface.create(that.surfaceWrap, {\n\t type: that.options.renderAs\n\t });\n\t that._setOptions(options);\n\t if (options && defined(options.value)) {\n\t that.redraw();\n\t }\n\t },\n\n\t setOptions: function (options) {\n\t this._setOptions(options);\n\t this.redraw();\n\t },\n\n\t redraw: function () {\n\t var size = this._getSize();\n\n\t this.surface.clear();\n\t this.surface.setSize({\n\t width: size.width,\n\t height: size.height\n\t });\n\n\t this.createVisual();\n\t this.surface.draw(this.visual);\n\t },\n\n\t getSize: function() {\n\t return kendo.dimensions(this.element);\n\t },\n\n\t _resize: function() {\n\t this.redraw();\n\t },\n\n\t createVisual: function() {\n\t this.visual = this._render();\n\t },\n\n\t _render: function() {\n\t var that = this,\n\t options = that.options,\n\t value = options.value,\n\t textOptions = options.text,\n\t textMargin = dataviz.getSpacing(textOptions.margin),\n\t size = that._getSize(),\n\t border = options.border || {},\n\t encoding = that.encoding,\n\t contentBox = new Box2D(0, 0, size.width, size.height).unpad(border.width).unpad(options.padding),\n\t barHeight = contentBox.height(),\n\t result, textToDisplay,\n\t textHeight;\n\n\t var visual = new draw.Group();\n\n\t that.contentBox = contentBox;\n\t visual.append(that._getBackground(size));\n\n\t if (textOptions.visible) {\n\t textHeight = draw.util.measureText(value, { font: textOptions.font }).height;\n\t barHeight -= textHeight + textMargin.top + textMargin.bottom;\n\t }\n\n\t result = encoding.encode(value, contentBox.width(), barHeight);\n\n\t if (textOptions.visible) {\n\t textToDisplay = value;\n\t if (options.checksum && defined(encoding.checksum)) {\n\t textToDisplay += \" \" + encoding.checksum;\n\t }\n\n\t visual.append(that._getText(textToDisplay));\n\t }\n\n\t that.barHeight = barHeight;\n\t this._bandsGroup = this._getBands(result.pattern, result.baseUnit);\n\t visual.append(this._bandsGroup);\n\n\t return visual;\n\t },\n\n\t exportVisual: function() {\n\t return this._render();\n\t },\n\n\t _getSize: function() {\n\t var that = this,\n\t element = that.element,\n\t size = new geom.Size(DEFAULT_WIDTH, DEFAULT_HEIGHT);\n\n\t if (element.width() > 0) {\n\t size.width = element.width();\n\t }\n\t if (element.height() > 0) {\n\t size.height = element.height();\n\t }\n\t if (that.options.width) {\n\t size.width = that.options.width;\n\t }\n\t if (that.options.height) {\n\t size.height = that.options.height;\n\t }\n\n\t return size;\n\t },\n\n\t value: function(value) {\n\t var that = this;\n\t if (!defined(value)) {\n\t return that.options.value;\n\t }\n\t that.options.value = value + '';\n\t that.redraw();\n\t },\n\n\t _getBands: function (pattern, baseUnit) {\n\t var that = this,\n\t contentBox = that.contentBox,\n\t position = contentBox.x1,\n\t step,\n\t item;\n\n\t var group = new draw.Group();\n\t for (var i = 0; i < pattern.length; i++) {\n\t item = isPlainObject(pattern[i]) ? pattern[i] : {\n\t width: pattern[i],\n\t y1: 0,\n\t y2: that.barHeight\n\t };\n\n\t step = item.width * baseUnit;\n\n\t if (i%2) {\n\t var rect = geom.Rect.fromPoints(\n\t new geom.Point(position, item.y1 + contentBox.y1),\n\t new geom.Point(position + step, item.y2 + contentBox.y1)\n\t );\n\n\t var path = draw.Path.fromRect(rect, {\n\t fill: {\n\t color: that.options.color\n\t },\n\t stroke: null\n\t });\n\n\t group.append(path);\n\t }\n\n\t position += step;\n\t }\n\n\t return group;\n\t },\n\n\t _getBackground: function (size) {\n\t var that = this,\n\t options = that.options,\n\t border = options.border || {};\n\n\t var box = new Box2D(0,0, size.width, size.height).unpad(border.width / 2);\n\t var path = draw.Path.fromRect(box.toRect(), {\n\t fill: {\n\t color: options.background\n\t },\n\t stroke: {\n\t color: border.width ? border.color : \"\",\n\t width: border.width,\n\t dashType: border.dashType\n\t }\n\t });\n\n\t return path;\n\t },\n\n\t _getText: function(value) {\n\t var that = this,\n\t textOptions = that.options.text,\n\t text = that._textbox = new TextBox(value, {\n\t font: textOptions.font,\n\t color: textOptions.color,\n\t align: \"center\",\n\t vAlign: \"bottom\",\n\t margin: textOptions.margin\n\t });\n\n\t text.reflow(that.contentBox);\n\t text.renderVisual();\n\n\t return text.visual;\n\t },\n\n\t _setOptions: function (options) {\n\t var that = this;\n\t that.type = (options.type || that.options.type).toLowerCase();\n\n\t if (that.type==\"upca\") { //extend instead\n\t that.type = \"ean13\";\n\t options.value = '0' + options.value;\n\t }\n\n\t if (that.type==\"upce\") {\n\t that.type = \"ean8\";\n\t options.value = '0' + options.value;\n\t }\n\n\t if (!encodings[that.type]) {\n\t throw new Error('Encoding ' + that.type + 'is not supported.');\n\t }\n\n\t that.encoding = new encodings[that.type]();\n\n\t that.options = extend(true, that.options, options);\n\t },\n\n\t options: {\n\t name: \"Barcode\",\n\t renderAs: \"svg\",\n\t value: \"\",\n\t type: \"code39\",\n\t checksum: false,\n\t width: 0,\n\t height: 0,\n\t color: \"black\",\n\t background: \"white\",\n\t text: {\n\t visible: true,\n\t font: \"16px Consolas, Monaco, Sans Mono, monospace, sans-serif\",\n\t color: \"black\",\n\t margin: {\n\t top: 0,\n\t bottom: 0,\n\t left: 0,\n\t right: 0\n\t }\n\t },\n\t border: {\n\t width: 0,\n\t dashType: \"solid\",\n\t color: \"black\"\n\t },\n\t padding: {\n\t top: 0,\n\t bottom: 0,\n\t left: 0,\n\t right: 0\n\t }\n\t }\n\t });\n\t dataviz.ExportMixin.extend(Barcode.fn);\n\n\t dataviz.ui.plugin(Barcode);\n\n\t kendo.deepExtend(dataviz, {\n\t encodings: encodings,\n\t Encoding: Encoding\n\t });\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1091);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1091:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(1092),\n\t __webpack_require__(1093)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dataviz.chart\",\n\t name: \"Chart\",\n\t category: \"dataviz\",\n\t description: \"The Chart widget uses modern browser technologies to render high-quality data visualizations in the browser.\",\n\t depends: [ \"data\", \"userevents\", \"drawing\", \"dataviz.core\", \"dataviz.themes\" ],\n\t features: [{\n\t id: \"dataviz.chart-pdf-export\",\n\t name: \"PDF export\",\n\t description: \"Export Chart as PDF\",\n\t depends: [ \"pdf\" ]\n\t }]\n\t};\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1092:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/chart/kendo-chart\");\n\n/***/ }),\n\n/***/ 1093:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/chart/chart\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1094);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1094:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(1095),\n\t __webpack_require__(1096)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dataviz.core\",\n\t name: \"Core\",\n\t description: \"The DataViz core functions\",\n\t category: \"dataviz\",\n\t depends: [ \"core\", \"drawing\" ],\n\t hidden: true\n\t};\n\n\t}, __webpack_require__(3));\n\n/***/ }),\n\n/***/ 1095:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/core/kendo-core\");\n\n/***/ }),\n\n/***/ 1096:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/core/core\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1097);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1014:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.drawing\");\n\n/***/ }),\n\n/***/ 1027:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data\");\n\n/***/ }),\n\n/***/ 1037:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.mobile.scroller\");\n\n/***/ }),\n\n/***/ 1056:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.userevents\");\n\n/***/ }),\n\n/***/ 1077:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.draganddrop\");\n\n/***/ }),\n\n/***/ 1097:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\r\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\r\n\t __webpack_require__(1027), __webpack_require__(1077), __webpack_require__(1056), __webpack_require__(1037),\r\n\t __webpack_require__(1014),\r\n\r\n\t __webpack_require__(1098),\r\n\t __webpack_require__(1099),\r\n\t __webpack_require__(1100),\r\n\t __webpack_require__(1101),\r\n\t __webpack_require__(1102),\r\n\t __webpack_require__(1103)\r\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n\t})(function(){\r\n\r\n\t var __meta__ = { // jshint ignore:line\r\n\t id: \"dataviz.diagram\",\r\n\t name: \"Diagram\",\r\n\t category: \"dataviz\",\r\n\t description: \"The Kendo DataViz Diagram \",\r\n\t depends: [ \"data\", \"userevents\", \"mobile.scroller\", \"draganddrop\", \"drawing\", \"dataviz.core\", \"dataviz.themes\", \"toolbar\" ],\r\n\t features: [{\r\n\t id: \"dataviz.diagram-pdf-export\",\r\n\t name: \"PDF export\",\r\n\t description: \"Export Diagram as PDF\",\r\n\t depends: [ \"pdf\" ]\r\n\t },{\r\n\t id: \"dataviz.diagram-editing\",\r\n\t name: \"Editing\",\r\n\t description: \"Support for model editing\",\r\n\t depends: [ \"editable\", \"window\", \"dropdownlist\" ]\r\n\t }]\r\n\t };\r\n\r\n\t return window.kendo;\r\n\r\n\t}, __webpack_require__(3));\r\n\n\n/***/ }),\n\n/***/ 1098:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/diagram/utils\");\n\n/***/ }),\n\n/***/ 1099:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/diagram/math\");\n\n/***/ }),\n\n/***/ 1100:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/diagram/svg\");\n\n/***/ }),\n\n/***/ 1101:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/diagram/services\");\n\n/***/ }),\n\n/***/ 1102:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/diagram/layout\");\n\n/***/ }),\n\n/***/ 1103:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/diagram/dom\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1104);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1079:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.themes\");\n\n/***/ }),\n\n/***/ 1104:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1105), __webpack_require__(1079) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dataviz.gauge\",\n\t name: \"Gauge\",\n\t category: \"dataviz\",\n\t description: \"Linear, Radial and Arc gauges.\",\n\t depends: [ \"dataviz.core\", \"dataviz.themes\" ]\n\t};\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1105:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/gauge/main\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1070);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1014:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.drawing\");\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1027:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data\");\n\n/***/ }),\n\n/***/ 1037:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.mobile.scroller\");\n\n/***/ }),\n\n/***/ 1054:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.popup\");\n\n/***/ }),\n\n/***/ 1056:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.userevents\");\n\n/***/ }),\n\n/***/ 1065:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.odata\");\n\n/***/ }),\n\n/***/ 1066:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.xml\");\n\n/***/ }),\n\n/***/ 1070:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(1018),\n\t __webpack_require__(1072),\n\t __webpack_require__(1073),\n\t __webpack_require__(1074),\n\t __webpack_require__(1065),\n\t __webpack_require__(1066),\n\t __webpack_require__(1027),\n\t __webpack_require__(1075),\n\t __webpack_require__(1076),\n\t __webpack_require__(1056),\n\t __webpack_require__(1077),\n\t __webpack_require__(1037),\n\t __webpack_require__(1054),\n\t __webpack_require__(1071),\n\t __webpack_require__(1014),\n\t __webpack_require__(1078),\n\t __webpack_require__(1079),\n\t __webpack_require__(1080),\n\t __webpack_require__(1081),\n\t __webpack_require__(1082),\n\t __webpack_require__(1083),\n\t __webpack_require__(1084),\n\t __webpack_require__(1085),\n\t __webpack_require__(1086),\n\t __webpack_require__(1087),\n\t __webpack_require__(1088),\n\t __webpack_require__(1089)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\t \"bundle all\";\n\t return window.kendo;\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1071:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.tooltip\");\n\n/***/ }),\n\n/***/ 1072:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.fx\");\n\n/***/ }),\n\n/***/ 1073:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.router\");\n\n/***/ }),\n\n/***/ 1074:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.view\");\n\n/***/ }),\n\n/***/ 1075:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data.signalr\");\n\n/***/ }),\n\n/***/ 1076:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.binder\");\n\n/***/ }),\n\n/***/ 1077:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.draganddrop\");\n\n/***/ }),\n\n/***/ 1078:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 1079:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.themes\");\n\n/***/ }),\n\n/***/ 1080:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.chart\");\n\n/***/ }),\n\n/***/ 1081:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.gauge\");\n\n/***/ }),\n\n/***/ 1082:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.barcode\");\n\n/***/ }),\n\n/***/ 1083:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.qrcode\");\n\n/***/ }),\n\n/***/ 1084:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.stock\");\n\n/***/ }),\n\n/***/ 1085:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.sparkline\");\n\n/***/ }),\n\n/***/ 1086:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.map\");\n\n/***/ }),\n\n/***/ 1087:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.diagram\");\n\n/***/ }),\n\n/***/ 1088:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.treemap\");\n\n/***/ }),\n\n/***/ 1089:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.angular\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1106);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1027:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data\");\n\n/***/ }),\n\n/***/ 1037:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.mobile.scroller\");\n\n/***/ }),\n\n/***/ 1056:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.userevents\");\n\n/***/ }),\n\n/***/ 1071:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.tooltip\");\n\n/***/ }),\n\n/***/ 1077:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.draganddrop\");\n\n/***/ }),\n\n/***/ 1078:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 1106:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(1027), __webpack_require__(1056), __webpack_require__(1071), __webpack_require__(1037), __webpack_require__(1077),\n\t __webpack_require__(1078),\n\n\t __webpack_require__(1108),\n\t __webpack_require__(1109),\n\t __webpack_require__(1110),\n\t __webpack_require__(1107),\n\t __webpack_require__(1111),\n\t __webpack_require__(1112),\n\t __webpack_require__(1113),\n\t __webpack_require__(1114),\n\t __webpack_require__(1115),\n\t __webpack_require__(1116),\n\t __webpack_require__(1117),\n\t __webpack_require__(1118)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t var __meta__ = { // jshint ignore:line\n\t id: \"dataviz.map\",\n\t name: \"Map\",\n\t category: \"dataviz\",\n\t description: \"The Kendo DataViz Map displays spatial data\",\n\t depends: [ \"data\", \"userevents\", \"tooltip\", \"dataviz.core\", \"drawing\", \"mobile.scroller\" ]\n\t };\n\n\t return window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1107:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/zoom\");\n\n/***/ }),\n\n/***/ 1108:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/location\");\n\n/***/ }),\n\n/***/ 1109:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/attribution\");\n\n/***/ }),\n\n/***/ 1110:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/navigator\");\n\n/***/ }),\n\n/***/ 1111:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/crs\");\n\n/***/ }),\n\n/***/ 1112:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/layers/base\");\n\n/***/ }),\n\n/***/ 1113:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/layers/shape\");\n\n/***/ }),\n\n/***/ 1114:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/layers/bubble\");\n\n/***/ }),\n\n/***/ 1115:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/layers/tile\");\n\n/***/ }),\n\n/***/ 1116:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/layers/bing\");\n\n/***/ }),\n\n/***/ 1117:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/layers/marker\");\n\n/***/ }),\n\n/***/ 1118:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/map/main\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1120);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1014:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.drawing\");\n\n/***/ }),\n\n/***/ 1078:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 1120:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1078), __webpack_require__(1014) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dataviz.qrcode\",\n\t name: \"QRCode\",\n\t category: \"dataviz\",\n\t description: \"QRCode widget.\",\n\t depends: [ \"dataviz.core\", \"drawing\" ]\n\t};\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t extend = $.extend,\n\t draw = kendo.drawing,\n\t dataviz = kendo.dataviz,\n\t Widget = kendo.ui.Widget,\n\t Box2D = dataviz.Box2D,\n\t terminator = \"0000\",\n\t NUMERIC = \"numeric\",\n\t ALPHA_NUMERIC = \"alphanumeric\",\n\t BYTE = \"byte\",\n\t powersOfTwo = {\"1\": 0},\n\t powersOfTwoResult = {\"0\": 1},\n\t generatorPolynomials = [[1,0],[1,25,0]],\n\t irregularAlignmentPatternsStartDistance = {15:20,16:20,18:24,19:24,22:20,24:22,26:24,28:20,30:20,31:24,32:28,33:24,36:18,37:22,39:20,40:24},\n\t versionsCodewordsInformation = [{L:{groups:[[1,19]],totalDataCodewords:19,errorCodewordsPerBlock:7},M:{groups:[[1,16]],totalDataCodewords:16,errorCodewordsPerBlock:10},Q:{groups:[[1,13]],totalDataCodewords:13,errorCodewordsPerBlock:13},H:{groups:[[1,9]],totalDataCodewords:9,errorCodewordsPerBlock:17}},{L:{groups:[[1,34]],totalDataCodewords:34,errorCodewordsPerBlock:10},M:{groups:[[1,28]],totalDataCodewords:28,errorCodewordsPerBlock:16},Q:{groups:[[1,22]],totalDataCodewords:22,errorCodewordsPerBlock:22},H:{groups:[[1,16]],totalDataCodewords:16,errorCodewordsPerBlock:28}},{L:{groups:[[1,55]],totalDataCodewords:55,errorCodewordsPerBlock:15},M:{groups:[[1,44]],totalDataCodewords:44,errorCodewordsPerBlock:26},Q:{groups:[[2,17]],totalDataCodewords:34,errorCodewordsPerBlock:18},H:{groups:[[2,13]],totalDataCodewords:26,errorCodewordsPerBlock:22}},{L:{groups:[[1,80]],totalDataCodewords:80,errorCodewordsPerBlock:20},M:{groups:[[2,32]],totalDataCodewords:64,errorCodewordsPerBlock:18},Q:{groups:[[2,24]],totalDataCodewords:48,errorCodewordsPerBlock:26},H:{groups:[[4,9]],totalDataCodewords:36,errorCodewordsPerBlock:16}},{L:{groups:[[1,108]],totalDataCodewords:108,errorCodewordsPerBlock:26},M:{groups:[[2,43]],totalDataCodewords:86,errorCodewordsPerBlock:24},Q:{groups:[[2,15],[2,16]],totalDataCodewords:62,errorCodewordsPerBlock:18},H:{groups:[[2,11],[2,12]],totalDataCodewords:46,errorCodewordsPerBlock:22}},{L:{groups:[[2,68]],totalDataCodewords:136,errorCodewordsPerBlock:18},M:{groups:[[4,27]],totalDataCodewords:108,errorCodewordsPerBlock:16},Q:{groups:[[4,19]],totalDataCodewords:76,errorCodewordsPerBlock:24},H:{groups:[[4,15]],totalDataCodewords:60,errorCodewordsPerBlock:28}},{L:{groups:[[2,78]],totalDataCodewords:156,errorCodewordsPerBlock:20},M:{groups:[[4,31]],totalDataCodewords:124,errorCodewordsPerBlock:18},Q:{groups:[[2,14],[4,15]],totalDataCodewords:88,errorCodewordsPerBlock:18},H:{groups:[[4,13],[1,14]],totalDataCodewords:66,errorCodewordsPerBlock:26}},{L:{groups:[[2,97]],totalDataCodewords:194,errorCodewordsPerBlock:24},M:{groups:[[2,38],[2,39]],totalDataCodewords:154,errorCodewordsPerBlock:22},Q:{groups:[[4,18],[2,19]],totalDataCodewords:110,errorCodewordsPerBlock:22},H:{groups:[[4,14],[2,15]],totalDataCodewords:86,errorCodewordsPerBlock:26}},{L:{groups:[[2,116]],totalDataCodewords:232,errorCodewordsPerBlock:30},M:{groups:[[3,36],[2,37]],totalDataCodewords:182,errorCodewordsPerBlock:22},Q:{groups:[[4,16],[4,17]],totalDataCodewords:132,errorCodewordsPerBlock:20},H:{groups:[[4,12],[4,13]],totalDataCodewords:100,errorCodewordsPerBlock:24}},{L:{groups:[[2,68],[2,69]],totalDataCodewords:274,errorCodewordsPerBlock:18},M:{groups:[[4,43],[1,44]],totalDataCodewords:216,errorCodewordsPerBlock:26},Q:{groups:[[6,19],[2,20]],totalDataCodewords:154,errorCodewordsPerBlock:24},H:{groups:[[6,15],[2,16]],totalDataCodewords:122,errorCodewordsPerBlock:28}},{L:{groups:[[4,81]],totalDataCodewords:324,errorCodewordsPerBlock:20},M:{groups:[[1,50],[4,51]],totalDataCodewords:254,errorCodewordsPerBlock:30},Q:{groups:[[4,22],[4,23]],totalDataCodewords:180,errorCodewordsPerBlock:28},H:{groups:[[3,12],[8,13]],totalDataCodewords:140,errorCodewordsPerBlock:24}},{L:{groups:[[2,92],[2,93]],totalDataCodewords:370,errorCodewordsPerBlock:24},M:{groups:[[6,36],[2,37]],totalDataCodewords:290,errorCodewordsPerBlock:22},Q:{groups:[[4,20],[6,21]],totalDataCodewords:206,errorCodewordsPerBlock:26},H:{groups:[[7,14],[4,15]],totalDataCodewords:158,errorCodewordsPerBlock:28}},{L:{groups:[[4,107]],totalDataCodewords:428,errorCodewordsPerBlock:26},M:{groups:[[8,37],[1,38]],totalDataCodewords:334,errorCodewordsPerBlock:22},Q:{groups:[[8,20],[4,21]],totalDataCodewords:244,errorCodewordsPerBlock:24},H:{groups:[[12,11],[4,12]],totalDataCodewords:180,errorCodewordsPerBlock:22}},{L:{groups:[[3,115],[1,116]],totalDataCodewords:461,errorCodewordsPerBlock:30},M:{groups:[[4,40],[5,41]],totalDataCodewords:365,errorCodewordsPerBlock:24},Q:{groups:[[11,16],[5,17]],totalDataCodewords:261,errorCodewordsPerBlock:20},H:{groups:[[11,12],[5,13]],totalDataCodewords:197,errorCodewordsPerBlock:24}},{L:{groups:[[5,87],[1,88]],totalDataCodewords:523,errorCodewordsPerBlock:22},M:{groups:[[5,41],[5,42]],totalDataCodewords:415,errorCodewordsPerBlock:24},Q:{groups:[[5,24],[7,25]],totalDataCodewords:295,errorCodewordsPerBlock:30},H:{groups:[[11,12],[7,13]],totalDataCodewords:223,errorCodewordsPerBlock:24}},{L:{groups:[[5,98],[1,99]],totalDataCodewords:589,errorCodewordsPerBlock:24},M:{groups:[[7,45],[3,46]],totalDataCodewords:453,errorCodewordsPerBlock:28},Q:{groups:[[15,19],[2,20]],totalDataCodewords:325,errorCodewordsPerBlock:24},H:{groups:[[3,15],[13,16]],totalDataCodewords:253,errorCodewordsPerBlock:30}},{L:{groups:[[1,107],[5,108]],totalDataCodewords:647,errorCodewordsPerBlock:28},M:{groups:[[10,46],[1,47]],totalDataCodewords:507,errorCodewordsPerBlock:28},Q:{groups:[[1,22],[15,23]],totalDataCodewords:367,errorCodewordsPerBlock:28},H:{groups:[[2,14],[17,15]],totalDataCodewords:283,errorCodewordsPerBlock:28}},{L:{groups:[[5,120],[1,121]],totalDataCodewords:721,errorCodewordsPerBlock:30},M:{groups:[[9,43],[4,44]],totalDataCodewords:563,errorCodewordsPerBlock:26},Q:{groups:[[17,22],[1,23]],totalDataCodewords:397,errorCodewordsPerBlock:28},H:{groups:[[2,14],[19,15]],totalDataCodewords:313,errorCodewordsPerBlock:28}},{L:{groups:[[3,113],[4,114]],totalDataCodewords:795,errorCodewordsPerBlock:28},M:{groups:[[3,44],[11,45]],totalDataCodewords:627,errorCodewordsPerBlock:26},Q:{groups:[[17,21],[4,22]],totalDataCodewords:445,errorCodewordsPerBlock:26},H:{groups:[[9,13],[16,14]],totalDataCodewords:341,errorCodewordsPerBlock:26}},{L:{groups:[[3,107],[5,108]],totalDataCodewords:861,errorCodewordsPerBlock:28},M:{groups:[[3,41],[13,42]],totalDataCodewords:669,errorCodewordsPerBlock:26},Q:{groups:[[15,24],[5,25]],totalDataCodewords:485,errorCodewordsPerBlock:30},H:{groups:[[15,15],[10,16]],totalDataCodewords:385,errorCodewordsPerBlock:28}},{L:{groups:[[4,116],[4,117]],totalDataCodewords:932,errorCodewordsPerBlock:28},M:{groups:[[17,42]],totalDataCodewords:714,errorCodewordsPerBlock:26},Q:{groups:[[17,22],[6,23]],totalDataCodewords:512,errorCodewordsPerBlock:28},H:{groups:[[19,16],[6,17]],totalDataCodewords:406,errorCodewordsPerBlock:30}},{L:{groups:[[2,111],[7,112]],totalDataCodewords:1006,errorCodewordsPerBlock:28},M:{groups:[[17,46]],totalDataCodewords:782,errorCodewordsPerBlock:28},Q:{groups:[[7,24],[16,25]],totalDataCodewords:568,errorCodewordsPerBlock:30},H:{groups:[[34,13]],totalDataCodewords:442,errorCodewordsPerBlock:24}},{L:{groups:[[4,121],[5,122]],totalDataCodewords:1094,errorCodewordsPerBlock:30},M:{groups:[[4,47],[14,48]],totalDataCodewords:860,errorCodewordsPerBlock:28},Q:{groups:[[11,24],[14,25]],totalDataCodewords:614,errorCodewordsPerBlock:30},H:{groups:[[16,15],[14,16]],totalDataCodewords:464,errorCodewordsPerBlock:30}},{L:{groups:[[6,117],[4,118]],totalDataCodewords:1174,errorCodewordsPerBlock:30},M:{groups:[[6,45],[14,46]],totalDataCodewords:914,errorCodewordsPerBlock:28},Q:{groups:[[11,24],[16,25]],totalDataCodewords:664,errorCodewordsPerBlock:30},H:{groups:[[30,16],[2,17]],totalDataCodewords:514,errorCodewordsPerBlock:30}},{L:{groups:[[8,106],[4,107]],totalDataCodewords:1276,errorCodewordsPerBlock:26},M:{groups:[[8,47],[13,48]],totalDataCodewords:1000,errorCodewordsPerBlock:28},Q:{groups:[[7,24],[22,25]],totalDataCodewords:718,errorCodewordsPerBlock:30},H:{groups:[[22,15],[13,16]],totalDataCodewords:538,errorCodewordsPerBlock:30}},{L:{groups:[[10,114],[2,115]],totalDataCodewords:1370,errorCodewordsPerBlock:28},M:{groups:[[19,46],[4,47]],totalDataCodewords:1062,errorCodewordsPerBlock:28},Q:{groups:[[28,22],[6,23]],totalDataCodewords:754,errorCodewordsPerBlock:28},H:{groups:[[33,16],[4,17]],totalDataCodewords:596,errorCodewordsPerBlock:30}},{L:{groups:[[8,122],[4,123]],totalDataCodewords:1468,errorCodewordsPerBlock:30},M:{groups:[[22,45],[3,46]],totalDataCodewords:1128,errorCodewordsPerBlock:28},Q:{groups:[[8,23],[26,24]],totalDataCodewords:808,errorCodewordsPerBlock:30},H:{groups:[[12,15],[28,16]],totalDataCodewords:628,errorCodewordsPerBlock:30}},{L:{groups:[[3,117],[10,118]],totalDataCodewords:1531,errorCodewordsPerBlock:30},M:{groups:[[3,45],[23,46]],totalDataCodewords:1193,errorCodewordsPerBlock:28},Q:{groups:[[4,24],[31,25]],totalDataCodewords:871,errorCodewordsPerBlock:30},H:{groups:[[11,15],[31,16]],totalDataCodewords:661,errorCodewordsPerBlock:30}},{L:{groups:[[7,116],[7,117]],totalDataCodewords:1631,errorCodewordsPerBlock:30},M:{groups:[[21,45],[7,46]],totalDataCodewords:1267,errorCodewordsPerBlock:28},Q:{groups:[[1,23],[37,24]],totalDataCodewords:911,errorCodewordsPerBlock:30},H:{groups:[[19,15],[26,16]],totalDataCodewords:701,errorCodewordsPerBlock:30}},{L:{groups:[[5,115],[10,116]],totalDataCodewords:1735,errorCodewordsPerBlock:30},M:{groups:[[19,47],[10,48]],totalDataCodewords:1373,errorCodewordsPerBlock:28},Q:{groups:[[15,24],[25,25]],totalDataCodewords:985,errorCodewordsPerBlock:30},H:{groups:[[23,15],[25,16]],totalDataCodewords:745,errorCodewordsPerBlock:30}},{L:{groups:[[13,115],[3,116]],totalDataCodewords:1843,errorCodewordsPerBlock:30},M:{groups:[[2,46],[29,47]],totalDataCodewords:1455,errorCodewordsPerBlock:28},Q:{groups:[[42,24],[1,25]],totalDataCodewords:1033,errorCodewordsPerBlock:30},H:{groups:[[23,15],[28,16]],totalDataCodewords:793,errorCodewordsPerBlock:30}},{L:{groups:[[17,115]],totalDataCodewords:1955,errorCodewordsPerBlock:30},M:{groups:[[10,46],[23,47]],totalDataCodewords:1541,errorCodewordsPerBlock:28},Q:{groups:[[10,24],[35,25]],totalDataCodewords:1115,errorCodewordsPerBlock:30},H:{groups:[[19,15],[35,16]],totalDataCodewords:845,errorCodewordsPerBlock:30}},{L:{groups:[[17,115],[1,116]],totalDataCodewords:2071,errorCodewordsPerBlock:30},M:{groups:[[14,46],[21,47]],totalDataCodewords:1631,errorCodewordsPerBlock:28},Q:{groups:[[29,24],[19,25]],totalDataCodewords:1171,errorCodewordsPerBlock:30},H:{groups:[[11,15],[46,16]],totalDataCodewords:901,errorCodewordsPerBlock:30}},{L:{groups:[[13,115],[6,116]],totalDataCodewords:2191,errorCodewordsPerBlock:30},M:{groups:[[14,46],[23,47]],totalDataCodewords:1725,errorCodewordsPerBlock:28},Q:{groups:[[44,24],[7,25]],totalDataCodewords:1231,errorCodewordsPerBlock:30},H:{groups:[[59,16],[1,17]],totalDataCodewords:961,errorCodewordsPerBlock:30}},{L:{groups:[[12,121],[7,122]],totalDataCodewords:2306,errorCodewordsPerBlock:30},M:{groups:[[12,47],[26,48]],totalDataCodewords:1812,errorCodewordsPerBlock:28},Q:{groups:[[39,24],[14,25]],totalDataCodewords:1286,errorCodewordsPerBlock:30},H:{groups:[[22,15],[41,16]],totalDataCodewords:986,errorCodewordsPerBlock:30}},{L:{groups:[[6,121],[14,122]],totalDataCodewords:2434,errorCodewordsPerBlock:30},M:{groups:[[6,47],[34,48]],totalDataCodewords:1914,errorCodewordsPerBlock:28},Q:{groups:[[46,24],[10,25]],totalDataCodewords:1354,errorCodewordsPerBlock:30},H:{groups:[[2,15],[64,16]],totalDataCodewords:1054,errorCodewordsPerBlock:30}},{L:{groups:[[17,122],[4,123]],totalDataCodewords:2566,errorCodewordsPerBlock:30},M:{groups:[[29,46],[14,47]],totalDataCodewords:1992,errorCodewordsPerBlock:28},Q:{groups:[[49,24],[10,25]],totalDataCodewords:1426,errorCodewordsPerBlock:30},H:{groups:[[24,15],[46,16]],totalDataCodewords:1096,errorCodewordsPerBlock:30}},{L:{groups:[[4,122],[18,123]],totalDataCodewords:2702,errorCodewordsPerBlock:30},M:{groups:[[13,46],[32,47]],totalDataCodewords:2102,errorCodewordsPerBlock:28},Q:{groups:[[48,24],[14,25]],totalDataCodewords:1502,errorCodewordsPerBlock:30},H:{groups:[[42,15],[32,16]],totalDataCodewords:1142,errorCodewordsPerBlock:30}},{L:{groups:[[20,117],[4,118]],totalDataCodewords:2812,errorCodewordsPerBlock:30},M:{groups:[[40,47],[7,48]],totalDataCodewords:2216,errorCodewordsPerBlock:28},Q:{groups:[[43,24],[22,25]],totalDataCodewords:1582,errorCodewordsPerBlock:30},H:{groups:[[10,15],[67,16]],totalDataCodewords:1222,errorCodewordsPerBlock:30}},{L:{groups:[[19,118],[6,119]],totalDataCodewords:2956,errorCodewordsPerBlock:30},M:{groups:[[18,47],[31,48]],totalDataCodewords:2334,errorCodewordsPerBlock:28},Q:{groups:[[34,24],[34,25]],totalDataCodewords:1666,errorCodewordsPerBlock:30},H:{groups:[[20,15],[61,16]],totalDataCodewords:1276,errorCodewordsPerBlock:30}}],\n\t finderPattern = [1,0,1,1,1],\n\t alignmentPattern = [1,0,1],\n\t errorCorrectionPatterns = {L: \"01\", M: \"00\", Q: \"11\", H: \"10\"},\n\t formatMaskPattern = \"101010000010010\",\n\t formatGeneratorPolynomial = \"10100110111\",\n\t versionGeneratorPolynomial = \"1111100100101\",\n\t paddingCodewords = [\"11101100\", \"00010001\"],\n\t finderPatternValue = 93,\n\t maskPatternConditions = [\n\t function(row,column){return (row + column) % 2 === 0;},\n\t function(row){return row % 2 === 0;},\n\t function(row,column){return column % 3 === 0;},\n\t function(row,column){return (row + column) % 3 === 0;},\n\t function(row,column){return (Math.floor(row/2) + Math.floor(column/3)) % 2 === 0;},\n\t function(row,column){return ((row * column) % 2) + ((row * column) % 3) === 0;},\n\t function(row,column){return (((row * column) % 2) + ((row * column) % 3)) % 2 === 0;},\n\t function(row,column){return (((row + column) % 2) + ((row * column) % 3)) % 2 === 0;}\n\t ],\n\t numberRegex = /^\\d+/,\n\t alphaPattern = \"A-Z0-9 $%*+./:-\",\n\t alphaExclusiveSet = \"A-Z $%*+./:-\",\n\t alphaRegex = new RegExp(\"^[\" + alphaExclusiveSet + \"]+\"),\n\t alphaNumericRegex = new RegExp(\"^[\" + alphaPattern+ \"]+\"),\n\t byteRegex = new RegExp(\"^[^\" + alphaPattern+ \"]+\"),\n\t initMinNumericBeforeAlpha = 8,\n\t initMinNumericBeforeByte = 5,\n\t initMinAlphaBeforeByte = 8,\n\t minNumericBeforeAlpha = 17,\n\t minNumericBeforeByte = 9,\n\t minAlphaBeforeByte = 16,\n\t round = Math.round;\n\n\t function toDecimal(value){\n\t return parseInt(value, 2);\n\t }\n\n\t function toBitsString(value, length){\n\t var result = Number(value).toString(2);\n\t if(result.length < length){\n\t result = new Array(length - result.length + 1).join(0) + result;\n\t }\n\t return result;\n\t }\n\n\t function splitInto(str, n){\n\t var result = [],\n\t idx = 0;\n\t while(idx < str.length){\n\t result.push(str.substring(idx, idx + n));\n\t idx+= n;\n\t }\n\t return result;\n\t }\n\n\t var QRDataMode = kendo.Class.extend({\n\t getVersionIndex: function(version){\n\t if(version < 10){\n\t return 0;\n\t }\n\t else if(version > 26){\n\t return 2;\n\t }\n\n\t return 1;\n\t },\n\t getBitsCharacterCount: function(version){\n\t var mode = this;\n\t return mode.bitsInCharacterCount[mode.getVersionIndex(version || 40)];\n\t },\n\t getModeCountString: function(length, version){\n\t var mode = this;\n\t return mode.modeIndicator + toBitsString(length, mode.getBitsCharacterCount(version));\n\t },\n\t encode: function(){},\n\t getStringBitsLength: function(){},\n\t getValue: function(){},\n\t modeIndicator: \"\",\n\t bitsInCharacterCount: []\n\t });\n\n\t var modes = {};\n\t modes[NUMERIC] = QRDataMode.extend({\n\t bitsInCharacterCount: [10, 12, 14],\n\t modeIndicator: \"0001\",\n\t getValue: function(character){\n\t return parseInt(character, 10);\n\t },\n\t encode: function(str, version){\n\t var mode = this,\n\t parts = splitInto(str, 3),\n\t result = mode.getModeCountString(str.length, version);\n\n\t for(var i = 0; i < parts.length - 1; i++){\n\t result += toBitsString(parts[i], 10);\n\t }\n\t return result + toBitsString(parts[i], 1 + 3 * parts[i].length);\n\t },\n\t getStringBitsLength: function(inputLength, version){\n\t var mod3 = inputLength % 3;\n\t return 4 + this.getBitsCharacterCount(version) + 10 * Math.floor(inputLength / 3) + 3 * mod3 + (mod3 === 0 ? 0 : 1);\n\t }\n\t });\n\n\t modes[ALPHA_NUMERIC] = QRDataMode.extend({\n\t characters: {\"0\":0,\"1\": 1,\"2\": 2,\"3\": 3,\"4\": 4,\"5\": 5,\"6\": 6,\"7\": 7,\"8\": 8,\"9\": 9,\"A\": 10,\"B\": 11,\"C\": 12,\"D\": 13,\"E\": 14,\"F\": 15,\"G\": 16,\"H\": 17,\"I\": 18,\"J\": 19,\"K\": 20,\"L\": 21,\"M\": 22,\"N\": 23,\"O\": 24,\"P\": 25,\"Q\": 26,\"R\": 27,\"S\": 28,\"T\": 29,\"U\": 30,\"V\": 31,\"W\": 32,\"X\": 33,\"Y\": 34,\"Z\": 35,\" \": 36,\"$\": 37,\"%\": 38,\"*\": 39,\"+\": 40,\"-\": 41,\".\": 42,\"/\": 43,\":\": 44},\n\t bitsInCharacterCount: [9,11,13],\n\t modeIndicator: \"0010\",\n\t getValue: function(character){\n\t return this.characters[character];\n\t },\n\t encode: function(str, version){\n\t var mode = this,\n\t parts = splitInto(str, 2),\n\t result = mode.getModeCountString(str.length, version),\n\t value;\n\t for(var i = 0; i < parts.length - 1; i++){\n\t value = 45 * mode.getValue(parts[i].charAt(0)) + mode.getValue(parts[i].charAt(1));\n\t result += toBitsString(value, 11);\n\t }\n\t value = parts[i].length == 2 ?\n\t 45 * mode.getValue(parts[i].charAt(0)) + mode.getValue(parts[i].charAt(1)) :\n\t mode.getValue(parts[i].charAt(0));\n\t return result + toBitsString(value, 1 + 5 * parts[i].length);\n\t },\n\t getStringBitsLength: function(inputLength, version){\n\t return 4 + this.getBitsCharacterCount(version) + 11 * Math.floor(inputLength / 2) + 6 * (inputLength % 2);\n\t }\n\t });\n\n\t modes[BYTE] = QRDataMode.extend({\n\t bitsInCharacterCount: [8,16,16],\n\t modeIndicator: \"0100\",\n\t getValue: function(character){\n\t var code = character.charCodeAt(0);\n\t if(code <= 127 || (160 <= code && code <= 255)){\n\t return code;\n\t }\n\t else{\n\t throw new Error(\"Unsupported character: \" + character);\n\t }\n\t },\n\t encode: function(str, version){\n\t var mode = this,\n\t result = mode.getModeCountString(str.length, version);\n\n\t for(var i = 0; i < str.length; i++){\n\t result += toBitsString(mode.getValue(str.charAt(i)), 8);\n\t }\n\t return result;\n\t },\n\t getStringBitsLength: function(inputLength, version){\n\t return 4 + this.getBitsCharacterCount(version) + 8 * inputLength;\n\t }\n\t });\n\n\t var modeInstances = {};\n\t for(var mode in modes){\n\t modeInstances[mode] = new modes[mode]();\n\t }\n\n\t var FreeCellVisitor = function (matrix){\n\t var that = this,\n\t row = matrix.length - 1,\n\t column = matrix.length - 1,\n\t startColumn = column,\n\t dir = -1,\n\t c = 0;\n\t that.move = function(){\n\t row += dir * c;\n\t c^=1;\n\t column = startColumn - c;\n\t };\n\t that.getNextCell = function(){\n\t while(matrix[row][column] !== undefined){\n\t that.move();\n\t if(row < 0 || row >= matrix.length){\n\t dir = -dir;\n\t startColumn-= startColumn != 8 ? 2 : 3;\n\t column = startColumn;\n\t row = dir < 0 ? matrix.length - 1 : 0;\n\t }\n\t }\n\t return {row: row, column: column};\n\t };\n\t that.getNextRemainderCell = function(){\n\t that.move();\n\t if(matrix[row][column] === undefined){\n\t return {row: row, column: column};\n\t }\n\t };\n\t };\n\n\t function fillFunctionCell(matrices, bit, x, y){\n\t for(var i = 0; i< matrices.length;i++){\n\t matrices[i][x][y] = bit;\n\t }\n\t }\n\n\t function fillDataCell(matrices, bit, x, y){\n\t for(var i = 0; i < maskPatternConditions.length;i++){\n\t matrices[i][x][y] = maskPatternConditions[i](x,y) ? bit ^ 1 : parseInt(bit, 10);\n\t }\n\t }\n\n\t var fillData = function (matrices, blocks){\n\t var cellVisitor = new FreeCellVisitor(matrices[0]),\n\t block,\n\t codewordIdx,\n\t cell;\n\n\t for(var blockIdx = 0; blockIdx < blocks.length;blockIdx++){\n\t block = blocks[blockIdx];\n\t codewordIdx = 0;\n\t while(block.length > 0){\n\t for(var i = 0; i< block.length; i++){\n\t for(var j = 0; j < 8;j++){\n\t cell = cellVisitor.getNextCell();\n\t fillDataCell(matrices, block[i][codewordIdx].charAt(j), cell.row, cell.column);\n\t }\n\t }\n\n\t codewordIdx++;\n\t while(block[0] && codewordIdx == block[0].length){\n\t block.splice(0,1);\n\t }\n\t }\n\t }\n\n\t while((cell = cellVisitor.getNextRemainderCell())){\n\t fillDataCell(matrices, 0, cell.row, cell.column);\n\t }\n\t };\n\n\t var padDataString = function (dataString, totalDataCodewords){\n\t var dataBitsCount = totalDataCodewords * 8,\n\t terminatorIndex = 0,\n\t paddingCodewordIndex = 0;\n\t while(dataString.length < dataBitsCount && terminatorIndex < terminator.length){\n\t dataString+=terminator.charAt(terminatorIndex++);\n\t }\n\n\t if(dataString.length % 8 !== 0){\n\t dataString+= new Array(9 - dataString.length % 8).join(\"0\");\n\t }\n\n\t while(dataString.length < dataBitsCount){\n\t dataString+= paddingCodewords[paddingCodewordIndex];\n\t paddingCodewordIndex ^= 1;\n\t }\n\t return dataString;\n\t };\n\n\t function generatePowersOfTwo(){\n\t var result;\n\t for(var power = 1; power < 255; power++){\n\n\t result = powersOfTwoResult[power - 1] * 2;\n\t if(result > 255){\n\t result = result ^ 285;\n\t }\n\n\t powersOfTwoResult[power] = result;\n\t powersOfTwo[result] = power;\n\t }\n\n\t result = (powersOfTwoResult[power - 1] * 2) ^ 285;\n\t powersOfTwoResult[power] = result;\n\t powersOfTwoResult[-1] = 0;\n\t }\n\n\t var xorPolynomials = function (x,y){\n\t var result = [],\n\t idx = x.length - 2;\n\t for(var i = idx; i>=0; i--){\n\t result[i] = x[i] ^ y[i];\n\t }\n\n\t return result;\n\t };\n\n\t var multiplyPolynomials = function (x, y){\n\t var result = [];\n\t for(var i = 0; i < x.length; i++){\n\t for(var j = 0; j < y.length; j++){\n\t if(result[i+j] === undefined){\n\t result[i+j] = (x[i] + (y[j] >= 0 ? y[j] : 0)) % 255;\n\t }\n\t else{\n\t result[i+j] = powersOfTwo[powersOfTwoResult[result[i+j]] ^ powersOfTwoResult[(x[i] + y[j]) % 255]];\n\t }\n\t }\n\t }\n\n\t return result;\n\t };\n\n\t function generateGeneratorPolynomials(){\n\t var maxErrorCorrectionCodeWordsCount = 68;\n\t for(var idx = 2; idx <= maxErrorCorrectionCodeWordsCount; idx++){\n\t var firstPolynomial = generatorPolynomials[idx - 1],\n\t secondPolynomial = [idx, 0];\n\t generatorPolynomials[idx] = multiplyPolynomials(firstPolynomial, secondPolynomial);\n\t }\n\t }\n\n\t //possibly generate on demand\n\t generatePowersOfTwo();\n\t generateGeneratorPolynomials();\n\n\t function multiplyByConstant(polynomial, power){\n\t var result = [],\n\t idx = polynomial.length - 1;\n\t do{\n\t result[idx] = powersOfTwoResult[(polynomial[idx] + power) % 255];\n\t idx--;\n\t }while(polynomial[idx] !== undefined);\n\n\t return result;\n\t }\n\n\t var generateErrorCodewords = function (data, errorCodewordsCount){\n\t var generator = generatorPolynomials[errorCodewordsCount - 1],\n\t result = new Array(errorCodewordsCount).concat(data),\n\t generatorPolynomial = new Array(result.length - generator.length).concat(generator),\n\t steps = data.length,\n\t errorCodewords = [],\n\t divisor,\n\t idx;\n\n\t for(idx = 0; idx < steps; idx++){\n\t divisor = multiplyByConstant(generatorPolynomial, powersOfTwo[result[result.length - 1]]);\n\t generatorPolynomial.splice(0,1);\n\n\t result = xorPolynomials(divisor, result);\n\t }\n\n\t for(idx = result.length - 1; idx >= 0;idx--){\n\t errorCodewords[errorCodewordsCount - 1 - idx] = toBitsString(result[idx], 8);\n\t }\n\n\t return errorCodewords;\n\t };\n\n\t var getBlocks = function (dataStream, versionCodewordsInformation){\n\t var codewordStart = 0,\n\t dataBlocks = [],\n\t errorBlocks = [],\n\t dataBlock,\n\t versionGroups = versionCodewordsInformation.groups,\n\t blockCodewordsCount,\n\t groupBlocksCount,\n\t messagePolynomial,\n\t codeword;\n\n\t for(var groupIdx = 0; groupIdx < versionGroups.length; groupIdx++){\n\t groupBlocksCount = versionGroups[groupIdx][0];\n\t for(var blockIdx = 0; blockIdx < groupBlocksCount;blockIdx++){\n\t blockCodewordsCount = versionGroups[groupIdx][1];\n\t dataBlock = [];\n\t messagePolynomial = [];\n\t for(var codewordIdx = 1; codewordIdx <= blockCodewordsCount; codewordIdx++){\n\t codeword = dataStream.substring(codewordStart, codewordStart + 8);\n\t dataBlock.push(codeword);\n\t messagePolynomial[blockCodewordsCount - codewordIdx] = toDecimal(codeword);\n\t codewordStart+=8;\n\t }\n\t dataBlocks.push(dataBlock);\n\t errorBlocks.push(generateErrorCodewords(messagePolynomial,\n\t versionCodewordsInformation.errorCodewordsPerBlock));\n\t }\n\t }\n\t return [dataBlocks, errorBlocks];\n\t };\n\n\t var chooseMode = function (str, minNumericBeforeAlpha, minNumericBeforeByte, minAlphaBeforeByte, previousMode){\n\t var numeric = numberRegex.exec(str),\n\t numericMatch = numeric ? numeric[0] : \"\",\n\t alpha = alphaRegex.exec(str),\n\t alphaMatch = alpha ? alpha[0] : \"\",\n\t alphaNumeric = alphaNumericRegex.exec(str),\n\t alphaNumericMatch = alphaNumeric ? alphaNumeric[0] : \"\",\n\t mode,\n\t modeString;\n\n\t if(numericMatch && (numericMatch.length >= minNumericBeforeAlpha ||\n\t str.length == numericMatch.length || (numericMatch.length >= minNumericBeforeByte &&\n\t !alphaNumericRegex.test(str.charAt(numericMatch.length))))){\n\t mode = NUMERIC;\n\t modeString = numericMatch;\n\t }\n\t else if(alphaNumericMatch && (str.length == alphaNumericMatch.length ||\n\t alphaNumericMatch.length >= minAlphaBeforeByte || previousMode == ALPHA_NUMERIC)){\n\t mode = ALPHA_NUMERIC;\n\t modeString = numericMatch || alphaMatch;\n\t }\n\t else {\n\t mode = BYTE;\n\t if(alphaNumericMatch){\n\t modeString = alphaNumericMatch + byteRegex.exec(str.substring(alphaNumericMatch.length))[0];\n\t }\n\t else{\n\t modeString = byteRegex.exec(str)[0];\n\t }\n\t }\n\n\t return {\n\t mode: mode,\n\t modeString: modeString\n\t };\n\t };\n\n\t var getModes = function (str){\n\t var modes = [],\n\t previousMode,\n\t idx = 0;\n\t modes.push(chooseMode(str, initMinNumericBeforeAlpha, initMinNumericBeforeByte, initMinAlphaBeforeByte, previousMode));\n\t previousMode = modes[0].mode;\n\t str = str.substr(modes[0].modeString.length);\n\n\t while(str.length > 0){\n\t var nextMode = chooseMode(str, minNumericBeforeAlpha, minNumericBeforeByte, minAlphaBeforeByte, previousMode);\n\t if(nextMode.mode != previousMode){\n\t previousMode = nextMode.mode;\n\t modes.push(nextMode);\n\t idx++;\n\t }\n\t else{\n\t modes[idx].modeString += nextMode.modeString;\n\t }\n\t str = str.substr(nextMode.modeString.length);\n\t }\n\n\t return modes;\n\t };\n\n\t var getDataCodewordsCount = function (modes){\n\t var length = 0,\n\t mode;\n\t for(var i = 0; i < modes.length; i++){\n\t mode = modeInstances[modes[i].mode];\n\t length+= mode.getStringBitsLength(modes[i].modeString.length);\n\t }\n\n\t return Math.ceil(length / 8);\n\t };\n\n\t var getVersion = function (dataCodewordsCount, errorCorrectionLevel){\n\t var x = 0,\n\t y = versionsCodewordsInformation.length - 1,\n\t version = Math.floor(versionsCodewordsInformation.length / 2);\n\n\t do{\n\t if(dataCodewordsCount < versionsCodewordsInformation[version][errorCorrectionLevel].totalDataCodewords){\n\t y = version;\n\t }\n\t else{\n\t x = version;\n\t }\n\t version = x + Math.floor((y - x) / 2);\n\n\t }while(y - x > 1);\n\n\t if(dataCodewordsCount <= versionsCodewordsInformation[x][errorCorrectionLevel].totalDataCodewords){\n\t return version + 1;\n\t }\n\t return y + 1;\n\t };\n\n\t var getDataString = function (modes, version){\n\t var dataString = \"\",\n\t mode;\n\t for(var i = 0; i < modes.length; i++){\n\t mode = modeInstances[modes[i].mode];\n\t dataString+= mode.encode(modes[i].modeString, version);\n\t }\n\n\t return dataString;\n\t };\n\n\t //fix case all zeros\n\t var encodeFormatInformation = function (format){\n\t var formatNumber = toDecimal(format),\n\t encodedString,\n\t result = \"\";\n\t if(formatNumber === 0){\n\t return \"101010000010010\";\n\t }\n\t else{\n\t encodedString = encodeBCH(toDecimal(format), formatGeneratorPolynomial, 15);\n\t }\n\t for(var i = 0; i < encodedString.length; i++){\n\t result += encodedString.charAt(i) ^ formatMaskPattern.charAt(i);\n\t }\n\n\t return result;\n\t };\n\n\t var encodeBCH = function (value, generatorPolynomial, codeLength){\n\t var generatorNumber = toDecimal(generatorPolynomial),\n\t polynomialLength = generatorPolynomial.length - 1,\n\t valueNumber = value << polynomialLength,\n\t length = codeLength - polynomialLength,\n\t valueString = toBitsString(value, length),\n\t result = dividePolynomials(valueNumber, generatorNumber);\n\t result = valueString + toBitsString(result, polynomialLength);\n\t return result;\n\t };\n\n\t var dividePolynomials = function (numberX,numberY){\n\t var yLength = numberY.toString(2).length,\n\t xLength = numberX.toString(2).length;\n\t do{\n\t numberX ^= numberY << xLength - yLength;\n\t xLength = numberX.toString(2).length;\n\t }\n\t while(xLength >= yLength);\n\n\t return numberX;\n\t };\n\n\t function getNumberAt(str, idx){\n\t return parseInt(str.charAt(idx), 10);\n\t }\n\n\t var initMatrices = function (version){\n\t var matrices = [],\n\t modules = 17 + 4 * version;\n\t for(var i = 0; i < maskPatternConditions.length; i++){\n\t matrices[i] = new Array(modules);\n\t for(var j = 0; j < modules; j++){\n\t matrices[i][j] = new Array(modules);\n\t }\n\t }\n\n\t return matrices;\n\t };\n\n\t var addFormatInformation =function (matrices, formatString){\n\t var matrix = matrices[0],\n\t x,\n\t y,\n\t idx = 0,\n\t length = formatString.length;\n\n\t for(x=0, y=8; x <= 8;x++){\n\t if(x!== 6){\n\t fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y);\n\t }\n\t }\n\n\t for(x=8, y=7; y>=0;y--){\n\t if(y!== 6){\n\t fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y);\n\t }\n\t }\n\t idx=0;\n\t for(y = matrix.length - 1, x = 8; y >= matrix.length - 8;y--){\n\t fillFunctionCell(matrices,getNumberAt(formatString, length - 1 - idx++), x, y);\n\t }\n\n\t fillFunctionCell(matrices, 1, matrix.length - 8, 8);\n\n\t for(x = matrix.length - 7, y = 8; x < matrix.length;x++){\n\t fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y);\n\t }\n\t };\n\n\t var encodeVersionInformation = function (version){\n\t return encodeBCH(version, versionGeneratorPolynomial, 18);\n\t };\n\n\t var addVersionInformation = function (matrices, dataString){\n\t var matrix = matrices[0],\n\t modules = matrix.length,\n\t x1 = 0,\n\t y1 = modules - 11,\n\t x2 = modules - 11,\n\t y2 = 0,\n\t quotient,\n\t mod,\n\t value;\n\n\t for(var idx =0; idx < dataString.length; idx++){\n\t quotient = Math.floor(idx / 3);\n\t mod = idx % 3;\n\t value = getNumberAt(dataString, dataString.length - idx - 1);\n\t fillFunctionCell(matrices, value, x1 + quotient, y1 + mod);\n\t fillFunctionCell(matrices, value, x2 + mod, y2 + quotient);\n\t }\n\t };\n\n\t var addCentricPattern = function (matrices, pattern, x, y){\n\t var size = pattern.length + 2,\n\t length = pattern.length + 1,\n\t value;\n\n\t for(var i = 0; i < pattern.length; i++){\n\t for(var j = i; j < size - i; j++){\n\t value = pattern[i];\n\t fillFunctionCell(matrices, value, x + j, y + i);\n\t fillFunctionCell(matrices, value, x + i, y + j);\n\t fillFunctionCell(matrices, value, x + length - j, y + length - i);\n\t fillFunctionCell(matrices, value, x + length - i, y + length - j);\n\t }\n\t }\n\t };\n\n\t var addFinderSeparator = function (matrices, direction, x, y){\n\t var nextX = x,\n\t nextY = y,\n\t matrix = matrices[0];\n\t do{\n\t fillFunctionCell(matrices, 0, nextX, y);\n\t fillFunctionCell(matrices, 0, x, nextY);\n\t nextX+= direction[0];\n\t nextY+= direction[1];\n\t }\n\t while(nextX >=0 && nextX < matrix.length);\n\t };\n\n\t var addFinderPatterns = function (matrices){\n\t var modules = matrices[0].length;\n\t addCentricPattern(matrices, finderPattern, 0, 0);\n\t addFinderSeparator(matrices, [-1,-1], 7,7);\n\t addCentricPattern(matrices, finderPattern, modules - 7, 0);\n\t addFinderSeparator(matrices, [1,-1], modules - 8, 7);\n\t addCentricPattern(matrices, finderPattern, 0 , modules - 7);\n\t addFinderSeparator(matrices, [-1,1],7, modules - 8);\n\t };\n\n\t var addAlignmentPatterns = function (matrices, version){\n\t if(version < 2) {\n\t return;\n\t }\n\n\t var matrix = matrices[0],\n\t modules = matrix.length,\n\t pointsCount = Math.floor(version / 7),\n\t points = [6],\n\t startDistance,\n\t distance,\n\t idx = 0;\n\n\t if((startDistance = irregularAlignmentPatternsStartDistance[version])){\n\t distance = (modules - 13 - startDistance) / pointsCount;\n\t }\n\t else{\n\t startDistance = distance = (modules - 13) / (pointsCount + 1);\n\t }\n\t points.push(points[idx++] + startDistance);\n\t while((points[idx] + distance) < modules){\n\t points.push(points[idx++] + distance);\n\t }\n\t for(var i = 0; i < points.length;i++){\n\t for(var j = 0; j < points.length; j++){\n\t if(matrix[points[i]][points[j]] === undefined){\n\t addCentricPattern(matrices, alignmentPattern, points[i] - 2, points[j] - 2);\n\t }\n\t }\n\t }\n\t };\n\n\t var addTimingFunctions = function (matrices){\n\t var row = 6,\n\t column = 6,\n\t value = 1,\n\t modules = matrices[0].length;\n\t for(var i = 8; i < modules - 8;i++){\n\t fillFunctionCell(matrices, value, row, i);\n\t fillFunctionCell(matrices, value, i, column);\n\t value ^= 1;\n\t }\n\t };\n\n\t var scoreMaskMatrixes = function (matrices){\n\t var scores = [],\n\t previousBits = [],\n\t darkModules = [],\n\t patterns = [],\n\t adjacentSameBits = [],\n\t matrix,\n\t i,\n\t row = 0,\n\t column = 1,\n\t modules = matrices[0].length;\n\n\n\t for(i = 0; i < matrices.length; i++){\n\t scores[i] = 0;\n\t darkModules[i] = 0;\n\t adjacentSameBits[i] = [0,0];\n\t patterns[i] = [0, 0];\n\t previousBits[i] = [];\n\t }\n\t for(i = 0; i < modules; i++){\n\t for(var j = 0; j < modules; j++){\n\t for(var k = 0; k < matrices.length; k++){\n\t matrix = matrices[k];\n\t darkModules[k]+= parseInt(matrix[i][j], 10);\n\t if(previousBits[k][row] === matrix[i][j] && i + 1 < modules && j - 1 >= 0 &&\n\t matrix[i + 1][j] == previousBits[k][row] && matrix[i + 1][j - 1] == previousBits[k][row]){\n\t scores[k]+=3;\n\t }\n\t scoreFinderPatternOccurance(k, patterns, scores, row, matrix[i][j]);\n\t scoreFinderPatternOccurance(k, patterns, scores, column, matrix[j][i]);\n\t scoreAdjacentSameBits(k,scores,previousBits,matrix[i][j],adjacentSameBits,row);\n\t scoreAdjacentSameBits(k,scores,previousBits,matrix[j][i],adjacentSameBits,column);\n\t }\n\t }\n\t }\n\t var total = modules * modules,\n\t minIdx,\n\t min = Number.MAX_VALUE;\n\n\t for(i = 0; i < scores.length; i++){\n\t scores[i]+= calculateDarkModulesRatioScore(darkModules[i], total);\n\t if(scores[i] < min){\n\t min = scores[i];\n\t minIdx = i;\n\t }\n\t }\n\n\t return minIdx;\n\t };\n\n\t function scoreFinderPatternOccurance(idx, patterns, scores, rowColumn, bit){\n\t patterns[idx][rowColumn] = ((patterns[idx][rowColumn] << 1) ^ bit) % 128;\n\t if(patterns[idx][rowColumn] == finderPatternValue){\n\t scores[idx] += 40;\n\t }\n\t }\n\n\t function scoreAdjacentSameBits(idx, scores, previousBits, bit, adjacentBits, rowColumn){\n\t if(previousBits[idx][rowColumn] == bit){\n\t adjacentBits[idx][rowColumn]++;\n\t }\n\t else{\n\t previousBits[idx][rowColumn] = bit;\n\t if(adjacentBits[idx][rowColumn] >= 5){\n\t scores[idx]+= 3 + adjacentBits[idx][rowColumn] - 5;\n\t }\n\t adjacentBits[idx][rowColumn] = 1;\n\t }\n\t }\n\n\t function calculateDarkModulesRatioScore(darkModules, total){\n\t var percent = Math.floor((darkModules / total) * 100),\n\t mod5 = percent % 5,\n\t previous = Math.abs(percent - mod5 - 50),\n\t next = Math.abs(percent + 5 - mod5 - 50),\n\t score = 10 * Math.min(previous / 5, next / 5);\n\t return score;\n\t }\n\n\t var EncodingResult = function(dataString, version){\n\t this.dataString = dataString;\n\t this.version = version;\n\t };\n\n\t var IsoEncoder = function(){\n\t this.getEncodingResult = function(inputString, errorCorrectionLevel){\n\t var modes = getModes(inputString),\n\t dataCodewordsCount = getDataCodewordsCount(modes),\n\t version = getVersion(dataCodewordsCount, errorCorrectionLevel),\n\t dataString = getDataString(modes, version);\n\n\t return new EncodingResult(dataString, version);\n\t };\n\t };\n\n\t var UTF8Encoder = function(){\n\t this.mode = modeInstances[this.encodingMode];\n\t };\n\n\t UTF8Encoder.fn = UTF8Encoder.prototype = {\n\t encodingMode: BYTE,\n\t utfBOM: \"111011111011101110111111\",\n\t initialModeCountStringLength: 20,\n\t getEncodingResult: function(inputString, errorCorrectionLevel){\n\t var that = this,\n\t data = that.encode(inputString),\n\t dataCodewordsCount = that.getDataCodewordsCount(data),\n\t version = getVersion(dataCodewordsCount, errorCorrectionLevel),\n\t dataString = that.mode.getModeCountString(data.length / 8, version) + data;\n\n\t return new EncodingResult(dataString, version);\n\t },\n\t getDataCodewordsCount: function(data){\n\t var that = this,\n\t dataLength = data.length,\n\t dataCodewordsCount = Math.ceil(( that.initialModeCountStringLength + dataLength) / 8);\n\n\t return dataCodewordsCount;\n\t },\n\t encode: function(str){\n\t var that = this,\n\t result = that.utfBOM;\n\t for(var i = 0; i < str.length; i++){\n\t result += that.encodeCharacter(str.charCodeAt(i));\n\t }\n\t return result;\n\t },\n\t encodeCharacter: function(code){\n\t var bytesCount = this.getBytesCount(code),\n\t bc = bytesCount - 1,\n\t result = \"\";\n\n\t if(bytesCount == 1){\n\t result = toBitsString(code, 8);\n\t }\n\t else{\n\t var significantOnes = 8 - bytesCount;\n\n\t for(var i = 0; i < bc; i++){\n\t result = toBitsString(code >> (i * 6) & 63 | 128, 8) + result;\n\t }\n\n\t result = ((code >> bc * 6) | ((255 >> significantOnes) << significantOnes)).toString(2) + result;\n\t }\n\t return result;\n\t },\n\t getBytesCount: function(code){\n\t var ranges = this.ranges;\n\t for(var i = 0; i < ranges.length;i++){\n\t if(code < ranges[i]){\n\t return i + 1;\n\t }\n\t }\n\t },\n\t ranges: [128,2048,65536,2097152,67108864]\n\t };\n\n\t var QRCodeDataEncoder = function(encoding){\n\t if(encoding && encoding.toLowerCase().indexOf(\"utf_8\") >= 0){\n\t return new UTF8Encoder();\n\t }\n\t else{\n\t return new IsoEncoder();\n\t }\n\t };\n\n\t var encodeData = function (inputString, errorCorrectionLevel, encoding){\n\t var encoder = new QRCodeDataEncoder(encoding),\n\t encodingResult = encoder.getEncodingResult(inputString, errorCorrectionLevel),\n\t version = encodingResult.version,\n\t versionInformation = versionsCodewordsInformation[version - 1][errorCorrectionLevel],\n\t dataString = padDataString(encodingResult.dataString, versionInformation.totalDataCodewords),\n\t blocks = getBlocks(dataString, versionInformation),\n\t matrices = initMatrices(version);\n\n\t addFinderPatterns(matrices);\n\t addAlignmentPatterns(matrices, version);\n\t addTimingFunctions(matrices);\n\n\t if(version >= 7){\n\t addVersionInformation(matrices, toBitsString(0, 18));\n\t }\n\n\t addFormatInformation(matrices, toBitsString(0, 15));\n\t fillData(matrices, blocks);\n\n\t var minIdx = scoreMaskMatrixes(matrices),\n\t optimalMatrix = matrices[minIdx];\n\n\t if(version >= 7){\n\t addVersionInformation([optimalMatrix], encodeVersionInformation(version));\n\t }\n\n\t var formatString = errorCorrectionPatterns[errorCorrectionLevel] + toBitsString(minIdx, 3);\n\t addFormatInformation([optimalMatrix], encodeFormatInformation(formatString));\n\n\t return optimalMatrix;\n\t };\n\n\t var QRCodeDefaults= {\n\t DEFAULT_SIZE: 200,\n\t QUIET_ZONE_LENGTH: 4,\n\t DEFAULT_ERROR_CORRECTION_LEVEL:\"L\",\n\t DEFAULT_BACKGROUND: \"#fff\",\n\t DEFAULT_DARK_MODULE_COLOR: \"#000\",\n\t MIN_BASE_UNIT_SIZE: 1\n\t };\n\n\t var QRCode = Widget.extend({\n\t init: function (element, options) {\n\t var that = this;\n\n\t Widget.fn.init.call(that, element, options);\n\n\t that.element = $(element);\n\t that.wrapper = that.element;\n\t that.element.addClass(\"k-qrcode\");\n\t that.surfaceWrap = $(\"
    \").css(\"position\", \"relative\").appendTo(this.element);\n\t that.surface = draw.Surface.create(that.surfaceWrap, {\n\t type: that.options.renderAs\n\t });\n\t that.setOptions(options);\n\t },\n\n\t redraw: function(){\n\t var size = this._getSize();\n\n\t this.surfaceWrap.css({\n\t width: size,\n\t height: size\n\t });\n\t this.surface.clear();\n\t this.surface.resize();\n\n\t this.createVisual();\n\t this.surface.draw(this.visual);\n\t },\n\n\t getSize: function() {\n\t return kendo.dimensions(this.element);\n\t },\n\n\t _resize: function() {\n\t this.redraw();\n\t },\n\n\t createVisual: function() {\n\t this.visual = this._render();\n\t },\n\n\t exportVisual: function() {\n\t return this._render();\n\t },\n\n\t _render: function() {\n\t var that = this,\n\t value = that._value,\n\t baseUnit,\n\t border = that.options.border || {},\n\t padding = that.options.padding || 0,\n\t borderWidth = border.width || 0,\n\t quietZoneSize,\n\t matrix,\n\t size,\n\t dataSize,\n\t contentSize;\n\n\t border.width = borderWidth;\n\n\t var visual = new draw.Group();\n\n\t if (value){\n\t matrix = encodeData(value, that.options.errorCorrection, that.options.encoding);\n\t size = that._getSize();\n\t contentSize = size - 2 * (borderWidth + padding);\n\t baseUnit = that._calculateBaseUnit(contentSize, matrix.length);\n\t dataSize = matrix.length * baseUnit;\n\t quietZoneSize = borderWidth + padding + (contentSize - dataSize) / 2;\n\n\t visual.append(that._renderBackground(size, border));\n\t visual.append(that._renderMatrix(matrix, baseUnit, quietZoneSize));\n\t }\n\n\t return visual;\n\t },\n\n\t _getSize: function(){\n\t var that = this,\n\t size;\n\n\t if (that.options.size){\n\t size = parseInt(that.options.size, 10);\n\t } else {\n\t var element = that.element,\n\t min = Math.min(element.width(), element.height());\n\n\t if (min > 0){\n\t size = min;\n\t } else {\n\t size = QRCodeDefaults.DEFAULT_SIZE;\n\t }\n\t }\n\n\t return size;\n\t },\n\n\t _calculateBaseUnit: function(size, matrixSize){\n\t var baseUnit = Math.floor(size/ matrixSize);\n\n\t if(baseUnit < QRCodeDefaults.MIN_BASE_UNIT_SIZE){\n\t throw new Error(\"Insufficient size.\");\n\t }\n\n\t if(baseUnit * matrixSize >= size &&\n\t baseUnit - 1 >= QRCodeDefaults.MIN_BASE_UNIT_SIZE){\n\t baseUnit--;\n\t }\n\n\t return baseUnit;\n\t },\n\n\t _renderMatrix: function(matrix, baseUnit, quietZoneSize){\n\t var path = new draw.MultiPath({\n\t fill: {\n\t color: this.options.color\n\t },\n\t stroke: null\n\t });\n\n\t for (var row = 0; row < matrix.length; row++){\n\t var y = quietZoneSize + row * baseUnit;\n\t var column = 0;\n\n\t while (column < matrix.length){\n\t while (matrix[row][column] === 0 && column < matrix.length){\n\t column++;\n\t }\n\n\t if (column < matrix.length){\n\t var x = column;\n\t while (matrix[row][column] == 1){\n\t column++;\n\t }\n\n\t var x1 = round(quietZoneSize + x * baseUnit);\n\t var y1 = round(y);\n\t var x2 = round(quietZoneSize + column * baseUnit);\n\t var y2 = round(y + baseUnit);\n\n\t path.moveTo(x1, y1)\n\t .lineTo(x1, y2)\n\t .lineTo(x2, y2)\n\t .lineTo(x2, y1)\n\t .close();\n\t }\n\t }\n\t }\n\n\t return path;\n\t },\n\n\t _renderBackground: function (size, border) {\n\t var box = new Box2D(0,0, size, size).unpad(border.width / 2);\n\t return draw.Path.fromRect(box.toRect(), {\n\t fill: {\n\t color: this.options.background\n\t },\n\t stroke: {\n\t color: border.color,\n\t width: border.width\n\t }\n\t });\n\t },\n\n\t setOptions: function (options) {\n\t var that = this;\n\t options = options || {};\n\t that.options = extend(that.options, options);\n\t if (options.value !== undefined) {\n\t that._value = that.options.value + \"\";\n\t }\n\t that.redraw();\n\t },\n\t value: function(value){\n\t var that = this;\n\t if (value === undefined) {\n\t return that._value;\n\t }\n\t that._value = value + \"\";\n\t that.redraw();\n\t },\n\t options: {\n\t name: \"QRCode\",\n\t renderAs: \"svg\",\n\t encoding: \"ISO_8859_1\",\n\t value: \"\",\n\t errorCorrection: QRCodeDefaults.DEFAULT_ERROR_CORRECTION_LEVEL,\n\t background: QRCodeDefaults.DEFAULT_BACKGROUND,\n\t color: QRCodeDefaults.DEFAULT_DARK_MODULE_COLOR,\n\t size: \"\",\n\t padding: 0,\n\t border: {\n\t color: \"\",\n\t width: 0\n\t }\n\t }\n\t });\n\n\t dataviz.ExportMixin.extend(QRCode.fn);\n\t dataviz.ui.plugin(QRCode);\n\n\t kendo.deepExtend(dataviz, {\n\t QRCode: QRCode,\n\t QRCodeDefaults: QRCodeDefaults,\n\t QRCodeFunctions: {\n\t FreeCellVisitor: FreeCellVisitor,\n\t fillData: fillData,\n\t padDataString: padDataString,\n\t generateErrorCodewords: generateErrorCodewords,\n\t xorPolynomials: xorPolynomials,\n\t getBlocks: getBlocks,\n\t multiplyPolynomials: multiplyPolynomials,\n\t chooseMode: chooseMode,\n\t getModes: getModes,\n\t getDataCodewordsCount: getDataCodewordsCount,\n\t getVersion: getVersion,\n\t getDataString: getDataString,\n\t encodeFormatInformation: encodeFormatInformation,\n\t encodeBCH: encodeBCH,\n\t dividePolynomials: dividePolynomials,\n\t initMatrices: initMatrices,\n\t addFormatInformation: addFormatInformation,\n\t encodeVersionInformation: encodeVersionInformation,\n\t addVersionInformation: addVersionInformation,\n\t addCentricPattern: addCentricPattern,\n\t addFinderSeparator: addFinderSeparator,\n\t addFinderPatterns: addFinderPatterns,\n\t addAlignmentPatterns: addAlignmentPatterns,\n\t addTimingFunctions: addTimingFunctions,\n\t scoreMaskMatrixes: scoreMaskMatrixes,\n\t encodeData: encodeData,\n\t UTF8Encoder: UTF8Encoder\n\t },\n\t QRCodeFields: {\n\t modes: modeInstances,\n\t powersOfTwo: powersOfTwo,\n\t powersOfTwoResult: powersOfTwoResult,\n\t generatorPolynomials: generatorPolynomials\n\t }\n\t });\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1121);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1121:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1122), __webpack_require__(1123) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dataviz.sparkline\",\n\t name: \"Sparkline\",\n\t category: \"dataviz\",\n\t description: \"Sparkline widgets.\",\n\t depends: [ \"dataviz.chart\" ]\n\t};\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1122:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/sparkline/kendo-sparkline\");\n\n/***/ }),\n\n/***/ 1123:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/sparkline/sparkline\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1124);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1124:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1125), __webpack_require__(1126) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dataviz.stockchart\",\n\t name: \"StockChart\",\n\t category: \"dataviz\",\n\t description: \"StockChart widget and associated financial series.\",\n\t depends: [ \"dataviz.chart\" ]\n\t};\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1125:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/stock/kendo-stock-chart\");\n\n/***/ }),\n\n/***/ 1126:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/stock/stock-chart\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1127);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1078:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.core\");\n\n/***/ }),\n\n/***/ 1127:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(1078),\n\t __webpack_require__(1128),\n\t __webpack_require__(1129),\n\t __webpack_require__(1130)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dataviz.themes\",\n\t name: \"Themes\",\n\t description: \"Built-in themes for the DataViz widgets\",\n\t category: \"dataviz\",\n\t depends: [ \"dataviz.core\" ],\n\t hidden: true\n\t};\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1128:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/themes/chart-base-theme\");\n\n/***/ }),\n\n/***/ 1129:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/themes/auto-theme\");\n\n/***/ }),\n\n/***/ 1130:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dataviz/themes/themes\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1131);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1027:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.data\");\n\n/***/ }),\n\n/***/ 1056:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.userevents\");\n\n/***/ }),\n\n/***/ 1079:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dataviz.themes\");\n\n/***/ }),\n\n/***/ 1131:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1027), __webpack_require__(1056), __webpack_require__(1079) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dataviz.treeMap\",\n\t name: \"TreeMap\",\n\t category: \"dataviz\",\n\t description: \"The Kendo DataViz TreeMap\",\n\t depends: [ \"data\", \"userevents\", \"dataviz.themes\" ]\n\t};\n\n\t(function($, undefined) {\n\t var math = Math,\n\n\t proxy = $.proxy,\n\t isArray = $.isArray,\n\n\t kendo = window.kendo,\n\t outerHeight = kendo._outerHeight,\n\t outerWidth = kendo._outerWidth,\n\t Class = kendo.Class,\n\t Widget = kendo.ui.Widget,\n\t template = kendo.template,\n\t deepExtend = kendo.deepExtend,\n\t HierarchicalDataSource = kendo.data.HierarchicalDataSource,\n\t getter = kendo.getter,\n\n\t dataviz = kendo.dataviz;\n\n\t var NS = \".kendoTreeMap\",\n\t CHANGE = \"change\",\n\t DATA_BOUND = \"dataBound\",\n\t ITEM_CREATED = \"itemCreated\",\n\t MAX_VALUE = Number.MAX_VALUE,\n\t MOUSEOVER_NS = \"mouseover\" + NS,\n\t MOUSELEAVE_NS = \"mouseleave\" + NS,\n\t UNDEFINED = \"undefined\";\n\n\t var TreeMap = Widget.extend({\n\t init: function(element, options) {\n\t kendo.destroy(element);\n\t $(element).empty();\n\n\t Widget.fn.init.call(this, element, options);\n\t this.wrapper = this.element;\n\n\t this._initTheme(this.options);\n\n\t this.element.addClass(\"k-widget k-treemap\");\n\n\t this._setLayout();\n\n\t this._originalOptions = deepExtend({}, this.options);\n\n\t this._initDataSource();\n\n\t this._attachEvents();\n\n\t kendo.notify(this, dataviz.ui);\n\t },\n\n\t options: {\n\t name: \"TreeMap\",\n\t theme: \"default\",\n\t autoBind: true,\n\t textField: \"text\",\n\t valueField: \"value\",\n\t colorField: \"color\"\n\t },\n\n\t events: [DATA_BOUND, ITEM_CREATED],\n\n\t _initTheme: function(options) {\n\t var that = this,\n\t themes = dataviz.ui.themes || {},\n\t themeName = ((options || {}).theme || \"\").toLowerCase(),\n\t themeOptions = (themes[themeName] || {}).treeMap;\n\n\t that.options = deepExtend({}, themeOptions, options);\n\t },\n\n\t _attachEvents: function() {\n\t this.element\n\t .on(MOUSEOVER_NS, proxy(this._mouseover, this))\n\t .on(MOUSELEAVE_NS, proxy(this._mouseleave, this));\n\n\t this._resizeHandler = proxy(this.resize, this, false);\n\t kendo.onResize(this._resizeHandler);\n\t },\n\n\t _setLayout: function() {\n\t if (this.options.type === \"horizontal\") {\n\t this._layout = new SliceAndDice(false);\n\t this._view = new SliceAndDiceView(this, this.options);\n\t } else if (this.options.type === \"vertical\") {\n\t this._layout = new SliceAndDice(true);\n\t this._view = new SliceAndDiceView(this, this.options);\n\t } else {\n\t this._layout = new Squarified();\n\t this._view = new SquarifiedView(this, this.options);\n\t }\n\t },\n\n\t _initDataSource: function() {\n\t var that = this,\n\t options = that.options,\n\t dataSource = options.dataSource;\n\n\t that._dataChangeHandler = proxy(that._onDataChange, that);\n\n\t that.dataSource = HierarchicalDataSource\n\t .create(dataSource)\n\t .bind(CHANGE, that._dataChangeHandler);\n\n\t if (dataSource) {\n\t if (that.options.autoBind) {\n\t that.dataSource.fetch();\n\t }\n\t }\n\t },\n\n\t setDataSource: function(dataSource) {\n\t var that = this;\n\t that.dataSource.unbind(CHANGE, that._dataChangeHandler);\n\t that.dataSource = dataSource\n\t .bind(CHANGE, that._dataChangeHandler);\n\n\t if (dataSource) {\n\t if (that.options.autoBind) {\n\t that.dataSource.fetch();\n\t }\n\t }\n\t },\n\n\t _onDataChange: function(e) {\n\t var node = e.node;\n\t var items = e.items;\n\t var options = this.options;\n\t var item, i;\n\n\t if (!node) {\n\t this._cleanItems();\n\t this.element.empty();\n\t item = this._wrapItem(items[0]);\n\t this._layout.createRoot(\n\t item,\n\t outerWidth(this.element),\n\t outerHeight(this.element),\n\t this.options.type === \"vertical\"\n\t );\n\t this._view.createRoot(item);\n\t // Reference of the root\n\t this._root = item;\n\t this._colorIdx = 0;\n\t } else {\n\t if (items.length) {\n\t var root = this._getByUid(node.uid);\n\t root.children = [];\n\t items = new kendo.data.Query(items)._sortForGrouping(options.valueField, \"desc\");\n\n\t for (i = 0; i < items.length; i++) {\n\t item = items[i];\n\t root.children.push(this._wrapItem(item));\n\t }\n\n\t var htmlSize = this._view.htmlSize(root);\n\t this._layout.compute(root.children, root.coord, htmlSize);\n\n\t this._setColors(root.children);\n\t this._view.render(root);\n\t }\n\t }\n\n\t for (i = 0; i < items.length; i++) {\n\t items[i].load();\n\t }\n\n\t if (node) {\n\t this.trigger(DATA_BOUND, {\n\t node: node\n\t });\n\t }\n\t },\n\n\t _cleanItems: function() {\n\t var that = this;\n\t that.angular(\"cleanup\", function() {\n\t return { elements: that.element.find(\".k-leaf div,.k-treemap-title,.k-treemap-title-vertical\") };\n\t });\n\t },\n\n\t _setColors: function(items) {\n\t var colors = this.options.colors;\n\t var colorIdx = this._colorIdx;\n\t var color = colors[colorIdx % colors.length];\n\t var colorRange, item;\n\t if (isArray(color)) {\n\t colorRange = colorsByLength(color[0], color[1], items.length);\n\t }\n\n\t var leafNodes = false;\n\t for (var i = 0; i < items.length; i++) {\n\t item = items[i];\n\n\t if (!defined(item.color)) {\n\t if (colorRange) {\n\t item.color = colorRange[i];\n\t } else {\n\t item.color = color;\n\t }\n\t }\n\t if (!item.dataItem.hasChildren) {\n\t leafNodes = true;\n\t }\n\t }\n\n\t if (leafNodes) {\n\t this._colorIdx++;\n\t }\n\t },\n\n\t _contentSize: function(root) {\n\t this.view.renderHeight(root);\n\t },\n\n\t _wrapItem: function(item) {\n\t var wrap = {};\n\n\t if (defined(this.options.valueField)) {\n\t wrap.value = getField(this.options.valueField, item);\n\t }\n\n\t if (defined(this.options.colorField)) {\n\t wrap.color = getField(this.options.colorField, item);\n\t }\n\n\t if (defined(this.options.textField)) {\n\t wrap.text = getField(this.options.textField, item);\n\t }\n\n\t wrap.level = item.level();\n\n\t wrap.dataItem = item;\n\n\t return wrap;\n\t },\n\n\t _getByUid: function(uid) {\n\t var items = [this._root];\n\t var item;\n\n\t while (items.length) {\n\t item = items.pop();\n\t if (item.dataItem.uid === uid) {\n\t return item;\n\t }\n\n\t if (item.children) {\n\t items = items.concat(item.children);\n\t }\n\t }\n\t },\n\n\t dataItem: function(node) {\n\t var uid = $(node).attr(kendo.attr(\"uid\")),\n\t dataSource = this.dataSource;\n\n\t return dataSource && dataSource.getByUid(uid);\n\t },\n\n\t findByUid: function(uid) {\n\t return this.element.find(\".k-treemap-tile[\" + kendo.attr(\"uid\") + \"='\" + uid + \"']\");\n\t },\n\n\t _mouseover: function(e) {\n\t var target = $(e.target);\n\t if (target.hasClass(\"k-leaf\")) {\n\t this._removeActiveState();\n\t target\n\t .removeClass(\"k-state-hover\")\n\t .addClass(\"k-state-hover\");\n\t }\n\t },\n\n\t _removeActiveState: function() {\n\t this.element\n\t .find(\".k-state-hover\")\n\t .removeClass(\"k-state-hover\");\n\t },\n\n\t _mouseleave: function() {\n\t this._removeActiveState();\n\t },\n\n\t destroy: function() {\n\t Widget.fn.destroy.call(this);\n\t this.element.off(NS);\n\n\t if (this.dataSource) {\n\t this.dataSource.unbind(CHANGE, this._dataChangeHandler);\n\t }\n\n\t this._root = null;\n\t kendo.unbindResize(this._resizeHandler);\n\n\t kendo.destroy(this.element);\n\t },\n\n\t items: function() {\n\t return $();\n\t },\n\n\t getSize: function() {\n\t return kendo.dimensions(this.element);\n\t },\n\n\t _resize: function() {\n\t var root = this._root;\n\t if (root) {\n\t var element = this.element;\n\t var rootElement = element.children();\n\t root.coord.width = outerWidth(element);\n\t root.coord.height = outerHeight(element);\n\n\t rootElement.css({\n\t width: root.coord.width,\n\t height: root.coord.height\n\t });\n\n\t this._resizeItems(root, rootElement);\n\t }\n\t },\n\n\t _resizeItems: function(root, element) {\n\t if (root.children && root.children.length) {\n\t var elements = element.children(\".k-treemap-wrap\").children();\n\t var child, childElement;\n\n\t this._layout.compute(root.children, root.coord, {text: this._view.titleSize(root, element)});\n\t for (var idx = 0; idx < root.children.length; idx++) {\n\t child = root.children[idx];\n\t childElement = elements.filter(\"[\" + kendo.attr(\"uid\") + \"='\" + child.dataItem.uid + \"']\");\n\t this._view.setItemSize(child, childElement);\n\t this._resizeItems(child, childElement);\n\t }\n\t }\n\t },\n\n\t setOptions: function(options) {\n\t var dataSource = options.dataSource;\n\n\t options.dataSource = undefined;\n\t this._originalOptions = deepExtend(this._originalOptions, options);\n\t this.options = deepExtend({}, this._originalOptions);\n\t this._setLayout();\n\t this._initTheme(this.options);\n\n\t Widget.fn._setEvents.call(this, options);\n\n\t if (dataSource) {\n\t this.setDataSource(HierarchicalDataSource.create(dataSource));\n\t }\n\n\t if (this.options.autoBind) {\n\t this.dataSource.fetch();\n\t }\n\t }\n\t });\n\n\t var Squarified = Class.extend({\n\t createRoot: function(root, width, height) {\n\t root.coord = {\n\t width: width,\n\t height: height,\n\t top: 0,\n\t left: 0\n\t };\n\t },\n\n\t leaf: function(tree) {\n\t return !tree.children;\n\t },\n\n\t layoutChildren: function(items, coord) {\n\t var parentArea = coord.width * coord.height;\n\t var totalArea = 0,\n\t itemsArea = [],\n\t i;\n\n\t for (i = 0; i < items.length; i++) {\n\t itemsArea[i] = parseFloat(items[i].value);\n\t totalArea += itemsArea[i];\n\t }\n\n\t for (i = 0; i < itemsArea.length; i++) {\n\t items[i].area = parentArea * itemsArea[i] / totalArea;\n\t }\n\n\t var minimumSideValue = this.layoutHorizontal() ? coord.height : coord.width;\n\n\t var firstElement = [items[0]];\n\t var tail = items.slice(1);\n\t this.squarify(tail, firstElement, minimumSideValue, coord);\n\t },\n\n\t squarify: function(tail, initElement, width, coord) {\n\t this.computeDim(tail, initElement, width, coord);\n\t },\n\n\t computeDim: function(tail, initElement, width, coord) {\n\t if (tail.length + initElement.length == 1) {\n\t var element = tail.length == 1 ? tail : initElement;\n\t this.layoutLast(element, width, coord);\n\t return;\n\t }\n\n\t if (tail.length >= 2 && initElement.length === 0) {\n\t initElement = [tail[0]];\n\t tail = tail.slice(1);\n\t }\n\n\t if (tail.length === 0) {\n\t if (initElement.length > 0) {\n\t this.layoutRow(initElement, width, coord);\n\t }\n\t return;\n\t }\n\n\t var firstElement = tail[0];\n\n\t if (this.worstAspectRatio(initElement, width) >= this.worstAspectRatio([firstElement].concat(initElement), width)) {\n\t this.computeDim(tail.slice(1), initElement.concat([firstElement]), width, coord);\n\t } else {\n\t var newCoords = this.layoutRow(initElement, width, coord);\n\t this.computeDim(tail, [], newCoords.dim, newCoords);\n\t }\n\t },\n\n\t layoutLast: function(items, w, coord) {\n\t items[0].coord = coord;\n\t },\n\n\t layoutRow: function(items, width, coord) {\n\t if (this.layoutHorizontal()) {\n\t return this.layoutV(items, width, coord);\n\t } else {\n\t return this.layoutH(items, width, coord);\n\t }\n\t },\n\n\t orientation: \"h\",\n\n\t layoutVertical: function() {\n\t return this.orientation === \"v\";\n\t },\n\n\t layoutHorizontal: function() {\n\t return this.orientation === \"h\";\n\t },\n\n\t layoutChange: function() {\n\t this.orientation = this.layoutVertical() ? \"h\" : \"v\";\n\t },\n\n\t worstAspectRatio: function(items, width) {\n\t if (!items || items.length === 0) {\n\t return MAX_VALUE;\n\t }\n\n\t var areaSum = 0,\n\t maxArea = 0,\n\t minArea = MAX_VALUE;\n\n\t for (var i = 0; i < items.length; i++) {\n\t var area = items[i].area;\n\t areaSum += area;\n\t minArea = (minArea < area) ? minArea : area;\n\t maxArea = (maxArea > area) ? maxArea : area;\n\t }\n\n\t return math.max(\n\t (width * width * maxArea) / (areaSum * areaSum),\n\t (areaSum * areaSum) / (width * width * minArea)\n\t );\n\t },\n\n\t compute: function(children, rootCoord, htmlSize) {\n\t if (!(rootCoord.width >= rootCoord.height && this.layoutHorizontal())) {\n\t this.layoutChange();\n\t }\n\n\t if (children && children.length > 0) {\n\t var newRootCoord = {\n\t width: rootCoord.width,\n\t height: rootCoord.height - htmlSize.text,\n\t top: 0,\n\t left: 0\n\t };\n\n\t this.layoutChildren(children, newRootCoord);\n\t }\n\t },\n\n\t layoutV: function(items, width, coord) {\n\t var totalArea = this._totalArea(items),\n\t top = 0;\n\n\t width = round(totalArea / width);\n\n\t for (var i = 0; i < items.length; i++) {\n\t var height = round(items[i].area / width);\n\t items[i].coord = {\n\t height: height,\n\t width: width,\n\t top: coord.top + top,\n\t left: coord.left\n\t };\n\n\t top += height;\n\t }\n\n\t var ans = {\n\t height: coord.height,\n\t width: coord.width - width,\n\t top: coord.top,\n\t left: coord.left + width\n\t };\n\n\t ans.dim = math.min(ans.width, ans.height);\n\n\t if (ans.dim != ans.height) {\n\t this.layoutChange();\n\t }\n\n\t return ans;\n\t },\n\n\t layoutH: function(items, width, coord) {\n\t var totalArea = this._totalArea(items);\n\n\t var height = round(totalArea / width),\n\t top = coord.top,\n\t left = 0;\n\n\t for (var i=0; i 180\n\t )\n\t .toggle(item.value !== 0)\n\t .append($(\"
    \")\n\t .html(this._getText(item)));\n\t },\n\n\t _createTile: function(item) {\n\t var tile = $(\"
    \");\n\t this.setItemSize(item, tile);\n\n\t if (defined(item.dataItem) && defined(item.dataItem.uid)) {\n\t tile.attr(kendo.attr(\"uid\"), item.dataItem.uid);\n\t }\n\n\t return tile;\n\t },\n\n\t _itemCoordinates: function(item) {\n\t var coordinates = {\n\t width: item.coord.width,\n\t height: item.coord.height,\n\t left: item.coord.left,\n\t top: item.coord.top\n\t };\n\n\t if (coordinates.left && this.offset) {\n\t coordinates.width += this.offset * 2;\n\t } else {\n\t coordinates.width += this.offset;\n\t }\n\n\t if (coordinates.top) {\n\t coordinates.height += this.offset * 2;\n\t } else {\n\t coordinates.height += this.offset;\n\t }\n\n\t return coordinates;\n\t },\n\n\t setItemSize: function(item, element) {\n\t var coordinates = this._itemCoordinates(item);\n\t element.css({\n\t width: coordinates.width,\n\t height: coordinates.height,\n\t left: coordinates.left,\n\t top: coordinates.top\n\t });\n\t },\n\n\t _getText: function(item) {\n\t var text = item.text;\n\n\t if (this.options.template) {\n\t text = this._renderTemplate(item);\n\t }\n\n\t return text;\n\t },\n\n\t _renderTemplate: function(item) {\n\t var titleTemplate = template(this.options.template);\n\t return titleTemplate({\n\t dataItem: item.dataItem,\n\t text: item.text\n\t });\n\t },\n\n\t _createTitle: function(item) {\n\t return $(\"
    \")\n\t .append($(\"
    \").html(this._getText(item)));\n\t },\n\n\t _createWrap: function() {\n\t return $(\"
    \");\n\t },\n\n\t _tileColorBrightness: function(item) {\n\t return colorBrightness(item.color);\n\t }\n\t });\n\n\t var SliceAndDice = Class.extend({\n\t createRoot: function(root, width, height, vertical) {\n\t root.coord = {\n\t width: width,\n\t height: height,\n\t top: 0,\n\t left: 0\n\t };\n\t root.vertical = vertical;\n\t },\n\n\t init: function(vertical) {\n\t this.vertical = vertical;\n\t this.quotient = vertical ? 1 : 0;\n\t },\n\n\t compute: function(children, rootCoord, htmlSize) {\n\n\t if (children.length > 0) {\n\t var width = rootCoord.width;\n\t var height = rootCoord.height;\n\n\t if (this.vertical) {\n\t height -= htmlSize.text;\n\t } else {\n\t width -= htmlSize.text;\n\t }\n\n\t var newRootCoord = {\n\t width: width,\n\t height: height,\n\t top: 0,\n\t left: 0\n\t };\n\n\t this.layoutChildren(children, newRootCoord);\n\t }\n\t },\n\n\t layoutChildren: function(items, coord) {\n\t var parentArea = coord.width * coord.height;\n\t var totalArea = 0;\n\t var itemsArea = [];\n\t var i;\n\n\t for (i = 0; i < items.length; i++) {\n\t var item = items[i];\n\t itemsArea[i] = parseFloat(items[i].value);\n\t totalArea += itemsArea[i];\n\t item.vertical = this.vertical;\n\t }\n\n\t for (i = 0; i < itemsArea.length; i++) {\n\t items[i].area = parentArea * itemsArea[i] / totalArea;\n\t }\n\n\t this.sliceAndDice(items, coord);\n\t },\n\n\t sliceAndDice: function(items, coord) {\n\t var totalArea = this._totalArea(items);\n\t if (items[0].level % 2 === this.quotient) {\n\t this.layoutHorizontal(items, coord, totalArea);\n\t } else {\n\t this.layoutVertical(items, coord, totalArea);\n\t }\n\t },\n\n\t layoutHorizontal: function(items, coord, totalArea) {\n\t var left = 0;\n\n\t for (var i = 0; i < items.length; i++) {\n\t var item = items[i];\n\t var width = item.area / (totalArea / coord.width);\n\t item.coord = {\n\t height: coord.height,\n\t width: width,\n\t top: coord.top,\n\t left: coord.left + left\n\t };\n\n\t left += width;\n\t }\n\t },\n\n\t layoutVertical: function(items, coord, totalArea) {\n\t var top = 0;\n\n\t for (var i = 0; i < items.length; i++) {\n\t var item = items[i];\n\t var height = item.area / (totalArea / coord.height);\n\t item.coord = {\n\t height: height,\n\t width: coord.width,\n\t top: coord.top + top,\n\t left: coord.left\n\t };\n\n\t top += height;\n\t }\n\t },\n\n\t _totalArea: function(items) {\n\t var total = 0;\n\n\t for (var i = 0; i < items.length; i++) {\n\t total += items[i].area;\n\t }\n\n\t return total;\n\t }\n\t });\n\n\t var SliceAndDiceView = SquarifiedView.extend({\n\t htmlSize: function(root) {\n\t var rootElement = this._getByUid(root.dataItem.uid);\n\t var htmlSize = {\n\t text: 0,\n\t offset: 0\n\t };\n\n\t if (root.children) {\n\t this._clean(rootElement);\n\n\t var text = this._getText(root);\n\t if (text) {\n\t var title = this._createTitle(root);\n\t rootElement.append(title);\n\t this._compile(title, root.dataItem);\n\n\t if (root.vertical) {\n\t htmlSize.text = title.height();\n\t } else {\n\t htmlSize.text = title.width();\n\t }\n\t }\n\n\t rootElement.append(this._createWrap());\n\n\t this.offset = (outerWidth(rootElement) - rootElement.innerWidth()) / 2;\n\t }\n\n\t return htmlSize;\n\t },\n\n\t titleSize: function(item, element) {\n\t var size;\n\t if (item.vertical) {\n\t size = element.children(\".k-treemap-title\").height();\n\t } else {\n\t size = element.children(\".k-treemap-title-vertical\").width();\n\t }\n\t return size || 0;\n\t },\n\n\t _createTitle: function(item) {\n\t var title;\n\t if (item.vertical) {\n\t title = $(\"
    \");\n\t } else {\n\t title = $(\"
    \");\n\t }\n\n\t return title.append($(\"
    \").html(this._getText(item)));\n\t }\n\t });\n\n\t function getField(field, row) {\n\t if (row === null) {\n\t return row;\n\t }\n\n\t var get = getter(field, true);\n\t return get(row);\n\t }\n\n\t function defined(value) {\n\t return typeof value !== UNDEFINED;\n\t }\n\n\t function colorsByLength(min, max, length) {\n\t var minRGBtoDecimal = rgbToDecimal(min);\n\t var maxRGBtoDecimal = rgbToDecimal(max);\n\t var isDarker = colorBrightness(min) - colorBrightness(max) < 0;\n\t var colors = [];\n\n\t colors.push(min);\n\n\t for (var i = 0; i < length; i++) {\n\t var rgbColor = {\n\t r: colorByIndex(minRGBtoDecimal.r, maxRGBtoDecimal.r, i, length, isDarker),\n\t g: colorByIndex(minRGBtoDecimal.g, maxRGBtoDecimal.g, i, length, isDarker),\n\t b: colorByIndex(minRGBtoDecimal.b, maxRGBtoDecimal.b, i, length, isDarker)\n\t };\n\t colors.push(buildColorFromRGB(rgbColor));\n\t }\n\n\t colors.push(max);\n\n\t return colors;\n\t }\n\n\t function colorByIndex(min, max, index, length, isDarker) {\n\t var minColor = math.min(math.abs(min), math.abs(max));\n\t var maxColor = math.max(math.abs(min), math.abs(max));\n\t var step = (maxColor - minColor) / (length + 1);\n\t var currentStep = step * (index + 1);\n\t var color;\n\n\t if (isDarker) {\n\t color = minColor + currentStep;\n\t } else {\n\t color = maxColor - currentStep;\n\t }\n\n\t return color;\n\t }\n\n\t function buildColorFromRGB(color) {\n\t return \"#\" + decimalToRgb(color.r) + decimalToRgb(color.g) + decimalToRgb(color.b);\n\t }\n\n\t function rgbToDecimal(color) {\n\t color = color.replace(\"#\", \"\");\n\t var rgbColor = colorToRGB(color);\n\n\t return {\n\t r: rgbToHex(rgbColor.r),\n\t g: rgbToHex(rgbColor.g),\n\t b: rgbToHex(rgbColor.b)\n\t };\n\t }\n\n\t function decimalToRgb(number) {\n\t var result = math.round(number).toString(16).toUpperCase();\n\n\t if (result.length === 1) {\n\t result = \"0\" + result;\n\t }\n\n\t return result;\n\t }\n\n\t function colorToRGB(color) {\n\t var colorLength = color.length;\n\t var rgbColor = {};\n\t if (colorLength === 3) {\n\t rgbColor.r = color[0];\n\t rgbColor.g = color[1];\n\t rgbColor.b = color[2];\n\t } else {\n\t rgbColor.r = color.substring(0, 2);\n\t rgbColor.g = color.substring(2, 4);\n\t rgbColor.b = color.substring(4, 6);\n\t }\n\n\t return rgbColor;\n\t }\n\n\t function rgbToHex(rgb) {\n\t return parseInt(rgb.toString(16), 16);\n\t }\n\n\t function colorBrightness(color) {\n\t var brightness = 0;\n\t if (color) {\n\t color = rgbToDecimal(color);\n\t brightness = math.sqrt(0.241 * color.r * color.r + 0.691 * color.g * color.g + 0.068 * color.b * color.b);\n\t }\n\n\t return brightness;\n\t }\n\n\t function round(value) {\n\t var power = math.pow(10, 4);\n\t return math.round(value * power) / power;\n\t }\n\n\t dataviz.ui.plugin(TreeMap);\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1132);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1132:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dateinput\",\n\t name: \"DateInput\",\n\t category: \"web\",\n\t description: \"The DateInput widget allows to edit date by typing.\",\n\t depends: [ \"core\" ]\n\t};\n\n\t(function ($, undefined) {\n\t var global = window;\n\t var kendo = global.kendo;\n\t var caret = kendo.caret;\n\t var ui = kendo.ui;\n\t var Widget = ui.Widget;\n\t var keys = kendo.keys;\n\t var ns = \".kendoDateInput\";\n\t var proxy = $.proxy;\n\t var objectToString = {}.toString;\n\n\t var INPUT_EVENT_NAME = (kendo.support.propertyChangeEvent ? \"propertychange.kendoDateInput input\" : \"input\") + ns;\n\n\t var STATEDISABLED = \"k-state-disabled\";\n\t var STATEDEFAULT = \"k-state-default\";\n\t // var STATEFOCUSED = \"k-state-focused\";\n\t // var STATEHOVER = \"k-state-hover\";\n\t var STATEINVALID = \"k-state-invalid\";\n\n\t var DISABLED = \"disabled\";\n\t var READONLY = \"readonly\";\n\t var CHANGE = \"change\";\n\n\t var knownSymbols = \"dMyHhmftsz\";\n\n\t var DateInput = Widget.extend({\n\t init: function (element, options) {\n\t var that = this;\n\n\t Widget.fn.init.call(that, element, options);\n\t element = that.element;\n\n\t options = that.options;\n\t options.format = kendo._extractFormat(options.format || kendo.getCulture(options.culture).calendars.standard.patterns.d);\n\t options.min = kendo.parseDate(element.attr(\"min\")) || kendo.parseDate(options.min);\n\t options.max = kendo.parseDate(element.attr(\"max\")) || kendo.parseDate(options.max);\n\n\t var insidePicker = ((element.parent().attr(\"class\") || \"\").indexOf(\"k-picker-wrap\") >= 0);\n\t if (insidePicker) {\n\t that.wrapper = element.parent();\n\t } else {\n\t that.wrapper = element.wrap(\"\").parent();\n\t that.wrapper.addClass(element[0].className).removeClass('input-validation-error');\n\t that.wrapper[0].style.cssText = element[0].style.cssText;\n\t element.css({\n\t width: \"100%\",\n\t height: element[0].style.height\n\t });\n\t }\n\n\t that._inputWrapper = $(that.wrapper[0]);\n\n\t $(\"\").insertAfter(element);\n\n\t that._form();\n\n\t that.element\n\t .addClass(insidePicker ? \" \" : \"k-textbox\")\n\t .attr(\"autocomplete\", \"off\")\n\t .on(\"focusout\" + ns, function () {\n\t that._change();\n\t });\n\n\t try {\n\t element[0].setAttribute(\"type\", \"text\");\n\t } catch (e) {\n\t element[0].type = \"text\";\n\t }\n\n\t var disabled = element.is(\"[disabled]\") || $(that.element).parents(\"fieldset\").is(':disabled');\n\n\t if (disabled) {\n\t that.enable(false);\n\t } else {\n\t that.readonly(element.is(\"[readonly]\"));\n\t }\n\n\t that.value(that.options.value || element.val());\n\n\t kendo.notify(that);\n\t },\n\n\t options: {\n\t name: \"DateInput\",\n\t culture: \"\",\n\t value: \"\",\n\t format: \"\",\n\t min: new Date(1900, 0, 1),\n\t max: new Date(2099, 11, 31),\n\t messages: {\n\t \"year\": \"year\",\n\t \"month\": \"month\",\n\t \"day\": \"day\",\n\t \"weekday\": \"day of the week\",\n\t \"hour\": \"hours\",\n\t \"minute\": \"minutes\",\n\t \"second\": \"seconds\",\n\t \"dayperiod\": \"AM/PM\"\n\t }\n\t },\n\n\t events: [\n\t CHANGE\n\t ],\n\n\t min: function (value) {\n\t if (value !== undefined) {\n\t this.options.min = value;\n\t } else {\n\t return this.options.min;\n\t }\n\t },\n\n\t max: function (value) {\n\t if (value !== undefined) {\n\t this.options.max = value;\n\t } else {\n\t return this.options.max;\n\t }\n\t },\n\n\t setOptions: function (options) {\n\t var that = this;\n\t Widget.fn.setOptions.call(that, options);\n\t this._unbindInput();\n\t this._bindInput();\n\t this._updateElementValue();\n\t },\n\n\t destroy: function () {\n\t var that = this;\n\t that.element.off(ns);\n\n\t if (that._formElement) {\n\t that._formElement.off(\"reset\", that._resetHandler);\n\t }\n\n\t Widget.fn.destroy.call(that);\n\t },\n\n\t value: function (value) {\n\t if (value === undefined) {\n\t return this._dateTime.getDateObject();\n\t }\n\n\t if (value === null) {\n\t value = \"\";\n\t }\n\n\t if (objectToString.call(value) !== \"[object Date]\") {\n\t value = kendo.parseDate(value, this.options.format, this.options.culture);\n\t }\n\n\t if (value && !value.getTime()) {\n\t value = null;\n\t }\n\n\t this._dateTime = new customDateTime(value, this.options.format, this.options.culture, this.options.messages);\n\n\t this._updateElementValue();\n\t this._oldValue = value;\n\t },\n\n\t _updateElementValue: function () {\n\t var stringAndFromat = this._dateTime.toPair(this.options.format, this.options.culture, this.options.messages);\n\t this.element.val(stringAndFromat[0]);\n\t this._oldText = stringAndFromat[0];\n\t this._format = stringAndFromat[1];\n\t },\n\n\t readonly: function (readonly) {\n\t this._editable({\n\t readonly: readonly === undefined ? true : readonly,\n\t disable: false\n\t });\n\t },\n\n\t enable: function (enable) {\n\t this._editable({\n\t readonly: false,\n\t disable: !(enable = enable === undefined ? true : enable)\n\t });\n\t },\n\n\t _bindInput: function () {\n\t var that = this;\n\t that.element\n\t .on(\"focusout\" + ns, function () {\n\t that._change();\n\t })\n\t .on(\"paste\" + ns, proxy(that._paste, that))\n\t .on(\"keydown\" + ns, proxy(that._keydown, that))\n\t .on(INPUT_EVENT_NAME, proxy(that._input, that))\n\t .on(\"mouseup\" + ns, proxy(that._mouseUp, that))\n\t .on(\"DOMMouseScroll\" + ns + \" mousewheel\" + ns, proxy(that._scroll, that));\n\t },\n\n\t _unbindInput: function () {\n\t this.element\n\t .off(\"keydown\" + ns)\n\t .off(\"paste\" + ns)\n\t .off(\"focusout\" + ns)\n\t .off(INPUT_EVENT_NAME)\n\t .off(\"mouseup\" + ns)\n\t .off(\"DOMMouseScroll\" + ns + \" mousewheel\" + ns);\n\t },\n\n\t _editable: function (options) {\n\t var that = this;\n\t var element = that.element;\n\t var disable = options.disable;\n\t var readonly = options.readonly;\n\t var wrapper = that.wrapper;\n\n\t that._unbindInput();\n\n\t if (!readonly && !disable) {\n\t wrapper.addClass(STATEDEFAULT)\n\t .removeClass(STATEDISABLED);\n\t if(element && element.length) {\n\t element[0].removeAttribute(DISABLED);\n\t element[0].removeAttribute(READONLY);\n\t }\n\n\t that._bindInput();\n\t } else {\n\t if (disable) {\n\t wrapper.addClass(STATEDISABLED)\n\t .removeClass(STATEDEFAULT);\n\t element.attr(DISABLED, disable);\n\t if(element && element.length) {\n\t element[0].removeAttribute(READONLY);\n\t }\n\t }\n\t if (readonly) {\n\t element.attr(READONLY, readonly);\n\t }\n\t }\n\t },\n\n\t _change: function () {\n\t var that = this;\n\t var oldValue = that._oldValue;\n\t var value = that.value();\n\n\t if (value && that.min() && value < that.min()) {\n\t that.value(that.min());\n\t value = that.value();\n\t }\n\t if (value && that.max() && value > that.max()) {\n\t that.value(that.max());\n\t value = that.value();\n\t }\n\n\t if (oldValue && value && value.getTime() !== oldValue.getTime() ||\n\t oldValue && !value ||\n\t !oldValue && value\n\t ) {\n\t that._oldValue = value;\n\t that.trigger(CHANGE);\n\t that.element.trigger(CHANGE);\n\t }\n\t },\n\n\t _input: function () {\n\t var that = this;\n\t var element = that.element[0];\n\t var blinkInvalid = false;\n\n\t if (kendo._activeElement() !== element) {\n\t return;\n\t }\n\n\t var diff = approximateStringMatching(\n\t this._oldText,\n\t this._format,\n\t this.element[0].value,\n\t caret(this.element[0])[0]);\n\n\t var navigationOnly = (diff.length === 1 && diff[0][1] === \" \");\n\t if (!navigationOnly) {\n\t for (var i = 0; i < diff.length; i++) {\n\t var valid = this._dateTime.parsePart(diff[i][0], diff[i][1]);\n\t blinkInvalid = blinkInvalid || !valid;\n\t }\n\t }\n\t this._updateElementValue();\n\n\t if (diff.length && diff[0][0] !== \" \") {\n\t this._selectSegment(diff[0][0]);\n\n\t //android fix\n\t if (!navigationOnly) {\n\t var difSym = diff[0][0];\n\t setTimeout(function () { that._selectSegment(difSym); });\n\t }\n\t }\n\t if (navigationOnly) {\n\t var newEvent = { keyCode: 39, preventDefault: function () { } };\n\t this._keydown(newEvent);\n\t }\n\t if (blinkInvalid) {\n\t clearTimeout(that._blinkInvalidTimeout);\n\t var stateInvalid = STATEINVALID;\n\t that.wrapper.addClass(STATEINVALID);\n\t that._blinkInvalidTimeout = setTimeout(function () { that.wrapper.removeClass(stateInvalid); }, 100);\n\t }\n\t },\n\n\t _mouseUp: function () {\n\t var selection = caret(this.element[0]);\n\t if (selection[0] === selection[1]) {\n\t this._selectNearestSegment();\n\t }\n\t },\n\n\t _scroll: function (e) {\n\t if (kendo._activeElement() !== this.element[0] || this.element.is(\"[readonly]\")) {\n\t return;\n\t }\n\t e = window.event || e;\n\n\t var newEvent = { keyCode: 37, preventDefault: function () { } };\n\n\t if (e.shiftKey) {\n\t newEvent.keyCode = (e.wheelDelta || -e.detail) > 0 ? 37 : 39;\n\t } else {\n\t newEvent.keyCode = (e.wheelDelta || -e.detail) > 0 ? 38 : 40;\n\t }\n\t this._keydown(newEvent);\n\t e.returnValue = false;\n\t if (e.preventDefault) {\n\t e.preventDefault();\n\t }\n\t if (e.stopPropagation) {\n\t e.stopPropagation();\n\t }\n\t },\n\n\t _form: function () {\n\t var that = this;\n\t var element = that.element;\n\t var formId = element.attr(\"form\");\n\t var form = formId ? $(\"#\" + formId) : element.closest(\"form\");\n\t var initialValue = element[0].value;\n\n\t if (!initialValue && that.options.value) {\n\t initialValue = that.options.value;\n\t }\n\n\t if (form[0]) {\n\t that._resetHandler = function () {\n\t setTimeout(function () {\n\t that.value(initialValue);\n\t });\n\t };\n\n\t that._formElement = form.on(\"reset\", that._resetHandler);\n\t }\n\t },\n\n\t _paste: function (e) {\n\t e.preventDefault();\n\t },\n\n\t _keydown: function (e) {\n\t var key = e.keyCode;\n\t var selection;\n\t if (key == 37 || key == 39) { //left/right\n\t e.preventDefault();\n\t selection = caret(this.element[0]);\n\t if (selection[0] != selection[1]) {\n\t this._selectNearestSegment();\n\t }\n\t var dir = (key == 37) ? -1 : 1;\n\t var index = (dir == -1) ? caret(this.element[0])[0] - 1 : caret(this.element[0])[1] + 1;\n\t while (index >= 0 && index < this._format.length) {\n\t if (knownSymbols.indexOf(this._format[index]) >= 0) {\n\t this._selectSegment(this._format[index]);\n\t break;\n\t }\n\t index += dir;\n\t }\n\t }\n\t if (key == 38 || key == 40) { //up/down\n\t e.preventDefault();\n\t selection = caret(this.element[0]);\n\t var symbol = this._format[selection[0]];\n\t if (knownSymbols.indexOf(symbol) >= 0) {\n\t var interval = 1;\n\t if (symbol == 'm') {\n\t interval = this.options.interval || 1;\n\t }\n\t this._dateTime.modifyPart(symbol, key == 38 ? interval * 1 : interval * -1);\n\t this._updateElementValue();\n\t this._selectSegment(symbol);\n\t this.element.trigger(CHANGE);\n\t }\n\t }\n\t if (kendo.support.browser.msie && kendo.support.browser.version < 10) {\n\t var keycode = e.keyCode ? e.keyCode : e.which;\n\t if (keycode === 8 || keycode === 46) {\n\t var that = this;\n\t setTimeout(function () {\n\t that._input();\n\t }, 0);\n\t }\n\t }\n\t if (key === keys.ENTER){\n\t this._change();\n\t }\n\t },\n\n\t _selectNearestSegment: function () {\n\t var selection = caret(this.element[0]);\n\t var start = selection[0];\n\t for (var i = start, j = start - 1; i < this._format.length || j >= 0; i++ , j--) {\n\t if (i < this._format.length && knownSymbols.indexOf(this._format[i]) !== -1) {\n\t this._selectSegment(this._format[i]);\n\t return;\n\t }\n\t if (j >= 0 && knownSymbols.indexOf(this._format[j]) !== -1) {\n\t this._selectSegment(this._format[j]);\n\t return;\n\t }\n\t }\n\t },\n\n\t _selectSegment: function (symbol) {\n\t var begin = -1, end = 0;\n\t for (var i = 0; i < this._format.length; i++) {\n\t if (this._format[i] === symbol) {\n\t end = i + 1;\n\t if (begin === -1) {\n\t begin = i;\n\t }\n\t }\n\t }\n\t if (begin < 0) {\n\t begin = 0;\n\t }\n\t caret(this.element, begin, end);\n\t }\n\n\t });\n\n\t ui.plugin(DateInput);\n\n\t var customDateTime = function (initDate, initFormat, initCulture, initMessages) {\n\n\t var value = null;\n\t var year = true, month = true, date = true, hours = true, minutes = true, seconds = true, milliseconds = true;\n\t var typedMonthPart = \"\";\n\t var typedDayPeriodPart = \"\";\n\t var placeholders = {};\n\n\t //TODO: rewrite pad method\n\t var zeros = [\"\", \"0\", \"00\", \"000\", \"0000\"];\n\t function pad(number, digits, end) {\n\t number = number + \"\";\n\t digits = digits || 2;\n\t end = digits - number.length;\n\n\t if (end) {\n\t return zeros[digits].substring(0, end) + number;\n\t }\n\n\t return number;\n\t }\n\t var dateFormatRegExp = /dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|HH|H|hh|h|mm|m|fff|ff|f|tt|ss|s|zzz|zz|z|\"[^\"]*\"|'[^']*'/g;\n\t var months = null, calendar = null, days = null, returnsFormat = false;\n\t var matcher = function (match) {\n\t var mins, sign;\n\t var result;\n\n\t switch (match) {\n\t case (\"d\"): result = date ? value.getDate() : placeholders.day; break;\n\t case (\"dd\"): result = date ? pad(value.getDate()) : placeholders.day; break;\n\t case (\"ddd\"): result = date && month && year ? days.namesAbbr[value.getDay()] : placeholders.weekday; break;\n\t case (\"dddd\"): result = date && month && year ? days.names[value.getDay()] : placeholders.weekday; break;\n\n\t case (\"M\"): result = month ? value.getMonth() + 1 : placeholders.month; break;\n\t case (\"MM\"): result = month ? pad(value.getMonth() + 1) : placeholders.month; break;\n\t case (\"MMM\"): result = month ? months.namesAbbr[value.getMonth()] : placeholders.month; break;\n\t case (\"MMMM\"): result = month ? months.names[value.getMonth()] : placeholders.month; break;\n\n\t case (\"yy\"): result = year ? pad(value.getFullYear() % 100) : placeholders.year; break;\n\t case (\"yyyy\"): result = year ? pad(value.getFullYear(), 4) : placeholders.year; break;\n\n\t case (\"h\"): result = hours ? value.getHours() % 12 || 12 : placeholders.hour; break;\n\t case (\"hh\"): result = hours ? pad(value.getHours() % 12 || 12) : placeholders.hour; break;\n\t case (\"H\"): result = hours ? value.getHours() : placeholders.hour; break;\n\t case (\"HH\"): result = hours ? pad(value.getHours()) : placeholders.hour; break;\n\n\t case (\"m\"): result = minutes ? value.getMinutes() : placeholders.minute; break;\n\t case (\"mm\"): result = minutes ? pad(value.getMinutes()) : placeholders.minute; break;\n\t case (\"s\"): result = seconds ? value.getSeconds() : placeholders.second; break;\n\t case (\"ss\"): result = seconds ? pad(value.getSeconds()) : placeholders.second; break;\n\t case (\"f\"): result = milliseconds ? Math.floor(value.getMilliseconds() / 100) : milliseconds; break;\n\t case (\"ff\"):\n\t result = value.getMilliseconds();\n\t if (result > 99) {\n\t result = Math.floor(result / 10);\n\t }\n\t result = milliseconds ? pad(result) : match;\n\t break;\n\t case (\"fff\"): result = milliseconds ? pad(value.getMilliseconds(), 3) : match; break;\n\t case (\"tt\"): result = hours ? (value.getHours() < 12 ? calendar.AM[0] : calendar.PM[0]) : placeholders.dayperiod; break;\n\t case (\"zzz\"):\n\t mins = value.getTimezoneOffset();\n\t sign = mins < 0;\n\t result = Math.abs(mins / 60).toString().split(\".\")[0];\n\t mins = Math.abs(mins) - (result * 60);\n\t result = (sign ? \"+\" : \"-\") + pad(result);\n\t result += \":\" + pad(mins);\n\t break;\n\t case (\"z\"):\n\t case (\"zz\"):\n\t result = value.getTimezoneOffset() / 60;\n\t sign = result < 0;\n\t result = Math.abs(result).toString().split(\".\")[0];\n\t result = (sign ? \"+\" : \"-\") + (match === \"zz\" ? pad(result) : result);\n\t break;\n\t }\n\t result = (result !== undefined ? result : match.slice(1, match.length - 1));\n\n\t if (returnsFormat) {\n\t result = \"\" + result;\n\t var formatResult = \"\";\n\t if (match == \"ddd\") { match = \"EEE\"; }\n\t if (match == \"dddd\") { match = \"EEEE\"; }\n\t for (var i = 0; i < result.length; i++) {\n\t formatResult += match[0];\n\t }\n\t return formatResult;\n\t } else {\n\t return result;\n\t }\n\t };\n\n\t function generateMatcher(retFormat) {\n\t returnsFormat = retFormat;\n\t return matcher;\n\t }\n\n\t function setExisting(symbol, val) {\n\t switch (symbol) {\n\t case \"y\": year = val; break;\n\t case \"M\": month = val;\n\t if (!val) {\n\t value.setMonth(0);\n\t typedMonthPart = \"\";\n\t }\n\t break;\n\t case \"d\": date = val; break;\n\t case \"H\":\n\t case \"h\": hours = val;\n\t if (!val) {\n\t typedDayPeriodPart = \"\";\n\t }\n\t break;\n\t case \"m\": minutes = val; break;\n\t case \"s\": seconds = val; break;\n\t default: return;\n\t }\n\t }\n\n\t this.setValue = function (val) {\n\t date = val;\n\t };\n\n\t this.getValue = function () {\n\t return date;\n\t };\n\n\t this.modifyPart = function (symbol, offset) {\n\t var newValue = new Date((value && value.getTime) ? value.getTime() : value);\n\t switch (symbol) {\n\t case \"y\": newValue.setFullYear(newValue.getFullYear() + offset); break;\n\t case \"M\":\n\t var newMonth = newValue.getMonth() + offset;\n\t newValue.setMonth(newMonth);\n\t if (newValue.getMonth() % 12 !== (newMonth + 12) % 12) {\n\t //handle case when new month does not have such date\n\t newValue.setDate(1);\n\t newValue.setMonth(newMonth);\n\t }\n\t break;\n\t case \"d\":\n\t case \"E\": newValue.setDate(newValue.getDate() + offset); break;\n\t case \"H\":\n\t case \"h\": newValue.setHours(newValue.getHours() + offset); break;\n\t case \"m\": newValue.setMinutes(newValue.getMinutes() + offset); break;\n\t case \"s\": newValue.setSeconds(newValue.getSeconds() + offset); break;\n\t case \"t\": newValue.setHours((newValue.getHours() + 12) % 24); break;\n\t default: break;\n\t }\n\t if (newValue.getFullYear() > 0) {\n\t setExisting(symbol, true);\n\t value = newValue;\n\t }\n\t };\n\n\t this.parsePart = function (symbol, currentChar) {\n\t if (!currentChar) {\n\t setExisting(symbol, false);\n\t return true;\n\t }\n\t var newValue = new Date((value && value.getTime) ? value.getTime() : value);\n\t var newHours;\n\t switch (symbol) {\n\t case \"d\":\n\t var newDate = (date ? newValue.getDate() * 10 : 0) + parseInt(currentChar, 10);\n\t if (isNaN(newDate)) { return; }\n\t while (newDate > 31) {\n\t newDate = parseInt(newDate.toString().slice(1), 10);\n\t }\n\t if (newDate < 1) {\n\t date = false;\n\t } else {\n\t newValue.setDate(newDate);\n\t if (newValue.getMonth() !== value.getMonth()) {\n\t return;\n\t }\n\t date = true;\n\t }\n\t break;\n\t case \"M\":\n\t var newMonth = (month ? (newValue.getMonth() + 1) * 10 : 0) + parseInt(currentChar, 10);\n\t if (!isNaN(newMonth)) {\n\t while (newMonth > 12) {\n\t newMonth = parseInt(newMonth.toString().slice(1), 10);\n\t }\n\t if (newMonth < 1) {\n\t month = false;\n\t } else {\n\t newValue.setMonth(newMonth - 1);\n\t if (newValue.getMonth() !== newMonth - 1) {\n\t newValue.setDate(1);\n\t newValue.setMonth(newMonth - 1);\n\t }\n\t month = true;\n\t }\n\t }\n\t else {\n\t var monthNames = calendar.months.names;\n\t typedMonthPart += currentChar.toLowerCase();\n\n\t while (typedMonthPart.length > 0) {\n\t for (var i = 0; i < monthNames.length; i++) {\n\t if (monthNames[i].toLowerCase().indexOf(typedMonthPart) === 0) {\n\t newValue.setMonth(i);\n\t month = true;\n\t value = newValue;\n\t return true;\n\t }\n\t }\n\t typedMonthPart = typedMonthPart.substring(1, typedMonthPart.length);\n\t }\n\t return false;\n\t }\n\t break;\n\t case \"y\":\n\t var newYear = (year ? (newValue.getFullYear()) * 10 : 0) + parseInt(currentChar, 10);\n\t if (isNaN(newYear)) {return;}\n\t while (newYear > 9999) {\n\t newYear = parseInt(newYear.toString().slice(1), 10);\n\t }\n\t if (newYear < 1) {\n\t year = false;\n\t } else {\n\t newValue.setFullYear(newYear);\n\t year = true;\n\t }\n\t break;\n\t case \"h\":\n\t newHours = (hours ? (newValue.getHours() % 12 || 12) * 10 : 0) + parseInt(currentChar, 10);\n\t if (isNaN(newHours)) { return; }\n\t while (newHours > 12) {\n\t newHours = parseInt(newHours.toString().slice(1), 10);\n\t }\n\t newValue.setHours(Math.floor(newValue.getHours() / 12) * 12 + newHours % 12);\n\t hours = true;\n\t break;\n\t case \"H\":\n\t newHours = (hours ? (newValue.getHours()) * 10 : 0) + parseInt(currentChar, 10);\n\t if (isNaN(newHours)) { return; }\n\t while (newHours > 23) {\n\t newHours = parseInt(newHours.toString().slice(1), 10);\n\t }\n\t newValue.setHours(newHours);\n\t hours = true;\n\t break;\n\t case \"m\":\n\t var newMinutes = (minutes ? (newValue.getMinutes()) * 10 : 0) + parseInt(currentChar, 10);\n\t if (isNaN(newMinutes)) { return; }\n\t while (newMinutes > 59) {\n\t newMinutes = parseInt(newMinutes.toString().slice(1), 10);\n\t }\n\t newValue.setMinutes(newMinutes);\n\t minutes = true;\n\t break;\n\t case \"s\":\n\t var newSeconds = (seconds ? (newValue.getSeconds()) * 10 : 0) + parseInt(currentChar, 10);\n\t if (isNaN(newSeconds)) { return; }\n\t while (newSeconds > 59) {\n\t newSeconds = parseInt(newSeconds.toString().slice(1), 10);\n\t }\n\t newValue.setSeconds(newSeconds);\n\t seconds = true;\n\t break;\n\t case \"t\":\n\t if (hours) {\n\t typedDayPeriodPart += currentChar.toLowerCase();\n\t while (typedDayPeriodPart.length > 0) {\n\t if (calendar.AM[0].toLowerCase().indexOf(typedDayPeriodPart) === 0 && newValue.getHours() >= 12 ||\n\t calendar.PM[0].toLowerCase().indexOf(typedDayPeriodPart) === 0 && newValue.getHours() < 12) {\n\t newValue.setHours((newValue.getHours() + 12) % 24);\n\t value = newValue;\n\t return true;\n\t }\n\t typedDayPeriodPart = typedDayPeriodPart.substring(1, typedDayPeriodPart.length);\n\t }\n\t return false;\n\t }\n\t break;\n\t default: break;\n\t }\n\t value = newValue;\n\t return true;\n\t };\n\n\t this.toPair = function (format, culture , messages) {\n\t if (!format) {\n\t return [\"\", \"\"];\n\t }\n\t culture = kendo.getCulture(culture);\n\t calendar = culture.calendars.standard;\n\t format = calendar.patterns[format] || format;\n\t days = calendar.days;\n\t months = calendar.months;\n\t placeholders = messages;\n\t return [\n\t format.replace(dateFormatRegExp, generateMatcher(false)),\n\t format.replace(dateFormatRegExp, generateMatcher(true))\n\t ];\n\t };\n\n\t this.getDateObject = function () {\n\t return (year && month && date && hours && minutes && seconds && milliseconds) ?\n\t new Date(value.getTime()) : null;\n\t };\n\n\t if (!initDate) {\n\t value = new Date();\n\t var sampleFormat = this.toPair(initFormat, initCulture, initMessages)[1];\n\t for (var i = 0; i < sampleFormat.length; i++) {\n\t setExisting(sampleFormat[i], false);\n\t }\n\t } else {\n\t value = new Date(initDate.getTime());\n\t }\n\t };\n\n\t function approximateStringMatching(oldText, oldFormat, newText, caret){\n\t var oldTextSeparator = oldText[caret + oldText.length - newText.length];\n\t oldText = oldText.substring(0, caret + oldText.length - newText.length);\n\t newText = newText.substring(0, caret);\n\t var diff = [];\n\t var i;\n\t //handle typing single character over the same selection\n\t if (oldText === newText && caret > 0) {\n\t diff.push([oldFormat[caret - 1], newText[caret - 1]]);\n\t return diff;\n\t }\n\t if (oldText.indexOf(newText) === 0 && (newText.length === 0 || oldFormat[newText.length - 1] !== oldFormat[newText.length])) {\n\t //handle delete/backspace\n\t var deletedSymbol = \"\";\n\t for (i = newText.length; i < oldText.length; i++) {\n\t if (oldFormat[i] !== deletedSymbol && knownSymbols.indexOf(oldFormat[i]) >= 0) {\n\t deletedSymbol = oldFormat[i];\n\t diff.push([deletedSymbol, \"\"]);\n\t }\n\t }\n\t return diff;\n\t }\n\n\t //handle entering space or separator, for nagivation to next item\n\t if (newText[newText.length - 1] === \" \" || newText[newText.length - 1] === oldTextSeparator) {\n\t return [[oldFormat[caret - 1], \" \"]];\n\t }\n\n\t //handle inserting text (new text is longer than previous)\n\t //handle typing over literal as well\n\t if (newText.indexOf(oldText) === 0 || knownSymbols.indexOf(oldFormat[caret - 1]) === -1) {\n\t var symbol = oldFormat[0];\n\t for (i = Math.max(0, oldText.length - 1); i < oldFormat.length; i++) {\n\t if (knownSymbols.indexOf(oldFormat[i]) >= 0) {\n\t symbol = oldFormat[i];\n\t break;\n\t }\n\t }\n\t return [[symbol, newText[caret - 1]]];\n\t }\n\t //handle typing over correctly selected part\n\t return [[oldFormat[caret - 1], newText[caret - 1]]];\n\t}\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1133);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1054:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.popup\");\n\n/***/ }),\n\n/***/ 1133:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1134), __webpack_require__(1054), __webpack_require__(1135) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"datepicker\",\n\t name: \"DatePicker\",\n\t category: \"web\",\n\t description: \"The DatePicker widget allows the user to select a date from a calendar or by direct input.\",\n\t depends: [ \"calendar\", \"popup\" ]\n\t};\n\n\t(function($, undefined) {\n\t var kendo = window.kendo,\n\t ui = kendo.ui,\n\t Widget = ui.Widget,\n\t parse = kendo.parseDate,\n\t keys = kendo.keys,\n\t support = kendo.support,\n\t template = kendo.template,\n\t activeElement = kendo._activeElement,\n\t DIV = \"
    \",\n\t SPAN = \"\",\n\t ns = \".kendoDatePicker\",\n\t CLICK = \"click\" + ns,\n\t UP = support.mouseAndTouchPresent ? kendo.applyEventMap(\"up\", ns.slice(1)) : CLICK,\n\t OPEN = \"open\",\n\t CLOSE = \"close\",\n\t CHANGE = \"change\",\n\t DISABLED = \"disabled\",\n\t READONLY = \"readonly\",\n\t DEFAULT = \"k-state-default\",\n\t FOCUSED = \"k-state-focused\",\n\t SELECTED = \"k-state-selected\",\n\t STATEDISABLED = \"k-state-disabled\",\n\t HOVER = \"k-state-hover\",\n\t HOVEREVENTS = \"mouseenter\" + ns + \" mouseleave\" + ns,\n\t MOUSEDOWN = \"mousedown\" + ns,\n\t ID = \"id\",\n\t MIN = \"min\",\n\t MAX = \"max\",\n\t MONTH = \"month\",\n\t ARIA_DISABLED = \"aria-disabled\",\n\t ARIA_EXPANDED = \"aria-expanded\",\n\t ARIA_HIDDEN = \"aria-hidden\",\n\t calendar = kendo.calendar,\n\t isInRange = calendar.isInRange,\n\t restrictValue = calendar.restrictValue,\n\t isEqualDatePart = calendar.isEqualDatePart,\n\t extend = $.extend,\n\t proxy = $.proxy,\n\t DATE = Date;\n\n\t function normalize(options) {\n\t var parseFormats = options.parseFormats,\n\t format = options.format;\n\n\t calendar.normalize(options);\n\n\n\t parseFormats = $.isArray(parseFormats) ? parseFormats : [parseFormats];\n\n\t if (!parseFormats.length) {\n\t parseFormats.push(\"yyyy-MM-dd\");\n\t }\n\n\t if ($.inArray(format, parseFormats) === -1) {\n\t parseFormats.splice(0, 0, options.format);\n\t }\n\n\t options.parseFormats = parseFormats;\n\t }\n\n\t function preventDefault(e) {\n\t e.preventDefault();\n\t }\n\n\t var DateView = function(options) {\n\t var that = this, id,\n\t body = document.body,\n\t div = $(DIV).attr(ARIA_HIDDEN, \"true\")\n\t .addClass(\"k-calendar-container\");\n\n\t that.options = options = options || {};\n\t id = options.id;\n\n\t if(!options.omitPopup){\n\t div.appendTo(body);\n\t that.popup = new ui.Popup(div, extend(options.popup, options, { name: \"Popup\", isRtl: kendo.support.isRtl(options.anchor) }));\n\t } else {\n\t div = options.dateDiv;\n\t }\n\t if (id) {\n\t id += \"_dateview\";\n\n\t div.attr(ID, id);\n\t that._dateViewID = id;\n\t }\n\t that.div = div;\n\n\t that.value(options.value);\n\t };\n\n\t DateView.prototype = {\n\t _calendar: function() {\n\t var that = this;\n\t var calendar = that.calendar;\n\t var options = that.options;\n\t var div;\n\n\t if (!calendar) {\n\t div = $(DIV).attr(ID, kendo.guid())\n\t .appendTo(options.omitPopup ? options.dateDiv : that.popup.element)\n\t .on(MOUSEDOWN, preventDefault)\n\t .on(CLICK, \"td:has(.k-link)\", proxy(that._click, that));\n\n\t that.calendar = calendar = new ui.Calendar(div, { componentType: options.componentType });\n\t that._setOptions(options);\n\n\t kendo.calendar.makeUnselectable(calendar.element);\n\n\t calendar.navigate(that._value || that._current, options.start);\n\n\t that.value(that._value);\n\t }\n\t },\n\n\t _setOptions: function(options) {\n\t this.calendar.setOptions({\n\t focusOnNav: false,\n\t change: options.change,\n\t culture: options.culture,\n\t dates: options.dates,\n\t depth: options.depth,\n\t footer: options.footer,\n\t format: options.format,\n\t max: options.max,\n\t min: options.min,\n\t month: options.month,\n\t weekNumber: options.weekNumber,\n\t start: options.start,\n\t disableDates: options.disableDates\n\t });\n\t },\n\n\t setOptions: function(options) {\n\t var old = this.options;\n\t var disableDates = options.disableDates;\n\n\t if (disableDates) {\n\t options.disableDates = calendar.disabled(disableDates);\n\t }\n\n\t this.options = extend(old, options, {\n\t change: old.change,\n\t close: old.close,\n\t open: old.open\n\t });\n\n\t if (this.calendar) {\n\t this._setOptions(this.options);\n\t }\n\t },\n\n\t destroy: function() {\n\t if(this.popup){\n\t this.popup.destroy();\n\t }\n\t },\n\n\t open: function() {\n\t var that = this;\n\t var popupHovered;\n\n\t that._calendar();\n\n\t // In some cases when the popup is opened resize is triggered which will cause it to close\n\t // Setting the below flag will prevent this from happening\n\t // Reference: https://github.com/telerik/kendo/pull/7553\n\t popupHovered = that.popup._hovered;\n\t that.popup._hovered = true;\n\n\t that.popup.open();\n\n\t setTimeout(function() {\n\t that.popup._hovered = popupHovered;\n\t }, 1);\n\t },\n\n\t close: function() {\n\t this.popup.close();\n\t },\n\n\t min: function(value) {\n\t this._option(MIN, value);\n\t },\n\n\t max: function(value) {\n\t this._option(MAX, value);\n\t },\n\n\t toggle: function() {\n\t var that = this;\n\n\t that[that.popup.visible() ? CLOSE : OPEN]();\n\t },\n\n\t move: function(e) {\n\t var that = this,\n\t key = e.keyCode,\n\t calendar = that.calendar,\n\t selectIsClicked = e.ctrlKey && key == keys.DOWN || key == keys.ENTER,\n\t handled = false;\n\n\t if (e.altKey) {\n\t if (key == keys.DOWN) {\n\t that.open();\n\t e.preventDefault();\n\t handled = true;\n\t } else if (key == keys.UP) {\n\t that.close();\n\t e.preventDefault();\n\t handled = true;\n\t }\n\n\t } else if (that.popup && that.popup.visible()) {\n\n\t if (key == keys.ESC || (selectIsClicked && calendar._cell.hasClass(SELECTED))) {\n\t that.close();\n\t e.preventDefault();\n\t return true;\n\t }\n\t //spacebar selects a date in the calendar\n\t if (key != keys.SPACEBAR) {\n\t that._current = calendar._move(e);\n\t }\n\n\t handled = true;\n\t }\n\n\t return handled;\n\t },\n\n\t current: function(date) {\n\t this._current = date;\n\t if (this.calendar) {\n\t this.calendar._focus(date);\n\t }\n\t },\n\n\t value: function(value) {\n\t var that = this,\n\t calendar = that.calendar,\n\t options = that.options,\n\t disabledDate = options.disableDates;\n\n\t if (disabledDate && disabledDate(value)) {\n\t value = null;\n\t }\n\n\t that._value = value;\n\t that._current = new DATE(+restrictValue(value, options.min, options.max));\n\n\t if (calendar) {\n\t calendar.value(value);\n\t }\n\t },\n\n\t _click: function(e) {\n\n\t if (e.currentTarget.className.indexOf(SELECTED) !== -1) {\n\t this.calendar.trigger(\"change\");\n\t this.close();\n\t }\n\t },\n\n\t _option: function(option, value) {\n\t var that = this;\n\t var calendar = that.calendar;\n\n\t that.options[option] = value;\n\n\t if (calendar) {\n\t calendar[option](value);\n\t }\n\t }\n\t };\n\n\t DateView.normalize = normalize;\n\n\t kendo.DateView = DateView;\n\n\t var DatePicker = Widget.extend({\n\t init: function(element, options) {\n\t var that = this,\n\t disabled,\n\t div;\n\n\t Widget.fn.init.call(that, element, options);\n\t element = that.element;\n\t options = that.options;\n\n\t options.disableDates = kendo.calendar.disabled(options.disableDates);\n\n\t options.min = parse(element.attr(\"min\")) || parse(options.min);\n\t options.max = parse(element.attr(\"max\")) || parse(options.max);\n\n\t normalize(options);\n\n\t that._initialOptions = extend({}, options);\n\n\t that._wrapper();\n\n\t that.dateView = new DateView(extend({}, options, {\n\t id: element.attr(ID),\n\t anchor: that.wrapper,\n\t change: function() {\n\t // calendar is the current scope\n\t that._change(this.value());\n\t that.close();\n\t },\n\t close: function(e) {\n\t if (that.trigger(CLOSE)) {\n\t e.preventDefault();\n\t } else {\n\t element.attr(ARIA_EXPANDED, false);\n\t div.attr(ARIA_HIDDEN, true);\n\t }\n\t },\n\t open: function(e) {\n\t var options = that.options,\n\t date;\n\n\t if (that.trigger(OPEN)) {\n\t e.preventDefault();\n\t } else {\n\t if (that.element.val() !== that._oldText) {\n\t date = parse(element.val(), options.parseFormats, options.culture);\n\n\t that.dateView[date ? \"current\" : \"value\"](date);\n\t }\n\n\t element.attr(ARIA_EXPANDED, true);\n\t div.attr(ARIA_HIDDEN, false);\n\n\t that._updateARIA(date);\n\n\t }\n\t }\n\t }));\n\t div = that.dateView.div;\n\n\t that._icon();\n\n\t try {\n\t element[0].setAttribute(\"type\", \"text\");\n\t } catch(e) {\n\t element[0].type = \"text\";\n\t }\n\n\t element\n\t .addClass(\"k-input\")\n\t .attr({\n\t role: \"combobox\",\n\t \"aria-expanded\": false,\n\t \"aria-owns\": that.dateView._dateViewID,\n\t \"autocomplete\": \"off\"\n\t });\n\t that._reset();\n\t that._template();\n\n\t disabled = element.is(\"[disabled]\") || $(that.element).parents(\"fieldset\").is(':disabled');\n\t if (disabled) {\n\t that.enable(false);\n\t } else {\n\t that.readonly(element.is(\"[readonly]\"));\n\t }\n\n\t that._createDateInput(options);\n\n\t that._old = that._update(options.value || that.element.val());\n\t that._oldText = element.val();\n\n\t kendo.notify(that);\n\t },\n\t events: [\n\t OPEN,\n\t CLOSE,\n\t CHANGE],\n\t options: {\n\t name: \"DatePicker\",\n\t value: null,\n\t footer: \"\",\n\t format: \"\",\n\t culture: \"\",\n\t parseFormats: [],\n\t min: new Date(1900, 0, 1),\n\t max: new Date(2099, 11, 31),\n\t start: MONTH,\n\t depth: MONTH,\n\t animation: {},\n\t month: {},\n\t dates: [],\n\t disableDates: null,\n\t ARIATemplate: 'Current focused date is #=kendo.toString(data.current, \"D\")#',\n\t dateInput: false,\n\t weekNumber: false\n\t },\n\n\t setOptions: function(options) {\n\t var that = this;\n\t var value = that._value;\n\n\t Widget.fn.setOptions.call(that, options);\n\n\t options = that.options;\n\n\t options.min = parse(options.min);\n\t options.max = parse(options.max);\n\n\t normalize(options);\n\n\t that.dateView.setOptions(options);\n\t that._createDateInput(options);\n\n\t if (!that._dateInput) {\n\t that.element.val(kendo.toString(value, options.format, options.culture));\n\t }\n\n\t if (value) {\n\t that._updateARIA(value);\n\t }\n\t },\n\n\t _editable: function(options) {\n\t var that = this,\n\t icon = that._dateIcon.off(ns),\n\t element = that.element.off(ns),\n\t wrapper = that._inputWrapper.off(ns),\n\t readonly = options.readonly,\n\t disable = options.disable;\n\n\t if (!readonly && !disable) {\n\t wrapper\n\t .addClass(DEFAULT)\n\t .removeClass(STATEDISABLED)\n\t .on(HOVEREVENTS, that._toggleHover);\n\t if(element && element.length) {\n\t element[0].removeAttribute(DISABLED);\n\t element[0].removeAttribute(READONLY);\n\t }\n\t element.attr(ARIA_DISABLED, false)\n\t .on(\"keydown\" + ns, proxy(that._keydown, that))\n\t .on(\"focusout\" + ns, proxy(that._blur, that))\n\t .on(\"focus\" + ns, function() {\n\t that._inputWrapper.addClass(FOCUSED);\n\t });\n\n\t icon.on(UP, proxy(that._click, that))\n\t .on(MOUSEDOWN, preventDefault);\n\t } else {\n\t wrapper\n\t .addClass(disable ? STATEDISABLED : DEFAULT)\n\t .removeClass(disable ? DEFAULT : STATEDISABLED);\n\n\t element.attr(DISABLED, disable)\n\t .attr(READONLY, readonly)\n\t .attr(ARIA_DISABLED, disable);\n\t }\n\t },\n\n\t readonly: function(readonly) {\n\t this._editable({\n\t readonly: readonly === undefined ? true : readonly,\n\t disable: false\n\t });\n\t if (this._dateInput) {\n\t this._dateInput._editable({\n\t readonly: readonly === undefined ? true : readonly,\n\t disable: false\n\t });\n\t }\n\t },\n\n\t enable: function(enable) {\n\t this._editable({\n\t readonly: false,\n\t disable: !(enable = enable === undefined ? true : enable)\n\t });\n\t if (this._dateInput) {\n\t this._dateInput._editable({\n\t readonly: false,\n\t disable: !(enable = enable === undefined ? true : enable)\n\t });\n\t }\n\t },\n\n\t destroy: function() {\n\t var that = this;\n\n\t Widget.fn.destroy.call(that);\n\n\t that.dateView.destroy();\n\n\t that.element.off(ns);\n\t that._dateIcon.off(ns);\n\t that._inputWrapper.off(ns);\n\n\t if (that._form) {\n\t that._form.off(\"reset\", that._resetHandler);\n\t }\n\t },\n\n\t open: function() {\n\t this.dateView.open();\n\t },\n\n\t close: function() {\n\t this.dateView.close();\n\t },\n\n\t min: function(value) {\n\t return this._option(MIN, value);\n\t },\n\n\t max: function(value) {\n\t return this._option(MAX, value);\n\t },\n\n\t value: function(value) {\n\t var that = this;\n\n\t if (value === undefined) {\n\t return that._value;\n\t }\n\n\t that._old = that._update(value);\n\n\t if (that._old === null) {\n\t that.element.val(\"\");\n\t }\n\n\t that._oldText = that.element.val();\n\t },\n\n\t _toggleHover: function(e) {\n\t $(e.currentTarget).toggleClass(HOVER, e.type === \"mouseenter\");\n\t },\n\n\t _blur: function() {\n\t var that = this,\n\t value = that.element.val();\n\n\t that.close();\n\t if (value !== that._oldText) {\n\t that._change(value);\n\t if (!value) {\n\t that.dateView.current(kendo.calendar.getToday());\n\t }\n\t }\n\n\t that._inputWrapper.removeClass(FOCUSED);\n\t },\n\n\t _click: function(e) {\n\t var that = this;\n\n\t that.dateView.toggle();\n\t that._focusElement(e.type);\n\t },\n\n\t _focusElement: function(eventType) {\n\t var element = this.element;\n\n\t if ((!support.touch || (support.mouseAndTouchPresent && !(eventType || \"\").match(/touch/i))) && element[0] !== activeElement()) {\n\t element.trigger(\"focus\");\n\t }\n\t },\n\n\t _change: function(value) {\n\t var that = this,\n\t oldValue = that.element.val(),\n\t dateChanged;\n\n\t value = that._update(value);\n\t dateChanged = !kendo.calendar.isEqualDate(that._old, value);\n\n\t var valueUpdated = dateChanged && !that._typing;\n\t var textFormatted = oldValue !== that.element.val();\n\n\t if (valueUpdated || textFormatted) {\n\t that.element.trigger(CHANGE);\n\t }\n\n\t if (dateChanged) {\n\t that._old = value;\n\t that._oldText = that.element.val();\n\n\t that.trigger(CHANGE);\n\t }\n\n\t that._typing = false;\n\t },\n\n\t _keydown: function(e) {\n\t var that = this,\n\t dateView = that.dateView,\n\t value = that.element.val(),\n\t handled = false;\n\n\t if (!dateView.popup.visible() && e.keyCode == keys.ENTER && value !== that._oldText) {\n\t that._change(value);\n\t } else {\n\t handled = dateView.move(e);\n\t that._updateARIA(dateView._current);\n\n\t if (!handled) {\n\t that._typing = true;\n\t } else if (that._dateInput && e.stopImmediatePropagation) {\n\t e.stopImmediatePropagation();\n\t }\n\t }\n\t },\n\n\t _icon: function() {\n\t var that = this,\n\t element = that.element,\n\t icon;\n\n\t icon = element.next(\"span.k-select\");\n\n\t if (!icon[0]) {\n\t icon = $('').insertAfter(element);\n\t }\n\n\t that._dateIcon = icon.attr({\n\t \"role\": \"button\",\n\t \"aria-controls\": that.dateView._dateViewID\n\t });\n\t },\n\n\t _option: function(option, value) {\n\t var that = this,\n\t options = that.options;\n\n\t if (value === undefined) {\n\t return options[option];\n\t }\n\n\t value = parse(value, options.parseFormats, options.culture);\n\n\t if (!value) {\n\t return;\n\t }\n\n\t options[option] = new DATE(+value);\n\t that.dateView[option](value);\n\t },\n\n\t _update: function(value) {\n\t var that = this,\n\t options = that.options,\n\t min = options.min,\n\t max = options.max,\n\t current = that._value,\n\t date = parse(value, options.parseFormats, options.culture),\n\t isSameType = (date === null && current === null) || (date instanceof Date && current instanceof Date),\n\t formattedValue;\n\n\t if (options.disableDates(date)) {\n\t date = null;\n\t if (!that._old && !that.element.val()) {\n\t value = null;\n\t }\n\t }\n\n\t if (+date === +current && isSameType) {\n\t formattedValue = kendo.toString(date, options.format, options.culture);\n\n\t if (formattedValue !== value) {\n\t that.element.val(date === null ? value : formattedValue);\n\t }\n\n\t return date;\n\t }\n\n\t if (date !== null && isEqualDatePart(date, min)) {\n\t date = restrictValue(date, min, max);\n\t } else if (!isInRange(date, min, max)) {\n\t date = null;\n\t }\n\n\t that._value = date;\n\t that.dateView.value(date);\n\t if (that._dateInput && date) {\n\t that._dateInput.value(date || value);\n\t } else {\n\t that.element.val(kendo.toString(date || value, options.format, options.culture));\n\t }\n\t that._updateARIA(date);\n\n\t return date;\n\t },\n\n\t _wrapper: function() {\n\t var that = this,\n\t element = that.element,\n\t wrapper;\n\n\t wrapper = element.parents(\".k-datepicker\");\n\n\t if (!wrapper[0]) {\n\t wrapper = element.wrap(SPAN).parent().addClass(\"k-picker-wrap k-state-default\");\n\t wrapper = wrapper.wrap(SPAN).parent();\n\t }\n\n\t wrapper[0].style.cssText = element[0].style.cssText;\n\t element.css({\n\t width: \"100%\",\n\t height: element[0].style.height\n\t });\n\n\t that.wrapper = wrapper.addClass(\"k-widget k-datepicker\")\n\t .addClass(element[0].className).removeClass('input-validation-error');\n\n\t that._inputWrapper = $(wrapper[0].firstChild);\n\t },\n\n\t _reset: function() {\n\t var that = this,\n\t element = that.element,\n\t formId = element.attr(\"form\"),\n\t options = that.options,\n\t disabledDate = options.disableDates,\n\t parseFormats = options.parseFormats.length ? options.parseFormats : null,\n\t optionsValue = that._initialOptions.value,\n\t form = formId ? $(\"#\" + formId) : element.closest(\"form\"),\n\t initialValue = element[0].defaultValue;\n\n\t if (optionsValue && (disabledDate && disabledDate(optionsValue))) {\n\t optionsValue = null;\n\t }\n\n\t if ((!initialValue || !kendo.parseDate(initialValue, parseFormats, options.culture)) && optionsValue) {\n\t element.attr(\"value\", kendo.toString(optionsValue, options.format, options.culture));\n\t }\n\n\t if (form[0]) {\n\t that._resetHandler = function() {\n\t that.value(optionsValue || element[0].defaultValue);\n\t that.max(that._initialOptions.max);\n\t that.min(that._initialOptions.min);\n\t };\n\n\t that._form = form.on(\"reset\", that._resetHandler);\n\t }\n\t },\n\n\t _template: function() {\n\t this._ariaTemplate = template(this.options.ARIATemplate);\n\t },\n\n\t _createDateInput: function(options) {\n\t if (this._dateInput) {\n\t this._dateInput.destroy();\n\t this._dateInput = null;\n\t }\n\n\t if (options.dateInput ) {\n\t this._dateInput = new ui.DateInput(this.element, {\n\t culture: options.culture,\n\t format: options.format,\n\t min: options.min,\n\t max: options.max\n\t });\n\t }\n\t },\n\n\t _updateARIA: function(date) {\n\t var cell;\n\t var that = this;\n\t var calendar = that.dateView.calendar;\n\t if(that.element && that.element.length) {\n\t that.element[0].removeAttribute(\"aria-activedescendant\");\n\t }\n\t if (calendar) {\n\t cell = calendar._cell;\n\t cell.attr(\"aria-label\", that._ariaTemplate({ current: date || calendar.current() }));\n\n\t that.element.attr(\"aria-activedescendant\", cell.attr(\"id\"));\n\t }\n\t }\n\t });\n\n\t ui.plugin(DatePicker);\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1134:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.calendar\");\n\n/***/ }),\n\n/***/ 1135:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dateinput\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1141);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1054:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.popup\");\n\n/***/ }),\n\n/***/ 1141:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define) {\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1018), __webpack_require__(1054)], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function() {\n\n\t var __meta__ = { // jshint ignore:line\n\t id: \"dialog\",\n\t name: \"Dialog\",\n\t category: \"web\", // suite\n\t description: \"The dialog widget is a modal popup that brings information to the user.\",\n\t depends: [\"core\", \"popup\"] // dependencies\n\t };\n\n\t (function($, undefined) {\n\t var kendo = window.kendo,\n\t Widget = kendo.ui.Widget,\n\t TabKeyTrap = kendo.ui.Popup.TabKeyTrap,\n\t proxy = $.proxy,\n\t template = kendo.template,\n\t keys = kendo.keys,\n\t isFunction = $.isFunction,\n\t NS = \"kendoWindow\",\n\t KDIALOG = \".k-dialog\",\n\t KWINDOW = \".k-window\",\n\t KICONCLOSE = \".k-dialog-close\",\n\t KCONTENTCLASS = \"k-window-content k-dialog-content\",\n\t KCONTENTSELECTOR = \".k-window-content\",\n\t KSCROLL = \"k-scroll\",\n\t KTITLELESS = \"k-dialog-titleless\",\n\t KDIALOGTITLE = \".k-dialog-title\",\n\t KDIALOGTITLEBAR = KDIALOGTITLE + \"bar\",\n\t KBUTTONGROUP = \".k-dialog-buttongroup\",\n\t KBUTTON = \".k-button\",\n\t KALERT = \"k-alert\",\n\t KCONFIRM = \"k-confirm\",\n\t KPROMPT = \"k-prompt\",\n\t KTEXTBOX = \".k-textbox\",\n\t KOVERLAY = \".k-overlay\",\n\t VISIBLE = \":visible\",\n\t ZINDEX = \"zIndex\",\n\t BODY = \"body\",\n\t INITOPEN = \"initOpen\",\n\t TOUCHSTART = \"touchstart\",\n\t TOUCHMOVE = \"touchmove\",\n\t OPEN = \"open\",\n\t CLOSE = \"close\",\n\t SHOW = \"show\",\n\t HIDE = \"hide\",\n\t SIZE = {\n\t small: \"k-window-sm\",\n\t medium: \"k-window-md\",\n\t large: \"k-window-lg\"\n\t },\n\t HIDDEN = \"hidden\",\n\t OVERFLOW = \"overflow\",\n\t DATADOCOVERFLOWRULE = \"original-overflow-rule\",\n\t DATAHTMLTAPYRULE = \"tap-y\",\n\t messages = {\n\t okText : \"OK\",\n\t cancel : \"Cancel\",\n\t promptInput: \"Input\"\n\t },\n\t ceil = Math.ceil,\n\t templates,\n\t overlaySelector = \":not(link,meta,script,style)\";\n\n\t function defined(x) {\n\t return (typeof x != \"undefined\");\n\t }\n\n\t function constrain(value, low, high) {\n\t return Math.max(Math.min(parseInt(value, 10), high === Infinity ? high : parseInt(high, 10)), parseInt(low, 10));\n\t }\n\n\t function buttonKeyTrigger(e) {\n\t return e.keyCode == keys.ENTER || e.keyCode == keys.SPACEBAR;\n\t }\n\n\t var DialogBase = Widget.extend({\n\t init: function(element, options) {\n\t var that = this;\n\t Widget.fn.init.call(that, element, options);\n\t that._init(that.element, that.options);\n\t kendo.notify(that);\n\t },\n\n\t _init: function(element, options) {\n\t var that = this,\n\t wrapper;\n\n\t that._centerCallback = proxy(that._center, that);\n\n\t that.appendTo = $(BODY);\n\t if (!defined(options.visible) || options.visible === null) {\n\t options.visible = element.is(VISIBLE);\n\t }\n\n\t if (that.wrapperTemplate === undefined) {\n\t that.wrapperTemplate = templates.wrapper;\n\t }\n\n\t that._createDialog();\n\t wrapper = that.wrapper = element.closest(KDIALOG);\n\n\t if (options._defaultFocus === undefined) {\n\t that._defaultFocus = element[0];\n\t }\n\n\t that._tabindex(element);\n\t that._dimensions();\n\n\t this._tabKeyTrap = new TabKeyTrap(wrapper);\n\n\t if (!that.options.visible) {\n\t that.wrapper.hide();\n\t } else {\n\t that._triggerOpen();\n\t }\n\t },\n\n\t setOptions: function(options) {\n\t var that = this;\n\t var sizeClass = that.options.size;\n\n\t options = $.extend(that.options, options);\n\n\t Widget.fn.setOptions.call(that, options);\n\n\t if (options.title !== undefined) {\n\t that.title(options.title);\n\t }\n\n\t if (options.content) {\n\t kendo.destroy(that.element.children());\n\t that.element.html(options.content);\n\t }\n\n\t if (options.actions) {\n\t that.wrapper.children(KBUTTONGROUP).remove();\n\t that._createActionbar(that.wrapper);\n\t }\n\n\t that.wrapper.show();\n\t that._closable(that.wrapper);\n\n\t that.wrapper.removeClass(SIZE[sizeClass]);\n\t that._dimensions();\n\n\t if (!options.visible) {\n\t that.wrapper.hide();\n\t } else {\n\t that._triggerOpen();\n\t }\n\n\t if (typeof options.modal !== \"undefined\") {\n\t var visible = that.options.visible !== false;\n\t that._enableDocumentScrolling();\n\t that._overlay(options.modal && visible);\n\t }\n\t },\n\n\t _dimensions: function() {\n\t var that = this,\n\t wrapper = that.wrapper,\n\t options = that.options,\n\t width = options.width,\n\t height = options.height,\n\t sizeClass = options.size,\n\t dimensions = [\"minWidth\", \"minHeight\", \"maxWidth\", \"maxHeight\"];\n\n\t for (var i = 0; i < dimensions.length; i++) {\n\t var value = options[dimensions[i]];\n\t if (value && value != Infinity) {\n\t wrapper.css(dimensions[i], value);\n\t }\n\t }\n\n\t this._setElementMaxHeight();\n\n\t if (width) {\n\t if (width.toString().indexOf(\"%\") > 0) {\n\t wrapper.width(width);\n\t } else {\n\t wrapper.outerWidth(constrain(width, options.minWidth, options.maxWidth));\n\t }\n\t }\n\n\t if (height) {\n\t if (height.toString().indexOf(\"%\") > 0) {\n\t wrapper.height(height);\n\t } else {\n\t wrapper.outerHeight(constrain(height, options.minHeight, options.maxHeight));\n\t }\n\n\t this._setElementHeight();\n\t }\n\n\t if (sizeClass && SIZE[sizeClass]) {\n\t wrapper.addClass(SIZE[sizeClass]);\n\t }\n\t },\n\n\t _setElementMaxHeight: function() {\n\t var that = this,\n\t element = that.element,\n\t maxHeight = that.options.maxHeight,\n\t elementMaxHeight;\n\n\t if (maxHeight != Infinity) {\n\t elementMaxHeight = parseFloat(maxHeight, 10) - that._uiHeight();\n\t if (elementMaxHeight > 0) {\n\t element.css({\n\t maxHeight: ceil(elementMaxHeight) + \"px\"\n\t });\n\t }\n\t }\n\n\t },\n\n\t _setElementHeight: function() {\n\t var that = this,\n\t element = that.element,\n\t height = that.wrapper.outerHeight(true),\n\t elementHeight = parseFloat(height, 10) - that._uiHeight();\n\n\t if (elementHeight < 0) {\n\t elementHeight = 0;\n\t }\n\n\t element.css({\n\t height: ceil(elementHeight) + \"px\"\n\t });\n\n\t this._applyScrollClassName(element);\n\n\t },\n\n\t _applyScrollClassName: function(element) {\n\t var hasScroll = element.get(0).scrollHeight > element.outerHeight();\n\n\t if (hasScroll){\n\t element.addClass(KSCROLL);\n\t } else {\n\t element.removeClass(KSCROLL);\n\t }\n\t },\n\n\t _uiHeight: function() {\n\t var that = this,\n\t wrapper = that.wrapper,\n\t actionbar = wrapper.children(KBUTTONGROUP),\n\t actionbarHeight = actionbar[0] && actionbar[0].offsetHeight || 0,\n\t titlebar = wrapper.children(KDIALOGTITLEBAR),\n\t titlebarHeight = titlebar[0] && titlebar[0].offsetHeight || 0;\n\n\t return actionbarHeight + titlebarHeight;\n\t },\n\n\t _overlay: function(visible) {\n\t var overlay = this.appendTo.children(KOVERLAY),\n\t wrapper = this.wrapper;\n\n\n\t if (!overlay.length) {\n\t overlay = $(templates.overlay);\n\t }\n\n\t overlay\n\t .insertBefore(wrapper[0])\n\t .toggle(visible)\n\t .css(ZINDEX, parseInt(wrapper.css(ZINDEX), 10) - 1);\n\n\t if (visible) {\n\t this._waiAriaOverlay();\n\t }\n\t else {\n\t this._removeWaiAriaOverlay();\n\t }\n\n\t if (this.options.modal.preventScroll) {\n\t this._stopDocumentScrolling();\n\t }\n\n\t return overlay;\n\t },\n\n\t _waiAriaOverlay: function() {\n\t var node = this.wrapper;\n\n\t this._overlayedNodes = node.prevAll(overlaySelector).add(node.nextAll(overlaySelector))\n\t .each(function() {\n\t var jthis = $(this);\n\t jthis.data(\"ariaHidden\", jthis.attr(\"aria-hidden\"));\n\t jthis.attr(\"aria-hidden\", \"true\");\n\t });\n\t },\n\n\t _removeWaiAriaOverlay: function() {\n\t return this._overlayedNodes && this._overlayedNodes.each(function() {\n\t var node = $(this);\n\t var hiddenValue = node.data(\"ariaHidden\");\n\t if (hiddenValue) {\n\t node.attr(\"aria-hidden\", hiddenValue);\n\t }\n\t else {\n\t node.removeAttr(\"aria-hidden\");\n\t }\n\t });\n\t },\n\n\t _closeClick: function(e) {\n\t e.preventDefault();\n\t this.close(false);\n\t },\n\n\t _closeKeyHandler: function(e) {\n\t if (buttonKeyTrigger(e) || e.keyCode == keys.ESC) {\n\t this.close(false);\n\t }\n\t },\n\n\t _keydown: function(e) {\n\t var that = this,\n\t options = that.options,\n\t keyCode = e.keyCode;\n\n\t if (keyCode == keys.ESC && !that._closing && options.closable) {\n\t that.close(false);\n\t }\n\t },\n\n\t _createDialog: function() {\n\t var that = this,\n\t content = that.element,\n\t options = that.options,\n\t isRtl = kendo.support.isRtl(content),\n\t titlebar = $(templates.titlebar(options)),\n\t titleId = (content.id || kendo.guid()) + \"_title\",\n\t wrapper = $(that.wrapperTemplate(options));\n\n\t wrapper.toggleClass(\"k-rtl\", isRtl);\n\n\t content.addClass(KCONTENTCLASS);\n\t that.appendTo.append(wrapper);\n\n\t if (options.title !== false) {\n\t wrapper.append(titlebar);\n\t titlebar.attr(\"id\", titleId);\n\t wrapper.attr(\"aria-labelledby\", titleId);\n\t } else {\n\t wrapper.addClass(KTITLELESS);\n\t }\n\n\t that._closable(wrapper);\n\n\t wrapper.append(content);\n\n\t if (options.content) {\n\t kendo.destroy(content.children());\n\t content.html(options.content);\n\t }\n\n\t if (options.actions.length) {\n\t that._createActionbar(wrapper);\n\t }\n\t },\n\n\t _closable: function (wrapper) {\n\t var that = this;\n\t var options = that.options;\n\t var titlebar = wrapper.children(KDIALOGTITLEBAR);\n\t var titlebarActions = titlebar.find(\".k-window-actions\");\n\t var closeAction = titlebarActions.length ? titlebarActions.find(\".k-dialog-close\") : wrapper.find(\".k-dialog-close\");\n\n\t closeAction.remove();\n\n\t if (options.closable !== false) {\n\t if (options.title !== false && titlebarActions.length) {\n\t titlebarActions.append(templates.close(options));\n\t }\n\t else {\n\t wrapper.prepend(templates.close(options));\n\t }\n\n\t wrapper.autoApplyNS(NS);\n\t that.element.autoApplyNS(NS);\n\n\t wrapper.find(KICONCLOSE)\n\t .on(\"click\", proxy(that._closeClick, that))\n\t .on(\"keydown\", proxy(that._closeKeyHandler, that));\n\n\t that.element.on(\"keydown\", proxy(that._keydown, that));\n\t }\n\t },\n\n\t _createActionbar: function(wrapper) {\n\t var isStretchedLayout = (this.options.buttonLayout === \"stretched\");\n\t var buttonLayout = isStretchedLayout ? \"stretched\" : \"normal\";\n\t var actionbar = $(templates.actionbar({ buttonLayout: buttonLayout }));\n\n\t this._addButtons(actionbar);\n\t wrapper.append(actionbar);\n\t },\n\n\t _addButtons: function(actionbar) {\n\t var that = this,\n\t actionClick = proxy(that._actionClick, that),\n\t actionKeyHandler = proxy(that._actionKeyHandler, that),\n\t actions = that.options.actions,\n\t length = actions.length,\n\t action,\n\t text;\n\n\t for (var i = 0; i < length; i++) {\n\t action = actions[i];\n\t text = that._mergeTextWithOptions(action);\n\n\t $(templates.action(action))\n\t .autoApplyNS(NS)\n\t .html(text)\n\t .appendTo(actionbar)\n\t .addClass(action.cssClass)\n\t .data(\"action\", action.action)\n\t .on(\"click\", actionClick)\n\t .on(\"keydown\", actionKeyHandler);\n\t }\n\t },\n\n\t _mergeTextWithOptions : function(action) {\n\t var text = action.text;\n\t return text ? template(text)(this.options) : \"\";\n\t },\n\n\t _tabindex: function(target) {\n\t var that = this;\n\t var wrapper = that.wrapper;\n\t var closeBtn = wrapper.find(KICONCLOSE);\n\t var actionButtons = wrapper.find(KBUTTONGROUP + \" \" + KBUTTON);\n\n\t Widget.fn._tabindex.call(this, target);\n\n\t var tabIndex = target.attr(\"tabindex\");\n\n\t closeBtn.attr(\"tabIndex\", tabIndex);\n\t actionButtons.attr(\"tabIndex\", tabIndex);\n\t },\n\n\t _actionClick: function(e) {\n\t if (this.wrapper.is(VISIBLE)) {\n\t this._runActionBtn(e.currentTarget);\n\t }\n\t },\n\n\t _actionKeyHandler: function(e) {\n\t if (buttonKeyTrigger(e)) {\n\t this._runActionBtn(e.currentTarget);\n\t } else if (e.keyCode == keys.ESC) {\n\t this.close(false);\n\t }\n\t },\n\n\t _runActionBtn: function(target) {\n\t var that = this;\n\t if (that._closing) {\n\t return;\n\t }\n\n\t var action = $(target).data(\"action\"),\n\t preventClose = (isFunction(action) && action({ sender: that }) === false);\n\n\t if (!preventClose) {\n\t that.close(false);\n\t }\n\t },\n\n\t _triggerOpen: function() {\n\t var that = this;\n\t var options = that.options;\n\t var wrapper = that.wrapper;\n\n\t that.toFront();\n\t that._triggerInitOpen();\n\t that.trigger(OPEN);\n\t if (options.modal) {\n\t that._overlay(wrapper.is(VISIBLE)).css({ opacity: 0.5 });\n\t that._focusDialog();\n\t }\n\t },\n\n\t open: function() {\n\t var that = this,\n\t wrapper = that.wrapper,\n\t showOptions = this._animationOptions(OPEN),\n\t options = that.options,\n\t overlay, otherModalsVisible;\n\n\t this._triggerInitOpen();\n\n\t if (!that.trigger(OPEN)) {\n\t if (that._closing) {\n\t wrapper.kendoStop(true, true);\n\t }\n\n\t that._closing = false;\n\n\t that.toFront();\n\t options.visible = true;\n\t if (options.modal) {\n\t otherModalsVisible = !!that._modals().length;\n\t overlay = that._overlay(otherModalsVisible);\n\n\t overlay.kendoStop(true, true);\n\n\t if (showOptions.duration && kendo.effects.Fade && !otherModalsVisible) {\n\t var overlayFx = kendo.fx(overlay).fadeIn();\n\t overlayFx.duration(showOptions.duration || 0);\n\t overlayFx.endValue(0.5);\n\t overlayFx.play();\n\t } else {\n\t overlay.css(\"opacity\", 0.5);\n\t }\n\n\t overlay.show();\n\t }\n\n\t wrapper.show().kendoStop().kendoAnimate({\n\t effects: showOptions.effects,\n\t duration: showOptions.duration,\n\t complete: proxy(that._openAnimationEnd, that)\n\t });\n\t wrapper.show();\n\n\t }\n\n\t return that;\n\t },\n\n\t _animationOptions: function(id) {\n\t var animation = this.options.animation;\n\t var basicAnimation = {\n\t open: { effects: {} },\n\t close: { hide: true, effects: {} }\n\t };\n\n\t return animation && animation[id] || basicAnimation[id];\n\t },\n\n\t _openAnimationEnd: function() {\n\t if (this.options.modal) {\n\t this._focusDialog();\n\t }\n\t this.trigger(SHOW);\n\t },\n\n\t _triggerInitOpen: function() {\n\t if (!defined(this._initOpenTriggered)) {\n\t this._initOpenTriggered = true;\n\t this.trigger(INITOPEN);\n\t }\n\t },\n\n\t toFront: function() {\n\t var that = this,\n\t wrapper = that.wrapper,\n\t zIndex = +wrapper.css(ZINDEX),\n\t originalZIndex = zIndex;\n\n\t that.center();\n\n\t $(KWINDOW).each(function(i, element) {\n\t var windowObject = $(element),\n\t zIndexNew = windowObject.css(ZINDEX);\n\n\t if (!isNaN(zIndexNew)) {\n\t zIndex = Math.max(+zIndexNew, zIndex);\n\t }\n\t });\n\n\t if (!wrapper[0].style.zIndex || originalZIndex < zIndex) {\n\t wrapper.css(ZINDEX, zIndex + 2);\n\t }\n\n\t that.element.find(\"> .k-overlay\").remove();\n\t wrapper = null;\n\n\t return that;\n\t },\n\n\t close: function(systemTriggered) {\n\t if(!arguments.length) {\n\t systemTriggered = true;\n\t }\n\n\t this._close(systemTriggered);\n\t this._stopCenterOnResize();\n\t return this;\n\t },\n\n\t _close: function(systemTriggered) {\n\t var that = this,\n\t wrapper = that.wrapper,\n\t options = that.options,\n\t showOptions = this._animationOptions(\"open\"),\n\t hideOptions = this._animationOptions(\"close\");\n\n\t if (wrapper.is(VISIBLE) && !that.trigger(CLOSE, { userTriggered: !systemTriggered })) {\n\t if (that._closing) {\n\t return;\n\t }\n\t that._closing = true;\n\n\t options.visible = false;\n\t this._removeOverlay();\n\n\t wrapper.kendoStop().kendoAnimate({\n\t effects: hideOptions.effects || showOptions.effects,\n\t reverse: hideOptions.reverse === true,\n\t duration: hideOptions.duration,\n\t complete: proxy(this._closeAnimationEnd, this)\n\t });\n\t }\n\n\t return that;\n\t },\n\n\t center: function() {\n\t this._center();\n\t this._centerOnResize();\n\t },\n\n\t _center: function() {\n\t var that = this,\n\t wrapper = that.wrapper,\n\t documentWindow = $(window),\n\t scrollTop = 0,\n\t scrollLeft = 0,\n\t newLeft = scrollLeft + Math.max(0, (documentWindow.width() - wrapper.width()) / 2),\n\t newTop = scrollTop + Math.max(0, (documentWindow.height() - wrapper.height() - parseInt(wrapper.css(\"paddingTop\"), 10)) / 2);\n\n\t wrapper.css({\n\t left: newLeft,\n\t top: newTop\n\t });\n\n\t return that;\n\t },\n\n\t _centerOnResize: function() {\n\t if (this._trackResize) {\n\t return;\n\t }\n\n\t kendo.onResize(this._centerCallback);\n\t this._trackResize = true;\n\t },\n\n\t _stopCenterOnResize: function() {\n\t kendo.unbindResize(this._centerCallback);\n\t this._trackResize = false;\n\t },\n\n\t _removeOverlay: function() {\n\t var modals = this._modals();\n\t var options = this.options;\n\t var hideOverlay = options.modal && !modals.length;\n\n\t if (hideOverlay) {\n\t this._overlay(false).remove();\n\n\t if (options.modal.preventScroll) {\n\t this._enableDocumentScrolling();\n\t }\n\t } else if (modals.length) {\n\t this._object(modals.last())._overlay(true);\n\n\t if (options.modal.preventScroll) {\n\t this._stopDocumentScrolling();\n\t }\n\t }\n\t },\n\n\t _stopDocumentScrolling: function(){\n\t var that = this;\n\n\t var $body = $(\"body\");\n\t that._storeOverflowRule($body);\n\t $body.css(OVERFLOW, HIDDEN);\n\n\t var $html = $(\"html\");\n\t var html = $html[0];\n\t that._storeOverflowRule($html);\n\t $html.css(OVERFLOW, HIDDEN);\n\n\t // prevent touch due to bug in ios\n\t if (kendo.support.mobileOS.ios) {\n\t html.addEventListener(TOUCHSTART, that._touchStart, { passive: false });\n\t html.addEventListener(TOUCHMOVE, that._touchMove, { passive: false });\n\t }\n\t },\n\n\t _touchStart: function (e) {\n\t $(this).data(DATAHTMLTAPYRULE, e.changedTouches[0].pageY);\n\t },\n\n\t _touchMove: function (e) {\n\t var target = e.target;\n\t var $target = $(e.target);\n\t var upScroll = e.changedTouches[0].pageY - $(this).data(DATAHTMLTAPYRULE) > 0;\n\t var preventYScroll = $target.is(KCONTENTSELECTOR) &&\n\t (upScroll && $target.scrollTop() === 0) ||\n\t (!upScroll && $target.scrollTop() === target.scrollHeight - target.clientHeight);\n\t if (!$target.is(KCONTENTSELECTOR) || preventYScroll) {\n\t e.preventDefault();\n\t }\n\t },\n\n\t _enableDocumentScrolling: function(){\n\t var that = this;\n\t var $body = $(document.body);\n\t var $html = $(\"html\");\n\t var html = $html[0];\n\n\t that._restoreOverflowRule($body);\n\t that._restoreOverflowRule($html);\n\n\t if (kendo.support.mobileOS.ios) {\n\t $html.removeData(DATAHTMLTAPYRULE);\n\t html.removeEventListener(TOUCHSTART, that._touchStart, { passive: false });\n\t html.removeEventListener(TOUCHMOVE, that._touchMove, { passive: false });\n\t }\n\t },\n\n\t _storeOverflowRule: function($element){\n\t if(this._isOverflowStored($element)){\n\t return;\n\t }\n\n\t var overflowRule = $element.get(0).style.overflow;\n\n\t if(typeof overflowRule === \"string\"){\n\t $element.data(DATADOCOVERFLOWRULE, overflowRule);\n\t }\n\t },\n\n\t _isOverflowStored: function ($element){\n\t return typeof $element.data(DATADOCOVERFLOWRULE) === \"string\";\n\t },\n\n\t _restoreOverflowRule: function($element){\n\t var overflowRule = $element.data(DATADOCOVERFLOWRULE);\n\n\t if(overflowRule !== null && overflowRule !== undefined){\n\t $element.css(OVERFLOW, overflowRule);\n\t $element.removeData(DATADOCOVERFLOWRULE);\n\t } else {\n\t $element.css(OVERFLOW, \"\");\n\t }\n\t },\n\n\t _closeAnimationEnd: function() {\n\t var that = this;\n\n\t that._closing = false;\n\t that.wrapper.hide().css(\"opacity\", \"\");\n\t that.trigger(HIDE);\n\n\t if (that.options.modal) {\n\t var lastModal = that._object(that._modals().last());\n\t if (lastModal) {\n\t lastModal.toFront();\n\t }\n\t }\n\t },\n\n\t _modals: function() {\n\t var that = this;\n\n\t var zStack = $(KWINDOW).filter(function() {\n\t var dom = $(this);\n\t var object = that._object(dom);\n\t var options = object && object.options;\n\n\t return options && options.modal && that.options.appendTo == options.appendTo && options.visible && dom.is(VISIBLE);\n\t }).sort(function(a, b) {\n\t return +$(a).css(\"zIndex\") - +$(b).css(\"zIndex\");\n\t });\n\n\t that = null;\n\n\t return zStack;\n\t },\n\n\t _object: function(element) {\n\t var content = element.children(KCONTENTSELECTOR);\n\t var widget = kendo.widgetInstance(content);\n\n\t if (widget) {\n\t return widget;\n\t }\n\n\t return undefined;\n\t },\n\n\t destroy: function() {\n\t var that = this;\n\t that._destroy();\n\n\t Widget.fn.destroy.call(that);\n\n\t kendo.destroy(that.wrapper);\n\n\t that.wrapper.remove();\n\t that.wrapper = that.element = $();\n\t },\n\n\t _destroy: function() {\n\t var that = this;\n\t var ns = \".\" + NS;\n\n\t that.wrapper.off(ns);\n\t that.element.off(ns);\n\t that.wrapper.find(KICONCLOSE + \",\" + KBUTTONGROUP + \" > \" + KBUTTON).off(ns);\n\t that._stopCenterOnResize();\n\t },\n\n\t title: function(html) {\n\t var that = this,\n\t wrapper = that.wrapper,\n\t options = that.options,\n\t titlebar = wrapper.children(KDIALOGTITLEBAR),\n\t title = titlebar.children(KDIALOGTITLE),\n\t encodedHtml = kendo.htmlEncode(html);\n\n\t if (!arguments.length) {\n\t return title.html();\n\t }\n\n\t if (html === false) {\n\t titlebar.remove();\n\t wrapper.addClass(KTITLELESS);\n\t } else {\n\t if (!titlebar.length) {\n\t titlebar = $(templates.titlebar(options)).prependTo(wrapper);\n\t title = titlebar.children(KDIALOGTITLE);\n\t wrapper.removeClass(KTITLELESS);\n\t }\n\t title.html(encodedHtml);\n\t }\n\n\t that.options.title = encodedHtml;\n\n\t return that;\n\t },\n\n\t content: function(html, data) {\n\t var that = this,\n\t content = that.wrapper.children(KCONTENTSELECTOR);\n\n\t if (!defined(html)) {\n\t return content.html();\n\t }\n\n\t this.angular(\"cleanup\", function(){\n\t return { elements: content.children() };\n\t });\n\n\t kendo.destroy(content.children());\n\t content.html(html);\n\n\t this.angular(\"compile\", function(){\n\t var a = [];\n\t for (var i = content.length; --i >= 0;) {\n\t a.push({ dataItem: data });\n\t }\n\t return {\n\t elements: content.children(),\n\t data: a\n\t };\n\t });\n\n\t that.options.content = html;\n\n\t return that;\n\t },\n\n\t _focusDialog: function() {\n\t if (this._defaultFocus) {\n\t this._focus(this._defaultFocus);\n\t }\n\t this._tabKeyTrap.trap();\n\t },\n\n\t _focus: function(node) {\n\t if (node) {\n\t node.focus();\n\t }\n\t },\n\n\t events: [\n\t INITOPEN,\n\t OPEN,\n\t CLOSE,\n\t SHOW,\n\t HIDE\n\t ],\n\n\t options: {\n\t title: \"\",\n\t buttonLayout: \"stretched\",\n\t actions: [],\n\t modal: true,\n\t size: \"auto\",\n\t width: null,\n\t height: null,\n\t minWidth: 0,\n\t minHeight: 0,\n\t maxWidth: Infinity,\n\t maxHeight: Infinity,\n\t content: null,\n\t visible: null,\n\t appendTo: BODY,\n\t closable: true\n\t }\n\t });\n\n\t var Dialog = DialogBase.extend({\n\t options: {\n\t name: \"Dialog\",\n\t messages: {\n\t close: \"Close\"\n\t }\n\t }\n\t });\n\n\t kendo.ui.plugin(Dialog);\n\n\t var PopupBox = DialogBase.extend({\n\t _init: function(element, options) {\n\t var that = this;\n\n\t that.wrapperTemplate = templates.alertWrapper;\n\t options._defaultFocus = null;\n\t that._ensureContentId(element);\n\n\t DialogBase.fn._init.call(that, element, options);\n\n\t that.bind(HIDE, proxy(that.destroy, that));\n\n\t that._ariaDescribedBy();\n\t that._initFocus();\n\t },\n\n\t _ensureContentId: function(element) {\n\t var node = $(element);\n\t if(!node.attr(\"id\")) {\n\t node.attr(\"id\", kendo.guid() + \"_k-popup\");\n\t }\n\t },\n\n\t _ariaDescribedBy: function() {\n\t this.wrapper.attr(\"aria-describedby\", this.element.attr(\"id\"));\n\t },\n\n\t _initFocus: function() {\n\t var o = this.options;\n\n\t this._defaultFocus = this._chooseEntryFocus();\n\t if (this._defaultFocus && o.visible && o.modal) {\n\t this._focusDialog();\n\t }\n\t },\n\n\t _chooseEntryFocus: function() {\n\t return this.wrapper.find(KBUTTONGROUP + \" > \" + KBUTTON)[0];\n\t },\n\n\t options: {\n\t title: window.location.host,\n\t closable: false,\n\t messages: messages\n\t }\n\t });\n\n\t var Alert = PopupBox.extend({\n\t _init: function(element, options) {\n\t var that = this;\n\t PopupBox.fn._init.call(that, element, options);\n\t that.wrapper.addClass(KALERT);\n\t },\n\n\t options: {\n\t name: \"Alert\",\n\t modal: true,\n\t actions: [{\n\t text: \"#: messages.okText #\"\n\t }]\n\t }\n\t });\n\n\t kendo.ui.plugin(Alert);\n\n\t var kendoAlert = function(text) {\n\t return $(templates.alert).kendoAlert({ content: text }).data(\"kendoAlert\").open();\n\t };\n\n\t var Confirm = PopupBox.extend({\n\t _init: function(element, options) {\n\t var that = this;\n\t PopupBox.fn._init.call(that, element, options);\n\t that.wrapper.addClass(KCONFIRM);\n\t that.result = $.Deferred();\n\t },\n\n\t options: {\n\t name: \"Confirm\",\n\t modal: true,\n\t actions: [{\n\t text: \"#: messages.okText #\",\n\t primary: true,\n\t action: function(e) {\n\t e.sender.result.resolve();\n\t }\n\t }, {\n\t text: \"#: messages.cancel #\",\n\t action: function(e) {\n\t e.sender.result.reject();\n\t }\n\t }]\n\t }\n\t });\n\n\t kendo.ui.plugin(Confirm);\n\n\t var kendoConfirm = function(text) {\n\t var confirmDialog = $(templates.confirm).kendoConfirm({ content: text }).data(\"kendoConfirm\").open();\n\t return confirmDialog.result;\n\t };\n\n\t var Prompt = PopupBox.extend({\n\t _init: function(element, options) {\n\t var that = this;\n\t PopupBox.fn._init.call(that, element, options);\n\t that.wrapper.addClass(KPROMPT);\n\t that._createPrompt();\n\t that.result = $.Deferred();\n\t },\n\n\t _createPrompt: function() {\n\t var value = this.options.value,\n\t promptContainer = $(templates.promptInputContainer(this.options)).insertAfter(this.element);\n\n\t if (value) {\n\t promptContainer.children(KTEXTBOX).val(value);\n\t }\n\n\t this._defaultFocus = this._chooseEntryFocus();\n\t this._focusDialog();\n\t },\n\n\t _chooseEntryFocus: function() {\n\t return this.wrapper.find(KTEXTBOX)[0];\n\t },\n\n\t options: {\n\t name: \"Prompt\",\n\t modal: true,\n\t value: \"\",\n\t actions: [{\n\t text: \"#: messages.okText #\",\n\t primary: true,\n\t action: function(e) {\n\t var sender = e.sender,\n\t value = sender.wrapper.find(KTEXTBOX).val();\n\n\t sender.result.resolve(value);\n\t }\n\t }, {\n\t text: \"#: messages.cancel #\",\n\t action: function(e) {\n\t var sender = e.sender,\n\t value = sender.wrapper.find(KTEXTBOX).val();\n\n\t e.sender.result.reject(value);\n\t }\n\t }]\n\t }\n\t });\n\n\t kendo.ui.plugin(Prompt);\n\n\t var kendoPrompt = function(text, value) {\n\t var promptDialog = $(templates.prompt).kendoPrompt({\n\t content: text,\n\t value: value\n\t }).data(\"kendoPrompt\").open();\n\n\t return promptDialog.result;\n\t };\n\n\t templates = {\n\t wrapper: template(\"\"),\n\t action: template(\"\"),\n\t titlebar: template(\n\t \"
    \" +\n\t \"#: title #\" +\n\t \"
    \" +\n\t \"
    \"\n\t ),\n\t close: template(\"
    \"),\n\t actionbar: template(\"\"),\n\t overlay: \"
    \",\n\t alertWrapper: template(\"
    \"),\n\t alert: \"
    \",\n\t confirm: \"
    \",\n\t prompt: \"
    \",\n\t promptInputContainer: template(\"
    \")\n\t };\n\n\t kendo.alert = kendoAlert;\n\t kendo.confirm = kendoConfirm;\n\t kendo.prompt = kendoPrompt;\n\n\t })(window.kendo.jQuery);\n\n\t return window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1143);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1018:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.core\");\n\n/***/ }),\n\n/***/ 1056:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.userevents\");\n\n/***/ }),\n\n/***/ 1143:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\r\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1018), __webpack_require__(1056) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n\t})(function(){\r\n\r\n\tvar __meta__ = { // jshint ignore:line\r\n\t id: \"draganddrop\",\r\n\t name: \"Drag & drop\",\r\n\t category: \"framework\",\r\n\t description: \"Drag & drop functionality for any DOM element.\",\r\n\t depends: [ \"core\", \"userevents\" ]\r\n\t};\r\n\r\n\t(function ($, undefined) {\r\n\t var kendo = window.kendo,\r\n\t support = kendo.support,\r\n\t document = window.document,\r\n\t $window = $(window),\r\n\t Class = kendo.Class,\r\n\t Widget = kendo.ui.Widget,\r\n\t Observable = kendo.Observable,\r\n\t UserEvents = kendo.UserEvents,\r\n\t proxy = $.proxy,\r\n\t extend = $.extend,\r\n\t getOffset = kendo.getOffset,\r\n\t draggables = {},\r\n\t dropTargets = {},\r\n\t dropAreas = {},\r\n\t lastDropTarget,\r\n\t elementUnderCursor = kendo.elementUnderCursor,\r\n\t KEYUP = \"keyup\",\r\n\t CHANGE = \"change\",\r\n\r\n\t // Draggable events\r\n\t DRAGSTART = \"dragstart\",\r\n\t HOLD = \"hold\",\r\n\t DRAG = \"drag\",\r\n\t DRAGEND = \"dragend\",\r\n\t DRAGCANCEL = \"dragcancel\",\r\n\t HINTDESTROYED = \"hintDestroyed\",\r\n\r\n\t // DropTarget events\r\n\t DRAGENTER = \"dragenter\",\r\n\t DRAGLEAVE = \"dragleave\",\r\n\t DROP = \"drop\";\r\n\r\n\t function contains(parent, child) {\r\n\t try {\r\n\t return $.contains(parent, child) || parent == child;\r\n\t } catch (e) {\r\n\t return false;\r\n\t }\r\n\t }\r\n\r\n\t function numericCssPropery(element, property) {\r\n\t return parseInt(element.css(property), 10) || 0;\r\n\t }\r\n\r\n\t function within(value, range) {\r\n\t return Math.min(Math.max(value, range.min), range.max);\r\n\t }\r\n\r\n\t function containerBoundaries(container, element) {\r\n\t var offset = getOffset(container),\r\n\t outerWidth = kendo._outerWidth,\r\n\t outerHeight = kendo._outerHeight,\r\n\t minX = offset.left + numericCssPropery(container, \"borderLeftWidth\") + numericCssPropery(container, \"paddingLeft\"),\r\n\t minY = offset.top + numericCssPropery(container, \"borderTopWidth\") + numericCssPropery(container, \"paddingTop\"),\r\n\t maxX = minX + container.width() - outerWidth(element, true),\r\n\t maxY = minY + container.height() - outerHeight(element, true);\r\n\r\n\t return {\r\n\t x: { min: minX, max: maxX },\r\n\t y: { min: minY, max: maxY }\r\n\t };\r\n\t }\r\n\r\n\t function checkTarget(target, targets, areas) {\r\n\t var theTarget, theFilter, i = 0,\r\n\t targetLen = targets && targets.length,\r\n\t areaLen = areas && areas.length;\r\n\r\n\t while (target && target.parentNode) {\r\n\t for (i = 0; i < targetLen; i ++) {\r\n\t theTarget = targets[i];\r\n\t if (theTarget.element[0] === target) {\r\n\t return { target: theTarget, targetElement: target };\r\n\t }\r\n\t }\r\n\r\n\t for (i = 0; i < areaLen; i ++) {\r\n\t theFilter = areas[i];\r\n\t if ($.contains(theFilter.element[0], target) && support.matchesSelector.call(target, theFilter.options.filter)) {\r\n\t return { target: theFilter, targetElement: target };\r\n\t }\r\n\t }\r\n\r\n\t target = target.parentNode;\r\n\t }\r\n\r\n\t return undefined;\r\n\t }\r\n\r\n\t var TapCapture = Observable.extend({\r\n\t init: function(element, options) {\r\n\t var that = this,\r\n\t domElement = element[0];\r\n\r\n\t that.capture = false;\r\n\r\n\t if (domElement.addEventListener) {\r\n\t $.each(kendo.eventMap.down.split(\" \"), function() {\r\n\t domElement.addEventListener(this, proxy(that._press, that), true);\r\n\t });\r\n\t $.each(kendo.eventMap.up.split(\" \"), function() {\r\n\t domElement.addEventListener(this, proxy(that._release, that), true);\r\n\t });\r\n\t } else {\r\n\t $.each(kendo.eventMap.down.split(\" \"), function() {\r\n\t domElement.attachEvent(this, proxy(that._press, that));\r\n\t });\r\n\t $.each(kendo.eventMap.up.split(\" \"), function() {\r\n\t domElement.attachEvent(this, proxy(that._release, that));\r\n\t });\r\n\t }\r\n\r\n\t Observable.fn.init.call(that);\r\n\r\n\t that.bind([\"press\", \"release\"], options || {});\r\n\t },\r\n\r\n\t captureNext: function() {\r\n\t this.capture = true;\r\n\t },\r\n\r\n\t cancelCapture: function() {\r\n\t this.capture = false;\r\n\t },\r\n\r\n\t _press: function(e) {\r\n\t var that = this;\r\n\t that.trigger(\"press\");\r\n\t if (that.capture) {\r\n\t e.preventDefault();\r\n\t }\r\n\t },\r\n\r\n\t _release: function(e) {\r\n\t var that = this;\r\n\t that.trigger(\"release\");\r\n\r\n\t if (that.capture) {\r\n\t e.preventDefault();\r\n\t that.cancelCapture();\r\n\t }\r\n\t }\r\n\t });\r\n\r\n\t var PaneDimension = Observable.extend({\r\n\t init: function(options) {\r\n\t var that = this;\r\n\t Observable.fn.init.call(that);\r\n\r\n\t that.forcedEnabled = false;\r\n\r\n\t $.extend(that, options);\r\n\r\n\t that.scale = 1;\r\n\r\n\t if (that.horizontal) {\r\n\t that.measure = \"offsetWidth\";\r\n\t that.scrollSize = \"scrollWidth\";\r\n\t that.axis = \"x\";\r\n\t } else {\r\n\t that.measure = \"offsetHeight\";\r\n\t that.scrollSize = \"scrollHeight\";\r\n\t that.axis = \"y\";\r\n\t }\r\n\t },\r\n\r\n\t makeVirtual: function() {\r\n\t $.extend(this, {\r\n\t virtual: true,\r\n\t forcedEnabled: true,\r\n\t _virtualMin: 0,\r\n\t _virtualMax: 0\r\n\t });\r\n\t },\r\n\r\n\t virtualSize: function(min, max) {\r\n\t if (this._virtualMin !== min || this._virtualMax !== max) {\r\n\t this._virtualMin = min;\r\n\t this._virtualMax = max;\r\n\t this.update();\r\n\t }\r\n\t },\r\n\r\n\t outOfBounds: function(offset) {\r\n\t return offset > this.max || offset < this.min;\r\n\t },\r\n\r\n\t forceEnabled: function() {\r\n\t this.forcedEnabled = true;\r\n\t },\r\n\r\n\t getSize: function() {\r\n\t return this.container[0][this.measure];\r\n\t },\r\n\r\n\t getTotal: function() {\r\n\t return this.element[0][this.scrollSize];\r\n\t },\r\n\r\n\t rescale: function(scale) {\r\n\t this.scale = scale;\r\n\t },\r\n\r\n\t update: function(silent) {\r\n\t var that = this,\r\n\t total = that.virtual ? that._virtualMax : that.getTotal(),\r\n\t scaledTotal = total * that.scale,\r\n\t size = that.getSize();\r\n\r\n\t if (total === 0 && !that.forcedEnabled) {\r\n\t return; // we are not visible.\r\n\t }\r\n\r\n\t that.max = that.virtual ? -that._virtualMin : 0;\r\n\t that.size = size;\r\n\t that.total = scaledTotal;\r\n\t that.min = Math.min(that.max, size - scaledTotal);\r\n\t that.minScale = size / total;\r\n\t that.centerOffset = (scaledTotal - size) / 2;\r\n\r\n\t that.enabled = that.forcedEnabled || (scaledTotal > size);\r\n\r\n\t if (!silent) {\r\n\t that.trigger(CHANGE, that);\r\n\t }\r\n\t }\r\n\t });\r\n\r\n\t var PaneDimensions = Observable.extend({\r\n\t init: function(options) {\r\n\t var that = this;\r\n\r\n\t Observable.fn.init.call(that);\r\n\r\n\t that.x = new PaneDimension(extend({horizontal: true}, options));\r\n\t that.y = new PaneDimension(extend({horizontal: false}, options));\r\n\t that.container = options.container;\r\n\t that.forcedMinScale = options.minScale;\r\n\t that.maxScale = options.maxScale || 100;\r\n\r\n\t that.bind(CHANGE, options);\r\n\t },\r\n\r\n\t rescale: function(newScale) {\r\n\t this.x.rescale(newScale);\r\n\t this.y.rescale(newScale);\r\n\t this.refresh();\r\n\t },\r\n\r\n\t centerCoordinates: function() {\r\n\t return { x: Math.min(0, -this.x.centerOffset), y: Math.min(0, -this.y.centerOffset) };\r\n\t },\r\n\r\n\t refresh: function() {\r\n\t var that = this;\r\n\t that.x.update();\r\n\t that.y.update();\r\n\t that.enabled = that.x.enabled || that.y.enabled;\r\n\t that.minScale = that.forcedMinScale || Math.min(that.x.minScale, that.y.minScale);\r\n\t that.fitScale = Math.max(that.x.minScale, that.y.minScale);\r\n\t that.trigger(CHANGE);\r\n\t }\r\n\t });\r\n\r\n\t var PaneAxis = Observable.extend({\r\n\t init: function(options) {\r\n\t var that = this;\r\n\t extend(that, options);\r\n\t Observable.fn.init.call(that);\r\n\t },\r\n\r\n\t outOfBounds: function() {\r\n\t return this.dimension.outOfBounds(this.movable[this.axis]);\r\n\t },\r\n\r\n\t dragMove: function(delta) {\r\n\t var that = this,\r\n\t dimension = that.dimension,\r\n\t axis = that.axis,\r\n\t movable = that.movable,\r\n\t position = movable[axis] + delta;\r\n\r\n\t if (!dimension.enabled) {\r\n\t return;\r\n\t }\r\n\r\n\t if ((position < dimension.min && delta < 0) || (position > dimension.max && delta > 0)) {\r\n\t delta *= that.resistance;\r\n\t }\r\n\r\n\t movable.translateAxis(axis, delta);\r\n\t that.trigger(CHANGE, that);\r\n\t }\r\n\t });\r\n\r\n\t var Pane = Class.extend({\r\n\r\n\t init: function(options) {\r\n\t var that = this,\r\n\t x,\r\n\t y,\r\n\t resistance,\r\n\t movable;\r\n\r\n\t extend(that, {elastic: true}, options);\r\n\r\n\t resistance = that.elastic ? 0.5 : 0;\r\n\t movable = that.movable;\r\n\r\n\t that.x = x = new PaneAxis({\r\n\t axis: \"x\",\r\n\t dimension: that.dimensions.x,\r\n\t resistance: resistance,\r\n\t movable: movable\r\n\t });\r\n\r\n\t that.y = y = new PaneAxis({\r\n\t axis: \"y\",\r\n\t dimension: that.dimensions.y,\r\n\t resistance: resistance,\r\n\t movable: movable\r\n\t });\r\n\r\n\t that.userEvents.bind([\"press\", \"move\", \"end\", \"gesturestart\", \"gesturechange\"], {\r\n\t gesturestart: function(e) {\r\n\t that.gesture = e;\r\n\t that.offset = that.dimensions.container.offset();\r\n\t },\r\n\r\n\t press: function(e) {\r\n\t if ($(e.event.target).closest(\"a\").is(\"[data-navigate-on-press=true]\")) {\r\n\t e.sender.cancel();\r\n\t }\r\n\t },\r\n\r\n\t gesturechange: function(e) {\r\n\t var previousGesture = that.gesture,\r\n\t previousCenter = previousGesture.center,\r\n\r\n\t center = e.center,\r\n\r\n\t scaleDelta = e.distance / previousGesture.distance,\r\n\r\n\t minScale = that.dimensions.minScale,\r\n\t maxScale = that.dimensions.maxScale,\r\n\t coordinates;\r\n\r\n\t if (movable.scale <= minScale && scaleDelta < 1) {\r\n\t // Resist shrinking. Instead of shrinking from 1 to 0.5, it will shrink to 0.5 + (1 /* minScale */ - 0.5) * 0.8 = 0.9;\r\n\t scaleDelta += (1 - scaleDelta) * 0.8;\r\n\t }\r\n\r\n\t if (movable.scale * scaleDelta >= maxScale) {\r\n\t scaleDelta = maxScale / movable.scale;\r\n\t }\r\n\r\n\t var offsetX = movable.x + that.offset.left,\r\n\t offsetY = movable.y + that.offset.top;\r\n\r\n\t coordinates = {\r\n\t x: (offsetX - previousCenter.x) * scaleDelta + center.x - offsetX,\r\n\t y: (offsetY - previousCenter.y) * scaleDelta + center.y - offsetY\r\n\t };\r\n\r\n\t movable.scaleWith(scaleDelta);\r\n\r\n\t x.dragMove(coordinates.x);\r\n\t y.dragMove(coordinates.y);\r\n\r\n\t that.dimensions.rescale(movable.scale);\r\n\t that.gesture = e;\r\n\t e.preventDefault();\r\n\t },\r\n\r\n\t move: function(e) {\r\n\t if (e.event.target.tagName.match(/textarea|input/i)) {\r\n\t return;\r\n\t }\r\n\r\n\t if (x.dimension.enabled || y.dimension.enabled) {\r\n\t x.dragMove(e.x.delta);\r\n\t y.dragMove(e.y.delta);\r\n\t e.preventDefault();\r\n\t } else {\r\n\t e.touch.skip();\r\n\t }\r\n\t },\r\n\r\n\t end: function(e) {\r\n\t e.preventDefault();\r\n\t }\r\n\t });\r\n\t }\r\n\t });\r\n\r\n\t var TRANSFORM_STYLE = support.transitions.prefix + \"Transform\",\r\n\t translate;\r\n\r\n\r\n\t if (support.hasHW3D) {\r\n\t translate = function(x, y, scale) {\r\n\t return \"translate3d(\" + x + \"px,\" + y +\"px,0) scale(\" + scale + \")\";\r\n\t };\r\n\t } else {\r\n\t translate = function(x, y, scale) {\r\n\t return \"translate(\" + x + \"px,\" + y +\"px) scale(\" + scale + \")\";\r\n\t };\r\n\t }\r\n\r\n\t var Movable = Observable.extend({\r\n\t init: function(element) {\r\n\t var that = this;\r\n\r\n\t Observable.fn.init.call(that);\r\n\r\n\t that.element = $(element);\r\n\t that.element[0].style.webkitTransformOrigin = \"left top\";\r\n\t that.x = 0;\r\n\t that.y = 0;\r\n\t that.scale = 1;\r\n\t that._saveCoordinates(translate(that.x, that.y, that.scale));\r\n\t },\r\n\r\n\t translateAxis: function(axis, by) {\r\n\t this[axis] += by;\r\n\t this.refresh();\r\n\t },\r\n\r\n\t scaleTo: function(scale) {\r\n\t this.scale = scale;\r\n\t this.refresh();\r\n\t },\r\n\r\n\t scaleWith: function(scaleDelta) {\r\n\t this.scale *= scaleDelta;\r\n\t this.refresh();\r\n\t },\r\n\r\n\t translate: function(coordinates) {\r\n\t this.x += coordinates.x;\r\n\t this.y += coordinates.y;\r\n\t this.refresh();\r\n\t },\r\n\r\n\t moveAxis: function(axis, value) {\r\n\t this[axis] = value;\r\n\t this.refresh();\r\n\t },\r\n\r\n\t moveTo: function(coordinates) {\r\n\t extend(this, coordinates);\r\n\t this.refresh();\r\n\t },\r\n\r\n\t refresh: function() {\r\n\t var that = this,\r\n\t x = that.x,\r\n\t y = that.y,\r\n\t newCoordinates;\r\n\r\n\t if (that.round) {\r\n\t x = Math.round(x);\r\n\t y = Math.round(y);\r\n\t }\r\n\r\n\t newCoordinates = translate(x, y, that.scale);\r\n\r\n\t if (newCoordinates != that.coordinates) {\r\n\t if (kendo.support.browser.msie && kendo.support.browser.version < 10) {\r\n\t that.element[0].style.position = \"absolute\";\r\n\t that.element[0].style.left = that.x + \"px\";\r\n\t that.element[0].style.top = that.y + \"px\";\r\n\r\n\t } else {\r\n\t that.element[0].style[TRANSFORM_STYLE] = newCoordinates;\r\n\t }\r\n\t that._saveCoordinates(newCoordinates);\r\n\t that.trigger(CHANGE);\r\n\t }\r\n\t },\r\n\r\n\t _saveCoordinates: function(coordinates) {\r\n\t this.coordinates = coordinates;\r\n\t }\r\n\t });\r\n\r\n\t function destroyDroppable(collection, widget) {\r\n\t var groupName = widget.options.group,\r\n\t droppables = collection[groupName],\r\n\t i;\r\n\r\n\t Widget.fn.destroy.call(widget);\r\n\r\n\t if (droppables.length > 1) {\r\n\t for (i = 0; i < droppables.length; i++) {\r\n\t if (droppables[i] == widget) {\r\n\t droppables.splice(i, 1);\r\n\t break;\r\n\t }\r\n\t }\r\n\t } else {\r\n\t droppables.length = 0; // WTF, porting this from the previous destroyGroup\r\n\t delete collection[groupName];\r\n\t }\r\n\t }\r\n\r\n\t var DropTarget = Widget.extend({\r\n\t init: function(element, options) {\r\n\t var that = this;\r\n\r\n\t Widget.fn.init.call(that, element, options);\r\n\r\n\t var group = that.options.group;\r\n\r\n\t if (!(group in dropTargets)) {\r\n\t dropTargets[group] = [ that ];\r\n\t } else {\r\n\t dropTargets[group].push( that );\r\n\t }\r\n\t },\r\n\r\n\t events: [\r\n\t DRAGENTER,\r\n\t DRAGLEAVE,\r\n\t DROP\r\n\t ],\r\n\r\n\t options: {\r\n\t name: \"DropTarget\",\r\n\t group: \"default\"\r\n\t },\r\n\r\n\t destroy: function() {\r\n\t destroyDroppable(dropTargets, this);\r\n\t },\r\n\r\n\t _trigger: function(eventName, e) {\r\n\t var that = this,\r\n\t draggable = draggables[that.options.group];\r\n\r\n\t if (draggable) {\r\n\t return that.trigger(eventName, extend({}, e.event, {\r\n\t draggable: draggable,\r\n\t dropTarget: e.dropTarget\r\n\t }));\r\n\t }\r\n\t },\r\n\r\n\t _over: function(e) {\r\n\t this._trigger(DRAGENTER, e);\r\n\t },\r\n\r\n\t _out: function(e) {\r\n\t this._trigger(DRAGLEAVE, e);\r\n\t },\r\n\r\n\t _drop: function(e) {\r\n\t var that = this,\r\n\t draggable = draggables[that.options.group];\r\n\r\n\t if (draggable) {\r\n\t draggable.dropped = !that._trigger(DROP, e);\r\n\t }\r\n\t }\r\n\t });\r\n\r\n\t DropTarget.destroyGroup = function(groupName) {\r\n\t var group = dropTargets[groupName] || dropAreas[groupName],\r\n\t i;\r\n\r\n\t if (group) {\r\n\t for (i = 0; i < group.length; i++) {\r\n\t Widget.fn.destroy.call(group[i]);\r\n\t }\r\n\r\n\t group.length = 0;\r\n\t delete dropTargets[groupName];\r\n\t delete dropAreas[groupName];\r\n\t }\r\n\t };\r\n\r\n\t DropTarget._cache = dropTargets;\r\n\r\n\t var DropTargetArea = DropTarget.extend({\r\n\t init: function(element, options) {\r\n\t var that = this;\r\n\r\n\t Widget.fn.init.call(that, element, options);\r\n\r\n\t var group = that.options.group;\r\n\r\n\t if (!(group in dropAreas)) {\r\n\t dropAreas[group] = [ that ];\r\n\t } else {\r\n\t dropAreas[group].push( that );\r\n\t }\r\n\t },\r\n\r\n\t destroy: function() {\r\n\t destroyDroppable(dropAreas, this);\r\n\t },\r\n\r\n\t options: {\r\n\t name: \"DropTargetArea\",\r\n\t group: \"default\",\r\n\t filter: null\r\n\t }\r\n\t });\r\n\r\n\t var Draggable = Widget.extend({\r\n\t init: function (element, options) {\r\n\t var that = this;\r\n\r\n\t Widget.fn.init.call(that, element, options);\r\n\r\n\t that._activated = false;\r\n\r\n\t that.userEvents = new UserEvents(that.element, {\r\n\t global: true,\r\n\t allowSelection: true,\r\n\t filter: that.options.filter,\r\n\t threshold: that.options.distance,\r\n\t start: proxy(that._start, that),\r\n\t hold: proxy(that._hold, that),\r\n\t move: proxy(that._drag, that),\r\n\t end: proxy(that._end, that),\r\n\t cancel: proxy(that._cancel, that),\r\n\t select: proxy(that._select, that)\r\n\t });\r\n\r\n\t if (kendo.support.touch) {\r\n\t that.element.find(that.options.filter).css('touch-action', 'none');\r\n\t }\r\n\r\n\t that._afterEndHandler = proxy(that._afterEnd, that);\r\n\t that._captureEscape = proxy(that._captureEscape, that);\r\n\t },\r\n\r\n\t events: [\r\n\t HOLD,\r\n\t DRAGSTART,\r\n\t DRAG,\r\n\t DRAGEND,\r\n\t DRAGCANCEL,\r\n\t HINTDESTROYED\r\n\t ],\r\n\r\n\t options: {\r\n\t name: \"Draggable\",\r\n\t distance: ( kendo.support.touch ? 0 : 5),\r\n\t group: \"default\",\r\n\t cursorOffset: null,\r\n\t axis: null,\r\n\t container: null,\r\n\t filter: null,\r\n\t ignore: null,\r\n\t holdToDrag: false,\r\n\t autoScroll: false,\r\n\t dropped: false\r\n\t },\r\n\r\n\t cancelHold: function() {\r\n\t this._activated = false;\r\n\t },\r\n\r\n\t _captureEscape: function(e) {\r\n\t var that = this;\r\n\r\n\t if (e.keyCode === kendo.keys.ESC) {\r\n\t that._trigger(DRAGCANCEL, { event: e });\r\n\t that.userEvents.cancel();\r\n\t }\r\n\t },\r\n\r\n\t _updateHint: function(e) {\r\n\t var that = this,\r\n\t coordinates,\r\n\t options = that.options,\r\n\t boundaries = that.boundaries,\r\n\t axis = options.axis,\r\n\t cursorOffset = that.options.cursorOffset;\r\n\r\n\t if (cursorOffset) {\r\n\t coordinates = { left: e.x.location + cursorOffset.left, top: e.y.location + cursorOffset.top };\r\n\t } else {\r\n\t that.hintOffset.left += e.x.delta;\r\n\t that.hintOffset.top += e.y.delta;\r\n\t coordinates = $.extend({}, that.hintOffset);\r\n\t }\r\n\r\n\t if (boundaries) {\r\n\t coordinates.top = within(coordinates.top, boundaries.y);\r\n\t coordinates.left = within(coordinates.left, boundaries.x);\r\n\t }\r\n\r\n\t if (axis === \"x\") {\r\n\t delete coordinates.top;\r\n\t } else if (axis === \"y\") {\r\n\t delete coordinates.left;\r\n\t }\r\n\r\n\t that.hint.css(coordinates);\r\n\t },\r\n\r\n\t _shouldIgnoreTarget: function(target) {\r\n\t var ignoreSelector = this.options.ignore;\r\n\t return ignoreSelector && $(target).is(ignoreSelector);\r\n\t },\r\n\r\n\t _select: function(e) {\r\n\t if (!this._shouldIgnoreTarget(e.event.target)) {\r\n\t e.preventDefault();\r\n\t }\r\n\t },\r\n\r\n\t _start: function(e) {\r\n\t var that = this,\r\n\t options = that.options,\r\n\t container = options.container ? $(options.container): null,\r\n\t hint = options.hint;\r\n\r\n\t if (this._shouldIgnoreTarget(e.touch.initialTouch) || (options.holdToDrag && !that._activated)) {\r\n\t that.userEvents.cancel();\r\n\t return;\r\n\t }\r\n\r\n\t that.currentTarget = e.target;\r\n\t that.currentTargetOffset = getOffset(that.currentTarget);\r\n\r\n\t if (hint) {\r\n\t if (that.hint) {\r\n\t that.hint.stop(true, true).remove();\r\n\t }\r\n\r\n\t that.hint = kendo.isFunction(hint) ? $(hint.call(that, that.currentTarget)) : hint;\r\n\r\n\t var offset = getOffset(that.currentTarget);\r\n\t that.hintOffset = offset;\r\n\r\n\t that.hint.css( {\r\n\t position: \"absolute\",\r\n\t zIndex: 20000, // the Window's z-index is 10000 and can be raised because of z-stacking\r\n\t left: offset.left,\r\n\t top: offset.top\r\n\t })\r\n\t .appendTo(document.body);\r\n\r\n\t that.angular(\"compile\", function(){\r\n\t that.hint.removeAttr(\"ng-repeat\");\r\n\t var scopeTarget = $(e.target);\r\n\r\n\t while (!scopeTarget.data(\"$$kendoScope\") && scopeTarget.length) {\r\n\t scopeTarget = scopeTarget.parent();\r\n\t }\r\n\r\n\t return {\r\n\t elements: that.hint.get(),\r\n\t scopeFrom: scopeTarget.data(\"$$kendoScope\")\r\n\t };\r\n\t });\r\n\t }\r\n\r\n\t draggables[options.group] = that;\r\n\r\n\t that.dropped = false;\r\n\r\n\t if (container) {\r\n\t that.boundaries = containerBoundaries(container, that.hint);\r\n\t }\r\n\r\n\t $(document).on(KEYUP, that._captureEscape);\r\n\r\n\t if (that._trigger(DRAGSTART, e)) {\r\n\t that.userEvents.cancel();\r\n\t that._afterEnd();\r\n\t }\r\n\r\n\t that.userEvents.capture();\r\n\t },\r\n\r\n\t _hold: function(e) {\r\n\t this.currentTarget = e.target;\r\n\r\n\t if (this._trigger(HOLD, e)) {\r\n\t this.userEvents.cancel();\r\n\t } else {\r\n\t this._activated = true;\r\n\t }\r\n\t },\r\n\r\n\t _drag: function(e) {\r\n\t e.preventDefault();\r\n\r\n\t var cursorElement = this._elementUnderCursor(e);\r\n\r\n\t if (this.options.autoScroll && this._cursorElement !== cursorElement) {\r\n\t this._scrollableParent = findScrollableParent(cursorElement);\r\n\t this._cursorElement = cursorElement;\r\n\t }\r\n\r\n\t this._lastEvent = e;\r\n\t this._processMovement(e, cursorElement);\r\n\r\n\t if (this.options.autoScroll) {\r\n\t // chrome seems to trigger mousemove when mouse is moved outside of the window (over the Chrome), too.\r\n\t if (this._scrollableParent[0]) {\r\n\t var velocity = autoScrollVelocity(e.x.location, e.y.location, scrollableViewPort(this._scrollableParent));\r\n\r\n\r\n\t this._scrollCompenstation = $.extend({}, this.hintOffset);\r\n\t this._scrollVelocity = velocity;\r\n\r\n\t if (velocity.y === 0 && velocity.x === 0) {\r\n\t clearInterval(this._scrollInterval);\r\n\t this._scrollInterval = null;\r\n\t } else if(!this._scrollInterval) {\r\n\t this._scrollInterval = setInterval($.proxy(this, \"_autoScroll\"), 50);\r\n\t }\r\n\t }\r\n\t }\r\n\r\n\t if (this.hint) {\r\n\t this._updateHint(e);\r\n\t }\r\n\t },\r\n\r\n\t _processMovement: function(e, cursorElement) {\r\n\t this._withDropTarget(cursorElement, function(target, targetElement) {\r\n\t if (!target) {\r\n\t if (lastDropTarget) {\r\n\t lastDropTarget._trigger(DRAGLEAVE, extend(e, { dropTarget: $(lastDropTarget.targetElement) }));\r\n\t lastDropTarget = null;\r\n\t }\r\n\t return;\r\n\t }\r\n\r\n\t if (lastDropTarget) {\r\n\t if (targetElement === lastDropTarget.targetElement) {\r\n\t return;\r\n\t }\r\n\r\n\t lastDropTarget._trigger(DRAGLEAVE, extend(e, { dropTarget: $(lastDropTarget.targetElement) }));\r\n\t }\r\n\r\n\t target._trigger(DRAGENTER, extend(e, { dropTarget: $(targetElement) }));\r\n\t lastDropTarget = extend(target, { targetElement: targetElement });\r\n\t });\r\n\r\n\t this._trigger(DRAG, extend(e, { dropTarget: lastDropTarget, elementUnderCursor: cursorElement }));\r\n\t },\r\n\r\n\t _autoScroll: function() {\r\n\t var parent = this._scrollableParent[0],\r\n\t velocity = this._scrollVelocity,\r\n\t compensation = this._scrollCompenstation;\r\n\r\n\t if (!parent) {\r\n\t return;\r\n\t }\r\n\r\n\t var cursorElement = this._elementUnderCursor(this._lastEvent);\r\n\t this._processMovement(this._lastEvent, cursorElement);\r\n\r\n\t var yIsScrollable, xIsScrollable;\r\n\r\n\t var isRootNode = parent === scrollableRoot()[0];\r\n\r\n\t if (isRootNode) {\r\n\t yIsScrollable = document.body.scrollHeight > $window.height();\r\n\t xIsScrollable = document.body.scrollWidth > $window.width();\r\n\t } else {\r\n\t yIsScrollable = parent.offsetHeight <= parent.scrollHeight;\r\n\t xIsScrollable = parent.offsetWidth <= parent.scrollWidth;\r\n\t }\r\n\r\n\t var yDelta = parent.scrollTop + velocity.y;\r\n\t var yInBounds = yIsScrollable && yDelta > 0 && yDelta < parent.scrollHeight;\r\n\r\n\t var xDelta = parent.scrollLeft + velocity.x;\r\n\t var xInBounds = xIsScrollable && xDelta > 0 && xDelta < parent.scrollWidth;\r\n\r\n\t if (yInBounds) {\r\n\t parent.scrollTop += velocity.y;\r\n\t }\r\n\r\n\t if (xInBounds) {\r\n\t parent.scrollLeft += velocity.x;\r\n\t }\r\n\r\n\t if (this.hint && isRootNode && (xInBounds || yInBounds)) {\r\n\t if (yInBounds) {\r\n\t compensation.top += velocity.y;\r\n\t }\r\n\r\n\t if (xInBounds) {\r\n\t compensation.left += velocity.x;\r\n\t }\r\n\r\n\t this.hint.css(compensation);\r\n\t }\r\n\t },\r\n\r\n\t _end: function(e) {\r\n\t this._withDropTarget(this._elementUnderCursor(e), function(target, targetElement) {\r\n\t if (target) {\r\n\t target._drop(extend({}, e, { dropTarget: $(targetElement) }));\r\n\t lastDropTarget = null;\r\n\t }\r\n\t });\r\n\r\n\t this._cancel(this._trigger(DRAGEND, e));\r\n\t },\r\n\r\n\t _cancel: function(isDefaultPrevented) {\r\n\t var that = this;\r\n\r\n\t that._scrollableParent = null;\r\n\t this._cursorElement = null;\r\n\t clearInterval(this._scrollInterval);\r\n\t that._activated = false;\r\n\r\n\t if (that.hint && !that.dropped) {\r\n\t setTimeout(function() {\r\n\t that.hint.stop(true, true);\r\n\r\n\t if (isDefaultPrevented) {\r\n\t that._afterEndHandler();\r\n\t } else {\r\n\t that.hint.animate(that.currentTargetOffset, \"fast\", that._afterEndHandler);\r\n\t }\r\n\t }, 0);\r\n\r\n\t } else {\r\n\t that._afterEnd();\r\n\t }\r\n\t },\r\n\r\n\t _trigger: function(eventName, e) {\r\n\t var that = this;\r\n\r\n\t return that.trigger(\r\n\t eventName, extend(\r\n\t {},\r\n\t e.event,\r\n\t {\r\n\t x: e.x,\r\n\t y: e.y,\r\n\t currentTarget: that.currentTarget,\r\n\t initialTarget: e.touch ? e.touch.initialTouch : null,\r\n\t dropTarget: e.dropTarget,\r\n\t elementUnderCursor: e.elementUnderCursor\r\n\t }\r\n\t ));\r\n\t },\r\n\r\n\t _elementUnderCursor: function(e) {\r\n\t var target = elementUnderCursor(e),\r\n\t hint = this.hint;\r\n\r\n\t if (hint && contains(hint[0], target)) {\r\n\t hint.hide();\r\n\t target = elementUnderCursor(e);\r\n\t // IE8 does not return the element in iframe from first attempt\r\n\t if (!target) {\r\n\t target = elementUnderCursor(e);\r\n\t }\r\n\t hint.show();\r\n\t }\r\n\r\n\t return target;\r\n\t },\r\n\r\n\t _withDropTarget: function(element, callback) {\r\n\t var result,\r\n\t group = this.options.group,\r\n\t targets = dropTargets[group],\r\n\t areas = dropAreas[group];\r\n\r\n\t if (targets && targets.length || areas && areas.length) {\r\n\t result = checkTarget(element, targets, areas);\r\n\r\n\t if (result) {\r\n\t callback(result.target, result.targetElement);\r\n\t } else {\r\n\t callback();\r\n\t }\r\n\t }\r\n\t },\r\n\r\n\t destroy: function() {\r\n\t var that = this;\r\n\r\n\t Widget.fn.destroy.call(that);\r\n\r\n\t that._afterEnd();\r\n\r\n\t that.userEvents.destroy();\r\n\r\n\t this._scrollableParent = null;\r\n\t this._cursorElement = null;\r\n\t clearInterval(this._scrollInterval);\r\n\r\n\t that.currentTarget = null;\r\n\t },\r\n\r\n\t _afterEnd: function() {\r\n\t var that = this;\r\n\r\n\t if (that.hint) {\r\n\t that.hint.remove();\r\n\t }\r\n\r\n\t delete draggables[that.options.group];\r\n\r\n\t that.trigger(\"destroy\");\r\n\t that.trigger(HINTDESTROYED);\r\n\t $(document).off(KEYUP, that._captureEscape);\r\n\t }\r\n\t });\r\n\r\n\t kendo.ui.plugin(DropTarget);\r\n\t kendo.ui.plugin(DropTargetArea);\r\n\t kendo.ui.plugin(Draggable);\r\n\t kendo.TapCapture = TapCapture;\r\n\t kendo.containerBoundaries = containerBoundaries;\r\n\r\n\t extend(kendo.ui, {\r\n\t Pane: Pane,\r\n\t PaneDimensions: PaneDimensions,\r\n\t Movable: Movable\r\n\t });\r\n\r\n\t function scrollableViewPort(element) {\r\n\t var root = scrollableRoot()[0],\r\n\t offset,\r\n\t top,\r\n\t left;\r\n\r\n\t if (element[0] === root) {\r\n\t top = root.scrollTop;\r\n\t left = root.scrollLeft;\r\n\r\n\t return {\r\n\t top: top,\r\n\t left: left,\r\n\t bottom: top + $window.height(),\r\n\t right: left + $window.width()\r\n\t };\r\n\t } else {\r\n\t offset = element.offset();\r\n\t offset.bottom = offset.top + element.height();\r\n\t offset.right = offset.left + element.width();\r\n\t return offset;\r\n\t }\r\n\t }\r\n\r\n\t function scrollableRoot() {\r\n\t return $(kendo.support.browser.edge || kendo.support.browser.safari ? document.body : document.documentElement);\r\n\t }\r\n\r\n\t function findScrollableParent(element) {\r\n\t var root = scrollableRoot();\r\n\r\n\t if (!element || element === document.body || element === document.documentElement) {\r\n\t return root;\r\n\t }\r\n\r\n\t var parent = $(element)[0];\r\n\r\n\t while (parent && !kendo.isScrollable(parent) && parent !== document.body) {\r\n\t parent = parent.parentNode;\r\n\t }\r\n\r\n\t if (parent === document.body) {\r\n\t return root;\r\n\t }\r\n\r\n\t return $(parent);\r\n\t }\r\n\r\n\t function autoScrollVelocity(mouseX, mouseY, rect) {\r\n\t var velocity = { x: 0, y: 0 };\r\n\r\n\t var AUTO_SCROLL_AREA = 50;\r\n\r\n\t if (mouseX - rect.left < AUTO_SCROLL_AREA) {\r\n\t velocity.x = -(AUTO_SCROLL_AREA - (mouseX - rect.left));\r\n\t } else if (rect.right - mouseX < AUTO_SCROLL_AREA) {\r\n\t velocity.x = AUTO_SCROLL_AREA - (rect.right - mouseX);\r\n\t }\r\n\r\n\t if (mouseY - rect.top < AUTO_SCROLL_AREA) {\r\n\t velocity.y = -(AUTO_SCROLL_AREA - (mouseY - rect.top));\r\n\t } else if (rect.bottom - mouseY < AUTO_SCROLL_AREA) {\r\n\t velocity.y = AUTO_SCROLL_AREA - (rect.bottom - mouseY);\r\n\t }\r\n\r\n\t return velocity;\r\n\t }\r\n\r\n\t // export for testing\r\n\t kendo.ui.Draggable.utils = {\r\n\t autoScrollVelocity: autoScrollVelocity,\r\n\t scrollableViewPort: scrollableViewPort,\r\n\t findScrollableParent: findScrollableParent\r\n\t };\r\n\r\n\t })(window.kendo.jQuery);\r\n\r\n\treturn window.kendo;\r\n\r\n\t}, __webpack_require__(3));\r\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1145);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1145:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n\t __webpack_require__(1146),\n\t __webpack_require__(1147),\n\t __webpack_require__(1148),\n\t __webpack_require__(1149),\n\t __webpack_require__(1150)\n\t ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t var __meta__ = { // jshint ignore:line\n\t id: \"drawing\",\n\t name: \"Drawing API\",\n\t category: \"framework\",\n\t description: \"The Kendo UI low-level drawing API\",\n\t depends: [ \"core\", \"color\", \"popup\" ]\n\t };\n\n\t}, __webpack_require__(3));\n\n/***/ }),\n\n/***/ 1146:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./drawing/util\");\n\n/***/ }),\n\n/***/ 1147:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./drawing/kendo-drawing\");\n\n/***/ }),\n\n/***/ 1148:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./drawing/surface-tooltip\");\n\n/***/ }),\n\n/***/ 1149:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./drawing/surface\");\n\n/***/ }),\n\n/***/ 1150:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./drawing/html\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1151);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1036:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.list\");\n\n/***/ }),\n\n/***/ 1037:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.mobile.scroller\");\n\n/***/ }),\n\n/***/ 1038:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.virtuallist\");\n\n/***/ }),\n\n/***/ 1151:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1036), __webpack_require__(1037), __webpack_require__(1038) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dropdownlist\",\n\t name: \"DropDownList\",\n\t category: \"web\",\n\t description: \"The DropDownList widget displays a list of values and allows the selection of a single value from the list.\",\n\t depends: [ \"list\" ],\n\t features: [ {\n\t id: \"mobile-scroller\",\n\t name: \"Mobile scroller\",\n\t description: \"Support for kinetic scrolling in mobile device\",\n\t depends: [ \"mobile.scroller\" ]\n\t }, {\n\t id: \"virtualization\",\n\t name: \"VirtualList\",\n\t description: \"Support for virtualization\",\n\t depends: [ \"virtuallist\" ]\n\t } ]\n\t};\n\n\t(function($, undefined) {\n\t var kendo = window.kendo,\n\t ui = kendo.ui,\n\t List = ui.List,\n\t Select = ui.Select,\n\t support = kendo.support,\n\t activeElement = kendo._activeElement,\n\t ObservableObject = kendo.data.ObservableObject,\n\t keys = kendo.keys,\n\t ns = \".kendoDropDownList\",\n\t nsFocusEvent = ns + \"FocusEvent\",\n\t DISABLED = \"disabled\",\n\t READONLY = \"readonly\",\n\t CHANGE = \"change\",\n\t FOCUSED = \"k-state-focused\",\n\t DEFAULT = \"k-state-default\",\n\t STATEDISABLED = \"k-state-disabled\",\n\t ARIA_DISABLED = \"aria-disabled\",\n\t CLICKEVENTS = \"click\" + ns + \" touchend\" + ns,\n\t HOVEREVENTS = \"mouseenter\" + ns + \" mouseleave\" + ns,\n\t TABINDEX = \"tabindex\",\n\t STATE_FILTER = \"filter\",\n\t STATE_ACCEPT = \"accept\",\n\t MSG_INVALID_OPTION_LABEL = \"The `optionLabel` option is not valid due to missing fields. Define a custom optionLabel as shown here http://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist#configuration-optionLabel\",\n\t proxy = $.proxy;\n\n\t var DropDownList = Select.extend( {\n\t init: function(element, options) {\n\t var that = this;\n\t var index = options && options.index;\n\t var optionLabel, text, disabled;\n\n\t that.ns = ns;\n\t options = $.isArray(options) ? { dataSource: options } : options;\n\n\t Select.fn.init.call(that, element, options);\n\n\t options = that.options;\n\t element = that.element.on(\"focus\" + ns, proxy(that._focusHandler, that));\n\n\t that._focusInputHandler = $.proxy(that._focusInput, that);\n\n\t that.optionLabel = $();\n\t that._optionLabel();\n\n\t that._inputTemplate();\n\n\t that._reset();\n\n\t that._prev = \"\";\n\t that._word = \"\";\n\n\t that._wrapper();\n\n\t that._tabindex();\n\t that.wrapper.data(TABINDEX, that.wrapper.attr(TABINDEX));\n\n\t that._span();\n\n\t that._popup();\n\n\t that._mobile();\n\n\t that._dataSource();\n\n\t that._ignoreCase();\n\n\t that._filterHeader();\n\n\t that._aria();\n\n\t //should read changed value of closed dropdownlist\n\t that.wrapper.attr(\"aria-live\", \"polite\");\n\n\t that._enable();\n\n\t that._attachFocusHandlers();\n\n\t that._oldIndex = that.selectedIndex = -1;\n\n\t if (index !== undefined) {\n\t options.index = index;\n\t }\n\n\t that._initialIndex = options.index;\n\n\t that.requireValueMapper(that.options);\n\t that._initList();\n\n\t that._cascade();\n\n\t that.one(\"set\", function(e) {\n\t if (!e.sender.listView.bound() && that.hasOptionLabel()) {\n\t that._textAccessor(that._optionLabelText());\n\t }\n\t });\n\n\t if (options.autoBind) {\n\t that.dataSource.fetch();\n\t } else if (that.selectedIndex === -1) { //selectedIndex !== -1 when cascade functionality happens instantly\n\t text = options.text || \"\";\n\t if (!text) {\n\t optionLabel = options.optionLabel;\n\n\t if (optionLabel && options.index === 0) {\n\t text = optionLabel;\n\t } else if (that._isSelect) {\n\t text = element.children(\":selected\").text();\n\t }\n\t }\n\n\t that._textAccessor(text);\n\t }\n\n\t disabled = $(that.element).parents(\"fieldset\").is(':disabled');\n\n\t if (disabled) {\n\t that.enable(false);\n\t }\n\n\t that.listView.bind(\"click\", function(e) { e.preventDefault(); });\n\n\t kendo.notify(that);\n\t },\n\n\t options: {\n\t name: \"DropDownList\",\n\t enabled: true,\n\t autoBind: true,\n\t index: 0,\n\t text: null,\n\t value: null,\n\t delay: 500,\n\t height: 200,\n\t dataTextField: \"\",\n\t dataValueField: \"\",\n\t optionLabel: \"\",\n\t cascadeFrom: \"\",\n\t cascadeFromField: \"\",\n\t cascadeFromParentField: \"\",\n\t ignoreCase: true,\n\t animation: {},\n\t filter: \"none\",\n\t minLength: 1,\n\t enforceMinLength: false,\n\t virtual: false,\n\t template: null,\n\t valueTemplate: null,\n\t optionLabelTemplate: null,\n\t groupTemplate: \"#:data#\",\n\t fixedGroupTemplate: \"#:data#\",\n\t autoWidth: false,\n\t popup: null\n\t },\n\n\t events: [\n\t \"open\",\n\t \"close\",\n\t CHANGE,\n\t \"select\",\n\t \"filtering\",\n\t \"dataBinding\",\n\t \"dataBound\",\n\t \"cascade\",\n\t \"set\",\n\t \"kendoKeydown\"\n\t ],\n\n\t setOptions: function(options) {\n\t Select.fn.setOptions.call(this, options);\n\n\t this.listView.setOptions(this._listOptions(options));\n\n\t this._optionLabel();\n\t this._inputTemplate();\n\t this._accessors();\n\t this._filterHeader();\n\t this._enable();\n\t this._aria();\n\n\t if (!this.value() && this.hasOptionLabel()) {\n\t this.select(0);\n\t }\n\t },\n\n\t destroy: function() {\n\t var that = this;\n\n\t Select.fn.destroy.call(that);\n\n\t that.wrapper.off(ns);\n\t that.wrapper.off(nsFocusEvent);\n\t that.element.off(ns);\n\t that._inputWrapper.off(ns);\n\n\t that._arrow.off();\n\t that._arrow = null;\n\t that._arrowIcon = null;\n\n\t that.optionLabel.off();\n\n\t if(that.filterInput){\n\t that.filterInput.off(nsFocusEvent);\n\t }\n\t },\n\n\t open: function() {\n\t var that = this;\n\t var isFiltered = that.dataSource.filter() ? that.dataSource.filter().filters.length > 0 : false;\n\n\t if (that.popup.visible()) {\n\t return;\n\t }\n\n\t if (!that.listView.bound() || that._state === STATE_ACCEPT) {\n\t that._open = true;\n\t that._state = \"rebind\";\n\n\t if (that.filterInput) {\n\t that.filterInput.val(\"\");\n\t that._prev = \"\";\n\t }\n\n\t if (that.filterInput && that.options.minLength !== 1 && !isFiltered) {\n\t that.refresh();\n\t that.popup.one(\"activate\", that._focusInputHandler);\n\t that.popup.open();\n\t that._resizeFilterInput();\n\t } else {\n\t that._filterSource();\n\t }\n\t } else if (that._allowOpening()) {\n\t that._focusFilter = true;\n\t that.popup.one(\"activate\", that._focusInputHandler);\n\t // In some cases when the popup is opened resize is triggered which will cause it to close\n\t // Setting the below flag will prevent this from happening\n\t that.popup._hovered = true;\n\t that.popup.open();\n\t that._resizeFilterInput();\n\t that._focusItem();\n\t }\n\t },\n\n\t _focusInput: function () {\n\t this._focusElement(this.filterInput);\n\t },\n\n\t _resizeFilterInput: function () {\n\t var filterInput = this.filterInput;\n\t var originalPrevent = this._prevent;\n\n\t if (!filterInput) {\n\t return;\n\t }\n\n\t var isInputActive = this.filterInput[0] === activeElement();\n\t var caret = kendo.caret(this.filterInput[0])[0];\n\n\t this._prevent = true;\n\n\t filterInput.css(\"display\", \"none\")\n\t .css(\"width\", this.popup.element.css(\"width\"))\n\t .css(\"display\", \"inline-block\");\n\n\t if (isInputActive) {\n\t filterInput.focus();\n\t kendo.caret(filterInput[0], caret);\n\t }\n\n\t this._prevent = originalPrevent;\n\t },\n\n\t _allowOpening: function() {\n\t return this.hasOptionLabel() || this.filterInput || Select.fn._allowOpening.call(this);\n\t },\n\n\t toggle: function(toggle) {\n\t this._toggle(toggle, true);\n\t },\n\n\t current: function(candidate) {\n\t var current;\n\n\t if (candidate === undefined) {\n\t current = this.listView.focus();\n\n\t if (!current && this.selectedIndex === 0 && this.hasOptionLabel()) {\n\t return this.optionLabel;\n\t }\n\n\t return current;\n\t }\n\n\t this._focus(candidate);\n\t },\n\n\t dataItem: function(index) {\n\t var that = this;\n\t var dataItem = null;\n\n\t if (index === null) { return index; }\n\n\t if (index === undefined) {\n\t dataItem = that.listView.selectedDataItems()[0];\n\t } else {\n\t if (typeof index !== \"number\") {\n\t if (that.options.virtual) {\n\t return that.dataSource.getByUid($(index).data(\"uid\"));\n\t }\n\t if (index.hasClass(\"k-list-optionlabel\")) {\n\t index = -1;\n\t } else {\n\t index = $(that.items()).index(index);\n\t }\n\t } else if (that.hasOptionLabel()) {\n\t index -= 1;\n\t }\n\n\t dataItem = that.dataSource.flatView()[index];\n\t }\n\n\t if (!dataItem) {\n\t dataItem = that._optionLabelDataItem();\n\t }\n\n\t return dataItem;\n\t },\n\n\t refresh: function() {\n\t this.listView.refresh();\n\t },\n\n\t text: function (text) {\n\t var that = this;\n\t var loweredText;\n\t var ignoreCase = that.options.ignoreCase;\n\n\t text = text === null ? \"\" : text;\n\n\t if (text !== undefined) {\n\t if (typeof text !== \"string\") {\n\t that._textAccessor(text);\n\t return;\n\t }\n\n\t loweredText = ignoreCase ? text.toLowerCase() : text;\n\n\t that._select(function(data) {\n\t data = that._text(data);\n\n\t if (ignoreCase) {\n\t data = (data + \"\").toLowerCase();\n\t }\n\n\t return data === loweredText;\n\t }).done(function() {\n\t that._textAccessor(that.dataItem() || text);\n\t });\n\n\t } else {\n\t return that._textAccessor();\n\t }\n\t },\n\n\t _clearFilter: function() {\n\t $(this.filterInput).val(\"\");\n\t Select.fn._clearFilter.call(this);\n\t },\n\n\t value: function(value) {\n\t var that = this;\n\t var listView = that.listView;\n\t var dataSource = that.dataSource;\n\n\t if (value === undefined) {\n\t value = that._accessor() || that.listView.value()[0];\n\t return value === undefined || value === null ? \"\" : value;\n\t }\n\n\t that.requireValueMapper(that.options, value);\n\n\t if (value || !that.hasOptionLabel()) {\n\t that._initialIndex = null;\n\t }\n\n\t this.trigger(\"set\", { value: value });\n\n\t if (that._request && that.options.cascadeFrom && that.listView.bound()) {\n\t if (that._valueSetter) {\n\t dataSource.unbind(CHANGE, that._valueSetter);\n\t }\n\n\t that._valueSetter = proxy(function() { that.value(value); }, that);\n\n\t dataSource.one(CHANGE, that._valueSetter);\n\t return;\n\t }\n\n\t if (that._isFilterEnabled() && listView.bound() && listView.isFiltered()) {\n\t that._clearFilter();\n\t } else {\n\t that._fetchData();\n\t }\n\n\t listView.value(value).done(function() {\n\t that._old = that._valueBeforeCascade = that._accessor();\n\t that._oldIndex = that.selectedIndex;\n\t });\n\t },\n\n\t hasOptionLabel: function() {\n\t return this.optionLabel && !!this.optionLabel[0];\n\t },\n\n\t _optionLabel: function() {\n\t var that = this;\n\t var options = that.options;\n\t var optionLabel = options.optionLabel;\n\t var template = options.optionLabelTemplate;\n\n\t if (!optionLabel) {\n\t that.optionLabel.off().remove();\n\t that.optionLabel = $();\n\t return;\n\t }\n\n\t if (!template) {\n\t template = \"#:\";\n\n\t if (typeof optionLabel === \"string\") {\n\t template += \"data\";\n\t } else {\n\t template += kendo.expr(options.dataTextField, \"data\");\n\t }\n\n\t template += \"#\";\n\t }\n\n\t if (typeof template !== \"function\") {\n\t template = kendo.template(template);\n\t }\n\n\t that.optionLabelTemplate = template;\n\n\t if (!that.hasOptionLabel()) {\n\t that.optionLabel = $('
    ').prependTo(that.list);\n\t }\n\n\t that.optionLabel.html(template(optionLabel))\n\t .off()\n\t .on(CLICKEVENTS, proxy(that._click, that))\n\t .on(HOVEREVENTS, that._toggleHover);\n\n\t that.angular(\"compile\", function() {\n\t return { elements: that.optionLabel, data: [{ dataItem: that._optionLabelDataItem() }] };\n\t });\n\t },\n\n\t _optionLabelText: function() {\n\t var optionLabel = this.options.optionLabel;\n\t return (typeof optionLabel === \"string\") ? optionLabel : this._text(optionLabel);\n\t },\n\n\t _optionLabelDataItem: function() {\n\t var that = this;\n\t var optionLabel = that.options.optionLabel;\n\n\t if (that.hasOptionLabel()) {\n\t return $.isPlainObject(optionLabel) ? new ObservableObject(optionLabel) : that._assignInstance(that._optionLabelText(), \"\");\n\t }\n\n\t return undefined;\n\t },\n\n\t _buildOptions: function(data) {\n\t var that = this;\n\t if (!that._isSelect) {\n\t return;\n\t }\n\n\t var value = that.listView.value()[0];\n\t var optionLabel = that._optionLabelDataItem();\n\t var optionLabelValue = optionLabel && that._value(optionLabel);\n\n\t if (value === undefined || value === null) {\n\t value = \"\";\n\t }\n\n\t if (optionLabel) {\n\t if (optionLabelValue === undefined || optionLabelValue === null) {\n\t optionLabelValue = \"\";\n\t }\n\n\t optionLabel = '\";\n\t }\n\n\t that._options(data, optionLabel, value);\n\n\t if (value !== List.unifyType(that._accessor(), typeof value)) {\n\t that._customOption = null;\n\t that._custom(value);\n\t }\n\t },\n\n\t _listBound: function() {\n\n\t var that = this;\n\t var initialIndex = that._initialIndex;\n\t var filtered = that._state === STATE_FILTER;\n\n\t var data = that.dataSource.flatView();\n\t var dataItem;\n\n\t that._presetValue = false;\n\n\t that._renderFooter();\n\t that._renderNoData();\n\t that._toggleNoData(!data.length);\n\n\t that._resizePopup(true);\n\n\t that.popup.position();\n\n\t that._buildOptions(data);\n\n\t that._makeUnselectable();\n\n\t if (!filtered) {\n\t if (that._open) {\n\t that.toggle(that._allowOpening());\n\t }\n\n\t that._open = false;\n\n\t if (!that._fetch) {\n\t if (data.length) {\n\t if (!that.listView.value().length && initialIndex > -1 && initialIndex !== null) {\n\t that.select(initialIndex);\n\t }\n\n\t that._initialIndex = null;\n\t dataItem = that.listView.selectedDataItems()[0];\n\t if (dataItem && that.text() !== that._text(dataItem)) {\n\t that._selectValue(dataItem);\n\t }\n\t } else if (that._textAccessor() !== that._optionLabelText()) {\n\t that.listView.value(\"\");\n\t that._selectValue(null);\n\t that._oldIndex = that.selectedIndex;\n\t }\n\t }\n\t }\n\n\t that._hideBusy();\n\t that.trigger(\"dataBound\");\n\t },\n\n\t _listChange: function() {\n\t this._selectValue(this.listView.selectedDataItems()[0]);\n\n\t if (this._presetValue || (this._old && this._oldIndex === -1)) {\n\t this._oldIndex = this.selectedIndex;\n\t }\n\t },\n\n\t _filterPaste: function() {\n\t this._search();\n\t },\n\n\t _attachFocusHandlers: function() {\n\t var that = this;\n\t var wrapper = that.wrapper;\n\n\t wrapper.on(\"focusin\" + nsFocusEvent, proxy(that._focusinHandler, that))\n\t .on(\"focusout\" + nsFocusEvent, proxy(that._focusoutHandler, that));\n\t if(that.filterInput) {\n\t that.filterInput.on(\"focusin\" + nsFocusEvent, proxy(that._focusinHandler, that))\n\t .on(\"focusout\" + nsFocusEvent, proxy(that._focusoutHandler, that));\n\t }\n\t },\n\n\t _focusHandler: function() {\n\t this.wrapper.focus();\n\t },\n\n\t _focusinHandler: function() {\n\t this._inputWrapper.addClass(FOCUSED);\n\t this._prevent = false;\n\t },\n\n\t _focusoutHandler: function() {\n\t var that = this;\n\t var isIFrame = window.self !== window.top;\n\n\t if (!that._prevent) {\n\t clearTimeout(that._typingTimeout);\n\n\t if (support.mobileOS.ios && isIFrame) {\n\t that._change();\n\t } else {\n\t that._blur();\n\t }\n\n\t that._inputWrapper.removeClass(FOCUSED);\n\t that._prevent = true;\n\t that._open = false;\n\t that.element.blur();\n\t }\n\t },\n\n\t _wrapperMousedown: function() {\n\t this._prevent = !!this.filterInput;\n\t },\n\n\t _wrapperClick: function(e) {\n\t e.preventDefault();\n\t this.popup.unbind(\"activate\", this._focusInputHandler);\n\t this._focused = this.wrapper;\n\t this._prevent = false;\n\t this._toggle();\n\t },\n\n\t _editable: function(options) {\n\t var that = this;\n\t var element = that.element;\n\t var disable = options.disable;\n\t var readonly = options.readonly;\n\t var wrapper = that.wrapper.add(that.filterInput).off(ns);\n\t var dropDownWrapper = that._inputWrapper.off(HOVEREVENTS);\n\n\t if (!readonly && !disable) {\n\t element.removeAttr(DISABLED).removeAttr(READONLY);\n\n\t dropDownWrapper\n\t .addClass(DEFAULT)\n\t .removeClass(STATEDISABLED)\n\t .on(HOVEREVENTS, that._toggleHover);\n\n\t wrapper\n\t .attr(TABINDEX, wrapper.data(TABINDEX))\n\t .attr(ARIA_DISABLED, false)\n\t .on(\"keydown\" + ns, that, proxy(that._keydown, that))\n\t .on(kendo.support.mousedown + ns, proxy(that._wrapperMousedown, that))\n\t .on(\"paste\" + ns, proxy(that._filterPaste, that));\n\n\t that.wrapper.on(\"click\" + ns, proxy(that._wrapperClick, that));\n\n\t if (!that.filterInput) {\n\t wrapper.on(\"keypress\" + ns, proxy(that._keypress, that));\n\t } else {\n\t wrapper.on(\"input\" + ns, proxy(that._search, that));\n\t }\n\n\t } else if (disable) {\n\t wrapper.removeAttr(TABINDEX);\n\t dropDownWrapper\n\t .addClass(STATEDISABLED)\n\t .removeClass(DEFAULT);\n\t } else {\n\t dropDownWrapper\n\t .addClass(DEFAULT)\n\t .removeClass(STATEDISABLED);\n\t }\n\n\t element.attr(DISABLED, disable)\n\t .attr(READONLY, readonly);\n\n\t wrapper.attr(ARIA_DISABLED, disable);\n\t },\n\n\t _keydown: function(e) {\n\t var that = this;\n\t var key = e.keyCode;\n\t var altKey = e.altKey;\n\t var isInputActive;\n\t var handled;\n\n\t var isPopupVisible = that.popup.visible();\n\n\t if (that.filterInput) {\n\t isInputActive = that.filterInput[0] === activeElement();\n\t }\n\n\t if (key === keys.LEFT) {\n\t key = keys.UP;\n\t handled = true;\n\t } else if (key === keys.RIGHT) {\n\t key = keys.DOWN;\n\t handled = true;\n\t }\n\n\t if (handled && isInputActive) {\n\t return;\n\t }\n\n\t e.keyCode = key;\n\n\t if ((altKey && key === keys.UP) || key === keys.ESC) {\n\t that._focusElement(that.wrapper);\n\t }\n\n\t if (that._state === STATE_FILTER && key === keys.ESC) {\n\t that._clearFilter();\n\t that._open = false;\n\t that._state = STATE_ACCEPT;\n\t }\n\n\t if (key === keys.ENTER && that._typingTimeout && that.filterInput && isPopupVisible) {\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if (key === keys.SPACEBAR && !isInputActive) {\n\t that.toggle(!isPopupVisible);\n\t e.preventDefault();\n\t }\n\n\t handled = that._move(e);\n\n\t if (handled) {\n\t return;\n\t }\n\n\t if (!isPopupVisible || !that.filterInput) {\n\t var current = that._focus();\n\n\t if (key === keys.HOME) {\n\t handled = true;\n\t that._firstItem();\n\t } else if (key === keys.END) {\n\t handled = true;\n\t that._lastItem();\n\t }\n\n\t if (handled) {\n\t if (that.trigger(\"select\", { dataItem: that._getElementDataItem(that._focus()), item: that._focus() })) {\n\t that._focus(current);\n\t return;\n\t }\n\n\t that._select(that._focus(), true).done(function() {\n\t if (!isPopupVisible) {\n\t that._blur();\n\t }\n\t });\n\t e.preventDefault();\n\t }\n\t }\n\n\t if (!altKey && !handled && that.filterInput) {\n\t that._search();\n\t }\n\t },\n\n\t _matchText: function(text, word) {\n\t var ignoreCase = this.options.ignoreCase;\n\n\t if (text === undefined || text === null) {\n\t return false;\n\t }\n\n\t text = text + \"\";\n\n\t if (ignoreCase) {\n\t text = text.toLowerCase();\n\t }\n\n\t return text.indexOf(word) === 0;\n\t },\n\n\t _shuffleData: function(data, splitIndex) {\n\t var optionDataItem = this._optionLabelDataItem();\n\n\t if (optionDataItem) {\n\t data = [optionDataItem].concat(data);\n\t }\n\n\t return data.slice(splitIndex).concat(data.slice(0, splitIndex));\n\t },\n\n\t _selectNext: function() {\n\t var that = this;\n\t var data = that.dataSource.flatView();\n\t var dataLength = data.length + (that.hasOptionLabel() ? 1 : 0);\n\t var isInLoop = sameCharsOnly(that._word, that._last);\n\t var startIndex = that.selectedIndex;\n\t var oldFocusedItem;\n\t var text;\n\n\t if (startIndex === -1) {\n\t startIndex = 0;\n\t } else {\n\t startIndex += isInLoop ? 1 : 0;\n\t startIndex = normalizeIndex(startIndex, dataLength);\n\t }\n\n\t data = data.toJSON ? data.toJSON() : data.slice();\n\t data = that._shuffleData(data, startIndex);\n\n\t for (var idx = 0; idx < dataLength; idx++) {\n\t text = that._text(data[idx]);\n\n\t if (isInLoop && that._matchText(text, that._last)) {\n\t break;\n\t } else if (that._matchText(text, that._word)) {\n\t break;\n\t }\n\t }\n\n\t if (idx !== dataLength) {\n\t oldFocusedItem = that._focus();\n\n\t that._select(normalizeIndex(startIndex + idx, dataLength)).done(function() {\n\t var done = function() {\n\t if (!that.popup.visible()) {\n\t that._change();\n\t }\n\t };\n\n\t if (that.trigger(\"select\", { dataItem: that._getElementDataItem(that._focus()), item: that._focus() })) {\n\t that._select(oldFocusedItem).done(done);\n\t } else {\n\t done();\n\t }\n\t });\n\t }\n\t },\n\n\t _keypress: function(e) {\n\t var that = this;\n\n\t if (e.which === 0 || e.keyCode === kendo.keys.ENTER) {\n\t return;\n\t }\n\n\t var character = String.fromCharCode(e.charCode || e.keyCode);\n\n\t if (that.options.ignoreCase) {\n\t character = character.toLowerCase();\n\t }\n\n\t if (character === \" \") {\n\t e.preventDefault();\n\t }\n\n\t that._word += character;\n\t that._last = character;\n\n\t that._search();\n\t },\n\n\t _popupOpen: function() {\n\t var popup = this.popup;\n\n\t popup.wrapper = kendo.wrap(popup.element);\n\n\t if (popup.element.closest(\".km-root\")[0]) {\n\t popup.wrapper.addClass(\"km-popup km-widget\");\n\t this.wrapper.addClass(\"km-widget\");\n\t }\n\t },\n\n\t _popup: function() {\n\t Select.fn._popup.call(this);\n\t this.popup.one(\"open\", proxy(this._popupOpen, this));\n\t },\n\n\t _getElementDataItem: function(element) {\n\t if (!element || !element[0]) {\n\t return null;\n\t }\n\n\t if (element[0] === this.optionLabel[0]) {\n\t return this._optionLabelDataItem();\n\t }\n\n\t return this.listView.dataItemByIndex(this.listView.getElementIndex(element));\n\t },\n\n\t _click: function (e) {\n\t var that = this;\n\t var item = e.item || $(e.currentTarget);\n\n\t e.preventDefault();\n\n\t if (that.trigger(\"select\", { dataItem: that._getElementDataItem(item), item: item })) {\n\t that.close();\n\t return;\n\t }\n\n\t that._userTriggered = true;\n\n\t that._select(item).done(function() {\n\t that._blur();\n\t that._focusElement(that.wrapper);\n\t });\n\t },\n\n\t _focusElement: function(element) {\n\t var active = activeElement();\n\t var wrapper = this.wrapper;\n\t var filterInput = this.filterInput;\n\t var compareElement = element === filterInput ? wrapper : filterInput;\n\t var touchEnabled = support.mobileOS && (support.touch || support.MSPointers || support.pointers);\n\n\t if (filterInput && filterInput[0] === element[0] && touchEnabled) {\n\t return;\n\t }\n\n\t if (filterInput && (compareElement[0] === active || this._focusFilter)) {\n\t this._focusFilter = false;\n\t this._prevent = true;\n\t this._focused = element.focus();\n\t }\n\t },\n\n\t _searchByWord: function(word) {\n\t if (!word) {\n\t return;\n\t }\n\n\t var that = this;\n\t var ignoreCase = that.options.ignoreCase;\n\n\t if (ignoreCase) {\n\t word = word.toLowerCase();\n\t }\n\n\t that._select(function(dataItem) {\n\t return that._matchText(that._text(dataItem), word);\n\t });\n\t },\n\n\t _inputValue: function() {\n\t return this.text();\n\t },\n\n\t _search: function() {\n\t var that = this;\n\t var dataSource = that.dataSource;\n\n\t clearTimeout(that._typingTimeout);\n\n\t if (that._isFilterEnabled()) {\n\t that._typingTimeout = setTimeout(function() {\n\t var value = that.filterInput.val();\n\n\t if (that._prev !== value) {\n\t that._prev = value;\n\t that.search(value);\n\t that._resizeFilterInput();\n\t }\n\n\t that._typingTimeout = null;\n\t }, that.options.delay);\n\t } else {\n\t that._typingTimeout = setTimeout(function() {\n\t that._word = \"\";\n\t }, that.options.delay);\n\n\t if (!that.listView.bound()) {\n\t dataSource.fetch().done(function () {\n\t that._selectNext();\n\t });\n\t return;\n\t }\n\n\t that._selectNext();\n\t }\n\t },\n\n\t _get: function(candidate) {\n\t var data, found, idx;\n\t var isFunction = typeof candidate === \"function\";\n\t var jQueryCandidate = !isFunction ? $(candidate) : $();\n\n\t if (this.hasOptionLabel()) {\n\t if (typeof candidate === \"number\") {\n\t if (candidate > -1) {\n\t candidate -= 1;\n\t }\n\t } else if (jQueryCandidate.hasClass(\"k-list-optionlabel\")) {\n\t candidate = -1;\n\t }\n\t }\n\n\t if (isFunction) {\n\t data = this.dataSource.flatView();\n\n\t for (idx = 0; idx < data.length; idx++) {\n\t if (candidate(data[idx])) {\n\t candidate = idx;\n\t found = true;\n\t break;\n\t }\n\t }\n\n\t if (!found) {\n\t candidate = -1;\n\t }\n\t }\n\n\t return candidate;\n\t },\n\n\t _firstItem: function() {\n\t if (this.hasOptionLabel()) {\n\t this._focus(this.optionLabel);\n\t } else {\n\t this.listView.focusFirst();\n\t }\n\t },\n\n\t _lastItem: function() {\n\t this._resetOptionLabel();\n\t this.listView.focusLast();\n\t },\n\n\t _nextItem: function() {\n\t var focusIndex;\n\n\t if (this.optionLabel.hasClass(\"k-state-focused\")) {\n\t this._resetOptionLabel();\n\t this.listView.focusFirst();\n\t focusIndex = 1;\n\t } else {\n\t focusIndex = this.listView.focusNext();\n\t }\n\n\t return focusIndex;\n\t },\n\n\t _prevItem: function() {\n\t var focusIndex;\n\n\t if (this.optionLabel.hasClass(\"k-state-focused\")) {\n\t return;\n\t }\n\n\t focusIndex = this.listView.focusPrev();\n\n\t if (!this.listView.focus() && !this.options.virtual) {\n\t this._focus(this.optionLabel);\n\t }\n\n\t return focusIndex;\n\t },\n\n\t _focusItem: function() {\n\t var options = this.options;\n\t var listView = this.listView;\n\t var focusedItem = listView.focus();\n\t var index = listView.select();\n\n\t index = index[index.length - 1];\n\n\t if (index === undefined && options.highlightFirst && !focusedItem) {\n\t index = 0;\n\t }\n\n\t if (index !== undefined) {\n\t listView.focus(index);\n\t } else {\n\t if (options.optionLabel && (!options.virtual || options.virtual.mapValueTo !== \"dataItem\")) {\n\t this._focus(this.optionLabel);\n\t this._select(this.optionLabel);\n\t this.listView.content.scrollTop(0);\n\t } else {\n\t listView.scrollToIndex(0);\n\t }\n\t }\n\t },\n\n\t _resetOptionLabel: function(additionalClass) {\n\t this.optionLabel.removeClass(\"k-state-focused\" + (additionalClass || \"\")).removeAttr(\"id\");\n\t },\n\n\t _focus: function(candidate) {\n\t var listView = this.listView;\n\t var optionLabel = this.optionLabel;\n\n\t if (candidate === undefined) {\n\t candidate = listView.focus();\n\n\t if (!candidate && optionLabel.hasClass(\"k-state-focused\")) {\n\t candidate = optionLabel;\n\t }\n\n\t return candidate;\n\t }\n\n\t this._resetOptionLabel();\n\n\t candidate = this._get(candidate);\n\n\t listView.focus(candidate);\n\n\t if (candidate === -1) {\n\t optionLabel.addClass(\"k-state-focused\")\n\t .attr(\"id\", listView._optionID);\n\n\t this._focused.add(this.filterInput)\n\t .removeAttr(\"aria-activedescendant\")\n\t .attr(\"aria-activedescendant\", listView._optionID);\n\t }\n\t },\n\n\t _select: function(candidate, keepState) {\n\t var that = this;\n\n\t candidate = that._get(candidate);\n\n\t return that.listView.select(candidate).done(function() {\n\t if (!keepState && that._state === STATE_FILTER) {\n\t that._state = STATE_ACCEPT;\n\t }\n\n\t if (candidate === -1) {\n\t that._selectValue(null);\n\t }\n\t });\n\t },\n\n\t _selectValue: function(dataItem) {\n\t var that = this;\n\t var optionLabel = that.options.optionLabel;\n\t var idx = that.listView.select();\n\n\t var value = \"\";\n\t var text = \"\";\n\n\t idx = idx[idx.length - 1];\n\t if (idx === undefined) {\n\t idx = -1;\n\t }\n\n\t this._resetOptionLabel(\" k-state-selected\");\n\n\t if (dataItem || dataItem === 0) {\n\t text = dataItem;\n\t value = that._dataValue(dataItem);\n\t if (optionLabel) {\n\t idx += 1;\n\t }\n\t } else if (optionLabel) {\n\t that._focus(that.optionLabel.addClass(\"k-state-selected\"));\n\n\t text = that._optionLabelText();\n\n\t if (typeof optionLabel === \"string\") {\n\t value = \"\";\n\t } else {\n\t value = that._value(optionLabel);\n\t }\n\n\t idx = 0;\n\t }\n\n\t that.selectedIndex = idx;\n\n\t if (value === null) {\n\t value = \"\";\n\t }\n\n\t that._textAccessor(text);\n\t that._accessor(value, idx);\n\n\t that._triggerCascade();\n\t },\n\n\t _mobile: function() {\n\t var that = this,\n\t popup = that.popup,\n\t mobileOS = support.mobileOS,\n\t root = popup.element.parents(\".km-root\").eq(0);\n\n\t if (root.length && mobileOS) {\n\t popup.options.animation.open.effects = (mobileOS.android || mobileOS.meego) ? \"fadeIn\" : (mobileOS.ios || mobileOS.wp) ? \"slideIn:up\" : popup.options.animation.open.effects;\n\t }\n\t },\n\n\t _filterHeader: function() {\n\t var icon;\n\n\t if (this.filterInput) {\n\t this.filterInput\n\t .off(ns)\n\t .parent()\n\t .remove();\n\n\t this.filterInput = null;\n\t }\n\n\t if (this._isFilterEnabled()) {\n\t icon = '';\n\n\t this.filterInput = $('')\n\t .attr({\n\t placeholder: this.element.attr(\"placeholder\"),\n\t title: this.element.attr(\"title\"),\n\t role: \"listbox\",\n\t \"aria-haspopup\": true,\n\t \"aria-expanded\": false\n\t });\n\t this.list\n\t .prepend($('')\n\t .append(this.filterInput.add(icon)));\n\t }\n\t },\n\n\t _span: function() {\n\t var that = this,\n\t wrapper = that.wrapper,\n\t SELECTOR = \"span.k-input\",\n\t span;\n\n\t span = wrapper.find(SELECTOR);\n\n\t if (!span[0]) {\n\t wrapper.append(' ')\n\t .append(that.element);\n\n\t span = wrapper.find(SELECTOR);\n\t }\n\n\t that.span = span;\n\t that._inputWrapper = $(wrapper[0].firstChild);\n\t that._arrow = wrapper.find(\".k-select\");\n\t that._arrowIcon = that._arrow.find(\".k-icon\");\n\t },\n\n\t _wrapper: function() {\n\t var that = this,\n\t element = that.element,\n\t DOMelement = element[0],\n\t wrapper;\n\n\t wrapper = element.parent();\n\n\t if (!wrapper.is(\"span.k-widget\")) {\n\t wrapper = element.wrap(\"\").parent();\n\t wrapper[0].style.cssText = DOMelement.style.cssText;\n\t wrapper[0].title = DOMelement.title;\n\t }\n\n\t that._focused = that.wrapper = wrapper\n\t .addClass(\"k-widget k-dropdown\")\n\t .addClass(DOMelement.className)\n\t .removeClass('input-validation-error')\n\t .css(\"display\", \"\")\n\t .attr({\n\t accesskey: element.attr(\"accesskey\"),\n\t unselectable: \"on\",\n\t role: \"listbox\",\n\t \"aria-haspopup\": true,\n\t \"aria-expanded\": false\n\t });\n\n\t element.hide().removeAttr(\"accesskey\");\n\t },\n\n\t _clearSelection: function(parent) {\n\t this.select(parent.value() ? 0 : -1);\n\t },\n\n\t _inputTemplate: function() {\n\t var that = this,\n\t template = that.options.valueTemplate;\n\n\n\t if (!template) {\n\t template = $.proxy(kendo.template('#:this._text(data)#', { useWithBlock: false }), that);\n\t } else {\n\t template = kendo.template(template);\n\t }\n\n\t that.valueTemplate = template;\n\n\t if (that.hasOptionLabel() && !that.options.optionLabelTemplate) {\n\t try {\n\t that.valueTemplate(that._optionLabelDataItem());\n\t } catch(e) {\n\t throw new Error(MSG_INVALID_OPTION_LABEL);\n\t }\n\t }\n\t },\n\n\t _textAccessor: function(text) {\n\t var dataItem = null;\n\t var template = this.valueTemplate;\n\t var optionLabelText = this._optionLabelText();\n\t var span = this.span;\n\n\t if (text === undefined) {\n\t return span.text();\n\t }\n\n\t if ($.isPlainObject(text) || text instanceof ObservableObject) {\n\t dataItem = text;\n\t } else if (optionLabelText && optionLabelText === text) {\n\t dataItem = this.options.optionLabel;\n\t }\n\n\t if (!dataItem) {\n\t dataItem = this._assignInstance(text, this._accessor());\n\t }\n\n\t if (this.hasOptionLabel()) {\n\t if (dataItem === optionLabelText || this._text(dataItem) === optionLabelText) {\n\t template = this.optionLabelTemplate;\n\n\t if (typeof this.options.optionLabel === \"string\" && !this.options.optionLabelTemplate) {\n\t dataItem = optionLabelText;\n\t }\n\t }\n\t }\n\n\t var getElements = function(){\n\t return {\n\t elements: span.get(),\n\t data: [ { dataItem: dataItem } ]\n\t };\n\t };\n\n\t this.angular(\"cleanup\", getElements);\n\n\t try {\n\t span.html(template(dataItem));\n\t } catch(e) {\n\t //dataItem has missing fields required in custom template\n\t span.html(\"\");\n\t }\n\n\t this.angular(\"compile\", getElements);\n\t },\n\n\t _preselect: function(value, text) {\n\t if (!value && !text) {\n\t text = this._optionLabelText();\n\t }\n\n\t this._accessor(value);\n\t this._textAccessor(text);\n\n\t this._old = this._accessor();\n\t this._oldIndex = this.selectedIndex;\n\n\t this.listView.setValue(value);\n\n\t this._initialIndex = null;\n\t this._presetValue = true;\n\t },\n\n\t _assignInstance: function(text, value) {\n\t var dataTextField = this.options.dataTextField;\n\t var dataItem = {};\n\n\t if (dataTextField) {\n\t assign(dataItem, dataTextField.split(\".\"), text);\n\t assign(dataItem, this.options.dataValueField.split(\".\"), value);\n\t dataItem = new ObservableObject(dataItem);\n\t } else {\n\t dataItem = text;\n\t }\n\n\t return dataItem;\n\t }\n\t });\n\n\t function assign(instance, fields, value) {\n\t var idx = 0,\n\t lastIndex = fields.length - 1,\n\t field;\n\n\t for (; idx < lastIndex; ++idx) {\n\t field = fields[idx];\n\n\t if (!(field in instance)) {\n\t instance[field] = {};\n\t }\n\n\t instance = instance[field];\n\t }\n\n\t instance[fields[lastIndex]] = value;\n\t }\n\n\t function normalizeIndex(index, length) {\n\t if (index >= length) {\n\t index -= length;\n\t }\n\t return index;\n\t }\n\n\t function sameCharsOnly(word, character) {\n\t for (var idx = 0; idx < word.length; idx++) {\n\t if (word.charAt(idx) !== character) {\n\t return false;\n\t }\n\t }\n\t return true;\n\t }\n\n\t ui.plugin(DropDownList);\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1152);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1054:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.popup\");\n\n/***/ }),\n\n/***/ 1152:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1153), __webpack_require__(1054) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"dropdowntree\",\n\t name: \"DropDownTree\",\n\t category: \"web\",\n\t description: \"The DropDownTree widget displays a hierarchy of items and allows the selection of single or multiple items.\",\n\t depends: [ \"treeview\", \"popup\" ]\n\t};\n\n\t(function($, undefined) {\n\t var kendo = window.kendo,\n\t ui = kendo.ui,\n\t Widget = ui.Widget,\n\t TreeView = ui._dropdowntree,\n\t ObservableArray = kendo.data.ObservableArray,\n\t ObservableObject = kendo.data.ObservableObject,\n\t extend = $.extend,\n\t activeElement = kendo._activeElement,\n\t ns = \".kendoDropDownTree\",\n\t keys = kendo.keys,\n\t support = kendo.support,\n\t HIDDENCLASS = \"k-hidden\",\n\t WIDTH = \"width\",\n\t browser = support.browser,\n\t outerWidth = kendo._outerWidth,\n\t DOT = \".\",\n\t DISABLED = \"disabled\",\n\t READONLY = \"readonly\",\n\t STATEDISABLED = \"k-state-disabled\",\n\t ARIA_DISABLED = \"aria-disabled\",\n\t HOVER = \"k-state-hover\",\n\t FOCUSED = \"k-state-focused\",\n\t HOVEREVENTS = \"mouseenter\" + ns + \" mouseleave\" + ns,\n\t TABINDEX = \"tabindex\",\n\t CLICK = \"click\",\n\t OPEN = \"open\",\n\t CLOSE = \"close\",\n\t CHANGE = \"change\",\n\t quotRegExp = /\"/g,\n\t proxy = $.proxy;\n\n\t var DropDownTree = kendo.ui.Widget.extend( {\n\t init: function(element, options) {\n\t this.ns = ns;\n\n\t kendo.ui.Widget.fn.init.call(this, element, options);\n\t this._selection = this._getSelection();\n\t this._focusInputHandler = $.proxy(this._focusInput, this);\n\t this._initial = this.element.val();\n\n\t this._values = [];\n\n\t var value = this.options.value;\n\n\t if (value === null || !value.length) {\n\t this._noInitialValue = true;\n\t }\n\n\t if (!this._isNullorUndefined(value)) {\n\t this._valueMethodCalled = true;\n\t this._values = $.isArray(value) ? value.slice(0) : [value];\n\t }\n\n\t this._inputTemplate();\n\n\t this._accessors();\n\t this._setTreeViewOptions(this.options);\n\t this._dataSource();\n\t this._selection._initWrapper();\n\t this._placeholder(true);\n\t this._tabindex();\n\t this.wrapper.data(TABINDEX, this.wrapper.attr(TABINDEX));\n\n\t this.tree = $('
    ')\n\t .attr({\n\t tabIndex: -1,\n\t \"aria-hidden\": true\n\t });\n\n\t this.list = $(\"
    \")\n\t .append(this.tree);\n\n\t this._header();\n\t this._noData();\n\t this._footer();\n\t this._reset();\n\t this._popup();\n\t this.popup.one(\"open\", proxy(this._popupOpen, this));\n\t this._clearButton();\n\t this._filterHeader();\n\t this._treeview();\n\n\t this._renderFooter();\n\n\t this._checkAll();\n\t this._enable();\n\t this._toggleCloseVisibility();\n\n\t if (!this.options.autoBind) {\n\t var text = options.text || \"\";\n\t if (!this._isNullorUndefined(options.value)) {\n\t this._preselect(options.value);\n\t } else if (text) {\n\t this._textAccessor(text);\n\t } else if (options.placeholder) {\n\t this._placeholder(true);\n\t }\n\t }\n\n\t var disabled = $(this.element).parents(\"fieldset\").is(':disabled');\n\n\t if (disabled) {\n\t this.enable(false);\n\t }\n\t this._valueMethodCalled = false;\n\t kendo.notify(this);\n\t },\n\n\t _preselect: function(data, value){\n\t this._selection._preselect(data, value);\n\t },\n\n\t _setTreeViewOptions: function(options) {\n\t var treeviewOptions = {\n\t autoBind: options.autoBind,\n\t checkboxes: options.checkboxes,\n\t dataImageUrlField: options.dataImageUrlField,\n\t dataSpriteCssClassField: options.dataSpriteCssClassField,\n\t dataTextField: options.dataTextField,\n\t dataUrlField: options.dataUrlField,\n\t loadOnDemand: options.loadOnDemand\n\t };\n\n\t this.options.treeview = $.extend({}, treeviewOptions, this.options.treeview);\n\n\t if (options.template) {\n\t this.options.treeview.template = options.template;\n\t }\n\t },\n\n\t _dataSource: function() {\n\t var rootDataSource = this.options.dataSource;\n\n\t this.dataSource = kendo.data.HierarchicalDataSource.create(rootDataSource);\n\t if (rootDataSource) {\n\t $.extend(this.options.treeview,{\n\t dataSource: this.dataSource\n\t });\n\t }\n\t },\n\n\t _popupOpen: function() {\n\t var popup = this.popup;\n\t popup.wrapper = kendo.wrap(popup.element);\n\t },\n\n\t _getSelection: function() {\n\t if (this._isMultipleSelection()) {\n\t return new ui.DropDownTree.MultipleSelection(this);\n\t } else {\n\t return new ui.DropDownTree.SingleSelection(this);\n\t }\n\t },\n\n\t setDataSource: function(dataSource) {\n\t this._isDataSourceSet = true;\n\t if(this._tags){\n\t this._noInitialValue = true;\n\t this.setValue([]);\n\t this._tags.empty();\n\t this.span.show();\n\t this._multipleTags.empty();\n\t }\n\t this.dataSource = dataSource;\n\t this.treeview.setDataSource(dataSource);\n\t this._isDataSourceSet = false;\n\t },\n\n\t _isMultipleSelection: function() {\n\t return this.options && (this.options.treeview.checkboxes || this.options.checkboxes);\n\t },\n\n\t options: {\n\t name: \"DropDownTree\",\n\t animation: {},\n\t autoBind: true,\n\t autoClose: true,\n\t autoWidth: false,\n\t clearButton: true,\n\t dataTextField: \"\",\n\t dataValueField: \"\",\n\t dataImageUrlField: \"\",\n\t dataSpriteCssClassField: \"\",\n\t dataUrlField: \"\",\n\t delay: 500,\n\t enabled: true,\n\t enforceMinLength: false,\n\t filter: \"none\",\n\t height: 200,\n\t ignoreCase: true,\n\t index: 0,\n\t loadOnDemand: false,\n\t messages: {\n\t \"singleTag\": \"item(s) selected\",\n\t \"clear\": \"clear\",\n\t \"deleteTag\": \"delete\",\n\t \"noData\": \"No data found.\"\n\t },\n\t minLength: 1,\n\t checkboxes: false,\n\t noDataTemplate: true,\n\t placeholder: \"\",\n\t checkAll:false,\n\t checkAllTemplate: \"Check all\",\n\t tagMode: \"multiple\",\n\t template: null,\n\t text: null,\n\t treeview: {},\n\t valuePrimitive: false,\n\t footerTemplate: \"\",\n\t headerTemplate: \"\",\n\t value: null,\n\t valueTemplate: null,\n\t popup: null\n\t },\n\n\t events: [\n\t \"open\",\n\t \"close\",\n\t \"dataBound\",\n\t CHANGE,\n\t \"select\",\n\t \"filtering\"\n\t ],\n\n\t focus: function() {\n\t this.wrapper.focus();\n\t },\n\n\t dataItem: function (node){\n\t return this.treeview.dataItem(node);\n\t },\n\n\t readonly: function(readonly) {\n\t this._editable({\n\t readonly: readonly === undefined ? true : readonly,\n\t disable: false\n\t });\n\t this._toggleCloseVisibility();\n\t },\n\n\t enable: function(enable) {\n\t this._editable({\n\t readonly: false,\n\t disable: !(enable = enable === undefined ? true : enable)\n\t });\n\t this._toggleCloseVisibility();\n\t },\n\n\t toggle: function(open) {\n\t this._toggle(open);\n\t },\n\n\t open: function() {\n\t var popup = this.popup;\n\n\t if(!this.options.autoBind && !this.dataSource.data().length){\n\t this.treeview._progress(true);\n\t if(this._isFilterEnabled()){\n\t this._search();\n\t } else {\n\t this.dataSource.fetch();\n\t }\n\t }\n\n\t if (popup.visible() || !this._allowOpening()) {\n\t return;\n\t }\n\n\t if(this._isMultipleSelection()){\n\t popup.element.addClass(\"k-multiple-selection\");\n\t }\n\t popup.element.addClass(\"k-popup-dropdowntree\");\n\n\t popup.one(\"activate\", this._focusInputHandler);\n\t popup._hovered = true;\n\t popup.open();\n\t },\n\n\t close: function() {\n\t this.popup.close();\n\t },\n\n\t search: function(word) {\n\t var options = this.options;\n\t var filter;\n\t clearTimeout(this._typingTimeout);\n\n\t if ((!options.enforceMinLength && !word.length) || word.length >= options.minLength) {\n\t filter = this._getFilter(word);\n\t if(this.trigger(\"filtering\", { filter: filter }) ||\n\t $.isArray(this.options.dataTextField)){\n\t return;\n\t }\n\n\t this._filtering = true;\n\t this.treeview.dataSource.filter(filter);\n\t }\n\t },\n\n\t _getFilter: function (word){\n\t return {\n\t field: this.options.dataTextField,\n\t operator: this.options.filter,\n\t value: word,\n\t ignoreCase: this.options.ignoreCase\n\t };\n\t },\n\n\t refresh: function() {\n\t var data = this.treeview.dataSource.flatView();\n\t this._renderFooter();\n\t this._renderNoData();\n\t if (this.filterInput && this.checkAll) {\n\t this.checkAll.toggle(!this.filterInput.val().length);\n\t }\n\n\t this.tree.toggle(!!data.length);\n\t $(this.noData).toggle(!data.length);\n\t },\n\n\t setOptions: function(options) {\n\t Widget.fn.setOptions.call(this, options);\n\n\t this._setTreeViewOptions(options);\n\t this._dataSource();\n\t if (this.options.treeview) {\n\t this.treeview.setOptions(this.options.treeview);\n\t }\n\n\t if (options.height && this.tree) {\n\t this.tree.css('max-height', options.height);\n\t }\n\n\t this._header();\n\t this._noData();\n\t this._footer();\n\n\t this._renderFooter();\n\t this._renderNoData();\n\t if (this.span && (this._isMultipleSelection() || this.span.hasClass(\"k-readonly\"))) {\n\t this._placeholder(true);\n\t }\n\t this._inputTemplate();\n\t this._accessors();\n\t this._filterHeader();\n\t this._checkAll();\n\t this._enable();\n\t if (options && (options.enable || options.enabled)) {\n\t this.enable(true);\n\t }\n\t this._clearButton();\n\t },\n\n\t destroy: function() {\n\t kendo.ui.Widget.fn.destroy.call(this);\n\t if(this.treeview){\n\t this.treeview.destroy();\n\t }\n\t this.popup.destroy();\n\n\t this.wrapper.off(ns);\n\t this._clear.off(ns);\n\t this._inputWrapper.off(ns);\n\t if (this.filterInput) {\n\t this.filterInput.off(ns);\n\t }\n\n\t if(this.tagList){\n\t this.tagList.off(ns);\n\t }\n\n\t kendo.unbind(this.tagList);\n\t if (this.options.checkAll && this.checkAll) {\n\t this.checkAll.off(ns);\n\t }\n\n\t if (this._form) {\n\t this._form.off(\"reset\", this._resetHandler);\n\t }\n\t },\n\n\t setValue: function(value) {\n\t value = $.isArray(value) || value instanceof ObservableArray ? value.slice(0) : [value];\n\n\t this._values = value;\n\t },\n\n\t items: function() {\n\t return this.treeview.items();\n\t },\n\n\t value: function(value) {\n\t var that = this;\n\n\t if(value){\n\t if(that.filterInput && that.dataSource._filter){\n\t that._filtering = true;\n\t that.dataSource.filter({});\n\t } else if (!that.dataSource.data().length || !that.treeview.dataSource.data().length){\n\t that.dataSource.fetch(function() {\n\t if(that.options.loadOnDemand){\n\t that._selection._setValue(value);\n\t } else {\n\t that.one('allNodesAreLoaded', function(){\n\t that._selection._setValue(value);\n\t });\n\t }\n\t });\n\n\t return;\n\t }\n\t }\n\n\t return that._selection._setValue(value);\n\t },\n\n\t text: function(text) {\n\t var loweredText;\n\t var ignoreCase = this.options.ignoreCase;\n\n\t text = text === null ? \"\" : text;\n\n\t if (text !== undefined && !this._isMultipleSelection()) {\n\t if (typeof text !== \"string\") {\n\t this._textAccessor(text);\n\t return;\n\t }\n\n\t loweredText = ignoreCase ? text : text.toLowerCase();\n\n\t this._selectItemByText(loweredText);\n\n\t this._textAccessor(loweredText);\n\t } else {\n\t return this._textAccessor();\n\t }\n\t },\n\n\t _header: function() {\n\t var list = this;\n\t var header = $(list.header);\n\t var template = list.options.headerTemplate;\n\n\t this._angularElement(header, \"cleanup\");\n\t kendo.destroy(header);\n\t header.remove();\n\n\t if (!template) {\n\t list.header = null;\n\t return;\n\t }\n\n\t var headerTemplate = typeof template !== \"function\" ? kendo.template(template) : template;\n\t header = $(headerTemplate({}));\n\n\t list.header = header[0] ? header : null;\n\t list.list.prepend(header);\n\n\t this._angularElement(list.header, \"compile\");\n\t },\n\n\t _noData: function() {\n\t var list = this;\n\t var noData = $(list.noData);\n\t var template = list.options.noDataTemplate === true ? list.options.messages.noData : list.options.noDataTemplate;\n\n\t list.angular(\"cleanup\", function() { return { elements: noData }; });\n\t kendo.destroy(noData);\n\t noData.remove();\n\n\t if (!template) {\n\t list.noData = null;\n\t return;\n\t }\n\n\t list.noData = $('
    ').appendTo(list.list);\n\t list.noDataTemplate = typeof template !== \"function\" ? kendo.template(template) : template;\n\t },\n\n\t _renderNoData: function() {\n\t var list = this;\n\t var noData = list.noData;\n\n\t if (!noData) {\n\t return;\n\t }\n\n\t this._angularElement(noData, \"cleanup\");\n\t noData.children(\":first\").html(list.noDataTemplate({ instance: list }));\n\t this._angularElement(noData, \"compile\");\n\t },\n\n\t _footer: function() {\n\t var list = this;\n\t var footer = $(list.footer);\n\t var template = list.options.footerTemplate;\n\n\t this._angularElement(footer, \"cleanup\");\n\t kendo.destroy(footer);\n\t footer.remove();\n\n\t if (!template) {\n\t list.footer = null;\n\t return;\n\t }\n\n\t list.footer = $('
    ').appendTo(list.list);\n\t list.footerTemplate = typeof template !== \"function\" ? kendo.template(template) : template;\n\t },\n\n\t _renderFooter: function() {\n\t var list = this;\n\t var footer = list.footer;\n\n\t if (!footer) {\n\t return;\n\t }\n\n\t this._angularElement(footer, \"cleanup\");\n\t footer.html(list.footerTemplate({ instance: list }));\n\t this._angularElement(footer, \"compile\");\n\t },\n\n\t _enable: function() {\n\t var that = this,\n\t options = that.options,\n\t disabled = that.element.is(\"[disabled]\");\n\n\t if (options.enable !== undefined) {\n\t options.enabled = options.enable;\n\t }\n\n\t if (!options.enabled || disabled) {\n\t that.enable(false);\n\t } else {\n\t that.readonly(that.element.is(\"[readonly]\"));\n\t }\n\t },\n\n\t _adjustListWidth: function() {\n\t var that = this,\n\t list = that.list,\n\t width = list[0].style.width,\n\t wrapper = that.wrapper,\n\t computedStyle, computedWidth;\n\n\t if (!list.data(WIDTH) && width) {\n\t return;\n\t }\n\n\t computedStyle = window.getComputedStyle ? window.getComputedStyle(wrapper[0], null) : 0;\n\t computedWidth = parseFloat(computedStyle && computedStyle.width) || outerWidth(wrapper);\n\n\t if (computedStyle && browser.msie) { // getComputedStyle returns different box in IE.\n\t computedWidth += parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight) + parseFloat(computedStyle.borderLeftWidth) + parseFloat(computedStyle.borderRightWidth);\n\t }\n\n\t if (list.css(\"box-sizing\") !== \"border-box\") {\n\t width = computedWidth - (outerWidth(list) - list.width());\n\t } else {\n\t width = computedWidth;\n\t }\n\n\t list.css({\n\t fontFamily: wrapper.css(\"font-family\"),\n\t width: that.options.autoWidth ? \"auto\" : width,\n\t minWidth: width,\n\t whiteSpace: that.options.autoWidth ? \"nowrap\" : \"normal\"\n\t })\n\t .data(WIDTH, width);\n\n\t return true;\n\t },\n\n\t _reset: function() {\n\t var that = this,\n\t element = that.element,\n\t formId = element.attr(\"form\"),\n\t form = formId ? $(\"#\" + formId) : element.closest(\"form\");\n\n\t if (form[0]) {\n\t that._resetHandler = function() {\n\t setTimeout(function() {\n\t that.value(that._initial);\n\t });\n\t };\n\n\t that._form = form.on(\"reset\", that._resetHandler);\n\t }\n\t },\n\n\t _popup: function() {\n\t var list = this;\n\n\t list.popup = new ui.Popup(list.list, extend({}, list.options.popup, {\n\t anchor: list.wrapper,\n\t open: proxy(list._openHandler, list),\n\t close: proxy(list._closeHandler, list),\n\t animation: list.options.animation,\n\t isRtl: support.isRtl(list.wrapper),\n\t autosize :list.options.autoWidth\n\t }));\n\t },\n\n\t _angularElement: function(element, action) {\n\t if (!element) {\n\t return;\n\t }\n\n\t this.angular(action, function() {\n\t return { elements: element };\n\t });\n\t },\n\n\t _allowOpening: function() {\n\t return this.options.noDataTemplate || this.treeview.dataSource.flatView().length;\n\t },\n\n\t _placeholder: function(show) {\n\t if (this.span) {\n\t this.span.toggleClass(\"k-readonly\", show).text(show? this.options.placeholder: \"\");\n\t }\n\t },\n\n\t _currentValue: function(dataItem) {\n\t var currentValue = this._value(dataItem);\n\t if (!currentValue && currentValue !== 0) {\n\t currentValue = dataItem;\n\t }\n\n\t return currentValue;\n\t },\n\n\t _checkValue: function(dataItem) {\n\t var value = \"\";\n\t var indexOfValue = -1;\n\t var currentValue = this.value();\n\t var isMultiple = this.options.tagMode === \"multiple\";\n\n\t if (dataItem || dataItem === 0) {\n\t if(dataItem.level){\n\t dataItem._level = dataItem.level();\n\t }\n\n\t value = this._currentValue(dataItem);\n\n\t indexOfValue = currentValue.indexOf(value);\n\t }\n\n\t if (dataItem.checked) {\n\t var alreadyAddedTag = $.grep(this._tags, function( item ) {\n\t return item.uid === dataItem._tagUid;\n\t });\n\n\t if (alreadyAddedTag.length){\n\t return;\n\t }\n\n\t var itemToAdd = new ObservableObject(dataItem.toJSON());\n\t dataItem._tagUid = itemToAdd.uid;\n\t this._tags.push(itemToAdd);\n\n\t if (this._tags.length === 1) {\n\t this.span.hide();\n\n\t if (!isMultiple) {\n\t this._multipleTags.push(itemToAdd);\n\t }\n\t }\n\n\t if (indexOfValue === -1) {\n\t currentValue.push(value);\n\t this.setValue(currentValue);\n\t }\n\t } else {\n\t var itemToRemove = this._tags.find(function(item){\n\t return item.uid === dataItem._tagUid;\n\t });\n\n\t var idx = this._tags.indexOf(itemToRemove);\n\n\t if (idx !== -1) {\n\t this._tags.splice(idx, 1);\n\t } else {\n\t this._treeViewCheckAllCheck(dataItem);\n\t return;\n\t }\n\n\t if (this._tags.length === 0) {\n\t this.span.show();\n\t if (!isMultiple) {\n\t this._multipleTags.splice(0, 1);\n\t }\n\t }\n\t if (indexOfValue !== -1) {\n\t currentValue.splice(indexOfValue, 1);\n\t this.setValue(currentValue);\n\t }\n\t }\n\n\t this._treeViewCheckAllCheck(dataItem);\n\t if (!this._preventChangeTrigger && !this._valueMethodCalled && !this._noInitialValue) {\n\t this.trigger(CHANGE);\n\t }\n\n\t if (this.options.autoClose && this.popup.visible()) {\n\t this.close();\n\t this.wrapper.focus();\n\t }\n\t this.popup.position();\n\t this._toggleCloseVisibility();\n\t this._updateSelectedOptions();\n\t },\n\n\t _updateSelectedOptions: function(){\n\t if(this.element[0].tagName.toLowerCase() !== 'select'){\n\t return;\n\t }\n\n\t var selectedItems = this._tags;\n\t var options = '';\n\t var dataItem = null;\n\t var value = null;\n\n\t if (selectedItems.length) {\n\t for (var idx = 0; idx < selectedItems.length; idx++) {\n\t dataItem = selectedItems[idx];\n\n\t value = this._value(dataItem);\n\t options += this._option(value, this._text(dataItem), true);\n\t }\n\t }\n\n\t this.element.html(options);\n\t },\n\n\t _option: function(dataValue, dataText, selected) {\n\t var option = \"\";\n\n\t if (dataText !== undefined) {\n\t option += kendo.htmlEncode(dataText);\n\t }\n\n\t return option += \"\";\n\t },\n\n\t _selectValue: function(dataItem) {\n\t var value = \"\";\n\t var text = \"\";\n\n\t if (dataItem || dataItem === 0) {\n\t if(dataItem.level){\n\t dataItem._level = dataItem.level();\n\t }\n\t text = this._text(dataItem) || dataItem;\n\t value = this._currentValue(dataItem);\n\t }\n\n\t if (value === null) {\n\t value = \"\";\n\t }\n\t this.setValue(value);\n\t this._textAccessor(text, dataItem);\n\t this._accessor(value);\n\n\t if(!this._preventChangeTrigger && !this._valueMethodCalled){\n\t this.trigger(CHANGE);\n\t }\n\t this._valueMethodCalled = false;\n\n\t if (this.options.autoClose && this.popup.visible()) {\n\t this.close();\n\t this.wrapper.focus();\n\t }\n\t this.popup.position();\n\t this._toggleCloseVisibility();\n\t },\n\n\t _clearClick: function(e) {\n\t e.stopPropagation();\n\t this.wrapper.focus();\n\t this._clearTextAndValue();\n\t },\n\n\t _clearTextAndValue: function() {\n\t this.setValue([]);\n\t this._clearInput();\n\t this._clearText();\n\t this._selection._clearValue();\n\t this.popup.position();\n\t this._toggleCloseVisibility();\n\t },\n\n\t _clearText: function() {\n\t if (this.options.placeholder) {\n\t this._placeholder(true);\n\t } else {\n\t if (this.span) {\n\t this.span.html(\"\");\n\t }\n\t }\n\t },\n\n\t _inputTemplate: function() {\n\t var template = this.options.valueTemplate;\n\n\t if (!template) {\n\t template = $.proxy(kendo.template('#:this._text(data)#', { useWithBlock: false }), this);\n\t } else {\n\t template = kendo.template(template);\n\t }\n\n\t this.valueTemplate = template;\n\t },\n\n\t _assignInstance: function(text, value) {\n\t var dataTextField = this.options.dataTextField;\n\t var dataItem = {};\n\n\t if (dataTextField) {\n\t assign(dataItem, dataTextField.split(DOT), text);\n\t assign(dataItem, this.options.dataValueField.split(DOT), value);\n\t dataItem = new ObservableObject(dataItem);\n\t } else {\n\t dataItem = text;\n\t }\n\n\t return dataItem;\n\t },\n\n\t _textAccessor: function(text, dataItem) {\n\t var valueTemplate = this.valueTemplate;\n\t var span = this.span;\n\n\t if (text === undefined) {\n\t return span.text();\n\t }\n\n\t span.removeClass(\"k-readonly\");\n\n\t if (!dataItem && ($.isPlainObject(text) || text instanceof ObservableObject)) {\n\t dataItem = text;\n\t }\n\n\t if (!dataItem) {\n\t dataItem = this._assignInstance(text, this._accessor());\n\t }\n\n\t var getElements = function() {\n\t return {\n\t elements: span.get(),\n\t data: [ { dataItem: dataItem } ]\n\t };\n\t };\n\n\t this.angular(\"cleanup\", getElements);\n\n\t try {\n\t span.html(valueTemplate(dataItem));\n\t } catch(e) {\n\t //dataItem has missing fields required in custom template\n\t if (span) {\n\t span.html(\"\");\n\t }\n\t }\n\n\t this.angular(\"compile\", getElements);\n\t },\n\n\t _accessors: function() {\n\t var element = this.element;\n\t var options = this.options;\n\t var getter = kendo.getter;\n\t var textField = element.attr(kendo.attr(\"text-field\"));\n\t var valueField = element.attr(kendo.attr(\"value-field\"));\n\n\t var getterFunction = function (field) {\n\t if ($.isArray(field)) {\n\t var count = field.length;\n\t var levels = $.map(field, function(x) {\n\t return function(d){ return d[x];};\n\t });\n\n\t return function (dataItem) {\n\t var level = dataItem._level;\n\n\t if(!level && level !== 0){\n\t return;\n\t }\n\n\t return levels[Math.min(level, count-1)](dataItem);\n\t };\n\t } else {\n\t return getter(field);\n\t }\n\t };\n\n\t if (!options.dataTextField && textField) {\n\t options.dataTextField = textField;\n\t }\n\n\t if (!options.dataValueField && valueField) {\n\t options.dataValueField = valueField;\n\t }\n\n\t options.dataTextField = options.dataTextField || \"text\";\n\t options.dataValueField = options.dataValueField || \"value\";\n\n\t this._text = getterFunction(options.dataTextField);\n\t this._value = getterFunction(options.dataValueField);\n\t },\n\n\t _accessor: function(value, idx) {\n\t return this._accessorInput(value, idx);\n\t },\n\n\t _accessorInput: function(value) {\n\t var element = this.element[0];\n\n\t if (value === undefined) {\n\t return element.value;\n\t } else {\n\t if (value === null) {\n\t value = \"\";\n\t }\n\t element.value = value;\n\t }\n\t },\n\n\t _clearInput: function() {\n\t var element = this.element[0];\n\t element.value = \"\";\n\t },\n\n\t _clearButton: function() {\n\t var clearTitle = this.options.messages.clear;\n\n\t if(!this._clear){\n\t this._clear = $('').attr({\n\t \"role\": \"button\",\n\t \"tabIndex\": -1\n\t });\n\t }\n\n\t if (this.options.clearButton) {\n\t this._clear.insertAfter(this.span);\n\t this.wrapper.addClass(\"k-dropdowntree-clearable\");\n\t } else {\n\t if (!this.options.clearButton) {\n\t this._clear.remove();\n\t }\n\t }\n\t },\n\n\t _toggleCloseVisibility: function() {\n\t var isReadOnly = this.element.attr(READONLY);\n\t var hasValue = (this.value() && !this._isMultipleSelection()) || this.value().length;\n\t var valueDoesNotEqualPlaceHolder = this.element.val() && this.element.val() !== this.options.placeholder;\n\n\t if ((!isReadOnly && (hasValue || valueDoesNotEqualPlaceHolder))) {\n\t this._showClear();\n\t } else {\n\t this._hideClear();\n\t }\n\t },\n\n\t _showClear: function() {\n\t if(this._clear) {\n\t this._clear.removeClass(HIDDENCLASS);\n\t }\n\t },\n\n\t _hideClear: function() {\n\t if(this._clear) {\n\t this._clear.addClass(HIDDENCLASS);\n\t }\n\t },\n\n\t _openHandler: function(e) {\n\t this._adjustListWidth();\n\n\t if (this.trigger(OPEN)) {\n\t e.preventDefault();\n\t } else {\n\t this.wrapper.attr(\"aria-expanded\", true);\n\t this.tree.attr(\"aria-hidden\", false).attr(\"role\", \"tree\");\n\t }\n\t },\n\n\t _closeHandler: function(e) {\n\t if (this.trigger(CLOSE)) {\n\t e.preventDefault();\n\t } else {\n\t this.wrapper.attr(\"aria-expanded\", false);\n\t this.tree.attr(\"aria-hidden\", true);\n\t }\n\t },\n\n\t _treeview: function() {\n\t var that = this;\n\t if (that.options.height) {\n\t that.tree.css('max-height',that.options.height);\n\t }\n\t that.tree.attr('id', kendo.guid());\n\t that.treeview = new TreeView(that.tree, extend({}, that.options.treeview), that);\n\t that.dataSource = that.treeview.dataSource;\n\n\t that.treeview.bind(\"select\",function(e) {\n\t that.trigger(\"select\", e);\n\t });\n\t },\n\n\t _treeViewDataBound: function(e) {\n\t if (e.node && this._prev && this._prev.length) {\n\t e.sender.expand(e.node);\n\t }\n\n\t if(this._filtering){\n\t if(!e.node){\n\t this._filtering = false;\n\t }\n\n\t if (!this._isMultipleSelection()) {\n\t this._deselectItem(e);\n\t }\n\t return;\n\t }\n\n\t if (!this.treeview) {\n\t this.treeview = e.sender;\n\t }\n\n\t if (!e.node) {\n\t var rootItems = e.sender.dataSource.data();\n\n\t this._checkLoadedItems(rootItems);\n\t if(this._noInitialValue){\n\t this._noInitialValue = false;\n\t }\n\t } else {\n\t var rootItem = e.sender.dataItem(e.node);\n\t if (rootItem) {\n\t var subItems = rootItem.children.data();\n\t this._checkLoadedItems(subItems);\n\t }\n\t }\n\t this.trigger(\"dataBound\", e);\n\t },\n\n\t _deselectItem: function(e){\n\t var items = [];\n\t if (!e.node) {\n\t items = e.sender.dataSource.data();\n\t } else {\n\t var rootItem = e.sender.dataItem(e.node);\n\t if (rootItem) {\n\t items = rootItem.children.data();\n\t }\n\t }\n\n\t for (var i = 0; i < items.length; i++) {\n\t if (items[i].selected &&\n\t !this._valueComparer(items[i], this.value())) {\n\t items[i].set(\"selected\", false);\n\t }\n\t }\n\t },\n\n\t _checkLoadedItems: function(items) {\n\t var value = this.value();\n\n\t if(!items){\n\t return;\n\t }\n\n\t for (var idx = 0; idx < items.length; idx++) {\n\t this._selection._checkLoadedItem(items[idx], value);\n\t }\n\t },\n\n\t _treeViewCheckAllCheck: function(dataItem) {\n\t if (this.options.checkAll && this.checkAll) {\n\t this._getAllChecked();\n\n\t if (dataItem.checked) {\n\t this._checkCheckAll();\n\t } else {\n\t this._uncheckCheckAll();\n\t }\n\t }\n\t },\n\n\t _checkCheckAll: function() {\n\t var checkAllCheckbox = this.checkAll.find('.k-checkbox');\n\n\t if (this._allItemsAreChecked) {\n\t checkAllCheckbox.prop('checked', true)\n\t .prop('indeterminate', false);\n\t } else {\n\t checkAllCheckbox.prop('indeterminate', true);\n\t }\n\t },\n\n\t _uncheckCheckAll: function() {\n\t var checkAllCheckbox = this.checkAll.find('.k-checkbox');\n\n\t if (this._allItemsAreUnchecked) {\n\t checkAllCheckbox.prop('checked', false)\n\t .prop('indeterminate', false);\n\t } else {\n\t checkAllCheckbox.prop('indeterminate', true);\n\t }\n\t },\n\n\t _filterHeader: function() {\n\t var icon;\n\n\t if (this.filterInput) {\n\t this.filterInput\n\t .off(ns)\n\t .parent()\n\t .remove();\n\n\t this.filterInput = null;\n\t }\n\n\t if (this._isFilterEnabled()) {\n\t this._disableCheckChildren();\n\n\t icon = '';\n\n\t this.filterInput = $('')\n\t .attr({\n\t placeholder: this.element.attr(\"placeholder\"),\n\t title: this.element.attr(\"title\"),\n\t role: \"listbox\",\n\t \"aria-haspopup\": true,\n\t \"aria-expanded\": false\n\t });\n\n\t this.filterInput.on(\"input\" , proxy(this._filterChange, this));\n\t $('').insertBefore(this.tree)\n\t .append(this.filterInput.add(icon));\n\t }\n\t },\n\n\t _filterChange: function() {\n\t if (this.filterInput) {\n\t this._search();\n\t }\n\t },\n\n\t _disableCheckChildren: function() {\n\t if (this._isMultipleSelection() && this.options.treeview.checkboxes && this.options.treeview.checkboxes.checkChildren) {\n\t this.options.treeview.checkboxes.checkChildren = false;\n\t }\n\t },\n\n\t _checkAll: function() {\n\t if (this.checkAll) {\n\t this.checkAll.find(\".k-checkbox-label, .k-checkbox\")\n\t .off(ns);\n\t this.checkAll.remove();\n\n\t this.checkAll = null;\n\t }\n\n\t if (this._isMultipleSelection() && this.options.checkAll) {\n\t this.checkAll = $('
    Check All
    ').insertBefore(this.tree);\n\t this.checkAll.find(\".k-checkbox-label\").html(kendo.template(this.options.checkAllTemplate)({ instance: this }));\n\t this.checkAll.find(\".k-checkbox-label\").on(CLICK + ns, proxy(this._clickCheckAll, this));\n\t this.checkAll.find(\".k-checkbox\")\n\t .on(\"change\" + ns, proxy(this._changeCheckAll, this))\n\t .on(\"keydown\" + ns, proxy(this._keydownCheckAll, this));\n\t this._disabledCheckedItems = [];\n\t this._disabledUnCheckedItems = [];\n\n\t this._getAllChecked();\n\n\t if (!this._allItemsAreUnchecked) {\n\t this._checkCheckAll();\n\t }\n\t }\n\t },\n\n\t _changeCheckAll: function() {\n\t var checkAllCheckbox = this.checkAll.find('.k-checkbox');\n\t var isChecked = checkAllCheckbox.prop('checked');\n\n\t this._updateCheckAll(isChecked);\n\t },\n\n\t _updateCheckAll: function(isChecked) {\n\t var checkAllCheckbox = this.checkAll.find('.k-checkbox');\n\t this._toggleCheckAllItems(isChecked);\n\t checkAllCheckbox.prop('checked', isChecked);\n\t if (this._disabledCheckedItems.length && this._disabledUnCheckedItems.length) {\n\t checkAllCheckbox.prop('indeterminate', true);\n\t } else if (this._disabledCheckedItems.length) {\n\t checkAllCheckbox.prop('indeterminate', !isChecked);\n\t } else if (this._disabledUnCheckedItems.length) {\n\t checkAllCheckbox.prop('indeterminate', isChecked);\n\t } else {\n\t checkAllCheckbox.prop('indeterminate', false);\n\t }\n\t this._disabledCheckedItems = [];\n\t this._disabledUnCheckedItems = [];\n\t },\n\n\t _keydownCheckAll: function(e) {\n\t var key = e.keyCode;\n\t var altKey = e.altKey;\n\n\t if ((altKey && key === keys.UP) || key === keys.ESC || key === keys.TAB) {\n\t this.close();\n\t this.wrapper.focus();\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if (key === keys.UP) {\n\t if (this.filterInput) {\n\t this.filterInput.focus();\n\t } else {\n\t this.wrapper.focus();\n\t }\n\n\t e.preventDefault();\n\t }\n\n\t if (key === keys.DOWN) {\n\t if (this.tree && this.tree.is(\":visible\")) {\n\t this.tree.focus();\n\t }\n\n\t e.preventDefault();\n\t }\n\n\t if (key === keys.SPACEBAR && (browser.msie || browser.edge)) {\n\t this._clickCheckAll();\n\t e.preventDefault();\n\t }\n\t },\n\n\t _clickCheckAll: function() {\n\t var checkAllCheckbox = this.checkAll.find('.k-checkbox');\n\t var isChecked = checkAllCheckbox.prop('checked');\n\n\t this._updateCheckAll(!isChecked);\n\n\t checkAllCheckbox.focus();\n\n\t },\n\t //treeview\n\t _dfs: function(items, action, prop) {\n\t for (var idx = 0; idx < items.length; idx++) {\n\t if (!this[action](items[idx], prop)) {\n\t break;\n\t }\n\t this._traverceChildren(items[idx], action, prop);\n\t }\n\t },\n\n\t _uncheckItemByUid: function(uid) {\n\t this._dfs(this.dataSource.data(), '_uncheckItemEqualsUid', uid);\n\t },\n\n\t _uncheckItemEqualsUid: function(item, uid) {\n\t if (item.enabled !== false && item._tagUid == uid) {\n\t item.set(\"checked\", false);\n\t return false;\n\t }\n\t return true;\n\t },\n\n\t _selectItemByText: function(text) {\n\t this._dfs(this.dataSource.data(), '_itemEqualsText', text);\n\t },\n\n\t _itemEqualsText: function(item, text) {\n\t if (item.enabled !== false && this._text(item) === text) {\n\t this.treeview.select(this.treeview.findByUid(item.uid));\n\t this._selectValue(item);\n\t return false;\n\t }\n\t return true;\n\t },\n\n\t _selectItemByValue: function(value) {\n\t this._dfs(this.dataSource.data(), '_itemEqualsValue', value);\n\t },\n\n\t _itemEqualsValue: function(item, value) {\n\t if (item.enabled !== false && this._valueComparer(item, value)) {\n\n\t this.treeview.select(this.treeview.findByUid(item.uid));\n\n\t return false;\n\t }\n\t return true;\n\t },\n\n\t _checkItemByValue: function(value) {\n\t var items = this.treeview.dataItems();\n\t for (var idx = 0; idx < value.length; idx++) {\n\t this._dfs(items, '_checkItemEqualsValue', value[idx]);\n\t }\n\t },\n\n\t _checkItemEqualsValue: function(item, value) {\n\t if (item.enabled !== false && this._valueComparer(item, value)) {\n\t item.set(\"checked\", true);\n\t return false;\n\t }\n\t return true;\n\t },\n\n\t _valueComparer: function(item, value) {\n\t var itemValue = this._value(item);\n\t var itemText;\n\n\t if (!this._isNullorUndefined(itemValue)) {\n\t if(this._isNullorUndefined(value)){\n\t return false;\n\t }\n\n\t var newValue = this._value(value);\n\n\t if(newValue){\n\t return itemValue == newValue;\n\t }else{\n\t return itemValue == value;\n\t }\n\t }\n\n\t itemText = this._text(item);\n\t if (itemText) {\n\t if (this._text(value)) {\n\t return itemText == this._text(value);\n\t } else {\n\t return itemText == value;\n\t }\n\t }\n\n\t return false;\n\t },\n\n\t _isNullorUndefined: function(value){\n\t return value === undefined || value === null;\n\t },\n\n\t _getAllChecked: function() {\n\t this._allCheckedItems = [];\n\t this._allItemsAreChecked = true;\n\t this._allItemsAreUnchecked = true;\n\n\t this._dfs(this.dataSource.data(), '_getAllCheckedItems');\n\n\t return this._allCheckedItems;\n\t },\n\n\t _getAllCheckedItems: function(item) {\n\t if (this._allItemsAreChecked) {\n\t this._allItemsAreChecked = item.checked;\n\t }\n\n\t if (this._allItemsAreUnchecked) {\n\t this._allItemsAreUnchecked = !item.checked;\n\t }\n\n\t if (item.checked) {\n\t this._allCheckedItems.push(item);\n\t }\n\t return true;\n\t },\n\n\t _traverceChildren: function(item, action, prop) {\n\t var childrenField = (item._childrenOptions && item._childrenOptions.schema) ? item._childrenOptions.schema.data : null;\n\t var subItems = item[childrenField] || item.items || item.children;\n\n\t if (!subItems) {\n\t return;\n\t }\n\n\t this._dfs(subItems, action, prop);\n\t },\n\n\t _toggleCheckAllItems: function(checked) {\n\t this._dfs(this.dataSource.data(), '_checkAllCheckItem', checked);\n\t },\n\n\t _checkAllCheckItem: function(item, checked) {\n\t if (item.enabled === false) {\n\t if (item.checked) {\n\t this._disabledCheckedItems.push(item);\n\t } else {\n\t this._disabledUnCheckedItems.push(item);\n\t }\n\t } else {\n\t item.set(\"checked\", checked);\n\t }\n\t return true;\n\t },\n\n\t _isFilterEnabled: function() {\n\t var filter = this.options.filter;\n\t return filter && filter !== \"none\";\n\t },\n\n\t _editable: function(options) {\n\t var that = this;\n\t var element = that.element;\n\t var disable = options.disable;\n\t var readonly = options.readonly;\n\t var wrapper = that.wrapper.add(that.filterInput).off(ns);\n\t var dropDownWrapper = that._inputWrapper.off(HOVEREVENTS);\n\t if (that._isMultipleSelection()) {\n\t that.tagList.off(CLICK + ns);\n\t }\n\t if (!readonly && !disable) {\n\t element.removeAttr(DISABLED).removeAttr(READONLY);\n\n\t dropDownWrapper\n\t .removeClass(STATEDISABLED)\n\t .on(HOVEREVENTS, that._toggleHover);\n\n\t that._clear.on(\"click\" + ns, proxy(that._clearClick, that));\n\t wrapper\n\t .attr(TABINDEX, wrapper.data(TABINDEX))\n\t .attr(ARIA_DISABLED, false)\n\t .on(\"keydown\" + ns, proxy(that._keydown, that))\n\t .on(\"focusin\" + ns, proxy(that._focusinHandler, that))\n\t .on(\"focusout\" + ns, proxy(that._focusoutHandler, that));\n\n\t that.wrapper.on(CLICK + ns, proxy(that._wrapperClick, that));\n\n\t if (this._isMultipleSelection()) {\n\t that.tagList.on(CLICK + ns, \"li.k-button\", function(e) {\n\t $(e.currentTarget).addClass(FOCUSED);\n\t });\n\n\t that.tagList.on(CLICK + ns, \".k-select\", function(e) {\n\t that._removeTagClick(e);\n\t });\n\t }\n\t } else if (disable) {\n\t wrapper.removeAttr(TABINDEX);\n\t dropDownWrapper\n\t .addClass(STATEDISABLED);\n\t } else {\n\t wrapper\n\t .attr(TABINDEX, wrapper.data(TABINDEX));\n\n\t dropDownWrapper\n\t .removeClass(STATEDISABLED);\n\n\t wrapper\n\t .on(\"focusin\" + ns, proxy(that._focusinHandler, that))\n\t .on(\"focusout\" + ns, proxy(that._focusoutHandler, that));\n\t }\n\n\t element.attr(DISABLED, disable)\n\t .attr(READONLY, readonly);\n\n\t wrapper.attr(ARIA_DISABLED, disable);\n\t },\n\n\t _focusinHandler: function() {\n\t this._inputWrapper.addClass(FOCUSED);\n\t this._prevent = false;\n\t },\n\n\t _focusoutHandler: function() {\n\t var that = this;\n\n\t if (this._isMultipleSelection()) {\n\t this.tagList.find(DOT + FOCUSED).removeClass(FOCUSED);\n\t }\n\t if (!that._prevent) {\n\t this._inputWrapper.removeClass(FOCUSED);\n\t that._prevent = true;\n\t that.element.blur();\n\t }\n\t },\n\n\t _toggle: function(open) {\n\t open = open !== undefined ? open : !this.popup.visible();\n\n\t this[open ? OPEN : CLOSE]();\n\t },\n\n\t _wrapperClick: function(e) {\n\t e.preventDefault();\n\t this.popup.unbind(\"activate\", this._focusInputHandler);\n\t this._focused = this.wrapper;\n\t this._prevent = false;\n\t this._toggle();\n\t },\n\n\t _toggleHover: function(e) {\n\t $(e.currentTarget).toggleClass(HOVER, e.type === \"mouseenter\");\n\t },\n\n\t _focusInput: function() {\n\t if (this.filterInput) {\n\t this.filterInput.focus();\n\t } else if (this.checkAll) {\n\t this.checkAll.find(\".k-checkbox\").focus();\n\t } else if (this.tree.is(\":visible\")) {\n\t this.tree.focus();\n\t }\n\t },\n\n\t _keydown: function(e) {\n\t var key = e.keyCode;\n\t var altKey = e.altKey;\n\t var isFilterInputActive;\n\t var isWrapperActive;\n\t var focused, tagItem;\n\n\t var isPopupVisible = this.popup.visible();\n\n\t if (this.filterInput) {\n\t isFilterInputActive = this.filterInput[0] === activeElement();\n\t }\n\n\t if (this.wrapper) {\n\t isWrapperActive = this.wrapper[0] === activeElement();\n\t }\n\n\t if(isWrapperActive){\n\t if (key === keys.ESC) {\n\t this._clearTextAndValue();\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if(this._isMultipleSelection()){\n\t if (key === keys.LEFT) {\n\t this._focusPrevTag();\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if (key === keys.RIGHT) {\n\t this._focusNextTag();\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if (key === keys.HOME) {\n\t this._focusFirstTag();\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if (key === keys.END) {\n\t this._focusLastTag();\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if (key === keys.DELETE) {\n\t focused = this.tagList.find(DOT + FOCUSED).first();\n\t if(focused.length){\n\t tagItem = this._tags[focused.index()];\n\t this._removeTag(tagItem);\n\t }\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if (key === keys.BACKSPACE) {\n\t focused = this.tagList.find(DOT + FOCUSED).first();\n\t if (focused.length) {\n\t tagItem = this._tags[focused.index()];\n\t this._removeTag(tagItem);\n\t } else {\n\t focused = this._focusLastTag();\n\t if (focused.length) {\n\t tagItem = this._tags[focused.index()];\n\t this._removeTag(tagItem);\n\t }\n\t }\n\t e.preventDefault();\n\t return;\n\t }\n\t }\n\t }\n\n\n\t if (isFilterInputActive) {\n\t if (key === keys.ESC) {\n\t this._clearFilter();\n\t }\n\n\t if ((key === keys.UP) && !altKey) {\n\t this.wrapper.focus();\n\t e.preventDefault();\n\t }\n\n\t if(browser.msie && browser.version < 10){\n\t if (key === keys.BACKSPACE || key === keys.DELETE) {\n\t this._search();\n\t }\n\t }\n\n\t if(key === keys.TAB){\n\t this.close();\n\t this.wrapper.focus();\n\t e.preventDefault();\n\t return;\n\t }\n\t }\n\n\t if ((altKey && key === keys.UP) || key === keys.ESC) {\n\t this.close();\n\t this.wrapper.focus();\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if (key === keys.ENTER && this._typingTimeout && this.filterInput && isPopupVisible) {\n\t e.preventDefault();\n\t return;\n\t }\n\n\t if (key === keys.SPACEBAR && !isFilterInputActive) {\n\t this._toggle(!isPopupVisible);\n\t e.preventDefault();\n\t }\n\n\t if ((altKey && key === keys.DOWN) && !isPopupVisible) {\n\t this.open();\n\t e.preventDefault();\n\t }\n\n\t if ((key === keys.DOWN) && isPopupVisible) {\n\t if (this.filterInput && !isFilterInputActive) {\n\t this.filterInput.focus();\n\t } else if (this.checkAll && this.checkAll.is(\":visible\")) {\n\t this.checkAll.find('input').focus();\n\t } else if(this.tree.is(\":visible\")) {\n\t this.tree.focus();\n\t }\n\t e.preventDefault();\n\t }\n\n\t if(key === keys.TAB && isPopupVisible){\n\t this.close();\n\t this.wrapper.focus();\n\t e.preventDefault();\n\t }\n\t },\n\n\t _focusPrevTag: function() {\n\t var focused = this.tagList.find(DOT + FOCUSED);\n\t if (focused.length) {\n\t var activedescendant = this.wrapper.attr(\"aria-activedescendant\");\n\t focused.first()\n\t .removeClass(FOCUSED)\n\t .removeAttr(\"id\")\n\t .prev().addClass(FOCUSED)\n\t .attr(\"id\", activedescendant);\n\t this.wrapper.attr(\"aria-activedescendant\", activedescendant);\n\t } else {\n\t this._focusLastTag();\n\t }\n\t },\n\n\t _focusNextTag: function() {\n\t var focused = this.tagList.find(DOT + FOCUSED);\n\t if (focused.length) {\n\t var activedescendant = this.wrapper.attr(\"aria-activedescendant\");\n\t focused.first().removeClass(FOCUSED).removeAttr(\"id\")\n\t .next().addClass(FOCUSED)\n\t .attr(\"id\", activedescendant);\n\t this.wrapper.attr(\"aria-activedescendant\", activedescendant);\n\t } else {\n\t this._focusFirstTag();\n\t }\n\t },\n\n\t _focusFirstTag: function() {\n\t var activedescendant = this.wrapper.attr(\"aria-activedescendant\");\n\t this._clearDisabledTag();\n\n\t var firstTag = this.tagList.children('li').first().addClass(FOCUSED)\n\t .attr(\"id\", activedescendant);\n\t this.wrapper.attr(\"aria-activedescendant\", activedescendant);\n\n\t return firstTag;\n\t },\n\n\t _focusLastTag: function() {\n\t var activedescendant = this.wrapper.attr(\"aria-activedescendant\");\n\t this._clearDisabledTag();\n\t var lastTag = this.tagList.children('li').last().addClass(FOCUSED)\n\t .attr(\"id\", activedescendant);\n\t this.wrapper.attr(\"aria-activedescendant\", activedescendant);\n\n\t return lastTag;\n\t },\n\n\t _clearDisabledTag: function() {\n\t this.tagList.find(DOT + FOCUSED).removeClass(FOCUSED).removeAttr(\"id\");\n\t },\n\n\t _search: function() {\n\t var that = this;\n\t clearTimeout(that._typingTimeout);\n\n\t that._typingTimeout = setTimeout(function() {\n\t var value = that.filterInput.val();\n\n\t if (that._prev !== value) {\n\t that._prev = value;\n\t that.search(value);\n\t }\n\n\t that._typingTimeout = null;\n\t }, that.options.delay);\n\t },\n\n\t _clearFilter: function() {\n\t if(this.filterInput.val().length){\n\t this.filterInput.val(\"\");\n\t this._prev = \"\";\n\t this._filtering = true;\n\t this.treeview.dataSource.filter({});\n\t }\n\t },\n\n\t _removeTagClick: function(e) {\n\t e.stopPropagation();\n\t var tagItem = this._tags[$(e.currentTarget.parentElement).index()];\n\t this._removeTag(tagItem);\n\t },\n\n\t _removeTag: function(tagItem) {\n\t if(!tagItem){\n\t return;\n\t }\n\n\t var uid = tagItem.uid;\n\t this._uncheckItemByUid(uid);\n\t }\n\t });\n\n\t function assign(instance, fields, value) {\n\t var idx = 0,\n\t lastIndex = fields.length - 1,\n\t field;\n\n\t for (; idx < lastIndex; ++idx) {\n\t field = fields[idx];\n\n\t if (!(field in instance)) {\n\t instance[field] = {};\n\t }\n\n\t instance = instance[field];\n\t }\n\n\t instance[fields[lastIndex]] = value;\n\t }\n\n\t ui.plugin(DropDownTree);\n\n\t var SingleSelection = kendo.Class.extend({\n\t init: function(view) {\n\t this._dropdowntree = view;\n\t },\n\n\t _initWrapper: function() {\n\t this._wrapper();\n\t this._span();\n\t },\n\n\t _preselect: function(data){\n\t var dropdowntree = this._dropdowntree;\n\n\t dropdowntree._selectValue(data);\n\t },\n\n\t _wrapper: function() {\n\t var dropdowntree = this._dropdowntree,\n\t element = dropdowntree.element,\n\t DOMelement = element[0],\n\t wrapper;\n\n\t wrapper = element.parent();\n\n\t if (!wrapper.is(\"span.k-widget\")) {\n\t wrapper = element.wrap(\"\").parent();\n\t wrapper[0].style.cssText = DOMelement.style.cssText;\n\t wrapper[0].title = DOMelement.title;\n\t }\n\n\t dropdowntree._focused = dropdowntree.wrapper = wrapper\n\t .addClass(\"k-widget k-dropdowntree\")\n\t .addClass(DOMelement.className)\n\t .removeClass('input-validation-error')\n\t .css(\"display\", \"\")\n\t .attr({\n\t accesskey: element.attr(\"accesskey\"),\n\t unselectable: \"on\",\n\t role: \"listbox\",\n\t \"aria-haspopup\": true,\n\t \"aria-expanded\": false\n\t });\n\n\t element.hide().removeAttr(\"accesskey\");\n\t },\n\n\t _span: function() {\n\t var dropdowntree = this._dropdowntree,\n\t wrapper = dropdowntree.wrapper,\n\t SELECTOR = \"span.k-input\",\n\t span;\n\n\t span = wrapper.find(SELECTOR);\n\n\t if (!span[0]) {\n\t wrapper.append(' ')\n\t .append(dropdowntree.element);\n\n\t span = wrapper.find(SELECTOR);\n\t }\n\n\t dropdowntree.span = span;\n\t dropdowntree._inputWrapper = $(wrapper[0].firstChild);\n\t dropdowntree._arrow = wrapper.find(\".k-select\");\n\t dropdowntree._arrowIcon = dropdowntree._arrow.find(\".k-icon\");\n\t },\n\n\t _setValue: function(value) {\n\t var dropdowntree = this._dropdowntree;\n\t var currentValue;\n\n\t if (value === undefined || value === null) {\n\t currentValue = dropdowntree._values.slice()[0];\n\t value = (typeof currentValue === \"object\") ? currentValue : dropdowntree._accessor() || currentValue;\n\t return value === undefined || value === null ? \"\" : value;\n\t }\n\t dropdowntree._valueMethodCalled = true;\n\t if (value.length === 0) {\n\t dropdowntree._clearTextAndValue();\n\t dropdowntree._valueMethodCalled = false;\n\t return;\n\t }\n\n\t dropdowntree._selectItemByValue(value);\n\t dropdowntree._toggleCloseVisibility();\n\t },\n\n\t _clearValue: function() {\n\t var dropdowntree = this._dropdowntree;\n\t var selectedNode = dropdowntree.treeview.select();\n\n\t if (dropdowntree.treeview.dataItem(selectedNode)) {\n\t dropdowntree.treeview.dataItem(selectedNode).set('selected', false);\n\t if(!dropdowntree._valueMethodCalled){\n\t dropdowntree.trigger(CHANGE);\n\t }\n\t }\n\t },\n\n\t _checkLoadedItem: function(tempItem, value) {\n\t var dropdowntree = this._dropdowntree;\n\n\t if (!dropdowntree._isNullorUndefined(value) && value!==\"\") {\n\t if(dropdowntree._valueComparer(tempItem, value)){\n\t dropdowntree._preventChangeTrigger = true;\n\t tempItem.set(\"selected\", true);\n\t dropdowntree._preventChangeTrigger = false;\n\t } else if (tempItem.selected){\n\t dropdowntree.treeview.select(dropdowntree.treeview.findByUid(tempItem.uid));\n\t }\n\n\t } else if (!value && tempItem.selected){\n\t dropdowntree.treeview.select(dropdowntree.treeview.findByUid(tempItem.uid));\n\t }\n\t }\n\t });\n\n\t var MultipleSelection = kendo.Class.extend({\n\t init: function(view) {\n\t this._dropdowntree = view;\n\t },\n\n\t _initWrapper: function() {\n\t var dropdowntree = this._dropdowntree;\n\n\t this._tagTemplate();\n\t dropdowntree.element.attr(\"multiple\", \"multiple\").hide();\n\t this._wrapper();\n\t dropdowntree._tags = new ObservableArray([]);\n\t dropdowntree._multipleTags = new ObservableArray([]);\n\t this._tagList();\n\t dropdowntree.span = $(' ').insertAfter(dropdowntree.tagList);\n\t dropdowntree._inputWrapper = $(dropdowntree.wrapper[0].firstChild);\n\t },\n\n\t _preselect: function(data, value){\n\t var dropdowntree = this._dropdowntree;\n\t var valueToSelect = value || dropdowntree.options.value;\n\n\t if (!$.isArray(data) && !(data instanceof kendo.data.ObservableArray)) {\n\t data = [data];\n\t }\n\n\t if ($.isPlainObject(data[0]) || data[0] instanceof kendo.data.ObservableObject || !dropdowntree.options.dataValueField) {\n\t dropdowntree.dataSource.data(data);\n\n\t dropdowntree.value(valueToSelect);\n\t }\n\t },\n\n\t _tagTemplate: function() {\n\t var dropdowntree = this._dropdowntree;\n\t var options = dropdowntree.options;\n\t var tagTemplate = options.valueTemplate;\n\t var isMultiple = options.tagMode === \"multiple\";\n\t var singleTag = options.messages.singleTag;\n\n\t tagTemplate = tagTemplate ? kendo.template(tagTemplate) : dropdowntree.valueTemplate;\n\n\t dropdowntree.valueTemplate = function(data) {\n\t if (isMultiple) {\n\t return '
  • ' +\n\t '' + tagTemplate(data) + '' +\n\t '' +\n\t '' +\n\t '' +\n\t '
  • ';\n\t }\n\n\t return '
  • ' +\n\t '' +\n\t ' ' + singleTag +'' +\n\t '
  • ';\n\t };\n\t },\n\n\t _wrapper: function() {\n\t var dropdowntree = this._dropdowntree,\n\t element = dropdowntree.element,\n\t wrapper = element.parent(\"span.k-dropdowntree\");\n\n\t if (!wrapper[0]) {\n\t wrapper = element.wrap('
    ').parent();\n\t wrapper[0].style.cssText = element[0].style.cssText;\n\t wrapper[0].title = element[0].title;\n\n\t $('
    ').insertBefore(element);\n\t }\n\n\t dropdowntree.wrapper = wrapper.addClass(element[0].className).css(\"display\", \"\")\n\t .attr({\n\t role: \"listbox\",\n\t \"aria-activedescendant\": kendo.guid(),\n\t \"aria-haspopup\": true,\n\t \"aria-expanded\": false\n\t });\n\t dropdowntree._innerWrapper = $(wrapper[0].firstChild);\n\t },\n\n\t _tagList: function() {\n\t var dropdowntree = this._dropdowntree,\n\t tagList = dropdowntree._innerWrapper.children(\"ul\");\n\n\t if (!tagList[0]) {\n\t var isMultiple = dropdowntree.options.tagMode === \"multiple\";\n\t var tagCollection = isMultiple ? \"tags\": \"multipleTag\";\n\t tagList = $('
      ').appendTo(dropdowntree._innerWrapper);\n\t }\n\n\t dropdowntree.tagList = tagList;\n\t dropdowntree.tagList.attr('id', kendo.guid() + \"_tagList\");\n\t dropdowntree.wrapper.attr(\"aria-owns\", dropdowntree.tagList.attr('id'));\n\t var viewModel = kendo.observable({\n\t multipleTag: dropdowntree._multipleTags,\n\t tags: dropdowntree._tags,\n\t tagTemplate: dropdowntree.valueTemplate\n\t });\n\t kendo.bind(dropdowntree.tagList, viewModel);\n\t dropdowntree.tagList.attr(\"data-stop\", true);\n\t },\n\n\t _setValue: function(value) {\n\t var dropdowntree = this._dropdowntree;\n\t var oldValues = dropdowntree._values;\n\t if (value === undefined || value === null) {\n\t return dropdowntree._values.slice();\n\t }\n\n\t dropdowntree.setValue(value);\n\t dropdowntree._valueMethodCalled = true;\n\t if (value.length) {\n\t this._removeValues(oldValues, value);\n\n\t dropdowntree._checkItemByValue(value);\n\t } else {\n\t dropdowntree._clearTextAndValue();\n\t }\n\n\t dropdowntree._valueMethodCalled = false;\n\t dropdowntree._toggleCloseVisibility();\n\t },\n\n\t _removeValues: function(oldValues, value) {\n\t var dropdowntree = this._dropdowntree;\n\t var removedValues = this._getNewValues(oldValues, value);\n\n\t for (var idx = 0; idx < removedValues.length; idx++) {\n\t for (var j = 0; j < dropdowntree._tags.length; j++) {\n\t if (dropdowntree._valueComparer(dropdowntree._tags[j],removedValues[idx])){\n\t dropdowntree._uncheckItemByUid(dropdowntree._tags[j].uid);\n\t }\n\t }\n\t }\n\t },\n\n\t _getNewValues: function(oldValues, value){\n\t var removedValues = [];\n\n\t for (var idx = 0; idx < oldValues.length; idx++) {\n\t if(value.indexOf(oldValues[idx]) === -1){\n\t removedValues.push(oldValues[idx]);\n\t }\n\t }\n\n\t return removedValues;\n\t },\n\n\t _clearValue: function() {\n\t var dropdowntree = this._dropdowntree;\n\t var tagsArray = dropdowntree._tags.slice();\n\n\t for (var idx = 0; idx < tagsArray.length; idx++) {\n\t var uid = tagsArray[idx].uid;\n\t dropdowntree._preventChangeTrigger = true;\n\t dropdowntree._uncheckItemByUid(uid);\n\t }\n\n\t if (tagsArray.length) {\n\t dropdowntree._preventChangeTrigger = false;\n\t if(!dropdowntree._valueMethodCalled){\n\t dropdowntree.trigger(CHANGE);\n\t }\n\t }\n\t },\n\n\t _checkLoadedItem: function(tempItem, value) {\n\t var dropdowntree = this._dropdowntree;\n\n\t if (dropdowntree._noInitialValue && tempItem.checked) {\n\t dropdowntree._checkValue(tempItem);\n\t return;\n\t }\n\n\t if ((value.length || this._isDataSourceSet) &&\n\t (value.indexOf(dropdowntree._currentValue(tempItem)) !== -1 || value.indexOf(tempItem)) !== -1 &&\n\t !this._findTag(dropdowntree._currentValue(tempItem))) {\n\t if (tempItem.checked) {\n\t dropdowntree._checkValue(tempItem);\n\t } else {\n\t dropdowntree._preventChangeTrigger = true;\n\t tempItem.set(\"checked\", true);\n\t dropdowntree._preventChangeTrigger = false;\n\t }\n\t }\n\t },\n\n\t _findTag: function(tempItemValue) {\n\t var dropdowntree = this._dropdowntree;\n\n\t return dropdowntree._tags.find(function(item) {\n\t return dropdowntree._valueComparer(item, tempItemValue);\n\t });\n\t }\n\t });\n\n\t kendo.ui.DropDownTree.SingleSelection = SingleSelection;\n\t kendo.ui.DropDownTree.MultipleSelection = MultipleSelection;\n\n\t})(window.kendo.jQuery);\n\n\treturn window.kendo;\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 1153:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./dropdowntree/treeview\");\n\n/***/ })\n\n/******/ });","module.exports =\n/******/ (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\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1154);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 1022:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.dropdownlist\");\n\n/***/ }),\n\n/***/ 1025:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.validator\");\n\n/***/ }),\n\n/***/ 1076:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.binder\");\n\n/***/ }),\n\n/***/ 1138:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./kendo.datepicker\");\n\n/***/ }),\n\n/***/ 1154:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1022), __webpack_require__(1138), __webpack_require__(1155), __webpack_require__(1025), __webpack_require__(1076) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\tvar __meta__ = { // jshint ignore:line\n\t id: \"editable\",\n\t name: \"Editable\",\n\t category: \"framework\",\n\t depends: [ \"dropdownlist\", \"datepicker\", \"numerictextbox\", \"validator\", \"binder\" ],\n\t hidden: true\n\t};\n\n\t/* jshint eqnull: true */\n\t(function($, undefined) {\n\t var kendo = window.kendo,\n\t ui = kendo.ui,\n\t Widget = ui.Widget,\n\t extend = $.extend,\n\t oldIE = kendo.support.browser.msie && kendo.support.browser.version < 9,\n\t isFunction = kendo.isFunction,\n\t isPlainObject = $.isPlainObject,\n\t inArray = $.inArray,\n\t POINT = \".\",\n\t AUTOCOMPLETEVALUE = \"off\",\n\t nameSpecialCharRegExp = /(\"|\\%|'|\\[|\\]|\\$|\\.|\\,|\\:|\\;|\\+|\\*|\\&|\\!|\\#|\\(|\\)|<|>|\\=|\\?|\\@|\\^|\\{|\\}|\\~|\\/|\\||`)/g,\n\t ERRORTEMPLATE = '
      ' +\n\t '' +\n\t '#= message #' +\n\t '' +\n\t '
      ',\n\t CHANGE = \"change\";\n\t var EQUAL_SET = \"equalSet\";\n\t var specialRules = [\"url\", \"email\", \"number\", \"date\", \"boolean\"];\n\n\t function fieldType(field) {\n\t field = field != null ? field : \"\";\n\t return field.type || $.type(field) || \"string\";\n\t }\n\n\t function convertToValueBinding(container) {\n\t container.find(\":input:not(:button, .k-combobox .k-input, [\" + kendo.attr(\"role\") + \"=listbox], [\" + kendo.attr(\"role\") + \"=upload], [\" + kendo.attr(\"skip\") + \"], [type=file])\").each(function() {\n\t var bindAttr = kendo.attr(\"bind\"),\n\t binding = this.getAttribute(bindAttr) || \"\",\n\t bindingName = this.type === \"checkbox\" || this.type === \"radio\" ? \"checked:\" : \"value:\",\n\t fieldName = this.name;\n\n\t if (binding.indexOf(bindingName) === -1 && fieldName) {\n\t binding += (binding.length ? \",\" : \"\") + bindingName + fieldName;\n\n\t $(this).attr(bindAttr, binding);\n\t }\n\t });\n\t }\n\n\t function createAttributes(options) {\n\t var field = (options.model.fields || options.model)[options.field],\n\t type = fieldType(field),\n\t validation = field ? field.validation : {},\n\t attributes = field ? field.attributes : {},\n\t ruleName,\n\t DATATYPE = kendo.attr(\"type\"),\n\t BINDING = kendo.attr(\"bind\"),\n\t rule,\n\t attr = {\n\t id: options.id || options.field,\n\t name: options.field,\n\t title: options.title ? options.title : options.field\n\t };\n\n\t for (ruleName in validation) {\n\t rule = validation[ruleName];\n\n\t if (inArray(ruleName, specialRules) >= 0) {\n\t attr[DATATYPE] = ruleName;\n\t } else if (!isFunction(rule)) {\n\t var culture = kendo.getCulture();\n\n\t if (typeof rule === \"number\" && culture.name.length) {\n\t var numberFormat = culture.numberFormat;\n\t var stringRule = rule.toString()\n\t .replace(POINT, numberFormat[POINT]);\n\n\t attr[ruleName] = stringRule;\n\t } else {\n\t attr[ruleName] = isPlainObject(rule) ? rule.value || ruleName : rule;\n\t }\n\t }\n\n\t attr[kendo.attr(ruleName + \"-msg\")] = rule.message;\n\n\t attr.autocomplete = AUTOCOMPLETEVALUE;\n\t }\n\n\t for (var attributeName in attributes) {\n\t attr[attributeName] = attributes[attributeName];\n\t }\n\n\t if (inArray(type, specialRules) >= 0) {\n\t attr[DATATYPE] = type;\n\t }\n\n\t attr[BINDING] = (\"value:\") + options.field;\n\n\t return attr;\n\t }\n\n\t function addIdAttribute(container, attr) {\n\t var id = container.attr(\"id\");\n\n\t if (id) {\n\t attr.id = id;\n\t container.removeAttr(\"id\");\n\t }\n\n\t return attr;\n\t }\n\n\t function convertItems(items) {\n\t var idx,\n\t length,\n\t item,\n\t value,\n\t text,\n\t result;\n\n\t if (items && items.length) {\n\t result = [];\n\t for (idx = 0, length = items.length; idx < length; idx++) {\n\t item = items[idx];\n\t text = item.text || item.value || item;\n\t value = item.value == null ? (item.text || item) : item.value;\n\n\t result[idx] = { text: text, value: value };\n\t }\n\t }\n\t return result;\n\t }\n\n\t function getEditorTag(type, options) {\n\t var tag;\n\n\t if (!type.length) { return; }\n\n\t if ((type === \"DropDownTree\" && options && options.checkboxes) || type === \"MultiSelect\") {\n\t tag = \"\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces \";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting or other required elements.\n\tthead: [ 1, \"\", \"
      \" ],\n\tcol: [ 2, \"\", \"
      \" ],\n\ttr: [ 2, \"\", \"
      \" ],\n\ttd: [ 3, \"\", \"
      \" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, \"\" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\t\tdataPriv.get( this, \"events\" ) || Object.create( null )\n\t\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event ) dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, \"handle events\" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase() !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( \"table\" );\n\t\t\t\ttr = document.createElement( \"tr\" );\n\t\t\t\ttrChild = document.createElement( \"div\" );\n\n\t\t\t\ttable.style.cssText = \"position:absolute;left:-11111px\";\n\t\t\t\ttr.style.height = \"1px\";\n\t\t\t\ttrChild.style.height = \"9px\";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = parseInt( trStyle.height ) > 3;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t// .css('filter') (IE 9 only, #12537)\n\t// .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Interestingly, in some cases IE 9 doesn't suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, \"tr\" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === \"auto\" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = (\n\t\t\t\t\tdataPriv.get( cur, \"events\" ) || Object.create( null )\n\t\t\t\t)[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\n\t\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t * - BEFORE asking for a transport\n\t * - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script\n\t\t\tif ( !isSuccess && jQuery.inArray( \"script\", s.dataTypes ) > -1 ) {\n\t\t\t\ts.converters[ \"text script\" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === \"content-type\" ) {\n\t\t\ts.contentType = s.headers[ i ] || \"\";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\" ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"