{ "version": 3, "sources": ["../../node_modules/bootstrap/js/src/collapse.js", "../../app/assets/application/components/action_table.js", "../../app/assets/application/components/autofocus.js", "../../app/assets/application/components/body.js", "../../app/assets/application/components/confirm_click.js", "../../app/assets/application/components/confirmation_dialog.js", "../../app/assets/application/components/content_in_overlay.js", "../../app/assets/application/components/data_confirm.js", "../../node_modules/lodash/isObject.js", "../../node_modules/lodash/_freeGlobal.js", "../../node_modules/lodash/_root.js", "../../node_modules/lodash/now.js", "../../node_modules/lodash/_trimmedEndIndex.js", "../../node_modules/lodash/_baseTrim.js", "../../node_modules/lodash/_Symbol.js", "../../node_modules/lodash/_getRawTag.js", "../../node_modules/lodash/_objectToString.js", "../../node_modules/lodash/_baseGetTag.js", "../../node_modules/lodash/isObjectLike.js", "../../node_modules/lodash/isSymbol.js", "../../node_modules/lodash/toNumber.js", "../../node_modules/lodash/debounce.js", "../../app/assets/application/components/dynamic_row.js", "../../node_modules/jquery.fancytree/dist/modules/jquery.fancytree.ui-deps.js", "../../node_modules/jquery.fancytree/dist/modules/jquery.fancytree.js", "../../node_modules/jquery.fancytree/dist/modules/jquery.fancytree.dnd5.js", "../../node_modules/jquery.fancytree/dist/modules/jquery.fancytree.edit.js", "../../node_modules/jquery.fancytree/dist/modules/jquery.fancytree.table.js", "../../app/assets/application/components/file_input.js", "../../app/assets/application/components/foldable.js", "../../app/assets/application/components/input_group.js", "../../app/assets/application/components/input_type_number.js", "../../app/assets/application/components/input_with_ellipsis.js", "../../app/assets/application/components/instant_modal.js", "../../app/assets/application/components/invalid_input.js", "../../app/assets/application/components/kpi_tile.js", "../../app/assets/application/components/nav-tabs.js", "../../app/assets/application/components/no_edit.js", "../../app/assets/application/components/open_createable_association.js", "../../app/assets/application/components/open_in_modal.js", "../../app/assets/application/components/open_modal_handler.js", "../../app/assets/application/components/query_diet.js", "../../app/assets/application/components/reload_on_accepted.js", "../../node_modules/lodash/head.js", "../../node_modules/lodash/first.js", "../../node_modules/lodash/last.js", "../../node_modules/lodash/_listCacheClear.js", "../../node_modules/lodash/eq.js", "../../node_modules/lodash/_assocIndexOf.js", "../../node_modules/lodash/_listCacheDelete.js", "../../node_modules/lodash/_listCacheGet.js", "../../node_modules/lodash/_listCacheHas.js", "../../node_modules/lodash/_listCacheSet.js", "../../node_modules/lodash/_ListCache.js", "../../node_modules/lodash/_stackClear.js", "../../node_modules/lodash/_stackDelete.js", "../../node_modules/lodash/_stackGet.js", "../../node_modules/lodash/_stackHas.js", "../../node_modules/lodash/isFunction.js", "../../node_modules/lodash/_coreJsData.js", "../../node_modules/lodash/_isMasked.js", "../../node_modules/lodash/_toSource.js", "../../node_modules/lodash/_baseIsNative.js", "../../node_modules/lodash/_getValue.js", "../../node_modules/lodash/_getNative.js", "../../node_modules/lodash/_Map.js", "../../node_modules/lodash/_nativeCreate.js", "../../node_modules/lodash/_hashClear.js", "../../node_modules/lodash/_hashDelete.js", "../../node_modules/lodash/_hashGet.js", "../../node_modules/lodash/_hashHas.js", "../../node_modules/lodash/_hashSet.js", "../../node_modules/lodash/_Hash.js", "../../node_modules/lodash/_mapCacheClear.js", "../../node_modules/lodash/_isKeyable.js", "../../node_modules/lodash/_getMapData.js", "../../node_modules/lodash/_mapCacheDelete.js", "../../node_modules/lodash/_mapCacheGet.js", "../../node_modules/lodash/_mapCacheHas.js", "../../node_modules/lodash/_mapCacheSet.js", "../../node_modules/lodash/_MapCache.js", "../../node_modules/lodash/_stackSet.js", "../../node_modules/lodash/_Stack.js", "../../node_modules/lodash/_defineProperty.js", "../../node_modules/lodash/_baseAssignValue.js", "../../node_modules/lodash/_assignMergeValue.js", "../../node_modules/lodash/_createBaseFor.js", "../../node_modules/lodash/_baseFor.js", "../../node_modules/lodash/_cloneBuffer.js", "../../node_modules/lodash/_Uint8Array.js", "../../node_modules/lodash/_cloneArrayBuffer.js", "../../node_modules/lodash/_cloneTypedArray.js", "../../node_modules/lodash/_copyArray.js", "../../node_modules/lodash/_baseCreate.js", "../../node_modules/lodash/_overArg.js", "../../node_modules/lodash/_getPrototype.js", "../../node_modules/lodash/_isPrototype.js", "../../node_modules/lodash/_initCloneObject.js", "../../node_modules/lodash/_baseIsArguments.js", "../../node_modules/lodash/isArguments.js", "../../node_modules/lodash/isArray.js", "../../node_modules/lodash/isLength.js", "../../node_modules/lodash/isArrayLike.js", "../../node_modules/lodash/isArrayLikeObject.js", "../../node_modules/lodash/stubFalse.js", "../../node_modules/lodash/isBuffer.js", "../../node_modules/lodash/isPlainObject.js", "../../node_modules/lodash/_baseIsTypedArray.js", "../../node_modules/lodash/_baseUnary.js", "../../node_modules/lodash/_nodeUtil.js", "../../node_modules/lodash/isTypedArray.js", "../../node_modules/lodash/_safeGet.js", "../../node_modules/lodash/_assignValue.js", "../../node_modules/lodash/_copyObject.js", "../../node_modules/lodash/_baseTimes.js", "../../node_modules/lodash/_isIndex.js", "../../node_modules/lodash/_arrayLikeKeys.js", "../../node_modules/lodash/_nativeKeysIn.js", "../../node_modules/lodash/_baseKeysIn.js", "../../node_modules/lodash/keysIn.js", "../../node_modules/lodash/toPlainObject.js", "../../node_modules/lodash/_baseMergeDeep.js", "../../node_modules/lodash/_baseMerge.js", "../../node_modules/lodash/identity.js", "../../node_modules/lodash/_apply.js", "../../node_modules/lodash/_overRest.js", "../../node_modules/lodash/constant.js", "../../node_modules/lodash/_baseSetToString.js", "../../node_modules/lodash/_shortOut.js", "../../node_modules/lodash/_setToString.js", "../../node_modules/lodash/_baseRest.js", "../../node_modules/lodash/_isIterateeCall.js", "../../node_modules/lodash/_createAssigner.js", "../../node_modules/lodash/merge.js", "../../app/assets/application/components/subform_in_overlay.js", "../../app/assets/application/components/substitution_form.js", "../../app/assets/application/components/ts_control_item.js", "../../app/assets/application/components/units_field.js", "../../node_modules/unpoly/unpoly.js", "../../node_modules/unpoly/unpoly-bootstrap5.js", "../../app/assets/application/util/environment.js", "../../app/assets/application/config/unpoly.js", "../../app/assets/application/components/accordion.js", "import-glob:./application/components/**/*.js", "../../app/assets/application/components/better_errors.js", "../../app/assets/application/util/async_compiler.js", "../../app/assets/application/util/tooltip_destructor.js", "../../app/assets/application/components/bootstrap_tooltip.js", "../../app/assets/application/components/checkbox_mismatch_warning.js", "../../app/assets/application/components/confirm_unsaved_changes.js", "../../app/assets/application/components/copy_field_value.js", "../../app/assets/application/util/load_style.js", "../../node_modules/ismobilejs/src/isMobile.ts", "../../app/assets/application/util/is_mobile.js", "../../app/assets/application/components/date_picker.js", "../../app/assets/application/util/format_as_euros.js", "../../app/assets/application/util/detailed_costs_chart.js", "../../app/assets/application/components/detailed_cost_distribution_chart.js", "../../app/assets/application/components/disable_button_in_pristine_forms.js", "../../app/assets/application/util/require_element.js", "../../app/assets/application/util/csv_builder.js", "../../app/assets/application/components/downloadable_data.js", "../../app/assets/application/components/fancytree.js", "../../app/assets/application/components/reference_impact_chooser_input.js", "../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js", "../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js", "../../node_modules/@popperjs/core/lib/utils/math.js", "../../node_modules/@popperjs/core/lib/utils/userAgent.js", "../../node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js", "../../node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js", "../../node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js", "../../node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js", "../../node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js", "../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js", "../../node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js", "../../node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js", "../../node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js", "../../node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js", "../../node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js", "../../node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js", "../../node_modules/@popperjs/core/lib/dom-utils/getParentNode.js", "../../node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js", "../../node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js", "../../node_modules/@popperjs/core/lib/dom-utils/isTableElement.js", "../../node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js", "../../node_modules/@popperjs/core/lib/enums.js", "../../node_modules/@popperjs/core/lib/utils/orderModifiers.js", "../../node_modules/@popperjs/core/lib/utils/debounce.js", "../../node_modules/@popperjs/core/lib/utils/mergeByName.js", "../../node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js", "../../node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js", "../../node_modules/@popperjs/core/lib/dom-utils/contains.js", "../../node_modules/@popperjs/core/lib/utils/rectToClientRect.js", "../../node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js", "../../node_modules/@popperjs/core/lib/utils/getBasePlacement.js", "../../node_modules/@popperjs/core/lib/utils/getVariation.js", "../../node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js", "../../node_modules/@popperjs/core/lib/utils/computeOffsets.js", "../../node_modules/@popperjs/core/lib/utils/getFreshSideObject.js", "../../node_modules/@popperjs/core/lib/utils/mergePaddingObject.js", "../../node_modules/@popperjs/core/lib/utils/expandToHashMap.js", "../../node_modules/@popperjs/core/lib/utils/detectOverflow.js", "../../node_modules/@popperjs/core/lib/createPopper.js", "../../node_modules/@popperjs/core/lib/modifiers/eventListeners.js", "../../node_modules/@popperjs/core/lib/modifiers/popperOffsets.js", "../../node_modules/@popperjs/core/lib/modifiers/computeStyles.js", "../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js", "../../node_modules/@popperjs/core/lib/popper-lite.js", "../../node_modules/@popperjs/core/lib/utils/getOppositePlacement.js", "../../node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js", "../../node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js", "../../node_modules/@popperjs/core/lib/modifiers/flip.js", "../../node_modules/@popperjs/core/lib/utils/getAltAxis.js", "../../node_modules/@popperjs/core/lib/utils/within.js", "../../node_modules/@popperjs/core/lib/modifiers/preventOverflow.js", "../../app/assets/tom-select/popperjs_same_width.js", "../../app/assets/application/util/dropdown_in_scroller.js", "../../app/assets/application/components/field_with_dropdown.js", "../../app/assets/application/components/filter.js", "../../app/assets/application/util/application.js", "../../app/assets/application/util/timeout.js", "../../app/assets/application/components/flash_message.js", "../../app/assets/application/components/page_dirty_tracker.js", "../../app/assets/application/components/form_dirty.js", "../../app/assets/application/components/form_group.js", "../../app/assets/application/util/leaflet_map.js", "../../app/assets/application/components/form_map.js", "../../app/assets/application/util/set_input_value.js", "../../app/assets/application/components/form_with_suggestions_field.js", "../../app/assets/application/components/form_with_suggestions_trigger.js", "../../app/assets/application/components/intro_animation.js", "../../app/assets/application/components/kpi_selection_segment.js", "../../app/assets/application/components/lca_configuration_chart.js", "../../app/assets/application/components/maps_opener.js", "../../app/assets/application/util/overall_costs_chart.js", "../../app/assets/application/components/overall_cost_distribution_chart.js", "../../app/assets/application/util/simapro_parser.js", "../../app/assets/application/components/paste-impacts.js", "../../app/assets/application/components/quill_editor.js", "../../app/assets/application/components/reference_impact_chooser.js", "../../app/assets/application/components/reference_impact_chooser_modal.js", "../../app/assets/application/components/reference_impact_chooser_modal_option.js", "../../app/assets/application/components/row_value_mismatch_warning.js", "../../app/assets/application/components/scroller.js", "../../app/assets/application/components/sidebar.js", "../../app/assets/application/components/stacked_bar_chart.js", "../../app/assets/application/components/subform_with_info_rows.js", "../../node_modules/autosize/dist/autosize.esm.js", "../../app/assets/application/components/textarea.js", "../../app/assets/application/components/tier_detector.js", "../../app/assets/application/util/frontend_api.js", "../../app/assets/application/components/tom_select.js", "../../app/assets/application/components/tooltip_on_overflow.js", "../../app/assets/application/components/value_mismatch_warning.js"], "sourcesContent": ["/**\n * --------------------------------------------------------------------------\n * Bootstrap collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport {\n defineJQueryPlugin,\n getElement,\n reflow\n} from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'collapse'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal'\n\nconst WIDTH = 'width'\nconst HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"collapse\"]'\n\nconst Default = {\n parent: null,\n toggle: true\n}\n\nconst DefaultType = {\n parent: '(null|element)',\n toggle: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._isTransitioning = false\n this._triggerArray = []\n\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE)\n\n for (const elem of toggleList) {\n const selector = SelectorEngine.getSelectorFromElement(elem)\n const filterElement = SelectorEngine.find(selector)\n .filter(foundElement => foundElement === this._element)\n\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem)\n }\n }\n\n this._initializeChildren()\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown())\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n if (this._isShown()) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning || this._isShown()) {\n return\n }\n\n let activeChildren = []\n\n // find active children\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES)\n .filter(element => element !== this._element)\n .map(element => Collapse.getOrCreateInstance(element, { toggle: false }))\n }\n\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW)\n if (startEvent.defaultPrevented) {\n return\n }\n\n for (const activeInstance of activeChildren) {\n activeInstance.hide()\n }\n\n const dimension = this._getDimension()\n\n this._element.classList.remove(CLASS_NAME_COLLAPSE)\n this._element.classList.add(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n this._addAriaAndCollapsedClass(this._triggerArray, true)\n this._isTransitioning = true\n\n const complete = () => {\n this._isTransitioning = false\n\n this._element.classList.remove(CLASS_NAME_COLLAPSING)\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n this._element.style[dimension] = ''\n\n EventHandler.trigger(this._element, EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n\n this._queueCallback(complete, this._element, true)\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n if (startEvent.defaultPrevented) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n reflow(this._element)\n\n this._element.classList.add(CLASS_NAME_COLLAPSING)\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n for (const trigger of this._triggerArray) {\n const element = SelectorEngine.getElementFromSelector(trigger)\n\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false)\n }\n }\n\n this._isTransitioning = true\n\n const complete = () => {\n this._isTransitioning = false\n this._element.classList.remove(CLASS_NAME_COLLAPSING)\n this._element.classList.add(CLASS_NAME_COLLAPSE)\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n\n this._queueCallback(complete, this._element, true)\n }\n\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW)\n }\n\n // Private\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle) // Coerce string values\n config.parent = getElement(config.parent)\n return config\n }\n\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT\n }\n\n _initializeChildren() {\n if (!this._config.parent) {\n return\n }\n\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE)\n\n for (const element of children) {\n const selected = SelectorEngine.getElementFromSelector(element)\n\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected))\n }\n }\n }\n\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent)\n // remove children if greater depth\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element))\n }\n\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return\n }\n\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen)\n element.setAttribute('aria-expanded', isOpen)\n }\n }\n\n // Static\n static jQueryInterface(config) {\n const _config = {}\n if (typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config)\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) {\n event.preventDefault()\n }\n\n for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {\n Collapse.getOrCreateInstance(element, { toggle: false }).toggle()\n }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse)\n\nexport default Collapse\n", "up.compiler('.action-table--actions', (element) => {\n up.on(element, 'click', (evt) => {\n if (!isLinkOrHasLinkAncestor(evt.target)) {\n // Dont trigger the `up-expand` of the table rows within the actions section.\n // Stop the propagation only for non link elements, to allow for e.g. `up-method` to work.\n evt.stopPropagation()\n }\n })\n\n function isLinkOrHasLinkAncestor(element) {\n while (element) {\n if (element.tagName === 'A') {\n return true\n }\n element = element.parentElement\n }\n return false\n }\n})\n", "up.compiler('[autofocus]', (element) => {\n window.queueMicrotask(() => {\n // [autofocused] are instantly focused by the browser when they are rendered\n // We have to emit the \"focusin\" event manually that your compilers can still\n // react to it.\n up.emit(element, 'focusin')\n })\n})\n", "/*\n This compiler temporarily adds a `body.-loading` class to the DOM\n until _after_ it was rendered.\n It can be used e.g. to prevent transitions that are only meant for\n user interaction.\n */\nup.compiler('body', (element) => {\n\n const LOADING_MODIFIER = '-loading'\n\n const setLoading = () => {\n element.classList.add(LOADING_MODIFIER)\n }\n\n const resetLoading = () => {\n element.classList.remove(LOADING_MODIFIER)\n }\n\n return [\n up.on('up:fragment:loaded up:location:restore up:network:late', setLoading),\n up.on('up:fragment:inserted up:framework:booted up:network:recover', resetLoading),\n ]\n\n})\n", "// Apply this compiler to any clickable element to show a confirmation dialog before actually clicking the element.\n// Required attributes: data-confirm-icon, data-confirm-title\n// Optional attributes: data-confirm-text\n//\n// Example usage:\n// \n\nup.compiler('[confirm-click]', (element, { confirmIcon, confirmTitle, confirmText }) => {\n\n up.on(element, 'up:click', handleClick)\n\n function handleClick(evt) {\n if (evt.clickConfirmed) {\n return\n }\n\n evt.preventDefault()\n openConfirmationDialog(evt)\n }\n\n function openConfirmationDialog(evt) {\n up.layer.open({\n content: confirmationDialogTemplate(confirmIcon, confirmTitle, confirmText),\n layer: 'new',\n mode: 'modal',\n history: false,\n onAccepted,\n })\n }\n\n function onAccepted() {\n up.emit(element, 'up:click', { clickConfirmed: true })\n }\n\n function confirmationDialogTemplate(icon, title, text) {\n return (`\n
\n
\n ${icon}\n
\n

\n ${title}\n

\n \n ${text}\n \n
\n \n \n
\n
\n `)\n }\n})\n", "/*\n This compiler takes a message from a 'input[confirmation-dialog]'.\n The message is then displayed in a modal which can be confirmed or canceled.\n If its confirmed, the input\u00B4s value is set to 'true' and the surrounding form gets submitted.\n\n See 'app/models/traits/does_confirmable.rb'\n*/\nup.compiler('[confirmation-dialog]', (element, { title, message, show }) => {\n const form = element.closest('form')\n title ||= SelectiveI18n.t('words.caution')\n\n if (show) {\n up.layer.open({\n content: dialogTemplate(message, title),\n mode: 'modal',\n layer: 'new',\n onAccepted: (_evt) => {\n element.value = 'true'\n up.submit(form)\n },\n onDismissed: () => {\n up.layer.emit(form, 'form:dirty')\n },\n })\n }\n\n function dialogTemplate(message, title) {\n return `\n
\n
\n \n

${title}

\n\n
${message}
\n\n
\n \n\n \n
\n
\n `\n }\n})\n", "// This compiler allows any content to be rendered in an overlay:\n//\n//
\n//
\n// \n// \n// \n// \n//\n// \n//
\n//
\n// Show content in overlay\n//
\n//
\n//\nup.compiler('.content-in-overlay', (container, data) => {\n const opener = container.querySelector('.content-in-overlay--opener')\n const body = container.querySelector('.content-in-overlay--body')\n\n const defaultOptions = {\n fragment: body,\n onDismiss: reclaimBody,\n dismissable: true,\n history: false,\n }\n\n function open() {\n up.layer.open(Object.assign(defaultOptions, data))\n }\n\n function reclaimBody() {\n container.append(body)\n }\n\n opener.addEventListener('click', open)\n})\n", "up.compiler('[data-confirm]', (element) => {\n\n function onClick(event) {\n const message = element.getAttribute('data-confirm')\n if (!confirm(message)) up.event.halt(event)\n }\n\n element.addEventListener('click', onClick)\n})\n", "/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n", "/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n", "var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n", "var root = require('./_root');\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return root.Date.now();\n};\n\nmodule.exports = now;\n", "/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n}\n\nmodule.exports = trimmedEndIndex;\n", "var trimmedEndIndex = require('./_trimmedEndIndex');\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n}\n\nmodule.exports = baseTrim;\n", "var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n", "var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n", "/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n", "var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n", "/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n", "var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n", "var baseTrim = require('./_baseTrim'),\n isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n", "var isObject = require('./isObject'),\n now = require('./now'),\n toNumber = require('./toNumber');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n timeWaiting = wait - timeSinceLastCall;\n\n return maxing\n ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\nmodule.exports = debounce;\n", "/*\n * A dynamic row is rendered within a container\n * The first thing it does is to _move itself out_.\n * This allows us to re-render the same form and target\n * only new rows within the container!\n */\nup.compiler('.dynamic-row', function(row, data) {\n const markAsDeletedText = data.mark_as_deleted_text\n const unmarkAsDeletedText = data.unmark_as_deleted_text\n\n const DESTROY_BUTTON_SELECTOR = '.dynamic-row--destroy-button'\n const DESTROY_ICON_SELECTOR = '.dynamic-row--destroy-icon'\n const DESTROY_BUTTON_COLUMN_SELECTOR = '.subform-row-delete'\n const INPUT_AND_LABELS_SELECTOR = 'input, label, select, textarea, fieldset, .form-group, .btn'\n\n const destroyButton = row.querySelector(DESTROY_BUTTON_SELECTOR)\n const destroyIcon = row.querySelector(DESTROY_ICON_SELECTOR)\n const destroyColumn = row.querySelector(DESTROY_BUTTON_COLUMN_SELECTOR)\n const inputsAndLabels = row.querySelectorAll(INPUT_AND_LABELS_SELECTOR)\n\n let markedForDestruction = false\n\n const container = row.closest('.dynamic-row--container')\n if (container) {\n // Move the row out of the container so it won't be replaced\n window.CapybaraLockstep?.startWork('moving-dynamic-row-to-safety')\n up.util.task(() => {\n container.before(row)\n window.CapybaraLockstep?.stopWork('moving-dynamic-row-to-safety')\n })\n }\n\n const listeners = []\n\n if (row.classList.contains('-template-row')) {\n // If the last row is being edited the first time, a new empty row appears\n const form = row.closest('form')\n\n async function addNewRow(evt) {\n if (evt.target.parentElement.classList.contains('ts-control')) {\n // dont add new rows when typing within the search input of a tom select\n return\n }\n if (evt.target.parentElement.classList.contains('subform--action')) {\n // dont add new rows when a row was disabled or similar\n return\n }\n\n if (up.util.isBlank(evt.target.value.trim())) {\n // Our model rejects :all_blank rows, so we have to wait\n // for the first \"real\" input\n // Otherwise we'd get duplicate nested form IDs!\n return\n }\n window.CapybaraLockstep?.startWork(`insert-blank-row-${form.id}`)\n unbindDirtynessListener()\n\n await up.render({\n // if the next line throws an exception, pass the `up_id` option to `#dynamic_rows_for`\n target: up.fragment.toTarget(container),\n url: form.action,\n method: form.method,\n headers: {\n 'validate-intent': 'add-new-row',\n 'X-Up-Validate': ':unknown',\n },\n params: new FormData(form),\n })\n window.CapybaraLockstep?.stopWork(`insert-blank-row-${form.id}`)\n }\n\n const unbindDirtynessListener = up.on(row, 'input', 'input, select, textarea', addNewRow)\n listeners.push(unbindDirtynessListener)\n }\n\n function toggleRowDisabling(evt) {\n if (evt.type === 'keydown') {\n if (evt.code === 'Space') {\n evt.preventDefault() // prevent scrolling down on the page\n } else {\n return // ignore any other keys like tabbing or pressing shift etc.\n }\n }\n markedForDestruction = !markedForDestruction\n\n let iconTitle\n if (markedForDestruction) {\n iconTitle = unmarkAsDeletedText\n } else {\n iconTitle = markAsDeletedText\n }\n\n const disableFields = !destroyButton.classList.contains('-marker-active')\n\n destroyButton.classList.toggle('-marker-active', disableFields)\n destroyIcon.setAttribute('title', iconTitle)\n row.classList.toggle('-marked-for-deletion', disableFields)\n\n Array.from(inputsAndLabels)\n .filter(element => !destroyColumn.contains(element))\n .filter(element => element.getAttribute('type') !== 'hidden')\n .forEach(element => {\n if (!element.toggledByDynamicRow && (element.getAttribute('disabled') === 'true' || element.classList.contains('disabled'))) {\n // Do nothing if a field was already disabled before we wanted to mark it as deleted\n } else {\n element.toggledByDynamicRow = true\n element.toggleAttribute('disabled', disableFields) // disable fields\n element.classList.toggle('disabled', disableFields) // disable pointer events for addons via bootstrap\n if (disableFields) {\n element.tomselect?.disable()\n } else {\n element.tomselect?.enable()\n }\n }\n })\n }\n\n if (destroyButton) {\n listeners.push(up.on(destroyButton, 'click keydown', toggleRowDisabling))\n }\n\n return listeners\n})\n", "/*! jQuery UI - v1.13.2 - 2022-08-16\n* http://jqueryui.com\n* Includes: widget.js, position.js, jquery-patch.js, keycode.js, scroll-parent.js, unique-id.js\n* Copyright jQuery Foundation and other contributors; Licensed MIT */\n\n( function( factory ) {\n\t\"use strict\";\n\t\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n} )( function( $ ) {\n\"use strict\";\n\n$.ui = $.ui || {};\n\nvar version = $.ui.version = \"1.13.2\";\n\n\n/*!\n * jQuery UI Widget 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Widget\n//>>group: Core\n//>>description: Provides a factory for creating stateful widgets with a common API.\n//>>docs: http://api.jqueryui.com/jQuery.widget/\n//>>demos: http://jqueryui.com/widget/\n\n\nvar widgetUuid = 0;\nvar widgetHasOwnProperty = Array.prototype.hasOwnProperty;\nvar widgetSlice = Array.prototype.slice;\n\n$.cleanData = $.cleanData || ( function( orig ) {\n\treturn function( elems ) {\n\t\tvar events, elem, i;\n\t\tfor ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {\n\n\t\t\t// Only trigger remove when necessary to save time\n\t\t\tevents = $._data( elem, \"events\" );\n\t\t\tif ( events && events.remove ) {\n\t\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t\t}\n\t\t}\n\t\torig( elems );\n\t};\n} )( $.cleanData );\n\n$.widget = $.widget || function( name, base, prototype ) {\n\tvar existingConstructor, constructor, basePrototype;\n\n\t// ProxiedPrototype allows the provided prototype to remain unmodified\n\t// so that it can be used as a mixin for multiple widgets (#8876)\n\tvar proxiedPrototype = {};\n\n\tvar namespace = name.split( \".\" )[ 0 ];\n\tname = name.split( \".\" )[ 1 ];\n\tvar fullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\tif ( Array.isArray( prototype ) ) {\n\t\tprototype = $.extend.apply( null, [ {} ].concat( prototype ) );\n\t}\n\n\t// Create selector for plugin\n\t$.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\n\t\t// Allow instantiation without \"new\" keyword\n\t\tif ( !this || !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// Allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\n\t// Extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\n\t\t// Copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\n\t\t// Track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t} );\n\n\tbasePrototype = new base();\n\n\t// We need to make the options hash a property directly on the new instance\n\t// otherwise we'll modify the options hash on the prototype that we're\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( typeof value !== \"function\" ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = ( function() {\n\t\t\tfunction _super() {\n\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t}\n\n\t\t\tfunction _superApply( args ) {\n\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t}\n\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super;\n\t\t\t\tvar __superApply = this._superApply;\n\t\t\t\tvar returnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t} )();\n\t} );\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don't prefix for widgets that aren't DOM-based\n\t\twidgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t} );\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We're essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// Redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor,\n\t\t\t\tchild._proto );\n\t\t} );\n\n\t\t// Remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n\n\treturn constructor;\n};\n\n$.widget.extend = function( target ) {\n\tvar input = widgetSlice.call( arguments, 1 );\n\tvar inputIndex = 0;\n\tvar inputLength = input.length;\n\tvar key;\n\tvar value;\n\n\tfor ( ; inputIndex < inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {\n\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\n\t\t\t\t\t\t// Don't extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\";\n\t\tvar args = widgetSlice.call( arguments, 1 );\n\t\tvar returnValue = this;\n\n\t\tif ( isMethodCall ) {\n\n\t\t\t// If this is an empty collection, we need to have the instance method\n\t\t\t// return undefined instead of the jQuery instance\n\t\t\tif ( !this.length && options === \"instance\" ) {\n\t\t\t\treturnValue = undefined;\n\t\t\t} else {\n\t\t\t\tthis.each( function() {\n\t\t\t\t\tvar methodValue;\n\t\t\t\t\tvar instance = $.data( this, fullName );\n\n\t\t\t\t\tif ( options === \"instance\" ) {\n\t\t\t\t\t\treturnValue = instance;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !instance ) {\n\t\t\t\t\t\treturn $.error( \"cannot call methods on \" + name +\n\t\t\t\t\t\t\t\" prior to initialization; \" +\n\t\t\t\t\t\t\t\"attempted to call method '\" + options + \"'\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( typeof instance[ options ] !== \"function\" ||\n\t\t\t\t\t\toptions.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\t\treturn $.error( \"no such method '\" + options + \"' for \" + name +\n\t\t\t\t\t\t\t\" widget instance\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\n\t\t\t\t\tif ( methodValue !== instance && methodValue !== undefined ) {\n\t\t\t\t\t\treturnValue = methodValue && methodValue.jquery ?\n\t\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\t\tmethodValue;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// Allow multiple hashes to be passed on init\n\t\t\tif ( args.length ) {\n\t\t\t\toptions = $.widget.extend.apply( null, [ options ].concat( args ) );\n\t\t\t}\n\n\t\t\tthis.each( function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} );\n\t\t\t\t\tif ( instance._init ) {\n\t\t\t\t\t\tinstance._init();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = $.Widget || function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"
\",\n\n\toptions: {\n\t\tclasses: {},\n\t\tdisabled: false,\n\n\t\t// Callbacks\n\t\tcreate: null\n\t},\n\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = widgetUuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\t\tthis.classesElementLookup = {};\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t\tthis.document = $( element.style ?\n\n\t\t\t\t// Element within the document\n\t\t\t\telement.ownerDocument :\n\n\t\t\t\t// Element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );\n\t\t}\n\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis._create();\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis._setOptionDisabled( this.options.disabled );\n\t\t}\n\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\n\t_getCreateOptions: function() {\n\t\treturn {};\n\t},\n\n\t_getCreateEventData: $.noop,\n\n\t_create: $.noop,\n\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tvar that = this;\n\n\t\tthis._destroy();\n\t\t$.each( this.classesElementLookup, function( key, value ) {\n\t\t\tthat._removeClass( value, key );\n\t\t} );\n\n\t\t// We can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.off( this.eventNamespace )\n\t\t\t.removeData( this.widgetFullName );\n\t\tthis.widget()\n\t\t\t.off( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" );\n\n\t\t// Clean up events and states\n\t\tthis.bindings.off( this.eventNamespace );\n\t},\n\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key;\n\t\tvar parts;\n\t\tvar curOption;\n\t\tvar i;\n\n\t\tif ( arguments.length === 0 ) {\n\n\t\t\t// Don't return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\n\t\t\t// Handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i < parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"classes\" ) {\n\t\t\tthis._setOptionClasses( value );\n\t\t}\n\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis._setOptionDisabled( value );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOptionClasses: function( value ) {\n\t\tvar classKey, elements, currentElements;\n\n\t\tfor ( classKey in value ) {\n\t\t\tcurrentElements = this.classesElementLookup[ classKey ];\n\t\t\tif ( value[ classKey ] === this.options.classes[ classKey ] ||\n\t\t\t\t\t!currentElements ||\n\t\t\t\t\t!currentElements.length ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// We are doing this to create a new jQuery object because the _removeClass() call\n\t\t\t// on the next line is going to destroy the reference to the current elements being\n\t\t\t// tracked. We need to save a copy of this collection so that we can add the new classes\n\t\t\t// below.\n\t\t\telements = $( currentElements.get() );\n\t\t\tthis._removeClass( currentElements, classKey );\n\n\t\t\t// We don't use _addClass() here, because that uses this.options.classes\n\t\t\t// for generating the string of classes. We want to use the value passed in from\n\t\t\t// _setOption(), this is the new value of the classes option which was passed to\n\t\t\t// _setOption(). We pass this value directly to _classes().\n\t\t\telements.addClass( this._classes( {\n\t\t\t\telement: elements,\n\t\t\t\tkeys: classKey,\n\t\t\t\tclasses: value,\n\t\t\t\tadd: true\n\t\t\t} ) );\n\t\t}\n\t},\n\n\t_setOptionDisabled: function( value ) {\n\t\tthis._toggleClass( this.widget(), this.widgetFullName + \"-disabled\", null, !!value );\n\n\t\t// If the widget is becoming disabled, then nothing is interactive\n\t\tif ( value ) {\n\t\t\tthis._removeClass( this.hoverable, null, \"ui-state-hover\" );\n\t\t\tthis._removeClass( this.focusable, null, \"ui-state-focus\" );\n\t\t}\n\t},\n\n\tenable: function() {\n\t\treturn this._setOptions( { disabled: false } );\n\t},\n\n\tdisable: function() {\n\t\treturn this._setOptions( { disabled: true } );\n\t},\n\n\t_classes: function( options ) {\n\t\tvar full = [];\n\t\tvar that = this;\n\n\t\toptions = $.extend( {\n\t\t\telement: this.element,\n\t\t\tclasses: this.options.classes || {}\n\t\t}, options );\n\n\t\tfunction bindRemoveEvent() {\n\t\t\tvar nodesToBind = [];\n\n\t\t\toptions.element.each( function( _, element ) {\n\t\t\t\tvar isTracked = $.map( that.classesElementLookup, function( elements ) {\n\t\t\t\t\treturn elements;\n\t\t\t\t} )\n\t\t\t\t\t.some( function( elements ) {\n\t\t\t\t\t\treturn elements.is( element );\n\t\t\t\t\t} );\n\n\t\t\t\tif ( !isTracked ) {\n\t\t\t\t\tnodesToBind.push( element );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tthat._on( $( nodesToBind ), {\n\t\t\t\tremove: \"_untrackClassesElement\"\n\t\t\t} );\n\t\t}\n\n\t\tfunction processClassString( classes, checkOption ) {\n\t\t\tvar current, i;\n\t\t\tfor ( i = 0; i < classes.length; i++ ) {\n\t\t\t\tcurrent = that.classesElementLookup[ classes[ i ] ] || $();\n\t\t\t\tif ( options.add ) {\n\t\t\t\t\tbindRemoveEvent();\n\t\t\t\t\tcurrent = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = $( current.not( options.element ).get() );\n\t\t\t\t}\n\t\t\t\tthat.classesElementLookup[ classes[ i ] ] = current;\n\t\t\t\tfull.push( classes[ i ] );\n\t\t\t\tif ( checkOption && options.classes[ classes[ i ] ] ) {\n\t\t\t\t\tfull.push( options.classes[ classes[ i ] ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( options.keys ) {\n\t\t\tprocessClassString( options.keys.match( /\\S+/g ) || [], true );\n\t\t}\n\t\tif ( options.extra ) {\n\t\t\tprocessClassString( options.extra.match( /\\S+/g ) || [] );\n\t\t}\n\n\t\treturn full.join( \" \" );\n\t},\n\n\t_untrackClassesElement: function( event ) {\n\t\tvar that = this;\n\t\t$.each( that.classesElementLookup, function( key, value ) {\n\t\t\tif ( $.inArray( event.target, value ) !== -1 ) {\n\t\t\t\tthat.classesElementLookup[ key ] = $( value.not( event.target ).get() );\n\t\t\t}\n\t\t} );\n\n\t\tthis._off( $( event.target ) );\n\t},\n\n\t_removeClass: function( element, keys, extra ) {\n\t\treturn this._toggleClass( element, keys, extra, false );\n\t},\n\n\t_addClass: function( element, keys, extra ) {\n\t\treturn this._toggleClass( element, keys, extra, true );\n\t},\n\n\t_toggleClass: function( element, keys, extra, add ) {\n\t\tadd = ( typeof add === \"boolean\" ) ? add : extra;\n\t\tvar shift = ( typeof element === \"string\" || element === null ),\n\t\t\toptions = {\n\t\t\t\textra: shift ? keys : extra,\n\t\t\t\tkeys: shift ? element : keys,\n\t\t\t\telement: shift ? this.element : element,\n\t\t\t\tadd: add\n\t\t\t};\n\t\toptions.element.toggleClass( this._classes( options ), add );\n\t\treturn this;\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement;\n\t\tvar instance = this;\n\n\t\t// No suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// No element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\n\t\t\t\t// Allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck &&\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// Copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^([\\w:-]*)\\s*(.*)$/ );\n\t\t\tvar eventName = match[ 1 ] + instance.eventNamespace;\n\t\t\tvar selector = match[ 2 ];\n\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.on( eventName, selector, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.on( eventName, handlerProxy );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = ( eventName || \"\" ).split( \" \" ).join( this.eventNamespace + \" \" ) +\n\t\t\tthis.eventNamespace;\n\t\telement.off( eventName );\n\n\t\t// Clear the stack to avoid memory leaks (#10056)\n\t\tthis.bindings = $( this.bindings.not( element ).get() );\n\t\tthis.focusable = $( this.focusable.not( element ).get() );\n\t\tthis.hoverable = $( this.hoverable.not( element ).get() );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\tthis._addClass( $( event.currentTarget ), null, \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\tthis._removeClass( $( event.currentTarget ), null, \"ui-state-hover\" );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\tthis._addClass( $( event.currentTarget ), null, \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\tthis._removeClass( $( event.currentTarget ), null, \"ui-state-focus\" );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig;\n\t\tvar callback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\n\t\t// The original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// Copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( typeof callback === \"function\" &&\n\t\t\tcallback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\n\t\tvar hasOptions;\n\t\tvar effectName = !options ?\n\t\t\tmethod :\n\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\tdefaultEffect :\n\t\t\t\toptions.effect || defaultEffect;\n\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t} else if ( options === true ) {\n\t\t\toptions = {};\n\t\t}\n\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\n\t\tif ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method && element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue( function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t} );\n\t\t}\n\t};\n} );\n\nvar widget = $.widget;\n\n\n/*!\n * jQuery UI Position 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/position/\n */\n\n//>>label: Position\n//>>group: Core\n//>>description: Positions elements relative to other elements.\n//>>docs: http://api.jqueryui.com/position/\n//>>demos: http://jqueryui.com/position/\n\n\n( function() {\nvar cachedScrollbarWidth,\n\tmax = Math.max,\n\tabs = Math.abs,\n\trhorizontal = /left|center|right/,\n\trvertical = /top|center|bottom/,\n\troffset = /[\\+\\-]\\d+(\\.[\\d]+)?%?/,\n\trposition = /^\\w+/,\n\trpercent = /%$/,\n\t_position = $.fn.position;\n\nfunction getOffsets( offsets, width, height ) {\n\treturn [\n\t\tparseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),\n\t\tparseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )\n\t];\n}\n\nfunction parseCss( element, property ) {\n\treturn parseInt( $.css( element, property ), 10 ) || 0;\n}\n\nfunction isWindow( obj ) {\n\treturn obj != null && obj === obj.window;\n}\n\nfunction getDimensions( elem ) {\n\tvar raw = elem[ 0 ];\n\tif ( raw.nodeType === 9 ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: 0, left: 0 }\n\t\t};\n\t}\n\tif ( isWindow( raw ) ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: elem.scrollTop(), left: elem.scrollLeft() }\n\t\t};\n\t}\n\tif ( raw.preventDefault ) {\n\t\treturn {\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\toffset: { top: raw.pageY, left: raw.pageX }\n\t\t};\n\t}\n\treturn {\n\t\twidth: elem.outerWidth(),\n\t\theight: elem.outerHeight(),\n\t\toffset: elem.offset()\n\t};\n}\n\n$.position = $.position || {\n\tscrollbarWidth: function() {\n\t\tif ( cachedScrollbarWidth !== undefined ) {\n\t\t\treturn cachedScrollbarWidth;\n\t\t}\n\t\tvar w1, w2,\n\t\t\tdiv = $( \"
\" +\n\t\t\t\t\"
\" ),\n\t\t\tinnerDiv = div.children()[ 0 ];\n\n\t\t$( \"body\" ).append( div );\n\t\tw1 = innerDiv.offsetWidth;\n\t\tdiv.css( \"overflow\", \"scroll\" );\n\n\t\tw2 = innerDiv.offsetWidth;\n\n\t\tif ( w1 === w2 ) {\n\t\t\tw2 = div[ 0 ].clientWidth;\n\t\t}\n\n\t\tdiv.remove();\n\n\t\treturn ( cachedScrollbarWidth = w1 - w2 );\n\t},\n\tgetScrollInfo: function( within ) {\n\t\tvar overflowX = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-x\" ),\n\t\t\toverflowY = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-y\" ),\n\t\t\thasOverflowX = overflowX === \"scroll\" ||\n\t\t\t\t( overflowX === \"auto\" && within.width < within.element[ 0 ].scrollWidth ),\n\t\t\thasOverflowY = overflowY === \"scroll\" ||\n\t\t\t\t( overflowY === \"auto\" && within.height < within.element[ 0 ].scrollHeight );\n\t\treturn {\n\t\t\twidth: hasOverflowY ? $.position.scrollbarWidth() : 0,\n\t\t\theight: hasOverflowX ? $.position.scrollbarWidth() : 0\n\t\t};\n\t},\n\tgetWithinInfo: function( element ) {\n\t\tvar withinElement = $( element || window ),\n\t\t\tisElemWindow = isWindow( withinElement[ 0 ] ),\n\t\t\tisDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,\n\t\t\thasOffset = !isElemWindow && !isDocument;\n\t\treturn {\n\t\t\telement: withinElement,\n\t\t\tisWindow: isElemWindow,\n\t\t\tisDocument: isDocument,\n\t\t\toffset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },\n\t\t\tscrollLeft: withinElement.scrollLeft(),\n\t\t\tscrollTop: withinElement.scrollTop(),\n\t\t\twidth: withinElement.outerWidth(),\n\t\t\theight: withinElement.outerHeight()\n\t\t};\n\t}\n};\n\n$.fn.position = function( options ) {\n\tif ( !options || !options.of ) {\n\t\treturn _position.apply( this, arguments );\n\t}\n\n\t// Make a copy, we don't want to modify arguments\n\toptions = $.extend( {}, options );\n\n\tvar atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,\n\n\t\t// Make sure string options are treated as CSS selectors\n\t\ttarget = typeof options.of === \"string\" ?\n\t\t\t$( document ).find( options.of ) :\n\t\t\t$( options.of ),\n\n\t\twithin = $.position.getWithinInfo( options.within ),\n\t\tscrollInfo = $.position.getScrollInfo( within ),\n\t\tcollision = ( options.collision || \"flip\" ).split( \" \" ),\n\t\toffsets = {};\n\n\tdimensions = getDimensions( target );\n\tif ( target[ 0 ].preventDefault ) {\n\n\t\t// Force left top to allow flipping\n\t\toptions.at = \"left top\";\n\t}\n\ttargetWidth = dimensions.width;\n\ttargetHeight = dimensions.height;\n\ttargetOffset = dimensions.offset;\n\n\t// Clone to reuse original targetOffset later\n\tbasePosition = $.extend( {}, targetOffset );\n\n\t// Force my and at to have valid horizontal and vertical positions\n\t// if a value is missing or invalid, it will be converted to center\n\t$.each( [ \"my\", \"at\" ], function() {\n\t\tvar pos = ( options[ this ] || \"\" ).split( \" \" ),\n\t\t\thorizontalOffset,\n\t\t\tverticalOffset;\n\n\t\tif ( pos.length === 1 ) {\n\t\t\tpos = rhorizontal.test( pos[ 0 ] ) ?\n\t\t\t\tpos.concat( [ \"center\" ] ) :\n\t\t\t\trvertical.test( pos[ 0 ] ) ?\n\t\t\t\t\t[ \"center\" ].concat( pos ) :\n\t\t\t\t\t[ \"center\", \"center\" ];\n\t\t}\n\t\tpos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : \"center\";\n\t\tpos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : \"center\";\n\n\t\t// Calculate offsets\n\t\thorizontalOffset = roffset.exec( pos[ 0 ] );\n\t\tverticalOffset = roffset.exec( pos[ 1 ] );\n\t\toffsets[ this ] = [\n\t\t\thorizontalOffset ? horizontalOffset[ 0 ] : 0,\n\t\t\tverticalOffset ? verticalOffset[ 0 ] : 0\n\t\t];\n\n\t\t// Reduce to just the positions without the offsets\n\t\toptions[ this ] = [\n\t\t\trposition.exec( pos[ 0 ] )[ 0 ],\n\t\t\trposition.exec( pos[ 1 ] )[ 0 ]\n\t\t];\n\t} );\n\n\t// Normalize collision option\n\tif ( collision.length === 1 ) {\n\t\tcollision[ 1 ] = collision[ 0 ];\n\t}\n\n\tif ( options.at[ 0 ] === \"right\" ) {\n\t\tbasePosition.left += targetWidth;\n\t} else if ( options.at[ 0 ] === \"center\" ) {\n\t\tbasePosition.left += targetWidth / 2;\n\t}\n\n\tif ( options.at[ 1 ] === \"bottom\" ) {\n\t\tbasePosition.top += targetHeight;\n\t} else if ( options.at[ 1 ] === \"center\" ) {\n\t\tbasePosition.top += targetHeight / 2;\n\t}\n\n\tatOffset = getOffsets( offsets.at, targetWidth, targetHeight );\n\tbasePosition.left += atOffset[ 0 ];\n\tbasePosition.top += atOffset[ 1 ];\n\n\treturn this.each( function() {\n\t\tvar collisionPosition, using,\n\t\t\telem = $( this ),\n\t\t\telemWidth = elem.outerWidth(),\n\t\t\telemHeight = elem.outerHeight(),\n\t\t\tmarginLeft = parseCss( this, \"marginLeft\" ),\n\t\t\tmarginTop = parseCss( this, \"marginTop\" ),\n\t\t\tcollisionWidth = elemWidth + marginLeft + parseCss( this, \"marginRight\" ) +\n\t\t\t\tscrollInfo.width,\n\t\t\tcollisionHeight = elemHeight + marginTop + parseCss( this, \"marginBottom\" ) +\n\t\t\t\tscrollInfo.height,\n\t\t\tposition = $.extend( {}, basePosition ),\n\t\t\tmyOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );\n\n\t\tif ( options.my[ 0 ] === \"right\" ) {\n\t\t\tposition.left -= elemWidth;\n\t\t} else if ( options.my[ 0 ] === \"center\" ) {\n\t\t\tposition.left -= elemWidth / 2;\n\t\t}\n\n\t\tif ( options.my[ 1 ] === \"bottom\" ) {\n\t\t\tposition.top -= elemHeight;\n\t\t} else if ( options.my[ 1 ] === \"center\" ) {\n\t\t\tposition.top -= elemHeight / 2;\n\t\t}\n\n\t\tposition.left += myOffset[ 0 ];\n\t\tposition.top += myOffset[ 1 ];\n\n\t\tcollisionPosition = {\n\t\t\tmarginLeft: marginLeft,\n\t\t\tmarginTop: marginTop\n\t\t};\n\n\t\t$.each( [ \"left\", \"top\" ], function( i, dir ) {\n\t\t\tif ( $.ui.position[ collision[ i ] ] ) {\n\t\t\t\t$.ui.position[ collision[ i ] ][ dir ]( position, {\n\t\t\t\t\ttargetWidth: targetWidth,\n\t\t\t\t\ttargetHeight: targetHeight,\n\t\t\t\t\telemWidth: elemWidth,\n\t\t\t\t\telemHeight: elemHeight,\n\t\t\t\t\tcollisionPosition: collisionPosition,\n\t\t\t\t\tcollisionWidth: collisionWidth,\n\t\t\t\t\tcollisionHeight: collisionHeight,\n\t\t\t\t\toffset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],\n\t\t\t\t\tmy: options.my,\n\t\t\t\t\tat: options.at,\n\t\t\t\t\twithin: within,\n\t\t\t\t\telem: elem\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\tif ( options.using ) {\n\n\t\t\t// Adds feedback as second argument to using callback, if present\n\t\t\tusing = function( props ) {\n\t\t\t\tvar left = targetOffset.left - position.left,\n\t\t\t\t\tright = left + targetWidth - elemWidth,\n\t\t\t\t\ttop = targetOffset.top - position.top,\n\t\t\t\t\tbottom = top + targetHeight - elemHeight,\n\t\t\t\t\tfeedback = {\n\t\t\t\t\t\ttarget: {\n\t\t\t\t\t\t\telement: target,\n\t\t\t\t\t\t\tleft: targetOffset.left,\n\t\t\t\t\t\t\ttop: targetOffset.top,\n\t\t\t\t\t\t\twidth: targetWidth,\n\t\t\t\t\t\t\theight: targetHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\telement: {\n\t\t\t\t\t\t\telement: elem,\n\t\t\t\t\t\t\tleft: position.left,\n\t\t\t\t\t\t\ttop: position.top,\n\t\t\t\t\t\t\twidth: elemWidth,\n\t\t\t\t\t\t\theight: elemHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\thorizontal: right < 0 ? \"left\" : left > 0 ? \"right\" : \"center\",\n\t\t\t\t\t\tvertical: bottom < 0 ? \"top\" : top > 0 ? \"bottom\" : \"middle\"\n\t\t\t\t\t};\n\t\t\t\tif ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {\n\t\t\t\t\tfeedback.horizontal = \"center\";\n\t\t\t\t}\n\t\t\t\tif ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {\n\t\t\t\t\tfeedback.vertical = \"middle\";\n\t\t\t\t}\n\t\t\t\tif ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {\n\t\t\t\t\tfeedback.important = \"horizontal\";\n\t\t\t\t} else {\n\t\t\t\t\tfeedback.important = \"vertical\";\n\t\t\t\t}\n\t\t\t\toptions.using.call( this, props, feedback );\n\t\t\t};\n\t\t}\n\n\t\telem.offset( $.extend( position, { using: using } ) );\n\t} );\n};\n\n$.ui.position = {\n\tfit: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\touterWidth = within.width,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = withinOffset - collisionPosLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,\n\t\t\t\tnewOverRight;\n\n\t\t\t// Element is wider than within\n\t\t\tif ( data.collisionWidth > outerWidth ) {\n\n\t\t\t\t// Element is initially over the left side of within\n\t\t\t\tif ( overLeft > 0 && overRight <= 0 ) {\n\t\t\t\t\tnewOverRight = position.left + overLeft + data.collisionWidth - outerWidth -\n\t\t\t\t\t\twithinOffset;\n\t\t\t\t\tposition.left += overLeft - newOverRight;\n\n\t\t\t\t// Element is initially over right side of within\n\t\t\t\t} else if ( overRight > 0 && overLeft <= 0 ) {\n\t\t\t\t\tposition.left = withinOffset;\n\n\t\t\t\t// Element is initially over both left and right sides of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overLeft > overRight ) {\n\t\t\t\t\t\tposition.left = withinOffset + outerWidth - data.collisionWidth;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Too far left -> align with left edge\n\t\t\t} else if ( overLeft > 0 ) {\n\t\t\t\tposition.left += overLeft;\n\n\t\t\t// Too far right -> align with right edge\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tposition.left -= overRight;\n\n\t\t\t// Adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.left = max( position.left - collisionPosLeft, position.left );\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\touterHeight = data.within.height,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = withinOffset - collisionPosTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,\n\t\t\t\tnewOverBottom;\n\n\t\t\t// Element is taller than within\n\t\t\tif ( data.collisionHeight > outerHeight ) {\n\n\t\t\t\t// Element is initially over the top of within\n\t\t\t\tif ( overTop > 0 && overBottom <= 0 ) {\n\t\t\t\t\tnewOverBottom = position.top + overTop + data.collisionHeight - outerHeight -\n\t\t\t\t\t\twithinOffset;\n\t\t\t\t\tposition.top += overTop - newOverBottom;\n\n\t\t\t\t// Element is initially over bottom of within\n\t\t\t\t} else if ( overBottom > 0 && overTop <= 0 ) {\n\t\t\t\t\tposition.top = withinOffset;\n\n\t\t\t\t// Element is initially over both top and bottom of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overTop > overBottom ) {\n\t\t\t\t\t\tposition.top = withinOffset + outerHeight - data.collisionHeight;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Too far up -> align with top\n\t\t\t} else if ( overTop > 0 ) {\n\t\t\t\tposition.top += overTop;\n\n\t\t\t// Too far down -> align with bottom edge\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tposition.top -= overBottom;\n\n\t\t\t// Adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.top = max( position.top - collisionPosTop, position.top );\n\t\t\t}\n\t\t}\n\t},\n\tflip: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.left + within.scrollLeft,\n\t\t\t\touterWidth = within.width,\n\t\t\t\toffsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = collisionPosLeft - offsetLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,\n\t\t\t\tmyOffset = data.my[ 0 ] === \"left\" ?\n\t\t\t\t\t-data.elemWidth :\n\t\t\t\t\tdata.my[ 0 ] === \"right\" ?\n\t\t\t\t\t\tdata.elemWidth :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 0 ] === \"left\" ?\n\t\t\t\t\tdata.targetWidth :\n\t\t\t\t\tdata.at[ 0 ] === \"right\" ?\n\t\t\t\t\t\t-data.targetWidth :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 0 ],\n\t\t\t\tnewOverRight,\n\t\t\t\tnewOverLeft;\n\n\t\t\tif ( overLeft < 0 ) {\n\t\t\t\tnewOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -\n\t\t\t\t\touterWidth - withinOffset;\n\t\t\t\tif ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tnewOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +\n\t\t\t\t\tatOffset + offset - offsetLeft;\n\t\t\t\tif ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.top + within.scrollTop,\n\t\t\t\touterHeight = within.height,\n\t\t\t\toffsetTop = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = collisionPosTop - offsetTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,\n\t\t\t\ttop = data.my[ 1 ] === \"top\",\n\t\t\t\tmyOffset = top ?\n\t\t\t\t\t-data.elemHeight :\n\t\t\t\t\tdata.my[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\tdata.elemHeight :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 1 ] === \"top\" ?\n\t\t\t\t\tdata.targetHeight :\n\t\t\t\t\tdata.at[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\t-data.targetHeight :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 1 ],\n\t\t\t\tnewOverTop,\n\t\t\t\tnewOverBottom;\n\t\t\tif ( overTop < 0 ) {\n\t\t\t\tnewOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -\n\t\t\t\t\touterHeight - withinOffset;\n\t\t\t\tif ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tnewOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +\n\t\t\t\t\toffset - offsetTop;\n\t\t\t\tif ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tflipfit: {\n\t\tleft: function() {\n\t\t\t$.ui.position.flip.left.apply( this, arguments );\n\t\t\t$.ui.position.fit.left.apply( this, arguments );\n\t\t},\n\t\ttop: function() {\n\t\t\t$.ui.position.flip.top.apply( this, arguments );\n\t\t\t$.ui.position.fit.top.apply( this, arguments );\n\t\t}\n\t}\n};\n\n} )();\n\nvar position = $.ui.position;\n\n\n/*!\n * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n */\n\n//>>label: jQuery 1.8+ Support\n//>>group: Core\n//>>description: Support version 1.8.x and newer of jQuery core\n\n\n// Support: jQuery 1.9.x or older\n// $.expr[ \":\" ] is deprecated.\nif ( !$.expr.pseudos ) {\n\t$.expr.pseudos = $.expr[ \":\" ];\n}\n\n// Support: jQuery 1.11.x or older\n// $.unique has been renamed to $.uniqueSort\nif ( !$.uniqueSort ) {\n\t$.uniqueSort = $.unique;\n}\n\n// Support: jQuery 2.2.x or older.\n// This method has been defined in jQuery 3.0.0.\n// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js\nif ( !$.escapeSelector ) {\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\tvar rcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g;\n\n\tvar fcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t};\n\n\t$.escapeSelector = function( sel ) {\n\t\treturn ( sel + \"\" ).replace( rcssescape, fcssescape );\n\t};\n}\n\n// Support: jQuery 3.4.x or older\n// These methods have been defined in jQuery 3.5.0.\nif ( !$.fn.even || !$.fn.odd ) {\n\t$.fn.extend( {\n\t\teven: function() {\n\t\t\treturn this.filter( function( i ) {\n\t\t\t\treturn i % 2 === 0;\n\t\t\t} );\n\t\t},\n\t\todd: function() {\n\t\t\treturn this.filter( function( i ) {\n\t\t\t\treturn i % 2 === 1;\n\t\t\t} );\n\t\t}\n\t} );\n}\n\n;\n/*!\n * jQuery UI Keycode 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Keycode\n//>>group: Core\n//>>description: Provide keycodes as keynames\n//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/\n\n\nvar keycode = $.ui.keyCode = {\n\tBACKSPACE: 8,\n\tCOMMA: 188,\n\tDELETE: 46,\n\tDOWN: 40,\n\tEND: 35,\n\tENTER: 13,\n\tESCAPE: 27,\n\tHOME: 36,\n\tLEFT: 37,\n\tPAGE_DOWN: 34,\n\tPAGE_UP: 33,\n\tPERIOD: 190,\n\tRIGHT: 39,\n\tSPACE: 32,\n\tTAB: 9,\n\tUP: 38\n};\n\n\n/*!\n * jQuery UI Scroll Parent 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: scrollParent\n//>>group: Core\n//>>description: Get the closest ancestor element that is scrollable.\n//>>docs: http://api.jqueryui.com/scrollParent/\n\n\nvar scrollParent = $.fn.scrollParent = function( includeHidden ) {\n\tvar position = this.css( \"position\" ),\n\t\texcludeStaticParent = position === \"absolute\",\n\t\toverflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,\n\t\tscrollParent = this.parents().filter( function() {\n\t\t\tvar parent = $( this );\n\t\t\tif ( excludeStaticParent && parent.css( \"position\" ) === \"static\" ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn overflowRegex.test( parent.css( \"overflow\" ) + parent.css( \"overflow-y\" ) +\n\t\t\t\tparent.css( \"overflow-x\" ) );\n\t\t} ).eq( 0 );\n\n\treturn position === \"fixed\" || !scrollParent.length ?\n\t\t$( this[ 0 ].ownerDocument || document ) :\n\t\tscrollParent;\n};\n\n\n/*!\n * jQuery UI Unique ID 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: uniqueId\n//>>group: Core\n//>>description: Functions to generate and remove uniqueId's\n//>>docs: http://api.jqueryui.com/uniqueId/\n\n\nvar uniqueId = $.fn.extend( {\n\tuniqueId: ( function() {\n\t\tvar uuid = 0;\n\n\t\treturn function() {\n\t\t\treturn this.each( function() {\n\t\t\t\tif ( !this.id ) {\n\t\t\t\t\tthis.id = \"ui-id-\" + ( ++uuid );\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\t} )(),\n\n\tremoveUniqueId: function() {\n\t\treturn this.each( function() {\n\t\t\tif ( /^ui-id-\\d+$/.test( this.id ) ) {\n\t\t\t\t$( this ).removeAttr( \"id\" );\n\t\t\t}\n\t\t} );\n\t}\n} );\n\n\n\n\n} );", "/*!\n * jquery.fancytree.js\n * Tree view control with support for lazy loading and much more.\n * https://github.com/mar10/fancytree/\n *\n * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de)\n * Released under the MIT license\n * https://github.com/mar10/fancytree/wiki/LicenseInfo\n *\n * @version 2.38.3\n * @date 2023-02-01T20:52:50Z\n */\n\n/** Core Fancytree module.\n */\n\n// UMD wrapper for the Fancytree core module\n(function (factory) {\n\tif (typeof define === \"function\" && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine([\"jquery\", \"./jquery.fancytree.ui-deps\"], factory);\n\t} else if (typeof module === \"object\" && module.exports) {\n\t\t// Node/CommonJS\n\t\trequire(\"./jquery.fancytree.ui-deps\");\n\t\tmodule.exports = factory(require(\"jquery\"));\n\t} else {\n\t\t// Browser globals\n\t\tfactory(jQuery);\n\t}\n})(function ($) {\n\t\"use strict\";\n\n\t// prevent duplicate loading\n\tif ($.ui && $.ui.fancytree) {\n\t\t$.ui.fancytree.warn(\"Fancytree: ignored duplicate include\");\n\t\treturn;\n\t}\n\n\t/******************************************************************************\n\t * Private functions and variables\n\t */\n\n\tvar i,\n\t\tattr,\n\t\tFT = null, // initialized below\n\t\tTEST_IMG = new RegExp(/\\.|\\//), // strings are considered image urls if they contain '.' or '/'\n\t\tREX_HTML = /[&<>\"'/]/g, // Escape those characters\n\t\tREX_TOOLTIP = /[<>\"'/]/g, // Don't escape `&` in tooltips\n\t\tRECURSIVE_REQUEST_ERROR = \"$recursive_request\",\n\t\tINVALID_REQUEST_TARGET_ERROR = \"$request_target_invalid\",\n\t\tENTITY_MAP = {\n\t\t\t\"&\": \"&\",\n\t\t\t\"<\": \"<\",\n\t\t\t\">\": \">\",\n\t\t\t'\"': \""\",\n\t\t\t\"'\": \"'\",\n\t\t\t\"/\": \"/\",\n\t\t},\n\t\tIGNORE_KEYCODES = { 16: true, 17: true, 18: true },\n\t\tSPECIAL_KEYCODES = {\n\t\t\t8: \"backspace\",\n\t\t\t9: \"tab\",\n\t\t\t10: \"return\",\n\t\t\t13: \"return\",\n\t\t\t// 16: null, 17: null, 18: null, // ignore shift, ctrl, alt\n\t\t\t19: \"pause\",\n\t\t\t20: \"capslock\",\n\t\t\t27: \"esc\",\n\t\t\t32: \"space\",\n\t\t\t33: \"pageup\",\n\t\t\t34: \"pagedown\",\n\t\t\t35: \"end\",\n\t\t\t36: \"home\",\n\t\t\t37: \"left\",\n\t\t\t38: \"up\",\n\t\t\t39: \"right\",\n\t\t\t40: \"down\",\n\t\t\t45: \"insert\",\n\t\t\t46: \"del\",\n\t\t\t59: \";\",\n\t\t\t61: \"=\",\n\t\t\t// 91: null, 93: null, // ignore left and right meta\n\t\t\t96: \"0\",\n\t\t\t97: \"1\",\n\t\t\t98: \"2\",\n\t\t\t99: \"3\",\n\t\t\t100: \"4\",\n\t\t\t101: \"5\",\n\t\t\t102: \"6\",\n\t\t\t103: \"7\",\n\t\t\t104: \"8\",\n\t\t\t105: \"9\",\n\t\t\t106: \"*\",\n\t\t\t107: \"+\",\n\t\t\t109: \"-\",\n\t\t\t110: \".\",\n\t\t\t111: \"/\",\n\t\t\t112: \"f1\",\n\t\t\t113: \"f2\",\n\t\t\t114: \"f3\",\n\t\t\t115: \"f4\",\n\t\t\t116: \"f5\",\n\t\t\t117: \"f6\",\n\t\t\t118: \"f7\",\n\t\t\t119: \"f8\",\n\t\t\t120: \"f9\",\n\t\t\t121: \"f10\",\n\t\t\t122: \"f11\",\n\t\t\t123: \"f12\",\n\t\t\t144: \"numlock\",\n\t\t\t145: \"scroll\",\n\t\t\t173: \"-\",\n\t\t\t186: \";\",\n\t\t\t187: \"=\",\n\t\t\t188: \",\",\n\t\t\t189: \"-\",\n\t\t\t190: \".\",\n\t\t\t191: \"/\",\n\t\t\t192: \"`\",\n\t\t\t219: \"[\",\n\t\t\t220: \"\\\\\",\n\t\t\t221: \"]\",\n\t\t\t222: \"'\",\n\t\t},\n\t\tMODIFIERS = {\n\t\t\t16: \"shift\",\n\t\t\t17: \"ctrl\",\n\t\t\t18: \"alt\",\n\t\t\t91: \"meta\",\n\t\t\t93: \"meta\",\n\t\t},\n\t\tMOUSE_BUTTONS = { 0: \"\", 1: \"left\", 2: \"middle\", 3: \"right\" },\n\t\t// Boolean attributes that can be set with equivalent class names in the LI tags\n\t\t// Note: v2.23: checkbox and hideCheckbox are *not* in this list\n\t\tCLASS_ATTRS =\n\t\t\t\"active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore\".split(\n\t\t\t\t\" \"\n\t\t\t),\n\t\tCLASS_ATTR_MAP = {},\n\t\t// Top-level Fancytree attributes, that can be set by dict\n\t\tTREE_ATTRS = \"columns types\".split(\" \"),\n\t\t// TREE_ATTR_MAP = {},\n\t\t// Top-level FancytreeNode attributes, that can be set by dict\n\t\tNODE_ATTRS =\n\t\t\t\"checkbox expanded extraClasses folder icon iconTooltip key lazy partsel radiogroup refKey selected statusNodeType title tooltip type unselectable unselectableIgnore unselectableStatus\".split(\n\t\t\t\t\" \"\n\t\t\t),\n\t\tNODE_ATTR_MAP = {},\n\t\t// Mapping of lowercase -> real name (because HTML5 data-... attribute only supports lowercase)\n\t\tNODE_ATTR_LOWERCASE_MAP = {},\n\t\t// Attribute names that should NOT be added to node.data\n\t\tNONE_NODE_DATA_MAP = {\n\t\t\tactive: true,\n\t\t\tchildren: true,\n\t\t\tdata: true,\n\t\t\tfocus: true,\n\t\t};\n\n\tfor (i = 0; i < CLASS_ATTRS.length; i++) {\n\t\tCLASS_ATTR_MAP[CLASS_ATTRS[i]] = true;\n\t}\n\tfor (i = 0; i < NODE_ATTRS.length; i++) {\n\t\tattr = NODE_ATTRS[i];\n\t\tNODE_ATTR_MAP[attr] = true;\n\t\tif (attr !== attr.toLowerCase()) {\n\t\t\tNODE_ATTR_LOWERCASE_MAP[attr.toLowerCase()] = attr;\n\t\t}\n\t}\n\t// for(i=0; i t;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Deep-merge a list of objects (but replace array-type options).\n\t *\n\t * jQuery's $.extend(true, ...) method does a deep merge, that also merges Arrays.\n\t * This variant is used to merge extension defaults with user options, and should\n\t * merge objects, but override arrays (for example the `triggerStart: [...]` option\n\t * of ext-edit). Also `null` values are copied over and not skipped.\n\t *\n\t * See issue #876\n\t *\n\t * Example:\n\t * _simpleDeepMerge({}, o1, o2);\n\t */\n\tfunction _simpleDeepMerge() {\n\t\tvar options,\n\t\t\tname,\n\t\t\tsrc,\n\t\t\tcopy,\n\t\t\tclone,\n\t\t\ttarget = arguments[0] || {},\n\t\t\ti = 1,\n\t\t\tlength = arguments.length;\n\n\t\t// Handle case when target is a string or something (possible in deep copy)\n\t\tif (typeof target !== \"object\" && !_isFunction(target)) {\n\t\t\ttarget = {};\n\t\t}\n\t\tif (i === length) {\n\t\t\tthrow Error(\"need at least two args\");\n\t\t}\n\t\tfor (; i < length; i++) {\n\t\t\t// Only deal with non-null/undefined values\n\t\t\tif ((options = arguments[i]) != null) {\n\t\t\t\t// Extend the base object\n\t\t\t\tfor (name in options) {\n\t\t\t\t\tif (_hasProp(options, name)) {\n\t\t\t\t\t\tsrc = target[name];\n\t\t\t\t\t\tcopy = options[name];\n\t\t\t\t\t\t// Prevent never-ending loop\n\t\t\t\t\t\tif (target === copy) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Recurse if we're merging plain objects\n\t\t\t\t\t\t// (NOTE: unlike $.extend, we don't merge arrays, but replace them)\n\t\t\t\t\t\tif (copy && $.isPlainObject(copy)) {\n\t\t\t\t\t\t\tclone = src && $.isPlainObject(src) ? src : {};\n\t\t\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\t\t\ttarget[name] = _simpleDeepMerge(clone, copy);\n\t\t\t\t\t\t\t// Don't bring in undefined values\n\t\t\t\t\t\t} else if (copy !== undefined) {\n\t\t\t\t\t\t\ttarget[name] = copy;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Return the modified object\n\t\treturn target;\n\t}\n\n\t/** Return a wrapper that calls sub.methodName() and exposes\n\t * this : tree\n\t * this._local : tree.ext.EXTNAME\n\t * this._super : base.methodName.call()\n\t * this._superApply : base.methodName.apply()\n\t */\n\tfunction _makeVirtualFunction(methodName, tree, base, extension, extName) {\n\t\t// $.ui.fancytree.debug(\"_makeVirtualFunction\", methodName, tree, base, extension, extName);\n\t\t// if(rexTestSuper && !rexTestSuper.test(func)){\n\t\t// // extension.methodName() doesn't call _super(), so no wrapper required\n\t\t// return func;\n\t\t// }\n\t\t// Use an immediate function as closure\n\t\tvar proxy = (function () {\n\t\t\tvar prevFunc = tree[methodName], // org. tree method or prev. proxy\n\t\t\t\tbaseFunc = extension[methodName], //\n\t\t\t\t_local = tree.ext[extName],\n\t\t\t\t_super = function () {\n\t\t\t\t\treturn prevFunc.apply(tree, arguments);\n\t\t\t\t},\n\t\t\t\t_superApply = function (args) {\n\t\t\t\t\treturn prevFunc.apply(tree, args);\n\t\t\t\t};\n\n\t\t\t// Return the wrapper function\n\t\t\treturn function () {\n\t\t\t\tvar prevLocal = tree._local,\n\t\t\t\t\tprevSuper = tree._super,\n\t\t\t\t\tprevSuperApply = tree._superApply;\n\n\t\t\t\ttry {\n\t\t\t\t\ttree._local = _local;\n\t\t\t\t\ttree._super = _super;\n\t\t\t\t\ttree._superApply = _superApply;\n\t\t\t\t\treturn baseFunc.apply(tree, arguments);\n\t\t\t\t} finally {\n\t\t\t\t\ttree._local = prevLocal;\n\t\t\t\t\ttree._super = prevSuper;\n\t\t\t\t\ttree._superApply = prevSuperApply;\n\t\t\t\t}\n\t\t\t};\n\t\t})(); // end of Immediate Function\n\t\treturn proxy;\n\t}\n\n\t/**\n\t * Subclass `base` by creating proxy functions\n\t */\n\tfunction _subclassObject(tree, base, extension, extName) {\n\t\t// $.ui.fancytree.debug(\"_subclassObject\", tree, base, extension, extName);\n\t\tfor (var attrName in extension) {\n\t\t\tif (typeof extension[attrName] === \"function\") {\n\t\t\t\tif (typeof tree[attrName] === \"function\") {\n\t\t\t\t\t// override existing method\n\t\t\t\t\ttree[attrName] = _makeVirtualFunction(\n\t\t\t\t\t\tattrName,\n\t\t\t\t\t\ttree,\n\t\t\t\t\t\tbase,\n\t\t\t\t\t\textension,\n\t\t\t\t\t\textName\n\t\t\t\t\t);\n\t\t\t\t} else if (attrName.charAt(0) === \"_\") {\n\t\t\t\t\t// Create private methods in tree.ext.EXTENSION namespace\n\t\t\t\t\ttree.ext[extName][attrName] = _makeVirtualFunction(\n\t\t\t\t\t\tattrName,\n\t\t\t\t\t\ttree,\n\t\t\t\t\t\tbase,\n\t\t\t\t\t\textension,\n\t\t\t\t\t\textName\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t$.error(\n\t\t\t\t\t\t\"Could not override tree.\" +\n\t\t\t\t\t\t\tattrName +\n\t\t\t\t\t\t\t\". Use prefix '_' to create tree.\" +\n\t\t\t\t\t\t\textName +\n\t\t\t\t\t\t\t\"._\" +\n\t\t\t\t\t\t\tattrName\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Create member variables in tree.ext.EXTENSION namespace\n\t\t\t\tif (attrName !== \"options\") {\n\t\t\t\t\ttree.ext[extName][attrName] = extension[attrName];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction _getResolvedPromise(context, argArray) {\n\t\tif (context === undefined) {\n\t\t\treturn $.Deferred(function () {\n\t\t\t\tthis.resolve();\n\t\t\t}).promise();\n\t\t}\n\t\treturn $.Deferred(function () {\n\t\t\tthis.resolveWith(context, argArray);\n\t\t}).promise();\n\t}\n\n\tfunction _getRejectedPromise(context, argArray) {\n\t\tif (context === undefined) {\n\t\t\treturn $.Deferred(function () {\n\t\t\t\tthis.reject();\n\t\t\t}).promise();\n\t\t}\n\t\treturn $.Deferred(function () {\n\t\t\tthis.rejectWith(context, argArray);\n\t\t}).promise();\n\t}\n\n\tfunction _makeResolveFunc(deferred, context) {\n\t\treturn function () {\n\t\t\tdeferred.resolveWith(context);\n\t\t};\n\t}\n\n\tfunction _getElementDataAsDict($el) {\n\t\t// Evaluate 'data-NAME' attributes with special treatment for 'data-json'.\n\t\tvar d = $.extend({}, $el.data()),\n\t\t\tjson = d.json;\n\n\t\tdelete d.fancytree; // added to container by widget factory (old jQuery UI)\n\t\tdelete d.uiFancytree; // added to container by widget factory\n\n\t\tif (json) {\n\t\t\tdelete d.json;\n\t\t\t//
  • is already returned as object (http://api.jquery.com/data/#data-html5)\n\t\t\td = $.extend(d, json);\n\t\t}\n\t\treturn d;\n\t}\n\n\tfunction _escapeTooltip(s) {\n\t\treturn (\"\" + s).replace(REX_TOOLTIP, function (s) {\n\t\t\treturn ENTITY_MAP[s];\n\t\t});\n\t}\n\n\t// TODO: use currying\n\tfunction _makeNodeTitleMatcher(s) {\n\t\ts = s.toLowerCase();\n\t\treturn function (node) {\n\t\t\treturn node.title.toLowerCase().indexOf(s) >= 0;\n\t\t};\n\t}\n\n\tfunction _makeNodeTitleStartMatcher(s) {\n\t\tvar reMatch = new RegExp(\"^\" + s, \"i\");\n\t\treturn function (node) {\n\t\t\treturn reMatch.test(node.title);\n\t\t};\n\t}\n\n\t/******************************************************************************\n\t * FancytreeNode\n\t */\n\n\t/**\n\t * Creates a new FancytreeNode\n\t *\n\t * @class FancytreeNode\n\t * @classdesc A FancytreeNode represents the hierarchical data model and operations.\n\t *\n\t * @param {FancytreeNode} parent\n\t * @param {NodeData} obj\n\t *\n\t * @property {Fancytree} tree The tree instance\n\t * @property {FancytreeNode} parent The parent node\n\t * @property {string} key Node id (must be unique inside the tree)\n\t * @property {string} title Display name (may contain HTML)\n\t * @property {object} data Contains all extra data that was passed on node creation\n\t * @property {FancytreeNode[] | null | undefined} children Array of child nodes.
    \n\t * For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array\n\t * to define a node that has no children.\n\t * @property {boolean} expanded Use isExpanded(), setExpanded() to access this property.\n\t * @property {string} extraClasses Additional CSS classes, added to the node's ``.
    \n\t * Note: use `node.add/remove/toggleClass()` to modify.\n\t * @property {boolean} folder Folder nodes have different default icons and click behavior.
    \n\t * Note: Also non-folders may have children.\n\t * @property {string} statusNodeType null for standard nodes. Otherwise type of special system node: 'error', 'loading', 'nodata', or 'paging'.\n\t * @property {boolean} lazy True if this node is loaded on demand, i.e. on first expansion.\n\t * @property {boolean} selected Use isSelected(), setSelected() to access this property.\n\t * @property {string} tooltip Alternative description used as hover popup\n\t * @property {string} iconTooltip Description used as hover popup for icon. @since 2.27\n\t * @property {string} type Node type, used with tree.types map. @since 2.27\n\t */\n\tfunction FancytreeNode(parent, obj) {\n\t\tvar i, l, name, cl;\n\n\t\tthis.parent = parent;\n\t\tthis.tree = parent.tree;\n\t\tthis.ul = null;\n\t\tthis.li = null; //
  • tag\n\t\tthis.statusNodeType = null; // if this is a temp. node to display the status of its parent\n\t\tthis._isLoading = false; // if this node itself is loading\n\t\tthis._error = null; // {message: '...'} if a load error occurred\n\t\tthis.data = {};\n\n\t\t// TODO: merge this code with node.toDict()\n\t\t// copy attributes from obj object\n\t\tfor (i = 0, l = NODE_ATTRS.length; i < l; i++) {\n\t\t\tname = NODE_ATTRS[i];\n\t\t\tthis[name] = obj[name];\n\t\t}\n\t\t// unselectableIgnore and unselectableStatus imply unselectable\n\t\tif (\n\t\t\tthis.unselectableIgnore != null ||\n\t\t\tthis.unselectableStatus != null\n\t\t) {\n\t\t\tthis.unselectable = true;\n\t\t}\n\t\tif (obj.hideCheckbox) {\n\t\t\t$.error(\n\t\t\t\t\"'hideCheckbox' node option was removed in v2.23.0: use 'checkbox: false'\"\n\t\t\t);\n\t\t}\n\t\t// node.data += obj.data\n\t\tif (obj.data) {\n\t\t\t$.extend(this.data, obj.data);\n\t\t}\n\t\t// Copy all other attributes to this.data.NAME\n\t\tfor (name in obj) {\n\t\t\tif (\n\t\t\t\t!NODE_ATTR_MAP[name] &&\n\t\t\t\t(this.tree.options.copyFunctionsToData ||\n\t\t\t\t\t!_isFunction(obj[name])) &&\n\t\t\t\t!NONE_NODE_DATA_MAP[name]\n\t\t\t) {\n\t\t\t\t// node.data.NAME = obj.NAME\n\t\t\t\tthis.data[name] = obj[name];\n\t\t\t}\n\t\t}\n\n\t\t// Fix missing key\n\t\tif (this.key == null) {\n\t\t\t// test for null OR undefined\n\t\t\tif (this.tree.options.defaultKey) {\n\t\t\t\tthis.key = \"\" + this.tree.options.defaultKey(this);\n\t\t\t\t_assert(this.key, \"defaultKey() must return a unique key\");\n\t\t\t} else {\n\t\t\t\tthis.key = \"_\" + FT._nextNodeKey++;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.key = \"\" + this.key; // Convert to string (#217)\n\t\t}\n\n\t\t// Fix tree.activeNode\n\t\t// TODO: not elegant: we use obj.active as marker to set tree.activeNode\n\t\t// when loading from a dictionary.\n\t\tif (obj.active) {\n\t\t\t_assert(\n\t\t\t\tthis.tree.activeNode === null,\n\t\t\t\t\"only one active node allowed\"\n\t\t\t);\n\t\t\tthis.tree.activeNode = this;\n\t\t}\n\t\tif (obj.selected) {\n\t\t\t// #186\n\t\t\tthis.tree.lastSelectedNode = this;\n\t\t}\n\t\t// TODO: handle obj.focus = true\n\n\t\t// Create child nodes\n\t\tcl = obj.children;\n\t\tif (cl) {\n\t\t\tif (cl.length) {\n\t\t\t\tthis._setChildren(cl);\n\t\t\t} else {\n\t\t\t\t// if an empty array was passed for a lazy node, keep it, in order to mark it 'loaded'\n\t\t\t\tthis.children = this.lazy ? [] : null;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.children = null;\n\t\t}\n\t\t// Add to key/ref map (except for root node)\n\t\t//\tif( parent ) {\n\t\tthis.tree._callHook(\"treeRegisterNode\", this.tree, true, this);\n\t\t//\t}\n\t}\n\n\tFancytreeNode.prototype = /** @lends FancytreeNode# */ {\n\t\t/* Return the direct child FancytreeNode with a given key, index. */\n\t\t_findDirectChild: function (ptr) {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tcl = this.children;\n\n\t\t\tif (cl) {\n\t\t\t\tif (typeof ptr === \"string\") {\n\t\t\t\t\tfor (i = 0, l = cl.length; i < l; i++) {\n\t\t\t\t\t\tif (cl[i].key === ptr) {\n\t\t\t\t\t\t\treturn cl[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof ptr === \"number\") {\n\t\t\t\t\treturn this.children[ptr];\n\t\t\t\t} else if (ptr.parent === this) {\n\t\t\t\t\treturn ptr;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\t// TODO: activate()\n\t\t// TODO: activateSilently()\n\t\t/* Internal helper called in recursive addChildren sequence.*/\n\t\t_setChildren: function (children) {\n\t\t\t_assert(\n\t\t\t\tchildren && (!this.children || this.children.length === 0),\n\t\t\t\t\"only init supported\"\n\t\t\t);\n\t\t\tthis.children = [];\n\t\t\tfor (var i = 0, l = children.length; i < l; i++) {\n\t\t\t\tthis.children.push(new FancytreeNode(this, children[i]));\n\t\t\t}\n\t\t\tthis.tree._callHook(\n\t\t\t\t\"treeStructureChanged\",\n\t\t\t\tthis.tree,\n\t\t\t\t\"setChildren\"\n\t\t\t);\n\t\t},\n\t\t/**\n\t\t * Append (or insert) a list of child nodes.\n\t\t *\n\t\t * @param {NodeData[]} children array of child node definitions (also single child accepted)\n\t\t * @param {FancytreeNode | string | Integer} [insertBefore] child node (or key or index of such).\n\t\t * If omitted, the new children are appended.\n\t\t * @returns {FancytreeNode} first child added\n\t\t *\n\t\t * @see FancytreeNode#applyPatch\n\t\t */\n\t\taddChildren: function (children, insertBefore) {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tpos,\n\t\t\t\torigFirstChild = this.getFirstChild(),\n\t\t\t\torigLastChild = this.getLastChild(),\n\t\t\t\tfirstNode = null,\n\t\t\t\tnodeList = [];\n\n\t\t\tif ($.isPlainObject(children)) {\n\t\t\t\tchildren = [children];\n\t\t\t}\n\t\t\tif (!this.children) {\n\t\t\t\tthis.children = [];\n\t\t\t}\n\t\t\tfor (i = 0, l = children.length; i < l; i++) {\n\t\t\t\tnodeList.push(new FancytreeNode(this, children[i]));\n\t\t\t}\n\t\t\tfirstNode = nodeList[0];\n\t\t\tif (insertBefore == null) {\n\t\t\t\tthis.children = this.children.concat(nodeList);\n\t\t\t} else {\n\t\t\t\t// Returns null if insertBefore is not a direct child:\n\t\t\t\tinsertBefore = this._findDirectChild(insertBefore);\n\t\t\t\tpos = $.inArray(insertBefore, this.children);\n\t\t\t\t_assert(pos >= 0, \"insertBefore must be an existing child\");\n\t\t\t\t// insert nodeList after children[pos]\n\t\t\t\tthis.children.splice.apply(\n\t\t\t\t\tthis.children,\n\t\t\t\t\t[pos, 0].concat(nodeList)\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (origFirstChild && !insertBefore) {\n\t\t\t\t// #708: Fast path -- don't render every child of root, just the new ones!\n\t\t\t\t// #723, #729: but only if it's appended to an existing child list\n\t\t\t\tfor (i = 0, l = nodeList.length; i < l; i++) {\n\t\t\t\t\tnodeList[i].render(); // New nodes were never rendered before\n\t\t\t\t}\n\t\t\t\t// Adjust classes where status may have changed\n\t\t\t\t// Has a first child\n\t\t\t\tif (origFirstChild !== this.getFirstChild()) {\n\t\t\t\t\t// Different first child -- recompute classes\n\t\t\t\t\torigFirstChild.renderStatus();\n\t\t\t\t}\n\t\t\t\tif (origLastChild !== this.getLastChild()) {\n\t\t\t\t\t// Different last child -- recompute classes\n\t\t\t\t\torigLastChild.renderStatus();\n\t\t\t\t}\n\t\t\t} else if (!this.parent || this.parent.ul || this.tr) {\n\t\t\t\t// render if the parent was rendered (or this is a root node)\n\t\t\t\tthis.render();\n\t\t\t}\n\t\t\tif (this.tree.options.selectMode === 3) {\n\t\t\t\tthis.fixSelection3FromEndNodes();\n\t\t\t}\n\t\t\tthis.triggerModifyChild(\n\t\t\t\t\"add\",\n\t\t\t\tnodeList.length === 1 ? nodeList[0] : null\n\t\t\t);\n\t\t\treturn firstNode;\n\t\t},\n\t\t/**\n\t\t * Add class to node's span tag and to .extraClasses.\n\t\t *\n\t\t * @param {string} className class name\n\t\t *\n\t\t * @since 2.17\n\t\t */\n\t\taddClass: function (className) {\n\t\t\treturn this.toggleClass(className, true);\n\t\t},\n\t\t/**\n\t\t * Append or prepend a node, or append a child node.\n\t\t *\n\t\t * This a convenience function that calls addChildren()\n\t\t *\n\t\t * @param {NodeData} node node definition\n\t\t * @param {string} [mode=child] 'before', 'after', 'firstChild', or 'child' ('over' is a synonym for 'child')\n\t\t * @returns {FancytreeNode} new node\n\t\t */\n\t\taddNode: function (node, mode) {\n\t\t\tif (mode === undefined || mode === \"over\") {\n\t\t\t\tmode = \"child\";\n\t\t\t}\n\t\t\tswitch (mode) {\n\t\t\t\tcase \"after\":\n\t\t\t\t\treturn this.getParent().addChildren(\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\tthis.getNextSibling()\n\t\t\t\t\t);\n\t\t\t\tcase \"before\":\n\t\t\t\t\treturn this.getParent().addChildren(node, this);\n\t\t\t\tcase \"firstChild\":\n\t\t\t\t\t// Insert before the first child if any\n\t\t\t\t\tvar insertBefore = this.children ? this.children[0] : null;\n\t\t\t\t\treturn this.addChildren(node, insertBefore);\n\t\t\t\tcase \"child\":\n\t\t\t\tcase \"over\":\n\t\t\t\t\treturn this.addChildren(node);\n\t\t\t}\n\t\t\t_assert(false, \"Invalid mode: \" + mode);\n\t\t},\n\t\t/**Add child status nodes that indicate 'More...', etc.\n\t\t *\n\t\t * This also maintains the node's `partload` property.\n\t\t * @param {boolean|object} node optional node definition. Pass `false` to remove all paging nodes.\n\t\t * @param {string} [mode='child'] 'child'|firstChild'\n\t\t * @since 2.15\n\t\t */\n\t\taddPagingNode: function (node, mode) {\n\t\t\tvar i, n;\n\n\t\t\tmode = mode || \"child\";\n\t\t\tif (node === false) {\n\t\t\t\tfor (i = this.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tn = this.children[i];\n\t\t\t\t\tif (n.statusNodeType === \"paging\") {\n\t\t\t\t\t\tthis.removeChild(n);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.partload = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnode = $.extend(\n\t\t\t\t{\n\t\t\t\t\ttitle: this.tree.options.strings.moreData,\n\t\t\t\t\tstatusNodeType: \"paging\",\n\t\t\t\t\ticon: false,\n\t\t\t\t},\n\t\t\t\tnode\n\t\t\t);\n\t\t\tthis.partload = true;\n\t\t\treturn this.addNode(node, mode);\n\t\t},\n\t\t/**\n\t\t * Append new node after this.\n\t\t *\n\t\t * This a convenience function that calls addNode(node, 'after')\n\t\t *\n\t\t * @param {NodeData} node node definition\n\t\t * @returns {FancytreeNode} new node\n\t\t */\n\t\tappendSibling: function (node) {\n\t\t\treturn this.addNode(node, \"after\");\n\t\t},\n\t\t/**\n\t\t * (experimental) Apply a modification (or navigation) operation.\n\t\t *\n\t\t * @param {string} cmd\n\t\t * @param {object} [opts]\n\t\t * @see Fancytree#applyCommand\n\t\t * @since 2.32\n\t\t */\n\t\tapplyCommand: function (cmd, opts) {\n\t\t\treturn this.tree.applyCommand(cmd, this, opts);\n\t\t},\n\t\t/**\n\t\t * Modify existing child nodes.\n\t\t *\n\t\t * @param {NodePatch} patch\n\t\t * @returns {$.Promise}\n\t\t * @see FancytreeNode#addChildren\n\t\t */\n\t\tapplyPatch: function (patch) {\n\t\t\t// patch [key, null] means 'remove'\n\t\t\tif (patch === null) {\n\t\t\t\tthis.remove();\n\t\t\t\treturn _getResolvedPromise(this);\n\t\t\t}\n\t\t\t// TODO: make sure that root node is not collapsed or modified\n\t\t\t// copy (most) attributes to node.ATTR or node.data.ATTR\n\t\t\tvar name,\n\t\t\t\tpromise,\n\t\t\t\tv,\n\t\t\t\tIGNORE_MAP = { children: true, expanded: true, parent: true }; // TODO: should be global\n\n\t\t\tfor (name in patch) {\n\t\t\t\tif (_hasProp(patch, name)) {\n\t\t\t\t\tv = patch[name];\n\t\t\t\t\tif (!IGNORE_MAP[name] && !_isFunction(v)) {\n\t\t\t\t\t\tif (NODE_ATTR_MAP[name]) {\n\t\t\t\t\t\t\tthis[name] = v;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.data[name] = v;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Remove and/or create children\n\t\t\tif (_hasProp(patch, \"children\")) {\n\t\t\t\tthis.removeChildren();\n\t\t\t\tif (patch.children) {\n\t\t\t\t\t// only if not null and not empty list\n\t\t\t\t\t// TODO: addChildren instead?\n\t\t\t\t\tthis._setChildren(patch.children);\n\t\t\t\t}\n\t\t\t\t// TODO: how can we APPEND or INSERT child nodes?\n\t\t\t}\n\t\t\tif (this.isVisible()) {\n\t\t\t\tthis.renderTitle();\n\t\t\t\tthis.renderStatus();\n\t\t\t}\n\t\t\t// Expand collapse (final step, since this may be async)\n\t\t\tif (_hasProp(patch, \"expanded\")) {\n\t\t\t\tpromise = this.setExpanded(patch.expanded);\n\t\t\t} else {\n\t\t\t\tpromise = _getResolvedPromise(this);\n\t\t\t}\n\t\t\treturn promise;\n\t\t},\n\t\t/** Collapse all sibling nodes.\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tcollapseSiblings: function () {\n\t\t\treturn this.tree._callHook(\"nodeCollapseSiblings\", this);\n\t\t},\n\t\t/** Copy this node as sibling or child of `node`.\n\t\t *\n\t\t * @param {FancytreeNode} node source node\n\t\t * @param {string} [mode=child] 'before' | 'after' | 'child'\n\t\t * @param {Function} [map] callback function(NodeData, FancytreeNode) that could modify the new node\n\t\t * @returns {FancytreeNode} new\n\t\t */\n\t\tcopyTo: function (node, mode, map) {\n\t\t\treturn node.addNode(this.toDict(true, map), mode);\n\t\t},\n\t\t/** Count direct and indirect children.\n\t\t *\n\t\t * @param {boolean} [deep=true] pass 'false' to only count direct children\n\t\t * @returns {int} number of child nodes\n\t\t */\n\t\tcountChildren: function (deep) {\n\t\t\tvar cl = this.children,\n\t\t\t\ti,\n\t\t\t\tl,\n\t\t\t\tn;\n\t\t\tif (!cl) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tn = cl.length;\n\t\t\tif (deep !== false) {\n\t\t\t\tfor (i = 0, l = n; i < l; i++) {\n\t\t\t\t\tn += cl[i].countChildren();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn n;\n\t\t},\n\t\t// TODO: deactivate()\n\t\t/** Write to browser console if debugLevel >= 4 (prepending node info)\n\t\t *\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\tdebug: function (msg) {\n\t\t\tif (this.tree.options.debugLevel >= 4) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"log\", arguments);\n\t\t\t}\n\t\t},\n\t\t/** Deprecated.\n\t\t * @deprecated since 2014-02-16. Use resetLazy() instead.\n\t\t */\n\t\tdiscard: function () {\n\t\t\tthis.warn(\n\t\t\t\t\"FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead.\"\n\t\t\t);\n\t\t\treturn this.resetLazy();\n\t\t},\n\t\t/** Remove DOM elements for all descendents. May be called on .collapse event\n\t\t * to keep the DOM small.\n\t\t * @param {boolean} [includeSelf=false]\n\t\t */\n\t\tdiscardMarkup: function (includeSelf) {\n\t\t\tvar fn = includeSelf ? \"nodeRemoveMarkup\" : \"nodeRemoveChildMarkup\";\n\t\t\tthis.tree._callHook(fn, this);\n\t\t},\n\t\t/** Write error to browser console if debugLevel >= 1 (prepending tree info)\n\t\t *\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\terror: function (msg) {\n\t\t\tif (this.tree.options.debugLevel >= 1) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"error\", arguments);\n\t\t\t}\n\t\t},\n\t\t/**Find all nodes that match condition (excluding self).\n\t\t *\n\t\t * @param {string | function(node)} match title string to search for, or a\n\t\t * callback function that returns `true` if a node is matched.\n\t\t * @returns {FancytreeNode[]} array of nodes (may be empty)\n\t\t */\n\t\tfindAll: function (match) {\n\t\t\tmatch = _isFunction(match) ? match : _makeNodeTitleMatcher(match);\n\t\t\tvar res = [];\n\t\t\tthis.visit(function (n) {\n\t\t\t\tif (match(n)) {\n\t\t\t\t\tres.push(n);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn res;\n\t\t},\n\t\t/**Find first node that matches condition (excluding self).\n\t\t *\n\t\t * @param {string | function(node)} match title string to search for, or a\n\t\t * callback function that returns `true` if a node is matched.\n\t\t * @returns {FancytreeNode} matching node or null\n\t\t * @see FancytreeNode#findAll\n\t\t */\n\t\tfindFirst: function (match) {\n\t\t\tmatch = _isFunction(match) ? match : _makeNodeTitleMatcher(match);\n\t\t\tvar res = null;\n\t\t\tthis.visit(function (n) {\n\t\t\t\tif (match(n)) {\n\t\t\t\t\tres = n;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn res;\n\t\t},\n\t\t/** Find a node relative to self.\n\t\t *\n\t\t * @param {number|string} where The keyCode that would normally trigger this move,\n\t\t *\t\tor a keyword ('down', 'first', 'last', 'left', 'parent', 'right', 'up').\n\t\t * @returns {FancytreeNode}\n\t\t * @since v2.31\n\t\t */\n\t\tfindRelatedNode: function (where, includeHidden) {\n\t\t\treturn this.tree.findRelatedNode(this, where, includeHidden);\n\t\t},\n\t\t/* Apply selection state (internal use only) */\n\t\t_changeSelectStatusAttrs: function (state) {\n\t\t\tvar changed = false,\n\t\t\t\topts = this.tree.options,\n\t\t\t\tunselectable = FT.evalOption(\n\t\t\t\t\t\"unselectable\",\n\t\t\t\t\tthis,\n\t\t\t\t\tthis,\n\t\t\t\t\topts,\n\t\t\t\t\tfalse\n\t\t\t\t),\n\t\t\t\tunselectableStatus = FT.evalOption(\n\t\t\t\t\t\"unselectableStatus\",\n\t\t\t\t\tthis,\n\t\t\t\t\tthis,\n\t\t\t\t\topts,\n\t\t\t\t\tundefined\n\t\t\t\t);\n\n\t\t\tif (unselectable && unselectableStatus != null) {\n\t\t\t\tstate = unselectableStatus;\n\t\t\t}\n\t\t\tswitch (state) {\n\t\t\t\tcase false:\n\t\t\t\t\tchanged = this.selected || this.partsel;\n\t\t\t\t\tthis.selected = false;\n\t\t\t\t\tthis.partsel = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase true:\n\t\t\t\t\tchanged = !this.selected || !this.partsel;\n\t\t\t\t\tthis.selected = true;\n\t\t\t\t\tthis.partsel = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase undefined:\n\t\t\t\t\tchanged = this.selected || !this.partsel;\n\t\t\t\t\tthis.selected = false;\n\t\t\t\t\tthis.partsel = true;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t_assert(false, \"invalid state: \" + state);\n\t\t\t}\n\t\t\t// this.debug(\"fixSelection3AfterLoad() _changeSelectStatusAttrs()\", state, changed);\n\t\t\tif (changed) {\n\t\t\t\tthis.renderStatus();\n\t\t\t}\n\t\t\treturn changed;\n\t\t},\n\t\t/**\n\t\t * Fix selection status, after this node was (de)selected in multi-hier mode.\n\t\t * This includes (de)selecting all children.\n\t\t */\n\t\tfixSelection3AfterClick: function (callOpts) {\n\t\t\tvar flag = this.isSelected();\n\n\t\t\t// this.debug(\"fixSelection3AfterClick()\");\n\n\t\t\tthis.visit(function (node) {\n\t\t\t\tnode._changeSelectStatusAttrs(flag);\n\t\t\t\tif (node.radiogroup) {\n\t\t\t\t\t// #931: don't (de)select this branch\n\t\t\t\t\treturn \"skip\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.fixSelection3FromEndNodes(callOpts);\n\t\t},\n\t\t/**\n\t\t * Fix selection status for multi-hier mode.\n\t\t * Only end-nodes are considered to update the descendants branch and parents.\n\t\t * Should be called after this node has loaded new children or after\n\t\t * children have been modified using the API.\n\t\t */\n\t\tfixSelection3FromEndNodes: function (callOpts) {\n\t\t\tvar opts = this.tree.options;\n\n\t\t\t// this.debug(\"fixSelection3FromEndNodes()\");\n\t\t\t_assert(opts.selectMode === 3, \"expected selectMode 3\");\n\n\t\t\t// Visit all end nodes and adjust their parent's `selected` and `partsel`\n\t\t\t// attributes. Return selection state true, false, or undefined.\n\t\t\tfunction _walk(node) {\n\t\t\t\tvar i,\n\t\t\t\t\tl,\n\t\t\t\t\tchild,\n\t\t\t\t\ts,\n\t\t\t\t\tstate,\n\t\t\t\t\tallSelected,\n\t\t\t\t\tsomeSelected,\n\t\t\t\t\tunselIgnore,\n\t\t\t\t\tunselState,\n\t\t\t\t\tchildren = node.children;\n\n\t\t\t\tif (children && children.length) {\n\t\t\t\t\t// check all children recursively\n\t\t\t\t\tallSelected = true;\n\t\t\t\t\tsomeSelected = false;\n\n\t\t\t\t\tfor (i = 0, l = children.length; i < l; i++) {\n\t\t\t\t\t\tchild = children[i];\n\t\t\t\t\t\t// the selection state of a node is not relevant; we need the end-nodes\n\t\t\t\t\t\ts = _walk(child);\n\t\t\t\t\t\t// if( !child.unselectableIgnore ) {\n\t\t\t\t\t\tunselIgnore = FT.evalOption(\n\t\t\t\t\t\t\t\"unselectableIgnore\",\n\t\t\t\t\t\t\tchild,\n\t\t\t\t\t\t\tchild,\n\t\t\t\t\t\t\topts,\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (!unselIgnore) {\n\t\t\t\t\t\t\tif (s !== false) {\n\t\t\t\t\t\t\t\tsomeSelected = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (s !== true) {\n\t\t\t\t\t\t\t\tallSelected = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// eslint-disable-next-line no-nested-ternary\n\t\t\t\t\tstate = allSelected\n\t\t\t\t\t\t? true\n\t\t\t\t\t\t: someSelected\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: false;\n\t\t\t\t} else {\n\t\t\t\t\t// This is an end-node: simply report the status\n\t\t\t\t\tunselState = FT.evalOption(\n\t\t\t\t\t\t\"unselectableStatus\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\topts,\n\t\t\t\t\t\tundefined\n\t\t\t\t\t);\n\t\t\t\t\tstate = unselState == null ? !!node.selected : !!unselState;\n\t\t\t\t}\n\t\t\t\t// #939: Keep a `partsel` flag that was explicitly set on a lazy node\n\t\t\t\tif (\n\t\t\t\t\tnode.partsel &&\n\t\t\t\t\t!node.selected &&\n\t\t\t\t\tnode.lazy &&\n\t\t\t\t\tnode.children == null\n\t\t\t\t) {\n\t\t\t\t\tstate = undefined;\n\t\t\t\t}\n\t\t\t\tnode._changeSelectStatusAttrs(state);\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\t_walk(this);\n\n\t\t\t// Update parent's state\n\t\t\tthis.visitParents(function (node) {\n\t\t\t\tvar i,\n\t\t\t\t\tl,\n\t\t\t\t\tchild,\n\t\t\t\t\tstate,\n\t\t\t\t\tunselIgnore,\n\t\t\t\t\tunselState,\n\t\t\t\t\tchildren = node.children,\n\t\t\t\t\tallSelected = true,\n\t\t\t\t\tsomeSelected = false;\n\n\t\t\t\tfor (i = 0, l = children.length; i < l; i++) {\n\t\t\t\t\tchild = children[i];\n\t\t\t\t\tunselIgnore = FT.evalOption(\n\t\t\t\t\t\t\"unselectableIgnore\",\n\t\t\t\t\t\tchild,\n\t\t\t\t\t\tchild,\n\t\t\t\t\t\topts,\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t\tif (!unselIgnore) {\n\t\t\t\t\t\tunselState = FT.evalOption(\n\t\t\t\t\t\t\t\"unselectableStatus\",\n\t\t\t\t\t\t\tchild,\n\t\t\t\t\t\t\tchild,\n\t\t\t\t\t\t\topts,\n\t\t\t\t\t\t\tundefined\n\t\t\t\t\t\t);\n\t\t\t\t\t\tstate =\n\t\t\t\t\t\t\tunselState == null\n\t\t\t\t\t\t\t\t? !!child.selected\n\t\t\t\t\t\t\t\t: !!unselState;\n\t\t\t\t\t\t// When fixing the parents, we trust the sibling status (i.e.\n\t\t\t\t\t\t// we don't recurse)\n\t\t\t\t\t\tif (state || child.partsel) {\n\t\t\t\t\t\t\tsomeSelected = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!state) {\n\t\t\t\t\t\t\tallSelected = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line no-nested-ternary\n\t\t\t\tstate = allSelected ? true : someSelected ? undefined : false;\n\t\t\t\tnode._changeSelectStatusAttrs(state);\n\t\t\t});\n\t\t},\n\t\t// TODO: focus()\n\t\t/**\n\t\t * Update node data. If dict contains 'children', then also replace\n\t\t * the hole sub tree.\n\t\t * @param {NodeData} dict\n\t\t *\n\t\t * @see FancytreeNode#addChildren\n\t\t * @see FancytreeNode#applyPatch\n\t\t */\n\t\tfromDict: function (dict) {\n\t\t\t// copy all other attributes to this.data.xxx\n\t\t\tfor (var name in dict) {\n\t\t\t\tif (NODE_ATTR_MAP[name]) {\n\t\t\t\t\t// node.NAME = dict.NAME\n\t\t\t\t\tthis[name] = dict[name];\n\t\t\t\t} else if (name === \"data\") {\n\t\t\t\t\t// node.data += dict.data\n\t\t\t\t\t$.extend(this.data, dict.data);\n\t\t\t\t} else if (\n\t\t\t\t\t!_isFunction(dict[name]) &&\n\t\t\t\t\t!NONE_NODE_DATA_MAP[name]\n\t\t\t\t) {\n\t\t\t\t\t// node.data.NAME = dict.NAME\n\t\t\t\t\tthis.data[name] = dict[name];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (dict.children) {\n\t\t\t\t// recursively set children and render\n\t\t\t\tthis.removeChildren();\n\t\t\t\tthis.addChildren(dict.children);\n\t\t\t}\n\t\t\tthis.renderTitle();\n\t\t\t/*\n\t\t\tvar children = dict.children;\n\t\t\tif(children === undefined){\n\t\t\t\tthis.data = $.extend(this.data, dict);\n\t\t\t\tthis.render();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdict = $.extend({}, dict);\n\t\t\tdict.children = undefined;\n\t\t\tthis.data = $.extend(this.data, dict);\n\t\t\tthis.removeChildren();\n\t\t\tthis.addChild(children);\n\t\t\t*/\n\t\t},\n\t\t/** Return the list of child nodes (undefined for unexpanded lazy nodes).\n\t\t * @returns {FancytreeNode[] | undefined}\n\t\t */\n\t\tgetChildren: function () {\n\t\t\tif (this.hasChildren() === undefined) {\n\t\t\t\t// TODO: only required for lazy nodes?\n\t\t\t\treturn undefined; // Lazy node: unloaded, currently loading, or load error\n\t\t\t}\n\t\t\treturn this.children;\n\t\t},\n\t\t/** Return the first child node or null.\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetFirstChild: function () {\n\t\t\treturn this.children ? this.children[0] : null;\n\t\t},\n\t\t/** Return the 0-based child index.\n\t\t * @returns {int}\n\t\t */\n\t\tgetIndex: function () {\n\t\t\t// return this.parent.children.indexOf(this);\n\t\t\treturn $.inArray(this, this.parent.children); // indexOf doesn't work in IE7\n\t\t},\n\t\t/** Return the hierarchical child index (1-based, e.g. '3.2.4').\n\t\t * @param {string} [separator=\".\"]\n\t\t * @param {int} [digits=1]\n\t\t * @returns {string}\n\t\t */\n\t\tgetIndexHier: function (separator, digits) {\n\t\t\tseparator = separator || \".\";\n\t\t\tvar s,\n\t\t\t\tres = [];\n\t\t\t$.each(this.getParentList(false, true), function (i, o) {\n\t\t\t\ts = \"\" + (o.getIndex() + 1);\n\t\t\t\tif (digits) {\n\t\t\t\t\t// prepend leading zeroes\n\t\t\t\t\ts = (\"0000000\" + s).substr(-digits);\n\t\t\t\t}\n\t\t\t\tres.push(s);\n\t\t\t});\n\t\t\treturn res.join(separator);\n\t\t},\n\t\t/** Return the parent keys separated by options.keyPathSeparator, e.g. \"/id_1/id_17/id_32\".\n\t\t *\n\t\t * (Unlike `node.getPath()`, this method prepends a \"/\" and inverts the first argument.)\n\t\t *\n\t\t * @see FancytreeNode#getPath\n\t\t * @param {boolean} [excludeSelf=false]\n\t\t * @returns {string}\n\t\t */\n\t\tgetKeyPath: function (excludeSelf) {\n\t\t\tvar sep = this.tree.options.keyPathSeparator;\n\n\t\t\treturn sep + this.getPath(!excludeSelf, \"key\", sep);\n\t\t},\n\t\t/** Return the last child of this node or null.\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetLastChild: function () {\n\t\t\treturn this.children\n\t\t\t\t? this.children[this.children.length - 1]\n\t\t\t\t: null;\n\t\t},\n\t\t/** Return node depth. 0: System root node, 1: visible top-level node, 2: first sub-level, ... .\n\t\t * @returns {int}\n\t\t */\n\t\tgetLevel: function () {\n\t\t\tvar level = 0,\n\t\t\t\tdtn = this.parent;\n\t\t\twhile (dtn) {\n\t\t\t\tlevel++;\n\t\t\t\tdtn = dtn.parent;\n\t\t\t}\n\t\t\treturn level;\n\t\t},\n\t\t/** Return the successor node (under the same parent) or null.\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetNextSibling: function () {\n\t\t\t// TODO: use indexOf, if available: (not in IE6)\n\t\t\tif (this.parent) {\n\t\t\t\tvar i,\n\t\t\t\t\tl,\n\t\t\t\t\tac = this.parent.children;\n\n\t\t\t\tfor (i = 0, l = ac.length - 1; i < l; i++) {\n\t\t\t\t\t// up to length-2, so next(last) = null\n\t\t\t\t\tif (ac[i] === this) {\n\t\t\t\t\t\treturn ac[i + 1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\t/** Return the parent node (null for the system root node).\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetParent: function () {\n\t\t\t// TODO: return null for top-level nodes?\n\t\t\treturn this.parent;\n\t\t},\n\t\t/** Return an array of all parent nodes (top-down).\n\t\t * @param {boolean} [includeRoot=false] Include the invisible system root node.\n\t\t * @param {boolean} [includeSelf=false] Include the node itself.\n\t\t * @returns {FancytreeNode[]}\n\t\t */\n\t\tgetParentList: function (includeRoot, includeSelf) {\n\t\t\tvar l = [],\n\t\t\t\tdtn = includeSelf ? this : this.parent;\n\t\t\twhile (dtn) {\n\t\t\t\tif (includeRoot || dtn.parent) {\n\t\t\t\t\tl.unshift(dtn);\n\t\t\t\t}\n\t\t\t\tdtn = dtn.parent;\n\t\t\t}\n\t\t\treturn l;\n\t\t},\n\t\t/** Return a string representing the hierachical node path, e.g. \"a/b/c\".\n\t\t * @param {boolean} [includeSelf=true]\n\t\t * @param {string | function} [part=\"title\"] node property name or callback\n\t\t * @param {string} [separator=\"/\"]\n\t\t * @returns {string}\n\t\t * @since v2.31\n\t\t */\n\t\tgetPath: function (includeSelf, part, separator) {\n\t\t\tincludeSelf = includeSelf !== false;\n\t\t\tpart = part || \"title\";\n\t\t\tseparator = separator || \"/\";\n\n\t\t\tvar val,\n\t\t\t\tpath = [],\n\t\t\t\tisFunc = _isFunction(part);\n\n\t\t\tthis.visitParents(function (n) {\n\t\t\t\tif (n.parent) {\n\t\t\t\t\tval = isFunc ? part(n) : n[part];\n\t\t\t\t\tpath.unshift(val);\n\t\t\t\t}\n\t\t\t}, includeSelf);\n\t\t\treturn path.join(separator);\n\t\t},\n\t\t/** Return the predecessor node (under the same parent) or null.\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetPrevSibling: function () {\n\t\t\tif (this.parent) {\n\t\t\t\tvar i,\n\t\t\t\t\tl,\n\t\t\t\t\tac = this.parent.children;\n\n\t\t\t\tfor (i = 1, l = ac.length; i < l; i++) {\n\t\t\t\t\t// start with 1, so prev(first) = null\n\t\t\t\t\tif (ac[i] === this) {\n\t\t\t\t\t\treturn ac[i - 1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\t/**\n\t\t * Return an array of selected descendant nodes.\n\t\t * @param {boolean} [stopOnParents=false] only return the topmost selected\n\t\t * node (useful with selectMode 3)\n\t\t * @returns {FancytreeNode[]}\n\t\t */\n\t\tgetSelectedNodes: function (stopOnParents) {\n\t\t\tvar nodeList = [];\n\t\t\tthis.visit(function (node) {\n\t\t\t\tif (node.selected) {\n\t\t\t\t\tnodeList.push(node);\n\t\t\t\t\tif (stopOnParents === true) {\n\t\t\t\t\t\treturn \"skip\"; // stop processing this branch\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn nodeList;\n\t\t},\n\t\t/** Return true if node has children. Return undefined if not sure, i.e. the node is lazy and not yet loaded).\n\t\t * @returns {boolean | undefined}\n\t\t */\n\t\thasChildren: function () {\n\t\t\tif (this.lazy) {\n\t\t\t\tif (this.children == null) {\n\t\t\t\t\t// null or undefined: Not yet loaded\n\t\t\t\t\treturn undefined;\n\t\t\t\t} else if (this.children.length === 0) {\n\t\t\t\t\t// Loaded, but response was empty\n\t\t\t\t\treturn false;\n\t\t\t\t} else if (\n\t\t\t\t\tthis.children.length === 1 &&\n\t\t\t\t\tthis.children[0].isStatusNode()\n\t\t\t\t) {\n\t\t\t\t\t// Currently loading or load error\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn !!(this.children && this.children.length);\n\t\t},\n\t\t/**\n\t\t * Return true if node has `className` defined in .extraClasses.\n\t\t *\n\t\t * @param {string} className class name (separate multiple classes by space)\n\t\t * @returns {boolean}\n\t\t *\n\t\t * @since 2.32\n\t\t */\n\t\thasClass: function (className) {\n\t\t\treturn (\n\t\t\t\t(\" \" + (this.extraClasses || \"\") + \" \").indexOf(\n\t\t\t\t\t\" \" + className + \" \"\n\t\t\t\t) >= 0\n\t\t\t);\n\t\t},\n\t\t/** Return true if node has keyboard focus.\n\t\t * @returns {boolean}\n\t\t */\n\t\thasFocus: function () {\n\t\t\treturn this.tree.hasFocus() && this.tree.focusNode === this;\n\t\t},\n\t\t/** Write to browser console if debugLevel >= 3 (prepending node info)\n\t\t *\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\tinfo: function (msg) {\n\t\t\tif (this.tree.options.debugLevel >= 3) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"info\", arguments);\n\t\t\t}\n\t\t},\n\t\t/** Return true if node is active (see also FancytreeNode#isSelected).\n\t\t * @returns {boolean}\n\t\t */\n\t\tisActive: function () {\n\t\t\treturn this.tree.activeNode === this;\n\t\t},\n\t\t/** Return true if node is vertically below `otherNode`, i.e. rendered in a subsequent row.\n\t\t * @param {FancytreeNode} otherNode\n\t\t * @returns {boolean}\n\t\t * @since 2.28\n\t\t */\n\t\tisBelowOf: function (otherNode) {\n\t\t\treturn this.getIndexHier(\".\", 5) > otherNode.getIndexHier(\".\", 5);\n\t\t},\n\t\t/** Return true if node is a direct child of otherNode.\n\t\t * @param {FancytreeNode} otherNode\n\t\t * @returns {boolean}\n\t\t */\n\t\tisChildOf: function (otherNode) {\n\t\t\treturn this.parent && this.parent === otherNode;\n\t\t},\n\t\t/** Return true, if node is a direct or indirect sub node of otherNode.\n\t\t * @param {FancytreeNode} otherNode\n\t\t * @returns {boolean}\n\t\t */\n\t\tisDescendantOf: function (otherNode) {\n\t\t\tif (!otherNode || otherNode.tree !== this.tree) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar p = this.parent;\n\t\t\twhile (p) {\n\t\t\t\tif (p === otherNode) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (p === p.parent) {\n\t\t\t\t\t$.error(\"Recursive parent link: \" + p);\n\t\t\t\t}\n\t\t\t\tp = p.parent;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\t/** Return true if node is expanded.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisExpanded: function () {\n\t\t\treturn !!this.expanded;\n\t\t},\n\t\t/** Return true if node is the first node of its parent's children.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisFirstSibling: function () {\n\t\t\tvar p = this.parent;\n\t\t\treturn !p || p.children[0] === this;\n\t\t},\n\t\t/** Return true if node is a folder, i.e. has the node.folder attribute set.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisFolder: function () {\n\t\t\treturn !!this.folder;\n\t\t},\n\t\t/** Return true if node is the last node of its parent's children.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisLastSibling: function () {\n\t\t\tvar p = this.parent;\n\t\t\treturn !p || p.children[p.children.length - 1] === this;\n\t\t},\n\t\t/** Return true if node is lazy (even if data was already loaded)\n\t\t * @returns {boolean}\n\t\t */\n\t\tisLazy: function () {\n\t\t\treturn !!this.lazy;\n\t\t},\n\t\t/** Return true if node is lazy and loaded. For non-lazy nodes always return true.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisLoaded: function () {\n\t\t\treturn !this.lazy || this.hasChildren() !== undefined; // Also checks if the only child is a status node\n\t\t},\n\t\t/** Return true if children are currently beeing loaded, i.e. a Ajax request is pending.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisLoading: function () {\n\t\t\treturn !!this._isLoading;\n\t\t},\n\t\t/*\n\t\t * @deprecated since v2.4.0: Use isRootNode() instead\n\t\t */\n\t\tisRoot: function () {\n\t\t\treturn this.isRootNode();\n\t\t},\n\t\t/** Return true if node is partially selected (tri-state).\n\t\t * @returns {boolean}\n\t\t * @since 2.23\n\t\t */\n\t\tisPartsel: function () {\n\t\t\treturn !this.selected && !!this.partsel;\n\t\t},\n\t\t/** (experimental) Return true if this is partially loaded.\n\t\t * @returns {boolean}\n\t\t * @since 2.15\n\t\t */\n\t\tisPartload: function () {\n\t\t\treturn !!this.partload;\n\t\t},\n\t\t/** Return true if this is the (invisible) system root node.\n\t\t * @returns {boolean}\n\t\t * @since 2.4\n\t\t */\n\t\tisRootNode: function () {\n\t\t\treturn this.tree.rootNode === this;\n\t\t},\n\t\t/** Return true if node is selected, i.e. has a checkmark set (see also FancytreeNode#isActive).\n\t\t * @returns {boolean}\n\t\t */\n\t\tisSelected: function () {\n\t\t\treturn !!this.selected;\n\t\t},\n\t\t/** Return true if this node is a temporarily generated system node like\n\t\t * 'loading', 'paging', or 'error' (node.statusNodeType contains the type).\n\t\t * @returns {boolean}\n\t\t */\n\t\tisStatusNode: function () {\n\t\t\treturn !!this.statusNodeType;\n\t\t},\n\t\t/** Return true if this node is a status node of type 'paging'.\n\t\t * @returns {boolean}\n\t\t * @since 2.15\n\t\t */\n\t\tisPagingNode: function () {\n\t\t\treturn this.statusNodeType === \"paging\";\n\t\t},\n\t\t/** Return true if this a top level node, i.e. a direct child of the (invisible) system root node.\n\t\t * @returns {boolean}\n\t\t * @since 2.4\n\t\t */\n\t\tisTopLevel: function () {\n\t\t\treturn this.tree.rootNode === this.parent;\n\t\t},\n\t\t/** Return true if node is lazy and not yet loaded. For non-lazy nodes always return false.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisUndefined: function () {\n\t\t\treturn this.hasChildren() === undefined; // also checks if the only child is a status node\n\t\t},\n\t\t/** Return true if all parent nodes are expanded. Note: this does not check\n\t\t * whether the node is scrolled into the visible part of the screen.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisVisible: function () {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tn,\n\t\t\t\thasFilter = this.tree.enableFilter,\n\t\t\t\tparents = this.getParentList(false, false);\n\n\t\t\t// TODO: check $(n.span).is(\":visible\")\n\t\t\t// i.e. return false for nodes (but not parents) that are hidden\n\t\t\t// by a filter\n\t\t\tif (hasFilter && !this.match && !this.subMatchCount) {\n\t\t\t\t// this.debug( \"isVisible: HIDDEN (\" + hasFilter + \", \" + this.match + \", \" + this.match + \")\" );\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor (i = 0, l = parents.length; i < l; i++) {\n\t\t\t\tn = parents[i];\n\n\t\t\t\tif (!n.expanded) {\n\t\t\t\t\t// this.debug(\"isVisible: HIDDEN (parent collapsed)\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// if (hasFilter && !n.match && !n.subMatchCount) {\n\t\t\t\t// \tthis.debug(\"isVisible: HIDDEN (\" + hasFilter + \", \" + this.match + \", \" + this.match + \")\");\n\t\t\t\t// \treturn false;\n\t\t\t\t// }\n\t\t\t}\n\t\t\t// this.debug(\"isVisible: VISIBLE\");\n\t\t\treturn true;\n\t\t},\n\t\t/** Deprecated.\n\t\t * @deprecated since 2014-02-16: use load() instead.\n\t\t */\n\t\tlazyLoad: function (discard) {\n\t\t\t$.error(\n\t\t\t\t\"FancytreeNode.lazyLoad() is deprecated since 2014-02-16. Use .load() instead.\"\n\t\t\t);\n\t\t},\n\t\t/**\n\t\t * Load all children of a lazy node if neccessary. The expanded state is maintained.\n\t\t * @param {boolean} [forceReload=false] Pass true to discard any existing nodes before. Otherwise this method does nothing if the node was already loaded.\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tload: function (forceReload) {\n\t\t\tvar res,\n\t\t\t\tsource,\n\t\t\t\tself = this,\n\t\t\t\twasExpanded = this.isExpanded();\n\n\t\t\t_assert(this.isLazy(), \"load() requires a lazy node\");\n\t\t\t// _assert( forceReload || this.isUndefined(), \"Pass forceReload=true to re-load a lazy node\" );\n\t\t\tif (!forceReload && !this.isUndefined()) {\n\t\t\t\treturn _getResolvedPromise(this);\n\t\t\t}\n\t\t\tif (this.isLoaded()) {\n\t\t\t\tthis.resetLazy(); // also collapses\n\t\t\t}\n\t\t\t// This method is also called by setExpanded() and loadKeyPath(), so we\n\t\t\t// have to avoid recursion.\n\t\t\tsource = this.tree._triggerNodeEvent(\"lazyLoad\", this);\n\t\t\tif (source === false) {\n\t\t\t\t// #69\n\t\t\t\treturn _getResolvedPromise(this);\n\t\t\t}\n\t\t\t_assert(\n\t\t\t\ttypeof source !== \"boolean\",\n\t\t\t\t\"lazyLoad event must return source in data.result\"\n\t\t\t);\n\t\t\tres = this.tree._callHook(\"nodeLoadChildren\", this, source);\n\t\t\tif (wasExpanded) {\n\t\t\t\tthis.expanded = true;\n\t\t\t\tres.always(function () {\n\t\t\t\t\tself.render();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tres.always(function () {\n\t\t\t\t\tself.renderStatus(); // fix expander icon to 'loaded'\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn res;\n\t\t},\n\t\t/** Expand all parents and optionally scroll into visible area as neccessary.\n\t\t * Promise is resolved, when lazy loading and animations are done.\n\t\t * @param {object} [opts] passed to `setExpanded()`.\n\t\t * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tmakeVisible: function (opts) {\n\t\t\tvar i,\n\t\t\t\tself = this,\n\t\t\t\tdeferreds = [],\n\t\t\t\tdfd = new $.Deferred(),\n\t\t\t\tparents = this.getParentList(false, false),\n\t\t\t\tlen = parents.length,\n\t\t\t\teffects = !(opts && opts.noAnimation === true),\n\t\t\t\tscroll = !(opts && opts.scrollIntoView === false);\n\n\t\t\t// Expand bottom-up, so only the top node is animated\n\t\t\tfor (i = len - 1; i >= 0; i--) {\n\t\t\t\t// self.debug(\"pushexpand\" + parents[i]);\n\t\t\t\tdeferreds.push(parents[i].setExpanded(true, opts));\n\t\t\t}\n\t\t\t$.when.apply($, deferreds).done(function () {\n\t\t\t\t// All expands have finished\n\t\t\t\t// self.debug(\"expand DONE\", scroll);\n\t\t\t\tif (scroll) {\n\t\t\t\t\tself.scrollIntoView(effects).done(function () {\n\t\t\t\t\t\t// self.debug(\"scroll DONE\");\n\t\t\t\t\t\tdfd.resolve();\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tdfd.resolve();\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn dfd.promise();\n\t\t},\n\t\t/** Move this node to targetNode.\n\t\t * @param {FancytreeNode} targetNode\n\t\t * @param {string} mode
    \n\t\t *      'child': append this node as last child of targetNode.\n\t\t *               This is the default. To be compatble with the D'n'd\n\t\t *               hitMode, we also accept 'over'.\n\t\t *      'firstChild': add this node as first child of targetNode.\n\t\t *      'before': add this node as sibling before targetNode.\n\t\t *      'after': add this node as sibling after targetNode.
    \n\t\t * @param {function} [map] optional callback(FancytreeNode) to allow modifcations\n\t\t */\n\t\tmoveTo: function (targetNode, mode, map) {\n\t\t\tif (mode === undefined || mode === \"over\") {\n\t\t\t\tmode = \"child\";\n\t\t\t} else if (mode === \"firstChild\") {\n\t\t\t\tif (targetNode.children && targetNode.children.length) {\n\t\t\t\t\tmode = \"before\";\n\t\t\t\t\ttargetNode = targetNode.children[0];\n\t\t\t\t} else {\n\t\t\t\t\tmode = \"child\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar pos,\n\t\t\t\ttree = this.tree,\n\t\t\t\tprevParent = this.parent,\n\t\t\t\ttargetParent =\n\t\t\t\t\tmode === \"child\" ? targetNode : targetNode.parent;\n\n\t\t\tif (this === targetNode) {\n\t\t\t\treturn;\n\t\t\t} else if (!this.parent) {\n\t\t\t\t$.error(\"Cannot move system root\");\n\t\t\t} else if (targetParent.isDescendantOf(this)) {\n\t\t\t\t$.error(\"Cannot move a node to its own descendant\");\n\t\t\t}\n\t\t\tif (targetParent !== prevParent) {\n\t\t\t\tprevParent.triggerModifyChild(\"remove\", this);\n\t\t\t}\n\t\t\t// Unlink this node from current parent\n\t\t\tif (this.parent.children.length === 1) {\n\t\t\t\tif (this.parent === targetParent) {\n\t\t\t\t\treturn; // #258\n\t\t\t\t}\n\t\t\t\tthis.parent.children = this.parent.lazy ? [] : null;\n\t\t\t\tthis.parent.expanded = false;\n\t\t\t} else {\n\t\t\t\tpos = $.inArray(this, this.parent.children);\n\t\t\t\t_assert(pos >= 0, \"invalid source parent\");\n\t\t\t\tthis.parent.children.splice(pos, 1);\n\t\t\t}\n\t\t\t// Remove from source DOM parent\n\t\t\t// if(this.parent.ul){\n\t\t\t// \tthis.parent.ul.removeChild(this.li);\n\t\t\t// }\n\n\t\t\t// Insert this node to target parent's child list\n\t\t\tthis.parent = targetParent;\n\t\t\tif (targetParent.hasChildren()) {\n\t\t\t\tswitch (mode) {\n\t\t\t\t\tcase \"child\":\n\t\t\t\t\t\t// Append to existing target children\n\t\t\t\t\t\ttargetParent.children.push(this);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"before\":\n\t\t\t\t\t\t// Insert this node before target node\n\t\t\t\t\t\tpos = $.inArray(targetNode, targetParent.children);\n\t\t\t\t\t\t_assert(pos >= 0, \"invalid target parent\");\n\t\t\t\t\t\ttargetParent.children.splice(pos, 0, this);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"after\":\n\t\t\t\t\t\t// Insert this node after target node\n\t\t\t\t\t\tpos = $.inArray(targetNode, targetParent.children);\n\t\t\t\t\t\t_assert(pos >= 0, \"invalid target parent\");\n\t\t\t\t\t\ttargetParent.children.splice(pos + 1, 0, this);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t$.error(\"Invalid mode \" + mode);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttargetParent.children = [this];\n\t\t\t}\n\t\t\t// Parent has no