Files
MYSOPHAL/public/lib/gridstack.min.js
2025-11-09 10:02:18 +01:00

12 lines
92 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function(e){var n={};function t(i){if(n[i]){return n[i].exports}var o=n[i]={i:i,l:false,exports:{}};e[i].call(o.exports,o,o.exports,t);o.l=true;return o.exports}t.m=e;t.c=n;t.d=function(e,n,i){if(!t.o(e,n)){Object.defineProperty(e,n,{enumerable:true,get:i})}};t.r=function(e){if(typeof Symbol!=="undefined"&&Symbol.toStringTag){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}Object.defineProperty(e,"__esModule",{value:true})};t.t=function(e,n){if(n&1)e=t(e);if(n&8)return e;if(n&4&&typeof e==="object"&&e&&e.__esModule)return e;var i=Object.create(null);t.r(i);Object.defineProperty(i,"default",{enumerable:true,value:e});if(n&2&&typeof e!="string")for(var o in e)t.d(i,o,function(n){return e[n]}.bind(null,o));return i};t.n=function(e){var n=e&&e.__esModule?function n(){return e["default"]}:function n(){return e};t.d(n,"a",n);return n};t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)};t.p="";return t(t.s=493)})({10:function(e,n,t){try{var i=t(7);if(typeof i.inherits!=="function")throw"";e.exports=i.inherits}catch(n){e.exports=t(11)}},11:function(e,n){if(typeof Object.create==="function"){e.exports=function e(n,t){n.super_=t;n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:false,writable:true,configurable:true}})}}else{e.exports=function e(n,t){n.super_=t;var i=function(){};i.prototype=t.prototype;n.prototype=new i;n.prototype.constructor=n}}},12:function(e,n,t){"use strict";(function(n){var i=t(13);
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/function o(e,n){if(e===n){return 0}var t=e.length;var i=n.length;for(var o=0,r=Math.min(t,i);o<r;++o){if(e[o]!==n[o]){t=e[o];i=n[o];break}}if(t<i){return-1}if(i<t){return 1}return 0}function r(e){if(n.Buffer&&typeof n.Buffer.isBuffer==="function"){return n.Buffer.isBuffer(e)}return!!(e!=null&&e._isBuffer)}var a=t(7);var s=Object.prototype.hasOwnProperty;var d=Array.prototype.slice;var l=function(){return function e(){}.name==="foo"}();function h(e){return Object.prototype.toString.call(e)}function c(e){if(r(e)){return false}if(typeof n.ArrayBuffer!=="function"){return false}if(typeof ArrayBuffer.isView==="function"){return ArrayBuffer.isView(e)}if(!e){return false}if(e instanceof DataView){return true}if(e.buffer&&e.buffer instanceof ArrayBuffer){return true}return false}var u=e.exports=w;var f=/\s*function\s+([^\(\s]*)\s*/;function g(e){if(!a.isFunction(e)){return}if(l){return e.name}var n=e.toString();var t=n.match(f);return t&&t[1]}u.AssertionError=function e(n){this.name="AssertionError";this.actual=n.actual;this.expected=n.expected;this.operator=n.operator;if(n.message){this.message=n.message;this.generatedMessage=false}else{this.message=y(this);this.generatedMessage=true}var t=n.stackStartFunction||v;if(Error.captureStackTrace){Error.captureStackTrace(this,t)}else{var i=new Error;if(i.stack){var o=i.stack;var r=g(t);var a=o.indexOf("\n"+r);if(a>=0){var s=o.indexOf("\n",a+1);o=o.substring(s+1)}this.stack=o}}};a.inherits(u.AssertionError,Error);function p(e,n){if(typeof e==="string"){return e.length<n?e:e.slice(0,n)}else{return e}}function m(e){if(l||!a.isFunction(e)){return a.inspect(e)}var n=g(e);var t=n?": "+n:"";return"[Function"+t+"]"}function y(e){return p(m(e.actual),128)+" "+e.operator+" "+p(m(e.expected),128)}function v(e,n,t,i,o){throw new u.AssertionError({message:t,actual:e,expected:n,operator:i,stackStartFunction:o})}u.fail=v;function w(e,n){if(!e)v(e,true,n,"==",u.ok)}u.ok=w;u.equal=function e(n,t,i){if(n!=t)v(n,t,i,"==",u.equal)};u.notEqual=function e(n,t,i){if(n==t){v(n,t,i,"!=",u.notEqual)}};u.deepEqual=function e(n,t,i){if(!b(n,t,false)){v(n,t,i,"deepEqual",u.deepEqual)}};u.deepStrictEqual=function e(n,t,i){if(!b(n,t,true)){v(n,t,i,"deepStrictEqual",u.deepStrictEqual)}};function b(e,n,t,i){if(e===n){return true}else if(r(e)&&r(n)){return o(e,n)===0}else if(a.isDate(e)&&a.isDate(n)){return e.getTime()===n.getTime()}else if(a.isRegExp(e)&&a.isRegExp(n)){return e.source===n.source&&e.global===n.global&&e.multiline===n.multiline&&e.lastIndex===n.lastIndex&&e.ignoreCase===n.ignoreCase}else if((e===null||typeof e!=="object")&&(n===null||typeof n!=="object")){return t?e===n:e==n}else if(c(e)&&c(n)&&h(e)===h(n)&&!(e instanceof Float32Array||e instanceof Float64Array)){return o(new Uint8Array(e.buffer),new Uint8Array(n.buffer))===0}else if(r(e)!==r(n)){return false}else{i=i||{actual:[],expected:[]};var s=i.actual.indexOf(e);if(s!==-1){if(s===i.expected.indexOf(n)){return true}}i.actual.push(e);i.expected.push(n);return x(e,n,t,i)}}function _(e){return Object.prototype.toString.call(e)=="[object Arguments]"}function x(e,n,t,i){if(e===null||e===undefined||n===null||n===undefined)return false;if(a.isPrimitive(e)||a.isPrimitive(n))return e===n;if(t&&Object.getPrototypeOf(e)!==Object.getPrototypeOf(n))return false;var o=_(e);var r=_(n);if(o&&!r||!o&&r)return false;if(o){e=d.call(e);n=d.call(n);return b(e,n,t)}var s=D(e);var l=D(n);var h,c;if(s.length!==l.length)return false;s.sort();l.sort();for(c=s.length-1;c>=0;c--){if(s[c]!==l[c])return false}for(c=s.length-1;c>=0;c--){h=s[c];if(!b(e[h],n[h],t,i))return false}return true}u.notDeepEqual=function e(n,t,i){if(b(n,t,false)){v(n,t,i,"notDeepEqual",u.notDeepEqual)}};u.notDeepStrictEqual=k;function k(e,n,t){if(b(e,n,true)){v(e,n,t,"notDeepStrictEqual",k)}}u.strictEqual=function e(n,t,i){if(n!==t){v(n,t,i,"===",u.strictEqual)}};u.notStrictEqual=function e(n,t,i){if(n===t){v(n,t,i,"!==",u.notStrictEqual)}};function N(e,n){if(!e||!n){return false}if(Object.prototype.toString.call(n)=="[object RegExp]"){return n.test(e)}try{if(e instanceof n){return true}}catch(e){}if(Error.isPrototypeOf(n)){return false}return n.call({},e)===true}function S(e){var n;try{e()}catch(e){n=e}return n}function E(e,n,t,i){var o;if(typeof n!=="function"){throw new TypeError('"block" argument must be a function')}if(typeof t==="string"){i=t;t=null}o=S(n);i=(t&&t.name?" ("+t.name+").":".")+(i?" "+i:".");if(e&&!o){v(o,t,"Missing expected exception"+i)}var r=typeof i==="string";var s=!e&&a.isError(o);var d=!e&&o&&!t;if(s&&r&&N(o,t)||d){v(o,t,"Got unwanted exception"+i)}if(e&&o&&t&&!N(o,t)||!e&&o){throw o}}u.throws=function(e,n,t){E(true,e,n,t)};u.doesNotThrow=function(e,n,t){E(false,e,n,t)};u.ifError=function(e){if(e)throw e};function H(e,n){if(!e)v(e,true,n,"==",H)}u.strict=i(H,u,{equal:u.strictEqual,deepEqual:u.deepStrictEqual,notEqual:u.notStrictEqual,notDeepEqual:u.notDeepStrictEqual});u.strict.strict=u.strict;var D=Object.keys||function(e){var n=[];for(var t in e){if(s.call(e,t))n.push(t)}return n}}).call(this,t(6))},13:function(e,n,t){"use strict";
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/var i=Object.getOwnPropertySymbols;var o=Object.prototype.hasOwnProperty;var r=Object.prototype.propertyIsEnumerable;function a(e){if(e===null||e===undefined){throw new TypeError("Object.assign cannot be called with null or undefined")}return Object(e)}function s(){try{if(!Object.assign){return false}var e=new String("abc");e[5]="de";if(Object.getOwnPropertyNames(e)[0]==="5"){return false}var n={};for(var t=0;t<10;t++){n["_"+String.fromCharCode(t)]=t}var i=Object.getOwnPropertyNames(n).map((function(e){return n[e]}));if(i.join("")!=="0123456789"){return false}var o={};"abcdefghijklmnopqrst".split("").forEach((function(e){o[e]=e}));if(Object.keys(Object.assign({},o)).join("")!=="abcdefghijklmnopqrst"){return false}return true}catch(e){return false}}e.exports=s()?Object.assign:function(e,n){var t;var s=a(e);var d;for(var l=1;l<arguments.length;l++){t=Object(arguments[l]);for(var h in t){if(o.call(t,h)){s[h]=t[h]}}if(i){d=i(t);for(var c=0;c<d.length;c++){if(r.call(t,d[c])){s[d[c]]=t[d[c]]}}}}return s}},4:function(e,n,t){(function(n){e.exports=function(e){function t(e){typeof n!=="undefined"&&(n.error||n.log)("[Script Loader]",e)}function i(){return typeof attachEvent!=="undefined"&&typeof addEventListener==="undefined"}try{if(typeof execScript!=="undefined"&&i()){execScript(e)}else if(typeof eval!=="undefined"){eval.call(null,e)}else{t("EvalError: No eval function available")}}catch(e){t(e)}}}).call(this,t(5))},493:function(e,n,t){t(494);t(496);t(498);t(499)},494:function(e,n,t){t(4)(t(495))},495:function(e,n){e.exports="/**\n * gridstack.js 0.6.3\n * https://gridstackjs.com/\n * (c) 2014-2020 Alain Dumesny, Dylan Weiss, Pavel Reznikov\n * gridstack.js may be freely distributed under the MIT license.\n * @preserve\n*/\n(function(factory) {\n if (typeof define === 'function' && define.amd) {\n define(['jquery', 'exports'], factory);\n } else if (typeof exports !== 'undefined') {\n var jQueryModule;\n\n try { jQueryModule = require('jquery'); } catch (e) {}\n\n factory(jQueryModule || window.jQuery, exports);\n } else {\n factory(window.jQuery, window);\n }\n})(function($, scope) {\n\n // checks for obsolete method names\n var obsolete = function(f, oldName, newName, rev) {\n var wrapper = function() {\n console.warn('gridstack.js: Function `' + oldName + '` is deprecated in ' + rev + ' and has been replaced ' +\n 'with `' + newName + '`. It will be **completely** removed in v1.0');\n return f.apply(this, arguments);\n };\n wrapper.prototype = f.prototype;\n\n return wrapper;\n };\n\n // checks for obsolete grid options (can be used for any fields, but msg is about options)\n var obsoleteOpts = function(opts, oldName, newName, rev) {\n if (opts[oldName] !== undefined) {\n opts[newName] = opts[oldName];\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + ' and has been replaced with `' +\n newName + '`. It will be **completely** removed in v1.0');\n }\n };\n\n // checks for obsolete grid options which are gone\n var obsoleteOptsDel = function(opts, oldName, rev, info) {\n if (opts[oldName] !== undefined) {\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + info);\n }\n };\n\n // checks for obsolete Jquery element attributes\n var obsoleteAttr = function(el, oldName, newName, rev) {\n var oldAttr = el.attr(oldName);\n if (oldAttr !== undefined) {\n el.attr(newName, oldAttr);\n console.warn('gridstack.js: attribute `' + oldName + '`=' + oldAttr + ' is deprecated on this object in ' + rev + ' and has been replaced with `' +\n newName + '`. It will be **completely** removed in v1.0');\n }\n };\n\n var Utils = {\n\n isIntercepted: function(a, b) {\n return !(a.x + a.width <= b.x || b.x + b.width <= a.x || a.y + a.height <= b.y || b.y + b.height <= a.y);\n },\n\n sort: function(nodes, dir, column) {\n if (!column) {\n var widths = nodes.map(function(node) { return node.x + node.width; });\n column = Math.max.apply(Math, widths);\n }\n\n if (dir === -1)\n return Utils.sortBy(nodes, function(n) { return -(n.x + n.y * column); });\n else\n return Utils.sortBy(nodes, function(n) { return (n.x + n.y * column); });\n },\n\n createStylesheet: function(id) {\n var style = document.createElement('style');\n style.setAttribute('type', 'text/css');\n style.setAttribute('data-gs-style-id', id);\n if (style.styleSheet) {\n style.styleSheet.cssText = '';\n } else {\n style.appendChild(document.createTextNode(''));\n }\n document.getElementsByTagName('head')[0].appendChild(style);\n return style.sheet;\n },\n\n removeStylesheet: function(id) {\n $('STYLE[data-gs-style-id=' + id + ']').remove();\n },\n\n insertCSSRule: function(sheet, selector, rules, index) {\n if (typeof sheet.insertRule === 'function') {\n sheet.insertRule(selector + '{' + rules + '}', index);\n } else if (typeof sheet.addRule === 'function') {\n sheet.addRule(selector, rules, index);\n }\n },\n\n toBool: function(v) {\n if (typeof v === 'boolean') {\n return v;\n }\n if (typeof v === 'string') {\n v = v.toLowerCase();\n return !(v === '' || v === 'no' || v === 'false' || v === '0');\n }\n return Boolean(v);\n },\n\n _collisionNodeCheck: function(n) {\n return n !== this.node && Utils.isIntercepted(n, this.nn);\n },\n\n _didCollide: function(bn) {\n return Utils.isIntercepted({x: this.n.x, y: this.newY, width: this.n.width, height: this.n.height}, bn);\n },\n\n _isAddNodeIntercepted: function(n) {\n return Utils.isIntercepted({x: this.x, y: this.y, width: this.node.width, height: this.node.height}, n);\n },\n\n parseHeight: function(val) {\n var height = val;\n var heightUnit = 'px';\n if (height && typeof height === 'string') {\n var match = height.match(/^(-[0-9]+\\.[0-9]+|[0-9]*\\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/);\n if (!match) {\n throw new Error('Invalid height');\n }\n heightUnit = match[2] || 'px';\n height = parseFloat(match[1]);\n }\n return {height: height, unit: heightUnit};\n },\n\n without: function(array, item) {\n var index = array.indexOf(item);\n\n if (index !== -1) {\n array = array.slice(0);\n array.splice(index, 1);\n }\n\n return array;\n },\n\n sortBy: function(array, getter) {\n return array.slice(0).sort(function(left, right) {\n var valueLeft = getter(left);\n var valueRight = getter(right);\n\n if (valueRight === valueLeft) {\n return 0;\n }\n\n return valueLeft > valueRight ? 1 : -1;\n });\n },\n\n defaults: function(target) {\n var sources = Array.prototype.slice.call(arguments, 1);\n\n sources.forEach(function(source) {\n for (var prop in source) {\n if (source.hasOwnProperty(prop) && (!target.hasOwnProperty(prop) || target[prop] === undefined)) {\n target[prop] = source[prop];\n }\n }\n });\n\n return target;\n },\n\n clone: function(target) {\n return $.extend({}, target);\n },\n\n throttle: function(callback, delay) {\n var isWaiting = false;\n\n return function() {\n if (!isWaiting) {\n callback.apply(this, arguments);\n isWaiting = true;\n setTimeout(function() { isWaiting = false; }, delay);\n }\n };\n },\n\n removePositioningStyles: function(el) {\n var style = el[0].style;\n if (style.position) {\n style.removeProperty('position');\n }\n if (style.left) {\n style.removeProperty('left');\n }\n if (style.top) {\n style.removeProperty('top');\n }\n if (style.width) {\n style.removeProperty('width');\n }\n if (style.height) {\n style.removeProperty('height');\n }\n },\n getScrollParent: function(el) {\n var returnEl;\n if (el === null) {\n returnEl = null;\n } else if (el.scrollHeight > el.clientHeight) {\n returnEl = el;\n } else {\n returnEl = Utils.getScrollParent(el.parentNode);\n }\n return returnEl;\n },\n updateScrollPosition: function(el, ui, distance) {\n // is widget in view?\n var rect = el.getBoundingClientRect();\n var innerHeightOrClientHeight = (window.innerHeight || document.documentElement.clientHeight);\n if (rect.top < 0 ||\n rect.bottom > innerHeightOrClientHeight\n ) {\n // set scrollTop of first parent that scrolls\n // if parent is larger than el, set as low as possible\n // to get entire widget on screen\n var offsetDiffDown = rect.bottom - innerHeightOrClientHeight;\n var offsetDiffUp = rect.top;\n var scrollEl = Utils.getScrollParent(el);\n if (scrollEl !== null) {\n var prevScroll = scrollEl.scrollTop;\n if (rect.top < 0 && distance < 0) {\n // moving up\n if (el.offsetHeight > innerHeightOrClientHeight) {\n scrollEl.scrollTop += distance;\n } else {\n scrollEl.scrollTop += Math.abs(offsetDiffUp) > Math.abs(distance) ? distance : offsetDiffUp;\n }\n } else if (distance > 0) {\n // moving down\n if (el.offsetHeight > innerHeightOrClientHeight) {\n scrollEl.scrollTop += distance;\n } else {\n scrollEl.scrollTop += offsetDiffDown > distance ? distance : offsetDiffDown;\n }\n }\n // move widget y by amount scrolled\n ui.position.top += scrollEl.scrollTop - prevScroll;\n }\n }\n }\n };\n\n /**\n * @class GridStackDragDropPlugin\n * Base class for drag'n'drop plugin.\n */\n function GridStackDragDropPlugin(grid) {\n this.grid = grid;\n }\n\n GridStackDragDropPlugin.registeredPlugins = [];\n\n GridStackDragDropPlugin.registerPlugin = function(pluginClass) {\n GridStackDragDropPlugin.registeredPlugins.push(pluginClass);\n };\n\n GridStackDragDropPlugin.prototype.resizable = function(el, opts) {\n return this;\n };\n\n GridStackDragDropPlugin.prototype.draggable = function(el, opts) {\n return this;\n };\n\n GridStackDragDropPlugin.prototype.droppable = function(el, opts) {\n return this;\n };\n\n GridStackDragDropPlugin.prototype.isDroppable = function(el) {\n return false;\n };\n\n GridStackDragDropPlugin.prototype.on = function(el, eventName, callback) {\n return this;\n };\n\n\n var idSeq = 0;\n\n var GridStackEngine = function(column, onchange, float, maxRow, items) {\n this.column = column || 12;\n this.float = float || false;\n this.maxRow = maxRow || 0;\n\n this.nodes = items || [];\n this.onchange = onchange || function() {};\n\n this._addedNodes = [];\n this._removedNodes = [];\n this._batchMode = false;\n };\n\n GridStackEngine.prototype.batchUpdate = function() {\n if (this._batchMode) return;\n this._batchMode = true;\n this._prevFloat = this.float;\n this.float = true; // let things go anywhere for now... commit() will restore and possibly reposition\n };\n\n GridStackEngine.prototype.commit = function() {\n if (!this._batchMode) return;\n this._batchMode = false;\n this.float = this._prevFloat;\n delete this._prevFloat;\n this._packNodes();\n this._notify();\n };\n\n // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272\n GridStackEngine.prototype.getNodeDataByDOMEl = function(el) {\n return this.nodes.find(function(n) { return el.get(0) === n.el.get(0); });\n };\n\n GridStackEngine.prototype._fixCollisions = function(node) {\n var self = this;\n this._sortNodes(-1);\n\n var nn = node;\n var hasLocked = Boolean(this.nodes.find(function(n) { return n.locked; }));\n if (!this.float && !hasLocked) {\n nn = {x: 0, y: node.y, width: this.column, height: node.height};\n }\n while (true) {\n var collisionNode = this.nodes.find(Utils._collisionNodeCheck, {node: node, nn: nn});\n if (!collisionNode) { return; }\n this.moveNode(collisionNode, collisionNode.x, node.y + node.height,\n collisionNode.width, collisionNode.height, true);\n }\n };\n\n GridStackEngine.prototype.isAreaEmpty = function(x, y, width, height) {\n var nn = {x: x || 0, y: y || 0, width: width || 1, height: height || 1};\n var collisionNode = this.nodes.find(function(n) {\n return Utils.isIntercepted(n, nn);\n });\n return !collisionNode;\n };\n\n GridStackEngine.prototype._sortNodes = function(dir) {\n this.nodes = Utils.sort(this.nodes, dir, this.column);\n };\n\n GridStackEngine.prototype._packNodes = function() {\n this._sortNodes();\n\n if (this.float) {\n this.nodes.forEach(function(n, i) {\n if (n._updating || n._packY === undefined || n.y === n._packY) {\n return;\n }\n\n var newY = n.y;\n while (newY >= n._packY) {\n var collisionNode = this.nodes\n .slice(0, i)\n .find(Utils._didCollide, {n: n, newY: newY});\n\n if (!collisionNode) {\n n._dirty = true;\n n.y = newY;\n }\n --newY;\n }\n }, this);\n } else {\n this.nodes.forEach(function(n, i) {\n if (n.locked) { return; }\n while (n.y > 0) {\n var newY = n.y - 1;\n var canBeMoved = i === 0;\n\n if (i > 0) {\n var collisionNode = this.nodes\n .slice(0, i)\n .find(Utils._didCollide, {n: n, newY: newY});\n canBeMoved = collisionNode === undefined;\n }\n\n if (!canBeMoved) { break; }\n // Note: must be dirty (from last position) for GridStack::OnChange CB to update positions\n // and move items back. The user 'change' CB should detect changes from the original\n // starting position instead.\n n._dirty = (n.y !== newY);\n n.y = newY;\n }\n }, this);\n }\n };\n\n GridStackEngine.prototype._prepareNode = function(node, resizing) {\n node = node || {};\n // if we're missing position, have the grid position us automatically (before we set them to 0,0)\n if (node.x === undefined || node.y === undefined || node.x === null || node.y === null) {\n node.autoPosition = true;\n }\n\n // assign defaults for missing required fields\n var defaults = {width: 1, height: 1, x: 0, y: 0};\n node = Utils.defaults(node, defaults);\n\n // convert any strings over\n node.x = parseInt(node.x);\n node.y = parseInt(node.y);\n node.width = parseInt(node.width);\n node.height = parseInt(node.height);\n node.autoPosition = node.autoPosition || false;\n node.noResize = node.noResize || false;\n node.noMove = node.noMove || false;\n\n // check for NaN (in case messed up strings were passed. can't do parseInt() || defaults.x above as 0 is valid #)\n if (Number.isNaN(node.x)) { node.x = defaults.x; node.autoPosition = true; }\n if (Number.isNaN(node.y)) { node.y = defaults.y; node.autoPosition = true; }\n if (Number.isNaN(node.width)) { node.width = defaults.width; }\n if (Number.isNaN(node.height)) { node.height = defaults.height; }\n\n if (node.width > this.column) {\n node.width = this.column;\n } else if (node.width < 1) {\n node.width = 1;\n }\n\n if (node.height < 1) {\n node.height = 1;\n }\n\n if (node.x < 0) {\n node.x = 0;\n }\n\n if (node.x + node.width > this.column) {\n if (resizing) {\n node.width = this.column - node.x;\n } else {\n node.x = this.column - node.width;\n }\n }\n\n if (node.y < 0) {\n node.y = 0;\n }\n\n return node;\n };\n\n GridStackEngine.prototype._notify = function() {\n if (this._batchMode) { return; }\n var args = Array.prototype.slice.call(arguments, 0);\n args[0] = (args[0] === undefined ? [] : (Array.isArray(args[0]) ? args[0] : [args[0]]) );\n args[1] = (args[1] === undefined ? true : args[1]);\n var dirtyNodes = args[0].concat(this.getDirtyNodes());\n this.onchange(dirtyNodes, args[1]);\n };\n\n GridStackEngine.prototype.cleanNodes = function() {\n if (this._batchMode) { return; }\n this.nodes.forEach(function(n) { delete n._dirty; });\n };\n\n GridStackEngine.prototype.getDirtyNodes = function() {\n return this.nodes.filter(function(n) { return n._dirty; });\n };\n\n GridStackEngine.prototype.addNode = function(node, triggerAddEvent) {\n var prev = {x: node.x, y: node.y, width: node.width, height: node.height};\n\n node = this._prepareNode(node);\n\n if (node.maxWidth !== undefined) { node.width = Math.min(node.width, node.maxWidth); }\n if (node.maxHeight !== undefined) { node.height = Math.min(node.height, node.maxHeight); }\n if (node.minWidth !== undefined) { node.width = Math.max(node.width, node.minWidth); }\n if (node.minHeight !== undefined) { node.height = Math.max(node.height, node.minHeight); }\n\n node._id = node._id || ++idSeq;\n\n if (node.autoPosition) {\n this._sortNodes();\n\n for (var i = 0;; ++i) {\n var x = i % this.column;\n var y = Math.floor(i / this.column);\n if (x + node.width > this.column) {\n continue;\n }\n if (!this.nodes.find(Utils._isAddNodeIntercepted, {x: x, y: y, node: node})) {\n node.x = x;\n node.y = y;\n delete node.autoPosition; // found our slot\n break;\n }\n }\n }\n\n this.nodes.push(node);\n if (triggerAddEvent) {\n this._addedNodes.push(node);\n }\n // use single equal as they come as string/undefined but end as number....\n if (!node._dirty && (prev.x != node.x || prev.y != node.y || prev.width != node.width || prev.height != node.height)) {\n node._dirty = true;\n }\n\n this._fixCollisions(node);\n this._packNodes();\n this._notify();\n return node;\n };\n\n GridStackEngine.prototype.removeNode = function(node, detachNode) {\n detachNode = (detachNode === undefined ? true : detachNode);\n this._removedNodes.push(node);\n node._id = null; // hint that node is being removed\n this.nodes = Utils.without(this.nodes, node);\n this._packNodes();\n this._notify(node, detachNode);\n };\n\n GridStackEngine.prototype.removeAll = function(detachNode) {\n delete this._layouts;\n if (this.nodes.length === 0) { return; }\n detachNode = (detachNode === undefined ? true : detachNode);\n this.nodes.forEach(function(n) { n._id = null; }); // hint that node is being removed\n this._removedNodes = this.nodes;\n this.nodes = [];\n this._notify(this._removedNodes, detachNode);\n };\n\n GridStackEngine.prototype.canMoveNode = function(node, x, y, width, height) {\n if (!this.isNodeChangedPosition(node, x, y, width, height)) {\n return false;\n }\n var hasLocked = Boolean(this.nodes.find(function(n) { return n.locked; }));\n\n if (!this.maxRow && !hasLocked) {\n return true;\n }\n\n var clonedNode;\n var clone = new GridStackEngine(\n this.column,\n null,\n this.float,\n 0,\n this.nodes.map(function(n) {\n if (n === node) {\n clonedNode = $.extend({}, n);\n return clonedNode;\n }\n return $.extend({}, n);\n }));\n\n if (!clonedNode) { return true;}\n\n clone.moveNode(clonedNode, x, y, width, height);\n\n var res = true;\n\n if (hasLocked) {\n res &= !Boolean(clone.nodes.find(function(n) {\n return n !== clonedNode && Boolean(n.locked) && Boolean(n._dirty);\n }));\n }\n if (this.maxRow) {\n res &= clone.getGridHeight() <= this.maxRow;\n }\n\n return res;\n };\n\n GridStackEngine.prototype.canBePlacedWithRespectToHeight = function(node) {\n if (!this.maxRow) {\n return true;\n }\n\n var clone = new GridStackEngine(\n this.column,\n null,\n this.float,\n 0,\n this.nodes.map(function(n) { return $.extend({}, n); }));\n clone.addNode(node);\n return clone.getGridHeight() <= this.maxRow;\n };\n\n GridStackEngine.prototype.isNodeChangedPosition = function(node, x, y, width, height) {\n if (typeof x !== 'number') { x = node.x; }\n if (typeof y !== 'number') { y = node.y; }\n if (typeof width !== 'number') { width = node.width; }\n if (typeof height !== 'number') { height = node.height; }\n\n if (node.maxWidth !== undefined) { width = Math.min(width, node.maxWidth); }\n if (node.maxHeight !== undefined) { height = Math.min(height, node.maxHeight); }\n if (node.minWidth !== undefined) { width = Math.max(width, node.minWidth); }\n if (node.minHeight !== undefined) { height = Math.max(height, node.minHeight); }\n\n if (node.x === x && node.y === y && node.width === width && node.height === height) {\n return false;\n }\n return true;\n };\n\n GridStackEngine.prototype.moveNode = function(node, x, y, width, height, noPack) {\n if (typeof x !== 'number') { x = node.x; }\n if (typeof y !== 'number') { y = node.y; }\n if (typeof width !== 'number') { width = node.width; }\n if (typeof height !== 'number') { height = node.height; }\n\n if (node.maxWidth !== undefined) { width = Math.min(width, node.maxWidth); }\n if (node.maxHeight !== undefined) { height = Math.min(height, node.maxHeight); }\n if (node.minWidth !== undefined) { width = Math.max(width, node.minWidth); }\n if (node.minHeight !== undefined) { height = Math.max(height, node.minHeight); }\n\n if (node.x === x && node.y === y && node.width === width && node.height === height) {\n return node;\n }\n\n var resizing = node.width !== width;\n node._dirty = true;\n\n node.x = x;\n node.y = y;\n node.width = width;\n node.height = height;\n\n node.lastTriedX = x;\n node.lastTriedY = y;\n node.lastTriedWidth = width;\n node.lastTriedHeight = height;\n\n node = this._prepareNode(node, resizing);\n\n this._fixCollisions(node);\n if (!noPack) {\n this._packNodes();\n this._notify();\n }\n return node;\n };\n\n GridStackEngine.prototype.getGridHeight = function() {\n return this.nodes.reduce(function(memo, n) { return Math.max(memo, n.y + n.height); }, 0);\n };\n\n GridStackEngine.prototype.beginUpdate = function(node) {\n if (node._updating) return;\n node._updating = true;\n this.nodes.forEach(function(n) { n._packY = n.y; });\n };\n\n GridStackEngine.prototype.endUpdate = function() {\n var n = this.nodes.find(function(n) { return n._updating; });\n if (n) {\n n._updating = false;\n this.nodes.forEach(function(n) { delete n._packY; });\n }\n };\n\n var GridStack = function(el, opts) {\n var self = this;\n var oneColumnMode, _prevColumn, isAutoCellHeight;\n\n opts = opts || {};\n\n this.container = $(el);\n\n obsoleteOpts(opts, 'width', 'column', 'v0.5.3');\n obsoleteOpts(opts, 'height', 'maxRow', 'v0.5.3');\n obsoleteOptsDel(opts, 'oneColumnModeClass', 'v0.6.3', '. Use class `.grid-stack-1` instead');\n\n // container attributes\n obsoleteAttr(this.container, 'data-gs-width', 'data-gs-column', 'v0.5.3');\n obsoleteAttr(this.container, 'data-gs-height', 'data-gs-max-row', 'v0.5.3');\n\n opts.itemClass = opts.itemClass || 'grid-stack-item';\n var isNested = this.container.closest('.' + opts.itemClass).length > 0;\n\n this.opts = Utils.defaults(opts, {\n column: parseInt(this.container.attr('data-gs-column')) || 12,\n maxRow: parseInt(this.container.attr('data-gs-max-row')) || 0,\n itemClass: 'grid-stack-item',\n placeholderClass: 'grid-stack-placeholder',\n placeholderText: '',\n handle: '.grid-stack-item-content',\n handleClass: null,\n cellHeight: 60,\n verticalMargin: 20,\n auto: true,\n minWidth: 768,\n float: false,\n staticGrid: false,\n _class: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0),\n animate: Boolean(this.container.attr('data-gs-animate')) || false,\n alwaysShowResizeHandle: opts.alwaysShowResizeHandle || false,\n resizable: Utils.defaults(opts.resizable || {}, {\n autoHide: !(opts.alwaysShowResizeHandle || false),\n handles: 'se'\n }),\n draggable: Utils.defaults(opts.draggable || {}, {\n handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) ||\n '.grid-stack-item-content',\n scroll: false,\n appendTo: 'body'\n }),\n disableDrag: opts.disableDrag || false,\n disableResize: opts.disableResize || false,\n rtl: 'auto',\n removable: false,\n removableOptions: Utils.defaults(opts.removableOptions || {}, {\n accept: '.' + opts.itemClass\n }),\n removeTimeout: 2000,\n verticalMarginUnit: 'px',\n cellHeightUnit: 'px',\n disableOneColumnMode: opts.disableOneColumnMode || false,\n oneColumnModeDomSort: opts.oneColumnModeDomSort,\n ddPlugin: null\n });\n\n if (this.opts.ddPlugin === false) {\n this.opts.ddPlugin = GridStackDragDropPlugin;\n } else if (this.opts.ddPlugin === null) {\n this.opts.ddPlugin = GridStackDragDropPlugin.registeredPlugins[0] || GridStackDragDropPlugin;\n }\n\n this.dd = new this.opts.ddPlugin(this);\n\n if (this.opts.rtl === 'auto') {\n this.opts.rtl = this.container.css('direction') === 'rtl';\n }\n\n if (this.opts.rtl) {\n this.container.addClass('grid-stack-rtl');\n }\n\n this.opts.isNested = isNested;\n\n isAutoCellHeight = (this.opts.cellHeight === 'auto');\n if (isAutoCellHeight) {\n // make the cell square initially\n self.cellHeight(self.cellWidth(), true);\n } else {\n this.cellHeight(this.opts.cellHeight, true);\n }\n this.verticalMargin(this.opts.verticalMargin, true);\n\n this.container.addClass(this.opts._class);\n\n this._setStaticClass();\n\n if (isNested) {\n this.container.addClass('grid-stack-nested');\n }\n\n this._initStyles();\n\n this.grid = new GridStackEngine(this.opts.column, function(nodes, detachNode) {\n detachNode = (detachNode === undefined ? true : detachNode);\n var maxHeight = 0;\n this.nodes.forEach(function(n) {\n maxHeight = Math.max(maxHeight, n.y + n.height);\n });\n nodes.forEach(function(n) {\n if (detachNode && n._id === null) {\n if (n.el) {\n n.el.remove();\n }\n } else {\n n.el\n .attr('data-gs-x', n.x)\n .attr('data-gs-y', n.y)\n .attr('data-gs-width', n.width)\n .attr('data-gs-height', n.height);\n }\n });\n self._updateStyles(maxHeight + 10);\n }, this.opts.float, this.opts.maxRow);\n\n if (this.opts.auto) {\n var elements = [];\n var _this = this;\n this.container.children('.' + this.opts.itemClass + ':not(.' + this.opts.placeholderClass + ')')\n .each(function(index, el) {\n el = $(el);\n var x = parseInt(el.attr('data-gs-x'));\n var y = parseInt(el.attr('data-gs-y'));\n elements.push({\n el: el,\n // if x,y are missing (autoPosition) add them to end of list - but keep their respective DOM order\n i: (Number.isNaN(x) ? 1000 : x) + (Number.isNaN(y) ? 1000 : y) * _this.opts.column\n });\n });\n Utils.sortBy(elements, function(x) { return x.i; }).forEach(function(item) {\n this._prepareElement(item.el);\n }, this);\n }\n\n this.setAnimation(this.opts.animate);\n\n this.placeholder = $(\n '<div class=\"' + this.opts.placeholderClass + ' ' + this.opts.itemClass + '\">' +\n '<div class=\"placeholder-content\">' + this.opts.placeholderText + '</div></div>').hide();\n\n this._updateContainerHeight();\n\n this._updateHeightsOnResize = Utils.throttle(function() {\n self.cellHeight(self.cellWidth(), false);\n }, 100);\n\n /**\n * called when we are being resized - check if the one Column Mode needs to be turned on/off\n * and remember the prev columns we used.\n */\n this.onResizeHandler = function() {\n if (isAutoCellHeight) {\n self._updateHeightsOnResize();\n }\n\n if (self.opts.staticGrid) { return; }\n\n if (!self.opts.disableOneColumnMode && (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= self.opts.minWidth) {\n if (self.oneColumnMode) { return; }\n self.oneColumnMode = true;\n self.setColumn(1);\n } else {\n if (!self.oneColumnMode) { return; }\n self.oneColumnMode = false;\n self.setColumn(self._prevColumn);\n }\n };\n\n $(window).resize(this.onResizeHandler);\n this.onResizeHandler();\n\n if (!self.opts.staticGrid && typeof self.opts.removable === 'string') {\n var trashZone = $(self.opts.removable);\n if (!this.dd.isDroppable(trashZone)) {\n this.dd.droppable(trashZone, self.opts.removableOptions);\n }\n this.dd\n .on(trashZone, 'dropover', function(event, ui) {\n var el = $(ui.draggable);\n var node = el.data('_gridstack_node');\n if (!node || node._grid !== self) {\n return;\n }\n el.data('inTrashZone', true);\n self._setupRemovingTimeout(el);\n })\n .on(trashZone, 'dropout', function(event, ui) {\n var el = $(ui.draggable);\n var node = el.data('_gridstack_node');\n if (!node || node._grid !== self) {\n return;\n }\n el.data('inTrashZone', false);\n self._clearRemovingTimeout(el);\n });\n }\n\n if (!self.opts.staticGrid && self.opts.acceptWidgets) {\n var draggingElement = null;\n\n var onDrag = function(event, ui) {\n var el = draggingElement;\n var node = el.data('_gridstack_node');\n var pos = self.getCellFromPixel({left: event.pageX, top: event.pageY}, true);\n var x = Math.max(0, pos.x);\n var y = Math.max(0, pos.y);\n if (!node._added) {\n node._added = true;\n\n node.el = el;\n node.autoPosition = true;\n node.x = x;\n node.y = y;\n self.grid.cleanNodes();\n self.grid.beginUpdate(node);\n self.grid.addNode(node);\n\n self.container.append(self.placeholder);\n self.placeholder\n .attr('data-gs-x', node.x)\n .attr('data-gs-y', node.y)\n .attr('data-gs-width', node.width)\n .attr('data-gs-height', node.height)\n .show();\n node.el = self.placeholder;\n node._beforeDragX = node.x;\n node._beforeDragY = node.y;\n\n self._updateContainerHeight();\n }\n if (!self.grid.canMoveNode(node, x, y)) {\n return;\n }\n self.grid.moveNode(node, x, y);\n self._updateContainerHeight();\n };\n\n this.dd\n .droppable(self.container, {\n accept: function(el) {\n el = $(el);\n var node = el.data('_gridstack_node');\n if (node && node._grid === self) {\n return false;\n }\n return el.is(self.opts.acceptWidgets === true ? '.grid-stack-item' : self.opts.acceptWidgets);\n }\n })\n .on(self.container, 'dropover', function(event, ui) {\n var el = $(ui.draggable);\n var width, height;\n\n // see if we already have a node with widget/height and check for attributes\n var origNode = el.data('_gridstack_node');\n if (!origNode || !origNode.width || !origNode.height) {\n var w = parseInt(el.attr('data-gs-width'));\n if (w > 0) { origNode = origNode || {}; origNode.width = w; }\n var h = parseInt(el.attr('data-gs-height'));\n if (h > 0) { origNode = origNode || {}; origNode.height = h; }\n }\n\n // if not calculate the grid size based on element outer size\n // height: Each row is cellHeight + verticalMargin, until last one which has no margin below\n var cellWidth = self.cellWidth();\n var cellHeight = self.cellHeight();\n var verticalMargin = self.opts.verticalMargin;\n width = origNode && origNode.width ? origNode.width : Math.ceil(el.outerWidth() / cellWidth);\n height = origNode && origNode.height ? origNode.height : Math.round((el.outerHeight() + verticalMargin) / (cellHeight + verticalMargin));\n\n draggingElement = el;\n\n var node = self.grid._prepareNode({width: width, height: height, _added: false, _temporary: true});\n node.isOutOfGrid = true;\n el.data('_gridstack_node', node);\n el.data('_gridstack_node_orig', origNode);\n\n el.on('drag', onDrag);\n })\n .on(self.container, 'dropout', function(event, ui) {\n // jquery-ui bug. Must verify widget is being dropped out\n // check node variable that gets set when widget is out of grid\n var el = $(ui.draggable);\n if (!el.data('_gridstack_node')) {\n return;\n }\n var node = el.data('_gridstack_node');\n if (!node.isOutOfGrid) {\n return;\n }\n el.unbind('drag', onDrag);\n node.el = null;\n self.grid.removeNode(node);\n self.placeholder.detach();\n self._updateContainerHeight();\n el.data('_gridstack_node', el.data('_gridstack_node_orig'));\n })\n .on(self.container, 'drop', function(event, ui) {\n self.placeholder.detach();\n\n var node = $(ui.draggable).data('_gridstack_node');\n node.isOutOfGrid = false;\n node._grid = self;\n var el = $(ui.draggable).clone(false);\n el.data('_gridstack_node', node);\n var originalNode = $(ui.draggable).data('_gridstack_node_orig');\n if (originalNode !== undefined && originalNode._grid !== undefined) {\n originalNode._grid._triggerRemoveEvent();\n }\n $(ui.helper).remove();\n node.el = el;\n self.placeholder.hide();\n Utils.removePositioningStyles(el);\n el.find('div.ui-resizable-handle').remove();\n\n el\n .attr('data-gs-x', node.x)\n .attr('data-gs-y', node.y)\n .attr('data-gs-width', node.width)\n .attr('data-gs-height', node.height)\n .addClass(self.opts.itemClass)\n .enableSelection()\n .removeData('draggable')\n .removeClass('ui-draggable ui-draggable-dragging ui-draggable-disabled')\n .unbind('drag', onDrag);\n self.container.append(el);\n self._prepareElementsByNode(el, node);\n self._updateContainerHeight();\n self.grid._addedNodes.push(node);\n self._triggerAddEvent();\n self._triggerChangeEvent();\n\n self.grid.endUpdate();\n $(ui.draggable).unbind('drag', onDrag);\n $(ui.draggable).removeData('_gridstack_node');\n $(ui.draggable).removeData('_gridstack_node_orig');\n self.container.trigger('dropped', [originalNode, node]);\n });\n }\n };\n\n GridStack.prototype._triggerChangeEvent = function(/*forceTrigger*/) {\n if (this.grid._batchMode) { return; }\n // TODO: compare original X,Y,W,H (or entire node?) instead as _dirty can be a temporary state\n var elements = this.grid.getDirtyNodes();\n if (elements && elements.length) {\n this.grid._layoutsNodesChange(elements);\n this.container.trigger('change', [elements]);\n this.grid.cleanNodes(); // clear dirty flags now that we called\n }\n };\n\n GridStack.prototype._triggerAddEvent = function() {\n if (this.grid._batchMode) { return; }\n if (this.grid._addedNodes && this.grid._addedNodes.length > 0) {\n this.grid._layoutsNodesChange(this.grid._addedNodes);\n this.container.trigger('added', [this.grid._addedNodes]);\n this.grid._addedNodes = [];\n }\n };\n\n GridStack.prototype._triggerRemoveEvent = function() {\n if (this.grid._batchMode) { return; }\n if (this.grid._removedNodes && this.grid._removedNodes.length > 0) {\n this.container.trigger('removed', [this.grid._removedNodes]);\n this.grid._removedNodes = [];\n }\n };\n\n GridStack.prototype._initStyles = function() {\n if (this._stylesId) {\n Utils.removeStylesheet(this._stylesId);\n }\n this._stylesId = 'gridstack-style-' + (Math.random() * 100000).toFixed();\n this._styles = Utils.createStylesheet(this._stylesId);\n if (this._styles !== null) {\n this._styles._max = 0;\n }\n };\n\n GridStack.prototype._updateStyles = function(maxHeight) {\n if (this._styles === null || this._styles === undefined) {\n return;\n }\n\n var prefix = '.' + this.opts._class + ' .' + this.opts.itemClass;\n var self = this;\n var getHeight;\n\n if (maxHeight === undefined) {\n maxHeight = this._styles._max;\n }\n\n this._initStyles();\n this._updateContainerHeight();\n if (!this.opts.cellHeight) { // The rest will be handled by CSS\n return ;\n }\n if (this._styles._max !== 0 && maxHeight <= this._styles._max) { // Keep this._styles._max increasing\n return ;\n }\n\n if (!this.opts.verticalMargin || this.opts.cellHeightUnit === this.opts.verticalMarginUnit) {\n getHeight = function(nbRows, nbMargins) {\n return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) +\n self.opts.cellHeightUnit;\n };\n } else {\n getHeight = function(nbRows, nbMargins) {\n if (!nbRows || !nbMargins) {\n return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) +\n self.opts.cellHeightUnit;\n }\n return 'calc(' + ((self.opts.cellHeight * nbRows) + self.opts.cellHeightUnit) + ' + ' +\n ((self.opts.verticalMargin * nbMargins) + self.opts.verticalMarginUnit) + ')';\n };\n }\n\n if (this._styles._max === 0) {\n Utils.insertCSSRule(this._styles, prefix, 'min-height: ' + getHeight(1, 0) + ';', 0);\n }\n\n if (maxHeight > this._styles._max) {\n for (var i = this._styles._max; i < maxHeight; ++i) {\n Utils.insertCSSRule(this._styles,\n prefix + '[data-gs-height=\"' + (i + 1) + '\"]',\n 'height: ' + getHeight(i + 1, i) + ';',\n i\n );\n Utils.insertCSSRule(this._styles,\n prefix + '[data-gs-min-height=\"' + (i + 1) + '\"]',\n 'min-height: ' + getHeight(i + 1, i) + ';',\n i\n );\n Utils.insertCSSRule(this._styles,\n prefix + '[data-gs-max-height=\"' + (i + 1) + '\"]',\n 'max-height: ' + getHeight(i + 1, i) + ';',\n i\n );\n Utils.insertCSSRule(this._styles,\n prefix + '[data-gs-y=\"' + i + '\"]',\n 'top: ' + getHeight(i, i) + ';',\n i\n );\n }\n this._styles._max = maxHeight;\n }\n };\n\n GridStack.prototype._updateContainerHeight = function() {\n if (this.grid._batchMode) { return; }\n var height = this.grid.getGridHeight();\n // check for css min height. Each row is cellHeight + verticalMargin, until last one which has no margin below\n var cssMinHeight = parseInt(this.container.css('min-height'));\n if (cssMinHeight > 0) {\n var verticalMargin = this.opts.verticalMargin;\n var minHeight = Math.round((cssMinHeight + verticalMargin) / (this.cellHeight() + verticalMargin));\n if (height < minHeight) {\n height = minHeight;\n }\n }\n this.container.attr('data-gs-current-height', height);\n if (!this.opts.cellHeight) {\n return ;\n }\n if (!this.opts.verticalMargin) {\n this.container.css('height', (height * (this.opts.cellHeight)) + this.opts.cellHeightUnit);\n } else if (this.opts.cellHeightUnit === this.opts.verticalMarginUnit) {\n this.container.css('height', (height * (this.opts.cellHeight + this.opts.verticalMargin) -\n this.opts.verticalMargin) + this.opts.cellHeightUnit);\n } else {\n this.container.css('height', 'calc(' + ((height * (this.opts.cellHeight)) + this.opts.cellHeightUnit) +\n ' + ' + ((height * (this.opts.verticalMargin - 1)) + this.opts.verticalMarginUnit) + ')');\n }\n };\n\n GridStack.prototype._setupRemovingTimeout = function(el) {\n var self = this;\n var node = $(el).data('_gridstack_node');\n\n if (node._removeTimeout || !self.opts.removable) {\n return;\n }\n node._removeTimeout = setTimeout(function() {\n el.addClass('grid-stack-item-removing');\n node._isAboutToRemove = true;\n }, self.opts.removeTimeout);\n };\n\n GridStack.prototype._clearRemovingTimeout = function(el) {\n var node = $(el).data('_gridstack_node');\n\n if (!node._removeTimeout) {\n return;\n }\n clearTimeout(node._removeTimeout);\n node._removeTimeout = null;\n el.removeClass('grid-stack-item-removing');\n node._isAboutToRemove = false;\n };\n\n GridStack.prototype._prepareElementsByNode = function(el, node) {\n var self = this;\n\n var cellWidth;\n var cellHeight;\n\n var dragOrResize = function(event, ui) {\n var x = Math.round(ui.position.left / cellWidth);\n var y = Math.floor((ui.position.top + cellHeight / 2) / cellHeight);\n var width;\n var height;\n\n if (event.type !== 'drag') {\n width = Math.round(ui.size.width / cellWidth);\n height = Math.round(ui.size.height / cellHeight);\n }\n\n if (event.type === 'drag') {\n var distance = ui.position.top - node._prevYPix;\n node._prevYPix = ui.position.top;\n Utils.updateScrollPosition(el[0], ui, distance);\n if (el.data('inTrashZone') || x < 0 || x >= self.grid.column || y < 0 ||\n (!self.grid.float && y > self.grid.getGridHeight())) {\n if (!node._temporaryRemoved) {\n if (self.opts.removable === true) {\n self._setupRemovingTimeout(el);\n }\n\n x = node._beforeDragX;\n y = node._beforeDragY;\n\n self.placeholder.detach();\n self.placeholder.hide();\n self.grid.removeNode(node);\n self._updateContainerHeight();\n\n node._temporaryRemoved = true;\n } else {\n return;\n }\n } else {\n self._clearRemovingTimeout(el);\n\n if (node._temporaryRemoved) {\n self.grid.addNode(node);\n self.placeholder\n .attr('data-gs-x', x)\n .attr('data-gs-y', y)\n .attr('data-gs-width', width)\n .attr('data-gs-height', height)\n .show();\n self.container.append(self.placeholder);\n node.el = self.placeholder;\n node._temporaryRemoved = false;\n }\n }\n } else if (event.type === 'resize') {\n if (x < 0) {\n return;\n }\n }\n // width and height are undefined if not resizing\n var lastTriedWidth = width !== undefined ? width : node.lastTriedWidth;\n var lastTriedHeight = height !== undefined ? height : node.lastTriedHeight;\n if (!self.grid.canMoveNode(node, x, y, width, height) ||\n (node.lastTriedX === x && node.lastTriedY === y &&\n node.lastTriedWidth === lastTriedWidth && node.lastTriedHeight === lastTriedHeight)) {\n return;\n }\n node.lastTriedX = x;\n node.lastTriedY = y;\n node.lastTriedWidth = width;\n node.lastTriedHeight = height;\n self.grid.moveNode(node, x, y, width, height);\n self._updateContainerHeight();\n\n if (event.type === 'resize') {\n $(event.target).trigger('gsresize', node);\n }\n };\n\n var onStartMoving = function(event, ui) {\n self.container.append(self.placeholder);\n var o = $(this);\n self.grid.cleanNodes();\n self.grid.beginUpdate(node);\n cellWidth = self.cellWidth();\n var strictCellHeight = self.cellHeight();\n // TODO: cellHeight = cellHeight() causes issue (i.e. remove strictCellHeight above) otherwise\n // when sizing up we jump almost right away to next size instead of half way there. Not sure\n // why as we don't use ceil() in many places but round() instead.\n cellHeight = self.container.height() / parseInt(self.container.attr('data-gs-current-height'));\n self.placeholder\n .attr('data-gs-x', o.attr('data-gs-x'))\n .attr('data-gs-y', o.attr('data-gs-y'))\n .attr('data-gs-width', o.attr('data-gs-width'))\n .attr('data-gs-height', o.attr('data-gs-height'))\n .show();\n node.el = self.placeholder;\n node._beforeDragX = node.x;\n node._beforeDragY = node.y;\n node._prevYPix = ui.position.top;\n var minHeight = (node.minHeight || 1);\n var verticalMargin = self.opts.verticalMargin;\n\n // mineHeight - Each row is cellHeight + verticalMargin, until last one which has no margin below\n self.dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minWidth || 1));\n self.dd.resizable(el, 'option', 'minHeight', (strictCellHeight * minHeight) + (minHeight - 1) * verticalMargin);\n\n if (event.type === 'resizestart') {\n o.find('.grid-stack-item').trigger('resizestart');\n }\n };\n\n var onEndMoving = function(event, ui) {\n var o = $(this);\n if (!o.data('_gridstack_node')) {\n return;\n }\n\n // var forceNotify = false; what is the point of calling 'change' event with no data, when the 'removed' event is already called ?\n self.placeholder.detach();\n node.el = o;\n self.placeholder.hide();\n\n if (node._isAboutToRemove) {\n // forceNotify = true;\n var gridToNotify = el.data('_gridstack_node')._grid;\n gridToNotify._triggerRemoveEvent();\n el.removeData('_gridstack_node');\n el.remove();\n } else {\n self._clearRemovingTimeout(el);\n if (!node._temporaryRemoved) {\n Utils.removePositioningStyles(o);\n o\n .attr('data-gs-x', node.x)\n .attr('data-gs-y', node.y)\n .attr('data-gs-width', node.width)\n .attr('data-gs-height', node.height);\n } else {\n Utils.removePositioningStyles(o);\n o\n .attr('data-gs-x', node._beforeDragX)\n .attr('data-gs-y', node._beforeDragY)\n .attr('data-gs-width', node.width)\n .attr('data-gs-height', node.height);\n node.x = node._beforeDragX;\n node.y = node._beforeDragY;\n node._temporaryRemoved = false;\n self.grid.addNode(node);\n }\n }\n self._updateContainerHeight();\n self._triggerChangeEvent(/*forceNotify*/);\n\n self.grid.endUpdate();\n\n var nestedGrids = o.find('.grid-stack');\n if (nestedGrids.length && event.type === 'resizestop') {\n nestedGrids.each(function(index, el) {\n $(el).data('gridstack').onResizeHandler();\n });\n o.find('.grid-stack-item').trigger('resizestop');\n o.find('.grid-stack-item').trigger('gsresizestop');\n }\n if (event.type === 'resizestop') {\n self.container.trigger('gsresizestop', o);\n }\n };\n\n this.dd\n .draggable(el, {\n start: onStartMoving,\n stop: onEndMoving,\n drag: dragOrResize\n })\n .resizable(el, {\n start: onStartMoving,\n stop: onEndMoving,\n resize: dragOrResize\n });\n\n if (node.noMove || this.opts.disableDrag || this.opts.staticGrid) {\n this.dd.draggable(el, 'disable');\n }\n\n if (node.noResize || this.opts.disableResize || this.opts.staticGrid) {\n this.dd.resizable(el, 'disable');\n }\n\n this._writeAttr(el, node);\n };\n\n GridStack.prototype._prepareElement = function(el, triggerAddEvent) {\n triggerAddEvent = triggerAddEvent !== undefined ? triggerAddEvent : false;\n var self = this;\n el = $(el);\n\n el.addClass(this.opts.itemClass);\n var node = this._readAttr(el, {el: el, _grid: self});\n node = self.grid.addNode(node, triggerAddEvent);\n el.data('_gridstack_node', node);\n\n this._prepareElementsByNode(el, node);\n };\n\n /** call to write any default attributes back to element */\n GridStack.prototype._writeAttr = function(el, node) {\n el = $(el);\n node = node || {};\n // Note: passing null removes the attr in jquery\n if (node.x !== undefined) { el.attr('data-gs-x', node.x); }\n if (node.y !== undefined) { el.attr('data-gs-y', node.y); }\n if (node.width !== undefined) { el.attr('data-gs-width', node.width); }\n if (node.height !== undefined) { el.attr('data-gs-height', node.height); }\n if (node.autoPosition !== undefined) { el.attr('data-gs-auto-position', node.autoPosition ? true : null); }\n if (node.minWidth !== undefined) { el.attr('data-gs-min-width', node.minWidth); }\n if (node.maxWidth !== undefined) { el.attr('data-gs-max-width', node.maxWidth); }\n if (node.minHeight !== undefined) { el.attr('data-gs-min-height', node.minHeight); }\n if (node.maxHeight !== undefined) { el.attr('data-gs-max-height', node.maxHeight); }\n if (node.noResize !== undefined) { el.attr('data-gs-no-resize', node.noResize ? true : null); }\n if (node.noMove !== undefined) { el.attr('data-gs-no-move', node.noMove ? true : null); }\n if (node.locked !== undefined) { el.attr('data-gs-locked', node.locked ? true : null); }\n if (node.resizeHandles !== undefined) { el.attr('data-gs-resize-handles', node.resizeHandles); }\n if (node.id !== undefined) { el.attr('data-gs-id', node.id); }\n };\n\n /** call to write any default attributes back to element */\n GridStack.prototype._readAttr = function(el, node) {\n el = $(el);\n node = node || {};\n node.x = el.attr('data-gs-x');\n node.y = el.attr('data-gs-y');\n node.width = el.attr('data-gs-width');\n node.height = el.attr('data-gs-height');\n node.autoPosition = Utils.toBool(el.attr('data-gs-auto-position'));\n node.maxWidth = el.attr('data-gs-max-width');\n node.minWidth = el.attr('data-gs-min-width');\n node.maxHeight = el.attr('data-gs-max-height');\n node.minHeight = el.attr('data-gs-min-height');\n node.noResize = Utils.toBool(el.attr('data-gs-no-resize'));\n node.noMove = Utils.toBool(el.attr('data-gs-no-move'));\n node.locked = Utils.toBool(el.attr('data-gs-locked'));\n node.resizeHandles = el.attr('data-gs-resize-handles');\n node.id = el.attr('data-gs-id');\n return node;\n };\n\n GridStack.prototype.setAnimation = function(enable) {\n if (enable) {\n this.container.addClass('grid-stack-animate');\n } else {\n this.container.removeClass('grid-stack-animate');\n }\n };\n\n GridStack.prototype.addWidget = function(el, node, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id) {\n\n // new way of calling with an object - make sure all items have been properly initialized\n if (node === undefined || typeof node === 'object') {\n // Tempting to initialize the passed in node with default and valid values, but this break knockout demos\n // as the actual value are filled in when _prepareElement() calls el.attr('data-gs-xyz) before adding the node.\n // node = this.grid._prepareNode(node);\n node = node || {};\n } else {\n // old legacy way of calling with items spelled out - call us back with single object instead (so we can properly initialized values)\n return this.addWidget(el, {x: node, y: y, width: width, height: height, autoPosition: autoPosition,\n minWidth: minWidth, maxWidth: maxWidth, minHeight: minHeight, maxHeight: maxHeight, id: id});\n }\n\n el = $(el);\n this._writeAttr(el, node);\n this.container.append(el);\n this._prepareElement(el, true);\n this._updateContainerHeight();\n this._triggerAddEvent();\n // this._triggerChangeEvent(true); already have AddEvent\n\n return el;\n };\n\n GridStack.prototype.makeWidget = function(el) {\n el = $(el);\n this._prepareElement(el, true);\n this._updateContainerHeight();\n this._triggerAddEvent();\n // this._triggerChangeEvent(true); already have AddEvent\n\n return el;\n };\n\n GridStack.prototype.willItFit = function(x, y, width, height, autoPosition) {\n var node = {x: x, y: y, width: width, height: height, autoPosition: autoPosition};\n return this.grid.canBePlacedWithRespectToHeight(node);\n };\n\n GridStack.prototype.removeWidget = function(el, detachNode) {\n detachNode = (detachNode === undefined ? true : detachNode);\n el = $(el);\n var node = el.data('_gridstack_node');\n // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272\n if (!node) {\n node = this.grid.getNodeDataByDOMEl(el);\n }\n\n el.removeData('_gridstack_node');\n this.grid.removeNode(node, detachNode);\n this._triggerRemoveEvent();\n // this._triggerChangeEvent(true); already have removeEvent\n };\n\n GridStack.prototype.removeAll = function(detachNode) {\n if (detachNode !== false) {\n // remove our data structure before list gets emptied and DOM elements stay behind\n this.grid.nodes.forEach(function(node) { node.el.removeData('_gridstack_node') });\n }\n this.grid.removeAll(detachNode);\n this._triggerRemoveEvent();\n };\n\n GridStack.prototype.destroy = function(detachGrid) {\n $(window).off('resize', this.onResizeHandler);\n this.disable();\n if (detachGrid !== undefined && !detachGrid) {\n this.removeAll(false);\n this.container.removeData('gridstack');\n } else {\n this.container.remove();\n }\n Utils.removeStylesheet(this._stylesId);\n if (this.grid) {\n this.grid = null;\n }\n };\n\n GridStack.prototype.resizable = function(el, val) {\n var self = this;\n el = $(el);\n el.each(function(index, el) {\n el = $(el);\n var node = el.data('_gridstack_node');\n if (!node) { return; }\n node.noResize = !(val || false);\n if (node.noResize) {\n self.dd.resizable(el, 'disable');\n } else {\n self.dd.resizable(el, 'enable');\n }\n });\n return this;\n };\n\n GridStack.prototype.movable = function(el, val) {\n var self = this;\n el = $(el);\n el.each(function(index, el) {\n el = $(el);\n var node = el.data('_gridstack_node');\n if (!node) { return; }\n node.noMove = !(val || false);\n if (node.noMove) {\n self.dd.draggable(el, 'disable');\n el.removeClass('ui-draggable-handle');\n } else {\n self.dd.draggable(el, 'enable');\n el.addClass('ui-draggable-handle');\n }\n });\n return this;\n };\n\n GridStack.prototype.enableMove = function(doEnable, includeNewWidgets) {\n this.movable(this.container.children('.' + this.opts.itemClass), doEnable);\n if (includeNewWidgets) {\n this.opts.disableDrag = !doEnable;\n }\n };\n\n GridStack.prototype.enableResize = function(doEnable, includeNewWidgets) {\n this.resizable(this.container.children('.' + this.opts.itemClass), doEnable);\n if (includeNewWidgets) {\n this.opts.disableResize = !doEnable;\n }\n };\n\n GridStack.prototype.disable = function() {\n this.movable(this.container.children('.' + this.opts.itemClass), false);\n this.resizable(this.container.children('.' + this.opts.itemClass), false);\n this.container.trigger('disable');\n };\n\n GridStack.prototype.enable = function() {\n this.movable(this.container.children('.' + this.opts.itemClass), true);\n this.resizable(this.container.children('.' + this.opts.itemClass), true);\n this.container.trigger('enable');\n };\n\n GridStack.prototype.locked = function(el, val) {\n el = $(el);\n el.each(function(index, el) {\n el = $(el);\n var node = el.data('_gridstack_node');\n if (!node) { return; }\n node.locked = (val || false);\n el.attr('data-gs-locked', node.locked ? 'yes' : null);\n });\n return this;\n };\n\n GridStack.prototype.maxHeight = function(el, val) {\n el = $(el);\n el.each(function(index, el) {\n el = $(el);\n var node = el.data('_gridstack_node');\n if (!node) { return; }\n if (!isNaN(val)) {\n node.maxHeight = (val || false);\n el.attr('data-gs-max-height', val);\n }\n });\n return this;\n };\n\n GridStack.prototype.minHeight = function(el, val) {\n el = $(el);\n el.each(function(index, el) {\n el = $(el);\n var node = el.data('_gridstack_node');\n if (!node) { return; }\n if (!isNaN(val)) {\n node.minHeight = (val || false);\n el.attr('data-gs-min-height', val);\n }\n });\n return this;\n };\n\n GridStack.prototype.maxWidth = function(el, val) {\n el = $(el);\n el.each(function(index, el) {\n el = $(el);\n var node = el.data('_gridstack_node');\n if (!node) { return; }\n if (!isNaN(val)) {\n node.maxWidth = (val || false);\n el.attr('data-gs-max-width', val);\n }\n });\n return this;\n };\n\n GridStack.prototype.minWidth = function(el, val) {\n el = $(el);\n el.each(function(index, el) {\n el = $(el);\n var node = el.data('_gridstack_node');\n if (!node) { return; }\n if (!isNaN(val)) {\n node.minWidth = (val || false);\n el.attr('data-gs-min-width', val);\n }\n });\n return this;\n };\n\n GridStack.prototype._updateElement = function(el, callback) {\n el = $(el).first();\n var node = el.data('_gridstack_node');\n if (!node) { return; }\n var self = this;\n\n self.grid.cleanNodes();\n self.grid.beginUpdate(node);\n\n callback.call(this, el, node);\n\n self._updateContainerHeight();\n self._triggerChangeEvent();\n\n self.grid.endUpdate();\n };\n\n GridStack.prototype.resize = function(el, width, height) {\n this._updateElement(el, function(el, node) {\n width = (width !== null && width !== undefined) ? width : node.width;\n height = (height !== null && height !== undefined) ? height : node.height;\n\n this.grid.moveNode(node, node.x, node.y, width, height);\n });\n };\n\n GridStack.prototype.move = function(el, x, y) {\n this._updateElement(el, function(el, node) {\n x = (x !== null && x !== undefined) ? x : node.x;\n y = (y !== null && y !== undefined) ? y : node.y;\n\n this.grid.moveNode(node, x, y, node.width, node.height);\n });\n };\n\n GridStack.prototype.update = function(el, x, y, width, height) {\n this._updateElement(el, function(el, node) {\n x = (x !== null && x !== undefined) ? x : node.x;\n y = (y !== null && y !== undefined) ? y : node.y;\n width = (width !== null && width !== undefined) ? width : node.width;\n height = (height !== null && height !== undefined) ? height : node.height;\n\n this.grid.moveNode(node, x, y, width, height);\n });\n };\n\n /**\n * relayout grid items to reclaim any empty space\n */\n GridStack.prototype.compact = function() {\n if (this.grid.nodes.length === 0) { return; }\n this.batchUpdate();\n this.grid._sortNodes();\n var nodes = this.grid.nodes;\n this.grid.nodes = []; // pretend we have no nodes to conflict layout to start with...\n nodes.forEach(function(n) {\n if (!n.noMove && !n.locked) {\n n.autoPosition = true;\n }\n this.grid.addNode(n, false); // 'false' for add event trigger\n }, this);\n this.commit();\n };\n\n GridStack.prototype.verticalMargin = function(val, noUpdate) {\n if (val === undefined) {\n return this.opts.verticalMargin;\n }\n\n var heightData = Utils.parseHeight(val);\n\n if (this.opts.verticalMarginUnit === heightData.unit && this.opts.maxRow === heightData.height) {\n return ;\n }\n this.opts.verticalMarginUnit = heightData.unit;\n this.opts.verticalMargin = heightData.height;\n\n if (!noUpdate) {\n this._updateStyles();\n }\n };\n\n /** set/get the current cell height value */\n GridStack.prototype.cellHeight = function(val, noUpdate) {\n // getter - returns the opts stored height else compute it...\n if (val === undefined) {\n if (this.opts.cellHeight && this.opts.cellHeight !== 'auto') {\n return this.opts.cellHeight;\n }\n // compute the height taking margin into account (each row has margin other than last one)\n var o = this.container.children('.' + this.opts.itemClass).first();\n var height = o.attr('data-gs-height');\n var verticalMargin = this.opts.verticalMargin;\n return Math.round((o.outerHeight() - (height - 1) * verticalMargin) / height);\n }\n\n // setter - updates the cellHeight value if they changed\n var heightData = Utils.parseHeight(val);\n if (this.opts.cellHeightUnit === heightData.unit && this.opts.cellHeight === heightData.height) {\n return ;\n }\n this.opts.cellHeightUnit = heightData.unit;\n this.opts.cellHeight = heightData.height;\n\n if (!noUpdate) {\n this._updateStyles();\n }\n };\n\n GridStack.prototype.cellWidth = function() {\n // TODO: take margin into account ($horizontal_padding in .scss) to make cellHeight='auto' square ? (see 810-many-columns.html)\n return Math.round(this.container.outerWidth() / this.opts.column);\n };\n\n GridStack.prototype.getCellFromPixel = function(position, useOffset) {\n var containerPos = (useOffset !== undefined && useOffset) ?\n this.container.offset() : this.container.position();\n var relativeLeft = position.left - containerPos.left;\n var relativeTop = position.top - containerPos.top;\n\n var columnWidth = Math.floor(this.container.width() / this.opts.column);\n var rowHeight = Math.floor(this.container.height() / parseInt(this.container.attr('data-gs-current-height')));\n\n return {x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight)};\n };\n\n GridStack.prototype.batchUpdate = function() {\n this.grid.batchUpdate();\n };\n\n GridStack.prototype.commit = function() {\n this.grid.commit();\n this._triggerRemoveEvent();\n this._triggerAddEvent();\n this._triggerChangeEvent();\n };\n\n GridStack.prototype.isAreaEmpty = function(x, y, width, height) {\n return this.grid.isAreaEmpty(x, y, width, height);\n };\n\n GridStack.prototype.setStatic = function(staticValue) {\n this.opts.staticGrid = (staticValue === true);\n this.enableMove(!staticValue);\n this.enableResize(!staticValue);\n this._setStaticClass();\n };\n\n GridStack.prototype._setStaticClass = function() {\n var staticClassName = 'grid-stack-static';\n\n if (this.opts.staticGrid === true) {\n this.container.addClass(staticClassName);\n } else {\n this.container.removeClass(staticClassName);\n }\n };\n\n /** called whenever a node is added or moved - updates the cached layouts */\n GridStackEngine.prototype._layoutsNodesChange = function(nodes) {\n if (!this._layouts || this._ignoreLayoutsNodeChange) return;\n // remove smaller layouts - we will re-generate those on the fly... larger ones need to update\n this._layouts.forEach(function(layout, column) {\n if (!layout || column === this.column) return;\n if (column < this.column) {\n this._layouts[column] = undefined;\n }\n else {\n // we save the original x,y,w (h isn't cached) to see what actually changed to propagate better.\n // Note: we don't need to check against out of bound scaling/moving as that will be done when using those cache values.\n nodes.forEach(function(node) {\n var n = layout.find(function(l) { return l._id === node._id });\n if (!n) return; // no cache for new nodes. Will use those values.\n var ratio = column / this.column;\n // Y changed, push down same amount\n // TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode)\n if (node.y !== node._origY) {\n n.y += (node.y - node._origY);\n }\n // X changed, scale from new position\n if (node.x !== node._origX) {\n n.x = Math.round(node.x * ratio);\n }\n // width changed, scale from new width\n if (node.width !== node._origW) {\n n.width = Math.round(node.width * ratio);\n }\n // ...height always carries over from cache\n }, this);\n }\n }, this);\n\n this._saveInitial(); // reset current value now that we diffed.\n }\n\n /**\n * Called to scale the widget width & position up/down based on the column change.\n * Note we store previous layouts (especially original ones) to make it possible to go\n * from say 12 -> 1 -> 12 and get back to where we were.\n *\n * oldColumn: previous number of columns\n * column: new column number\n * nodes?: different sorted list (ex: DOM order) instead of current list\n */\n GridStackEngine.prototype._updateNodeWidths = function(oldColumn, column, nodes) {\n if (!this.nodes.length || oldColumn === column) { return; }\n\n // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data\n var copy = [this.nodes.length];\n this.nodes.forEach(function(n, i) {copy[i] = {x: n.x, y: n.y, width: n.width, _id: n._id}}); // only thing we change is x,y,w and id to find it back\n this._layouts = this._layouts || []; // use array to find larger quick\n this._layouts[oldColumn] = copy;\n\n // if we're going to 1 column and using DOM order rather than default sorting, then generate that layout\n if (column === 1 && nodes && nodes.length) {\n var top = 0;\n nodes.forEach(function(n) {\n n.x = 0;\n n.width = 1;\n n.y = Math.max(n.y, top);\n top = n.y + n.height;\n });\n } else {\n nodes = Utils.sort(this.nodes, -1, oldColumn); // current column reverse sorting so we can insert last to front (limit collision)\n }\n\n // see if we have cached previous layout.\n var cacheNodes = this._layouts[column] || [];\n // if not AND we are going up in size start with the largest layout as down-scaling is more accurate\n var lastIndex = this._layouts.length - 1;\n if (cacheNodes.length === 0 && column > oldColumn && column < lastIndex) {\n cacheNodes = this._layouts[lastIndex] || [];\n if (cacheNodes.length) {\n // pretend we came from that larger column by assigning those values as starting point\n oldColumn = lastIndex;\n cacheNodes.forEach(function(cacheNode) {\n var j = nodes.findIndex(function(n) {return n && n._id === cacheNode._id});\n if (j !== -1) {\n // still current, use cache info positions\n nodes[j].x = cacheNode.x;\n nodes[j].y = cacheNode.y;\n nodes[j].width = cacheNode.width;\n }\n });\n cacheNodes = []; // we still don't have new column cached data... will generate from larger one.\n }\n }\n\n // if we found cache re-use those nodes that are still current\n var newNodes = [];\n cacheNodes.forEach(function(cacheNode) {\n var j = nodes.findIndex(function(n) {return n && n._id === cacheNode._id});\n if (j !== -1) {\n // still current, use cache info positions\n nodes[j].x = cacheNode.x;\n nodes[j].y = cacheNode.y;\n nodes[j].width = cacheNode.width;\n newNodes.push(nodes[j]);\n nodes[j] = null; // erase it so we know what's left\n }\n });\n // ...and add any extra non-cached ones\n var ratio = column / oldColumn;\n nodes.forEach(function(node) {\n if (!node) return;\n node.x = (column === 1 ? 0 : Math.round(node.x * ratio));\n node.width = ((column === 1 || oldColumn === 1) ? 1 : (Math.round(node.width * ratio) || 1));\n newNodes.push(node);\n });\n\n // finally relayout them in reverse order (to get correct placement)\n newNodes = Utils.sort(newNodes, -1, column);\n this._ignoreLayoutsNodeChange = true;\n this.batchUpdate();\n this.nodes = []; // pretend we have no nodes to start with (we use same structures) to simplify layout\n newNodes.forEach(function(node) {\n this.addNode(node, false); // 'false' for add event trigger\n node._dirty = true; // force attr update\n }, this);\n this.commit();\n delete this._ignoreLayoutsNodeChange;\n\n // save this initial layout so we can see what changed and apply changes to other layouts better (diff)\n this._saveInitial();\n }\n\n /** called to save initial position/size */\n GridStackEngine.prototype._saveInitial = function() {\n this.nodes.forEach(function(n) {\n n._origX = n.x;\n n._origY = n.y;\n n._origW = n.width;\n n._origH = n.height;\n });\n }\n\n /**\n * Modify number of columns in the grid. Will attempt to update existing widgets\n * to conform to new number of columns. Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [1-11],\n * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)\n * @param column - Integer > 0 (default 12).\n * @param doNotPropagate if true existing widgets will not be updated (optional)\n */\n GridStack.prototype.setColumn = function(column, doNotPropagate) {\n if (this.opts.column === column) { return; }\n var oldColumn = this.opts.column;\n\n // if we go into 1 column mode (which happens if we're sized less than minWidth unless disableOneColumnMode is on)\n // then remember the original columns so we can restore.\n if (column === 1) {\n this._prevColumn = oldColumn;\n } else {\n delete this._prevColumn;\n }\n\n this.container.removeClass('grid-stack-' + oldColumn);\n this.container.addClass('grid-stack-' + column);\n this.opts.column = this.grid.column = column;\n\n if (doNotPropagate === true) { return; }\n\n // update the items now - see if the dom order nodes should be passed instead (else default to current list)\n var domNodes;\n if (this.opts.oneColumnModeDomSort && column === 1) {\n domNodes = [];\n this.container.children('.' + this.opts.itemClass).each(function(index, el) {\n var node = $(el).data('_gridstack_node');\n if (node) { domNodes.push(node); }\n });\n if (!domNodes.length) { domNodes = undefined; }\n }\n this.grid._updateNodeWidths(oldColumn, column, domNodes);\n\n // and trigger our event last...\n this.grid._ignoreLayoutsNodeChange = true;\n this._triggerChangeEvent();\n delete this.grid._ignoreLayoutsNodeChange;\n };\n\n GridStack.prototype.float = function(val) {\n // getter - returns the opts stored mode\n if (val === undefined) {\n return this.opts.float || false;\n }\n // setter - updates the mode and relayout if gravity is back on\n if (this.opts.float === val) { return; }\n this.opts.float = this.grid.float = val || false;\n if (!val) {\n this.grid._packNodes();\n this.grid._notify();\n }\n };\n\n // legacy method renames\n GridStack.prototype.setGridWidth = obsolete(GridStack.prototype.setColumn,\n 'setGridWidth', 'setColumn', 'v0.5.3');\n\n scope.GridStackUI = GridStack;\n\n scope.GridStackUI.Utils = Utils;\n scope.GridStackUI.Engine = GridStackEngine;\n scope.GridStackUI.GridStackDragDropPlugin = GridStackDragDropPlugin;\n\n $.fn.gridstack = function(opts) {\n return this.each(function() {\n var o = $(this);\n if (!o.data('gridstack')) {\n o\n .data('gridstack', new GridStack(this, opts));\n }\n });\n };\n\n return scope.GridStackUI;\n});\n"},496:function(e,n,t){t(4)(t(497))},497:function(e,n){e.exports="/** gridstack.js 0.6.3 - JQuery UI Drag&Drop plugin @preserve */\n/**\n * https://gridstackjs.com/\n * (c) 2014-2020 Alain Dumesny, Dylan Weiss, Pavel Reznikov\n * gridstack.js may be freely distributed under the MIT license.\n*/\n(function(factory) {\n if (typeof define === 'function' && define.amd) {\n define(['jquery', 'gridstack', 'exports'], factory);\n } else if (typeof exports !== 'undefined') {\n try { jQuery = require('jquery'); } catch (e) {}\n try { gridstack = require('gridstack'); } catch (e) {}\n factory(jQuery, gridstack.GridStackUI, exports);\n } else {\n factory(jQuery, GridStackUI, window);\n }\n})(function($, GridStackUI, scope) {\n /**\n * @class JQueryUIGridStackDragDropPlugin\n * jQuery UI implementation of drag'n'drop gridstack plugin.\n */\n function JQueryUIGridStackDragDropPlugin(grid) {\n GridStackUI.GridStackDragDropPlugin.call(this, grid);\n }\n\n GridStackUI.GridStackDragDropPlugin.registerPlugin(JQueryUIGridStackDragDropPlugin);\n\n JQueryUIGridStackDragDropPlugin.prototype = Object.create(GridStackUI.GridStackDragDropPlugin.prototype);\n JQueryUIGridStackDragDropPlugin.prototype.constructor = JQueryUIGridStackDragDropPlugin;\n\n JQueryUIGridStackDragDropPlugin.prototype.resizable = function(el, opts) {\n el = $(el);\n if (opts === 'disable' || opts === 'enable') {\n el.resizable(opts);\n } else if (opts === 'option') {\n var key = arguments[2];\n var value = arguments[3];\n el.resizable(opts, key, value);\n } else {\n var handles = el.data('gs-resize-handles') ? el.data('gs-resize-handles') :\n this.grid.opts.resizable.handles;\n el.resizable($.extend({}, this.grid.opts.resizable, {\n handles: handles\n }, {\n start: opts.start || function() {},\n stop: opts.stop || function() {},\n resize: opts.resize || function() {}\n }));\n }\n return this;\n };\n\n JQueryUIGridStackDragDropPlugin.prototype.draggable = function(el, opts) {\n el = $(el);\n if (opts === 'disable' || opts === 'enable') {\n el.draggable(opts);\n } else {\n el.draggable($.extend({}, this.grid.opts.draggable, {\n containment: (this.grid.opts.isNested && !this.grid.opts.dragOut) ?\n this.grid.container.parent() :\n (this.grid.opts.draggable.containment || null),\n start: opts.start || function() {},\n stop: opts.stop || function() {},\n drag: opts.drag || function() {}\n }));\n }\n return this;\n };\n\n JQueryUIGridStackDragDropPlugin.prototype.droppable = function(el, opts) {\n el = $(el);\n el.droppable(opts);\n return this;\n };\n\n JQueryUIGridStackDragDropPlugin.prototype.isDroppable = function(el, opts) {\n el = $(el);\n return Boolean(el.data('droppable'));\n };\n\n JQueryUIGridStackDragDropPlugin.prototype.on = function(el, eventName, callback) {\n $(el).on(eventName, callback);\n return this;\n };\n\n scope.JQueryUIGridStackDragDropPlugin = JQueryUIGridStackDragDropPlugin;\n\n return JQueryUIGridStackDragDropPlugin;\n});\n"},498:function(e,n,t){},499:function(e,n,t){},5:function(e,n,t){(function(n){var i=t(7);var o=t(12);function r(){return(new Date).getTime()}var a=Array.prototype.slice;var s;var d={};if(typeof n!=="undefined"&&n.console){s=n.console}else if(typeof window!=="undefined"&&window.console){s=window.console}else{s={}}var l=[[g,"log"],[p,"info"],[m,"warn"],[y,"error"],[v,"time"],[w,"timeEnd"],[b,"trace"],[_,"dir"],[x,"assert"]];for(var h=0;h<l.length;h++){var c=l[h];var u=c[0];var f=c[1];if(!s[f]){s[f]=u}}e.exports=s;function g(){}function p(){s.log.apply(s,arguments)}function m(){s.log.apply(s,arguments)}function y(){s.warn.apply(s,arguments)}function v(e){d[e]=r()}function w(e){var n=d[e];if(!n){throw new Error("No such label: "+e)}delete d[e];var t=r()-n;s.log(e+": "+t+"ms")}function b(){var e=new Error;e.name="Trace";e.message=i.format.apply(null,arguments);s.error(e.stack)}function _(e){s.log(i.inspect(e)+"\n")}function x(e){if(!e){var n=a.call(arguments,1);o.ok(false,i.format.apply(null,n))}}}).call(this,t(6))},6:function(e,n){var t;t=function(){return this}();try{t=t||new Function("return this")()}catch(e){if(typeof window==="object")t=window}e.exports=t},7:function(e,n,t){(function(e,i){var o=Object.getOwnPropertyDescriptors||function e(n){var t=Object.keys(n);var i={};for(var o=0;o<t.length;o++){i[t[o]]=Object.getOwnPropertyDescriptor(n,t[o])}return i};var r=/%[sdj%]/g;n.format=function(e){if(!k(e)){var n=[];for(var t=0;t<arguments.length;t++){n.push(d(arguments[t]))}return n.join(" ")}var t=1;var i=arguments;var o=i.length;var a=String(e).replace(r,(function(e){if(e==="%%")return"%";if(t>=o)return e;switch(e){case"%s":return String(i[t++]);case"%d":return Number(i[t++]);case"%j":try{return JSON.stringify(i[t++])}catch(e){return"[Circular]"}default:return e}}));for(var s=i[t];t<o;s=i[++t]){if(b(s)||!H(s)){a+=" "+s}else{a+=" "+d(s)}}return a};n.deprecate=function(t,o){if(typeof e!=="undefined"&&e.noDeprecation===true){return t}if(typeof e==="undefined"){return function(){return n.deprecate(t,o).apply(this,arguments)}}var r=false;function a(){if(!r){if(e.throwDeprecation){throw new Error(o)}else if(e.traceDeprecation){i.trace(o)}else{i.error(o)}r=true}return t.apply(this,arguments)}return a};var a={};var s;n.debuglog=function(t){if(S(s))s=e.env.NODE_DEBUG||"";t=t.toUpperCase();if(!a[t]){if(new RegExp("\\b"+t+"\\b","i").test(s)){var o=e.pid;a[t]=function(){var e=n.format.apply(n,arguments);i.error("%s %d: %s",t,o,e)}}else{a[t]=function(){}}}return a[t]};function d(e,t){var i={seen:[],stylize:h};if(arguments.length>=3)i.depth=arguments[2];if(arguments.length>=4)i.colors=arguments[3];if(w(t)){i.showHidden=t}else if(t){n._extend(i,t)}if(S(i.showHidden))i.showHidden=false;if(S(i.depth))i.depth=2;if(S(i.colors))i.colors=false;if(S(i.customInspect))i.customInspect=true;if(i.colors)i.stylize=l;return u(i,e,i.depth)}n.inspect=d;d.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]};d.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"};function l(e,n){var t=d.styles[n];if(t){return"["+d.colors[t][0]+"m"+e+"["+d.colors[t][1]+"m"}else{return e}}function h(e,n){return e}function c(e){var n={};e.forEach((function(e,t){n[e]=true}));return n}function u(e,t,i){if(e.customInspect&&t&&M(t.inspect)&&t.inspect!==n.inspect&&!(t.constructor&&t.constructor.prototype===t)){var o=t.inspect(i,e);if(!k(o)){o=u(e,o,i)}return o}var r=f(e,t);if(r){return r}var a=Object.keys(t);var s=c(a);if(e.showHidden){a=Object.getOwnPropertyNames(t)}if(C(t)&&(a.indexOf("message")>=0||a.indexOf("description")>=0)){return g(t)}if(a.length===0){if(M(t)){var d=t.name?": "+t.name:"";return e.stylize("[Function"+d+"]","special")}if(E(t)){return e.stylize(RegExp.prototype.toString.call(t),"regexp")}if(D(t)){return e.stylize(Date.prototype.toString.call(t),"date")}if(C(t)){return g(t)}}var l="",h=false,w=["{","}"];if(v(t)){h=true;w=["[","]"]}if(M(t)){var b=t.name?": "+t.name:"";l=" [Function"+b+"]"}if(E(t)){l=" "+RegExp.prototype.toString.call(t)}if(D(t)){l=" "+Date.prototype.toUTCString.call(t)}if(C(t)){l=" "+g(t)}if(a.length===0&&(!h||t.length==0)){return w[0]+l+w[1]}if(i<0){if(E(t)){return e.stylize(RegExp.prototype.toString.call(t),"regexp")}else{return e.stylize("[Object]","special")}}e.seen.push(t);var _;if(h){_=p(e,t,i,s,a)}else{_=a.map((function(n){return m(e,t,i,s,n,h)}))}e.seen.pop();return y(_,l,w)}function f(e,n){if(S(n))return e.stylize("undefined","undefined");if(k(n)){var t="'"+JSON.stringify(n).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(t,"string")}if(x(n))return e.stylize(""+n,"number");if(w(n))return e.stylize(""+n,"boolean");if(b(n))return e.stylize("null","null")}function g(e){return"["+Error.prototype.toString.call(e)+"]"}function p(e,n,t,i,o){var r=[];for(var a=0,s=n.length;a<s;++a){if(z(n,String(a))){r.push(m(e,n,t,i,String(a),true))}else{r.push("")}}o.forEach((function(o){if(!o.match(/^\d+$/)){r.push(m(e,n,t,i,o,true))}}));return r}function m(e,n,t,i,o,r){var a,s,d;d=Object.getOwnPropertyDescriptor(n,o)||{value:n[o]};if(d.get){if(d.set){s=e.stylize("[Getter/Setter]","special")}else{s=e.stylize("[Getter]","special")}}else{if(d.set){s=e.stylize("[Setter]","special")}}if(!z(i,o)){a="["+o+"]"}if(!s){if(e.seen.indexOf(d.value)<0){if(b(t)){s=u(e,d.value,null)}else{s=u(e,d.value,t-1)}if(s.indexOf("\n")>-1){if(r){s=s.split("\n").map((function(e){return" "+e})).join("\n").substr(2)}else{s="\n"+s.split("\n").map((function(e){return" "+e})).join("\n")}}}else{s=e.stylize("[Circular]","special")}}if(S(a)){if(r&&o.match(/^\d+$/)){return s}a=JSON.stringify(""+o);if(a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)){a=a.substr(1,a.length-2);a=e.stylize(a,"name")}else{a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'");a=e.stylize(a,"string")}}return a+": "+s}function y(e,n,t){var i=0;var o=e.reduce((function(e,n){i++;if(n.indexOf("\n")>=0)i++;return e+n.replace(/\u001b\[\d\d?m/g,"").length+1}),0);if(o>60){return t[0]+(n===""?"":n+"\n ")+" "+e.join(",\n ")+" "+t[1]}return t[0]+n+" "+e.join(", ")+" "+t[1]}function v(e){return Array.isArray(e)}n.isArray=v;function w(e){return typeof e==="boolean"}n.isBoolean=w;function b(e){return e===null}n.isNull=b;function _(e){return e==null}n.isNullOrUndefined=_;function x(e){return typeof e==="number"}n.isNumber=x;function k(e){return typeof e==="string"}n.isString=k;function N(e){return typeof e==="symbol"}n.isSymbol=N;function S(e){return e===void 0}n.isUndefined=S;function E(e){return H(e)&&O(e)==="[object RegExp]"}n.isRegExp=E;function H(e){return typeof e==="object"&&e!==null}n.isObject=H;function D(e){return H(e)&&O(e)==="[object Date]"}n.isDate=D;function C(e){return H(e)&&(O(e)==="[object Error]"||e instanceof Error)}n.isError=C;function M(e){return typeof e==="function"}n.isFunction=M;function G(e){return e===null||typeof e==="boolean"||typeof e==="number"||typeof e==="string"||typeof e==="symbol"||typeof e==="undefined"}n.isPrimitive=G;n.isBuffer=t(9);function O(e){return Object.prototype.toString.call(e)}function P(e){return e<10?"0"+e.toString(10):e.toString(10)}var U=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function j(){var e=new Date;var n=[P(e.getHours()),P(e.getMinutes()),P(e.getSeconds())].join(":");return[e.getDate(),U[e.getMonth()],n].join(" ")}n.log=function(){i.log("%s - %s",j(),n.format.apply(n,arguments))};n.inherits=t(10);n._extend=function(e,n){if(!n||!H(n))return e;var t=Object.keys(n);var i=t.length;while(i--){e[t[i]]=n[t[i]]}return e};function z(e,n){return Object.prototype.hasOwnProperty.call(e,n)}var T=typeof Symbol!=="undefined"?Symbol("util.promisify.custom"):undefined;n.promisify=function e(n){if(typeof n!=="function")throw new TypeError('The "original" argument must be of type Function');if(T&&n[T]){var t=n[T];if(typeof t!=="function"){throw new TypeError('The "util.promisify.custom" argument must be of type Function')}Object.defineProperty(t,T,{value:t,enumerable:false,writable:false,configurable:true});return t}function t(){var e,t;var i=new Promise((function(n,i){e=n;t=i}));var o=[];for(var r=0;r<arguments.length;r++){o.push(arguments[r])}o.push((function(n,i){if(n){t(n)}else{e(i)}}));try{n.apply(this,o)}catch(e){t(e)}return i}Object.setPrototypeOf(t,Object.getPrototypeOf(n));if(T)Object.defineProperty(t,T,{value:t,enumerable:false,writable:false,configurable:true});return Object.defineProperties(t,o(n))};n.promisify.custom=T;function R(e,n){if(!e){var t=new Error("Promise was rejected with a falsy value");t.reason=e;e=t}return n(e)}function W(n){if(typeof n!=="function"){throw new TypeError('The "original" argument must be of type Function')}function t(){var t=[];for(var i=0;i<arguments.length;i++){t.push(arguments[i])}var o=t.pop();if(typeof o!=="function"){throw new TypeError("The last argument must be of type Function")}var r=this;var a=function(){return o.apply(r,arguments)};n.apply(this,t).then((function(n){e.nextTick(a,null,n)}),(function(n){e.nextTick(R,n,a)}))}Object.setPrototypeOf(t,Object.getPrototypeOf(n));Object.defineProperties(t,o(n));return t}n.callbackify=W}).call(this,t(8),t(5))},8:function(e,n){var t=e.exports={};var i;var o;function r(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function"){i=setTimeout}else{i=r}}catch(e){i=r}try{if(typeof clearTimeout==="function"){o=clearTimeout}else{o=a}}catch(e){o=a}})();function s(e){if(i===setTimeout){return setTimeout(e,0)}if((i===r||!i)&&setTimeout){i=setTimeout;return setTimeout(e,0)}try{return i(e,0)}catch(n){try{return i.call(null,e,0)}catch(n){return i.call(this,e,0)}}}function d(e){if(o===clearTimeout){return clearTimeout(e)}if((o===a||!o)&&clearTimeout){o=clearTimeout;return clearTimeout(e)}try{return o(e)}catch(n){try{return o.call(null,e)}catch(n){return o.call(this,e)}}}var l=[];var h=false;var c;var u=-1;function f(){if(!h||!c){return}h=false;if(c.length){l=c.concat(l)}else{u=-1}if(l.length){g()}}function g(){if(h){return}var e=s(f);h=true;var n=l.length;while(n){c=l;l=[];while(++u<n){if(c){c[u].run()}}u=-1;n=l.length}c=null;h=false;d(e)}t.nextTick=function(e){var n=new Array(arguments.length-1);if(arguments.length>1){for(var t=1;t<arguments.length;t++){n[t-1]=arguments[t]}}l.push(new p(e,n));if(l.length===1&&!h){s(g)}};function p(e,n){this.fun=e;this.array=n}p.prototype.run=function(){this.fun.apply(null,this.array)};t.title="browser";t.browser=true;t.env={};t.argv=[];t.version="";t.versions={};function m(){}t.on=m;t.addListener=m;t.once=m;t.off=m;t.removeListener=m;t.removeAllListeners=m;t.emit=m;t.prependListener=m;t.prependOnceListener=m;t.listeners=function(e){return[]};t.binding=function(e){throw new Error("process.binding is not supported")};t.cwd=function(){return"/"};t.chdir=function(e){throw new Error("process.chdir is not supported")};t.umask=function(){return 0}},9:function(e,n){e.exports=function e(n){return n&&typeof n==="object"&&typeof n.copy==="function"&&typeof n.fill==="function"&&typeof n.readUInt8==="function"}}});