{"version":3,"file":"Draggable.min.js","sources":["../src/utils/matrix.js","../src/Draggable.js"],"sourcesContent":["/*!\n * matrix 3.1.1\n * https://greensock.com\n *\n * Copyright 2008-2020, GreenSock. All rights reserved.\n * Subject to the terms at https://greensock.com/standard-license or for\n * Club GreenSock members, the agreement issued with that membership.\n * @author: Jack Doyle, jack@greensock.com\n*/\n/* eslint-disable */\n\nlet _doc, _win, _docElement, _body,\t_divContainer, _svgContainer, _identityMatrix,\n\t_transformProp = \"transform\",\n\t_transformOriginProp = _transformProp + \"Origin\",\n\t_setDoc = element => {\n\t\tlet doc = element.ownerDocument || element;\n\t\tif (!(_transformProp in element.style) && \"msTransform\" in element.style) { //to improve compatibility with old Microsoft browsers\n\t\t\t_transformProp = \"msTransform\";\n\t\t\t_transformOriginProp = _transformProp + \"Origin\";\n\t\t}\n\t\twhile (doc.parentNode && (doc = doc.parentNode)) {\t}\n\t\t_win = window;\n\t\t_identityMatrix = new Matrix2D();\n\t\tif (doc) {\n\t\t\t_doc = doc;\n\t\t\t_docElement = doc.documentElement;\n\t\t\t_body = doc.body;\n\t\t}\n\t\treturn doc;\n\t},\n\t_svgTemps = [], //we create 3 elements for SVG, and 3 for other DOM elements and cache them for performance reasons. They get nested in _divContainer and _svgContainer so that just one element is added to the DOM on each successive attempt. Again, performance is key.\n\t_divTemps = [],\n\t_getDocScrollTop = () => _win.pageYOffset || _doc.scrollTop || _docElement.scrollTop || _body.scrollTop || 0,\n\t_getDocScrollLeft = () => _win.pageXOffset || _doc.scrollLeft || _docElement.scrollLeft || _body.scrollLeft || 0,\n\t_svgOwner = element => element.ownerSVGElement || ((element.tagName + \"\").toLowerCase() === \"svg\" ? element : null),\n\t_isFixed = element => {\n\t\tif (_win.getComputedStyle(element).position === \"fixed\") {\n\t\t\treturn true;\n\t\t}\n\t\telement = element.parentNode;\n\t\tif (element && element.nodeType === 1) { // avoid document fragments which will throw an error.\n\t\t\treturn _isFixed(element);\n\t\t}\n\t},\n\t_createSibling = (element, i) => {\n\t\tif (element.parentNode && (_doc || _setDoc(element))) {\n\t\t\tlet svg = _svgOwner(element),\n\t\t\t\tns = svg ? (svg.getAttribute(\"xmlns\") || \"http://www.w3.org/2000/svg\") : \"http://www.w3.org/1999/xhtml\",\n\t\t\t\ttype = svg ? (i ? \"rect\" : \"g\") : \"div\",\n\t\t\t\tx = i !== 2 ? 0 : 100,\n\t\t\t\ty = i === 3 ? 100 : 0,\n\t\t\t\tcss = \"position:absolute;display:block;pointer-events:none;\",\n\t\t\t\te = _doc.createElementNS ? _doc.createElementNS(ns.replace(/^https/, \"http\"), type) : _doc.createElement(type);\n\t\t\tif (i) {\n\t\t\t\tif (!svg) {\n\t\t\t\t\tif (!_divContainer) {\n\t\t\t\t\t\t_divContainer = _createSibling(element);\n\t\t\t\t\t\t_divContainer.style.cssText = css;\n\t\t\t\t\t}\n\t\t\t\t\te.style.cssText = css + \"width:1px;height:1px;top:\" + y + \"px;left:\" + x + \"px\";\n\t\t\t\t\t_divContainer.appendChild(e);\n\n\t\t\t\t} else {\n\t\t\t\t\tif (!_svgContainer) {\n\t\t\t\t\t\t_svgContainer = _createSibling(element);\n\t\t\t\t\t}\n\t\t\t\t\te.setAttribute(\"width\", 1);\n\t\t\t\t\te.setAttribute(\"height\", 1);\n\t\t\t\t\te.setAttribute(\"transform\", \"translate(\" + x + \",\" + y + \")\");\n\t\t\t\t\t_svgContainer.appendChild(e);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn e;\n\t\t}\n\t\tthrow \"Need document and parent.\";\n\t},\n\t_placeSiblings = element => {\n\t\tlet svg = _svgOwner(element),\n\t\t\tisRootSVG = element === svg,\n\t\t\tsiblings = svg ? _svgTemps : _divTemps,\n\t\t\tcontainer, m, b, x, y;\n\t\tif (element === _win) {\n\t\t\treturn element;\n\t\t}\n\t\tif (!siblings.length) {\n\t\t\tsiblings.push(_createSibling(element, 1), _createSibling(element, 2), _createSibling(element, 3));\n\t\t}\n\t\tcontainer = svg ? _svgContainer : _divContainer;\n\t\tif (svg) {\n\t\t\tb = isRootSVG ? {x:0, y:0} : element.getBBox();\n\t\t\tm = element.transform ? element.transform.baseVal : []; // IE11 doesn't follow the spec.\n\t\t\tif (m.length) {\n\t\t\t\tm = m.consolidate().matrix;\n\t\t\t\tx = m.a * b.x + m.c * b.y;\n\t\t\t\ty = m.b * b.x + m.d * b.y;\n\t\t\t} else {\n\t\t\t\tm = _identityMatrix;\n\t\t\t\tx = b.x;\n\t\t\t\ty = b.y;\n\t\t\t}\n\t\t\tif (element.tagName.toLowerCase() === \"g\") {\n\t\t\t\tx = y = 0;\n\t\t\t}\n\t\t\tcontainer.setAttribute(\"transform\", \"matrix(\" + m.a + \",\" + m.b + \",\" + m.c + \",\" + m.d + \",\" + (m.e + x) + \",\" + (m.f + y) + \")\");\n\t\t\t(isRootSVG ? svg : element.parentNode).appendChild(container);\n\t\t} else {\n\t\t\tcontainer.style.top = element.offsetTop + \"px\";\n\t\t\tcontainer.style.left = element.offsetLeft + \"px\";\n\t\t\tm = _win.getComputedStyle(element);\n\t\t\tcontainer.style[_transformProp] = m[_transformProp];\n\t\t\tcontainer.style[_transformOriginProp] = m[_transformOriginProp];\n\t\t\tcontainer.style.position = m.position === \"fixed\" ? \"fixed\" : \"absolute\";\n\t\t\telement.parentNode.appendChild(container);\n\t\t}\n\t\treturn container;\n\t},\n\t_setMatrix = (m, a, b, c, d, e, f) => {\n\t\tm.a = a;\n\t\tm.b = b;\n\t\tm.c = c;\n\t\tm.d = d;\n\t\tm.e = e;\n\t\tm.f = f;\n\t\treturn m;\n\t};\n\nexport class Matrix2D {\n\tconstructor(a=1, b=0, c=0, d=1, e=0, f=0) {\n\t\t_setMatrix(this, a, b, c, d, e, f);\n\t}\n\n\tinverse() {\n\t\tlet {a, b, c, d, e, f} = this,\n\t\t\tdeterminant = (a * d - b * c);\n\t\treturn _setMatrix(\n\t\t\tthis,\n\t\t\td / determinant,\n\t\t\t-b / determinant,\n\t\t\t-c / determinant,\n\t\t\ta / determinant,\n\t\t\t(c * f - d * e) / determinant,\n\t\t\t-(a * f - b * e) / determinant\n\t\t);\n\t}\n\n\tmultiply(matrix) {\n\t\tlet {a, b, c, d, e, f} = this,\n\t\t\ta2 = matrix.a,\n\t\t\tb2 = matrix.c,\n\t\t\tc2 = matrix.b,\n\t\t\td2 = matrix.d,\n\t\t\te2 = matrix.e,\n\t\t\tf2 = matrix.f;\n\t\treturn _setMatrix(this,\n\t\t\ta2 * a + c2 * c,\n\t\t\ta2 * b + c2 * d,\n\t\t\tb2 * a + d2 * c,\n\t\t\tb2 * b + d2 * d,\n\t\t\te + e2 * a + f2 * c,\n\t\t\tf + e2 * b + f2 * d);\n\t}\n\n\tequals(matrix) {\n\t\tlet {a, b, c, d, e, f} = this;\n\t\treturn (a === matrix.a && b === matrix.b && c === matrix.c && d === matrix.d && e === matrix.e && f === matrix.f);\n\t}\n\n\tapply(point, decoratee={}) {\n\t\tlet {x, y} = point,\n\t\t\t{a, b, c, d, e, f} = this;\n\t\tdecoratee.x = x * a + y * c + e;\n\t\tdecoratee.y = x * b + y * d + f;\n\t\treturn decoratee;\n\t}\n\n}\n\n//feed in an element and it'll return a 2D matrix (optionally inverted) so that you can translate between coordinate spaces.\n// Inverting lets you translate a global point into a local coordinate space. No inverting lets you go the other way.\n// We needed this to work around various browser bugs, like Firefox doesn't accurately report getScreenCTM() when there\n// are transforms applied to ancestor elements.\n// The matrix math to convert any x/y coordinate is:\n// tx = m.a * x + m.c * y + m.e\n// ty = m.b * x + m.d * y + m.f\nexport function getGlobalMatrix(element, inverse) {\n\tif (!element || !element.parentNode) {\n\t\treturn new Matrix2D();\n\t}\n\tlet svg = _svgOwner(element),\n\t\ttemps = svg ? _svgTemps : _divTemps,\n\t\tcontainer = _placeSiblings(element),\n\t\tb1 = temps[0].getBoundingClientRect(),\n\t\tb2 = temps[1].getBoundingClientRect(),\n\t\tb3 = temps[2].getBoundingClientRect(),\n\t\tparent = container.parentNode,\n\t\tisFixed = _isFixed(element),\n\t\tm = new Matrix2D(\n\t\t\t(b2.left - b1.left) / 100,\n\t\t\t(b2.top - b1.top) / 100,\n\t\t\t(b3.left - b1.left) / 100,\n\t\t\t(b3.top - b1.top) / 100,\n\t\t\tb1.left + (isFixed ? 0 : _getDocScrollLeft()),\n\t\t\tb1.top + (isFixed ? 0 : _getDocScrollTop())\n\t\t);\n\tparent.removeChild(container);\n\treturn inverse ? m.inverse() : m;\n}\n","/*!\n * Draggable 3.1.1\n * https://greensock.com\n *\n * @license Copyright 2008-2020, GreenSock. All rights reserved.\n * Subject to the terms at https://greensock.com/standard-license or for\n * Club GreenSock members, the agreement issued with that membership.\n * @author: Jack Doyle, jack@greensock.com\n */\n/* eslint-disable */\n\nimport { getGlobalMatrix, Matrix2D } from \"./utils/matrix.js\";\n\nlet gsap, _win, _doc, _docElement, _body, _tempDiv, _placeholderDiv, _coreInitted, _checkPrefix, _toArray, _supportsPassive, _isTouchDevice, _touchEventLookup, _dragCount, _isMultiTouching, _isAndroid, InertiaPlugin, _defaultCursor, _supportsPointer,\n\t_windowExists = () => typeof(window) !== \"undefined\",\n\t_getGSAP = () => gsap || (_windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap),\n\t_isFunction = value => typeof(value) === \"function\",\n\t_isObject = value => typeof(value) === \"object\",\n\t_isUndefined = value => typeof(value) === \"undefined\",\n\t_emptyFunc = () => false,\n\t_transformProp = \"transform\",\n\t_transformOriginProp = \"transformOrigin\",\n\t_round = value => Math.round(value * 10000) / 10000,\n\t_isArray = Array.isArray,\n\t_createElement = (type, ns) => {\n\t\tlet e = _doc.createElementNS ? _doc.createElementNS((ns || \"http://www.w3.org/1999/xhtml\").replace(/^https/, \"http\"), type) : _doc.createElement(type); //some servers swap in https for http in the namespace which can break things, making \"style\" inaccessible.\n\t\treturn e.style ? e : _doc.createElement(type); //some environments won't allow access to the element's style when created with a namespace in which case we default to the standard createElement() to work around the issue. Also note that when GSAP is embedded directly inside an SVG file, createElement() won't allow access to the style object in Firefox (see https://greensock.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/).\n\t},\n\t_RAD2DEG = 180 / Math.PI,\n\t_bigNum = 1e20,\n\t_identityMatrix = new Matrix2D(),\n\t_getTime = Date.now || (() => new Date().getTime()),\n\t_renderQueue = [],\n\t_lookup = {}, //when a Draggable is created, the target gets a unique _gsDragID property that allows gets associated with the Draggable instance for quick lookups in Draggable.get(). This avoids circular references that could cause gc problems.\n\t_lookupCount = 0,\n\t_clickableTagExp = /^(?:a|input|textarea|button|select)$/i,\n\t_lastDragTime = 0,\n\t_temp1 = {}, // a simple object we reuse and populate (usually x/y properties) to conserve memory and improve performance.\n\t_windowProxy = {}, //memory/performance optimization - we reuse this object during autoScroll to store window-related bounds/offsets.\n\t_copy = (obj, factor) => {\n\t\tlet copy = {}, p;\n\t\tfor (p in obj) {\n\t\t\tcopy[p] = factor ? obj[p] * factor : obj[p];\n\t\t}\n\t\treturn copy;\n\t},\n\t_extend = (obj, defaults) => {\n\t\tfor (let p in defaults) {\n\t\t\tif (!(p in obj)) {\n\t\t\t\tobj[p] = defaults[p];\n\t\t\t}\n\t\t}\n\t\treturn obj;\n\t},\n\t_renderQueueTick = () => _renderQueue.forEach(func => func()),\n\t_addToRenderQueue = func => {\n\t\t_renderQueue.push(func);\n\t\tif (_renderQueue.length === 1) {\n\t\t\tgsap.ticker.add(_renderQueueTick);\n\t\t}\n\t},\n\t_renderQueueTimeout = () => !_renderQueue.length && gsap.ticker.remove(_renderQueueTick),\n\t_removeFromRenderQueue = func => {\n\t\tlet i = _renderQueue.length;\n\t\twhile (i--) {\n\t\t\tif (_renderQueue[i] === func) {\n\t\t\t\t_renderQueue.splice(i, 1);\n\t\t\t}\n\t\t}\n\t\tgsap.to(_renderQueueTimeout, {overwrite:true, delay:15, duration:0, onComplete:_renderQueueTimeout, data:\"_draggable\"}); //remove the \"tick\" listener only after the render queue is empty for 15 seconds (to improve performance). Adding/removing it constantly for every click/touch wouldn't deliver optimal speed, and we also don't want the ticker to keep calling the render method when things are idle for long periods of time (we want to improve battery life on mobile devices).\n\t},\n\t_setDefaults = (obj, defaults) => {\n\t\tfor (let p in defaults) {\n\t\t\tif (!(p in obj)) {\n\t\t\t\tobj[p] = defaults[p];\n\t\t\t}\n\t\t}\n\t\treturn obj;\n\t},\n\t_addListener = (element, type, func, capture) => {\n\t\tif (element.addEventListener) {\n\t\t\tlet touchType = _touchEventLookup[type];\n\t\t\tcapture = capture || (_supportsPassive ? {passive:false} : null);\n\t\t\telement.addEventListener(touchType || type, func, capture);\n\t\t\tif (touchType && type !== touchType && touchType.substr(0, 7) !== \"pointer\") { //some browsers actually support both, so must we. But pointer events cover all.\n\t\t\t\telement.addEventListener(type, func, capture);\n\t\t\t}\n\t\t}\n\t},\n\t_removeListener = (element, type, func) => {\n\t\tif (element.removeEventListener) {\n\t\t\tlet touchType = _touchEventLookup[type];\n\t\t\telement.removeEventListener(touchType || type, func);\n\t\t\tif (touchType && type !== touchType && touchType.substr(0, 7) !== \"pointer\") {\n\t\t\t\telement.removeEventListener(type, func);\n\t\t\t}\n\t\t}\n\t},\n\t_preventDefault = event => {\n\t\tif (event.preventDefault) {\n\t\t\tevent.preventDefault();\n\t\t\tif (event.preventManipulation) {\n\t\t\t\tevent.preventManipulation(); //for some Microsoft browsers\n\t\t\t}\n\t\t}\n\t},\n\t_hasTouchID = (list, ID) => {\n\t\tlet i = list.length;\n\t\twhile (i--) {\n\t\t\tif (list[i].identifier === ID) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t},\n\t_onMultiTouchDocumentEnd = event => {\n\t\t_isMultiTouching = (event.touches && _dragCount < event.touches.length);\n\t\t_removeListener(event.target, \"touchend\", _onMultiTouchDocumentEnd);\n\t},\n\n\t_onMultiTouchDocument = event => {\n\t\t_isMultiTouching = (event.touches && _dragCount < event.touches.length);\n\t\t_addListener(event.target, \"touchend\", _onMultiTouchDocumentEnd);\n\t},\n\t_getDocScrollTop = doc => _win.pageYOffset || doc.scrollTop || doc.documentElement.scrollTop || doc.body.scrollTop || 0,\n\t_getDocScrollLeft = doc => _win.pageXOffset || doc.scrollLeft || doc.documentElement.scrollLeft || doc.body.scrollLeft || 0,\n\t_addScrollListener = (e, callback) => {\n\t\t_addListener(e, \"scroll\", callback);\n\t\tif (!_isRoot(e.parentNode)) {\n\t\t\t_addScrollListener(e.parentNode, callback);\n\t\t}\n\t},\n\t_removeScrollListener = (e, callback) => {\n\t\t_removeListener(e, \"scroll\", callback);\n\t\tif (!_isRoot(e.parentNode)) {\n\t\t\t_removeScrollListener(e.parentNode, callback);\n\t\t}\n\t},\n\t_isRoot = e => !!(!e || e === _docElement || e.nodeType === 9 || e === _doc.body || e === _win || !e.nodeType || !e.parentNode),\n\t_getMaxScroll = (element, axis) => {\n\t\tlet dim = (axis === \"x\") ? \"Width\" : \"Height\",\n\t\t\tscroll = \"scroll\" + dim,\n\t\t\tclient = \"client\" + dim;\n\t\treturn Math.max(0, _isRoot(element) ? Math.max(_docElement[scroll], _body[scroll]) - (_win[\"inner\" + dim] || _docElement[client] || _body[client]) : element[scroll] - element[client]);\n\t},\n\t_recordMaxScrolls = e => { //records _gsMaxScrollX and _gsMaxScrollY properties for the element and all ancestors up the chain so that we can cap it, otherwise dragging beyond the edges with autoScroll on can endlessly scroll.\n\t\tlet x = _getMaxScroll(e, \"x\"),\n\t\t\ty = _getMaxScroll(e, \"y\");\n\t\tif (_isRoot(e)) {\n\t\t\te = _windowProxy;\n\t\t} else {\n\t\t\t_recordMaxScrolls(e.parentNode);\n\t\t}\n\t\te._gsMaxScrollX = x;\n\t\te._gsMaxScrollY = y;\n\t\te._gsScrollX = e.scrollLeft || 0;\n\t\te._gsScrollY = e.scrollTop || 0;\n\t},\n\t_setStyle = (element, property, value) => {\n\t\tlet style = element.style;\n\t\tif (!style) {\n\t\t\treturn;\n\t\t}\n\t\tif (_isUndefined(style[property])) {\n\t\t\tproperty = _checkPrefix(property, element) || property;\n\t\t}\n\t\tif (value == null) {\n\t\t\tstyle.removeProperty && style.removeProperty(property.replace(/([A-Z])/g, \"-$1\").toLowerCase());\n\t\t} else {\n\t\t\tstyle[property] = value;\n\t\t}\n\t},\n\t_getComputedStyle = element => _win.getComputedStyle((element instanceof Element) ? element : element.host || (element.parentNode || {}).host || element), //the \"host\" stuff helps to accommodate ShadowDom objects.\n\n\t_tempRect = {}, //reuse to reduce garbage collection tasks\n\t_parseRect = e => { //accepts a DOM element, a mouse event, or a rectangle object and returns the corresponding rectangle with left, right, width, height, top, and bottom properties\n\t\tif (e === _win) {\n\t\t\t_tempRect.left = _tempRect.top = 0;\n\t\t\t_tempRect.width = _tempRect.right = _docElement.clientWidth || e.innerWidth || _body.clientWidth || 0;\n\t\t\t_tempRect.height = _tempRect.bottom = ((e.innerHeight || 0) - 20 < _docElement.clientHeight) ? _docElement.clientHeight : e.innerHeight || _body.clientHeight || 0;\n\t\t\treturn _tempRect;\n\t\t}\n\t\tlet doc = e.ownerDocument || _doc,\n\t\t\tr = !_isUndefined(e.pageX) ? {left: e.pageX - _getDocScrollLeft(doc), top: e.pageY - _getDocScrollTop(doc), right: e.pageX - _getDocScrollLeft(doc) + 1, bottom: e.pageY - _getDocScrollTop(doc) + 1} : (!e.nodeType && !_isUndefined(e.left) && !_isUndefined(e.top)) ? e : _toArray(e)[0].getBoundingClientRect();\n\t\tif (_isUndefined(r.right) && !_isUndefined(r.width)) {\n\t\t\tr.right = r.left + r.width;\n\t\t\tr.bottom = r.top + r.height;\n\t\t} else if (_isUndefined(r.width)) { //some browsers don't include width and height properties. We can't just set them directly on r because some browsers throw errors, so create a new generic object.\n\t\t\tr = {width: r.right - r.left, height: r.bottom - r.top, right: r.right, left: r.left, bottom: r.bottom, top: r.top};\n\t\t}\n\t\treturn r;\n\t},\n\n\t_dispatchEvent = (target, type, callbackName) => {\n\t\tlet vars = target.vars,\n\t\t\tcallback = vars[callbackName],\n\t\t\tlisteners = target._listeners[type],\n\t\t\tresult;\n\t\tif (_isFunction(callback)) {\n\t\t\tresult = callback.apply(vars.callbackScope || target, vars[callbackName + \"Params\"] || [target.pointerEvent]);\n\t\t}\n\t\tif (listeners && target.dispatchEvent(type) === false) {\n\t\t\tresult = false;\n\t\t}\n\t\treturn result;\n\t},\n\t_getBounds = (target, context) => { //accepts any of the following: a DOM element, jQuery object, selector text, or an object defining bounds as {top, left, width, height} or {minX, maxX, minY, maxY}. Returns an object with left, top, width, and height properties.\n\t\tlet e = _toArray(target)[0],\n\t\t\ttop, left, offset;\n\t\tif (!e.nodeType && e !== _win) {\n\t\t\tif (!_isUndefined(target.left)) {\n\t\t\t\toffset = {x:0, y:0}; //_getOffsetTransformOrigin(context); //the bounds should be relative to the origin\n\t\t\t\treturn {left: target.left - offset.x, top: target.top - offset.y, width: target.width, height: target.height};\n\t\t\t}\n\t\t\tleft = target.min || target.minX || target.minRotation || 0;\n\t\t\ttop = target.min || target.minY || 0;\n\t\t\treturn {left:left, top:top, width:(target.max || target.maxX || target.maxRotation || 0) - left, height:(target.max || target.maxY || 0) - top};\n\t\t}\n\t\treturn _getElementBounds(e, context);\n\t},\n\t_point1 = {}, //we reuse to minimize garbage collection tasks.\n\t_getElementBounds = (element, context) => {\n\t\tcontext = _toArray(context)[0];\n\t\tlet isSVG = (element.getBBox && element.ownerSVGElement),\n\t\t\tdoc = element.ownerDocument || _doc,\n\t\t\tleft, right, top, bottom, matrix, p1, p2, p3, p4, bbox, width, height, cs, contextParent;\n\t\tif (element === _win) {\n\t\t\ttop = _getDocScrollTop(doc);\n\t\t\tleft = _getDocScrollLeft(doc);\n\t\t\tright = left + (doc.documentElement.clientWidth || element.innerWidth || doc.body.clientWidth || 0);\n\t\t\tbottom = top + (((element.innerHeight || 0) - 20 < doc.documentElement.clientHeight) ? doc.documentElement.clientHeight : element.innerHeight || doc.body.clientHeight || 0); //some browsers (like Firefox) ignore absolutely positioned elements, and collapse the height of the documentElement, so it could be 8px, for example, if you have just an absolutely positioned div. In that case, we use the innerHeight to resolve this.\n\t\t} else if (context === _win || _isUndefined(context)) {\n\t\t\treturn element.getBoundingClientRect();\n\t\t} else {\n\t\t\tleft = top = 0;\n\t\t\tif (isSVG) {\n\t\t\t\tbbox = element.getBBox();\n\t\t\t\twidth = bbox.width;\n\t\t\t\theight = bbox.height;\n\t\t\t} else {\n\t\t\t\tif (element.viewBox && (bbox = element.viewBox.baseVal)) {\n\t\t\t\t\tleft = bbox.x || 0;\n\t\t\t\t\ttop = bbox.y || 0;\n\t\t\t\t\twidth = bbox.width;\n\t\t\t\t\theight = bbox.height;\n\t\t\t\t}\n\t\t\t\tif (!width) {\n\t\t\t\t\tcs = _getComputedStyle(element);\n\t\t\t\t\twidth = (parseFloat(cs.width) || element.clientWidth || 0) + parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth);\n\t\t\t\t\theight = (parseFloat(cs.height) || element.clientHeight || 0) + parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth);\n\t\t\t\t}\n\t\t\t}\n\t\t\tright = width;\n\t\t\tbottom = height;\n\t\t}\n\t\tif (element === context) {\n\t\t\treturn {left:left, top:top, width: right - left, height: bottom - top};\n\t\t}\n\t\tmatrix = getGlobalMatrix(context, true).multiply(getGlobalMatrix(element));\n\t\tp1 = matrix.apply({x:left, y:top});\n\t\tp2 = matrix.apply({x:right, y:top});\n\t\tp3 = matrix.apply({x:right, y:bottom});\n\t\tp4 = matrix.apply({x:left, y:bottom});\n\t\tleft = Math.min(p1.x, p2.x, p3.x, p4.x);\n\t\ttop = Math.min(p1.y, p2.y, p3.y, p4.y);\n\t\tcontextParent = context.parentNode || {};\n\t\treturn {left: left + (contextParent.scrollLeft || 0), top: top + (contextParent.scrollTop || 0), width: Math.max(p1.x, p2.x, p3.x, p4.x) - left, height: Math.max(p1.y, p2.y, p3.y, p4.y) - top};\n\t},\n\t_parseInertia = (draggable, snap, max, min, factor, forceZeroVelocity) => {\n\t\tlet vars = {},\n\t\t\ta, i, l;\n\t\tif (snap) {\n\t\t\tif (factor !== 1 && snap instanceof Array) { //some data must be altered to make sense, like if the user passes in an array of rotational values in degrees, we must convert it to radians. Or for scrollLeft and scrollTop, we invert the values.\n\t\t\t\tvars.end = a = [];\n\t\t\t\tl = snap.length;\n\t\t\t\tif (_isObject(snap[0])) { //if the array is populated with objects, like points ({x:100, y:200}), make copies before multiplying by the factor, otherwise we'll mess up the originals and the user may reuse it elsewhere.\n\t\t\t\t\tfor (i = 0; i < l; i++) {\n\t\t\t\t\t\ta[i] = _copy(snap[i], factor);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (i = 0; i < l; i++) {\n\t\t\t\t\t\ta[i] = snap[i] * factor;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmax += 1.1; //allow 1.1 pixels of wiggle room when snapping in order to work around some browser inconsistencies in the way bounds are reported which can make them roughly a pixel off. For example, if \"snap:[-$('#menu').width(), 0]\" was defined and #menu had a wrapper that was used as the bounds, some browsers would be one pixel off, making the minimum -752 for example when snap was [-753,0], thus instead of snapping to -753, it would snap to 0 since -753 was below the minimum.\n\t\t\t\tmin -= 1.1;\n\t\t\t} else if (_isFunction(snap)) {\n\t\t\t\tvars.end = value => {\n\t\t\t\t\tlet result = snap.call(draggable, value),\n\t\t\t\t\t\tcopy, p;\n\t\t\t\t\tif (factor !== 1) {\n\t\t\t\t\t\tif (_isObject(result)) {\n\t\t\t\t\t\t\tcopy = {};\n\t\t\t\t\t\t\tfor (p in result) {\n\t\t\t\t\t\t\t\tcopy[p] = result[p] * factor;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tresult = copy;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresult *= factor;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn result; //we need to ensure that we can scope the function call to the Draggable instance itself so that users can access important values like maxX, minX, maxY, minY, x, and y from within that function.\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tvars.end = snap;\n\t\t\t}\n\t\t}\n\t\tif (max || max === 0) {\n\t\t\tvars.max = max;\n\t\t}\n\t\tif (min || min === 0) {\n\t\t\tvars.min = min;\n\t\t}\n\t\tif (forceZeroVelocity) {\n\t\t\tvars.velocity = 0;\n\t\t}\n\t\treturn vars;\n\t},\n\t_isClickable = element => { //sometimes it's convenient to mark an element as clickable by adding a data-clickable=\"true\" attribute (in which case we won't preventDefault() the mouse/touch event). This method checks if the element is an , , or